#include #include #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; if (q == client_r_p) { client_r_p = p; } 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); } client_r_p = &client_list; } 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) { ESP_LOGI(LOG_TAG, "TCP accept 0x%x", (unsigned int)pcb); 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); tcp_output(p->pcb); } p = p->next; } }