WIZlib Library API  ver 1.0
WIZlib Library API User Menual
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
w5200/socket.c
Go to the documentation of this file.
1 
12 //#define FILE_LOG_SILENCE
13 #include "common/common.h"
14 //#include "device/socket.h"
15 
16 
17 extern uint8 I_STATUS[TOTAL_SOCK_NUM];
18 extern uint16 SMASK[TOTAL_SOCK_NUM]; // Variable for Tx buffer MASK in each channel
19 extern uint16 RMASK[TOTAL_SOCK_NUM]; // Variable for Rx buffer MASK in each channel
20 extern uint16 SSIZE[TOTAL_SOCK_NUM]; // Max Tx buffer size by each channel
21 extern uint16 RSIZE[TOTAL_SOCK_NUM]; // Max Rx buffer size by each channel
22 extern uint16 SBUFBASEADDRESS[TOTAL_SOCK_NUM]; // Tx buffer base address by each channel
23 extern uint16 RBUFBASEADDRESS[TOTAL_SOCK_NUM]; // Rx buffer base address by each channel
24 
25 static uint8 DNS[4]={0};
26 static dhcp_mode DHCP = NETINFO_STATIC;
27 static uint16 local_port = 0xC000; // Dynamic Port: C000(49152) ~ FFFF(65535)
28 
29 static uint32 tcp_close_elapse[TOTAL_SOCK_NUM] = {0,};
30 static uint32 tcp_resend_elapse[TOTAL_SOCK_NUM] = {0,};
31 static uint16 txrd_checker[TOTAL_SOCK_NUM];
32 
33 
34 void device_init(uint8 *tx_size, uint8 *rx_size)
35 {
37  device_mem_init(tx_size, rx_size);
38 }
39 
40 void device_SW_reset(void)
41 {
42  setMR(MR_RST);
43  DBGA("MR value is %02x", IINCHIP_READ(WIZC_MR));
44 }
45 
46 void device_mem_init(uint8 *tx_size, uint8 *rx_size)
47 {
48  int16 i, mul;
49  int16 ssum, rsum;
50 
51  DBG("device_mem_init()");
52 
53  ssum = 0;
54  rsum = 0;
55  SBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_TXBUF__); // Set base address of Tx memory for channel #0
56  RBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_RXBUF__); // Set base address of Rx memory for channel #0
57 
58  for (i=0; i<TOTAL_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel
59  {
60  IINCHIP_WRITE((Sn_TXMEM_SIZE(i)),tx_size[i]);
61  IINCHIP_WRITE((Sn_RXMEM_SIZE(i)),rx_size[i]);
62 
63  DBGA("Sn_TXMEM_SIZE = %d, Sn_RXMEM_SIZE = %d",
64  IINCHIP_READ(Sn_TXMEM_SIZE(i)), IINCHIP_READ(Sn_RXMEM_SIZE(i)));
65 
66  SSIZE[i] = (int16)(0);
67  RSIZE[i] = (int16)(0);
68 
69  if(ssum <= 16384) { //if(ssum <= 8192)
70  if(tx_size[i]==1 || tx_size[i]==2 || tx_size[i]==4 ||
71  tx_size[i]==8 || tx_size[i]==16) mul = tx_size[i];
72  else mul = 2; // by Ssoo Default 2K --20120522
73  SSIZE[i] = 0x400 * mul;
74  SMASK[i] = 0x400 * mul - 1;
75  }
76  if(rsum <= 16384) { //if(rsum <= 8192)
77  if(rx_size[i]==1 || rx_size[i]==2 || rx_size[i]==4 ||
78  rx_size[i]==8 || rx_size[i]==16) mul = rx_size[i];
79  else mul = 2; // by Ssoo Default 2K --20120522
80  RSIZE[i] = 0x400 * mul;
81  RMASK[i] = 0x400 * mul - 1;
82  }
83 
84  ssum += SSIZE[i];
85  rsum += RSIZE[i];
86 
87  if(i != 0) { // Sets base address of Tx and Rx memory for channel #1,#2,#3
88  SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1];
89  RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1];
90  }
91  DBGA("ch = %d, SSIZE = %d, RSIZE = %d",i,SSIZE[i],RSIZE[i]);
92  DBGA("SBUFBASEADDRESS = %d, RBUFBASEADDRESS = %d",
93  (uint16)SBUFBASEADDRESS[i],(uint16)RBUFBASEADDRESS[i]);
94  }
95 }
96 
97 void SetNetInfo(wiz_NetInfo *netinfo)
98 {
99  if(netinfo->mac[0] != 0x00 || netinfo->mac[1] != 0x00 || netinfo->mac[2] != 0x00 ||
100  netinfo->mac[3] != 0x00 || netinfo->mac[4] != 0x00 || netinfo->mac[5] != 0x00)
101  setSHAR(netinfo->mac); // set local MAC address
102  if(netinfo->ip[0] != 0x00 || netinfo->ip[1] != 0x00 || netinfo->ip[2] != 0x00 ||
103  netinfo->ip[3] != 0x00) setSIPR(netinfo->ip); // set local IP address
104  if(netinfo->sn[0] != 0x00 || netinfo->sn[1] != 0x00 || netinfo->sn[2] != 0x00 ||
105  netinfo->sn[3] != 0x00) setSUBR(netinfo->sn); // set Subnet mask
106  if(netinfo->gw[0] != 0x00 || netinfo->gw[1] != 0x00 || netinfo->gw[2] != 0x00 ||
107  netinfo->gw[3] != 0x00) setGAR(netinfo->gw); // set Gateway address
108  if(netinfo->dns[0] != 0x00 || netinfo->dns[1] != 0x00 || netinfo->dns[2] != 0x00 ||
109  netinfo->dns[3] != 0x00){
110  DNS[0] = netinfo->dns[0];
111  DNS[1] = netinfo->dns[1];
112  DNS[2] = netinfo->dns[2];
113  DNS[3] = netinfo->dns[3];
114  }
115 
116  if(netinfo->dhcp != 0) DHCP = netinfo->dhcp;
117 }
118 
120 {
121  uint8 zero[6] = {0,};
122 
123  DBGA("Reset Address(%d)", member);
124  switch(member) {
125  //case NI_MAC_ADDR: // If need, uncomment
126  // setSHAR(zero);
127  // break;
128  case NI_IP_ADDR:
129  setSIPR(zero);
130  break;
131  case NI_SN_MASK:
132  setSUBR(zero);
133  break;
134  case NI_GW_ADDR:
135  setGAR(zero);
136  break;
137  case NI_DNS_ADDR:
138  DNS[0] = DNS[1] = DNS[2] = DNS[3] = 0;
139  break;
140  default:
141  ERRA("wrong member value (%d)", member);
142  }
143 }
144 
145 void GetNetInfo(wiz_NetInfo *netinfo)
146 {
147  getSHAR(netinfo->mac); // get local MAC address
148  getSIPR(netinfo->ip); // get local IP address
149  getSUBR(netinfo->sn); // get subnet mask address
150  getGAR(netinfo->gw); // get gateway address
151  netinfo->dns[0] = DNS[0];
152  netinfo->dns[1] = DNS[1];
153  netinfo->dns[2] = DNS[2];
154  netinfo->dns[3] = DNS[3];
155  netinfo->dhcp = DHCP;
156 }
157 
158 void GetDstInfo(uint8 s, uint8 *dstip, uint16 *dstport)
159 {
160  getDIPR(s, dstip);
161  getDPORT(s, dstport);
162 }
163 
164 void SetSocketOption(uint8 option_type, uint16 option_value)
165 {
166  switch(option_type){
167  case 0:
168  setRTR(option_value); // set retry duration for data transmission, connection, closing ...
169  break;
170  case 1:
171  setRCR((uint8)(option_value&0x00FF)); // set retry count (above the value, assert timeout interrupt)
172  break;
173  case 2:
174  setIMR((uint8)(option_value&0x00FF)); // set interrupt mask.
175  break;
176  default:
177  break;
178  }
179 }
180 
181 int8 GetTCPSocketStatus(uint8 s)
182 {
183  if(s > TOTAL_SOCK_NUM) {
184  ERRA("wrong socket number(%d)", s);
185  return SOCKERR_NOT_TCP;
186  }
187 
188  switch(getSn_SR(s)){
189  case SOCK_CLOSED: return SOCKSTAT_CLOSED; // closed
190  case SOCK_INIT: return SOCKSTAT_INIT; // init state
191  case SOCK_LISTEN: return SOCKSTAT_LISTEN; // listen state
192  case SOCK_SYNSENT: return SOCKSTAT_SYNSENT; // connection state
193  case SOCK_SYNRECV: return SOCKSTAT_SYNRECV; // connection state
194  case SOCK_ESTABLISHED: return SOCKSTAT_ESTABLISHED; // success to connect
195  case SOCK_FIN_WAIT: return SOCKSTAT_FIN_WAIT; // closing state
196  case SOCK_CLOSING: return SOCKSTAT_CLOSING; // closing state
197  case SOCK_TIME_WAIT: return SOCKSTAT_TIME_WAIT; // closing state
198  case SOCK_CLOSE_WAIT: return SOCKSTAT_CLOSE_WAIT; // closing state
199  case SOCK_LAST_ACK: return SOCKSTAT_LAST_ACK; // closing state
200  default:
201  if((IINCHIP_READ(Sn_MR(Sn_MR_TCP))&0x0F) != Sn_MR_TCP)
202  return SOCKERR_NOT_TCP;
203  else return SOCKERR_WRONG_STATUS;
204  }
205 }
206 
207 int8 GetUDPSocketStatus(uint8 s)
208 {
209  if(s > TOTAL_SOCK_NUM) {
210  ERRA("wrong socket number(%d)", s);
211  return SOCKERR_NOT_UDP;
212  }
213 
214  switch(getSn_SR(s)){
215  case SOCK_CLOSED: return SOCKSTAT_CLOSED; // closed
216  case SOCK_UDP: return SOCKSTAT_UDP; // udp socket
217 #if 0
218  case SOCK_IPRAW: return 11; // ip raw mode socket
219  case SOCK_MACRAW: return 12; // mac raw mode socket
220  case SOCK_PPPOE: return 13; // pppoe socket
221 #endif
222  default:
223  if((IINCHIP_READ(Sn_MR(Sn_MR_UDP))&0x0F) != Sn_MR_UDP)
224  return SOCKERR_NOT_UDP;
225  else return SOCKERR_WRONG_STATUS;
226  }
227 }
228 
230 {
231  return getSn_TX_FSR(s); // get socket TX free buf size
232 }
233 
235 {
236  return getSn_RX_RSR(s); // get socket RX recv buf size
237 }
238 
239 int8 TCPServerOpen(uint8 s, uint16 port)
240 {
241  if(s > TOTAL_SOCK_NUM) {
242  ERRA("wrong socket number(%d)", s);
243  return SOCKERR_NOT_TCP;
244  } else DBG("start");
245 
246  if (port == 0) { // if don't set the source port, set local_port number.
247  if(local_port == 0xffff) local_port = 0xc000;
248  else local_port++;
249  port = local_port;
250  }
251 
252  TCPClose(s);
253  IINCHIP_WRITE(Sn_MR(s),Sn_MR_TCP);
254  IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
255  IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
256  IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
257  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
258  DBGA("Sn_SR = %.2x , Protocol = %.2x", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
259 
260  if (IINCHIP_READ(Sn_SR(s)) != SOCK_INIT) {
261  DBGA("wrong status(%d)", IINCHIP_READ(Sn_SR(s)));
262  return SOCKERR_WRONG_STATUS;
263  } else {
264  IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
265  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
266  }
267 
268  return RET_OK;
269 }
270 
271 int8 TCPClientOpen(uint8 s, uint16 sport, uint8 *dip, uint16 dport)
272 {
273  int8 ret;
274 
275  DBG("start");
276  ret = TCPCltOpenNB(s, sport, dip, dport);
277  if(ret != RET_OK) return ret;
278 
279  do {
280  ret = TCPConnChk(s);
281  } while(ret == SOCKERR_BUSY);
282 
283  return ret;
284 }
285 
286 int8 TCPCltOpenNB(uint8 s, uint16 sport, uint8 *dip, uint16 dport)
287 {
288  uint8 srcip[4], snmask[4];
289 
290  if(s > TOTAL_SOCK_NUM) {
291  ERRA("wrong socket number(%d)", s);
292  return SOCKERR_NOT_TCP;
293  } else if(dip == NULL) {
294  ERR("NULL Dst IP");
295  return SOCKERR_WRONG_ARG;
296  } else DBG("start");
297 
298  if (sport == 0) { // if don't set the source port, set local_port number.
299  if(local_port == 0xffff) local_port = 0xc000;
300  else local_port++;
301  sport = local_port;
302  }
303 
304  TCPClose(s);
305  IINCHIP_WRITE(Sn_MR(s),Sn_MR_TCP);
306  IINCHIP_WRITE(Sn_PORT0(s),(uint8)((sport & 0xff00) >> 8));
307  IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(sport & 0x00ff));
308  IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
309  while(IINCHIP_READ(Sn_CR(s)) ); // wait to process the command...
310  DBGA("Sn_SR = %.2x , Protocol = %.2x", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
311 
312  getSIPR(srcip);
313  getSUBR(snmask);
314 
315  if( ((dip[0] == 0xFF) && (dip[1] == 0xFF) &&
316  (dip[2] == 0xFF) && (dip[3] == 0xFF)) ||
317  ((dip[0] == 0x00) && (dip[1] == 0x00) &&
318  (dip[2] == 0x00) && (dip[3] == 0x00)) || (sport == 0x00) )
319  {
320  DBG("invalid ip or port");
321  DBGA("SOCK(%d)-[%02x.%02x.%02x.%02x, %d]",s,
322  dip[0], dip[1], dip[2], dip[3] , sport);
323  return SOCKERR_WRONG_ARG;
324  }
325  else if( (srcip[0]==0 && srcip[1]==0 && srcip[2]==0 && srcip[3]==0) &&
326  (snmask[0]!=0 || snmask[1]!=0 || snmask[2]!=0 || snmask[3]!=0) ) //Mikej : ARP Errata
327  {
328  DBG("Source IP is NULL while SN Mask is Not NULL");
329  return SOCKERR_NULL_SRC_IP;
330  }
331  else
332  {
333  IINCHIP_WRITE(Sn_DIPR0(s),dip[0]); // set destination IP
334  IINCHIP_WRITE((Sn_DIPR0(s) + 1),dip[1]);
335  IINCHIP_WRITE((Sn_DIPR0(s) + 2),dip[2]);
336  IINCHIP_WRITE((Sn_DIPR0(s) + 3),dip[3]);
337  IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((dport & 0xff00) >> 8));
338  IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(dport & 0x00ff));
339  IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
340  while (IINCHIP_READ(Sn_CR(s)) ); // wait for completion
341  }
342 
343  return RET_OK;
344 }
345 
346 int8 TCPConnChk(uint8 s)
347 {
348  uint8 socksr;
349 
350  if(s > TOTAL_SOCK_NUM) {
351  ERRA("wrong socket number(%d)", s);
352  return SOCKERR_NOT_TCP;
353  }
354 
355  socksr = IINCHIP_READ(Sn_SR(s));
356  if(socksr == SOCK_ESTABLISHED) { // || socksr == SOCK_SYNSENT) { ???
357  return RET_OK;
358  } else if(IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT) {
359  IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt
360  return SOCKERR_TIME_OUT;
361  }
362 
363  return SOCKERR_BUSY;
364 }
365 
366 int8 TCPClose(uint8 s)
367 {
368  int8 ret;
369 
370  DBG("start");
371  ret = TCPCloseNB(s);
372  if(ret != RET_OK) return ret;
373 
374  do {
375  ret = TCPCloseCHK(s);
376  } while(ret == SOCKERR_BUSY);
377 
378  return ret;
379 }
380 
381 int8 TCPCloseNB(uint8 s)
382 {
383  uint8 status;
384 
385  if(s > TOTAL_SOCK_NUM) {
386  ERRA("wrong socket number(%d)", s);
387  return SOCKERR_NOT_TCP;
388  } else DBG("start");
389 
390  IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
391  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
392 
393  status = getSn_SR(s);
394  if(status == SOCK_CLOSED) return SOCKERR_WRONG_STATUS;
395  else tcp_close_elapse[s] = wizpf_get_systick();
396 
397  return RET_OK;
398 }
399 
400 int8 TCPCloseCHK(uint8 s)
401 {
402 #define TIMEOUT_CLOSE_WAIT 200
403  uint8 status;
404 
405  if(s > TOTAL_SOCK_NUM) {
406  ERRA("wrong socket number(%d)", s);
407  return SOCKERR_NOT_TCP;
408  }
409 
410  status = getSn_SR(s);
411  if(status == SOCK_CLOSED) goto END_OK;
412  else if(wizpf_tick_elapse(tcp_close_elapse[s]) < TIMEOUT_CLOSE_WAIT)
413  return SOCKERR_BUSY;
414 
415  IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
416  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
417 
418 END_OK:
419  IINCHIP_WRITE(Sn_IR(s), 0xFF); // interrupt all clear
420  return RET_OK;
421 }
422 
423 int8 TCPClsRcvCHK(uint8 s)
424 {
425 #define TIMEOUT_CLOSE_WAIT 200
426  uint8 status;
427 
428  if(s > TOTAL_SOCK_NUM) {
429  ERRA("wrong socket number(%d)", s);
430  return SOCKERR_NOT_TCP;
431  }
432 
433  status = getSn_SR(s);
434  if(status == SOCK_CLOSED) goto END_OK;
435  if(status == SOCK_CLOSE_WAIT) {
436  IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
437  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
438  } else return SOCKERR_BUSY;
439 
440 END_OK:
441  IINCHIP_WRITE(Sn_IR(s), 0xFF); // interrupt all clear
442  return RET_OK;
443 }
444 
445 int32 TCPSend(uint8 s, const int8 *buf, uint16 len)
446 {
447  int32 ret;
448 
449  while(1) {
450  ret = TCPSendNB(s, buf, len);
451  if(ret == RET_OK) break;
452  if(ret != SOCKERR_BUSY) return ret;
453  }
454 
455  while(1) {
456  ret = TCPSendCHK(s);
457  if(ret >= 0 || ret != SOCKERR_BUSY) break;
458  }
459 
460  return ret;
461 }
462 
463 int8 TCPSendNB(uint8 s, const int8 *buf, uint16 len)
464 {
465  uint8 status = 0;
466 
467  if(s > TOTAL_SOCK_NUM) {
468  ERRA("wrong socket number(%d)", s);
469  return SOCKERR_NOT_TCP;
470  } else if(len == 0) {
471  ERR("Zero length");
472  return SOCKERR_WRONG_ARG;
473  } else DBG("start");
474 
475  status = getSn_SR(s);
476  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
477  if((IINCHIP_READ(Sn_MR(s))&0x0F) != Sn_MR_TCP) return SOCKERR_NOT_TCP;
478  if(status == SOCK_FIN_WAIT) return SOCKERR_FIN_WAIT;
479  if(status != SOCK_ESTABLISHED && status != SOCK_CLOSE_WAIT) return SOCKERR_NOT_ESTABLISHED;
480 
481  init_windowfull_retry_cnt(s);
482  if(len > getIINCHIP_TxMAX(s)) len = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
483  if(GetSocketTxFreeBufferSize(s) < len) return SOCKERR_BUSY;
484 
485  send_data_processing(s, (uint8*)buf, len); // copy data
486 
487  txrd_checker[s] = IINCHIP_READ(Sn_TX_RD0(s));
488  txrd_checker[s] = (txrd_checker[s] << 8) + IINCHIP_READ(Sn_TX_RD0(s) + 1);
489 
490  IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
491  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
492 
493  return RET_OK;
494 }
495 
496 int32 TCPReSend(uint8 s)
497 {
498  int32 ret;
499 
500  while(1) {
501  ret = TCPReSendNB(s);
502  if(ret == RET_OK) break;
503  if(ret != SOCKERR_BUSY) return ret;
504  }
505 
506  while(1) {
507  ret = TCPSendCHK(s);
508  if(ret >= 0 || ret != SOCKERR_BUSY) break;
509  }
510 
511  return ret;
512 }
513 
514 int8 TCPReSendNB(uint8 s)
515 {
516  uint8 status=0;
517 
518  if(s > TOTAL_SOCK_NUM) {
519  ERRA("wrong socket number(%d)", s);
520  return SOCKERR_NOT_TCP;
521  } else DBG("start");
522 
523  status = getSn_SR(s);
524  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
525  if((IINCHIP_READ(Sn_MR(s))&0x0F) != Sn_MR_TCP) return SOCKERR_NOT_TCP;
526  if(status == SOCK_FIN_WAIT) return SOCKERR_FIN_WAIT;
527  if(status != SOCK_ESTABLISHED && status != SOCK_CLOSE_WAIT) return SOCKERR_NOT_ESTABLISHED;
528 
529  status = incr_windowfull_retry_cnt(s);
530  if(status == 1) tcp_resend_elapse[s] = wizpf_get_systick();
531  else if(status > WINDOWFULL_MAX_RETRY_NUM) return SOCKERR_WINDOW_FULL;
532  else if(wizpf_tick_elapse(tcp_resend_elapse[s]) < WINDOWFULL_WAIT_TIME)
533  return SOCKERR_BUSY;
534 
535  txrd_checker[s] = IINCHIP_READ(Sn_TX_RD0(s));
536  txrd_checker[s] = (txrd_checker[s] << 8) + IINCHIP_READ(Sn_TX_RD0(s) + 1);
537 
538  IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
539  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
540 
541  return RET_OK;
542 }
543 
544 int32 TCPSendCHK(uint8 s)
545 {
546  uint16 txrd;
547 
548  if(!(IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK)) {
549  if(IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED) {
550  DBG("SOCK_CLOSED");
551  TCPClose(s);
552  return SOCKERR_CLOSED;
553  }
554  return SOCKERR_BUSY;
555  } else IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
556 
557  txrd = IINCHIP_READ(Sn_TX_RD0(s));
558  txrd = (txrd << 8) + IINCHIP_READ(Sn_TX_RD0(s) + 1);
559 
560  if(txrd > txrd_checker[s]) return txrd - txrd_checker[s];
561  else return (0xffff - txrd_checker[s]) + txrd + 1;
562 }
563 
564 int32 TCPRecv(uint8 s, int8 *buf, uint16 len)
565 {
566  uint8 status = 0;
567  uint16 RSR_len = 0;
568 
569  if(s > TOTAL_SOCK_NUM) {
570  ERRA("wrong socket number(%d)", s);
571  return SOCKERR_NOT_TCP;
572  } else if(len == 0) {
573  ERR("Zero length");
574  return SOCKERR_WRONG_ARG;
575  }
576 
577  RSR_len = GetSocketRxRecvBufferSize(s); // Check Receive Buffer
578  if(RSR_len == 0){
579  status = getSn_SR(s);
580  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
581  if((IINCHIP_READ(Sn_MR(s))&0x0F) != Sn_MR_TCP) return SOCKERR_NOT_TCP;
582  if(status == SOCK_CLOSE_WAIT) return SOCKERR_CLOSE_WAIT;
583  if(status != SOCK_ESTABLISHED && status != SOCK_CLOSE_WAIT) return SOCKERR_NOT_ESTABLISHED;
584  } else {
585  if(len < RSR_len) RSR_len = len;
586  recv_data_processing(s, (uint8*)buf, RSR_len);
587  IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
588  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
589  }
590 
591  return RSR_len;
592 }
593 
594 int8 UDPOpen(uint8 s, uint16 port)
595 {
596  if(s > TOTAL_SOCK_NUM) {
597  ERRA("wrong socket number(%d)", s);
598  return SOCKERR_NOT_UDP;
599  } else DBG("start");
600 
601  if (port == 0) { // if don't set the source port, set local_port number.
602  if(local_port == 0xffff) local_port = 0xc000;
603  else local_port++;
604  port = local_port;
605  }
606 
607  UDPClose(s);
608  IINCHIP_WRITE(Sn_MR(s),Sn_MR_UDP);
609  IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
610  IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
611  IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
612  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
613  DBGA("Sn_SR = %.2x , Protocol = %.2x", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
614 
615  return RET_OK;
616 }
617 
618 int8 UDPClose(uint8 s)
619 {
620  if(s > TOTAL_SOCK_NUM) {
621  ERRA("wrong socket number(%d)", s);
622  return SOCKERR_NOT_UDP;
623  } else DBG("start");
624 
625  IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
626  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
627  IINCHIP_WRITE(Sn_IR(s), 0xFF); // interrupt all clear
628 
629  return RET_OK;
630 }
631 
632 int32 UDPSend(uint8 s, const int8 *buf, uint16 len, uint8 *addr, uint16 port)
633 {
634  int32 ret = 0;
635 
636  ret = UDPSendNB(s, buf, len, addr, port);
637  if(ret < RET_OK) return ret;
638  else len = ret;
639 
640  do {
641  ret = UDPSendCHK(s);
642  if(ret == RET_OK) return len;
643  if(ret != SOCKERR_BUSY) return ret;
644  } while(1);
645 }
646 
647 int32 UDPSendNB(uint8 s, const int8 *buf, uint16 len, uint8 *addr, uint16 port)
648 {
649  uint8 srcip[4], snmask[4], status = 0;
650 
651  if(s > TOTAL_SOCK_NUM) {
652  ERRA("wrong socket number(%d)", s);
653  return SOCKERR_NOT_UDP;
654  } else if(len == 0 || addr == NULL) {
655  if(len == 0) ERR("Zero length");
656  else ERR("NULL Dst IP");
657  return SOCKERR_WRONG_ARG;
658  } else DBG("start");
659 
660  status = getSn_SR(s);
661  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
662  if((IINCHIP_READ(Sn_MR(s))&0x0F) != Sn_MR_UDP) return SOCKERR_NOT_UDP;
663  if(status != SOCK_UDP) return SOCKERR_NOT_UDP;
664 
665  if (len > getIINCHIP_TxMAX(s)) len = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
666  getSIPR(srcip);
667  getSUBR(snmask);
668 
669  if((addr[0]==0x00 && addr[1]==0x00 && addr[2]==0x00 &&
670  addr[3]==0x00) || (port==0x00))
671  {
672  DBG("invalid ip or port");
673  DBGA("SOCK(%d)-[%02x.%02x.%02x.%02x, %d, %d]",s,
674  addr[0], addr[1], addr[2], addr[3] , port, len);
675  return SOCKERR_WRONG_ARG;
676  }
677  else if( (srcip[0]==0 && srcip[1]==0 && srcip[2]==0 && srcip[3]==0) &&
678  (snmask[0]!=0 || snmask[1]!=0 || snmask[2]!=0 || snmask[3]!=0) ) //Mikej : ARP Errata
679  {
680  DBG("Source IP is NULL while SN Mask is Not NULL");
681  return SOCKERR_NULL_SRC_IP;
682  }
683  else
684  {
685  IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
686  IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
687  IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
688  IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
689  IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
690  IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
691 
692  send_data_processing(s, (uint8*)buf, len); // copy data
693 
694  IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
695  while(IINCHIP_READ(Sn_CR(s))); // wait to process the command...
696  }
697 
698  return len;
699 }
700 
701 int8 UDPSendCHK(uint8 s)
702 {
703  uint8 ir = IINCHIP_READ(Sn_IR(s));
704 
705  //DBGA("WATCH UDP Send CHK - sock(%d)", s);
706  if(!(ir & Sn_IR_SEND_OK)) {
707  if(ir & Sn_IR_TIMEOUT) {
708  DBG("send fail");
709  IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); // clear SEND_OK & TIMEOUT
710  return SOCKERR_TIME_OUT;
711  }
712  return SOCKERR_BUSY;
713  } else IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
714 
715  return RET_OK;
716 }
717 
718 int32 UDPRecv(uint8 s, int8 *buf, uint16 len, uint8 *addr, uint16 *port)
719 {
720  uint8 prebuf[8], status = 0;
721  uint16 tmp_len = 0, RSR_len = 0;
722 
723  if(s > TOTAL_SOCK_NUM) {
724  ERRA("wrong socket number(%d)", s);
725  return SOCKERR_NOT_UDP;
726  } else if(len == 0) {
727  ERR("Zero length");
728  return SOCKERR_WRONG_ARG;
729  }
730 
731  status = getSn_SR(s);
732  if(status == SOCK_CLOSED) return SOCKERR_CLOSED;
733  if((IINCHIP_READ(Sn_MR(s))&0x0F) != Sn_MR_UDP) return SOCKERR_NOT_UDP;
734  if(status != SOCK_UDP) return SOCKERR_NOT_UDP;
735 
736  RSR_len = GetSocketRxRecvBufferSize(s); // Check Receive Buffer of W5200
737  if(RSR_len < 8) {
738  DBGA("wrong data received (%d)", RSR_len);
739  recv_data_ignore(s, RSR_len);
740  IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
741  while(IINCHIP_READ(Sn_CR(s)));
742 
743  return SOCKERR_NOT_SPECIFIED;
744  } else {
745  recv_data_processing(s, prebuf, 8);
746  IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
747 
748  if(addr) { // read peer's IP address, port number.
749  addr[0] = prebuf[0];
750  addr[1] = prebuf[1];
751  addr[2] = prebuf[2];
752  addr[3] = prebuf[3];
753  }
754  if(port) {
755  *port = prebuf[4];
756  *port = (*port << 8) + prebuf[5];
757  }
758  tmp_len = prebuf[6];
759  tmp_len = (tmp_len << 8) + prebuf[7];
760  while(IINCHIP_READ(Sn_CR(s)));
761 
762  DBGA("UDP Recv - addr(%d.%d.%d.%d:%d), t(%d), R(%d)",
763  addr[0], addr[1], addr[2], addr[3], *port, tmp_len, RSR_len);
764  if(tmp_len == 0) {
765  ERR("UDP Recv len Zero - remove rest all");
766  recv_data_ignore(s, GetSocketRxRecvBufferSize(s));
767  IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
768  while(IINCHIP_READ(Sn_CR(s)));
769 
770  return SOCKERR_NOT_SPECIFIED;
771  }
772  RSR_len = tmp_len;
773  }
774 
775  if(len < RSR_len) {
776  tmp_len = RSR_len - len;
777  RSR_len = len;
778  DBGA("Recv buffer not enough - len(%d)", len);
779  } else tmp_len = 0;
780 
781  switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
782  {
783  case Sn_MR_UDP:
784  recv_data_processing(s, (uint8*)buf, RSR_len);
785  IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
786 
787  if(tmp_len) {
788  while(IINCHIP_READ(Sn_CR(s)));
789  DBG("Ignore rest data");
790  recv_data_ignore(s, tmp_len);
791  IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
792  while(IINCHIP_READ(Sn_CR(s)));
793  tmp_len = GetSocketRxRecvBufferSize(s);
794  if(tmp_len) DBGA("another rest data(%d)", tmp_len);
795  else DBG("No rest data");
796  }
797  break;
798  case Sn_MR_IPRAW:
799  case Sn_MR_MACRAW:
800  default :
801  break;
802  }
803  while(IINCHIP_READ(Sn_CR(s)));
804 
805  return RSR_len;
806 }
807 
808 
809 
810