Files
w5500-eth/Application/loopback/loopback.c
2025-12-10 17:55:05 +03:00

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