1
1
#include " AsyncUDP.h"
2
+ #include " Utility.h"
2
3
3
4
void _asyncudp_async_cb (uv_async_t *handle) {
4
5
AsyncUDP *udp = (AsyncUDP *)handle->data ;
@@ -38,9 +39,8 @@ bool AsyncUDP::listenMulticast(const IPAddress addr, uint16_t port, uint8_t ttl)
38
39
if (_connected) {
39
40
return false ;
40
41
}
41
- // FIXME: implement error handling rather than raising SIGSEGV
42
42
if (uv_udp_init (&_loop, &_socket) < 0 ) {
43
- raise (SIGSEGV );
43
+ portduinoError ( " FIXME: implement proper error handling; uv_udp_init failed " );
44
44
}
45
45
_socket.data = this ;
46
46
// 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)
49
49
snprintf (addr_str, maxIpLength, " %d.%d.%d.%d" , addr[0 ], addr[1 ], addr[2 ], addr[3 ]);
50
50
addr_str[maxIpLength] = ' \0 ' ;
51
51
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);
55
53
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 " );
57
55
}
58
56
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 " );
60
58
}
61
59
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 " );
63
61
}
64
62
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 " );
66
64
}
67
65
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 " );
69
67
}
70
68
71
69
_ioThread = std::thread ([this ](){
@@ -96,6 +94,16 @@ void AsyncUDP::_DO_NOT_CALL_async_cb() {
96
94
_sendQueueMutex.lock ();
97
95
}
98
96
_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
+ }
99
107
};
100
108
101
109
void _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
111
119
112
120
// FIXME: implement error handling rather than raising SIGSEGV
113
121
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);
117
123
118
124
uv_udp_send_t *req = (uv_udp_send_t *)malloc (sizeof (uv_udp_send_t ));
119
125
uv_buf_t msg;
120
126
msg.base = (char *)data;
121
127
msg.len = len;
122
128
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 " );
124
130
}
125
131
};
0 commit comments