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