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