pile_com_stm32/main/communication_pad/udp_server.c

170 lines
4.3 KiB
C
Raw Normal View History

2024-04-25 10:20:39 +08:00
#include <stdint.h>
#include <string.h>
#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;
}
}