BSD style socket API for W5500.
Dependencies: W5500
Fork of Ethernet by
socket.c
00001 //***************************************************************************** 00002 // 00003 //! \file socket.c 00004 //! \brief SOCKET APIs Implements file. 00005 //! \details SOCKET APIs like as Berkeley Socket APIs. 00006 //! \version 1.0.0.0 00007 //! \date 2013/10/01 00008 //! \par Revision history 00009 //! <2013/10/01> 1st Release 00010 //! \author MidnightCow 00011 //! \copyright 00012 //! 00013 //! Copyright (c) 2013, WIZnet Co., LTD. 00014 //! All rights reserved. 00015 //! 00016 //! Redistribution and use in source and binary forms, with or without 00017 //! modification, are permitted provided that the following conditions 00018 //! are met: 00019 //! 00020 //! * Redistributions of source code must retain the above copyright 00021 //! notice, this list of conditions and the following disclaimer. 00022 //! * Redistributions in binary form must reproduce the above copyright 00023 //! notice, this list of conditions and the following disclaimer in the 00024 //! documentation and/or other materials provided with the distribution. 00025 //! * Neither the name of the <ORGANIZATION> nor the names of its 00026 //! contributors may be used to endorse or promote products derived 00027 //! from this software without specific prior written permission. 00028 //! 00029 //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00030 //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00031 //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00032 //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00033 //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00034 //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00035 //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00036 //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00037 //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00038 //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00039 //! THE POSSIBILITY OF SUCH DAMAGE. 00040 // 00041 //***************************************************************************** 00042 #include "socket.h" 00043 00044 #define SOCK_ANY_PORT_NUM 0xC000; 00045 00046 static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; 00047 static uint16_t sock_io_mode = 0; 00048 static uint16_t sock_is_sending = 0; 00049 static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; 00050 00051 #define CHECK_SOCKNUM() \ 00052 do{ \ 00053 if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ 00054 }while(0); \ 00055 00056 #define CHECK_SOCKMODE(mode) \ 00057 do{ \ 00058 if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ 00059 }while(0); \ 00060 00061 #define CHECK_SOCKINIT() \ 00062 do{ \ 00063 if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ 00064 }while(0); \ 00065 00066 #define CHECK_SOCKDATA() \ 00067 do{ \ 00068 if(len == 0) return SOCKERR_DATALEN; \ 00069 }while(0); \ 00070 00071 00072 00073 int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) 00074 { 00075 CHECK_SOCKNUM(); 00076 switch(protocol) 00077 { 00078 case Sn_MR_TCP : 00079 case Sn_MR_UDP : 00080 case Sn_MR_MACRAW : 00081 break; 00082 #if ( _WIZCHIP_ < 5200 ) 00083 case Sn_MR_IPRAW : 00084 case Sn_MR_PPPoE : 00085 break; 00086 #endif 00087 default : 00088 return SOCKERR_SOCKMODE; 00089 } 00090 if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; 00091 #if _WIZCHIP_ == 5200 00092 if(flag & 0x10) return SOCKERR_SOCKFLAG; 00093 #endif 00094 00095 if(flag != 0) 00096 { 00097 switch(protocol) 00098 { 00099 case Sn_MR_TCP: 00100 if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; 00101 break; 00102 case Sn_MR_UDP: 00103 if(flag & SF_IGMP_VER2) 00104 { 00105 if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; 00106 } 00107 #if _WIZCHIP_ == 5500 00108 if(flag & SF_UNI_BLOCK) 00109 { 00110 if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; 00111 } 00112 #endif 00113 break; 00114 default: 00115 break; 00116 } 00117 } 00118 close(sn); 00119 setSn_MR(sn, (protocol | (flag & 0xF0))); 00120 if(!port) 00121 { 00122 port = sock_any_port++; 00123 if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; 00124 } 00125 setSn_PORT(sn,port); 00126 setSn_CR(sn,Sn_CR_OPEN); 00127 while(getSn_CR(sn)); 00128 sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); 00129 sock_is_sending &= ~(1<<sn); 00130 sock_remained_size[sn] = 0; 00131 while(getSn_SR(sn) == SOCK_CLOSED); 00132 return (int8_t)sn; 00133 } 00134 00135 int8_t close(uint8_t sn) 00136 { 00137 CHECK_SOCKNUM(); 00138 00139 setSn_CR(sn,Sn_CR_CLOSE); 00140 /* wait to process the command... */ 00141 while( getSn_CR(sn) ); 00142 /* clear all interrupt of the socket. */ 00143 setSn_IR(sn, 0xFF); 00144 sock_is_sending &= ~(1<<sn); 00145 sock_remained_size[sn] = 0; 00146 while(getSn_SR(sn) != SOCK_CLOSED); 00147 return SOCK_OK; 00148 } 00149 00150 int8_t listen(uint8_t sn) 00151 { 00152 CHECK_SOCKNUM(); 00153 CHECK_SOCKMODE(Sn_MR_TCP); 00154 CHECK_SOCKINIT(); 00155 setSn_CR(sn,Sn_CR_LISTEN); 00156 while(getSn_CR(sn)); 00157 while(getSn_SR(sn) != SOCK_LISTEN) 00158 { 00159 if(getSn_CR(sn) == SOCK_CLOSED) 00160 { 00161 close(sn); 00162 return SOCKERR_SOCKCLOSED; 00163 } 00164 } 00165 return SOCK_OK; 00166 } 00167 00168 00169 int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port) 00170 { 00171 CHECK_SOCKNUM(); 00172 CHECK_SOCKMODE(Sn_MR_TCP); 00173 CHECK_SOCKINIT(); 00174 if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; 00175 if(port == 0) return SOCKERR_PORTZERO; 00176 setSn_DIPR(sn,addr); 00177 setSn_DPORT(sn,port); 00178 // setSUBR(); // set the subnet mask register 00179 setSn_CR(sn,Sn_CR_CONNECT); 00180 while(getSn_CR(sn)); 00181 if(sock_io_mode & (1<<sn)) return SOCK_BUSY; 00182 while(getSn_SR(sn) != SOCK_ESTABLISHED) 00183 { 00184 if (getSn_IR(sn) & Sn_IR_TIMEOUT) 00185 { 00186 setSn_IR(sn, Sn_IR_TIMEOUT); 00187 return SOCKERR_TIMEOUT; 00188 } 00189 } 00190 // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100 00191 return SOCK_OK; 00192 } 00193 00194 int8_t disconnect(uint8_t sn) 00195 { 00196 CHECK_SOCKNUM(); 00197 CHECK_SOCKMODE(Sn_MR_TCP); 00198 setSn_CR(sn,Sn_CR_DISCON); 00199 /* wait to process the command... */ 00200 while(getSn_CR(sn)); 00201 sock_is_sending &= ~(1<<sn); 00202 if(sock_io_mode & (1<<sn)) return SOCK_BUSY; 00203 while(getSn_SR(sn) != SOCK_CLOSED) 00204 { 00205 if(getSn_IR(sn) & Sn_IR_TIMEOUT) 00206 { 00207 close(sn); 00208 return SOCKERR_TIMEOUT; 00209 } 00210 } 00211 return SOCK_OK; 00212 } 00213 00214 int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) 00215 { 00216 uint8_t tmp=0; 00217 uint16_t freesize=0; 00218 00219 CHECK_SOCKNUM(); 00220 CHECK_SOCKMODE(Sn_MR_TCP); 00221 CHECK_SOCKDATA(); 00222 tmp = getSn_SR(sn); 00223 if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS; 00224 if( sock_is_sending & (1<<sn) ) 00225 { 00226 tmp = getSn_IR(sn); 00227 if(tmp & Sn_IR_SENDOK) 00228 { 00229 setSn_IR(sn, Sn_IR_SENDOK); 00230 sock_is_sending &= ~(1<<sn); 00231 } 00232 else if(tmp & Sn_IR_TIMEOUT) 00233 { 00234 close(sn); 00235 return SOCKERR_TIMEOUT; 00236 } 00237 else return SOCK_BUSY; 00238 } 00239 freesize = getSn_TxMAX(sn); 00240 if (len > freesize) len = freesize; // check size not to exceed MAX size. 00241 while(1) 00242 { 00243 freesize = getSn_TX_FSR(sn); 00244 tmp = getSn_SR(sn); 00245 if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) 00246 { 00247 close(sn); 00248 return SOCKERR_SOCKSTATUS; 00249 } 00250 if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; 00251 if(len <= freesize) break; 00252 } 00253 wiz_send_data(sn, buf, len); 00254 setSn_CR(sn,Sn_CR_SEND); 00255 /* wait to process the command... */ 00256 while(getSn_CR(sn)); 00257 sock_is_sending |= (1 << sn); 00258 /* 00259 if(sock_io_mode & (1<<sn)) return len; 00260 while( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) !=Sn_IR_SENDOK ) 00261 { 00262 if(tmp & Sn_IR_TIMEOUT) 00263 { 00264 close(sn); 00265 return SOCKERR_TIMEOUT; 00266 } 00267 } 00268 setSn_IR(sn, Sn_IR_SENDOK); 00269 */ 00270 return len; 00271 } 00272 00273 00274 int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) 00275 { 00276 uint8_t tmp = 0; 00277 uint16_t recvsize = 0; 00278 CHECK_SOCKNUM(); 00279 CHECK_SOCKMODE(Sn_MR_TCP); 00280 CHECK_SOCKDATA(); 00281 00282 recvsize = getSn_RxMAX(sn); 00283 if(recvsize < len) len = recvsize; 00284 while(1) 00285 { 00286 recvsize = getSn_RX_RSR(sn); 00287 tmp = getSn_SR(sn); 00288 if (tmp != SOCK_ESTABLISHED) 00289 { 00290 if(tmp == SOCK_CLOSE_WAIT) 00291 { 00292 if(recvsize != 0) break; 00293 else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) 00294 { 00295 close(sn); 00296 return SOCKERR_SOCKSTATUS; 00297 } 00298 } 00299 else 00300 { 00301 close(sn); 00302 return SOCKERR_SOCKSTATUS; 00303 } 00304 } 00305 if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; 00306 if(recvsize != 0) break; 00307 }; 00308 if(recvsize < len) len = recvsize; 00309 wiz_recv_data(sn, buf, len); 00310 setSn_CR(sn,Sn_CR_RECV); 00311 while(getSn_CR(sn)); 00312 return len; 00313 } 00314 00315 int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) 00316 { 00317 uint8_t tmp = 0; 00318 uint16_t freesize = 0; 00319 CHECK_SOCKNUM(); 00320 //CHECK_SOCKMODE(Sn_MR_UDP); 00321 switch(getSn_MR(sn) & 0x0F) 00322 { 00323 case Sn_MR_UDP: 00324 case Sn_MR_MACRAW: 00325 break; 00326 default: 00327 return SOCKERR_SOCKMODE; 00328 } 00329 CHECK_SOCKDATA(); 00330 if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; 00331 if(port == 0) return SOCKERR_PORTZERO; 00332 tmp = getSn_SR(sn); 00333 if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; 00334 00335 if( sock_is_sending & (1<<sn) ) 00336 { 00337 tmp = getSn_IR(sn); 00338 if(tmp & Sn_IR_SENDOK) 00339 { 00340 setSn_IR(sn, Sn_IR_SENDOK); 00341 sock_is_sending &= ~(1<<sn); 00342 } 00343 else if(tmp & Sn_IR_TIMEOUT) 00344 { 00345 close(sn); 00346 return SOCKERR_TIMEOUT; 00347 } 00348 else return SOCK_BUSY; 00349 } 00350 00351 setSn_DIPR(sn,addr); 00352 setSn_DPORT(sn,port); 00353 freesize = getSn_TxMAX(sn); 00354 if (len > freesize) len = freesize; // check size not to exceed MAX size. 00355 while(1) 00356 { 00357 freesize = getSn_TX_FSR(sn); 00358 if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; 00359 if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; 00360 if(len <= freesize) break; 00361 }; 00362 wiz_send_data(sn, buf, len); 00363 // setSUBR(); // set the subnet mask register 00364 setSn_CR(sn,Sn_CR_SEND); 00365 /* wait to process the command... */ 00366 while(getSn_CR(sn)); 00367 sock_is_sending |= (1<<sn); 00368 #if 0 00369 if(sock_io_mode & (1<<sn)) return len; 00370 while ( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) != Sn_IR_SENDOK ) 00371 { 00372 if(tmp & Sn_IR_TIMEOUT) 00373 { 00374 setSn_IR(sn, (Sn_IR_SENDOK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */ 00375 return SOCKERR_TIMEOUT; 00376 } 00377 } 00378 // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100 00379 setSn_IR(sn, Sn_IR_SENDOK); 00380 #endif 00381 return len; 00382 } 00383 00384 00385 00386 int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t* packinfo) 00387 { 00388 uint8_t mr; 00389 uint8_t head[8]; 00390 uint16_t pack_len=0; 00391 00392 CHECK_SOCKNUM(); 00393 //CHECK_SOCKMODE(Sn_MR_UDP); 00394 switch((mr=getSn_MR(sn)) & 0x0F) 00395 { 00396 case Sn_MR_UDP: 00397 case Sn_MR_MACRAW: 00398 break; 00399 #if ( _WIZCHIP_ < 5200 ) 00400 case Sn_MR_IPRAW: 00401 case Sn_MR_PPPoE: 00402 break; 00403 #endif 00404 default: 00405 return SOCKERR_SOCKMODE; 00406 } 00407 CHECK_SOCKDATA(); 00408 if(sock_remained_size[sn] == 0) 00409 { 00410 while(1) 00411 { 00412 pack_len = getSn_RX_RSR(sn); 00413 if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; 00414 if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; 00415 if(pack_len != 0) break; 00416 }; 00417 } 00418 *packinfo = 0x00; 00419 switch (mr & 0x07) 00420 { 00421 case Sn_MR_UDP : 00422 if(sock_remained_size[sn] == 0) 00423 { 00424 wiz_recv_data(sn, head, 8); 00425 setSn_CR(sn,Sn_CR_RECV); 00426 while(getSn_CR(sn)); 00427 // read peer's IP address, port number & packet length 00428 addr[0] = head[0]; 00429 addr[1] = head[1]; 00430 addr[2] = head[2]; 00431 addr[3] = head[3]; 00432 *port = head[4]; 00433 *port = (*port << 8) + head[5]; 00434 sock_remained_size[sn] = head[6]; 00435 sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; 00436 *packinfo = 0x80; 00437 } 00438 if(len < sock_remained_size[sn]) pack_len = len; 00439 else pack_len = sock_remained_size[sn]; 00440 // 00441 // Need to packet length check (default 1472) 00442 // 00443 wiz_recv_data(sn, buf, pack_len); // data copy. 00444 break; 00445 case Sn_MR_MACRAW : 00446 if(sock_remained_size[sn] == 0) 00447 { 00448 wiz_recv_data(sn, head, 2); 00449 setSn_CR(sn,Sn_CR_RECV); 00450 while(getSn_CR(sn)); 00451 // read peer's IP address, port number & packet length 00452 sock_remained_size[sn] = head[0]; 00453 sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; 00454 if(sock_remained_size[sn] > 1514) 00455 { 00456 close(sn); 00457 return SOCKFATAL_PACKLEN; 00458 } 00459 } 00460 if(len < sock_remained_size[sn]) pack_len = len; 00461 else pack_len = sock_remained_size[sn]; 00462 wiz_recv_data(sn,buf,pack_len); 00463 break; 00464 #if ( _WIZCHIP_ < 5200 ) 00465 case Sn_MR_IPRAW: 00466 if(sock_remained_size[sn] == 0) 00467 { 00468 wiz_recv_data(sn, head, 6); 00469 setSn_CR(sn,Sn_CR_RECV); 00470 while(getSn_CR(sn)); 00471 addr[0] = head[0]; 00472 addr[1] = head[1]; 00473 addr[2] = head[2]; 00474 addr[3] = head[3]; 00475 sock_remained_size[sn] = head[4]; 00476 sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; 00477 *packinfo = 0x80; 00478 } 00479 // 00480 // Need to packet length check 00481 // 00482 if(len < sock_remained_size[sn]) pack_len = len; 00483 else pack_len = sock_remained_size[sn]; 00484 wiz_recv_data(sn, buf, pack_len); // data copy. 00485 break; 00486 #endif 00487 default: 00488 wiz_recv_ignore(sn, pack_len); // data copy. 00489 sock_remained_size[sn] = pack_len; 00490 break; 00491 } 00492 setSn_CR(sn,Sn_CR_RECV); 00493 /* wait to process the command... */ 00494 while(getSn_CR(sn)) ; 00495 sock_remained_size[sn] -= pack_len; 00496 if(sock_remained_size[sn] != 0) *packinfo |= 0x01; 00497 return pack_len; 00498 } 00499 00500 00501 int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) 00502 { 00503 uint8_t tmp = 0; 00504 CHECK_SOCKNUM(); 00505 switch(cstype) 00506 { 00507 case CS_SET_IOMODE: 00508 tmp = *((uint8_t*)arg); 00509 if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn); 00510 else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn); 00511 else return SOCKERR_ARG; 00512 break; 00513 case CS_GET_IOMODE: 00514 *((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; 00515 break; 00516 case CS_GET_MAXTXBUF: 00517 *((uint16_t*)arg) = getSn_TxMAX(sn); 00518 break; 00519 case CS_GET_MAXRXBUF: 00520 *((uint16_t*)arg) = getSn_RxMAX(sn); 00521 break; 00522 case CS_CLR_INTERRUPT: 00523 if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; 00524 setSn_IR(sn,*(uint8_t*)arg); 00525 break; 00526 case CS_GET_INTERRUPT: 00527 *((uint8_t*)arg) = getSn_IR(sn); 00528 break; 00529 case CS_SET_INTMASK: 00530 if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; 00531 setSn_IMR(sn,*(uint8_t*)arg); 00532 break; 00533 case CS_GET_INTMASK: 00534 *((uint8_t*)arg) = getSn_IMR(sn); 00535 default: 00536 return SOCKERR_ARG; 00537 } 00538 return SOCK_OK; 00539 } 00540 00541 int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg) 00542 { 00543 uint8_t tmp; 00544 CHECK_SOCKNUM(); 00545 switch(sotype) 00546 { 00547 case SO_TTL: 00548 setSn_TTL(sn,*(uint8_t*)arg); 00549 break; 00550 case SO_TOS: 00551 setSn_TOS(sn,*(uint8_t*)arg); 00552 break; 00553 case SO_MSS: 00554 setSn_MSSR(sn,*(uint16_t*)arg); 00555 break; 00556 case SO_DESTIP: 00557 setSn_DIPR(sn, (uint8_t*)arg); 00558 break; 00559 case SO_DESTPORT: 00560 setSn_DPORT(sn, *(uint16_t*)arg); 00561 break; 00562 #if _WIZCHIP_ != 5100 00563 case SO_KEEPALIVESEND: 00564 CHECK_SOCKMODE(Sn_MR_TCP); 00565 #if _WIZCHIP_ > 5200 00566 if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; 00567 #endif 00568 setSn_CR(sn,Sn_CR_SEND_KEEP); 00569 while((tmp = getSn_CR(sn)) != 0) 00570 { 00571 if (getSn_IR(sn) & Sn_IR_TIMEOUT) 00572 { 00573 setSn_IR(sn, Sn_IR_TIMEOUT); 00574 return SOCKERR_TIMEOUT; 00575 } 00576 } 00577 break; 00578 #if _WIZCHIP_ > 5200 00579 case SO_KEEPALIVEAUTO: 00580 CHECK_SOCKMODE(Sn_MR_TCP); 00581 setSn_KPALVTR(sn,*(uint8_t*)arg); 00582 break; 00583 #endif 00584 #endif 00585 default: 00586 return SOCKERR_ARG; 00587 } 00588 return SOCK_OK; 00589 } 00590 00591 int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg) 00592 { 00593 CHECK_SOCKNUM(); 00594 switch(sotype) 00595 { 00596 case SO_FLAG: 00597 *(uint8_t*)arg = getSn_MR(sn) & 0xF0; 00598 break; 00599 case SO_TTL: 00600 *(uint8_t*) arg = getSn_TTL(sn); 00601 break; 00602 case SO_TOS: 00603 *(uint8_t*) arg = getSn_TOS(sn); 00604 break; 00605 case SO_MSS: 00606 *(uint8_t*) arg = getSn_MSSR(sn); 00607 case SO_DESTIP: 00608 getSn_DIPR(sn, (uint8_t*)arg); 00609 break; 00610 case SO_DESTPORT: 00611 *(uint16_t*) arg = getSn_DPORT(sn); 00612 break; 00613 #if _WIZCHIP_ > 5200 00614 case SO_KEEPALIVEAUTO: 00615 CHECK_SOCKMODE(Sn_MR_TCP); 00616 *(uint16_t*) arg = getSn_KPALVTR(sn); 00617 break; 00618 #endif 00619 case SO_SENDBUF: 00620 *(uint16_t*) arg = getSn_TX_FSR(sn); 00621 case SO_RECVBUF: 00622 *(uint16_t*) arg = getSn_RX_RSR(sn); 00623 case SO_STATUS: 00624 *(uint8_t*) arg = getSn_SR(sn); 00625 break; 00626 case SO_REMAINSIZE: 00627 if(getSn_MR(sn) == Sn_MR_TCP) 00628 *(uint16_t*)arg = getSn_RX_RSR(sn); 00629 else 00630 *(uint16_t*)arg = sock_remained_size[sn]; 00631 break; 00632 default: 00633 return SOCKERR_SOCKOPT; 00634 } 00635 return SOCK_OK; 00636 }
Generated on Tue Jul 12 2022 17:16:46 by 1.7.2