|
51 | 51 | #include "lwip/sockets.h"
|
52 | 52 | #include "lwip/netdb.h"
|
53 | 53 | #include "lwip/ip4.h"
|
| 54 | +#include "lwip/igmp.h" |
54 | 55 | #include "esp_log.h"
|
55 | 56 |
|
56 | 57 | #define SOCKET_POLL_US (100000)
|
@@ -208,18 +209,37 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
208 | 209 | (void)n_args; // always 4
|
209 | 210 | socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
210 | 211 |
|
211 |
| - int level = mp_obj_get_int(args[1]); |
212 |
| - if (level != SOL_SOCKET) { |
213 |
| - mp_raise_ValueError("unsupported level"); |
214 |
| - } |
215 |
| - |
216 |
| - // only "int" arguments are supported at the moment |
217 | 212 | int opt = mp_obj_get_int(args[2]);
|
218 |
| - int val = mp_obj_get_int(args[3]); |
219 |
| - int ret = lwip_setsockopt_r(self->fd, SOL_SOCKET, opt, &val, sizeof(int)); |
220 | 213 |
|
221 |
| - if (ret != 0) { |
222 |
| - exception_from_errno(errno); |
| 214 | + switch (opt) { |
| 215 | + // level: SOL_SOCKET |
| 216 | + case SO_REUSEADDR: { |
| 217 | + int val = mp_obj_get_int(args[3]); |
| 218 | + int ret = lwip_setsockopt_r(self->fd, SOL_SOCKET, opt, &val, sizeof(int)); |
| 219 | + if (ret != 0) { |
| 220 | + exception_from_errno(errno); |
| 221 | + } |
| 222 | + break; |
| 223 | + } |
| 224 | + |
| 225 | + // level: IPPROTO_IP |
| 226 | + case IP_ADD_MEMBERSHIP: { |
| 227 | + mp_buffer_info_t bufinfo; |
| 228 | + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); |
| 229 | + if (bufinfo.len != sizeof(ip4_addr_t) * 2) { |
| 230 | + mp_raise_ValueError(NULL); |
| 231 | + } |
| 232 | + |
| 233 | + // POSIX setsockopt has order: group addr, if addr, lwIP has it vice-versa |
| 234 | + err_t err = igmp_joingroup((const ip4_addr_t*)bufinfo.buf + 1, bufinfo.buf); |
| 235 | + if (err != ERR_OK) { |
| 236 | + mp_raise_OSError(-err); |
| 237 | + } |
| 238 | + break; |
| 239 | + } |
| 240 | + |
| 241 | + default: |
| 242 | + mp_printf(&mp_plat_print, "Warning: lwip.setsockopt() option not implemented\n"); |
223 | 243 | }
|
224 | 244 |
|
225 | 245 | return mp_const_none;
|
@@ -558,8 +578,10 @@ STATIC const mp_map_elem_t mp_module_socket_globals_table[] = {
|
558 | 578 | { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(SOCK_RAW) },
|
559 | 579 | { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(IPPROTO_TCP) },
|
560 | 580 | { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(IPPROTO_UDP) },
|
| 581 | + { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IP), MP_OBJ_NEW_SMALL_INT(IPPROTO_IP) }, |
561 | 582 | { MP_OBJ_NEW_QSTR(MP_QSTR_SOL_SOCKET), MP_OBJ_NEW_SMALL_INT(SOL_SOCKET) },
|
562 | 583 | { MP_OBJ_NEW_QSTR(MP_QSTR_SO_REUSEADDR), MP_OBJ_NEW_SMALL_INT(SO_REUSEADDR) },
|
| 584 | + { MP_OBJ_NEW_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_OBJ_NEW_SMALL_INT(IP_ADD_MEMBERSHIP) }, |
563 | 585 | };
|
564 | 586 |
|
565 | 587 | STATIC MP_DEFINE_CONST_DICT(mp_module_socket_globals, mp_module_socket_globals_table);
|
|
0 commit comments