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