#include #include #include "lwip/ip_addr.h" #include "lwip/udp.h" #include "lwip/err.h" #include "lwip/opt.h" #include "lwip/sockets.h" #include "esp_log.h" #include "inc/udp_server.h" #include "inc/communication_pad.h" #define LOG_TAG "[communication_udp_server]: " struct clientNode client_list; // 客户端链表头结点 struct clientNode *client_r_p = &client_list; // 客户端链表尾指针 struct clientNode *client_list_add(struct udp_pcb * upcb, ip_addr_t *addr, uint16_t port) { struct clientNode *p = client_list.next; struct clientNode *ret = NULL; while (p) { if (ip_addr_cmp(&p->addr, addr) && p->port == port) { ret = p; break; } p = p->next; } if (ret == NULL) { struct clientNode *client = (struct clientNode *)malloc(sizeof(struct clientNode)); client->upcb = upcb; ip_addr_copy(client->addr, *addr); client->port = port; client->notify_timeout = UDP_NOTIFY_TIMEOUT; client->next = NULL; client_r_p->next = client; client_r_p = client; ret = client; } return ret; } // 返回删除的前一个 struct clientNode *client_list_delete(ip_addr_t *addr, uint16_t port) { struct clientNode *p = &client_list; while (p->next) { if (ip_addr_cmp(&p->next->addr, addr) && p->next->port == port) { struct clientNode *q = p->next; if (q == client_r_p) { client_r_p = p; } p->next = q->next; free(q); return p; } p = p->next; } return NULL; } 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; } void udp_server_recived(void *arg, struct udp_pcb *upcb, struct pbuf *pkt_buf, ip_addr_t *addr, u16_t port) { uint8_t *rxbuf; uint8_t *txbuf = NULL; int rxlen, txlen = 0; rxbuf = (uint8_t *)pkt_buf->payload; rxlen = pkt_buf->len; ESP_LOGI(LOG_TAG, "recive data %d:", rxlen); esp_log_buffer_hex(LOG_TAG, rxbuf, rxlen); // 接受到数据,调用pad_deal_recived_data处理,如果需要回复(读操作),则再将数据发送出去 struct clientNode* client = client_list_add(upcb, addr, port); int enable_notify = -1; pad_deal_recived_data(rxbuf, rxlen, &enable_notify, &txbuf, &txlen); if (enable_notify == 1) { client->notify_timeout = UDP_NOTIFY_TIMEOUT; } else if (enable_notify == 0) { client->notify_timeout = 0; } if (txbuf) { struct pbuf *pkt_txbuf = pbuf_alloc(PBUF_TRANSPORT, 1400, PBUF_RAM); char *buf = (char *)pkt_txbuf->payload; pkt_txbuf->len = txlen; pkt_txbuf->tot_len = txlen; memcpy(buf, txbuf, txlen); err_t err = udp_sendto(upcb, pkt_txbuf, &addr, port); pbuf_free(pkt_txbuf); free(txbuf); } pbuf_free(pkt_buf); } void udp_server_init(void) { err_t err; struct udp_pcb *UDPpcb; UDPpcb = udp_new(); if (!UDPpcb) { return; } err = udp_bind(UDPpcb, IP_ADDR_ANY, UDP_SERVER_PORT); if (err != ERR_OK) { return; } udp_recv(UDPpcb, udp_server_recived, NULL); } // 遍历所有客户端,如果允许上报,则将数据上报 void udp_server_notify(uint8_t *data, int len) { struct clientNode *p = client_list.next; while (p) { if (p->notify_timeout > 0) { // ESP_LOGI(LOG_TAG, "tcp_server_notify"); // esp_log_buffer_hex(LOG_TAG, data, len); struct pbuf *pkt_txbuf = pbuf_alloc(PBUF_TRANSPORT, 1400, PBUF_RAM); char *buf = (char *)pkt_txbuf->payload; pkt_txbuf->len = len; pkt_txbuf->tot_len = len; memcpy(buf, data, len); udp_sendto(p->upcb, pkt_txbuf, &p->addr, p->port); pbuf_free(pkt_txbuf); p->notify_timeout--; } else if (p->notify_timeout == 0) // 时间耗尽,删除 { p = client_list_delete(&p->addr, p->port); if (p == NULL) { ESP_LOGI(LOG_TAG, "err, confilct"); return; } } p = p->next; } }