Files
433_STM32/User/Loopback/loopback.c

356 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include "loopback.h"
#include "socket.h"
#include "wizchip_conf.h"
/* 【新增】引入多串口路由模块 */
#include "multi_uart_router.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;
/* ========================================================== *
/* :只在数据前加一个 [NET] 标识,直接透传 */
uint8_t tx_buf[2048]; // 申请一个足够大的临时数组存放拼接后的数据
// 1. 先把网络标识 "[NET]" 写进数组头部tag_len 会自动等于 5
int tag_len = sprintf((char*)tx_buf, "[NET]");
// 2. 把网络收到的真实数据 (buf) 紧挨着标识拼接到后面
memcpy(tx_buf + tag_len, buf, size);
// 3. 把拼接好的整串数据直接发给 RF433
MultiUART_Send(PORT_UART1, tx_buf, 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