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.

103 lines
4.1 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "xs_udp.h"
  2. #include "xs_log.h"
  3. #define TAG "xs_udp"
  4. #define UDP_DEFAULT_SEND_PORT 5000
  5. #define SOCKET_DO(function) \
  6. do { \
  7. int ret = function; \
  8. if (ret) { \
  9. ZLOGE(TAG, "do %s fail", #function); \
  10. return false; \
  11. } \
  12. } while (0)
  13. static void udp_server_receive_thread(void const *argument) { //
  14. udp_t *udp_handler = (udp_t *)argument;
  15. ZLOGI(TAG, "udp server receive thread start: %s", udp_handler->name);
  16. while (true) {
  17. struct sockaddr_in sock;
  18. socklen_t sock_len = sizeof(sock);
  19. int recv_datalen = recvfrom(udp_handler->sock_fd, (char *)udp_handler->rxbuf, udp_handler->rxbuf_len, 0, (struct sockaddr *)&sock, &sock_len);
  20. if (recv_datalen > 0) {
  21. if (udp_handler->on_packet) udp_handler->on_packet(udp_handler, &sock, (uint8_t *)udp_handler->rxbuf, recv_datalen);
  22. }
  23. }
  24. }
  25. 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) {
  26. memset(udp_handler, 0, sizeof(udp_t));
  27. udp_handler->server.sin_family = AF_INET;
  28. udp_handler->server.sin_addr.s_addr = inet_addr("0.0.0.0");
  29. udp_handler->server.sin_port = htons(port);
  30. udp_handler->on_packet = on_packet;
  31. udp_handler->data = data;
  32. udp_handler->name = name;
  33. if (rxbuf_size == 0) {
  34. udp_handler->rxbuf_len = 1024;
  35. } else {
  36. udp_handler->rxbuf_len = rxbuf_size;
  37. }
  38. udp_handler->rxbuf = (char *)malloc(udp_handler->rxbuf_len);
  39. ZASSERT(udp_handler->rxbuf != NULL);
  40. // �����ͻ�������ͨ�ŵ�Socket
  41. udp_handler->sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  42. if (udp_handler->sock_fd < 0) {
  43. ZLOGE(TAG, "create socket fail");
  44. return false;
  45. }
  46. // ���ó�ʱ
  47. struct timeval tv = {0, 1000};
  48. SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)));
  49. // ����
  50. SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server)));
  51. if (on_packet) {
  52. // ���������߳�
  53. osThreadDef(udp_server_rx_thread, udp_server_receive_thread, osPriorityBelowNormal, 0, 512);
  54. udp_handler->rx_thread = osThreadCreate(osThread(udp_server_rx_thread), udp_handler);
  55. ZASSERT(udp_handler->rx_thread != NULL);
  56. }
  57. return true;
  58. }
  59. int xs_udp_send_message(udp_t *udp_handler, const char *ip, int port, const char *data, int len) { //
  60. struct sockaddr_in sockaddr;
  61. sockaddr.sin_family = AF_INET;
  62. sockaddr.sin_addr.s_addr = inet_addr(ip);
  63. sockaddr.sin_port = htons(port);
  64. return sendto(udp_handler->sock_fd, data, len, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
  65. }
  66. int xs_udp_send_message2(udp_t *udp_handler, struct sockaddr_in *add, const char *data, int len) { //
  67. return sendto(udp_handler->sock_fd, data, len, 0, (struct sockaddr *)add, sizeof(struct sockaddr_in));
  68. }
  69. bool xs_udp_broadcast_init(udp_broadcast_handler_t *udp_handler, uint16_t localport) {
  70. memset(udp_handler, 0, sizeof(udp_broadcast_handler_t));
  71. udp_handler->server.sin_family = AF_INET;
  72. udp_handler->server.sin_addr.s_addr = inet_addr("0.0.0.0");
  73. udp_handler->server.sin_port = htons(localport);
  74. // �����ͻ�������ͨ�ŵ�Socket
  75. udp_handler->sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  76. if (udp_handler->sock_fd < 0) {
  77. ZLOGE(TAG, "create socket fail");
  78. return false;
  79. }
  80. // ���ó�ʱ
  81. struct timeval tv = {0, 1000};
  82. SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)));
  83. // ����
  84. SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server)));
  85. return true;
  86. }
  87. bool xs_udp_broadcast(udp_broadcast_handler_t *handler, uint32_t remoteport, uint8_t *data, size_t datalen) {
  88. struct sockaddr_in sockaddr;
  89. sockaddr.sin_family = AF_INET;
  90. sockaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  91. sockaddr.sin_port = htons(remoteport);
  92. return sendto(handler->sock_fd, data, datalen, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
  93. }