#include "xs_udp.h" #include "xs_log.h" #define TAG "xs_udp" #define UDP_DEFAULT_SEND_PORT 5000 #define SOCKET_DO(function) \ do { \ int ret = function; \ if (ret) { \ ZLOGE(TAG, "do %s fail", #function); \ return false; \ } \ } while (0) static void udp_server_receive_thread(void const *argument) { // udp_t *udp_handler = (udp_t *)argument; ZLOGI(TAG, "udp server receive thread start: %s", udp_handler->name); while (true) { struct sockaddr_in sock; socklen_t sock_len = sizeof(sock); int recv_datalen = recvfrom(udp_handler->sock_fd, (char *)udp_handler->rxbuf, udp_handler->rxbuf_len, 0, (struct sockaddr *)&sock, &sock_len); if (recv_datalen > 0) { if (udp_handler->on_packet) udp_handler->on_packet(udp_handler, &sock, (uint8_t *)udp_handler->rxbuf, recv_datalen); } } } bool xs_udp_init(udp_t *udp_handler, const char *name, uint16_t port, udp_on_packet_t on_packet, int32_t rxbuf_size, void *data) { memset(udp_handler, 0, sizeof(udp_t)); udp_handler->server.sin_family = AF_INET; udp_handler->server.sin_addr.s_addr = inet_addr("0.0.0.0"); udp_handler->server.sin_port = htons(port); udp_handler->on_packet = on_packet; udp_handler->data = data; udp_handler->name = name; if (rxbuf_size == 0) { udp_handler->rxbuf_len = 1024; } else { udp_handler->rxbuf_len = rxbuf_size; } udp_handler->rxbuf = (char *)malloc(udp_handler->rxbuf_len); ZASSERT(udp_handler->rxbuf != NULL); // 创建客户端用于通信的Socket udp_handler->sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (udp_handler->sock_fd < 0) { ZLOGE(TAG, "create socket fail"); return false; } // 设置超时 struct timeval tv = {0, 1000}; SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))); // 绑定 SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server))); if (on_packet) { // 创建接收线程 osThreadDef(udp_server_rx_thread, udp_server_receive_thread, osPriorityBelowNormal, 0, 512); udp_handler->rx_thread = osThreadCreate(osThread(udp_server_rx_thread), udp_handler); ZASSERT(udp_handler->rx_thread != NULL); } return true; } int xs_udp_send_message(udp_t *udp_handler, const char *ip, int port, const char *data, int len) { // struct sockaddr_in sockaddr; sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = inet_addr(ip); sockaddr.sin_port = htons(port); return sendto(udp_handler->sock_fd, data, len, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); } int xs_udp_send_message2(udp_t *udp_handler, struct sockaddr_in *add, const char *data, int len) { // return sendto(udp_handler->sock_fd, data, len, 0, (struct sockaddr *)add, sizeof(struct sockaddr_in)); } bool xs_udp_broadcast_init(udp_broadcast_handler_t *udp_handler, uint16_t localport) { memset(udp_handler, 0, sizeof(udp_broadcast_handler_t)); udp_handler->server.sin_family = AF_INET; udp_handler->server.sin_addr.s_addr = inet_addr("0.0.0.0"); udp_handler->server.sin_port = htons(localport); // 创建客户端用于通信的Socket udp_handler->sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (udp_handler->sock_fd < 0) { ZLOGE(TAG, "create socket fail"); return false; } // 设置超时 struct timeval tv = {0, 1000}; SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))); // 绑定 SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server))); return true; } bool xs_udp_broadcast(udp_broadcast_handler_t *handler, uint32_t remoteport, uint8_t *data, size_t datalen) { struct sockaddr_in sockaddr; sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); sockaddr.sin_port = htons(remoteport); return sendto(handler->sock_fd, data, datalen, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); }