11#include " AsyncUDP.h"
2+ #include " Utility.h"
23
34void _asyncudp_async_cb (uv_async_t *handle) {
45 AsyncUDP *udp = (AsyncUDP *)handle->data ;
@@ -38,9 +39,8 @@ bool AsyncUDP::listenMulticast(const IPAddress addr, uint16_t port, uint8_t ttl)
3839 if (_connected) {
3940 return false ;
4041 }
41- // FIXME: implement error handling rather than raising SIGSEGV
4242 if (uv_udp_init (&_loop, &_socket) < 0 ) {
43- raise (SIGSEGV );
43+ portduinoError ( " FIXME: implement proper error handling; uv_udp_init failed " );
4444 }
4545 _socket.data = this ;
4646 // FIXME: don't do bytes → string → bytes IP conversion
@@ -49,23 +49,21 @@ bool AsyncUDP::listenMulticast(const IPAddress addr, uint16_t port, uint8_t ttl)
4949 snprintf (addr_str, maxIpLength, " %d.%d.%d.%d" , addr[0 ], addr[1 ], addr[2 ], addr[3 ]);
5050 addr_str[maxIpLength] = ' \0 ' ;
5151 struct sockaddr uvAddr;
52- if (uv_ip4_addr (addr_str, port, (struct sockaddr_in *)&uvAddr) < 0 ) {
53- raise (SIGSEGV);
54- }
52+ uv_ip4_addr (addr_str, port, (struct sockaddr_in *)&uvAddr);
5553 if (uv_udp_bind (&_socket, (const struct sockaddr *)&uvAddr, 0 ) < 0 ) {
56- raise (SIGSEGV );
54+ portduinoError ( " FIXME: implement proper error handling; uv_udp_bind failed " );
5755 }
5856 if (uv_udp_set_multicast_loop (&_socket, false ) < 0 ) {
59- raise (SIGSEGV );
57+ portduinoError ( " FIXME: implement proper error handling; uv_udp_set_multicast_loop failed " );
6058 }
6159 if (uv_udp_set_multicast_ttl (&_socket, ttl) < 0 ) {
62- raise (SIGSEGV );
60+ portduinoError ( " FIXME: implement proper error handling; uv_udp_set_multicast_ttl failed " );
6361 }
6462 if (uv_udp_set_membership (&_socket, addr_str, NULL , UV_JOIN_GROUP) < 0 ) {
65- raise (SIGSEGV );
63+ portduinoError ( " FIXME: implement proper error handling; uv_udp_set_membership failed " );
6664 }
6765 if (uv_udp_recv_start (&_socket, _asyncudp_alloc_buffer_cb, _asyncudp_on_read_cb) < 0 ) {
68- raise (SIGSEGV );
66+ portduinoError ( " FIXME: implement proper error handling; uv_udp_recv_start failed " );
6967 }
7068
7169 _ioThread = std::thread ([this ](){
@@ -96,6 +94,16 @@ void AsyncUDP::_DO_NOT_CALL_async_cb() {
9694 _sendQueueMutex.lock ();
9795 }
9896 _sendQueueMutex.unlock ();
97+ if (_quit.load ()) {
98+ uv_udp_recv_stop (&_socket);
99+ // FIXME: don't do bytes → string → bytes IP conversion
100+ int maxIpLength = 3 *4 +3 ; // 3 digits per octet, 4 octets, 3 dots
101+ char addr_str[maxIpLength+1 ]; // +1 for null terminator
102+ snprintf (addr_str, maxIpLength, " %d.%d.%d.%d" , _listenIP[0 ], _listenIP[1 ], _listenIP[2 ], _listenIP[3 ]);
103+ addr_str[maxIpLength] = ' \0 ' ;
104+ uv_udp_set_membership (&_socket, addr_str, NULL , UV_LEAVE_GROUP);
105+ uv_stop (&_loop);
106+ }
99107};
100108
101109void _asyncudp_send_cb (uv_udp_send_t *req, int status) {
@@ -111,15 +119,13 @@ void AsyncUDP::_doWrite(const uint8_t *data, size_t len, const IPAddress addr, u
111119
112120 // FIXME: implement error handling rather than raising SIGSEGV
113121 struct sockaddr uvAddr;
114- if (uv_ip4_addr (addr_str, port, (struct sockaddr_in *)&uvAddr) < 0 ) {
115- raise (SIGSEGV);
116- }
122+ uv_ip4_addr (addr_str, port, (struct sockaddr_in *)&uvAddr);
117123
118124 uv_udp_send_t *req = (uv_udp_send_t *)malloc (sizeof (uv_udp_send_t ));
119125 uv_buf_t msg;
120126 msg.base = (char *)data;
121127 msg.len = len;
122128 if (uv_udp_send (req, &_socket, &msg, 1 , (const struct sockaddr *)&uvAddr, _asyncudp_send_cb) < 0 ) {
123- raise (SIGSEGV );
129+ portduinoError ( " FIXME: implement proper error handling; uv_udp_send failed " );
124130 }
125131};
0 commit comments