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
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));
|
|
}
|