#include #include "loopback.h" #include "socket.h" #include "wizchip_conf.h" /* 【新增】引入多串口路由模块 */ #include "multi_uart_router.h" #include "main.h" #if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK /** * @brief tcp server loopback test * @param sn: socket number * @param buf: Data sending and receiving cache * @param port: Listen port * @return value for SOCK_ERRORs,return 1:no error */ 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 // We need to send a packet of data to activate keepalive ret = send(sn, (uint8_t *)"", 1); // Data send process if (ret < 0) // Send Error occurred (sent data length < 0) { close(sn); // socket close return ret; } 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; buf[size] = 0x00; printf("rece data:%s\r\n", buf); 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; } /** * @brief tcp client loopback test * @param sn: socket number * @param buf: Data sending and receiving cache * @param destip: Destination IP address * @param destport: Destination port * @return value for SOCK_ERRORs,return 1:no error */ 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 dip[4] = {192, 168, 0, 214}; uint16_t dport = 5000; getSn_DIPR(sn, dip); dport = getSn_DPORT(sn); // 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 { // We need to send a packet of data to activate keepalive ret = send(sn, (uint8_t *)"", 1); // Data send process if (ret < 0) // Send Error occurred (sent data length < 0) { close(sn); // socket close return ret; } #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) buf[size] = 0x00; printf("rece from %d.%d.%d.%d:%d data:%s\r\n", dip[0], dip[1], dip[2], dip[3], dport, buf); 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; } /** * @brief udp server mode loopback test * @param sn: socket number * @param buf: Data sending and receiving cache * @param port: Local port * @return value for SOCK_ERRORs,return 1:no error */ 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); buf[ret] = 0x00; printf("recv form[%d.%d.%d.%d][%d]: %s\r\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; /* ========================================================== * /* 🚀 核心修改:网络数据透传时,加上 [0xAA] 和设备 ID */ uint8_t tx_buf[2048]; // 1. 添加统一的空中协议头 (0xAA + ID) tx_buf[0] = 0xAA; tx_buf[1] = MY_DEVICE_ID; // 2. 把网络标识 "[NET]" 写进数组,注意要从第 2 个字节开始写 int tag_len = sprintf((char*)&tx_buf[2], "[NET]"); // 3. 把网络收到的真实数据 (buf) 紧挨着拼接到后面 memcpy(&tx_buf[2 + tag_len], buf, size); // 4. 把拼接好的整串数据 (头 + ID + [NET] + 数据) 发给 RF433 MultiUART_Send(PORT_UART1, tx_buf, 2 + tag_len + size); /* ========================================================== */ 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; } /** * @brief udp client loopback test * @param sn: socket number * @param buf: Data sending and receiving cache * @param destip: Destination IP address * @param destport: Destination port * @return value for SOCK_ERRORs,return 1:no error */ 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"; 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\r\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; } #endif