io6Library
WIZnet Dual Stack TCP/IP Ethernet Controller Driver
loopback.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include "loopback.h"
3 #include "socket.h"
4 #include "wizchip_conf.h"
5 #include "stdlib.h"
6 
7 #if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK
8 
9 //static uint16_t j=0;
10 static uint16_t any_port = 50000;
11 static uint8_t curr_state[8] = {0,};
12 static uint8_t sock_state[8] = {0,};
13 uint8_t* msg_v4 = "IPv4 mode";
14 uint8_t* msg_v6 = "IPv6 mode";
15 uint8_t* msg_dual = "Dual IP mode";
16 
17 int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port, uint8_t loopback_mode)
18 {
19  int32_t ret;
20  datasize_t sentsize=0;
21  int8_t status,inter;
22  uint8_t tmp = 0;
23  datasize_t received_size;
24  uint8_t arg_tmp8;
25  uint8_t* mode_msg;
26 
27  if(loopback_mode == AS_IPV4)
28  {
29  mode_msg = msg_v4;
30  }else if(loopback_mode == AS_IPV6)
31  {
32  mode_msg = msg_v6;
33  }else
34  {
35  mode_msg = msg_dual;
36  }
37  #ifdef _LOOPBACK_DEBUG_
38  uint8_t dst_ip[16], ext_status;
39  uint16_t dst_port;
40  #endif
41  getsockopt(sn, SO_STATUS, &status);
42  switch(status)
43  {
44  case SOCK_ESTABLISHED :
45  ctlsocket(sn,CS_GET_INTERRUPT,&inter);
46  if(inter & Sn_IR_CON)
47  {
48  #ifdef _LOOPBACK_DEBUG_
49  getsockopt(sn,SO_DESTIP,dst_ip);
50  getsockopt(sn,SO_EXTSTATUS, &ext_status);
51  if(ext_status & TCPSOCK_MODE){
52  //IPv6
53  printf("%d:Peer IP : %04X:%04X", sn, ((uint16_t)dst_ip[0] << 8) | ((uint16_t)dst_ip[1]),
54  ((uint16_t)dst_ip[2] << 8) | ((uint16_t)dst_ip[3]));
55  printf(":%04X:%04X", ((uint16_t)dst_ip[4] << 8) | ((uint16_t)dst_ip[5]),
56  ((uint16_t)dst_ip[6] << 8) | ((uint16_t)dst_ip[7]));
57  printf(":%04X:%04X", ((uint16_t)dst_ip[8] << 8) | ((uint16_t)dst_ip[9]),
58  ((uint16_t)dst_ip[10] << 8) | ((uint16_t)dst_ip[11]));
59  printf(":%04X:%04X, ", ((uint16_t)dst_ip[12] << 8) | ((uint16_t)dst_ip[13]),
60  ((uint16_t)dst_ip[14] << 8) | ((uint16_t)dst_ip[15]));
61  }else
62  {
63  //IPv4
64  //getSn_DIPR(sn,dst_ip);
65  printf("%d:Peer IP : %.3d.%.3d.%.3d.%.3d, ",
66  sn, dst_ip[0], dst_ip[1], dst_ip[2], dst_ip[3]);
67  }
68  getsockopt(sn,SO_DESTPORT,&dst_port);
69  printf("Peer Port : %d\r\n", dst_port);
70  #endif
71  arg_tmp8 = Sn_IR_CON;
72  ctlsocket(sn,CS_CLR_INTERRUPT,&arg_tmp8);
73  }
74  getsockopt(sn,SO_RECVBUF,&received_size);
75 
76  if(received_size > 0){
77  if(received_size > DATA_BUF_SIZE) received_size = DATA_BUF_SIZE;
78  ret = recv(sn, buf, received_size);
79 
80  if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
81  received_size = (uint16_t) ret;
82  sentsize = 0;
83  char c = buf[10]; // hrozna prasecina
84  buf[10] = '\0';
85  printf("Dostal jsem %d bytu: %10s ... \n",received_size,buf);
86  buf[10] = c;
87 
88  while(received_size != sentsize)
89  {
90  ret = send(sn, buf+sentsize, received_size-sentsize);
91  if(ret < 0)
92  {
93  close(sn);
94  return ret;
95  }
96  sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
97  }
98  }
99  break;
100  case SOCK_CLOSE_WAIT :
101  #ifdef _LOOPBACK_DEBUG_
102  printf("%d:CloseWait\r\n",sn);
103  #endif
104  getsockopt(sn, SO_RECVBUF, &received_size);
105  if(received_size > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
106  {
107  if(received_size > DATA_BUF_SIZE) received_size = DATA_BUF_SIZE;
108  ret = recv(sn, buf, received_size);
109 
110  if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
111  received_size = (uint16_t) ret;
112  sentsize = 0;
113 
114  while(received_size != sentsize)
115  {
116  ret = send(sn, buf+sentsize, received_size-sentsize);
117  if(ret < 0)
118  {
119  close(sn);
120  return ret;
121  }
122  sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
123  }
124  }
125 
126  if((ret = disconnect(sn)) != SOCK_OK) return ret;
127  #ifdef _LOOPBACK_DEBUG_
128  printf("%d:Socket Closed\r\n", sn);
129  #endif
130  break;
131  case SOCK_INIT :
132  if( (ret = listen(sn)) != SOCK_OK) return ret;
133  #ifdef _LOOPBACK_DEBUG_
134  printf("%d:Listen, TCP server loopback, port [%d] as %s\r\n", sn, port, mode_msg);
135  #endif
136  printf("%d:Listen, TCP server loopback, port [%d] as %s\r\n", sn, port, mode_msg);
137  break;
138  case SOCK_CLOSED:
139  #ifdef _LOOPBACK_DEBUG_
140  printf("%d:TCP server loopback start\r\n",sn);
141  #endif
142  switch(loopback_mode)
143  {
144  case AS_IPV4:
145  tmp = socket(sn, Sn_MR_TCP4, port, SOCK_IO_NONBLOCK);
146  break;
147  case AS_IPV6:
148  tmp = socket(sn, Sn_MR_TCP6, port, SOCK_IO_NONBLOCK);
149  break;
150  case AS_IPDUAL:
151  tmp = socket(sn, Sn_MR_TCPD, port, SOCK_IO_NONBLOCK);
152  break;
153  default:
154  break;
155  }
156  if(tmp != sn) /* reinitialize the socket */
157  {
158  #ifdef _LOOPBACK_DEBUG_
159  printf("%d : Fail to create socket.\r\n",sn);
160  #endif
161  return SOCKERR_SOCKNUM;
162  }
163  #ifdef _LOOPBACK_DEBUG_
164  printf("%d:Socket opened[%d]\r\n",sn, getSn_SR(sn));
165  sock_state[sn] = 1;
166  #endif
167  break;
168  default:
169  break;
170  }
171  return 1;
172 }
173 
174 
175 int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport, uint8_t loopback_mode)
176 {
177 
178  int32_t ret; // return value for SOCK_ERRORs
179  datasize_t sentsize=0;
180  uint8_t status,inter,addr_len;
181  datasize_t received_size;
182  uint8_t tmp = 0;
183  uint8_t arg_tmp8;
184  wiz_IPAddress destinfo;
185 
186 
187  // Socket Status Transitions
188  // Check the W6100 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
189  getsockopt(sn,SO_STATUS,&status);
190  switch(status)
191  {
192  case SOCK_ESTABLISHED :
193  ctlsocket(sn,CS_GET_INTERRUPT,&inter);
194  if(inter & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
195  {
196  #ifdef _LOOPBACK_DEBUG_
197  printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
198  #endif
199  arg_tmp8 = Sn_IR_CON;
200  ctlsocket(sn,CS_CLR_INTERRUPT,&arg_tmp8);// this interrupt should be write the bit cleared to '1'
201  }
202 
204  // Data Transaction Parts; Handle the [data receive and send] process
206  getsockopt(sn, SO_RECVBUF, &received_size);
207 
208  if(received_size > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
209  {
210  if(received_size > DATA_BUF_SIZE) received_size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
211  ret = recv(sn, buf, received_size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
212 
213  if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
214  received_size = (uint16_t) ret;
215  sentsize = 0;
216 
217  // Data sentsize control
218  while(received_size != sentsize)
219  {
220  ret = send(sn, buf+sentsize, received_size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
221  if(ret < 0) // Send Error occurred (sent data length < 0)
222  {
223  close(sn); // socket close
224  return ret;
225  }
226  sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
227  }
228  }
230  break;
231 
232  case SOCK_CLOSE_WAIT :
233  #ifdef _LOOPBACK_DEBUG_
234  printf("%d:CloseWait\r\n",sn);
235  #endif
236  getsockopt(sn, SO_RECVBUF, &received_size);
237 
238  if((received_size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
239  {
240  if(received_size > DATA_BUF_SIZE) received_size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
241  ret = recv(sn, buf, received_size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
242 
243  if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
244  received_size = (uint16_t) ret;
245  sentsize = 0;
246 
247  // Data sentsize control
248  while(received_size != sentsize)
249  {
250  ret = send(sn, buf+sentsize, received_size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
251  if(ret < 0) // Send Error occurred (sent data length < 0)
252  {
253  close(sn); // socket close
254  return ret;
255  }
256  sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
257  }
258  }
259  if((ret=disconnect(sn)) != SOCK_OK) return ret;
260  #ifdef _LOOPBACK_DEBUG_
261  printf("%d:Socket Closed\r\n", sn);
262  #endif
263  break;
264 
265  case SOCK_INIT :
266  #ifdef _LOOPBACK_DEBUG_
267  if(loopback_mode == AS_IPV4)
268  printf("%d:Try to connect to the %d.%d.%d.%d, %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
269  else if(loopback_mode == AS_IPV6)
270  {
271  printf("%d:Try to connect to the %04X:%04X", sn, ((uint16_t)destip[0] << 8) | ((uint16_t)destip[1]),
272  ((uint16_t)destip[2] << 8) | ((uint16_t)destip[3]));
273  printf(":%04X:%04X", ((uint16_t)destip[4] << 8) | ((uint16_t)destip[5]),
274  ((uint16_t)destip[6] << 8) | ((uint16_t)destip[7]));
275  printf(":%04X:%04X", ((uint16_t)destip[8] << 8) | ((uint16_t)destip[9]),
276  ((uint16_t)destip[10] << 8) | ((uint16_t)destip[11]));
277  printf(":%04X:%04X,", ((uint16_t)destip[12] << 8) | ((uint16_t)destip[13]),
278  ((uint16_t)destip[14] << 8) | ((uint16_t)destip[15]));
279  printf("%d\r\n", destport);
280  }
281  #endif
282 
283  if(loopback_mode == AS_IPV4)
284  ret = connect(sn, destip, destport, 4); /* Try to connect to TCP server(Socket, DestIP, DestPort) */
285  else if(loopback_mode == AS_IPV6)
286  ret = connect(sn, destip, destport, 16); /* Try to connect to TCP server(Socket, DestIP, DestPort) */
287 
288  printf("SOCK Status: %d\r\n", ret);
289 
290  if( ret != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination)
291  break;
292 
293  case SOCK_CLOSED:
294  switch(loopback_mode)
295  {
296  case AS_IPV4:
297  tmp = socket(sn, Sn_MR_TCP4, any_port++, SOCK_IO_NONBLOCK);
298  break;
299  case AS_IPV6:
300  tmp = socket(sn, Sn_MR_TCP6, any_port++, SOCK_IO_NONBLOCK);
301  break;
302  case AS_IPDUAL:
303  tmp = socket(sn, Sn_MR_TCPD, any_port++, SOCK_IO_NONBLOCK);
304  break;
305  default:
306  break;
307  }
308 
309  if(tmp != sn){ /* reinitialize the socket */
310  #ifdef _LOOPBACK_DEBUG_
311  printf("%d : Fail to create socket.\r\n",sn);
312  #endif
313  return SOCKERR_SOCKNUM;
314  }
315  printf("%d:Socket opened[%d]\r\n",sn, getSn_SR(sn));
316  sock_state[sn] = 1;
317 
318  break;
319  default:
320  break;
321  }
322  return 1;
323 }
324 
325 int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port, uint8_t loopback_mode)
326 {
327  uint8_t status;
328  static uint8_t destip[16] = {0,};
329  static uint16_t destport;
330  uint8_t pack_info;
331  uint8_t addr_len;
332  datasize_t ret;
333  datasize_t received_size;
334  uint16_t size, sentsize;
335  uint8_t* mode_msg;
336 
337  if(loopback_mode == AS_IPV4)
338  {
339  mode_msg = msg_v4;
340  }else if(loopback_mode == AS_IPV6)
341  {
342  mode_msg = msg_v6;
343  }else
344  {
345  mode_msg = msg_dual;
346  }
347 
348  getsockopt(sn, SO_STATUS,&status);
349  switch(status)
350  {
351  case SOCK_UDP:
352  getsockopt(sn, SO_RECVBUF, &received_size);
353  if(received_size > DATA_BUF_SIZE) received_size = DATA_BUF_SIZE;
354  if(received_size>0)
355  {
356  ret = recvfrom(sn, buf, received_size, (uint8_t*)&destip, (uint16_t*)&destport, &addr_len);
357 
358  if(ret <= 0)
359  return ret;
360  received_size = (uint16_t) ret;
361  sentsize = 0;
362  while(sentsize != received_size){
363  ret = sendto(sn, buf+sentsize, received_size-sentsize, destip, destport, addr_len);
364 
365  if(ret < 0) return ret;
366 
367  sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
368  }
369  }
370  break;
371  case SOCK_CLOSED:
372 
373  switch(loopback_mode)
374  {
375  case AS_IPV4:
377  break;
378  case AS_IPV6:
380  break;
381  case AS_IPDUAL:
383  break;
384  }
385  printf("%d:Opened, UDP loopback, port [%d] as %s\r\n", sn, port, mode_msg);
386 
387  }
388 
389  return 0;
390 }
391 
392 #endif
loopback.h
sendto
datasize_t sendto(uint8_t sn, uint8_t *buf, datasize_t len, uint8_t *addr, uint16_t port, uint8_t addrlen)
Send datagram to the peer specifed by destination IP address and port number passed as parameter.
Definition: socket.c:372
recv
datasize_t recv(uint8_t sn, uint8_t *buf, datasize_t len)
Receive data from the connected peer.
Definition: socket.c:338
loopback_udps
int32_t loopback_udps(uint8_t sn, uint8_t *buf, uint16_t port, uint8_t loopback_mode)
Definition: loopback.c:325
socket
int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
Open a socket.
Definition: socket.c:101
Sn_MR_TCP4
#define Sn_MR_TCP4
Refer to Sn_MR_TCP.
Definition: w6100.h:2392
connect
int8_t connect(uint8_t sn, uint8_t *addr, uint16_t port, uint8_t addrlen)
Try to connect to a TCP SERVER.
Definition: socket.c:219
SOCK_CLOSE_WAIT
#define SOCK_CLOSE_WAIT
TCP SOCKETn Half Closing staus.
Definition: w6100.h:2863
TCPSOCK_MODE
#define TCPSOCK_MODE
It indicates the IP version when SOCKETn is opened as TCP6 or TCPD mode.(0 - IPv4 ,...
Definition: socket.h:177
SO_DESTPORT
@ SO_DESTPORT
Set/Get the destination Port number. To get it, SOCKETn should be TCP mode.
Definition: socket.h:443
msg_v6
uint8_t * msg_v6
Definition: loopback.c:14
Sn_MR_TCP6
#define Sn_MR_TCP6
IPv6 TCP mode.
Definition: w6100.h:2439
SO_DESTIP
@ SO_DESTIP
Set/Get the destination IP address with argument wiz_IPAddress. To get it, SOCKETn should be TCP mode...
Definition: socket.h:442
SOCK_INIT
#define SOCK_INIT
TCP SOCKETn initialized status.
Definition: w6100.h:2767
getSn_RX_RSR
datasize_t getSn_RX_RSR(uint8_t s)
SOCK_UDP
#define SOCK_UDP
UDP SOCKETn status.
Definition: w6100.h:2893
Sn_MR_UDPD
#define Sn_MR_UDPD
UDP Dual mode.
Definition: w6100.h:2499
msg_dual
uint8_t * msg_dual
Definition: loopback.c:15
ctlsocket
int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg)
Control SOCKETn.
Definition: socket.c:528
SO_RECVBUF
@ SO_RECVBUF
Valid only in getsockopt(). Get the received data size in SOCKETn RX buffer. getSn_RX_RSR()
Definition: socket.h:447
SO_EXTSTATUS
@ SO_EXTSTATUS
Valid only in getsockopt(). Get the extended TCP SOCKETn status. getSn_ESR()
Definition: socket.h:449
DATA_BUF_SIZE
#define DATA_BUF_SIZE
Definition: loopback.h:11
SOCK_CLOSED
#define SOCK_CLOSED
SOCKETn Closed status.
Definition: w6100.h:2755
CS_GET_INTERRUPT
@ CS_GET_INTERRUPT
get the SOCKET interrupt. refer to sockint_kind.
Definition: socket.h:424
msg_v4
uint8_t * msg_v4
Definition: loopback.c:13
AS_IPV4
#define AS_IPV4
Definition: Application.h:15
size
unsigned size
Definition: dhcpv6.c:177
CS_CLR_INTERRUPT
@ CS_CLR_INTERRUPT
clear the interrupt of SOCKET with sockint_kind.
Definition: socket.h:423
Sn_MR_TCPD
#define Sn_MR_TCPD
Both IPv4 & IPv6 TCP mode (TCP dual mode)
Definition: w6100.h:2485
listen
int8_t listen(uint8_t sn)
Listen to a connection request from a TCP CLIENT.
Definition: socket.c:204
SO_STATUS
@ SO_STATUS
Valid only in getsockopt(). Get the SOCKETn status. getSn_SR()
Definition: socket.h:448
AS_IPV6
#define AS_IPV6
Definition: Application.h:16
loopback_tcpc
int32_t loopback_tcpc(uint8_t sn, uint8_t *buf, uint8_t *destip, uint16_t destport, uint8_t loopback_mode)
Definition: loopback.c:175
SOCK_IO_NONBLOCK
#define SOCK_IO_NONBLOCK
Socket Non-block IO Mode in setsockopt().
Definition: socket.h:185
SOCKERR_SOCKNUM
#define SOCKERR_SOCKNUM
Invalid socket number.
Definition: socket.h:87
SOCK_OK
#define SOCK_OK
Result is OK about socket process.
Definition: socket.h:82
send
datasize_t send(uint8_t sn, uint8_t *buf, datasize_t len)
Send data to the connected peer.
Definition: socket.c:289
close
int8_t close(uint8_t sn)
Close a SOCKET.
Definition: socket.c:186
getSn_SR
#define getSn_SR(sn)
Definition: w6100.h:3837
Sn_IR_CON
#define Sn_IR_CON
CONNECT Interrupt.
Definition: w6100.h:2744
getsockopt
int8_t getsockopt(uint8_t sn, sockopt_type sotype, void *arg)
get SOCKETn options
Definition: socket.c:620
Sn_MR_UDP6
#define Sn_MR_UDP6
IPv6 UDP mode.
Definition: w6100.h:2450
socket.h
SOCKET APIs Header File.
AS_IPDUAL
#define AS_IPDUAL
Definition: Application.h:17
disconnect
int8_t disconnect(uint8_t sn)
Try to disconnect to the connected peer.
Definition: socket.c:266
Sn_MR_UDP4
#define Sn_MR_UDP4
Refer to Sn_MR_UDP.
Definition: w6100.h:2404
wiz_IPAddress_t
Destination Information for Network Service of _WIZCHIP_.
Definition: wizchip_conf.h:517
loopback_tcps
int32_t loopback_tcps(uint8_t sn, uint8_t *buf, uint16_t port, uint8_t loopback_mode)
Definition: loopback.c:17
SOCK_ESTABLISHED
#define SOCK_ESTABLISHED
TCP SOCKETn Established status.
Definition: w6100.h:2826
wizchip_conf.h
WIZCHIP Config Header File.
recvfrom
datasize_t recvfrom(uint8_t sn, uint8_t *buf, datasize_t len, uint8_t *addr, uint16_t *port, uint8_t *addrlen)
Receive datagram from a peer.
Definition: socket.c:441