Socket APIs
socket.c
Go to the documentation of this file.
1 //*****************************************************************************
2 //
44 //
45 //*****************************************************************************
46 #include "socket.h"
47 
48 #define SOCK_ANY_PORT_NUM 0xC000;
49 
50 static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
51 static uint16_t sock_io_mode = 0;
52 static uint16_t sock_is_sending = 0;
53 static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
54 static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
55 
56 #if _WIZCHIP_ == 5200
57  static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
58 #endif
59 
60 #define CHECK_SOCKNUM() \
61  do{ \
62  if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
63  }while(0); \
64 
65 #define CHECK_SOCKMODE(mode) \
66  do{ \
67  if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
68  }while(0); \
69 
70 #define CHECK_SOCKINIT() \
71  do{ \
72  if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
73  }while(0); \
74 
75 #define CHECK_SOCKDATA() \
76  do{ \
77  if(len == 0) return SOCKERR_DATALEN; \
78  }while(0); \
79 
80 
81 
82 int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
83 {
84  CHECK_SOCKNUM();
85  switch(protocol)
86  {
87  case Sn_MR_TCP :
88  case Sn_MR_UDP :
89  case Sn_MR_MACRAW :
90 // case Sn_MR_IPRAW :
91 // break;
92 // #if ( _WIZCHIP_ < 5200 )
93  case Sn_MR_IPRAW :
94  // case Sn_MR_PPPoE :
95  break;
96 // #endif
97  default :
98  return SOCKERR_SOCKMODE;
99  }
100  if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
101 //#if _WIZCHIP_ == 5200
102  if(flag & 0x10) return SOCKERR_SOCKFLAG;
103 //#endif
104 
105  if(flag != 0)
106  {
107  switch(protocol)
108  {
109  case Sn_MR_TCP:
110  if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
111  break;
112  case Sn_MR_UDP:
113  if(flag & SF_IGMP_VER2)
114  {
115  if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
116  }
117  #if _WIZCHIP_ == 5500
118  if(flag & SF_UNI_BLOCK)
119  {
120  if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
121  }
122  #endif
123  break;
124  default:
125  break;
126  }
127  }
128  close(sn);
129  setSn_MR(sn, (protocol | (flag & 0xF0)));
130  if(!port)
131  {
132  port = sock_any_port++;
133  if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
134  }
135  setSn_PORT(sn,port);
136  setSn_CR(sn,Sn_CR_OPEN);
137  while(getSn_CR(sn));
138  sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
139  sock_is_sending &= ~(1<<sn);
140  sock_remained_size[sn] = 0;
141  sock_pack_info[sn] = 0;
142  while(getSn_SR(sn) == SOCK_CLOSED);
143  return (int8_t)sn;
144 }
145 
146 int8_t close(uint8_t sn)
147 {
148  CHECK_SOCKNUM();
149 
150  setSn_CR(sn,Sn_CR_CLOSE);
151  /* wait to process the command... */
152  while( getSn_CR(sn) );
153  /* clear all interrupt of the socket. */
154  setSn_IR(sn, 0xFF);
155  sock_is_sending &= ~(1<<sn);
156  sock_remained_size[sn] = 0;
157  sock_pack_info[sn] = 0;
158  while(getSn_SR(sn) != SOCK_CLOSED);
159  return SOCK_OK;
160 }
161 
162 int8_t listen(uint8_t sn)
163 {
164  CHECK_SOCKNUM();
166  CHECK_SOCKINIT();
168  while(getSn_CR(sn));
169  while(getSn_SR(sn) != SOCK_LISTEN)
170  {
171  if(getSn_CR(sn) == SOCK_CLOSED)
172  {
173  close(sn);
174  return SOCKERR_SOCKCLOSED;
175  }
176  }
177  return SOCK_OK;
178 }
179 
180 
181 int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
182 {
183  CHECK_SOCKNUM();
185  CHECK_SOCKINIT();
186  if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
187  if(port == 0) return SOCKERR_PORTZERO;
188  setSn_DIPR(sn,addr);
189  setSn_DPORT(sn,port);
190  #if _WIZCHIP_ == 5200 // for W5200 ARP errata
191  setSUBR(0);
192  #endif
194  while(getSn_CR(sn));
195  if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
196  while(getSn_SR(sn) != SOCK_ESTABLISHED)
197  {
198  if (getSn_IR(sn) & Sn_IR_TIMEOUT)
199  {
200  setSn_IR(sn, Sn_IR_TIMEOUT);
201  #if _WIZCHIP_ == 5200 // for W5200 ARP errata
202  setSUBR((uint8_t*)"\x00\x00\x00\x00");
203  #endif
204  return SOCKERR_TIMEOUT;
205  }
206  }
207  #if _WIZCHIP_ == 5200 // for W5200 ARP errata
208  setSUBR((uint8_t*)"\x00\x00\x00\x00");
209  #endif
210 
211  return SOCK_OK;
212 }
213 
214 int8_t disconnect(uint8_t sn)
215 {
216  CHECK_SOCKNUM();
219  /* wait to process the command... */
220  while(getSn_CR(sn));
221  sock_is_sending &= ~(1<<sn);
222  if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
223  while(getSn_SR(sn) != SOCK_CLOSED)
224  {
225  if(getSn_IR(sn) & Sn_IR_TIMEOUT)
226  {
227  close(sn);
228  return SOCKERR_TIMEOUT;
229  }
230  }
231  return SOCK_OK;
232 }
233 
234 int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
235 {
236  uint8_t tmp=0;
237  uint16_t freesize=0;
238 
239  CHECK_SOCKNUM();
241  CHECK_SOCKDATA();
242  tmp = getSn_SR(sn);
243  if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
244  if( sock_is_sending & (1<<sn) )
245  {
246  tmp = getSn_IR(sn);
247  if(tmp & Sn_IR_SENDOK)
248  {
249  setSn_IR(sn, Sn_IR_SENDOK);
250  #if _WZICHIP_ == 5200
251  if(getSn_TX_RD(sn) != sock_next_rd[sn])
252  {
253  setSn_CR(sn,Sn_CR_SEND);
254  while(getSn_CR(sn));
255  return SOCKERR_BUSY;
256  }
257  #endif
258  sock_is_sending &= ~(1<<sn);
259  }
260  else if(tmp & Sn_IR_TIMEOUT)
261  {
262  close(sn);
263  return SOCKERR_TIMEOUT;
264  }
265  else return SOCK_BUSY;
266  }
267  freesize = getSn_TxMAX(sn);
268  if (len > freesize) len = freesize; // check size not to exceed MAX size.
269  while(1)
270  {
271  freesize = getSn_TX_FSR(sn);
272  tmp = getSn_SR(sn);
273  if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
274  {
275  close(sn);
276  return SOCKERR_SOCKSTATUS;
277  }
278  if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
279  if(len <= freesize) break;
280  }
281  wiz_send_data(sn, buf, len);
282  #if _WIZCHIP_ == 5200
283  sock_next_rd[sn] = getSn_TX_RD(sn) + len;
284  #endif
285  setSn_CR(sn,Sn_CR_SEND);
286  /* wait to process the command... */
287  while(getSn_CR(sn));
288  sock_is_sending |= (1 << sn);
289  return len;
290 }
291 
292 
293 int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
294 {
295  uint8_t tmp = 0;
296  uint16_t recvsize = 0;
297  CHECK_SOCKNUM();
299  CHECK_SOCKDATA();
300 
301  recvsize = getSn_RxMAX(sn);
302  if(recvsize < len) len = recvsize;
303  while(1)
304  {
305  recvsize = getSn_RX_RSR(sn);
306  tmp = getSn_SR(sn);
307  if (tmp != SOCK_ESTABLISHED)
308  {
309  if(tmp == SOCK_CLOSE_WAIT)
310  {
311  if(recvsize != 0) break;
312  else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
313  {
314  close(sn);
315  return SOCKERR_SOCKSTATUS;
316  }
317  }
318  else
319  {
320  close(sn);
321  return SOCKERR_SOCKSTATUS;
322  }
323  }
324  if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
325  if(recvsize != 0) break;
326  };
327  if(recvsize < len) len = recvsize;
328  wiz_recv_data(sn, buf, len);
329  setSn_CR(sn,Sn_CR_RECV);
330  while(getSn_CR(sn));
331  return len;
332 }
333 
334 int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
335 {
336  uint8_t tmp = 0;
337  uint16_t freesize = 0;
338  CHECK_SOCKNUM();
339  switch(getSn_MR(sn) & 0x0F)
340  {
341  case Sn_MR_UDP:
342  case Sn_MR_IPRAW:
343  case Sn_MR_MACRAW:
344  break;
345  default:
346  return SOCKERR_SOCKMODE;
347  }
348  CHECK_SOCKDATA();
349  if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
350  if(port == 0) return SOCKERR_PORTZERO;
351  tmp = getSn_SR(sn);
352  if(tmp != SOCK_MACRAW && tmp != SOCK_UDP && tmp != SOCK_IPRAW ) return SOCKERR_SOCKSTATUS;
353 
354  setSn_DIPR(sn,addr);
355  setSn_DPORT(sn,port);
356  freesize = getSn_TxMAX(sn);
357  if (len > freesize) len = freesize; // check size not to exceed MAX size.
358  while(1)
359  {
360  freesize = getSn_TX_FSR(sn);
361  if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
362  if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
363  if(len <= freesize) break;
364  };
365  wiz_send_data(sn, buf, len);
366 
367  #if _WIZCHIP_ == 5200 // for W5200 ARP errata
368  setSUBR(0);
369  #endif
370 
371  setSn_CR(sn,Sn_CR_SEND);
372  /* wait to process the command... */
373  while(getSn_CR(sn));
374  #if _WIZCHIP_ == 5200 // for W5200 ARP errata
375  setSUBR((uint8_t*)"\x00\x00\x00\x00");
376  #endif
377  while(1)
378  {
379  tmp = getSn_IR(sn);
380  if(tmp & Sn_IR_SENDOK)
381  {
382  setSn_IR(sn, Sn_IR_SENDOK);
383  break;
384  }
385  //M:20131104
386  //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
387  else if(tmp & Sn_IR_TIMEOUT)
388  {
389  setSn_IR(sn, Sn_IR_TIMEOUT);
390  return SOCKERR_TIMEOUT;
391  }
393  }
394  return len;
395 }
396 
397 
398 
399 int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
400 {
401  uint8_t mr;
402  uint8_t head[8];
403  uint16_t pack_len=0;
404 
405  CHECK_SOCKNUM();
406  //CHECK_SOCKMODE(Sn_MR_UDP);
407  switch((mr=getSn_MR(sn)) & 0x0F)
408  {
409  case Sn_MR_UDP:
410  case Sn_MR_IPRAW:
411  case Sn_MR_MACRAW:
412  break;
413  #if ( _WIZCHIP_ < 5200 )
414  case Sn_MR_PPPoE:
415  break;
416  #endif
417  default:
418  return SOCKERR_SOCKMODE;
419  }
420  CHECK_SOCKDATA();
421  if(sock_remained_size[sn] == 0)
422  {
423  while(1)
424  {
425  pack_len = getSn_RX_RSR(sn);
426  if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
427  if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
428  if(pack_len != 0) break;
429 
430  };
431  }
432  sock_pack_info[sn] = PACK_COMPLETED;
433  switch (mr & 0x07)
434  {
435  case Sn_MR_UDP :
436  if(sock_remained_size[sn] == 0)
437  {
438  wiz_recv_data(sn, head, 8);
439  setSn_CR(sn,Sn_CR_RECV);
440  while(getSn_CR(sn));
441  // read peer's IP address, port number & packet length
442  addr[0] = head[0];
443  addr[1] = head[1];
444  addr[2] = head[2];
445  addr[3] = head[3];
446  *port = head[4];
447  *port = (*port << 8) + head[5];
448  sock_remained_size[sn] = head[6];
449  sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
450  sock_pack_info[sn] = PACK_FIRST;
451  }
452  if(len < sock_remained_size[sn]) pack_len = len;
453  else pack_len = sock_remained_size[sn];
454  //
455  // Need to packet length check (default 1472)
456  //
457  wiz_recv_data(sn, buf, pack_len); // data copy.
458  break;
459  case Sn_MR_MACRAW :
460  if(sock_remained_size[sn] == 0)
461  {
462  wiz_recv_data(sn, head, 2);
463  setSn_CR(sn,Sn_CR_RECV);
464  while(getSn_CR(sn));
465  // read peer's IP address, port number & packet length
466  sock_remained_size[sn] = head[0];
467  sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
468  if(sock_remained_size[sn] > 1514)
469  {
470  close(sn);
471  return SOCKFATAL_PACKLEN;
472  }
473  sock_pack_info[sn] = PACK_FIRST;
474  }
475  if(len < sock_remained_size[sn]) pack_len = len;
476  else pack_len = sock_remained_size[sn];
477  wiz_recv_data(sn,buf,pack_len);
478  break;
479  // #if ( _WIZCHIP_ < 5200 )
480  case Sn_MR_IPRAW:
481  if(sock_remained_size[sn] == 0)
482  {
483  wiz_recv_data(sn, head, 6);
484  setSn_CR(sn,Sn_CR_RECV);
485  while(getSn_CR(sn));
486  addr[0] = head[0];
487  addr[1] = head[1];
488  addr[2] = head[2];
489  addr[3] = head[3];
490  sock_remained_size[sn] = head[4];
491  sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
492  sock_pack_info[sn] = PACK_FIRST;
493  }
494  //
495  // Need to packet length check
496  //
497 
498  if(len < sock_remained_size[sn]) pack_len = len;
499  else pack_len = sock_remained_size[sn];
500  wiz_recv_data(sn, buf, pack_len); // data copy.
501  break;
502 // #endif
503  default:
504  wiz_recv_ignore(sn, pack_len); // data copy.
505  sock_remained_size[sn] = pack_len;
506  break;
507  }
508  setSn_CR(sn,Sn_CR_RECV);
509  /* wait to process the command... */
510  while(getSn_CR(sn)) ;
511  sock_remained_size[sn] -= pack_len;
512  if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
513  return pack_len;
514 }
515 
516 
517 int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
518 {
519  uint8_t tmp = 0;
520  CHECK_SOCKNUM();
521  switch(cstype)
522  {
523  case CS_SET_IOMODE:
524  tmp = *((uint8_t*)arg);
525  if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn);
526  else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
527  else return SOCKERR_ARG;
528  break;
529  case CS_GET_IOMODE:
530  *((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
531  break;
532  case CS_GET_MAXTXBUF:
533  *((uint16_t*)arg) = getSn_TxMAX(sn);
534  break;
535  case CS_GET_MAXRXBUF:
536  *((uint16_t*)arg) = getSn_RxMAX(sn);
537  break;
538  case CS_CLR_INTERRUPT:
539  if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
540  setSn_IR(sn,*(uint8_t*)arg);
541  break;
542  case CS_GET_INTERRUPT:
543  *((uint8_t*)arg) = getSn_IR(sn);
544  break;
545  case CS_SET_INTMASK:
546  if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
547  setSn_IMR(sn,*(uint8_t*)arg);
548  break;
549  case CS_GET_INTMASK:
550  *((uint8_t*)arg) = getSn_IMR(sn);
551  default:
552  return SOCKERR_ARG;
553  }
554  return SOCK_OK;
555 }
556 
557 int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
558 {
559  // M20131220 : Remove warning
560  //uint8_t tmp;
561  CHECK_SOCKNUM();
562  switch(sotype)
563  {
564  case SO_TTL:
565  setSn_TTL(sn,*(uint8_t*)arg);
566  break;
567  case SO_TOS:
568  setSn_TOS(sn,*(uint8_t*)arg);
569  break;
570  case SO_MSS:
571  setSn_MSSR(sn,*(uint16_t*)arg);
572  break;
573  case SO_DESTIP:
574  setSn_DIPR(sn, (uint8_t*)arg);
575  break;
576  case SO_DESTPORT:
577  setSn_DPORT(sn, *(uint16_t*)arg);
578  break;
579 #if _WIZCHIP_ != 5100
580  case SO_KEEPALIVESEND:
582  #if _WIZCHIP_ > 5200
583  if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
584  #endif
586  while(getSn_CR(sn) != 0)
587  {
588  // M20131220
589  //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
590  if (getSn_IR(sn) & Sn_IR_TIMEOUT)
591  {
592  setSn_IR(sn, Sn_IR_TIMEOUT);
593  return SOCKERR_TIMEOUT;
594  }
595  }
596  break;
597  #if _WIZCHIP_ > 5200
598  case SO_KEEPALIVEAUTO:
600  setSn_KPALVTR(sn,*(uint8_t*)arg);
601  break;
602  #endif
603 #endif
604  default:
605  return SOCKERR_ARG;
606  }
607  return SOCK_OK;
608 }
609 
610 int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
611 {
612  CHECK_SOCKNUM();
613  switch(sotype)
614  {
615  case SO_FLAG:
616  *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
617  break;
618  case SO_TTL:
619  *(uint8_t*) arg = getSn_TTL(sn);
620  break;
621  case SO_TOS:
622  *(uint8_t*) arg = getSn_TOS(sn);
623  break;
624  case SO_MSS:
625  *(uint8_t*) arg = getSn_MSSR(sn);
626  case SO_DESTIP:
627  getSn_DIPR(sn, (uint8_t*)arg);
628  break;
629  case SO_DESTPORT:
630  *(uint16_t*) arg = getSn_DPORT(sn);
631  break;
632  #if _WIZCHIP_ > 5200
633  case SO_KEEPALIVEAUTO:
635  *(uint16_t*) arg = getSn_KPALVTR(sn);
636  break;
637  #endif
638  case SO_SENDBUF:
639  *(uint16_t*) arg = getSn_TX_FSR(sn);
640  case SO_RECVBUF:
641  *(uint16_t*) arg = getSn_RX_RSR(sn);
642  case SO_STATUS:
643  *(uint8_t*) arg = getSn_SR(sn);
644  break;
645  case SO_REMAINSIZE:
646  if(getSn_MR(sn) == Sn_MR_TCP)
647  *(uint16_t*)arg = getSn_RX_RSR(sn);
648  else
649  *(uint16_t*)arg = sock_remained_size[sn];
650  break;
651  case SO_PACKINFO:
653  *(uint8_t*)arg = sock_pack_info[sn];
654  break;
655  default:
656  return SOCKERR_SOCKOPT;
657  }
658  return SOCK_OK;
659 }