401 lines
15 KiB
C
401 lines
15 KiB
C
#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_forwarding_flags_hart1;
|
||
extern uint8_t uart_forwarding_flags_hart2;
|
||
extern uint8_t uart_forwarding_flags_ble1;
|
||
extern uint8_t uart_forwarding_flags_ble2;
|
||
/*接收回调函数*/
|
||
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;
|
||
communication_data_u communication_data;
|
||
if (p != NULL)
|
||
{
|
||
tcp_echo_flags_control = 1;
|
||
/* 更新窗口*/
|
||
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
|
||
server_pcb_control = tpcb; // 直接赋值
|
||
memcpy(tcp_rx_data, (int *)p->payload, p->tot_len);
|
||
rx_data_len = p->tot_len;
|
||
/*1. 对接收的数据做异或校验、帧头帧尾判断,校验失败返回信息,校验通过继续下一步、校验数据从帧头后面到校验位结束*/
|
||
if (tcp_rx_data[0] != 0xAA || tcp_rx_data[rx_data_len - 1] != 0x3C) // 帧头帧尾判断
|
||
{
|
||
tx_data_len = COM_ERROR_CODE_SIZE;
|
||
communication_exception(tcp_tx_data, tcp_rx_data, FRAMING_ERROR);
|
||
tcp_write(tpcb, tcp_tx_data, tx_data_len, 1);
|
||
}
|
||
else
|
||
{
|
||
if (tcp_rx_data[rx_data_len - 2] != xor_compute(tcp_rx_data + 1, rx_data_len - 3)) // 异或校验
|
||
{
|
||
tx_data_len = COM_ERROR_CODE_SIZE;
|
||
communication_exception(tcp_tx_data, tcp_rx_data, CHECK_ERROR);
|
||
tcp_write(tpcb, tcp_tx_data, tx_data_len, 1);
|
||
}
|
||
else
|
||
{
|
||
memcpy(communication_data.data, tcp_rx_data + 5, tcp_rx_data[4]);
|
||
if (tcp_rx_data[3] == READ_ANALOG_CMD) // 读模拟量指令
|
||
{
|
||
/*读操作,从寄存器读取数据,组包返回*/
|
||
tx_data_len = COM_AI_DATA_SIZE;
|
||
user_communication_ai = &communication_data.ai_data;
|
||
communication_get_ai(user_communication_ai, tcp_tx_data, tcp_rx_data);
|
||
tcp_write(tpcb, tcp_tx_data, tx_data_len, 1);
|
||
}
|
||
else if (tcp_rx_data[3] == WRITE_ANALOG_CMD) // 写模拟量指令
|
||
{
|
||
/*写操作,将数据写入寄存器,组包返回*/
|
||
|
||
user_communication_ao = &communication_data.ao_data;
|
||
communication_set_ao(user_communication_ao);
|
||
tcp_write(tpcb, tcp_rx_data, rx_data_len, 1);
|
||
}
|
||
else if (tcp_rx_data[3] == READ_DIGITAL_CMD) // 读数字量指令
|
||
{
|
||
/*读操作,从寄存器读取数据,组包返回*/
|
||
|
||
user_communication_di = &communication_data.di_data;
|
||
tx_data_len = 7 + user_communication_di->num;
|
||
user_read_gpio(user_communication_di, tcp_tx_data, tcp_rx_data);
|
||
tcp_write(tpcb, tcp_tx_data, tx_data_len, 1);
|
||
}
|
||
else if (tcp_rx_data[3] == WRITE_DIGITAL_CMD) // 写数字量指令
|
||
{
|
||
/*写操作,将数据写入寄存器,组包返回*/
|
||
user_communication_do = &communication_data.do_data;
|
||
user_write_gpio(user_communication_do);
|
||
tcp_write(tpcb, tcp_rx_data, rx_data_len, 1);
|
||
}
|
||
else if (tcp_rx_data[3] == SEND_STATE_CMD)
|
||
{
|
||
send_data_flag_cmd = 0; // 上位机返回数据,发送状态标志位清零
|
||
}
|
||
else if (tcp_rx_data[3] == READ_ENCODER_CMD)
|
||
{
|
||
/*读操作,从寄存器读取数据,组包返回*/
|
||
tx_data_len = COM_ENCODER_DATA_SIZE;
|
||
user_communication_encoder = &communication_data.encoder_data;
|
||
communication_get_encoder(user_communication_encoder, tcp_tx_data, tcp_rx_data);
|
||
tcp_write(tpcb, tcp_tx_data, tx_data_len, 1);
|
||
}
|
||
|
||
else
|
||
{
|
||
// 返回命令号错误
|
||
tx_data_len = COM_ERROR_CODE_SIZE;
|
||
communication_exception(tcp_tx_data, tcp_rx_data, COMMAND_ERROR);
|
||
tcp_write(tpcb, tcp_tx_data, tx_data_len, 1);
|
||
}
|
||
}
|
||
|
||
/*2. 判断所要执行的操作 读或写指令*/
|
||
/*3. 对要发送的数据进行校验,组包,返回数据*/
|
||
}
|
||
pbuf_free(p);
|
||
}
|
||
else if (err == ERR_OK) // 检测到对方主动关闭连接时,也会调用recv函数,此时p为空
|
||
{
|
||
// HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
|
||
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_forwarding_flags_hart1 == 1)
|
||
{
|
||
user_send_data_hart1(hart1_uart5.rx_data, hart1_uart5.rx_num);
|
||
uart_forwarding_flags_hart1 = 0;
|
||
}
|
||
if (uart_forwarding_flags_hart2 == 1)
|
||
{
|
||
user_send_data_hart2(hart2_uart2.rx_data, hart2_uart2.rx_num);
|
||
uart_forwarding_flags_hart2 = 0;
|
||
}
|
||
#if (BLE2_USART6 == 1)
|
||
if (uart_forwarding_flags_ble1 == 1)
|
||
{
|
||
user_send_data_ble1(ble1_uart6.rx_data, ble1_uart6.rx_num);
|
||
uart_forwarding_flags_ble1 = 0;
|
||
}
|
||
#endif
|
||
if (uart_forwarding_flags_ble2 == 1)
|
||
{
|
||
user_send_data_ble2(ble2_uart3.rx_data, ble2_uart3.rx_num);
|
||
uart_forwarding_flags_ble2 = 0;
|
||
}
|
||
}
|
||
|