1030 lines
36 KiB
C
1030 lines
36 KiB
C
#include <stdio.h>
|
|
#include "loopback.h"
|
|
#include "socket.h"
|
|
#include "wizchip_conf.h"
|
|
|
|
|
|
#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK
|
|
|
|
|
|
static int8_t loopback_mode = 0 ;
|
|
|
|
|
|
|
|
|
|
|
|
#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500)
|
|
int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port) {
|
|
int32_t ret;
|
|
uint16_t size = 0, sentsize = 0;
|
|
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
uint8_t destip[4];
|
|
uint16_t destport;
|
|
#endif
|
|
|
|
switch (getSn_SR(sn)) {
|
|
case SOCK_ESTABLISHED :
|
|
if (getSn_IR(sn) & Sn_IR_CON) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
getSn_DIPR(sn, destip);
|
|
destport = getSn_DPORT(sn);
|
|
|
|
printf("%d:Connected - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
|
#endif
|
|
setSn_IR(sn, Sn_IR_CON);
|
|
}
|
|
if ((size = getSn_RX_RSR(sn)) > 0) { // Don't need to check SOCKERR_BUSY because it doesn't not occur.
|
|
if (size > DATA_BUF_SIZE) {
|
|
size = DATA_BUF_SIZE;
|
|
}
|
|
ret = recv(sn, buf, size);
|
|
|
|
if (ret <= 0) {
|
|
return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
|
|
}
|
|
size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
|
|
while (size != sentsize) {
|
|
ret = send(sn, buf + sentsize, size - sentsize);
|
|
if (ret < 0) {
|
|
close(sn);
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
}
|
|
break;
|
|
case SOCK_CLOSE_WAIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
//printf("%d:CloseWait\r\n",sn);
|
|
#endif
|
|
if ((ret = disconnect(sn)) != SOCK_OK) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Socket Closed\r\n", sn);
|
|
#endif
|
|
break;
|
|
case SOCK_INIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port);
|
|
#endif
|
|
if ((ret = listen(sn)) != SOCK_OK) {
|
|
return ret;
|
|
}
|
|
break;
|
|
case SOCK_CLOSED:
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
//printf("%d:TCP server loopback start\r\n",sn);
|
|
#endif
|
|
if ((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
//printf("%d:Socket opened\r\n",sn);
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) {
|
|
int32_t ret; // return value for SOCK_ERRORs
|
|
uint16_t size = 0, sentsize = 0;
|
|
|
|
// Destination (TCP Server) IP info (will be connected)
|
|
// >> loopback_tcpc() function parameter
|
|
// >> Ex)
|
|
// uint8_t destip[4] = {192, 168, 0, 214};
|
|
// uint16_t destport = 5000;
|
|
|
|
// Port number for TCP client (will be increased)
|
|
static uint16_t any_port = 50000;
|
|
|
|
// Socket Status Transitions
|
|
// Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
|
|
switch (getSn_SR(sn)) {
|
|
case SOCK_ESTABLISHED :
|
|
if (getSn_IR(sn) & Sn_IR_CON) { // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Connected to - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
|
#endif
|
|
setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1'
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Data Transaction Parts; Handle the [data receive and send] process
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
if ((size = getSn_RX_RSR(sn)) > 0) { // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
|
|
if (size > DATA_BUF_SIZE) {
|
|
size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
|
|
}
|
|
ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
|
|
|
|
if (ret <= 0) {
|
|
return ret; // If the received data length <= 0, receive failed and process end
|
|
}
|
|
size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
|
|
// Data sentsize control
|
|
while (size != sentsize) {
|
|
ret = send(sn, buf + sentsize, size - sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
|
|
if (ret < 0) { // Send Error occurred (sent data length < 0)
|
|
close(sn); // socket close
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
break;
|
|
|
|
case SOCK_CLOSE_WAIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
//printf("%d:CloseWait\r\n",sn);
|
|
#endif
|
|
if ((ret = disconnect(sn)) != SOCK_OK) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Socket Closed\r\n", sn);
|
|
#endif
|
|
break;
|
|
|
|
case SOCK_INIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
|
#endif
|
|
if ((ret = connect(sn, destip, destport)) != SOCK_OK) {
|
|
return ret; // Try to TCP connect to the TCP server (destination)
|
|
}
|
|
break;
|
|
|
|
case SOCK_CLOSED:
|
|
close(sn);
|
|
if ((ret = socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn) {
|
|
if (any_port == 0xffff) {
|
|
any_port = 50000;
|
|
}
|
|
return ret; // TCP socket open with 'any_port' port number
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
//printf("%d:TCP client loopback start\r\n",sn);
|
|
//printf("%d:Socket opened\r\n",sn);
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port) {
|
|
int32_t ret;
|
|
uint16_t size, sentsize;
|
|
uint8_t destip[4];
|
|
uint16_t destport;
|
|
|
|
switch (getSn_SR(sn)) {
|
|
case SOCK_UDP :
|
|
if ((size = getSn_RX_RSR(sn)) > 0) {
|
|
if (size > DATA_BUF_SIZE) {
|
|
size = DATA_BUF_SIZE;
|
|
}
|
|
ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
|
|
if (ret <= 0) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d: recvfrom error. %ld\r\n", sn, ret);
|
|
#endif
|
|
return ret;
|
|
}
|
|
size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
while (sentsize != size) {
|
|
ret = sendto(sn, buf + sentsize, size - sentsize, destip, destport);
|
|
if (ret < 0) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d: sendto error. %ld\r\n", sn, ret);
|
|
#endif
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
}
|
|
break;
|
|
case SOCK_CLOSED:
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
//printf("%d:UDP loopback start\r\n",sn);
|
|
#endif
|
|
if ((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port);
|
|
#endif
|
|
break;
|
|
default :
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
int32_t loopback_udpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) {
|
|
int32_t ret;
|
|
uint16_t size = 0, sentsize = 0;
|
|
static uint16_t any_port = 50000;
|
|
// uint8_t* strtest = "\r\nhello world";
|
|
// uint8_t flag = 0;
|
|
switch (getSn_SR(sn)) {
|
|
case SOCK_UDP :
|
|
// sendto(sn, strtest, strlen(strtest), destip, destport);
|
|
if ((size = getSn_RX_RSR(sn)) > 0) {
|
|
if (size > DATA_BUF_SIZE) {
|
|
size = DATA_BUF_SIZE;
|
|
}
|
|
ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
|
|
buf[ret] = 0x00;
|
|
printf("recv form[%d.%d.%d.%d][%d]: %s\n", destip[0], destip[1], destip[2], destip[3], destport, buf);
|
|
if (ret <= 0) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d: recvfrom error. %ld\r\n", sn, ret);
|
|
#endif
|
|
return ret;
|
|
}
|
|
size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
while (sentsize != size) {
|
|
ret = sendto(sn, buf + sentsize, size - sentsize, destip, destport);
|
|
if (ret < 0) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d: sendto error. %ld\r\n", sn, ret);
|
|
#endif
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
}
|
|
break;
|
|
case SOCK_CLOSED:
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
// printf("%d:UDP loopback start\r\n",sn);
|
|
#endif
|
|
if ((ret = socket(sn, Sn_MR_UDP, any_port, 0x00)) != sn) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, any_port);
|
|
#endif
|
|
break;
|
|
default :
|
|
break;
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
|
|
//teddy 240122
|
|
|
|
|
|
|
|
#elif ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
|
|
|
|
int8_t set_loopback_mode_W6x00(uint8_t get_loopback_mode) {
|
|
loopback_mode = get_loopback_mode ;
|
|
return 0;
|
|
}
|
|
|
|
int8_t check_loopback_mode_W6x00() {
|
|
if (loopback_mode != AS_IPV4 && loopback_mode != AS_IPV6 && loopback_mode != AS_IPDUAL) {
|
|
loopback_mode = AS_IPV4 ;
|
|
}
|
|
return loopback_mode;
|
|
}
|
|
|
|
//static uint16_t j=0;
|
|
static uint16_t any_port = 50000;
|
|
static uint8_t curr_state[8] = {0,};
|
|
static uint8_t sock_state[8] = {0,};
|
|
uint8_t* msg_v4 = "IPv4 mode";
|
|
uint8_t* msg_v6 = "IPv6 mode";
|
|
uint8_t* msg_dual = "Dual IP mode";
|
|
|
|
int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port) {
|
|
// by Lihan 20241119
|
|
check_loopback_mode_W6x00();
|
|
int32_t ret;
|
|
uint16_t sentsize = 0;
|
|
int8_t status, inter;
|
|
uint8_t tmp = 0;
|
|
uint16_t received_size;
|
|
uint8_t arg_tmp8;
|
|
uint8_t* mode_msg;
|
|
#if 1
|
|
// 20231018 taylor
|
|
uint8_t destip[16], sn_status;
|
|
uint16_t destport;
|
|
#endif
|
|
|
|
if (loopback_mode == AS_IPV4) {
|
|
mode_msg = msg_v4;
|
|
} else if (loopback_mode == AS_IPV6) {
|
|
mode_msg = msg_v6;
|
|
} else {
|
|
mode_msg = msg_dual;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
uint8_t dst_ip[16], ext_status;
|
|
uint16_t dst_port;
|
|
#endif
|
|
getsockopt(sn, SO_STATUS, &status);
|
|
switch (status) {
|
|
case SOCK_ESTABLISHED :
|
|
ctlsocket(sn, CS_GET_INTERRUPT, &inter);
|
|
if (inter & Sn_IR_CON) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
getsockopt(sn, SO_DESTIP, dst_ip);
|
|
getsockopt(sn, SO_EXTSTATUS, &ext_status);
|
|
if (ext_status & TCPSOCK_MODE) {
|
|
//IPv6
|
|
printf("%d:Peer IP : %04X:%04X", sn, ((uint16_t)dst_ip[0] << 8) | ((uint16_t)dst_ip[1]),
|
|
((uint16_t)dst_ip[2] << 8) | ((uint16_t)dst_ip[3]));
|
|
printf(":%04X:%04X", ((uint16_t)dst_ip[4] << 8) | ((uint16_t)dst_ip[5]),
|
|
((uint16_t)dst_ip[6] << 8) | ((uint16_t)dst_ip[7]));
|
|
printf(":%04X:%04X", ((uint16_t)dst_ip[8] << 8) | ((uint16_t)dst_ip[9]),
|
|
((uint16_t)dst_ip[10] << 8) | ((uint16_t)dst_ip[11]));
|
|
printf(":%04X:%04X, ", ((uint16_t)dst_ip[12] << 8) | ((uint16_t)dst_ip[13]),
|
|
((uint16_t)dst_ip[14] << 8) | ((uint16_t)dst_ip[15]));
|
|
} else {
|
|
//IPv4
|
|
//getSn_DIPR(sn,dst_ip);
|
|
printf("%d:Peer IP : %.3d.%.3d.%.3d.%.3d, ",
|
|
sn, dst_ip[0], dst_ip[1], dst_ip[2], dst_ip[3]);
|
|
}
|
|
getsockopt(sn, SO_DESTPORT, &dst_port);
|
|
printf("Peer Port : %d\r\n", dst_port);
|
|
#endif
|
|
arg_tmp8 = Sn_IR_CON;
|
|
ctlsocket(sn, CS_CLR_INTERRUPT, &arg_tmp8);
|
|
}
|
|
getsockopt(sn, SO_RECVBUF, &received_size);
|
|
|
|
if (received_size > 0) {
|
|
if (received_size > DATA_BUF_SIZE) {
|
|
received_size = DATA_BUF_SIZE;
|
|
}
|
|
ret = recv(sn, buf, received_size);
|
|
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
getsockopt(sn, SO_DESTIP, destip);
|
|
getsockopt(sn, SO_DESTPORT, &destport);
|
|
getsockopt(sn, SO_EXTSTATUS, &sn_status);
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Received %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, received_size,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Received %d bytes from %d.%d.%d.%d port %d : \r\n", sn, received_size, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < received_size; i++) {
|
|
printf("%c", buf[i]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
if (ret <= 0) {
|
|
return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
|
|
}
|
|
received_size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
|
|
while (received_size != sentsize) {
|
|
ret = send(sn, buf + sentsize, received_size - sentsize);
|
|
if (ret < 0) {
|
|
close(sn);
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Sent back %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, sentsize,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Sent back %d bytes from %d.%d.%d.%d port %d : \r\n", sn, sentsize, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int j;
|
|
for (j = 0; j < sentsize; j++) {
|
|
printf("%c", buf[j]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
}
|
|
break;
|
|
case SOCK_CLOSE_WAIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:CloseWait\r\n", sn);
|
|
#endif
|
|
getsockopt(sn, SO_RECVBUF, &received_size);
|
|
if (received_size > 0) { // Don't need to check SOCKERR_BUSY because it doesn't not occur.
|
|
if (received_size > DATA_BUF_SIZE) {
|
|
received_size = DATA_BUF_SIZE;
|
|
}
|
|
ret = recv(sn, buf, received_size);
|
|
|
|
if (ret <= 0) {
|
|
return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
|
|
}
|
|
received_size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
getsockopt(sn, SO_DESTIP, destip);
|
|
getsockopt(sn, SO_DESTPORT, &destport);
|
|
getsockopt(sn, SO_EXTSTATUS, &sn_status);
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Received %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, received_size,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Received %d bytes from %d.%d.%d.%d port %d : \r\n", sn, received_size, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < received_size; i++) {
|
|
printf("%c", buf[i]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
|
|
while (received_size != sentsize) {
|
|
ret = send(sn, buf + sentsize, received_size - sentsize);
|
|
if (ret < 0) {
|
|
close(sn);
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Sent back %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, sentsize,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Sent back %d bytes from %d.%d.%d.%d port %d : \r\n", sn, sentsize, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int j;
|
|
for (j = 0; j < sentsize; j++) {
|
|
printf("%c", buf[j]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
if ((ret = disconnect(sn)) != SOCK_OK) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Socket Closed\r\n", sn);
|
|
#endif
|
|
break;
|
|
case SOCK_INIT :
|
|
if ((ret = listen(sn)) != SOCK_OK) {
|
|
return ret;
|
|
}
|
|
#if 1
|
|
// 20231018 taylor
|
|
#if 0
|
|
#endif
|
|
#else
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Listen, TCP server loopback, port [%d] as %s\r\n", sn, port, mode_msg);
|
|
#endif
|
|
#endif
|
|
printf("%d:Listen, TCP server loopback, port [%d] as %s\r\n", sn, port, mode_msg);
|
|
break;
|
|
case SOCK_CLOSED:
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:TCP server loopback start\r\n", sn);
|
|
#endif
|
|
switch (loopback_mode) {
|
|
case AS_IPV4:
|
|
tmp = socket(sn, Sn_MR_TCP4, port, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPV6:
|
|
tmp = socket(sn, Sn_MR_TCP6, port, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPDUAL:
|
|
tmp = socket(sn, Sn_MR_TCPD, port, SOCK_IO_NONBLOCK);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (tmp != sn) { /* reinitialize the socket */
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d : Fail to create socket.\r\n", sn);
|
|
#endif
|
|
return SOCKERR_SOCKNUM;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Socket opened[%d]\r\n", sn, getSn_SR(sn));
|
|
sock_state[sn] = 1;
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) {
|
|
check_loopback_mode_W6x00();
|
|
int32_t ret; // return value for SOCK_ERRORs
|
|
uint16_t sentsize = 0;
|
|
uint8_t status, inter, addr_len;
|
|
uint16_t received_size;
|
|
uint8_t tmp = 0;
|
|
uint8_t arg_tmp8;
|
|
wiz_IPAddress destinfo;
|
|
#if 1
|
|
// 20231018 taylor
|
|
uint8_t sn_status;
|
|
#endif
|
|
|
|
|
|
// Socket Status Transitions
|
|
// Check the W6100 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
|
|
getsockopt(sn, SO_STATUS, &status);
|
|
switch (status) {
|
|
case SOCK_ESTABLISHED :
|
|
ctlsocket(sn, CS_GET_INTERRUPT, &inter);
|
|
if (inter & Sn_IR_CON) { // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
#if 1
|
|
// 20231018 taylor
|
|
getsockopt(sn, SO_EXTSTATUS, &sn_status);
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("%d:Connected to - %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d\r\n", sn,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("%d:Connected to - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
#else
|
|
printf("%d:Connected to - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
|
#endif
|
|
#endif
|
|
arg_tmp8 = Sn_IR_CON;
|
|
ctlsocket(sn, CS_CLR_INTERRUPT, &arg_tmp8); // this interrupt should be write the bit cleared to '1'
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Data Transaction Parts; Handle the [data receive and send] process
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
getsockopt(sn, SO_RECVBUF, &received_size);
|
|
|
|
if (received_size > 0) { // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
|
|
if (received_size > DATA_BUF_SIZE) {
|
|
received_size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
|
|
}
|
|
ret = recv(sn, buf, received_size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
|
|
|
|
if (ret <= 0) {
|
|
return ret; // If the received data length <= 0, receive failed and process end
|
|
}
|
|
received_size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
getsockopt(sn, SO_EXTSTATUS, &sn_status);
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Received %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, received_size,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Received %d bytes from %d.%d.%d.%d port %d : \r\n", sn, received_size, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < received_size; i++) {
|
|
printf("%c", buf[i]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
|
|
// Data sentsize control
|
|
while (received_size != sentsize) {
|
|
ret = send(sn, buf + sentsize, received_size - sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
|
|
if (ret < 0) { // Send Error occurred (sent data length < 0)
|
|
close(sn); // socket close
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Sent back %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, sentsize,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Sent back %d bytes from %d.%d.%d.%d port %d : \r\n", sn, sentsize, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int j;
|
|
for (j = 0; j < sentsize; j++) {
|
|
printf("%c", buf[j]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
break;
|
|
|
|
case SOCK_CLOSE_WAIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:CloseWait\r\n", sn);
|
|
#endif
|
|
getsockopt(sn, SO_RECVBUF, &received_size);
|
|
|
|
if ((received_size = getSn_RX_RSR(sn)) > 0) { // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
|
|
if (received_size > DATA_BUF_SIZE) {
|
|
received_size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
|
|
}
|
|
ret = recv(sn, buf, received_size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
|
|
|
|
if (ret <= 0) {
|
|
return ret; // If the received data length <= 0, receive failed and process end
|
|
}
|
|
received_size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
getsockopt(sn, SO_EXTSTATUS, &sn_status);
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Received %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, received_size,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Received %d bytes from %d.%d.%d.%d port %d : \r\n", sn, received_size, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < received_size; i++) {
|
|
printf("%c", buf[i]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
|
|
// Data sentsize control
|
|
while (received_size != sentsize) {
|
|
ret = send(sn, buf + sentsize, received_size - sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
|
|
if (ret < 0) { // Send Error occurred (sent data length < 0)
|
|
close(sn); // socket close
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
if (sn_status & TCPSOCK_MODE) {
|
|
printf("Socket %d Sent back %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, sentsize,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
} else {
|
|
printf("Socket %d Sent back %d bytes from %d.%d.%d.%d port %d : \r\n", sn, sentsize, destip[0], destip[1], destip[2], destip[3], destport);
|
|
}
|
|
|
|
int j;
|
|
for (j = 0; j < sentsize; j++) {
|
|
printf("%c", buf[j]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
}
|
|
if ((ret = disconnect(sn)) != SOCK_OK) {
|
|
return ret;
|
|
}
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Socket Closed\r\n", sn);
|
|
#endif
|
|
break;
|
|
|
|
case SOCK_INIT :
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
if (loopback_mode == AS_IPV4) {
|
|
printf("%d:Try to connect to the %d.%d.%d.%d, %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
|
} else if (loopback_mode == AS_IPV6) {
|
|
printf("%d:Try to connect to the %04X:%04X", sn, ((uint16_t)destip[0] << 8) | ((uint16_t)destip[1]),
|
|
((uint16_t)destip[2] << 8) | ((uint16_t)destip[3]));
|
|
printf(":%04X:%04X", ((uint16_t)destip[4] << 8) | ((uint16_t)destip[5]),
|
|
((uint16_t)destip[6] << 8) | ((uint16_t)destip[7]));
|
|
printf(":%04X:%04X", ((uint16_t)destip[8] << 8) | ((uint16_t)destip[9]),
|
|
((uint16_t)destip[10] << 8) | ((uint16_t)destip[11]));
|
|
printf(":%04X:%04X,", ((uint16_t)destip[12] << 8) | ((uint16_t)destip[13]),
|
|
((uint16_t)destip[14] << 8) | ((uint16_t)destip[15]));
|
|
printf("%d\r\n", destport);
|
|
}
|
|
#endif
|
|
|
|
if (loopback_mode == AS_IPV4) {
|
|
ret = connect(sn, destip, destport, 4); /* Try to connect to TCP server(Socket, DestIP, DestPort) */
|
|
} else if (loopback_mode == AS_IPV6) {
|
|
ret = connect(sn, destip, destport, 16); /* Try to connect to TCP server(Socket, DestIP, DestPort) */
|
|
}
|
|
|
|
printf("SOCK Status: %d\r\n", ret);
|
|
|
|
if (ret != SOCK_OK) {
|
|
return ret; // Try to TCP connect to the TCP server (destination)
|
|
}
|
|
break;
|
|
|
|
case SOCK_CLOSED:
|
|
switch (loopback_mode) {
|
|
case AS_IPV4:
|
|
tmp = socket(sn, Sn_MR_TCP4, any_port++, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPV6:
|
|
tmp = socket(sn, Sn_MR_TCP6, any_port++, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPDUAL:
|
|
tmp = socket(sn, Sn_MR_TCPD, any_port++, SOCK_IO_NONBLOCK);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (tmp != sn) { /* reinitialize the socket */
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d : Fail to create socket.\r\n", sn);
|
|
#endif
|
|
return SOCKERR_SOCKNUM;
|
|
}
|
|
printf("%d:Socket opened[%d]\r\n", sn, getSn_SR(sn));
|
|
sock_state[sn] = 1;
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port) {
|
|
check_loopback_mode_W6x00();
|
|
uint8_t status;
|
|
static uint8_t destip[16] = {0,};
|
|
static uint16_t destport;
|
|
uint8_t pack_info;
|
|
uint8_t addr_len;
|
|
uint16_t ret;
|
|
uint16_t received_size;
|
|
uint16_t size, sentsize;
|
|
uint8_t* mode_msg;
|
|
|
|
if (loopback_mode == AS_IPV4) {
|
|
mode_msg = msg_v4;
|
|
} else if (loopback_mode == AS_IPV6) {
|
|
mode_msg = msg_v6;
|
|
} else {
|
|
mode_msg = msg_dual;
|
|
}
|
|
|
|
getsockopt(sn, SO_STATUS, &status);
|
|
switch (status) {
|
|
case SOCK_UDP:
|
|
getsockopt(sn, SO_RECVBUF, &received_size);
|
|
if (received_size > DATA_BUF_SIZE) {
|
|
received_size = DATA_BUF_SIZE;
|
|
}
|
|
if (received_size > 0) {
|
|
ret = recvfrom(sn, buf, received_size, (uint8_t*)&destip, (uint16_t*)&destport, &addr_len);
|
|
|
|
if (ret <= 0) {
|
|
return ret;
|
|
}
|
|
received_size = (uint16_t) ret;
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
if (addr_len == 4) {
|
|
printf("Socket %d Received %d bytes from %d.%d.%d.%d port %d : \r\n", sn, received_size, destip[0], destip[1], destip[2], destip[3], destport);
|
|
} else {
|
|
printf("Socket %d Received %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, received_size,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < received_size; i++) {
|
|
printf("%c", buf[i]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
sentsize = 0;
|
|
while (sentsize != received_size) {
|
|
ret = sendto(sn, buf + sentsize, received_size - sentsize, destip, destport, addr_len);
|
|
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
#if 1
|
|
// 20231018 taylor
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
int j;
|
|
if (addr_len == 4) {
|
|
printf("Socket %d Sent back %d bytes from %d.%d.%d.%d port %d : \r\n", sn, sentsize, destip[0], destip[1], destip[2], destip[3], destport);
|
|
} else {
|
|
printf("Socket %d Sent back %d bytes from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %d : \r\n",
|
|
sn, sentsize,
|
|
destip[0], destip[1], destip[2], destip[3],
|
|
destip[4], destip[5], destip[6], destip[7],
|
|
destip[8], destip[9], destip[10], destip[11],
|
|
destip[12], destip[13], destip[14], destip[15],
|
|
destport);
|
|
}
|
|
for (j = 0; j < sentsize; j++) {
|
|
printf("%c", buf[j]);
|
|
}
|
|
printf("\r\n");
|
|
#endif
|
|
#endif
|
|
}
|
|
break;
|
|
case SOCK_CLOSED:
|
|
|
|
switch (loopback_mode) {
|
|
case AS_IPV4:
|
|
socket(sn, Sn_MR_UDP4, port, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPV6:
|
|
socket(sn, Sn_MR_UDP6, port, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPDUAL:
|
|
socket(sn, Sn_MR_UDPD, port, SOCK_IO_NONBLOCK);
|
|
break;
|
|
}
|
|
printf("%d:Opened, UDP loopback, port [%d] as %s\r\n", sn, port, mode_msg);
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int32_t loopback_udpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) {
|
|
check_loopback_mode_W6x00();
|
|
int32_t ret;
|
|
uint16_t size = 0, sentsize = 0;
|
|
static uint16_t any_port = 50000;
|
|
uint8_t addr_len;
|
|
|
|
|
|
uint8_t* mode_msg;
|
|
if (loopback_mode == AS_IPV4) {
|
|
mode_msg = msg_v4;
|
|
} else if (loopback_mode == AS_IPV6) {
|
|
mode_msg = msg_v6;
|
|
} else {
|
|
mode_msg = msg_dual;
|
|
}
|
|
|
|
// uint8_t* strtest = "\r\nhello world";
|
|
// uint8_t flag = 0;
|
|
switch (getSn_SR(sn)) {
|
|
case SOCK_UDP :
|
|
// sendto(sn, strtest, strlen(strtest), destip, destport);
|
|
if ((size = getSn_RX_RSR(sn)) > 0) {
|
|
if (size > DATA_BUF_SIZE) {
|
|
size = DATA_BUF_SIZE;
|
|
}
|
|
ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport, &addr_len);
|
|
buf[ret] = 0x00;
|
|
printf("recv form[%d.%d.%d.%d][%d]: %s\n", destip[0], destip[1], destip[2], destip[3], destport, buf);
|
|
if (ret <= 0) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d: recvfrom error. %ld\r\n", sn, ret);
|
|
#endif
|
|
return ret;
|
|
}
|
|
size = (uint16_t) ret;
|
|
sentsize = 0;
|
|
while (sentsize != size) {
|
|
ret = sendto(sn, buf + sentsize, size - sentsize, destip, destport, addr_len);
|
|
if (ret < 0) {
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d: sendto error. %ld\r\n", sn, ret);
|
|
#endif
|
|
return ret;
|
|
}
|
|
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
|
}
|
|
}
|
|
break;
|
|
case SOCK_CLOSED:
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
// printf("%d:UDP loopback start\r\n",sn);
|
|
#endif
|
|
|
|
switch (loopback_mode) {
|
|
case AS_IPV4:
|
|
socket(sn, Sn_MR_UDP4, destport, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPV6:
|
|
socket(sn, Sn_MR_UDP6, destport, SOCK_IO_NONBLOCK);
|
|
break;
|
|
case AS_IPDUAL:
|
|
socket(sn, Sn_MR_UDPD, destport, SOCK_IO_NONBLOCK);
|
|
break;
|
|
}
|
|
printf("%d:Opened, UDP loopback, port [%d] as %s\r\n", sn, destport, mode_msg);
|
|
#ifdef _LOOPBACK_DEBUG_
|
|
printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, any_port);
|
|
#endif
|
|
break;
|
|
default :
|
|
break;
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|