controller-pcba/User/application/src/tcpserverc.c

807 lines
28 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 "tcpserverc.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/init.h"
#include "netif/etharp.h"
#include "lwip/udp.h"
#include "lwip/pbuf.h"
#include <stdio.h>
#include <string.h>
#include "usart.h"
#include "main.h"
#include "ht1200m.h"
#include "user_lib.h"
#include "communication_protocol.h"
#include "user_gpio.h"
#include "tim.h"
struct tcp_pcb *server_pcb_hart1 = NULL;
struct tcp_pcb *server_pcb_hart2 = NULL;
struct tcp_pcb *server_pcb_ble1 = NULL;
struct tcp_pcb *server_pcb_ble2 = NULL;
struct tcp_pcb *server_pcb_control = NULL;
communication_di_t *user_communication_di = NULL;
communication_do_t *user_communication_do = NULL;
communication_ai_t *user_communication_ai = NULL;
communication_ao_t *user_communication_ao = NULL;
comnmunication_encoder_t *user_communication_encoder = NULL;
extern uint8_t tcp_echo_flags_hart1;
extern uint8_t tcp_echo_flags_hart2;
extern uint8_t tcp_echo_flags_ble1;
extern uint8_t tcp_echo_flags_ble2;
extern uint8_t tcp_echo_flags_control;
extern uint8_t send_data_flag_cmd;
extern uint8_t uart_echo_flags_hart1;
extern uint8_t uart_echo_flags_hart2;
extern uint8_t uart_echo_flags_ble1;
extern uint8_t uart_echo_flags_ble2;
#define head_00 0xD5 // 帧头1
#define head_01 0xC8 // 帧头2
uint16_t data_len = 0; // 帧体长度
#define source_addr_h 0x01 // 源地址高
#define source_addr_l 0x02 // 源地址低
#define target_addr_h 0x0A // 目标地址高
#define target_addr_l 0x0B // 目标地址低
uint16_t reply_type = 0x00;// 报文类型_应答
uint8_t enable_data[7] = {
0x03, // Byte 0: 蓝牙 + WIFI
0x00, // Byte 1: 预留
0xFF, // Byte 2: 恒压输出 + 模拟输出(全使能)
0x0F, // Byte 3: 电磁阀1-3 + IO扩展2
0x00, // Byte 4: 预留
0x00, // Byte 5: 预留
0x00 // Byte 6: 预留
};
uint8_t adc_read_data[22] = {
0x0C,0x80,// 恒压输出1高字节, 恒压输出1低字节,
0x0C,0x80,// 恒压输出2高字节, 恒压输出2低字节,
0x0C,0x80,// 模拟输出1高字节, 模拟输出1低字节,
0x0C,0x80,// 模拟输出2高字节, 模拟输出2低字节,
0x0C,0x80,// 模拟输出3高字节, 模拟输出3低字节,
0x0C,0x80,// 模拟输出4高字节, 模拟输出4低字节,
0x0C,0x80,// 模拟输出5高字节, 模拟输出5低字节,
0x0C,0x80,// 模拟输出6高字节, 模拟输出6低字节,
0x0C,0x80,// 输出目标设备4 - 20mA高字节, 输出目标设备4 - 20mA低字节,
0x0C,0x80,// 比例阀1输出高字节, 比例阀1输出低字节,
0x0C,0x80,// 比例阀2输出高字节, 比例阀2输出低字节
};
uint8_t adc_set_data[22] = {
0x0D,0xF0,// 恒压输出1高字节, 恒压输出1低字节,
0x0D,0xF0,// 恒压输出2高字节, 恒压输出2低字节,
0x0D,0xF0,// 模拟输出1高字节, 模拟输出1低字节,
0x0D,0xF0,// 模拟输出2高字节, 模拟输出2低字节,
0x0D,0xF0,// 模拟输出3高字节, 模拟输出3低字节,
0x0D,0xF0,// 模拟输出4高字节, 模拟输出4低字节,
0x0D,0xF0,// 模拟输出5高字节, 模拟输出5低字节,
0x0D,0xF0,// 模拟输出6高字节, 模拟输出6低字节,
0x0D,0xF0,// 输出目标设备4 - 20mA高字节, 输出目标设备4 - 20mA低字节,
0x0D,0xF0,// 比例阀1输出高字节, 比例阀1输出低字节,
0x0D,0xF0,// 比例阀2输出高字节, 比例阀2输出低字节
};
// 假设数据按高字节到低字节排列
// 定义数组存放数据总字节数根据表格计算为2 + 4×18 = 74 字节
uint8_t test_adc_read_data[74] = {
// IO扩展1高字节, IO扩展1低字节
0x12, 0x34,
// ADC(通道1)高字节1, ADC(通道1)高字节2, ADC(通道1)低字节1, ADC(通道1)低字节2
0x01, 0x02, 0x03, 0x04,
// ADC(通道2)高字节1, ADC(通道2)高字节2, ADC(通道2)低字节1, ADC(通道2)低字节2
0x05, 0x06, 0x07, 0x08,
// ADC(通道3)高字节1, ADC(通道3)高字节2, ADC(通道3)低字节1, ADC(通道3)低字节2
0x09, 0x0A, 0x0B, 0x0C,
// ADC(通道4)高字节1, ADC(通道4)高字节2, ADC(通道4)低字节1, ADC(通道4)低字节2
0x0D, 0x0E, 0x0F, 0x10,
// ADC(通道5)高字节1, ADC(通道5)高字节2, ADC(通道5)低字节1, ADC(通道5)低字节2
0x11, 0x12, 0x13, 0x14,
// ADC(通道6)高字节1, ADC(通道6)高字节2, ADC(通道6)低字节1, ADC(通道6)低字节2
0x15, 0x16, 0x17, 0x18,
// ADC(通道7)高字节1, ADC(通道7)高字节2, ADC(通道7)低字节1, ADC(通道7)低字节2
0x19, 0x1A, 0x1B, 0x1C,
// ADC(通道8)高字节1, ADC(通道8)高字节2, ADC(通道8)低字节1, ADC(通道8)低字节2
0x1D, 0x1E, 0x1F, 0x20,
// ADC(通道9)高字节1, ADC(通道9)高字节2, ADC(通道9)低字节1, ADC(通道9)低字节2
0x21, 0x22, 0x23, 0x24,
// ADC(通道10)高字节1, ADC(通道10)高字节2, ADC(通道10)低字节1, ADC(通道10)低字节2
0x25, 0x26, 0x27, 0x28,
// ADC(通道11)高字节1, ADC(通道11)高字节2, ADC(通道11)低字节1, ADC(通道11)低字节2
0x29, 0x2A, 0x2B, 0x2C,
// ADC(通道12)高字节1, ADC(通道12)高字节2, ADC(通道12)低字节1, ADC(通道12)低字节2
0x2D, 0x2E, 0x2F, 0x30,
// ADC(通道13)高字节1, ADC(通道13)高字节2, ADC(通道13)低字节1, ADC(通道13)低字节2
0x31, 0x32, 0x33, 0x34,
// ADC(通道14)高字节1, ADC(通道14)高字节2, ADC(通道14)低字节1, ADC(通道14)低字节2
0x35, 0x36, 0x37, 0x38,
// ADC(通道15)高字节1, ADC(通道15)高字节2, ADC(通道15)低字节1, ADC(通道15)低字节2
0x39, 0x3A, 0x3B, 0x3C,
// ADC(通道16)高字节1, ADC(通道16)高字节2, ADC(通道16)低字节1, ADC(通道16)低字节2
0x3D, 0x3E, 0x3F, 0x40,
// 比例阀1输入高字节1, 比例阀1输入高字节2, 比例阀1输入低字节1, 比例阀1输入低字节2
0x41, 0x42, 0x43, 0x44,
// 比例阀2输入高字节1, 比例阀2输入高字节2, 比例阀2输入低字节1, 比例阀2输入低字节2
0x45, 0x46, 0x47, 0x48
};
// 校验和函数
uint8_t calc_checksum(const uint8_t *data, uint8_t start, uint8_t end) {
uint8_t checksum = 0;
for (uint8_t i = start; i <= end; i++) {
checksum += data[i];
}
return checksum;
}
// body: 报文体指针, body_len: 报文体长度, tx: 返回帧缓冲区, 返回帧总长度
uint16_t handle_type_80(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + body_len + 2; // 帧头+帧长+源+目标+类型+体+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 报文体
tx[9] = 0x01;//执行成功
//memcpy(&tx[9], body, body_len);
// 校验和(累加源地址到报文体)
uint16_t checksum = 0;
for (int i = 4; i < 9 + body_len; ++i)
{
checksum += tx[i];
}
// 校验和2字节大端
tx[total_len - 2] = 0x00;//校验和只取低八位
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_81(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + body_len + 2; // 帧头+帧长+源+目标+类型+体+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 报文体
tx[9] = 0x01;//主版本号1.0
tx[10] = 0x00;//次版本号0.0
//memcpy(&tx[9], body, body_len);
// 校验和(累加源地址到报文体)
uint16_t checksum = 0;
for (int i = 4; i < 9 + body_len; ++i)
{
checksum += tx[i];
}
// 校验和2字节大端
tx[total_len - 2] = 0x00;//校验和只取低八位
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_82(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + body_len + 2; // 帧头+帧长+源+目标+类型+体+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 报文体
tx[9] = 0xBC;//心跳回复
// 校验和(累加源地址到报文体)
uint16_t checksum = 0;
for (int i = 4; i < 9 + body_len; ++i)
{
checksum += tx[i];
}
// 校验和2字节大端
//tx[total_len - 2] = (checksum >> 8) & 0xFF;
tx[total_len - 2] =0x00;//校验和只取低八位
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_83(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
// 检查 body_len 是否为7如果不是则返回错误可选
if (body_len != 7) {
return 0; // 或返回错误码
}
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 7 + 2; // 帧头+帧长+源+目标+类型+7字节使能+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 7字节使能状态直接复制 body 到 tx[9]~tx[15]
memcpy(&tx[9], body, 7); // 确保 body 是7字节
// 校验和累加源地址到7字节使能数据
uint16_t checksum = 0;
for (int i = 4; i < 16; ++i) // 4~15源地址+目标地址+类型+7字节使能
{
checksum += tx[i];
}
// 校验和2字节大端只取低8位
tx[total_len - 2] = 0x00; // 高8位强制为0如果协议要求
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_84(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + body_len + 2; // 帧头+帧长+源+目标+类型+体+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 报文体
memcpy(&tx[9], body, body_len);//发啥回啥
// 校验和(累加源地址到报文体)
uint16_t checksum = 0;
for (int i = 4; i < 9 + body_len; ++i)
{
checksum += tx[i];
}
// 校验和2字节大端
tx[total_len - 2] = 0x00;//校验和只取低八位
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_85(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 22 + 2; // 帧头+帧长+源+目标+类型+22字节输出读取+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 7字节使能状态直接复制 body 到 tx[9]~tx[15]
memcpy(&tx[9], body, 22); // 确保 body 是22字节
// 校验和
uint16_t checksum = 0;
for (int i = 4; i < 32; ++i) // 4~32源地址+目标地址+类型+22字节
{
checksum += tx[i];
}
// 校验和2字节大端只取低8位
tx[total_len - 2] = 0x00; // 高8位强制为0如果协议要求
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_86(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 22 + 2; // 帧头+帧长+源+目标+类型+22字节输出读取+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 7字节使能状态直接复制 body 到 tx[9]~tx[15]
memcpy(&tx[9], body, 22); // 确保 body 是22字节
// 校验和
uint16_t checksum = 0;
for (int i = 4; i < 32; ++i) // 4~31源地址+目标地址+类型+22字节
{
checksum += tx[i];
}
// 校验和2字节大端只取低8位
tx[total_len - 2] = 0x00; // 高8位强制为0如果协议要求
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
uint16_t handle_type_87(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 74 + 2; // 帧头+帧长+源+目标+类型+74字节输出读取+校验
// 帧头
tx[0] = head_00;
tx[1] = head_01;
// 帧长度(大端)
tx[2] = (total_len >> 8) & 0xFF;
tx[3] = total_len & 0xFF;
// 源地址
tx[4] = source_addr_h;
tx[5] = source_addr_l;
// 目标地址
tx[6] = target_addr_h;
tx[7] = target_addr_l;
// 报文类型
tx[8] = reply_type;
// 7字节使能状态直接复制 body 到 tx[9]~tx[15]
memcpy(&tx[9], body, 74); // 确保 body 是74字节
// 校验和
uint16_t checksum = 0;
for (int i = 4; i < 84; ++i) // 4~83源地址+目标地址+类型+74字节
{
checksum += tx[i];
}
// 校验和2字节大端只取低8位
tx[total_len - 2] = 0x00; // 高8位强制为0如果协议要求
tx[total_len - 1] = checksum & 0xFF;
return total_len;
}
/*接收回调函数*/
static err_t tcpecho_recv_hart1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{ // 对应接收数据连接的控制块 接收到的数据
if (p != NULL)
{
/* 更新窗口*/
tcp_echo_flags_hart1 = 1;
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_hart1 = tpcb; // 直接赋值
memcpy(hart1_uart5.tx_data, (int *)p->payload, p->tot_len);
if (huart5.gState == HAL_UART_STATE_READY)
{
HART1_RTS_SEND;
dma_usart_send(&huart5, hart1_uart5.tx_data, p->tot_len);
}
pbuf_free(p);
}
else if (err == ERR_OK) // 检测到对方主动关闭连接时也会调用recv函数此时p为空
{
// HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
tcp_echo_flags_hart1 = 0;
return tcp_close(tpcb);
}
return ERR_OK;
}
static err_t tcpecho_recv_hart2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{ // 对应接收数据连接的控制块 接收到的数据
if (p != NULL)
{
/* 更新窗口*/
tcp_echo_flags_hart2 = 1;
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_hart2 = tpcb; // 直接赋值
memcpy(hart2_uart2.tx_data, (int *)p->payload, p->tot_len);
if (huart2.gState == HAL_UART_STATE_READY)
{
HART2_RTS_SEND;
dma_usart_send(&huart2, hart2_uart2.tx_data, p->tot_len);
}
pbuf_free(p);
}
else if (err == ERR_OK) // 检测到对方主动关闭连接时也会调用recv函数此时p为空
{
// HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
tcp_echo_flags_hart2 = 0;
return tcp_close(tpcb);
}
return ERR_OK;
}
#if (BLE2_USART6 == 1)
static err_t tcpecho_recv_ble1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{ // 对应接收数据连接的控制块 接收到的数据
if (p != NULL)
{
/* 更新窗口*/
tcp_echo_flags_ble1 = 1;
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_ble1 = tpcb; // 直接赋值
memcpy(ble1_uart6.tx_data, (int *)p->payload, p->tot_len);
if (huart6.gState == HAL_UART_STATE_READY)
{
dma_usart_send(&huart6, ble1_uart6.tx_data, p->tot_len);
}
pbuf_free(p);
}
else if (err == ERR_OK) // 检测到对方主动关闭连接时也会调用recv函数此时p为空
{
return tcp_close(tpcb);
}
return ERR_OK;
}
#endif
static err_t tcpecho_recv_ble2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{ // 对应接收数据连接的控制块 接收到的数据
if (p != NULL)
{
/* 更新窗口*/
tcp_echo_flags_ble2 = 1;
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_ble2 = tpcb; // 直接赋值
memcpy(ble2_uart3.tx_data, (int *)p->payload, p->tot_len);
if (huart3.gState == HAL_UART_STATE_READY)
{
dma_usart_send(&huart3, ble2_uart3.tx_data, p->tot_len);
}
pbuf_free(p);
}
else if (err == ERR_OK) // 检测到对方主动关闭连接时也会调用recv函数此时p为空
{
// HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
tcp_echo_flags_ble2 = 0;
return tcp_close(tpcb);
}
return ERR_OK;
}
static err_t tcpecho_recv_control(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
uint8_t tcp_rx_data[128] = {0};
uint8_t tcp_tx_data[128] = {0};
uint8_t rx_data_len = 0;
uint8_t tx_data_len = 0;
if (p != NULL)
{
tcp_echo_flags_control = 1;
tcp_recved(tpcb, p->tot_len);
server_pcb_control = tpcb;
memcpy(tcp_rx_data, (uint8_t *)p->payload, p->tot_len);
rx_data_len = p->tot_len;
// 基本帧头校验,帧长和固定帧头
if (rx_data_len == tcp_rx_data[3] && tcp_rx_data[0] == 0xD5 && tcp_rx_data[1] == 0xC8)
{
uint8_t calc_sum = 0; // 改用uint8_t自动取低8位
for (int i = 4; i < rx_data_len - 1; i++)
{
calc_sum += tcp_rx_data[i];
}
uint8_t recv_sum = tcp_rx_data[rx_data_len - 1]; // 只取最后一个字节作为校验和
if (calc_sum != recv_sum)
{
pbuf_free(p);
return ERR_OK;
}
// 根据报文类型分发
switch (tcp_rx_data[8])
{
case 0x80: //复位
{
uint16_t body_len = rx_data_len - 11; //报文体长度 = 总长度 - 2(帧头) - 2(帧长) - 2(源) - 2(目标) - 1(类型) - 2(校验)
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_80(tcp_rx_data + 9, body_len, tcp_tx_data);
break;
}
case 0x81://查询版本号
{
uint16_t body_len = 2; //报文体有主次2个字节
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_81(tcp_rx_data + 9, body_len, tcp_tx_data);
break;
}
case 0x82://心跳请求
{
uint16_t body_len = 1; //心跳报文体有1个字节
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_82(tcp_rx_data + 9, body_len, tcp_tx_data);
break;
}
case 0x83://读取模块使能状态
{
uint16_t body_len = 7; //7个字节表示的是各个模块的使能状态
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_83(enable_data, body_len, tcp_tx_data);
}
break;
case 0x84://设置模块使能状态
{
uint16_t body_len = 7; //7个字节表示的是各个模块的使能状态
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_84(tcp_rx_data + 9, body_len, tcp_tx_data);
}
break;
case 0x85://读取读取配置参数
{
uint16_t body_len = 22; //22个字节表示的是输出参数
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_85(adc_read_data, body_len, tcp_tx_data);
}
break;
case 0x86://设置配置参数
{
uint16_t body_len = 22; //22个字节表示的是设置的参数
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_86(adc_set_data, body_len, tcp_tx_data);
}
break;
case 0x87://读取测试数据
{
uint16_t body_len = 74; //22个字节表示的是设置的参数
reply_type = tcp_rx_data[8];
tx_data_len = handle_type_87(test_adc_read_data, body_len, tcp_tx_data);
}
break;
case 0x88://透传数据
{
}
break;
default:
pbuf_free(p);
return ERR_OK;
}
// 发送返回帧
if (tx_data_len > 0)
{
if (tcp_write(tpcb, tcp_tx_data, tx_data_len, 1) != ERR_OK)
{
pbuf_free(p);
return ERR_MEM;
}
tcp_output(tpcb);
}
pbuf_free(p);
}
}
else if (err == ERR_OK)
{
tcp_echo_flags_control = 0;
return tcp_close(tpcb);
}
return ERR_OK;
}
static err_t tcpecho_accept_hart1(void *arg, struct tcp_pcb *newpcb, err_t err) // 由于这个函数是*tcp_accept_fn类型的形参的数量和类型必须一致
{
tcp_recv(newpcb, tcpecho_recv_hart1); // 当收到数据时回调用户自己写的tcpecho_recv
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 停止蜂鸣器PWM输出用于关闭蜂鸣器发声
return ERR_OK;
}
static err_t tcpecho_accept_hart2(void *arg, struct tcp_pcb *newpcb, err_t err) // 由于这个函数是*tcp_accept_fn类型的
{
tcp_recv(newpcb, tcpecho_recv_hart2); // 当收到数据时回调用户自己写的tcpecho_recv
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 停止蜂鸣器PWM输出用于关闭蜂鸣器发声
return ERR_OK;
}
#if (BLE2_USART6 == 1)
static err_t tcpecho_accept_ble1(void *arg, struct tcp_pcb *newpcb, err_t err) // 由于这个函数是*tcp_accept_fn类型的
{
tcp_recv(newpcb, tcpecho_recv_ble1); // 当收到数据时回调用户自己写的tcpecho_recv
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 停止蜂鸣器PWM输出用于关闭蜂鸣器发声
return ERR_OK;
}
#endif
static err_t tcpecho_accept_ble2(void *arg, struct tcp_pcb *newpcb, err_t err) // 由于这个函数是*tcp_accept_fn类型的
{
tcp_recv(newpcb, tcpecho_recv_ble2); // 当收到数据时回调用户自己写的tcpecho_recv
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 停止蜂鸣器PWM输出用于关闭蜂鸣器发声
return ERR_OK;
}
static err_t tcpecho_accept_control(void *arg, struct tcp_pcb *newpcb, err_t err) // 由于这个函数是*tcp_accept_fn类型的
{
tcp_recv(newpcb, tcpecho_recv_control); // 当收到数据时回调用户自己写的tcpecho_recv
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 停止蜂鸣器PWM输出用于关闭蜂鸣器发声
return ERR_OK;
}
void tcp_echo_init(void)
{
struct tcp_pcb *server_hart1 = NULL;
struct tcp_pcb *server_hart2 = NULL;
#if (BLE2_USART6 == 1)
struct tcp_pcb *server_ble1 = NULL;
#endif
struct tcp_pcb *server_ble2 = NULL;
struct tcp_pcb *server_control = NULL;
/* 创建一路HART */
server_hart1 = tcp_new();
/* 绑定TCP控制块 */
tcp_bind(server_hart1, IP_ADDR_ANY, TCP_PORT_HART1);
/* 进入监听状态 */
server_hart1 = tcp_listen(server_hart1);
/* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */
tcp_accept(server_hart1, tcpecho_accept_hart1); // 侦听到连接后回调用户编写的tcpecho_accept
/* 创建二路HART */
server_hart2 = tcp_new();
/* 绑定TCP控制块 */
tcp_bind(server_hart2, IP_ADDR_ANY, TCP_PORT_HART2);
/* 进入监听状态 */
server_hart2 = tcp_listen(server_hart2);
/* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */
tcp_accept(server_hart2, tcpecho_accept_hart2); // 侦听到连接后回调用户编写的tcpecho_accept
#if (BLE2_USART6 == 1)
/* 创建一路蓝牙 */
server_ble1 = tcp_new();
/* 绑定TCP控制块 */
tcp_bind(server_ble1, IP_ADDR_ANY, TCP_PORT_BLE1);
/* 进入监听状态 */
server_ble1 = tcp_listen(server_ble1);
/* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */
tcp_accept(server_ble1, tcpecho_accept_ble1); // 侦听到连接后回调用户编写的tcpecho_accept
#endif
/* 创建二路蓝牙 */
server_ble2 = tcp_new();
/* 绑定TCP控制块 */
tcp_bind(server_ble2, IP_ADDR_ANY, TCP_PORT_BLE2);
/* 进入监听状态 */
server_ble2 = tcp_listen(server_ble2);
/* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */
tcp_accept(server_ble2, tcpecho_accept_ble2); // 侦听到连接后回调用户编写的tcpecho_accept
/* 创建控制块 */
server_control = tcp_new();
/* 绑定TCP控制块 */
tcp_bind(server_control, IP_ADDR_ANY, TCP_PORT_CONTROL);
/* 进入监听状态 */
server_control = tcp_listen(server_control);
/* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */
tcp_accept(server_control, tcpecho_accept_control); // 侦听到连接后回调用户编写的tcpecho_accept
}
void user_send_data_hart1(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_hart1, data, len, 1);
}
void user_send_data_hart2(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_hart2, data, len, 1);
}
#if (BLE2_USART6 == 1)
void user_send_data_ble1(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_ble1, data, len, 1);
}
#endif
void user_send_data_ble2(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_ble2, data, len, 1);
}
void user_send_data_control(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_control, data, len, 1);
}
void uart_forwarding_tcp(void)
{
if (uart_echo_flags_hart1 == 1)
{
uart_echo_flags_hart1 = 0;
user_send_data_hart1(hart1_uart5.rx_data, hart1_uart5.rx_num);
}
if (uart_echo_flags_hart2 == 1)
{
uart_echo_flags_hart2 = 0;
user_send_data_hart2(hart2_uart2.rx_data, hart2_uart2.rx_num);
}
#if (BLE2_USART6 == 1)
if (uart_echo_flags_ble1 == 1)
{
uart_echo_flags_ble1 = 0;
user_send_data_ble1(ble1_uart6.rx_data, ble1_uart6.rx_num);
}
#endif
if (uart_echo_flags_ble2 == 1)
{
uart_echo_flags_ble2 = 0;
user_send_data_ble2(ble2_uart3.rx_data, ble2_uart3.rx_num);
}
}