You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
5.0 KiB

#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);
}
}
}
/**
* @brief
*
* 由于lwip如果不接收消息,消息就会一直缓存,不会被丢弃,所以只要创建了某个socket就需要
* 监听其消息
*/
static void udp_broadcast_rx_thread(void const *argument) { //
udp_broadcast_handler_t *udp_handler = (udp_t *)argument;
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);
}
}
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;
}
// 绑定
SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server)));
// 设置超时
struct timeval tv = {1, 0};
SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)));
if (on_packet) {
// 创建接收线程
osThreadDef(udp_server_rx_thread, udp_server_receive_thread, osPriorityNormal, 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);
udp_handler->rxbuf_len = 1024;
udp_handler->rxbuf = (char *)malloc(udp_handler->rxbuf_len);
ZASSERT(udp_handler->rxbuf);
// 创建客户端用于通信的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 = {1, 0};
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)));
osThreadDef(_udp_broadcast_rx_thread, udp_broadcast_rx_thread, osPriorityNormal, 0, 512);
udp_handler->rx_thread = osThreadCreate(osThread(_udp_broadcast_rx_thread), udp_handler);
ZASSERT(udp_handler->rx_thread != NULL);
return true;
}
ssize_t 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));
}