pile_com_stm32/main_old/communication_pad/tcp_server.c
2024-03-30 18:47:02 +08:00

164 lines
3.9 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 <stdint.h>
#include <string.h>
#include "lwip/ip_addr.h"
#include "lwip/tcp.h"
#include "lwip/err.h"
#include "lwip/opt.h"
#include "lwip/sockets.h"
#include "esp_log.h"
#include "tcp_server.h"
#include "inc/communication_pad.h"
#define LOG_TAG "[communication_tcp_sr]: "
struct clientNode client_list; // 客户端链表头结点
struct clientNode *client_r_p = &client_list; // 客户端链表尾指针
void client_list_add(struct tcp_pcb *pcb)
{
struct clientNode *client = (struct clientNode *)malloc(sizeof(struct clientNode));
client->pcb = pcb;
client->enable_notify = 0;
client->next = NULL;
client_r_p->next = client;
client_r_p = client;
}
void client_list_delete(struct tcp_pcb *pcb)
{
struct clientNode *p = &client_list;
while (p->next)
{
if (p->next->pcb == pcb)
{
struct clientNode *q = p->next;
p->next = q->next;
free(q);
return;
}
p = p->next;
}
}
void cilent_list_delete_all(void)
{
struct clientNode *p = &client_list;
while (p->next)
{
struct clientNode *q = p->next;
p->next = q->next;
free(q);
}
}
struct clientNode* find_client_by_pcb(struct tcp_pcb *pcb)
{
struct clientNode *p = client_list.next;
struct clientNode *ret = NULL;
while (p)
{
if (p->pcb == pcb)
{
ret = p;
break;
}
p = p->next;
}
return ret;
}
static err_t ModBusSlave_recv(void *arg, struct tcp_pcb *newpcb, struct pbuf *p, err_t err) {
if (p != NULL) {
uint8_t *rxbuf;
uint8_t *txbuf = NULL;
int rxlen, txlen = 0;
tcp_recved(newpcb, p->tot_len);
rxbuf = (uint8_t *)p->payload;
rxlen = p->len;
ESP_LOGI(LOG_TAG, "recive data %d:", rxlen);
esp_log_buffer_hex(LOG_TAG, rxbuf, rxlen);
// 接受到数据调用pad_deal_recived_data处理如果需要回复读操作则再将数据发送出去
struct clientNode* client = find_client_by_pcb(newpcb);
if (!client)
{
ESP_LOGI(LOG_TAG, "err:not find this client");
return ERR_OK;
}
pad_deal_recived_data(rxbuf, rxlen, &client->enable_notify, &txbuf, &txlen);
if (txbuf)
{
tcp_write(newpcb, txbuf, txlen, 1);
free(txbuf);
}
pbuf_free(p);
}
else if (err == ERR_OK)
{
ESP_LOGI(LOG_TAG, "gps1 remote end is closing the connection\n");
tcp_err(newpcb, NULL);
tcp_recv(newpcb, NULL);
// tcp_poll(newpcb, NULL, 120);
err_t err_p = tcp_close(newpcb);
client_list_delete(newpcb);
if (ERR_OK != err_p)
{
ESP_LOGI(LOG_TAG, "gps1 close error. err:%d\n", err_p);
}
return err_p;
}
return ERR_OK;
}
static void ModBusSlave_conn_err(void *arg, err_t err) {
ESP_LOGI(LOG_TAG, "connect err!");
// log_printf(LERROR, LOG_TAG "connection error, err:%d\n", err);
// cilent_list_delete_all(); // 不知道为什么这个回调函数没有提供newpcb
}
static err_t ModBusSlave_poll(void *arg, struct tcp_pcb *newpcb) {
// if (newpcb) {
// // log_printf(LERROR, LOG_TAG "close pcb\n");
// tcp_close(newpcb);
// newpcb = NULL;
// }
ESP_LOGI(LOG_TAG, "poll!");
return ERR_OK;
}
static err_t ModBusSlave_accept(void *arg, struct tcp_pcb *pcb, err_t err) {
tcp_err(pcb, ModBusSlave_conn_err);
tcp_recv(pcb, ModBusSlave_recv);
// tcp_poll(pcb, ModBusSlave_poll, 120); // 60 second timeout
client_list_add(pcb);
return ERR_OK;
}
void tcp_server_init(void) {
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, TCP_SERVER_PORT);
pcb = tcp_listen(pcb);
tcp_accept(pcb, ModBusSlave_accept);
}
// 遍历所有客户端,如果允许上报,则将数据上报
void tcp_server_notify(uint8_t *data, int len)
{
struct clientNode *p = client_list.next;
while (p)
{
if (p->enable_notify == 1) // 开启上报
{
ESP_LOGI(LOG_TAG, "tcp_server_notify");
esp_log_buffer_hex(LOG_TAG, data, len);
tcp_write(p->pcb, data, len, 1);
}
p = p->next;
}
}