BSD style socket API for W5500.

Dependencies:   W5500

Fork of Ethernet by Raphael Kwon

Committer:
xeon011
Date:
Tue Feb 18 05:41:48 2014 +0000
Revision:
2:ee0f7508fb5c
Parent:
0:9158fe13dc14
First release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xeon011 0:9158fe13dc14 1 //*****************************************************************************
xeon011 0:9158fe13dc14 2 //
xeon011 0:9158fe13dc14 3 //! \file socket.c
xeon011 0:9158fe13dc14 4 //! \brief SOCKET APIs Implements file.
xeon011 0:9158fe13dc14 5 //! \details SOCKET APIs like as Berkeley Socket APIs.
xeon011 0:9158fe13dc14 6 //! \version 1.0.0.0
xeon011 0:9158fe13dc14 7 //! \date 2013/10/01
xeon011 0:9158fe13dc14 8 //! \par Revision history
xeon011 0:9158fe13dc14 9 //! <2013/10/01> 1st Release
xeon011 0:9158fe13dc14 10 //! \author MidnightCow
xeon011 0:9158fe13dc14 11 //! \copyright
xeon011 0:9158fe13dc14 12 //!
xeon011 0:9158fe13dc14 13 //! Copyright (c) 2013, WIZnet Co., LTD.
xeon011 0:9158fe13dc14 14 //! All rights reserved.
xeon011 0:9158fe13dc14 15 //!
xeon011 0:9158fe13dc14 16 //! Redistribution and use in source and binary forms, with or without
xeon011 0:9158fe13dc14 17 //! modification, are permitted provided that the following conditions
xeon011 0:9158fe13dc14 18 //! are met:
xeon011 0:9158fe13dc14 19 //!
xeon011 0:9158fe13dc14 20 //! * Redistributions of source code must retain the above copyright
xeon011 0:9158fe13dc14 21 //! notice, this list of conditions and the following disclaimer.
xeon011 0:9158fe13dc14 22 //! * Redistributions in binary form must reproduce the above copyright
xeon011 0:9158fe13dc14 23 //! notice, this list of conditions and the following disclaimer in the
xeon011 0:9158fe13dc14 24 //! documentation and/or other materials provided with the distribution.
xeon011 0:9158fe13dc14 25 //! * Neither the name of the <ORGANIZATION> nor the names of its
xeon011 0:9158fe13dc14 26 //! contributors may be used to endorse or promote products derived
xeon011 0:9158fe13dc14 27 //! from this software without specific prior written permission.
xeon011 0:9158fe13dc14 28 //!
xeon011 0:9158fe13dc14 29 //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
xeon011 0:9158fe13dc14 30 //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
xeon011 0:9158fe13dc14 31 //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
xeon011 0:9158fe13dc14 32 //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
xeon011 0:9158fe13dc14 33 //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
xeon011 0:9158fe13dc14 34 //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
xeon011 0:9158fe13dc14 35 //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
xeon011 0:9158fe13dc14 36 //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
xeon011 0:9158fe13dc14 37 //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
xeon011 0:9158fe13dc14 38 //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
xeon011 0:9158fe13dc14 39 //! THE POSSIBILITY OF SUCH DAMAGE.
xeon011 0:9158fe13dc14 40 //
xeon011 0:9158fe13dc14 41 //*****************************************************************************
xeon011 0:9158fe13dc14 42 #include "socket.h"
xeon011 0:9158fe13dc14 43
xeon011 0:9158fe13dc14 44 #define SOCK_ANY_PORT_NUM 0xC000;
xeon011 0:9158fe13dc14 45
xeon011 0:9158fe13dc14 46 static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
xeon011 0:9158fe13dc14 47 static uint16_t sock_io_mode = 0;
xeon011 0:9158fe13dc14 48 static uint16_t sock_is_sending = 0;
xeon011 0:9158fe13dc14 49 static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
xeon011 0:9158fe13dc14 50
xeon011 0:9158fe13dc14 51 #define CHECK_SOCKNUM() \
xeon011 0:9158fe13dc14 52 do{ \
xeon011 0:9158fe13dc14 53 if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
xeon011 0:9158fe13dc14 54 }while(0); \
xeon011 0:9158fe13dc14 55
xeon011 0:9158fe13dc14 56 #define CHECK_SOCKMODE(mode) \
xeon011 0:9158fe13dc14 57 do{ \
xeon011 0:9158fe13dc14 58 if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
xeon011 0:9158fe13dc14 59 }while(0); \
xeon011 0:9158fe13dc14 60
xeon011 0:9158fe13dc14 61 #define CHECK_SOCKINIT() \
xeon011 0:9158fe13dc14 62 do{ \
xeon011 0:9158fe13dc14 63 if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
xeon011 0:9158fe13dc14 64 }while(0); \
xeon011 0:9158fe13dc14 65
xeon011 0:9158fe13dc14 66 #define CHECK_SOCKDATA() \
xeon011 0:9158fe13dc14 67 do{ \
xeon011 0:9158fe13dc14 68 if(len == 0) return SOCKERR_DATALEN; \
xeon011 0:9158fe13dc14 69 }while(0); \
xeon011 0:9158fe13dc14 70
xeon011 0:9158fe13dc14 71
xeon011 0:9158fe13dc14 72
xeon011 0:9158fe13dc14 73 int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
xeon011 0:9158fe13dc14 74 {
xeon011 0:9158fe13dc14 75 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 76 switch(protocol)
xeon011 0:9158fe13dc14 77 {
xeon011 0:9158fe13dc14 78 case Sn_MR_TCP :
xeon011 0:9158fe13dc14 79 case Sn_MR_UDP :
xeon011 0:9158fe13dc14 80 case Sn_MR_MACRAW :
xeon011 0:9158fe13dc14 81 break;
xeon011 0:9158fe13dc14 82 #if ( _WIZCHIP_ < 5200 )
xeon011 0:9158fe13dc14 83 case Sn_MR_IPRAW :
xeon011 0:9158fe13dc14 84 case Sn_MR_PPPoE :
xeon011 0:9158fe13dc14 85 break;
xeon011 0:9158fe13dc14 86 #endif
xeon011 0:9158fe13dc14 87 default :
xeon011 0:9158fe13dc14 88 return SOCKERR_SOCKMODE;
xeon011 0:9158fe13dc14 89 }
xeon011 0:9158fe13dc14 90 if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
xeon011 0:9158fe13dc14 91 #if _WIZCHIP_ == 5200
xeon011 0:9158fe13dc14 92 if(flag & 0x10) return SOCKERR_SOCKFLAG;
xeon011 0:9158fe13dc14 93 #endif
xeon011 0:9158fe13dc14 94
xeon011 0:9158fe13dc14 95 if(flag != 0)
xeon011 0:9158fe13dc14 96 {
xeon011 0:9158fe13dc14 97 switch(protocol)
xeon011 0:9158fe13dc14 98 {
xeon011 0:9158fe13dc14 99 case Sn_MR_TCP:
xeon011 0:9158fe13dc14 100 if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
xeon011 0:9158fe13dc14 101 break;
xeon011 0:9158fe13dc14 102 case Sn_MR_UDP:
xeon011 0:9158fe13dc14 103 if(flag & SF_IGMP_VER2)
xeon011 0:9158fe13dc14 104 {
xeon011 0:9158fe13dc14 105 if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
xeon011 0:9158fe13dc14 106 }
xeon011 0:9158fe13dc14 107 #if _WIZCHIP_ == 5500
xeon011 0:9158fe13dc14 108 if(flag & SF_UNI_BLOCK)
xeon011 0:9158fe13dc14 109 {
xeon011 0:9158fe13dc14 110 if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
xeon011 0:9158fe13dc14 111 }
xeon011 0:9158fe13dc14 112 #endif
xeon011 0:9158fe13dc14 113 break;
xeon011 0:9158fe13dc14 114 default:
xeon011 0:9158fe13dc14 115 break;
xeon011 0:9158fe13dc14 116 }
xeon011 0:9158fe13dc14 117 }
xeon011 0:9158fe13dc14 118 close(sn);
xeon011 0:9158fe13dc14 119 setSn_MR(sn, (protocol | (flag & 0xF0)));
xeon011 0:9158fe13dc14 120 if(!port)
xeon011 0:9158fe13dc14 121 {
xeon011 0:9158fe13dc14 122 port = sock_any_port++;
xeon011 0:9158fe13dc14 123 if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
xeon011 0:9158fe13dc14 124 }
xeon011 0:9158fe13dc14 125 setSn_PORT(sn,port);
xeon011 0:9158fe13dc14 126 setSn_CR(sn,Sn_CR_OPEN);
xeon011 0:9158fe13dc14 127 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 128 sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
xeon011 0:9158fe13dc14 129 sock_is_sending &= ~(1<<sn);
xeon011 0:9158fe13dc14 130 sock_remained_size[sn] = 0;
xeon011 0:9158fe13dc14 131 while(getSn_SR(sn) == SOCK_CLOSED);
xeon011 0:9158fe13dc14 132 return (int8_t)sn;
xeon011 0:9158fe13dc14 133 }
xeon011 0:9158fe13dc14 134
xeon011 0:9158fe13dc14 135 int8_t close(uint8_t sn)
xeon011 0:9158fe13dc14 136 {
xeon011 0:9158fe13dc14 137 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 138
xeon011 0:9158fe13dc14 139 setSn_CR(sn,Sn_CR_CLOSE);
xeon011 0:9158fe13dc14 140 /* wait to process the command... */
xeon011 0:9158fe13dc14 141 while( getSn_CR(sn) );
xeon011 0:9158fe13dc14 142 /* clear all interrupt of the socket. */
xeon011 0:9158fe13dc14 143 setSn_IR(sn, 0xFF);
xeon011 0:9158fe13dc14 144 sock_is_sending &= ~(1<<sn);
xeon011 0:9158fe13dc14 145 sock_remained_size[sn] = 0;
xeon011 0:9158fe13dc14 146 while(getSn_SR(sn) != SOCK_CLOSED);
xeon011 0:9158fe13dc14 147 return SOCK_OK;
xeon011 0:9158fe13dc14 148 }
xeon011 0:9158fe13dc14 149
xeon011 0:9158fe13dc14 150 int8_t listen(uint8_t sn)
xeon011 0:9158fe13dc14 151 {
xeon011 0:9158fe13dc14 152 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 153 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 154 CHECK_SOCKINIT();
xeon011 0:9158fe13dc14 155 setSn_CR(sn,Sn_CR_LISTEN);
xeon011 0:9158fe13dc14 156 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 157 while(getSn_SR(sn) != SOCK_LISTEN)
xeon011 0:9158fe13dc14 158 {
xeon011 0:9158fe13dc14 159 if(getSn_CR(sn) == SOCK_CLOSED)
xeon011 0:9158fe13dc14 160 {
xeon011 0:9158fe13dc14 161 close(sn);
xeon011 0:9158fe13dc14 162 return SOCKERR_SOCKCLOSED;
xeon011 0:9158fe13dc14 163 }
xeon011 0:9158fe13dc14 164 }
xeon011 0:9158fe13dc14 165 return SOCK_OK;
xeon011 0:9158fe13dc14 166 }
xeon011 0:9158fe13dc14 167
xeon011 0:9158fe13dc14 168
xeon011 0:9158fe13dc14 169 int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
xeon011 0:9158fe13dc14 170 {
xeon011 0:9158fe13dc14 171 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 172 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 173 CHECK_SOCKINIT();
xeon011 0:9158fe13dc14 174 if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
xeon011 0:9158fe13dc14 175 if(port == 0) return SOCKERR_PORTZERO;
xeon011 0:9158fe13dc14 176 setSn_DIPR(sn,addr);
xeon011 0:9158fe13dc14 177 setSn_DPORT(sn,port);
xeon011 0:9158fe13dc14 178 // setSUBR(); // set the subnet mask register
xeon011 0:9158fe13dc14 179 setSn_CR(sn,Sn_CR_CONNECT);
xeon011 0:9158fe13dc14 180 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 181 if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
xeon011 0:9158fe13dc14 182 while(getSn_SR(sn) != SOCK_ESTABLISHED)
xeon011 0:9158fe13dc14 183 {
xeon011 0:9158fe13dc14 184 if (getSn_IR(sn) & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 185 {
xeon011 0:9158fe13dc14 186 setSn_IR(sn, Sn_IR_TIMEOUT);
xeon011 0:9158fe13dc14 187 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 188 }
xeon011 0:9158fe13dc14 189 }
xeon011 0:9158fe13dc14 190 // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100
xeon011 0:9158fe13dc14 191 return SOCK_OK;
xeon011 0:9158fe13dc14 192 }
xeon011 0:9158fe13dc14 193
xeon011 0:9158fe13dc14 194 int8_t disconnect(uint8_t sn)
xeon011 0:9158fe13dc14 195 {
xeon011 0:9158fe13dc14 196 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 197 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 198 setSn_CR(sn,Sn_CR_DISCON);
xeon011 0:9158fe13dc14 199 /* wait to process the command... */
xeon011 0:9158fe13dc14 200 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 201 sock_is_sending &= ~(1<<sn);
xeon011 0:9158fe13dc14 202 if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
xeon011 0:9158fe13dc14 203 while(getSn_SR(sn) != SOCK_CLOSED)
xeon011 0:9158fe13dc14 204 {
xeon011 0:9158fe13dc14 205 if(getSn_IR(sn) & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 206 {
xeon011 0:9158fe13dc14 207 close(sn);
xeon011 0:9158fe13dc14 208 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 209 }
xeon011 0:9158fe13dc14 210 }
xeon011 0:9158fe13dc14 211 return SOCK_OK;
xeon011 0:9158fe13dc14 212 }
xeon011 0:9158fe13dc14 213
xeon011 0:9158fe13dc14 214 int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
xeon011 0:9158fe13dc14 215 {
xeon011 0:9158fe13dc14 216 uint8_t tmp=0;
xeon011 0:9158fe13dc14 217 uint16_t freesize=0;
xeon011 0:9158fe13dc14 218
xeon011 0:9158fe13dc14 219 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 220 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 221 CHECK_SOCKDATA();
xeon011 0:9158fe13dc14 222 tmp = getSn_SR(sn);
xeon011 0:9158fe13dc14 223 if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
xeon011 0:9158fe13dc14 224 if( sock_is_sending & (1<<sn) )
xeon011 0:9158fe13dc14 225 {
xeon011 0:9158fe13dc14 226 tmp = getSn_IR(sn);
xeon011 0:9158fe13dc14 227 if(tmp & Sn_IR_SENDOK)
xeon011 0:9158fe13dc14 228 {
xeon011 0:9158fe13dc14 229 setSn_IR(sn, Sn_IR_SENDOK);
xeon011 0:9158fe13dc14 230 sock_is_sending &= ~(1<<sn);
xeon011 0:9158fe13dc14 231 }
xeon011 0:9158fe13dc14 232 else if(tmp & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 233 {
xeon011 0:9158fe13dc14 234 close(sn);
xeon011 0:9158fe13dc14 235 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 236 }
xeon011 0:9158fe13dc14 237 else return SOCK_BUSY;
xeon011 0:9158fe13dc14 238 }
xeon011 0:9158fe13dc14 239 freesize = getSn_TxMAX(sn);
xeon011 0:9158fe13dc14 240 if (len > freesize) len = freesize; // check size not to exceed MAX size.
xeon011 0:9158fe13dc14 241 while(1)
xeon011 0:9158fe13dc14 242 {
xeon011 0:9158fe13dc14 243 freesize = getSn_TX_FSR(sn);
xeon011 0:9158fe13dc14 244 tmp = getSn_SR(sn);
xeon011 0:9158fe13dc14 245 if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
xeon011 0:9158fe13dc14 246 {
xeon011 0:9158fe13dc14 247 close(sn);
xeon011 0:9158fe13dc14 248 return SOCKERR_SOCKSTATUS;
xeon011 0:9158fe13dc14 249 }
xeon011 0:9158fe13dc14 250 if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
xeon011 0:9158fe13dc14 251 if(len <= freesize) break;
xeon011 0:9158fe13dc14 252 }
xeon011 0:9158fe13dc14 253 wiz_send_data(sn, buf, len);
xeon011 0:9158fe13dc14 254 setSn_CR(sn,Sn_CR_SEND);
xeon011 0:9158fe13dc14 255 /* wait to process the command... */
xeon011 0:9158fe13dc14 256 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 257 sock_is_sending |= (1 << sn);
xeon011 0:9158fe13dc14 258 /*
xeon011 0:9158fe13dc14 259 if(sock_io_mode & (1<<sn)) return len;
xeon011 0:9158fe13dc14 260 while( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) !=Sn_IR_SENDOK )
xeon011 0:9158fe13dc14 261 {
xeon011 0:9158fe13dc14 262 if(tmp & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 263 {
xeon011 0:9158fe13dc14 264 close(sn);
xeon011 0:9158fe13dc14 265 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 266 }
xeon011 0:9158fe13dc14 267 }
xeon011 0:9158fe13dc14 268 setSn_IR(sn, Sn_IR_SENDOK);
xeon011 0:9158fe13dc14 269 */
xeon011 0:9158fe13dc14 270 return len;
xeon011 0:9158fe13dc14 271 }
xeon011 0:9158fe13dc14 272
xeon011 0:9158fe13dc14 273
xeon011 0:9158fe13dc14 274 int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
xeon011 0:9158fe13dc14 275 {
xeon011 0:9158fe13dc14 276 uint8_t tmp = 0;
xeon011 0:9158fe13dc14 277 uint16_t recvsize = 0;
xeon011 0:9158fe13dc14 278 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 279 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 280 CHECK_SOCKDATA();
xeon011 0:9158fe13dc14 281
xeon011 0:9158fe13dc14 282 recvsize = getSn_RxMAX(sn);
xeon011 0:9158fe13dc14 283 if(recvsize < len) len = recvsize;
xeon011 0:9158fe13dc14 284 while(1)
xeon011 0:9158fe13dc14 285 {
xeon011 0:9158fe13dc14 286 recvsize = getSn_RX_RSR(sn);
xeon011 0:9158fe13dc14 287 tmp = getSn_SR(sn);
xeon011 0:9158fe13dc14 288 if (tmp != SOCK_ESTABLISHED)
xeon011 0:9158fe13dc14 289 {
xeon011 0:9158fe13dc14 290 if(tmp == SOCK_CLOSE_WAIT)
xeon011 0:9158fe13dc14 291 {
xeon011 0:9158fe13dc14 292 if(recvsize != 0) break;
xeon011 0:9158fe13dc14 293 else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
xeon011 0:9158fe13dc14 294 {
xeon011 0:9158fe13dc14 295 close(sn);
xeon011 0:9158fe13dc14 296 return SOCKERR_SOCKSTATUS;
xeon011 0:9158fe13dc14 297 }
xeon011 0:9158fe13dc14 298 }
xeon011 0:9158fe13dc14 299 else
xeon011 0:9158fe13dc14 300 {
xeon011 0:9158fe13dc14 301 close(sn);
xeon011 0:9158fe13dc14 302 return SOCKERR_SOCKSTATUS;
xeon011 0:9158fe13dc14 303 }
xeon011 0:9158fe13dc14 304 }
xeon011 0:9158fe13dc14 305 if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
xeon011 0:9158fe13dc14 306 if(recvsize != 0) break;
xeon011 0:9158fe13dc14 307 };
xeon011 0:9158fe13dc14 308 if(recvsize < len) len = recvsize;
xeon011 0:9158fe13dc14 309 wiz_recv_data(sn, buf, len);
xeon011 0:9158fe13dc14 310 setSn_CR(sn,Sn_CR_RECV);
xeon011 0:9158fe13dc14 311 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 312 return len;
xeon011 0:9158fe13dc14 313 }
xeon011 0:9158fe13dc14 314
xeon011 0:9158fe13dc14 315 int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
xeon011 0:9158fe13dc14 316 {
xeon011 0:9158fe13dc14 317 uint8_t tmp = 0;
xeon011 0:9158fe13dc14 318 uint16_t freesize = 0;
xeon011 0:9158fe13dc14 319 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 320 //CHECK_SOCKMODE(Sn_MR_UDP);
xeon011 0:9158fe13dc14 321 switch(getSn_MR(sn) & 0x0F)
xeon011 0:9158fe13dc14 322 {
xeon011 0:9158fe13dc14 323 case Sn_MR_UDP:
xeon011 0:9158fe13dc14 324 case Sn_MR_MACRAW:
xeon011 0:9158fe13dc14 325 break;
xeon011 0:9158fe13dc14 326 default:
xeon011 0:9158fe13dc14 327 return SOCKERR_SOCKMODE;
xeon011 0:9158fe13dc14 328 }
xeon011 0:9158fe13dc14 329 CHECK_SOCKDATA();
xeon011 0:9158fe13dc14 330 if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
xeon011 0:9158fe13dc14 331 if(port == 0) return SOCKERR_PORTZERO;
xeon011 0:9158fe13dc14 332 tmp = getSn_SR(sn);
xeon011 0:9158fe13dc14 333 if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
xeon011 0:9158fe13dc14 334
xeon011 0:9158fe13dc14 335 if( sock_is_sending & (1<<sn) )
xeon011 0:9158fe13dc14 336 {
xeon011 0:9158fe13dc14 337 tmp = getSn_IR(sn);
xeon011 0:9158fe13dc14 338 if(tmp & Sn_IR_SENDOK)
xeon011 0:9158fe13dc14 339 {
xeon011 0:9158fe13dc14 340 setSn_IR(sn, Sn_IR_SENDOK);
xeon011 0:9158fe13dc14 341 sock_is_sending &= ~(1<<sn);
xeon011 0:9158fe13dc14 342 }
xeon011 0:9158fe13dc14 343 else if(tmp & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 344 {
xeon011 0:9158fe13dc14 345 close(sn);
xeon011 0:9158fe13dc14 346 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 347 }
xeon011 0:9158fe13dc14 348 else return SOCK_BUSY;
xeon011 0:9158fe13dc14 349 }
xeon011 0:9158fe13dc14 350
xeon011 0:9158fe13dc14 351 setSn_DIPR(sn,addr);
xeon011 0:9158fe13dc14 352 setSn_DPORT(sn,port);
xeon011 0:9158fe13dc14 353 freesize = getSn_TxMAX(sn);
xeon011 0:9158fe13dc14 354 if (len > freesize) len = freesize; // check size not to exceed MAX size.
xeon011 0:9158fe13dc14 355 while(1)
xeon011 0:9158fe13dc14 356 {
xeon011 0:9158fe13dc14 357 freesize = getSn_TX_FSR(sn);
xeon011 0:9158fe13dc14 358 if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
xeon011 0:9158fe13dc14 359 if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
xeon011 0:9158fe13dc14 360 if(len <= freesize) break;
xeon011 0:9158fe13dc14 361 };
xeon011 0:9158fe13dc14 362 wiz_send_data(sn, buf, len);
xeon011 0:9158fe13dc14 363 // setSUBR(); // set the subnet mask register
xeon011 0:9158fe13dc14 364 setSn_CR(sn,Sn_CR_SEND);
xeon011 0:9158fe13dc14 365 /* wait to process the command... */
xeon011 0:9158fe13dc14 366 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 367 sock_is_sending |= (1<<sn);
xeon011 0:9158fe13dc14 368 #if 0
xeon011 0:9158fe13dc14 369 if(sock_io_mode & (1<<sn)) return len;
xeon011 0:9158fe13dc14 370 while ( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) != Sn_IR_SENDOK )
xeon011 0:9158fe13dc14 371 {
xeon011 0:9158fe13dc14 372 if(tmp & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 373 {
xeon011 0:9158fe13dc14 374 setSn_IR(sn, (Sn_IR_SENDOK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
xeon011 0:9158fe13dc14 375 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 376 }
xeon011 0:9158fe13dc14 377 }
xeon011 0:9158fe13dc14 378 // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100
xeon011 0:9158fe13dc14 379 setSn_IR(sn, Sn_IR_SENDOK);
xeon011 0:9158fe13dc14 380 #endif
xeon011 0:9158fe13dc14 381 return len;
xeon011 0:9158fe13dc14 382 }
xeon011 0:9158fe13dc14 383
xeon011 0:9158fe13dc14 384
xeon011 0:9158fe13dc14 385
xeon011 0:9158fe13dc14 386 int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t* packinfo)
xeon011 0:9158fe13dc14 387 {
xeon011 0:9158fe13dc14 388 uint8_t mr;
xeon011 0:9158fe13dc14 389 uint8_t head[8];
xeon011 0:9158fe13dc14 390 uint16_t pack_len=0;
xeon011 0:9158fe13dc14 391
xeon011 0:9158fe13dc14 392 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 393 //CHECK_SOCKMODE(Sn_MR_UDP);
xeon011 0:9158fe13dc14 394 switch((mr=getSn_MR(sn)) & 0x0F)
xeon011 0:9158fe13dc14 395 {
xeon011 0:9158fe13dc14 396 case Sn_MR_UDP:
xeon011 0:9158fe13dc14 397 case Sn_MR_MACRAW:
xeon011 0:9158fe13dc14 398 break;
xeon011 0:9158fe13dc14 399 #if ( _WIZCHIP_ < 5200 )
xeon011 0:9158fe13dc14 400 case Sn_MR_IPRAW:
xeon011 0:9158fe13dc14 401 case Sn_MR_PPPoE:
xeon011 0:9158fe13dc14 402 break;
xeon011 0:9158fe13dc14 403 #endif
xeon011 0:9158fe13dc14 404 default:
xeon011 0:9158fe13dc14 405 return SOCKERR_SOCKMODE;
xeon011 0:9158fe13dc14 406 }
xeon011 0:9158fe13dc14 407 CHECK_SOCKDATA();
xeon011 0:9158fe13dc14 408 if(sock_remained_size[sn] == 0)
xeon011 0:9158fe13dc14 409 {
xeon011 0:9158fe13dc14 410 while(1)
xeon011 0:9158fe13dc14 411 {
xeon011 0:9158fe13dc14 412 pack_len = getSn_RX_RSR(sn);
xeon011 0:9158fe13dc14 413 if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
xeon011 0:9158fe13dc14 414 if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
xeon011 0:9158fe13dc14 415 if(pack_len != 0) break;
xeon011 0:9158fe13dc14 416 };
xeon011 0:9158fe13dc14 417 }
xeon011 0:9158fe13dc14 418 *packinfo = 0x00;
xeon011 0:9158fe13dc14 419 switch (mr & 0x07)
xeon011 0:9158fe13dc14 420 {
xeon011 0:9158fe13dc14 421 case Sn_MR_UDP :
xeon011 0:9158fe13dc14 422 if(sock_remained_size[sn] == 0)
xeon011 0:9158fe13dc14 423 {
xeon011 0:9158fe13dc14 424 wiz_recv_data(sn, head, 8);
xeon011 0:9158fe13dc14 425 setSn_CR(sn,Sn_CR_RECV);
xeon011 0:9158fe13dc14 426 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 427 // read peer's IP address, port number & packet length
xeon011 0:9158fe13dc14 428 addr[0] = head[0];
xeon011 0:9158fe13dc14 429 addr[1] = head[1];
xeon011 0:9158fe13dc14 430 addr[2] = head[2];
xeon011 0:9158fe13dc14 431 addr[3] = head[3];
xeon011 0:9158fe13dc14 432 *port = head[4];
xeon011 0:9158fe13dc14 433 *port = (*port << 8) + head[5];
xeon011 0:9158fe13dc14 434 sock_remained_size[sn] = head[6];
xeon011 0:9158fe13dc14 435 sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
xeon011 0:9158fe13dc14 436 *packinfo = 0x80;
xeon011 0:9158fe13dc14 437 }
xeon011 0:9158fe13dc14 438 if(len < sock_remained_size[sn]) pack_len = len;
xeon011 0:9158fe13dc14 439 else pack_len = sock_remained_size[sn];
xeon011 0:9158fe13dc14 440 //
xeon011 0:9158fe13dc14 441 // Need to packet length check (default 1472)
xeon011 0:9158fe13dc14 442 //
xeon011 0:9158fe13dc14 443 wiz_recv_data(sn, buf, pack_len); // data copy.
xeon011 0:9158fe13dc14 444 break;
xeon011 0:9158fe13dc14 445 case Sn_MR_MACRAW :
xeon011 0:9158fe13dc14 446 if(sock_remained_size[sn] == 0)
xeon011 0:9158fe13dc14 447 {
xeon011 0:9158fe13dc14 448 wiz_recv_data(sn, head, 2);
xeon011 0:9158fe13dc14 449 setSn_CR(sn,Sn_CR_RECV);
xeon011 0:9158fe13dc14 450 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 451 // read peer's IP address, port number & packet length
xeon011 0:9158fe13dc14 452 sock_remained_size[sn] = head[0];
xeon011 0:9158fe13dc14 453 sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
xeon011 0:9158fe13dc14 454 if(sock_remained_size[sn] > 1514)
xeon011 0:9158fe13dc14 455 {
xeon011 0:9158fe13dc14 456 close(sn);
xeon011 0:9158fe13dc14 457 return SOCKFATAL_PACKLEN;
xeon011 0:9158fe13dc14 458 }
xeon011 0:9158fe13dc14 459 }
xeon011 0:9158fe13dc14 460 if(len < sock_remained_size[sn]) pack_len = len;
xeon011 0:9158fe13dc14 461 else pack_len = sock_remained_size[sn];
xeon011 0:9158fe13dc14 462 wiz_recv_data(sn,buf,pack_len);
xeon011 0:9158fe13dc14 463 break;
xeon011 0:9158fe13dc14 464 #if ( _WIZCHIP_ < 5200 )
xeon011 0:9158fe13dc14 465 case Sn_MR_IPRAW:
xeon011 0:9158fe13dc14 466 if(sock_remained_size[sn] == 0)
xeon011 0:9158fe13dc14 467 {
xeon011 0:9158fe13dc14 468 wiz_recv_data(sn, head, 6);
xeon011 0:9158fe13dc14 469 setSn_CR(sn,Sn_CR_RECV);
xeon011 0:9158fe13dc14 470 while(getSn_CR(sn));
xeon011 0:9158fe13dc14 471 addr[0] = head[0];
xeon011 0:9158fe13dc14 472 addr[1] = head[1];
xeon011 0:9158fe13dc14 473 addr[2] = head[2];
xeon011 0:9158fe13dc14 474 addr[3] = head[3];
xeon011 0:9158fe13dc14 475 sock_remained_size[sn] = head[4];
xeon011 0:9158fe13dc14 476 sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
xeon011 0:9158fe13dc14 477 *packinfo = 0x80;
xeon011 0:9158fe13dc14 478 }
xeon011 0:9158fe13dc14 479 //
xeon011 0:9158fe13dc14 480 // Need to packet length check
xeon011 0:9158fe13dc14 481 //
xeon011 0:9158fe13dc14 482 if(len < sock_remained_size[sn]) pack_len = len;
xeon011 0:9158fe13dc14 483 else pack_len = sock_remained_size[sn];
xeon011 0:9158fe13dc14 484 wiz_recv_data(sn, buf, pack_len); // data copy.
xeon011 0:9158fe13dc14 485 break;
xeon011 0:9158fe13dc14 486 #endif
xeon011 0:9158fe13dc14 487 default:
xeon011 0:9158fe13dc14 488 wiz_recv_ignore(sn, pack_len); // data copy.
xeon011 0:9158fe13dc14 489 sock_remained_size[sn] = pack_len;
xeon011 0:9158fe13dc14 490 break;
xeon011 0:9158fe13dc14 491 }
xeon011 0:9158fe13dc14 492 setSn_CR(sn,Sn_CR_RECV);
xeon011 0:9158fe13dc14 493 /* wait to process the command... */
xeon011 0:9158fe13dc14 494 while(getSn_CR(sn)) ;
xeon011 0:9158fe13dc14 495 sock_remained_size[sn] -= pack_len;
xeon011 0:9158fe13dc14 496 if(sock_remained_size[sn] != 0) *packinfo |= 0x01;
xeon011 0:9158fe13dc14 497 return pack_len;
xeon011 0:9158fe13dc14 498 }
xeon011 0:9158fe13dc14 499
xeon011 0:9158fe13dc14 500
xeon011 0:9158fe13dc14 501 int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
xeon011 0:9158fe13dc14 502 {
xeon011 0:9158fe13dc14 503 uint8_t tmp = 0;
xeon011 0:9158fe13dc14 504 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 505 switch(cstype)
xeon011 0:9158fe13dc14 506 {
xeon011 0:9158fe13dc14 507 case CS_SET_IOMODE:
xeon011 0:9158fe13dc14 508 tmp = *((uint8_t*)arg);
xeon011 0:9158fe13dc14 509 if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn);
xeon011 0:9158fe13dc14 510 else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
xeon011 0:9158fe13dc14 511 else return SOCKERR_ARG;
xeon011 0:9158fe13dc14 512 break;
xeon011 0:9158fe13dc14 513 case CS_GET_IOMODE:
xeon011 0:9158fe13dc14 514 *((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
xeon011 0:9158fe13dc14 515 break;
xeon011 0:9158fe13dc14 516 case CS_GET_MAXTXBUF:
xeon011 0:9158fe13dc14 517 *((uint16_t*)arg) = getSn_TxMAX(sn);
xeon011 0:9158fe13dc14 518 break;
xeon011 0:9158fe13dc14 519 case CS_GET_MAXRXBUF:
xeon011 0:9158fe13dc14 520 *((uint16_t*)arg) = getSn_RxMAX(sn);
xeon011 0:9158fe13dc14 521 break;
xeon011 0:9158fe13dc14 522 case CS_CLR_INTERRUPT:
xeon011 0:9158fe13dc14 523 if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
xeon011 0:9158fe13dc14 524 setSn_IR(sn,*(uint8_t*)arg);
xeon011 0:9158fe13dc14 525 break;
xeon011 0:9158fe13dc14 526 case CS_GET_INTERRUPT:
xeon011 0:9158fe13dc14 527 *((uint8_t*)arg) = getSn_IR(sn);
xeon011 0:9158fe13dc14 528 break;
xeon011 0:9158fe13dc14 529 case CS_SET_INTMASK:
xeon011 0:9158fe13dc14 530 if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
xeon011 0:9158fe13dc14 531 setSn_IMR(sn,*(uint8_t*)arg);
xeon011 0:9158fe13dc14 532 break;
xeon011 0:9158fe13dc14 533 case CS_GET_INTMASK:
xeon011 0:9158fe13dc14 534 *((uint8_t*)arg) = getSn_IMR(sn);
xeon011 0:9158fe13dc14 535 default:
xeon011 0:9158fe13dc14 536 return SOCKERR_ARG;
xeon011 0:9158fe13dc14 537 }
xeon011 0:9158fe13dc14 538 return SOCK_OK;
xeon011 0:9158fe13dc14 539 }
xeon011 0:9158fe13dc14 540
xeon011 0:9158fe13dc14 541 int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
xeon011 0:9158fe13dc14 542 {
xeon011 0:9158fe13dc14 543 uint8_t tmp;
xeon011 0:9158fe13dc14 544 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 545 switch(sotype)
xeon011 0:9158fe13dc14 546 {
xeon011 0:9158fe13dc14 547 case SO_TTL:
xeon011 0:9158fe13dc14 548 setSn_TTL(sn,*(uint8_t*)arg);
xeon011 0:9158fe13dc14 549 break;
xeon011 0:9158fe13dc14 550 case SO_TOS:
xeon011 0:9158fe13dc14 551 setSn_TOS(sn,*(uint8_t*)arg);
xeon011 0:9158fe13dc14 552 break;
xeon011 0:9158fe13dc14 553 case SO_MSS:
xeon011 0:9158fe13dc14 554 setSn_MSSR(sn,*(uint16_t*)arg);
xeon011 0:9158fe13dc14 555 break;
xeon011 0:9158fe13dc14 556 case SO_DESTIP:
xeon011 0:9158fe13dc14 557 setSn_DIPR(sn, (uint8_t*)arg);
xeon011 0:9158fe13dc14 558 break;
xeon011 0:9158fe13dc14 559 case SO_DESTPORT:
xeon011 0:9158fe13dc14 560 setSn_DPORT(sn, *(uint16_t*)arg);
xeon011 0:9158fe13dc14 561 break;
xeon011 0:9158fe13dc14 562 #if _WIZCHIP_ != 5100
xeon011 0:9158fe13dc14 563 case SO_KEEPALIVESEND:
xeon011 0:9158fe13dc14 564 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 565 #if _WIZCHIP_ > 5200
xeon011 0:9158fe13dc14 566 if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
xeon011 0:9158fe13dc14 567 #endif
xeon011 0:9158fe13dc14 568 setSn_CR(sn,Sn_CR_SEND_KEEP);
xeon011 0:9158fe13dc14 569 while((tmp = getSn_CR(sn)) != 0)
xeon011 0:9158fe13dc14 570 {
xeon011 0:9158fe13dc14 571 if (getSn_IR(sn) & Sn_IR_TIMEOUT)
xeon011 0:9158fe13dc14 572 {
xeon011 0:9158fe13dc14 573 setSn_IR(sn, Sn_IR_TIMEOUT);
xeon011 0:9158fe13dc14 574 return SOCKERR_TIMEOUT;
xeon011 0:9158fe13dc14 575 }
xeon011 0:9158fe13dc14 576 }
xeon011 0:9158fe13dc14 577 break;
xeon011 0:9158fe13dc14 578 #if _WIZCHIP_ > 5200
xeon011 0:9158fe13dc14 579 case SO_KEEPALIVEAUTO:
xeon011 0:9158fe13dc14 580 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 581 setSn_KPALVTR(sn,*(uint8_t*)arg);
xeon011 0:9158fe13dc14 582 break;
xeon011 0:9158fe13dc14 583 #endif
xeon011 0:9158fe13dc14 584 #endif
xeon011 0:9158fe13dc14 585 default:
xeon011 0:9158fe13dc14 586 return SOCKERR_ARG;
xeon011 0:9158fe13dc14 587 }
xeon011 0:9158fe13dc14 588 return SOCK_OK;
xeon011 0:9158fe13dc14 589 }
xeon011 0:9158fe13dc14 590
xeon011 0:9158fe13dc14 591 int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
xeon011 0:9158fe13dc14 592 {
xeon011 0:9158fe13dc14 593 CHECK_SOCKNUM();
xeon011 0:9158fe13dc14 594 switch(sotype)
xeon011 0:9158fe13dc14 595 {
xeon011 0:9158fe13dc14 596 case SO_FLAG:
xeon011 0:9158fe13dc14 597 *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
xeon011 0:9158fe13dc14 598 break;
xeon011 0:9158fe13dc14 599 case SO_TTL:
xeon011 0:9158fe13dc14 600 *(uint8_t*) arg = getSn_TTL(sn);
xeon011 0:9158fe13dc14 601 break;
xeon011 0:9158fe13dc14 602 case SO_TOS:
xeon011 0:9158fe13dc14 603 *(uint8_t*) arg = getSn_TOS(sn);
xeon011 0:9158fe13dc14 604 break;
xeon011 0:9158fe13dc14 605 case SO_MSS:
xeon011 0:9158fe13dc14 606 *(uint8_t*) arg = getSn_MSSR(sn);
xeon011 0:9158fe13dc14 607 case SO_DESTIP:
xeon011 0:9158fe13dc14 608 getSn_DIPR(sn, (uint8_t*)arg);
xeon011 0:9158fe13dc14 609 break;
xeon011 0:9158fe13dc14 610 case SO_DESTPORT:
xeon011 0:9158fe13dc14 611 *(uint16_t*) arg = getSn_DPORT(sn);
xeon011 0:9158fe13dc14 612 break;
xeon011 0:9158fe13dc14 613 #if _WIZCHIP_ > 5200
xeon011 0:9158fe13dc14 614 case SO_KEEPALIVEAUTO:
xeon011 0:9158fe13dc14 615 CHECK_SOCKMODE(Sn_MR_TCP);
xeon011 0:9158fe13dc14 616 *(uint16_t*) arg = getSn_KPALVTR(sn);
xeon011 0:9158fe13dc14 617 break;
xeon011 0:9158fe13dc14 618 #endif
xeon011 0:9158fe13dc14 619 case SO_SENDBUF:
xeon011 0:9158fe13dc14 620 *(uint16_t*) arg = getSn_TX_FSR(sn);
xeon011 0:9158fe13dc14 621 case SO_RECVBUF:
xeon011 0:9158fe13dc14 622 *(uint16_t*) arg = getSn_RX_RSR(sn);
xeon011 0:9158fe13dc14 623 case SO_STATUS:
xeon011 0:9158fe13dc14 624 *(uint8_t*) arg = getSn_SR(sn);
xeon011 0:9158fe13dc14 625 break;
xeon011 0:9158fe13dc14 626 case SO_REMAINSIZE:
xeon011 0:9158fe13dc14 627 if(getSn_MR(sn) == Sn_MR_TCP)
xeon011 0:9158fe13dc14 628 *(uint16_t*)arg = getSn_RX_RSR(sn);
xeon011 0:9158fe13dc14 629 else
xeon011 0:9158fe13dc14 630 *(uint16_t*)arg = sock_remained_size[sn];
xeon011 0:9158fe13dc14 631 break;
xeon011 0:9158fe13dc14 632 default:
xeon011 0:9158fe13dc14 633 return SOCKERR_SOCKOPT;
xeon011 0:9158fe13dc14 634 }
xeon011 0:9158fe13dc14 635 return SOCK_OK;
xeon011 0:9158fe13dc14 636 }