ioLibrary for Cortex M series
socket.c
Go to the documentation of this file.
1 
13 //#define FILE_LOG_SILENCE
14 #include "common/common.h"
15 
16 
17 static uint16_t local_port = 0xC000; // Dynamic Port: C000(49152) ~ FFFF(65535)
18 static uint16_t txrd_checker[_WIZCHIP_SOCK_NUM_];
19 static uint32_t tcp_resend_elapse[_WIZCHIP_SOCK_NUM_] = {0,};
21 
22 uint8_t incr_windowfull_retry_cnt(uint8_t s);
23 void init_windowfull_retry_cnt(uint8_t s);
24 
25 int8_t TCPServerOpen(uint8_t s, uint16_t port)
26 {
27  if(s > _WIZCHIP_SOCK_NUM_) {
28  ERRA("wrong socket number(%d)", s);
29  return SOCKERR_NOT_TCP;
30  } else DBG("start");
31 
32  if (port == 0) { // if don't set the source port, set local_port number.
33  if(local_port == 0xffff) local_port = 0xc000;
34  else local_port++;
35  port = local_port;
36  }
37 
38  TCPClose(s);
39  setSn_MR(s, Sn_MR_TCP);
40  setSn_PORT(s, port );
41  setSn_CR(s, Sn_CR_OPEN); // run sockinit Sn_CR
42  while(getSn_CR(s)); // wait to process the command...
43  DBGA("Sn_SR = %.2x , Protocol = %.2x", getSn_SR(s), getSn_MR(s));
44  if(getSn_SR(s) != SOCK_INIT) {
45  DBGA("wrong status(%d)", getSn_SR(s));
46  return SOCKERR_WRONG_STATUS;
47  } else {
49  while(getSn_CR(s)); // wait to process the command...
50  }
51  return RET_OK;
52 }
53 
54 int8_t TCPClientOpen(uint8_t s, uint16_t sport, uint8_t *dip, uint16_t dport)
55 {
56  int8_t ret;
57 
58  DBG("start");
59  ret = TCPCltOpenNB(s, sport, dip, dport);
60  if(ret != RET_OK) return ret;
61 
62  do {
63  ret = TCPConnChk(s);
64  } while(ret == SOCKERR_BUSY);
65 
66  return ret;
67 }
68 
69 int8_t TCPCltOpenNB(uint8_t s, uint16_t sport, uint8_t *dip, uint16_t dport)
70 {
71  uint8_t srcip[4], snmask[4];
72 
73  if(s > _WIZCHIP_SOCK_NUM_) {
74  ERRA("wrong socket number(%d)", s);
75  return SOCKERR_NOT_TCP;
76  } else if(dip == NULL) {
77  ERR("NULL Dst IP");
78  return SOCKERR_WRONG_ARG;
79  } else DBG("start");
80 
81  if (sport == 0) { // if don't set the source port, set local_port number.
82  if(local_port == 0xffff) local_port = 0xc000;
83  else local_port++;
84  sport = local_port;
85  }
86 
87  TCPClose(s);
88  setSn_MR(s, Sn_MR_TCP);
89  setSn_PORT(s, sport);
90  setSn_CR(s, Sn_CR_OPEN); // run sockinit Sn_CR
91  while(getSn_CR(s)); // wait to process the command...
92  DBGA("Sn_SR = %.2x , Protocol = %.2x", getSn_SR(s), getSn_SR(s));
93 
94  getSIPR(srcip);
95  getSUBR(snmask);
96 
97  if( ((dip[0] == 0xFF) && (dip[1] == 0xFF) &&
98  (dip[2] == 0xFF) && (dip[3] == 0xFF)) ||
99  ((dip[0] == 0x00) && (dip[1] == 0x00) &&
100  (dip[2] == 0x00) && (dip[3] == 0x00)) || (sport == 0x00) )
101  {
102  DBG("invalid ip or port");
103  DBGA("SOCK(%d)-[%02x.%02x.%02x.%02x, %d]",s,
104  dip[0], dip[1], dip[2], dip[3] , sport);
105  return SOCKERR_WRONG_ARG;
106  }
107  else if( (srcip[0]==0 && srcip[1]==0 && srcip[2]==0 && srcip[3]==0) &&
108  (snmask[0]!=0 || snmask[1]!=0 || snmask[2]!=0 || snmask[3]!=0) ) //Mikej : ARP Errata
109  {
110  DBG("Source IP is NULL while SN Mask is Not NULL");
111  return SOCKERR_NULL_SRC_IP;
112  }
113  else
114  {
115  setSn_DIPR(s, dip); // set destination IP
116  setSn_DPORT(s, dport);
117  //SetSubnet(sn); // for ARP Errata
119  while (getSn_CR(s)); // wait for completion
120  }
121 
122  return RET_OK;
123 }
124 
125 int8_t TCPConnChk(uint8_t s)
126 {
127  uint8_t socksr;
128 
129  if(s > _WIZCHIP_SOCK_NUM_) {
130  ERRA("wrong socket number(%d)", s);
131  return SOCKERR_NOT_TCP;
132  }
133 
134  socksr = getSn_SR(s);
135 
136  if(socksr == SOCK_ESTABLISHED) {
137  //ClearSubnet(); // for ARP Errata
138  return RET_OK;
139  } else if(getSn_IR(s) & Sn_IR_TIMEOUT) {
140  setSn_IR(s, Sn_IR_TIMEOUT); // clear TIMEOUT Interrupt
141 
142  //ClearSubnet(); // for ARP Errata
143  return SOCKERR_TIME_OUT;
144  }
145 
146  return SOCKERR_BUSY;
147 }
148 
149 int8_t TCPDisconnect(uint8_t s)
150 {
151  ERR("Not implemented yet");
152  return RET_NOK;
153 #if 0
154  if(s > _WIZCHIP_SOCK_NUM_) {
155  ERRA("wrong socket number(%d)", s);
156  return SOCKERR_NOT_TCP;
157  } else DBG("start");
158 
160  while(getSn_CR(s)); // wait to process the command...
161  return RET_OK;
162 #endif
163 }
164 
165 int8_t TCPClose(uint8_t s)
166 {
167  int8_t ret;
168 
169  DBG("start");
170  ret = TCPCloseNB(s);
171  if(ret != RET_OK) return ret;
172 
173  do {
174  ret = TCPCloseCHK(s);
175  } while(ret == SOCKERR_BUSY);
176 
177  return ret;
178 }
179 
180 int8_t TCPCloseNB(uint8_t s)
181 {
182  uint8_t status;
183 
184  if(s > _WIZCHIP_SOCK_NUM_) {
185  ERRA("wrong socket number(%d)", s);
186  return SOCKERR_NOT_TCP;
187  } else DBG("start");
189  while(getSn_CR(s)); // wait to process the command...
190  status = getSn_SR(s);
191  if(status == SOCK_CLOSED) return SOCKERR_WRONG_STATUS;
192 
193  return RET_OK;
194 }
195 
196 int8_t TCPCloseCHK(uint8_t s)
197 {
198 #define TIMEOUT_CLOSE_WAIT 200
199  uint8_t status;
200 
201  if(s > _WIZCHIP_SOCK_NUM_) {
202  ERRA("wrong socket number(%d)", s);
203  return SOCKERR_NOT_TCP;
204  } else DBG("start");
205 
206  status = getSn_SR(s);
207  if(status == SOCK_CLOSED) goto END_OK;
208 
209  setSn_CR(s, Sn_CR_CLOSE);
210  while(getSn_CR(s)); // wait to process the command...
211 
212 END_OK:
213  setSn_IR(s, 0xFF); // interrupt all clear
214  return RET_OK;
215 }
216 
217 int8_t TCPClsRcvCHK(uint8_t s)
218 {
219 #define TIMEOUT_CLOSE_WAIT 200
220  uint8_t status;
221 
222  if(s > _WIZCHIP_SOCK_NUM_) {
223  ERRA("wrong socket number(%d)", s);
224  return SOCKERR_NOT_TCP;
225  }
226 
227  status = getSn_SR(s);
228  if(status == SOCK_CLOSED) goto END_OK;
229  if(status == SOCK_CLOSE_WAIT) {
230  setSn_CR(s, Sn_CR_CLOSE);
231  while(getSn_CR(s)); // wait to process the command...
232  } else return SOCKERR_BUSY;
233 
234 END_OK:
235  setSn_IR(s,0xFF); // interrupt all clear
236  return RET_OK;
237 }
238 
239 int32_t TCPSend(uint8_t s, const int8_t *buf, uint16_t len)
240 {
241  int32_t ret;
242 
243  while(1) {
244  ret = TCPSendNB(s, buf, len);
245  if(ret == RET_OK) break;
246  if(ret != SOCKERR_BUSY) return ret;
247  }
248 
249  while(1) {
250  ret = TCPSendCHK(s);
251  if(ret >= 0 || ret != SOCKERR_BUSY) break;
252  }
253 
254  return ret;
255 }
256 
257 int8_t TCPSendNB(uint8_t s, const int8_t *buf, uint16_t len)
258 {
259  uint8_t status = 0;
260 
261  if(s > _WIZCHIP_SOCK_NUM_) {
262  ERRA("wrong socket number(%d)", s);
263  return SOCKERR_NOT_TCP;
264  } else if(len == 0) {
265  ERR("Zero length");
266  return SOCKERR_WRONG_ARG;
267  } else DBG("start");
268 
269  status = getSn_SR(s);
270  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
271  if((getSn_MR(s) & 0x0F) != Sn_MR_TCP) return SOCKERR_NOT_TCP;
272 
273  if(status == SOCK_FIN_WAIT) return SOCKERR_FIN_WAIT;
274  if(status != SOCK_ESTABLISHED && status != SOCK_CLOSE_WAIT) return SOCKERR_NOT_ESTABLISHED;
275 
277  if(len > getSn_TxMAX(s)) len = getSn_TxMAX(s); // check size not to exceed MAX size.
278  if(GetSocketTxFreeBufferSize(s) < len) return SOCKERR_BUSY;
279 
280  wiz_send_data(s, (uint8_t*)buf, len);
281  txrd_checker[s] = getSn_TX_RD(s);
282 
283  setSn_CR(s,Sn_CR_SEND);
284  while (getSn_CR(s)); // wait to process the command...
285 
286  return RET_OK;
287 }
288 
289 int32_t TCPReSend(uint8_t s)
290 {
291  int32_t ret;
292 
293  while(1) {
294  ret = TCPReSendNB(s);
295  if(ret == RET_OK) break;
296  if(ret != SOCKERR_BUSY) return ret;
297  }
298 
299  while(1) {
300  ret = TCPSendCHK(s);
301  if(ret >= 0 || ret != SOCKERR_BUSY) break;
302  }
303 
304  return ret;
305 }
306 
307 int8_t TCPReSendNB(uint8_t s)
308 {
309  uint8_t status=0;
310 
311  if(s > _WIZCHIP_SOCK_NUM_) {
312  ERRA("wrong socket number(%d)", s);
313  return SOCKERR_NOT_TCP;
314  } else DBG("start");
315 
316  status = getSn_SR(s);
317  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
318  if((getSn_MR(s) & 0x0F) != Sn_MR_TCP) return SOCKERR_NOT_TCP;
319 
320  if(status == SOCK_FIN_WAIT) return SOCKERR_FIN_WAIT;
321  if(status != SOCK_ESTABLISHED && status != SOCK_CLOSE_WAIT) return SOCKERR_NOT_ESTABLISHED;
322 
323  status = incr_windowfull_retry_cnt(s);
324  if(status == 1) tcp_resend_elapse[s] = wizpf_get_systick();
325  else if(status > WINDOWFULL_MAX_RETRY_NUM) return SOCKERR_WINDOW_FULL;
326  else if(wizpf_tick_elapse(tcp_resend_elapse[s]) < WINDOWFULL_WAIT_TIME)
327  return SOCKERR_BUSY;
328 
329  txrd_checker[s] = getSn_TX_RD(s);
330  setSn_CR(s, Sn_CR_SEND);
331  while (getSn_CR(s)); // wait to process the command...
332 
333  return RET_OK;
334 }
335 
336 int32_t TCPSendCHK(uint8_t s)
337 {
338  uint16_t txrd;
339 
340  if(!(getSn_IR(s) & Sn_IR_SENDOK)) {
341  if(getSn_SR(s) == SOCK_CLOSED) {
342 
343  DBG("SOCK_CLOSED");
344  TCPClose(s);
345  return SOCKERR_CLOSED;
346  }
347  return SOCKERR_BUSY;
348  } else setSn_IR(s, Sn_IR_SENDOK);
349  txrd = getSn_TX_RD(s);
350  if(txrd > txrd_checker[s]) return txrd - txrd_checker[s];
351  else return (0xffff - txrd_checker[s]) + txrd + 1;
352 }
353 
354 int32_t TCPRecv(uint8_t s, int8_t *buf, uint16_t len)
355 {
356  uint8_t status = 0;
357  uint16_t RSR_len = 0;
358 
359  if(s > _WIZCHIP_SOCK_NUM_) {
360  ERRA("wrong socket number(%d)", s);
361  return SOCKERR_NOT_TCP;
362  } else if(len == 0) {
363  ERR("Zero length");
364  return SOCKERR_WRONG_ARG;
365  }
366 
367  RSR_len = GetSocketRxRecvBufferSize(s); // Check Receive Buffer
368  if(RSR_len == 0){
369  status = getSn_SR(s);
370  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
371  if((getSn_MR(s) & 0x0F) != Sn_MR_TCP) return SOCKERR_NOT_TCP;
372 
373  if(status == SOCK_CLOSE_WAIT) return SOCKERR_CLOSE_WAIT;
374  if(status != SOCK_ESTABLISHED && status != SOCK_CLOSE_WAIT) return SOCKERR_NOT_ESTABLISHED;
375  } else {
376  if(len < RSR_len) RSR_len = len;
377  wiz_recv_data(s, (uint8_t*)buf, RSR_len);
378  setSn_CR(s, Sn_CR_RECV);
379  while(getSn_CR(s)); // wait to process the command...
380  }
381 
382  return RSR_len;
383 }
384 
385 int8_t UDPOpen(uint8_t s, uint16_t port)
386 {
387  if(s > _WIZCHIP_SOCK_NUM_) {
388  ERRA("wrong socket number(%d)", s);
389  return SOCKERR_NOT_UDP;
390  } else DBG("start");
391 
392  if (port == 0) { // if don't set the source port, set local_port number.
393  if(local_port == 0xffff) local_port = 0xc000;
394  else local_port++;
395  port = local_port;
396  }
397 
398  UDPClose(s);
399 
400  setSn_MR(s, Sn_MR_UDP);
401  setSn_PORT(s, port);
402  setSn_CR(s, Sn_CR_OPEN); // run sockinit Sn_CR
403  while(getSn_CR(s)); // wait to process the command...
404  DBGA("Sn_SR = %.2x , Protocol = %.2x", getSn_SR(s), getSn_MR(s));
405 
406 
407  return RET_OK;
408 }
409 
410 int8_t UDPClose(uint8_t s)
411 {
412  if(s > _WIZCHIP_SOCK_NUM_) {
413  ERRA("wrong socket number(%d)", s);
414  return SOCKERR_NOT_UDP;
415  } else DBG("start");
416 
417  setSn_CR(s, Sn_CR_CLOSE);
418  while(getSn_CR(s)); // wait to process the command...
419  setSn_IR(s, 0xFF); // interrupt all clear
420 
421  return RET_OK;
422 }
423 
424 int32_t UDPSend(uint8_t s, const int8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
425 {
426  int32_t ret = 0;
427 
428  ret = UDPSendNB(s, buf, len, addr, port);
429  if(ret < RET_OK) return ret;
430  else len = ret;
431 
432  do {
433  ret = UDPSendCHK(s);
434  if(ret == RET_OK) return len;
435  if(ret != SOCKERR_BUSY) return ret;
436  } while(1);
437 }
438 
439 int32_t UDPSendNB(uint8_t s, const int8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
440 {
441  uint8_t srcip[4], snmask[4], status = 0;
442 
443  if(s > _WIZCHIP_SOCK_NUM_) {
444  ERRA("wrong socket number(%d)", s);
445  return SOCKERR_NOT_UDP;
446  } else if(len == 0 || addr == NULL) {
447  if(len == 0) ERR("Zero length");
448  else ERR("NULL Dst IP");
449  return SOCKERR_WRONG_ARG;
450  } else DBG("start");
451 
452  status = getSn_SR(s);
453  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
454  if((getSn_MR(s) & 0x0F) != Sn_MR_UDP) return SOCKERR_NOT_UDP;
455  if(status != SOCK_UDP) return SOCKERR_NOT_UDP;
456 
457  if (len > getSn_TxMAX(s)) len = getSn_TxMAX(s); // check size not to exceed MAX size.
458 
459  getSIPR(srcip);
460  getSUBR(snmask);
461 
462  if((addr[0]==0x00 && addr[1]==0x00 && addr[2]==0x00 &&
463  addr[3]==0x00) || (port==0x00))
464  {
465  DBG("invalid ip or port");
466  DBGA("SOCK(%d)-[%02x.%02x.%02x.%02x, %d, %d]",s,
467  addr[0], addr[1], addr[2], addr[3] , port, len);
468  return SOCKERR_WRONG_ARG;
469  }
470  else if( (srcip[0]==0 && srcip[1]==0 && srcip[2]==0 && srcip[3]==0) &&
471  (snmask[0]!=0 || snmask[1]!=0 || snmask[2]!=0 || snmask[3]!=0) ) //Mikej : ARP Errata
472  {
473  DBG("Source IP is NULL while SN Mask is Not NULL");
474  return SOCKERR_NULL_SRC_IP;
475  }
476  else
477  {
478  setSn_DIPR(s, addr);
479  setSn_DPORT(s, port);
480 
481  wiz_send_data(s, (uint8_t*)buf, len);
482  //SetSubnet(sn); // for ARP Errata
483 
484  setSn_CR(s, Sn_CR_SEND);
485  while(getSn_CR(s)); // wait to process the command...
486  }
487 
488  return len;
489 }
490 
491 int8_t UDPSendCHK(uint8_t s)
492 {
493  uint8_t ir = getSn_IR(s);
494 
495 
496  if(!(ir & Sn_IR_SENDOK)) {
497  if(ir & Sn_IR_TIMEOUT) {
498  DBG("send fail");
499  setSn_IR(s, (Sn_IR_SENDOK | Sn_IR_TIMEOUT)); // clear SEND_OK & TIMEOUT Interrupt
500  return SOCKERR_TIME_OUT;
501  }
502  return SOCKERR_BUSY;
503  } else setSn_IR(s, Sn_IR_SENDOK);
504  //ClearSubnet(); // for ARP Errata
505 
506  return RET_OK;
507 }
508 
509 int32_t UDPRecv(uint8_t s, int8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port)
510 {
511  uint8_t prebuf[8], status = 0;
512  uint16_t tmp_len = 0, RSR_len = 0;
513 
514  if(s > _WIZCHIP_SOCK_NUM_) {
515  ERRA("wrong socket number(%d)", s);
516  return SOCKERR_NOT_UDP;
517  } else if(len == 0) {
518  ERR("Zero length");
519  return SOCKERR_WRONG_ARG;
520  }
521 
522  status = getSn_SR(s);
523  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
524  if((getSn_MR(s) & 0x0F) != Sn_MR_UDP) return SOCKERR_NOT_UDP;
525  if(status != SOCK_UDP) return SOCKERR_NOT_UDP;
526 
527  RSR_len = GetSocketRxRecvBufferSize(s); // Check Receive Buffer of W5500
528  if(RSR_len < 8) {
529  DBGA("wrong data received (%d)", RSR_len);
530  wiz_recv_ignore(s, RSR_len);
531  setSn_CR(s, Sn_CR_RECV);
532  while(getSn_CR(s));
533 
534  return SOCKERR_NOT_SPECIFIED;
535  } else {
536  wiz_recv_data(s, prebuf, 8);
537  setSn_CR(s, Sn_CR_RECV); // µ¥ÀÌÅ͸¦ ó¸®ÇÑ ÈÄ À̰ÍÀ» ÇØÁà¾ß Àû¿ëµÊ
538 
539  if(addr) { // read peer's IP address, port number.
540  addr[0] = prebuf[0];
541  addr[1] = prebuf[1];
542  addr[2] = prebuf[2];
543  addr[3] = prebuf[3];
544  }
545  if(port) {
546  *port = prebuf[4];
547  *port = (*port << 8) + prebuf[5];
548  }
549  tmp_len = prebuf[6];
550  tmp_len = (tmp_len << 8) + prebuf[7];
551  while(getSn_CR(s)); // IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV); ¸í·É ÈÄ ÇØ¾ßÇÔ, ½Ã°£ ¹ú·Á°í ¹Ù·Î ¾ÈÇÔ
552 
553  DBGA("UDP Recv - addr(%d.%d.%d.%d:%d), t(%d), R(%d)",
554  addr[0], addr[1], addr[2], addr[3], *port, tmp_len, RSR_len);
555  if(tmp_len == 0) {
556  ERR("UDP Recv len Zero - remove rest all");
557  setSn_CR(s,Sn_CR_RECV);
558  while(getSn_CR(s));
559  return SOCKERR_NOT_SPECIFIED;
560  }
561  RSR_len = tmp_len;
562  }
563 
564  if(len < RSR_len) {
565  tmp_len = RSR_len - len;
566  RSR_len = len;
567  DBGA("Recv buffer not enough - len(%d)", len);
568  } else tmp_len = 0;
569 
570  switch (getSn_MR(s) & 0x07)
571  {
572  case Sn_MR_UDP:
573  wiz_recv_data(s, (uint8_t*)buf, RSR_len);
574  setSn_CR(s, Sn_CR_RECV);
575 
576  if(tmp_len) {
577  while(getSn_CR(s));
578  DBG("Ignore rest data");
579  wiz_recv_ignore(s, tmp_len);
580  setSn_CR(s, Sn_CR_RECV);
581  while(getSn_CR(s));
582  tmp_len = GetSocketRxRecvBufferSize(s);
583  if(tmp_len) DBGA("another rest data(%d)", tmp_len);
584  else DBG("No rest data");
585  }
586  break;
587  //case Sn_MR_IPRAW:
588  case Sn_MR_MACRAW:
589  default :
590  break;
591  }
592  while(getSn_CR(s));
593 
594  return RSR_len;
595 }
596 
597 
598 uint8_t incr_windowfull_retry_cnt(uint8_t s)
599 {
600  return ++windowfull_retry_cnt[s];
601 }
602 
604 {
605  windowfull_retry_cnt[s] = 0;
606 }
607 
608 
609