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