source: ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.c @ 106

Last change on this file since 106 was 79, checked in by Zed, 3 months ago

DHCP client can get IP-address from fritz!box

File size: 25.4 KB
Line 
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//!       <2015/02/05> Notice
10//!        The version history is not updated after this point.
11//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
12//!        >> https://github.com/Wiznet/ioLibrary_Driver
13//!       <2014/05/01> V1.0.3. Refer to M20140501
14//!         1. Implicit type casting -> Explicit type casting.
15//!         2. replace 0x01 with PACK_REMAINED in recvfrom()
16//!         3. Validation a destination ip in connect() & sendto():
17//!            It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
18//!            Copy 4 byte addr value into temporary uint32 variable and then compares it.
19//!       <2013/12/20> V1.0.2 Refer to M20131220
20//!                    Remove Warning.
21//!       <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
22//!                    In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
23//!       <2013/10/21> 1st Release
24//! \author MidnightCow
25//! \copyright
26//!
27//! Copyright (c)  2013, WIZnet Co., LTD.
28//! All rights reserved.
29//!
30//! Redistribution and use in source and binary forms, with or without
31//! modification, are permitted provided that the following conditions
32//! are met:
33//!
34//!     * Redistributions of source code must retain the above copyright
35//! notice, this list of conditions and the following disclaimer.
36//!     * Redistributions in binary form must reproduce the above copyright
37//! notice, this list of conditions and the following disclaimer in the
38//! documentation and/or other materials provided with the distribution.
39//!     * Neither the name of the <ORGANIZATION> nor the names of its
40//! contributors may be used to endorse or promote products derived
41//! from this software without specific prior written permission.
42//!
43//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
44//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
47//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
53//! THE POSSIBILITY OF SUCH DAMAGE.
54//
55//*****************************************************************************
56#include "socket.h"
57
58//M20150401 : Typing Error
59//#define SOCK_ANY_PORT_NUM  0xC000;
60#define SOCK_ANY_PORT_NUM  0xC000
61
62static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
63static uint16_t sock_io_mode = 0;
64static uint16_t sock_is_sending = 0;
65
66static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
67
68//M20150601 : For extern decleation
69//static uint8_t  sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
70uint8_t  sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
71//
72
73#if _WIZCHIP_ == 5200
74   static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
75#endif
76
77//A20150601 : For integrating with W5300
78#if _WIZCHIP_ == 5300
79   uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data()
80#endif
81
82
83#define CHECK_SOCKNUM()   \
84   do{                    \
85      if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM;   \
86   }while(0);             \
87
88#define CHECK_SOCKMODE(mode)  \
89   do{                     \
90      if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE;  \
91   }while(0);              \
92
93#define CHECK_SOCKINIT()   \
94   do{                     \
95      if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
96   }while(0);              \
97
98#define CHECK_SOCKDATA()   \
99   do{                     \
100      if(len == 0) return SOCKERR_DATALEN;   \
101   }while(0);              \
102
103
104
105int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
106{
107        CHECK_SOCKNUM();
108        switch(protocol)
109        {
110                case Sn_MR_TCP :
111                        {
112                                //M20150601 : Fixed the warning - taddr will never be NULL
113                                /*
114                                uint8_t taddr[4];
115                                getSIPR(taddr);
116                                */
117                                uint32_t taddr;
118                                getSIPR((uint8_t*)&taddr);
119                                if(taddr == 0) return SOCKERR_SOCKINIT;
120                                break;
121                        }
122                case Sn_MR_UDP :
123                case Sn_MR_MACRAW :
124                case Sn_MR_IPRAW :
125                        break;
126#if ( _WIZCHIP_ < 5200 )
127                case Sn_MR_PPPoE :
128                        break;
129#endif
130                default :
131                        return SOCKERR_SOCKMODE;
132        }
133        //M20150601 : For SF_TCP_ALIGN & W5300
134        //if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
135        if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG;
136#if _WIZCHIP_ == 5200
137        if(flag & 0x10) return SOCKERR_SOCKFLAG;
138#endif
139
140        if(flag != 0)
141        {
142                switch(protocol)
143                {
144                        case Sn_MR_TCP:
145                                //M20150601 :  For SF_TCP_ALIGN & W5300
146#if _WIZCHIP_ == 5300
147                                if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG;
148#else
149                                if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
150#endif
151
152                                break;
153                        case Sn_MR_UDP:
154                                if(flag & SF_IGMP_VER2)
155                                {
156                                        if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
157                                }
158#if _WIZCHIP_ == 5500
159                                if(flag & SF_UNI_BLOCK)
160                                {
161                                        if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
162                                }
163#endif
164                                break;
165                        default:
166                                break;
167                }
168        }
169        close(sn);
170        //M20150601
171#if _WIZCHIP_ == 5300
172        setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) );
173#else
174        setSn_MR(sn, (protocol | (flag & 0xF0)));
175#endif
176        if(!port)
177        {
178                port = sock_any_port++;
179                if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
180        }
181        setSn_PORT(sn,port);
182        setSn_CR(sn,Sn_CR_OPEN);
183        while(getSn_CR(sn));
184        //A20150401 : For release the previous sock_io_mode
185        sock_io_mode &= ~(1 <<sn);
186        //
187        sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
188        sock_is_sending &= ~(1<<sn);
189        sock_remained_size[sn] = 0;
190        //M20150601 : repalce 0 with PACK_COMPLETED
191        //sock_pack_info[sn] = 0;
192        sock_pack_info[sn] = PACK_COMPLETED;
193        //
194        while(getSn_SR(sn) == SOCK_CLOSED);
195        return (int8_t)sn;
196}
197
198int8_t close(uint8_t sn)
199{
200        CHECK_SOCKNUM();
201//A20160426 : Applied the erratum 1 of W5300
202#if   (_WIZCHIP_ == 5300)
203   //M20160503 : Wrong socket parameter. s -> sn
204   //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
205   if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )
206   {
207      uint8_t destip[4] = {0, 0, 0, 1};
208      // TODO
209      // You can wait for completing to sending data;
210      // wait about 1 second;
211      // if you have completed to send data, skip the code of erratum 1
212      // ex> wait_1s();
213      //     if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
214      //
215      //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
216      //socket(s,Sn_MR_UDP,0x3000,0);
217      //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
218      setSn_MR(sn,Sn_MR_UDP);
219      setSn_PORTR(sn, 0x3000);
220      setSn_CR(sn,Sn_CR_OPEN);
221      while(getSn_CR(sn) != 0);
222      while(getSn_SR(sn) != SOCK_UDP);
223      sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
224   };
225#endif
226        setSn_CR(sn,Sn_CR_CLOSE);
227   /* wait to process the command... */
228        while( getSn_CR(sn) );
229        /* clear all interrupt of the socket. */
230        setSn_IR(sn, 0xFF);
231        //A20150401 : Release the sock_io_mode of socket n.
232        sock_io_mode &= ~(1<<sn);
233        //
234        sock_is_sending &= ~(1<<sn);
235        sock_remained_size[sn] = 0;
236        sock_pack_info[sn] = 0;
237        while(getSn_SR(sn) != SOCK_CLOSED);
238        return SOCK_OK;
239}
240
241int8_t listen(uint8_t sn)
242{
243        CHECK_SOCKNUM();
244   CHECK_SOCKMODE(Sn_MR_TCP);
245        CHECK_SOCKINIT();
246        setSn_CR(sn,Sn_CR_LISTEN);
247        while(getSn_CR(sn));
248   while(getSn_SR(sn) != SOCK_LISTEN)
249   {
250         close(sn);
251         return SOCKERR_SOCKCLOSED;
252   }
253   return SOCK_OK;
254}
255
256
257int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
258{
259   CHECK_SOCKNUM();
260   CHECK_SOCKMODE(Sn_MR_TCP);
261   CHECK_SOCKINIT();
262   //M20140501 : For avoiding fatal error on memory align mismatched
263   //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
264   {
265      uint32_t taddr;
266      taddr = ((uint32_t)addr[0] & 0x000000FF);
267      taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
268      taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
269      taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
270      if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
271   }
272   //
273
274        if(port == 0) return SOCKERR_PORTZERO;
275        setSn_DIPR(sn,addr);
276        setSn_DPORT(sn,port);
277        setSn_CR(sn,Sn_CR_CONNECT);
278   while(getSn_CR(sn));
279   if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
280   while(getSn_SR(sn) != SOCK_ESTABLISHED)
281   {
282                if (getSn_IR(sn) & Sn_IR_TIMEOUT)
283                {
284                        setSn_IR(sn, Sn_IR_TIMEOUT);
285            return SOCKERR_TIMEOUT;
286                }
287
288                if (getSn_SR(sn) == SOCK_CLOSED)
289                {
290                        return SOCKERR_SOCKCLOSED;
291                }
292        }
293
294   return SOCK_OK;
295}
296
297int8_t disconnect(uint8_t sn)
298{
299   CHECK_SOCKNUM();
300   CHECK_SOCKMODE(Sn_MR_TCP);
301        setSn_CR(sn,Sn_CR_DISCON);
302        /* wait to process the command... */
303        while(getSn_CR(sn));
304        sock_is_sending &= ~(1<<sn);
305   if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
306        while(getSn_SR(sn) != SOCK_CLOSED)
307        {
308           if(getSn_IR(sn) & Sn_IR_TIMEOUT)
309           {
310              close(sn);
311              return SOCKERR_TIMEOUT;
312           }
313        }
314        return SOCK_OK;
315}
316
317int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
318{
319   uint8_t tmp=0;
320   uint16_t freesize=0;
321
322   CHECK_SOCKNUM();
323   CHECK_SOCKMODE(Sn_MR_TCP);
324   CHECK_SOCKDATA();
325   tmp = getSn_SR(sn);
326   if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
327   if( sock_is_sending & (1<<sn) )
328   {
329      tmp = getSn_IR(sn);
330      if(tmp & Sn_IR_SENDOK)
331      {
332         setSn_IR(sn, Sn_IR_SENDOK);
333         //M20150401 : Typing Error
334         //#if _WZICHIP_ == 5200
335         #if _WIZCHIP_ == 5200
336            if(getSn_TX_RD(sn) != sock_next_rd[sn])
337            {
338               setSn_CR(sn,Sn_CR_SEND);
339               while(getSn_CR(sn));
340               return SOCK_BUSY;
341            }
342         #endif
343         sock_is_sending &= ~(1<<sn);
344      }
345      else if(tmp & Sn_IR_TIMEOUT)
346      {
347         close(sn);
348         return SOCKERR_TIMEOUT;
349      }
350      else return SOCK_BUSY;
351   }
352   freesize = getSn_TxMAX(sn);
353   if (len > freesize) len = freesize; // check size not to exceed MAX size.
354   while(1)
355   {
356      freesize = getSn_TX_FSR(sn);
357      tmp = getSn_SR(sn);
358      if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
359      {
360         close(sn);
361         return SOCKERR_SOCKSTATUS;
362      }
363      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
364      if(len <= freesize) break;
365   }
366   wiz_send_data(sn, buf, len);
367   #if _WIZCHIP_ == 5200
368      sock_next_rd[sn] = getSn_TX_RD(sn) + len;
369   #endif
370
371   #if _WIZCHIP_ == 5300
372      setSn_TX_WRSR(sn,len);
373   #endif
374
375   setSn_CR(sn,Sn_CR_SEND);
376   /* wait to process the command... */
377   while(getSn_CR(sn));
378   sock_is_sending |= (1 << sn);
379   //M20150409 : Explicit Type Casting
380   //return len;
381   return (int32_t)len;
382}
383
384
385int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
386{
387   uint8_t  tmp = 0;
388   uint16_t recvsize = 0;
389//A20150601 : For integarating with W5300
390#if   _WIZCHIP_ == 5300
391   uint8_t head[2];
392   uint16_t mr;
393#endif
394//
395   CHECK_SOCKNUM();
396   CHECK_SOCKMODE(Sn_MR_TCP);
397   CHECK_SOCKDATA();
398
399   recvsize = getSn_RxMAX(sn);
400   if(recvsize < len) len = recvsize;
401
402//A20150601 : For Integrating with W5300
403#if _WIZCHIP_ == 5300
404   //sock_pack_info[sn] = PACK_COMPLETED;    // for clear
405   if(sock_remained_size[sn] == 0)
406   {
407#endif
408//
409      while(1)
410      {
411         recvsize = getSn_RX_RSR(sn);
412         tmp = getSn_SR(sn);
413         if (tmp != SOCK_ESTABLISHED)
414         {
415            if(tmp == SOCK_CLOSE_WAIT)
416            {
417               if(recvsize != 0) break;
418               else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
419               {
420                  close(sn);
421                  return SOCKERR_SOCKSTATUS;
422               }
423            }
424            else
425            {
426               close(sn);
427               return SOCKERR_SOCKSTATUS;
428            }
429         }
430         if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
431         if(recvsize != 0) break;
432      };
433#if _WIZCHIP_ == 5300
434   }
435#endif
436
437//A20150601 : For integrating with W5300
438#if _WIZCHIP_ == 5300
439   if((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN))
440   {
441      mr = getMR();
442      if((getSn_MR(sn) & Sn_MR_ALIGN)==0)
443      {
444         wiz_recv_data(sn,head,2);
445         if(mr & MR_FS)
446            recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]);
447         else
448            recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]);
449         sock_pack_info[sn] = PACK_FIRST;
450      }
451      sock_remained_size[sn] = recvsize;
452   }
453   if(len > sock_remained_size[sn]) len = sock_remained_size[sn];
454   recvsize = len;
455   if(sock_pack_info[sn] & PACK_FIFOBYTE)
456   {
457      *buf = sock_remained_byte[sn];
458      buf++;
459      sock_pack_info[sn] &= ~(PACK_FIFOBYTE);
460      recvsize -= 1;
461      sock_remained_size[sn] -= 1;
462   }
463   if(recvsize != 0)
464   {
465      wiz_recv_data(sn, buf, recvsize);
466      setSn_CR(sn,Sn_CR_RECV);
467      while(getSn_CR(sn));
468   }
469   sock_remained_size[sn] -= recvsize;
470   if(sock_remained_size[sn] != 0)
471   {
472      sock_pack_info[sn] |= PACK_REMAINED;
473      if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE;
474   }
475   else sock_pack_info[sn] = PACK_COMPLETED;
476   if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0;
477   //len = recvsize;
478#else
479   if(recvsize < len) len = recvsize;
480   wiz_recv_data(sn, buf, len);
481   setSn_CR(sn,Sn_CR_RECV);
482   while(getSn_CR(sn));
483#endif
484
485   //M20150409 : Explicit Type Casting
486   //return len;
487   return (int32_t)len;
488}
489
490int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
491{
492   uint8_t tmp = 0;
493   uint16_t freesize = 0;
494   uint32_t taddr;
495
496   CHECK_SOCKNUM();
497   switch(getSn_MR(sn) & 0x0F)
498   {
499      case Sn_MR_UDP:
500      case Sn_MR_MACRAW:
501//         break;
502//   #if ( _WIZCHIP_ < 5200 )
503      case Sn_MR_IPRAW:
504         break;
505//   #endif
506      default:
507         return SOCKERR_SOCKMODE;
508   }
509   CHECK_SOCKDATA();
510   //M20140501 : For avoiding fatal error on memory align mismatched
511   //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
512   //{
513      //uint32_t taddr;
514      taddr = ((uint32_t)addr[0]) & 0x000000FF;
515      taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
516      taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
517      taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
518   //}
519   //
520   //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
521   if((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_IPINVALID;
522   if((port  == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_PORTZERO;
523   tmp = getSn_SR(sn);
524//#if ( _WIZCHIP_ < 5200 )
525   if((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) return SOCKERR_SOCKSTATUS;
526//#else
527//   if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
528//#endif
529
530   setSn_DIPR(sn,addr);
531   setSn_DPORT(sn,port);
532   freesize = getSn_TxMAX(sn);
533   if (len > freesize) len = freesize; // check size not to exceed MAX size.
534   while(1)
535   {
536      freesize = getSn_TX_FSR(sn);
537      if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
538      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
539      if(len <= freesize) break;
540   };
541        wiz_send_data(sn, buf, len);
542
543   #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
544      getSIPR((uint8_t*)&taddr);
545      if(taddr == 0)
546      {
547         getSUBR((uint8_t*)&taddr);
548         setSUBR((uint8_t*)"\x00\x00\x00\x00");
549      }
550      else taddr = 0;
551   #endif
552
553//A20150601 : For W5300
554#if _WIZCHIP_ == 5300
555   setSn_TX_WRSR(sn, len);
556#endif
557//
558        setSn_CR(sn,Sn_CR_SEND);
559        /* wait to process the command... */
560        while(getSn_CR(sn));
561   while(1)
562   {
563      tmp = getSn_IR(sn);
564      if(tmp & Sn_IR_SENDOK)
565      {
566         setSn_IR(sn, Sn_IR_SENDOK);
567         break;
568      }
569      //M:20131104
570      //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
571      else if(tmp & Sn_IR_TIMEOUT)
572      {
573         setSn_IR(sn, Sn_IR_TIMEOUT);
574         //M20150409 : Fixed the lost of sign bits by type casting.
575         //len = (uint16_t)SOCKERR_TIMEOUT;
576         //break;
577         #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
578            if(taddr) setSUBR((uint8_t*)&taddr);
579         #endif
580         return SOCKERR_TIMEOUT;
581      }
582      ////////////
583   }
584   #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
585      if(taddr) setSUBR((uint8_t*)&taddr);
586   #endif
587   //M20150409 : Explicit Type Casting
588   //return len;
589   return (int32_t)len;
590}
591
592
593
594int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
595{
596//M20150601 : For W5300
597#if _WIZCHIP_ == 5300
598        uint16_t mr;
599        uint16_t mr1;
600#else
601        uint8_t  mr;
602#endif
603//
604        uint8_t  head[8];
605        uint16_t pack_len=0;
606
607        CHECK_SOCKNUM();
608        //CHECK_SOCKMODE(Sn_MR_UDP);
609//A20150601
610#if _WIZCHIP_ == 5300
611        mr1 = getMR();
612#endif
613
614        switch((mr = getSn_MR(sn)) & 0x0F)
615        {
616                case Sn_MR_UDP:
617                case Sn_MR_IPRAW:
618                case Sn_MR_MACRAW:
619                        break;
620#if ( _WIZCHIP_ < 5200 )
621                case Sn_MR_PPPoE:
622                        break;
623#endif
624                default:
625                        return SOCKERR_SOCKMODE;
626        }
627
628        CHECK_SOCKDATA();
629
630        if(sock_remained_size[sn] == 0)
631        {
632                while(1)
633                {
634                        pack_len = getSn_RX_RSR(sn);
635                        if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
636                        if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
637                        if(pack_len != 0) break;
638                };
639        }
640
641//D20150601 : Move it to bottom
642// sock_pack_info[sn] = PACK_COMPLETED;
643
644        switch (mr & 0x07)
645        {
646                case Sn_MR_UDP :
647                        if(sock_remained_size[sn] == 0)
648                        {
649                                wiz_recv_data(sn, head, 8);
650                                setSn_CR(sn,Sn_CR_RECV);
651                                while(getSn_CR(sn));
652                                // read peer's IP address, port number & packet length
653                                //A20150601 : For W5300
654#if _WIZCHIP_ == 5300
655                                if(mr1 & MR_FS)
656                                {
657                                        addr[0] = head[1];
658                            addr[1] = head[0];
659                            addr[2] = head[3];
660                            addr[3] = head[2];
661                            *port = head[5];
662                            *port = (*port << 8) + head[4];
663                                        sock_remained_size[sn] = head[7];
664                                        sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6];
665                                }
666                                else
667                                {
668#endif
669                                        addr[0] = head[0];
670                                        addr[1] = head[1];
671                                        addr[2] = head[2];
672                                        addr[3] = head[3];
673                                        *port = head[4];
674                                        *port = (*port << 8) + head[5];
675                                        sock_remained_size[sn] = head[6];
676                                        sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
677#if _WIZCHIP_ == 5300
678                                }
679#endif
680                                sock_pack_info[sn] = PACK_FIRST;
681                        }
682
683                        if(len < sock_remained_size[sn]) pack_len = len;
684                        else pack_len = sock_remained_size[sn];
685                        //A20150601 : For W5300
686                        len = pack_len;
687#if _WIZCHIP_ == 5300
688                        if(sock_pack_info[sn] & PACK_FIFOBYTE)
689                        {
690                                *buf++ = sock_remained_byte[sn];
691                            pack_len -= 1;
692                            sock_remained_size[sn] -= 1;
693                            sock_pack_info[sn] &= ~PACK_FIFOBYTE;
694                        }
695#endif
696                        //
697                        // Need to packet length check (default 1472)
698                        //
699                        wiz_recv_data(sn, buf, pack_len); // data copy.
700                        break;
701
702                case Sn_MR_MACRAW :
703                        if(sock_remained_size[sn] == 0)
704                        {
705                                wiz_recv_data(sn, head, 2);
706                                setSn_CR(sn,Sn_CR_RECV);
707                                while(getSn_CR(sn));
708                                // read peer's IP address, port number & packet length
709                        sock_remained_size[sn] = head[0];
710                                sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1] -2;
711#if _WIZCHIP_ == W5300
712                                if(sock_remained_size[sn] & 0x01)
713                                        sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4;
714                                else
715                                        sock_remained_size[sn] -= 4;
716#endif
717                                if(sock_remained_size[sn] > 1514)
718                                {
719                                        close(sn);
720                                        return SOCKFATAL_PACKLEN;
721                                }
722                                sock_pack_info[sn] = PACK_FIRST;
723                        }
724                        if(len < sock_remained_size[sn]) pack_len = len;
725                        else pack_len = sock_remained_size[sn];
726                        wiz_recv_data(sn,buf,pack_len);
727                        break;
728//#if ( _WIZCHIP_ < 5200 )
729                case Sn_MR_IPRAW:
730                        if(sock_remained_size[sn] == 0)
731                        {
732                                wiz_recv_data(sn, head, 6);
733                                setSn_CR(sn,Sn_CR_RECV);
734                                while(getSn_CR(sn));
735                                addr[0] = head[0];
736                                addr[1] = head[1];
737                                addr[2] = head[2];
738                                addr[3] = head[3];
739                                sock_remained_size[sn] = head[4];
740                                //M20150401 : For Typing Error
741                                //sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
742                                sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
743                                sock_pack_info[sn] = PACK_FIRST;
744                        }
745                        //
746                        // Need to packet length check
747                        //
748                        if(len < sock_remained_size[sn]) pack_len = len;
749                        else pack_len = sock_remained_size[sn];
750                        wiz_recv_data(sn, buf, pack_len); // data copy.
751                        break;
752//#endif
753                default:
754                        wiz_recv_ignore(sn, pack_len); // data copy.
755                        sock_remained_size[sn] = pack_len;
756                        break;
757        }
758        setSn_CR(sn,Sn_CR_RECV);
759        /* wait to process the command... */
760        while(getSn_CR(sn)) ;
761        sock_remained_size[sn] -= pack_len;
762        //M20150601 :
763        //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
764        if(sock_remained_size[sn] != 0)
765        {
766                sock_pack_info[sn] |= PACK_REMAINED;
767#if _WIZCHIP_ == 5300
768                if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE;
769#endif
770        }
771        else sock_pack_info[sn] = PACK_COMPLETED;
772#if _WIZCHIP_ == 5300
773        pack_len = len;
774#endif
775        //
776        //M20150409 : Explicit Type Casting
777        //return pack_len;
778        return (int32_t)pack_len;
779}
780
781
782int8_t  ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
783{
784   uint8_t tmp = 0;
785   CHECK_SOCKNUM();
786   switch(cstype)
787   {
788      case CS_SET_IOMODE:
789         tmp = *((uint8_t*)arg);
790         if(tmp == SOCK_IO_NONBLOCK)  sock_io_mode |= (1<<sn);
791         else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
792         else return SOCKERR_ARG;
793         break;
794      case CS_GET_IOMODE:
795         //M20140501 : implict type casting -> explict type casting
796         //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
797         *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
798         //
799         break;
800      case CS_GET_MAXTXBUF:
801         *((uint16_t*)arg) = getSn_TxMAX(sn);
802         break;
803      case CS_GET_MAXRXBUF:
804         *((uint16_t*)arg) = getSn_RxMAX(sn);
805         break;
806      case CS_CLR_INTERRUPT:
807         if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
808         setSn_IR(sn,*(uint8_t*)arg);
809         break;
810      case CS_GET_INTERRUPT:
811         *((uint8_t*)arg) = getSn_IR(sn);
812         break;
813   #if _WIZCHIP_ != 5100
814      case CS_SET_INTMASK:
815         if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
816         setSn_IMR(sn,*(uint8_t*)arg);
817         break;
818      case CS_GET_INTMASK:
819         *((uint8_t*)arg) = getSn_IMR(sn);
820         break;
821   #endif
822      default:
823         return SOCKERR_ARG;
824   }
825   return SOCK_OK;
826}
827
828int8_t  setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
829{
830 // M20131220 : Remove warning
831 //uint8_t tmp;
832   CHECK_SOCKNUM();
833   switch(sotype)
834   {
835      case SO_TTL:
836         setSn_TTL(sn,*(uint8_t*)arg);
837         break;
838      case SO_TOS:
839         setSn_TOS(sn,*(uint8_t*)arg);
840         break;
841      case SO_MSS:
842         setSn_MSSR(sn,*(uint16_t*)arg);
843         break;
844      case SO_DESTIP:
845         setSn_DIPR(sn, (uint8_t*)arg);
846         break;
847      case SO_DESTPORT:
848         setSn_DPORT(sn, *(uint16_t*)arg);
849         break;
850#if _WIZCHIP_ != 5100
851      case SO_KEEPALIVESEND:
852         CHECK_SOCKMODE(Sn_MR_TCP);
853         #if _WIZCHIP_ > 5200
854            if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
855         #endif
856            setSn_CR(sn,Sn_CR_SEND_KEEP);
857            while(getSn_CR(sn) != 0)
858            {
859               // M20131220
860                        //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
861               if (getSn_IR(sn) & Sn_IR_TIMEOUT)
862                        {
863                                setSn_IR(sn, Sn_IR_TIMEOUT);
864                  return SOCKERR_TIMEOUT;
865                        }
866            }
867         break;
868   #if !( (_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200) )
869      case SO_KEEPALIVEAUTO:
870         CHECK_SOCKMODE(Sn_MR_TCP);
871         setSn_KPALVTR(sn,*(uint8_t*)arg);
872         break;
873   #endif
874#endif
875      default:
876         return SOCKERR_ARG;
877   }
878   return SOCK_OK;
879}
880
881int8_t  getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
882{
883   CHECK_SOCKNUM();
884   switch(sotype)
885   {
886      case SO_FLAG:
887         *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
888         break;
889      case SO_TTL:
890         *(uint8_t*) arg = getSn_TTL(sn);
891         break;
892      case SO_TOS:
893         *(uint8_t*) arg = getSn_TOS(sn);
894         break;
895      case SO_MSS:
896         *(uint16_t*) arg = getSn_MSSR(sn);
897         break;
898      case SO_DESTIP:
899         getSn_DIPR(sn, (uint8_t*)arg);
900         break;
901      case SO_DESTPORT:
902         *(uint16_t*) arg = getSn_DPORT(sn);
903         break;
904   #if _WIZCHIP_ > 5200
905      case SO_KEEPALIVEAUTO:
906         CHECK_SOCKMODE(Sn_MR_TCP);
907         *(uint16_t*) arg = getSn_KPALVTR(sn);
908         break;
909   #endif
910      case SO_SENDBUF:
911         *(uint16_t*) arg = getSn_TX_FSR(sn);
912         break;
913      case SO_RECVBUF:
914         *(uint16_t*) arg = getSn_RX_RSR(sn);
915         break;
916      case SO_STATUS:
917         *(uint8_t*) arg = getSn_SR(sn);
918         break;
919      case SO_REMAINSIZE:
920         if(getSn_MR(sn) & Sn_MR_TCP)
921            *(uint16_t*)arg = getSn_RX_RSR(sn);
922         else
923            *(uint16_t*)arg = sock_remained_size[sn];
924         break;
925      case SO_PACKINFO:
926         //CHECK_SOCKMODE(Sn_MR_TCP);
927#if _WIZCHIP_ != 5300
928         if((getSn_MR(sn) == Sn_MR_TCP))
929             return SOCKERR_SOCKMODE;
930#endif
931         *(uint8_t*)arg = sock_pack_info[sn];
932         break;
933      default:
934         return SOCKERR_SOCKOPT;
935   }
936   return SOCK_OK;
937}
Note: See TracBrowser for help on using the repository browser.