summaryrefslogtreecommitdiffstatshomepage
path: root/extmod/modlwip.c
diff options
context:
space:
mode:
Diffstat (limited to 'extmod/modlwip.c')
-rw-r--r--extmod/modlwip.c122
1 files changed, 74 insertions, 48 deletions
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 01190d200c..cc10523e54 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2015 Galen Hazelwood
- * Copyright (c) 2015-2016 Paul Sokolovsky
+ * Copyright (c) 2015-2017 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -45,6 +45,7 @@
//#include "lwip/raw.h"
#include "lwip/dns.h"
#include "lwip/tcp_impl.h"
+#include "lwip/igmp.h"
#if 0 // print debugging info
#define DEBUG_printf DEBUG_printf
@@ -52,6 +53,10 @@
#define DEBUG_printf(...) (void)0
#endif
+// All socket options should be globally distinct,
+// because we ignore option levels for efficiency.
+#define IP_ADD_MEMBERSHIP 0x400
+
// For compatibilily with older lwIP versions.
#ifndef ip_set_option
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
@@ -124,15 +129,15 @@ STATIC mp_obj_t lwip_slip_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw,
ip_addr_t iplocal, ipremote;
if (!ipaddr_aton(mp_obj_str_get_str(args[1]), &iplocal)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "not a valid local IP"));
+ mp_raise_ValueError("not a valid local IP");
}
if (!ipaddr_aton(mp_obj_str_get_str(args[2]), &ipremote)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "not a valid remote IP"));
+ mp_raise_ValueError("not a valid remote IP");
}
struct netif *n = &lwip_slip_obj.lwip_netif;
if (netif_add(n, &iplocal, IP_ADDR_BROADCAST, &ipremote, NULL, slipif_init, ip_input) == NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "out of memory"));
+ mp_raise_ValueError("out of memory");
}
netif_set_up(n);
netif_set_default(n);
@@ -148,8 +153,8 @@ STATIC mp_obj_t lwip_slip_status(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(lwip_slip_status_obj, lwip_slip_status);
-STATIC const mp_map_elem_t lwip_slip_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_status), (mp_obj_t)&lwip_slip_status_obj },
+STATIC const mp_rom_map_elem_t lwip_slip_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&lwip_slip_status_obj) },
};
STATIC MP_DEFINE_CONST_DICT(lwip_slip_locals_dict, lwip_slip_locals_dict_table);
@@ -158,7 +163,7 @@ STATIC const mp_obj_type_t lwip_slip_type = {
{ &mp_type_type },
.name = MP_QSTR_slip,
.make_new = lwip_slip_make_new,
- .locals_dict = (mp_obj_t)&lwip_slip_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&lwip_slip_locals_dict,
};
#endif // MICROPY_PY_LWIP_SLIP
@@ -1028,7 +1033,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
break;
}
case MOD_NETWORK_SOCK_DGRAM:
- mp_not_implemented("");
+ mp_raise_NotImplementedError("");
break;
}
@@ -1079,10 +1084,10 @@ STATIC mp_obj_t lwip_socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
return mp_const_none;
}
- // Integer options
- mp_int_t val = mp_obj_get_int(args[3]);
switch (opt) {
- case SOF_REUSEADDR:
+ // level: SOL_SOCKET
+ case SOF_REUSEADDR: {
+ mp_int_t val = mp_obj_get_int(args[3]);
// Options are common for UDP and TCP pcb's.
if (val) {
ip_set_option(socket->pcb.tcp, SOF_REUSEADDR);
@@ -1090,6 +1095,24 @@ STATIC mp_obj_t lwip_socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
ip_reset_option(socket->pcb.tcp, SOF_REUSEADDR);
}
break;
+ }
+
+ // level: IPPROTO_IP
+ case IP_ADD_MEMBERSHIP: {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
+ if (bufinfo.len != sizeof(ip_addr_t) * 2) {
+ mp_raise_ValueError(NULL);
+ }
+
+ // POSIX setsockopt has order: group addr, if addr, lwIP has it vice-versa
+ err_t err = igmp_joingroup((ip_addr_t*)bufinfo.buf + 1, bufinfo.buf);
+ if (err != ERR_OK) {
+ mp_raise_OSError(error_lookup_table[-err]);
+ }
+ break;
+ }
+
default:
printf("Warning: lwip.setsockopt() not implemented\n");
}
@@ -1160,27 +1183,27 @@ STATIC mp_uint_t lwip_socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_
return ret;
}
-STATIC const mp_map_elem_t lwip_socket_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&lwip_socket_close_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&lwip_socket_close_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&lwip_socket_bind_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&lwip_socket_listen_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&lwip_socket_accept_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&lwip_socket_connect_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&lwip_socket_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&lwip_socket_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&lwip_socket_sendto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&lwip_socket_recvfrom_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sendall), (mp_obj_t)&lwip_socket_sendall_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&lwip_socket_settimeout_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&lwip_socket_setblocking_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&lwip_socket_setsockopt_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&lwip_socket_makefile_obj },
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
+STATIC const mp_rom_map_elem_t lwip_socket_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&lwip_socket_close_obj) },
+ { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&lwip_socket_close_obj) },
+ { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&lwip_socket_bind_obj) },
+ { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&lwip_socket_listen_obj) },
+ { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&lwip_socket_accept_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&lwip_socket_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&lwip_socket_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&lwip_socket_recv_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&lwip_socket_sendto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&lwip_socket_recvfrom_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&lwip_socket_sendall_obj) },
+ { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&lwip_socket_settimeout_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&lwip_socket_setblocking_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&lwip_socket_setsockopt_obj) },
+ { MP_ROM_QSTR(MP_QSTR_makefile), MP_ROM_PTR(&lwip_socket_makefile_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
};
STATIC MP_DEFINE_CONST_DICT(lwip_socket_locals_dict, lwip_socket_locals_dict_table);
@@ -1196,7 +1219,7 @@ STATIC const mp_obj_type_t lwip_socket_type = {
.print = lwip_socket_print,
.make_new = lwip_socket_make_new,
.protocol = &lwip_socket_stream_p,
- .locals_dict = (mp_obj_t)&lwip_socket_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&lwip_socket_locals_dict,
};
/******************************************************************************/
@@ -1321,27 +1344,30 @@ MP_DEFINE_CONST_FUN_OBJ_0(lwip_print_pcbs_obj, lwip_print_pcbs);
#ifdef MICROPY_PY_LWIP
-STATIC const mp_map_elem_t mp_module_lwip_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_lwip) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&mod_lwip_reset_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&mod_lwip_callback_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&lwip_getaddrinfo_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_print_pcbs), (mp_obj_t)&lwip_print_pcbs_obj },
+STATIC const mp_rom_map_elem_t mp_module_lwip_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_lwip) },
+ { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mod_lwip_reset_obj) },
+ { MP_ROM_QSTR(MP_QSTR_callback), MP_ROM_PTR(&mod_lwip_callback_obj) },
+ { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&lwip_getaddrinfo_obj) },
+ { MP_ROM_QSTR(MP_QSTR_print_pcbs), MP_ROM_PTR(&lwip_print_pcbs_obj) },
// objects
- { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&lwip_socket_type },
+ { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&lwip_socket_type) },
#ifdef MICROPY_PY_LWIP_SLIP
- { MP_OBJ_NEW_QSTR(MP_QSTR_slip), (mp_obj_t)&lwip_slip_type },
+ { MP_ROM_QSTR(MP_QSTR_slip), MP_ROM_PTR(&lwip_slip_type) },
#endif
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET6), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET6) },
+ { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) },
+ { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) },
+
+ { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) },
+ { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) },
+ { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_DGRAM) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_RAW) },
+ { MP_ROM_QSTR(MP_QSTR_SOL_SOCKET), MP_ROM_INT(1) },
+ { MP_ROM_QSTR(MP_QSTR_SO_REUSEADDR), MP_ROM_INT(SOF_REUSEADDR) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOL_SOCKET), MP_OBJ_NEW_SMALL_INT(1) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SO_REUSEADDR), MP_OBJ_NEW_SMALL_INT(SOF_REUSEADDR) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(0) },
+ { MP_ROM_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_ROM_INT(IP_ADD_MEMBERSHIP) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table);