|
45 | 45 | //#include "lwip/raw.h"
|
46 | 46 | #include "lwip/dns.h"
|
47 | 47 | #include "lwip/tcp_impl.h"
|
| 48 | +#include "lwip/igmp.h" |
48 | 49 |
|
49 | 50 | #if 0 // print debugging info
|
50 | 51 | #define DEBUG_printf DEBUG_printf
|
51 | 52 | #else // don't print debugging info
|
52 | 53 | #define DEBUG_printf(...) (void)0
|
53 | 54 | #endif
|
54 | 55 |
|
| 56 | +// All socket options should be globally distinct, |
| 57 | +// because we ignore option levels for efficiency. |
| 58 | +#define IP_ADD_MEMBERSHIP 0x400 |
| 59 | + |
55 | 60 | // For compatibilily with older lwIP versions.
|
56 | 61 | #ifndef ip_set_option
|
57 | 62 | #define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
|
@@ -1079,17 +1084,35 @@ STATIC mp_obj_t lwip_socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
|
1079 | 1084 | return mp_const_none;
|
1080 | 1085 | }
|
1081 | 1086 |
|
1082 |
| - // Integer options |
1083 |
| - mp_int_t val = mp_obj_get_int(args[3]); |
1084 | 1087 | switch (opt) {
|
1085 |
| - case SOF_REUSEADDR: |
| 1088 | + // level: SOL_SOCKET |
| 1089 | + case SOF_REUSEADDR: { |
| 1090 | + mp_int_t val = mp_obj_get_int(args[3]); |
1086 | 1091 | // Options are common for UDP and TCP pcb's.
|
1087 | 1092 | if (val) {
|
1088 | 1093 | ip_set_option(socket->pcb.tcp, SOF_REUSEADDR);
|
1089 | 1094 | } else {
|
1090 | 1095 | ip_reset_option(socket->pcb.tcp, SOF_REUSEADDR);
|
1091 | 1096 | }
|
1092 | 1097 | break;
|
| 1098 | + } |
| 1099 | + |
| 1100 | + // level: IPPROTO_IP |
| 1101 | + case IP_ADD_MEMBERSHIP: { |
| 1102 | + mp_buffer_info_t bufinfo; |
| 1103 | + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); |
| 1104 | + if (bufinfo.len != sizeof(ip_addr_t) * 2) { |
| 1105 | + mp_raise_ValueError(NULL); |
| 1106 | + } |
| 1107 | + |
| 1108 | + // POSIX setsockopt has order: group addr, if addr, lwIP has it vice-versa |
| 1109 | + err_t err = igmp_joingroup((ip_addr_t*)bufinfo.buf + 1, bufinfo.buf); |
| 1110 | + if (err != ERR_OK) { |
| 1111 | + mp_raise_OSError(error_lookup_table[-err]); |
| 1112 | + } |
| 1113 | + break; |
| 1114 | + } |
| 1115 | + |
1093 | 1116 | default:
|
1094 | 1117 | printf("Warning: lwip.setsockopt() not implemented\n");
|
1095 | 1118 | }
|
@@ -1342,6 +1365,9 @@ STATIC const mp_rom_map_elem_t mp_module_lwip_globals_table[] = {
|
1342 | 1365 |
|
1343 | 1366 | { MP_ROM_QSTR(MP_QSTR_SOL_SOCKET), MP_ROM_INT(1) },
|
1344 | 1367 | { MP_ROM_QSTR(MP_QSTR_SO_REUSEADDR), MP_ROM_INT(SOF_REUSEADDR) },
|
| 1368 | + |
| 1369 | + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(0) }, |
| 1370 | + { MP_ROM_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_ROM_INT(IP_ADD_MEMBERSHIP) }, |
1345 | 1371 | };
|
1346 | 1372 |
|
1347 | 1373 | STATIC MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table);
|
|
0 commit comments