/* * lwip_util.c * * Created on: 2025年7月29日 * Author: wulianwei */ #include "nim_config.h" #include "device/console.h" #include "hal/nim_ethernet.h" #include "lwiplib.h" #include "lwipopts.h" #include #define TCP_POLL_INTERVAL 4 #define MAX_SIZE 4096 static err_t tcp_accept_handle(void *arg, struct tcp_pcb *pcb, err_t err); static err_t tcp_recv_handle(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); static void tcp_close_conn(struct tcp_pcb *pcb); err_t tcp_send_data(struct tcp_pcb *pcb, struct pbuf *p); err_t queue_send_data(struct pbuf *p); static struct udp_pcb *gui_udp_pcb; static struct tcp_pcb *tcp_server_pcb ; static struct tcp_pcb *cur_conn = NULL; // 当前连接 void lwip_device_init(void) { unsigned char macArray[6] = MAC_ADDRESS; EthernetInit(); //以太网外设配置 unsigned int ipAddr = 0; unsigned int retry_count = 0; while (ipAddr == 0) { #if STATIC_IP_ADDRESS ipAddr = lwIPInit(0, macArray, STATIC_IP_ADDRESS, 0, 0, IPADDR_USE_STATIC); #else ipAddr = lwIPInit(0, macArray, 0, 0, 0, IPADDR_USE_DHCP); #endif if (retry_count++ > 5) { ConsolePrintf("lwIPInit failed!.\r\n\r\n"); } } ConsolePrintf("lwIP HostIP:%d.%d.%d.%d\n", (ipAddr >> (0 * 8)) & 0xFF, (ipAddr >> (1 * 8)) & 0xFF, (ipAddr >> (2 * 8)) & 0xFF, (ipAddr >> (3 * 8)) & 0xFF); gui_udp_pcb = udp_new(); udp_bind(gui_udp_pcb, IP_ADDR_ANY, 3000); lwip_udp_connect(gui_udp_pcb, UI_IP_ADDRESS, UI_UDP_PORT); } /** * tcp 服务初始化 */ err_t lwip_tcp_init(int port) { err_t err; //struct tcp_pcb *pcb; tcp_server_pcb = tcp_new(); if (tcp_server_pcb == NULL) { ConsolePuts("tcp new 空间不足", -1); return ERR_MEM; // 内存不足 } err = tcp_bind(tcp_server_pcb , IP_ADDR_ANY, port); if (err != ERR_OK) { ConsolePuts("tcp 绑定断开失败", -1); return err; } tcp_server_pcb = tcp_listen(tcp_server_pcb ); if(tcp_server_pcb == NULL) { ConsolePuts("tcp 监听失败", -1); } /* initialize callback arg and accept callback */ tcp_arg(tcp_server_pcb , NULL); tcp_accept(tcp_server_pcb , tcp_accept_handle); return ERR_OK; } /** * 链接监听函数. */ static err_t tcp_accept_handle(void *arg, struct tcp_pcb *pcb, err_t err) { LWIP_UNUSED_ARG(err); LWIP_UNUSED_ARG(arg); tcp_setprio(pcb, TCP_PRIO_MAX); /* Set up the various callback functions */ tcp_recv(pcb, tcp_recv_handle); tcp_err(pcb, NULL); tcp_poll(pcb, NULL, TCP_POLL_INTERVAL); tcp_sent(pcb, NULL); return ERR_OK; } /** * 接收数据处理函数. */ static err_t tcp_recv_handle(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); err_t err_send; if (p != NULL) { /* Inform TCP that we have taken the data. */ tcp_recved(pcb, p->tot_len); } if ((err != ERR_OK) || (p == NULL)) { /* error or closed by other side */ if (p != NULL) { pbuf_free(p); } tcp_close_conn(pcb); return ERR_OK; } cur_conn = pcb; //tcp_send_data(pcb ,p); err_send = queue_send_data(p); return err_send; } /** * 关闭远程连接. */ static void tcp_close_conn(struct tcp_pcb *pcb) { tcp_recv(pcb, NULL); tcp_close(pcb); /* closing succeeded */ tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); } /** * 发送数据 */ err_t tcp_send_data(struct tcp_pcb *pcb, struct pbuf *p) { unsigned char mydata[MAX_SIZE]; err_t err = ERR_OK; char *data; unsigned int cnt = 0, j, i; unsigned int len, tot_len; struct pbuf *temp = p; tot_len = p->tot_len; /** * traverse pbuf chain and store payload * of each pbuf into buffer */ do { data = (char*) p->payload; len = p->len; for (i = 0, j = 0; i < len; i++, j++, cnt++) { if(cnt>=MAX_SIZE) break; mydata[cnt] = data[j]; } p = p->next; } while (p != NULL); /* free pbuf's */ pbuf_free(temp); /** *send the data in buffer over network with * tcp header attached */ err = tcp_write(pcb, mydata, tot_len , TCP_WRITE_FLAG_COPY); return err; } void lwip_tcp_send_gui(unsigned char *data, int len) { tcp_write(cur_conn, data, len , TCP_WRITE_FLAG_COPY); tcp_output(cur_conn); } /** * 发送数据到USB */ err_t queue_send_data(struct pbuf *p) { struct pbuf *temp = p; unsigned int len = 0; do { char* data = (char*) p->payload; len = p->len; ConsolePuts("\r\ntcp rec data:\r\n", -1); ConsolePutsHexStr(data, len); enqueueFromEthernet(data, len); p = p->next; } while (p != NULL); pbuf_free(temp); return ERR_OK; } /** * udp 链接 */ void lwip_udp_connect(struct udp_pcb *pcb, unsigned int ip, int port) { struct ip_addr ip_dst; ip_dst.addr = htonl(ip); udp_connect(pcb, &ip_dst, port); } /** * udp 发送 */ void lwip_udp_send(struct udp_pcb *pcb, unsigned char *data, int len) { struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, len + sizeof(struct pbuf), PBUF_REF); pbuf->payload = data; udp_send(pcb, pbuf); pbuf_free(pbuf); } /** * udp 发送 */ void lwip_udp_sendto(struct udp_pcb *pcb, unsigned int ip, int port, unsigned char *data, int len) { struct ip_addr ip_dst; ip_dst.addr = htonl(ip); struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct pbuf), PBUF_REF); pbuf->payload = data; udp_sendto(pcb, pbuf, &ip_dst, port); pbuf_free(pbuf); } /** * udp 向gui发送数据 */ void lwip_udp_send_gui(unsigned char *data, int len) { struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_REF); pbuf->payload = data; udp_send(gui_udp_pcb, pbuf); pbuf_free(pbuf); } /** * udp 向gui发送数据 * data 浮点数据指针, flen 数据数量, channelFlag 有效通道 */ void lwip_udp_send_gui_signal(float *data, int flen, char channelFlag) { unsigned char head[8]={'T','R',1,3,1,1}; int clen = sizeof(float)*flen; int head_len = sizeof(head); int total_len = head_len+1+clen; head[6] = total_len>>8; head[7] = total_len; unsigned char* fdata = malloc(total_len); memcpy(fdata,&head,head_len); fdata[head_len] = channelFlag; memcpy(fdata+head_len+1,data,clen); struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, total_len, PBUF_REF); pbuf->payload = fdata; udp_send(gui_udp_pcb, pbuf); pbuf_free(pbuf); free(fdata); } /** * udp 向gui发送数据 * data 浮点数据指针, flen 数据数量, channelFlag 有效通道 */ void lwip_udp_send_gui_signal2(float *data1,float *data2,float *data3,float *data4, int flen, char channelFlag) { unsigned char head[8]={'T','R',1,3,1,1}; int clen = sizeof(float)*flen; int head_len = sizeof(head); int total_len = head_len+1+clen; head[6] = total_len>>8; head[7] = total_len; unsigned char* fdata = malloc(total_len); memcpy(fdata,&head,head_len); fdata[head_len] = channelFlag; struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, total_len, PBUF_REF); pbuf->payload = fdata; udp_send(gui_udp_pcb, pbuf); pbuf_free(pbuf); free(fdata); } /** * udp 向波形模拟器VOFA发送数据 单通道 * data 要发送的数据,len float数组长度 */ void lwip_udp_send_vofa(float *data, int len) { int i = 0; char tail[4] = {0x00, 0x00, 0x80, 0x7f}; int flen = (sizeof(float)+4)*len; unsigned char* fdata = malloc(flen); for(i=0;ipayload = fdata; udp_send(gui_udp_pcb, pbuf); pbuf_free(pbuf); free(fdata); } /** * udp 向波形模拟器VOFA发送数据 双通道 * data1 要发送的通道1数据,data1 要发送的通道2数据,len float数组长度 */ void lwip_udp_send_vofa2(float *data1, float *data2, int len) { ConsolePuts("lwip send data", -1); int i = 0; char tail[4] = {0x00, 0x00, 0x80, 0x7f}; int flen = (sizeof(float)*2+4)*len; unsigned char* fdata = malloc(flen); for(i=0;ipayload = fdata; udp_send(gui_udp_pcb, pbuf); pbuf_free(pbuf); free(fdata); } /** * udp 向波形模拟器VOFA发送数据 四通道 * data1 要发送的通道1数据,data1 要发送的通道2数据,len float数组长度 */ void lwip_udp_send_vofa4(float *data1, float *data2,float *data3, float *data4, int len) { int i = 0; char tail[4] = {0x00, 0x00, 0x80, 0x7f}; int flen = (sizeof(float)*4+4)*len; unsigned char* fdata = malloc(flen); for(i=0;ipayload = fdata; udp_send(gui_udp_pcb, pbuf); pbuf_free(pbuf); free(fdata); }