diff --git a/extmod/modnetwork.c b/extmod/modnetwork.c index aa237bd93c..88f9d37180 100644 --- a/extmod/modnetwork.c +++ b/extmod/modnetwork.c @@ -144,12 +144,15 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_network_hostname_obj, 0, 1, mod_n #if LWIP_VERSION_MAJOR >= 2 MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, mod_network_ipconfig); #endif +#if MICROPY_PY_NETWORK_NINAW10 +MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, network_ninaw10_ipconfig); +#endif static const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, { MP_ROM_QSTR(MP_QSTR_country), MP_ROM_PTR(&mod_network_country_obj) }, { MP_ROM_QSTR(MP_QSTR_hostname), MP_ROM_PTR(&mod_network_hostname_obj) }, - #if LWIP_VERSION_MAJOR >= 2 + #if LWIP_VERSION_MAJOR >= 2 || MICROPY_PY_NETWORK_NINAW10 { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&mod_network_ipconfig_obj) }, #endif diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 2ff9ce09de..1a4aa7797e 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -83,6 +83,10 @@ extern int mp_mod_network_prefer_dns_use_ip_version; #endif #elif defined(MICROPY_PORT_NETWORK_INTERFACES) +#if MICROPY_PY_NETWORK_NINAW10 +mp_obj_t network_ninaw10_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); +#endif + struct _mod_network_socket_obj_t; typedef struct _mod_network_nic_protocol_t { diff --git a/extmod/network_lwip.c b/extmod/network_lwip.c index 97cb43902d..329a45c46f 100644 --- a/extmod/network_lwip.c +++ b/extmod/network_lwip.c @@ -297,20 +297,23 @@ mp_obj_t mod_network_nic_ipconfig(struct netif *netif, size_t n_args, const mp_o char plain_ip[IPADDR_STRLEN_MAX]; char *split = strchr(input_str, '/'); const char *addr_str = input_str; + int to_copy = MIN(sizeof(plain_ip) - 1, addr_len); + memcpy(plain_ip, addr_str, to_copy); if (split) { - int to_copy = sizeof(plain_ip) - 1; if (split - addr_str < to_copy) { to_copy = split - addr_str; } - memcpy(plain_ip, addr_str, to_copy); mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL); prefix_bits = mp_obj_get_int(prefix_obj); + if (mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr4) { + uint32_t mask = -(1u << (32 - prefix_bits)); + ip_addr_set_ip4_u32_val(netmask, ((mask & 0xFF) << 24) | ((mask & 0xFF00) << 8) | ((mask >> 8) & 0xFF00) | ((mask >> 24) & 0xFF)); + } + } else { + netmask = netif->netmask; } - if (mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr4) { - uint32_t mask = -(1u << (32 - prefix_bits)); - ip_addr_set_ip4_u32_val(netmask, ((mask & 0xFF) << 24) | ((mask & 0xFF00) << 8) | ((mask >> 8) & 0xFF00) | ((mask >> 24) & 0xFF)); - } - if (!ipaddr_aton(addr_str, &ip_addr)) { + plain_ip[to_copy] = '\0'; + if (!ipaddr_aton(plain_ip, &ip_addr)) { mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments")); } if ((mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr6) != IP_IS_V6(&ip_addr) diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c index 926e228a35..702adcd976 100644 --- a/extmod/network_ninaw10.c +++ b/extmod/network_ninaw10.c @@ -41,6 +41,7 @@ #include "py/runtime.h" #include "py/misc.h" #include "py/mperrno.h" +#include "py/parsenum.h" #include "shared/netutils/netutils.h" #include "shared/runtime/softtimer.h" #include "extmod/modnetwork.h" @@ -75,6 +76,8 @@ typedef struct _nina_obj_t { #define SO_NO_CHECK (0x100a) #define NINAW10_POLL_INTERVAL (100) +#define IPADDR_STRLEN_MAX 46 + #define is_nonblocking_error(errno) ((errno) == MP_EAGAIN || (errno) == MP_EWOULDBLOCK || (errno) == MP_EINPROGRESS) #define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__) @@ -87,6 +90,8 @@ static mp_sched_node_t mp_wifi_poll_node; static soft_timer_entry_t mp_wifi_poll_timer; static void network_ninaw10_deinit(void); +static bool network_ninaw10_dhcp_active = false; + static bool network_ninaw10_poll_list_is_empty(void) { return MP_STATE_PORT(mp_wifi_poll_list) == NULL || MP_STATE_PORT(mp_wifi_poll_list)->len == 0; @@ -199,6 +204,7 @@ static mp_obj_t network_ninaw10_active(size_t n_args, const mp_obj_t *args) { mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("failed to initialize Nina-W10 module, error: %d"), error); } + network_ninaw10_dhcp_active = true; // check firmware version uint8_t semver[NINA_FW_VER_LEN]; if (nina_fw_version(semver) != 0) { @@ -367,11 +373,155 @@ static mp_obj_t network_ninaw10_ifconfig(size_t n_args, const mp_obj_t *args) { netutils_parse_ipv4_addr(items[2], ifconfig.gateway_addr, NETUTILS_BIG); netutils_parse_ipv4_addr(items[3], ifconfig.dns_addr, NETUTILS_BIG); nina_ifconfig(&ifconfig, true); + network_ninaw10_dhcp_active = false; return mp_const_none; } } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_ifconfig_obj, 1, 2, network_ninaw10_ifconfig); +mp_obj_t network_ninaw10_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + nina_ifconfig_t ifconfig; + // get ifconfig info + nina_ifconfig(&ifconfig, false); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + switch (mp_obj_str_get_qstr(args[0])) { + case MP_QSTR_dns: { + return netutils_format_ipv4_addr(ifconfig.dns_addr, NETUTILS_BIG); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } else { + // Set config value(s) + if (n_args != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dns: { + netutils_parse_ipv4_addr(e->value, ifconfig.dns_addr, NETUTILS_BIG); + nina_ifconfig(&ifconfig, true); + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + } + return mp_const_none; +} + +static mp_obj_t network_ninaw10_nic_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + nina_ifconfig_t ifconfig; + // get ifconfig info + nina_ifconfig(&ifconfig, false); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_dhcp4: { + return mp_obj_new_bool(network_ninaw10_dhcp_active); + } + case MP_QSTR_has_dhcp4: { + uint16_t ip_sum = + ifconfig.ip_addr[0] + ifconfig.ip_addr[1] + ifconfig.ip_addr[2] + ifconfig.ip_addr[3]; + if (network_ninaw10_dhcp_active) { + return mp_obj_new_bool(ip_sum != 0); + } else { + return mp_const_false; + } + } + case MP_QSTR_addr4: { + mp_obj_t tuple[2] = { + netutils_format_ipv4_addr(ifconfig.ip_addr, NETUTILS_BIG), + netutils_format_ipv4_addr(ifconfig.subnet_addr, NETUTILS_BIG), + }; + return mp_obj_new_tuple(2, tuple); + } + case MP_QSTR_gw4: { + return netutils_format_ipv4_addr(ifconfig.gateway_addr, NETUTILS_BIG); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + return mp_const_none; + } else { + // Set config value(s) + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dhcp4: { + mp_raise_ValueError(MP_ERROR_TEXT("DHCP control unsupported")); + break; + } + case MP_QSTR_addr4: { + int prefix_bits = 32; + if (e->value != mp_const_none && mp_obj_is_str(e->value)) { + size_t addr_len; + const char *input_str = mp_obj_str_get_data(e->value, &addr_len); + char *split = strchr(input_str, '/'); + if (split) { + mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL); + prefix_bits = mp_obj_get_int(prefix_obj); + uint32_t mask = -(1u << (32 - prefix_bits)); + ifconfig.subnet_addr[0] = (mask >> 24) & 0xFF; + ifconfig.subnet_addr[1] = (mask >> 16) & 0xFF; + ifconfig.subnet_addr[2] = (mask >> 8) & 0xFF; + ifconfig.subnet_addr[3] = mask & 0xFF; + } + netutils_parse_ipv4_addr(e->value, ifconfig.ip_addr, NETUTILS_BIG); + } else if (e->value != mp_const_none) { + mp_obj_t *items; + mp_obj_get_array_fixed_n(e->value, 2, &items); + netutils_parse_ipv4_addr(items[0], ifconfig.ip_addr, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], ifconfig.subnet_addr, NETUTILS_BIG); + } + nina_ifconfig(&ifconfig, true); + network_ninaw10_dhcp_active = false; + break; + } + case MP_QSTR_gw4: { + netutils_parse_ipv4_addr(e->value, ifconfig.gateway_addr, NETUTILS_BIG); + nina_ifconfig(&ifconfig, true); + network_ninaw10_dhcp_active = false; + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(network_ninaw10_nic_ipconfig_obj, 1, network_ninaw10_nic_ipconfig); + static mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { nina_obj_t *self = MP_OBJ_TO_PTR(args[0]); (void)self; @@ -856,6 +1006,7 @@ static const mp_rom_map_elem_t nina_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ninaw10_disconnect_obj) }, { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ninaw10_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ninaw10_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_ninaw10_nic_ipconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ninaw10_config_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ninaw10_status_obj) }, { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&network_ninaw10_ioctl_obj) }, diff --git a/ports/cc3200/mods/modnetwork.c b/ports/cc3200/mods/modnetwork.c index 3a949136dc..7de32ea3b6 100644 --- a/ports/cc3200/mods/modnetwork.c +++ b/ports/cc3200/mods/modnetwork.c @@ -143,6 +143,9 @@ static mp_obj_t network_server_deinit(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(network_server_deinit_obj, network_server_deinit); #endif +mp_obj_t mod_network_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); +MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, mod_network_ipconfig); + static const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_wlan) }, @@ -150,6 +153,7 @@ static const mp_rom_map_elem_t mp_module_network_globals_table[] = { #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) { MP_ROM_QSTR(MP_QSTR_Server), MP_ROM_PTR(&network_server_type) }, #endif + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&mod_network_ipconfig_obj) }, }; static MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table); diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c index fc55201eaa..547f6e55f7 100644 --- a/ports/cc3200/mods/modwlan.c +++ b/ports/cc3200/mods/modwlan.c @@ -32,6 +32,7 @@ #include "py/mpconfig.h" #include "py/obj.h" #include "py/objstr.h" +#include "py/parsenum.h" #include "py/runtime.h" #include "py/stream.h" #include "py/mphal.h" @@ -1057,6 +1058,164 @@ static mp_obj_t wlan_ifconfig(size_t n_args, const mp_obj_t *pos_args, mp_map_t } static MP_DEFINE_CONST_FUN_OBJ_KW(wlan_ifconfig_obj, 1, wlan_ifconfig); +mp_obj_t mod_network_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + + unsigned char len = sizeof(SlNetCfgIpV4Args_t); + unsigned char dhcpIsOn; + SlNetCfgIpV4Args_t ipV4; + sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO, &dhcpIsOn, &len, (uint8_t *)&ipV4); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + switch (mp_obj_str_get_qstr(args[0])) { + case MP_QSTR_dns: { + return netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4DnsServer, NETUTILS_LITTLE); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } else { + // Set config value(s) + if (n_args != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dns: { + netutils_parse_ipv4_addr(e->value, (uint8_t *)&ipV4.ipV4DnsServer, NETUTILS_LITTLE); + sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4); + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + } + return mp_const_none; +} + +static mp_obj_t wlan_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + + unsigned char len = sizeof(SlNetCfgIpV4Args_t); + unsigned char dhcpIsOn; + SlNetCfgIpV4Args_t ipV4; + sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO, &dhcpIsOn, &len, (uint8_t *)&ipV4); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_dhcp4: { + return mp_obj_new_bool(dhcpIsOn); + } + case MP_QSTR_has_dhcp4: { + return mp_obj_new_bool(dhcpIsOn && ipV4.ipV4 != 0); + } + case MP_QSTR_addr4: { + mp_obj_t tuple[2] = { + netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4, NETUTILS_LITTLE), + netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4Mask, NETUTILS_LITTLE), + }; + return mp_obj_new_tuple(2, tuple); + } + case MP_QSTR_gw4: { + return netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4Gateway, NETUTILS_LITTLE); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + return mp_const_none; + } else { + // Set config value(s) + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dhcp4: { + if (wlan_obj.mode == ROLE_AP) { + if (mp_obj_is_true(e->value)) { + sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, + sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4); + SlNetAppDhcpServerBasicOpt_t dhcpParams; + dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address + dhcpParams.ipv4_addr_start = ipV4.ipV4 + 1; // first IP Address for allocation. + dhcpParams.ipv4_addr_last = (ipV4.ipV4 & 0xFFFFFF00) + 254; // last IP Address for allocation. + sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID); // stop DHCP server before settings + sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT, + sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams); // set parameters + sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID); // start DHCP server with new settings + } else { + sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID); // stop DHCP server before settings + } + } else { + _u8 val = 1; + if (mp_obj_is_true(e->value)) { + sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, 1, &val); + } else { + sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, + sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4); + } + } + break; + } + case MP_QSTR_addr4: { + int prefix_bits = 32; + if (e->value != mp_const_none && mp_obj_is_str(e->value)) { + size_t addr_len; + const char *input_str = mp_obj_str_get_data(e->value, &addr_len); + char *split = strchr(input_str, '/'); + if (split) { + mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL); + prefix_bits = mp_obj_get_int(prefix_obj); + ipV4.ipV4Mask = -(1u << (32 - prefix_bits)); + } + netutils_parse_ipv4_addr(e->value, (uint8_t *)&ipV4.ipV4, NETUTILS_LITTLE); + } else if (e->value != mp_const_none) { + mp_obj_t *items; + mp_obj_get_array_fixed_n(e->value, 2, &items); + netutils_parse_ipv4_addr(items[0], (uint8_t *)&ipV4.ipV4, NETUTILS_LITTLE); + netutils_parse_ipv4_addr(items[1], (uint8_t *)&ipV4.ipV4Mask, NETUTILS_LITTLE); + } + ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4)); + break; + } + case MP_QSTR_gw4: { + netutils_parse_ipv4_addr(e->value, (uint8_t *)&ipV4.ipV4Gateway, NETUTILS_LITTLE); + sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4); + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(wlan_ipconfig_obj, 1, wlan_ipconfig); + static mp_obj_t wlan_mode(size_t n_args, const mp_obj_t *args) { wlan_obj_t *self = args[0]; if (n_args == 1) { @@ -1260,6 +1419,7 @@ static const mp_rom_map_elem_t wlan_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&wlan_disconnect_obj) }, { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wlan_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wlan_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&wlan_ipconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&wlan_mode_obj) }, { MP_ROM_QSTR(MP_QSTR_ssid), MP_ROM_PTR(&wlan_ssid_obj) }, { MP_ROM_QSTR(MP_QSTR_auth), MP_ROM_PTR(&wlan_auth_obj) }, diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h index e57b80657f..387f961976 100644 --- a/ports/esp32/modnetwork.h +++ b/ports/esp32/modnetwork.h @@ -54,6 +54,8 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_get_wlan_obj); MP_DECLARE_CONST_FUN_OBJ_KW(esp_network_get_lan_obj); MP_DECLARE_CONST_FUN_OBJ_1(esp_network_ppp_make_new_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_ifconfig_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(esp_network_ipconfig_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(esp_nic_ipconfig_obj); MP_DECLARE_CONST_FUN_OBJ_KW(esp_network_config_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_phy_mode_obj); diff --git a/ports/esp32/modnetwork_globals.h b/ports/esp32/modnetwork_globals.h index 7dd2ee9e66..c0cf229421 100644 --- a/ports/esp32/modnetwork_globals.h +++ b/ports/esp32/modnetwork_globals.h @@ -11,6 +11,7 @@ { MP_ROM_QSTR(MP_QSTR_PPP), MP_ROM_PTR(&esp_network_ppp_make_new_obj) }, #endif { MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_network_phy_mode_obj) }, +{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&esp_network_ipconfig_obj) }, #if MICROPY_PY_NETWORK_WLAN { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(WIFI_IF_STA)}, diff --git a/ports/esp32/network_common.c b/ports/esp32/network_common.c index 223803a5d1..d22cac43bd 100644 --- a/ports/esp32/network_common.c +++ b/ports/esp32/network_common.c @@ -34,6 +34,7 @@ #include #include "py/runtime.h" +#include "py/parsenum.h" #include "py/mperrno.h" #include "shared/netutils/netutils.h" #include "modnetwork.h" @@ -42,7 +43,7 @@ #include "esp_netif.h" #include "esp_wifi.h" #include "lwip/sockets.h" -// #include "lwip/dns.h" +#include "lwip/dns.h" NORETURN void esp_exceptions_helper(esp_err_t e) { switch (e) { @@ -154,6 +155,176 @@ static mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_ifconfig_obj, 1, 2, esp_ifconfig); +static mp_obj_t esp_network_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + if (kwargs->used == 0) { + // Get config value + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[0])) { + case MP_QSTR_dns: { + char addr_str[IPADDR_STRLEN_MAX]; + ipaddr_ntoa_r(dns_getserver(0), addr_str, sizeof(addr_str)); + return mp_obj_new_str(addr_str, strlen(addr_str)); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } else { + // Set config value(s) + if (n_args != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dns: { + ip_addr_t dns; + size_t addr_len; + const char *addr_str = mp_obj_str_get_data(e->value, &addr_len); + if (!ipaddr_aton(addr_str, &dns)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments as dns server")); + } + dns_setserver(0, &dns); + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(esp_network_ipconfig_obj, 0, esp_network_ipconfig); + +static mp_obj_t esp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + base_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + esp_netif_ip_info_t info; + esp_netif_get_ip_info(self->netif, &info); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_dhcp4: { + if (self->if_id == ESP_IF_WIFI_STA || self->if_id == ESP_IF_ETH) { + esp_netif_dhcp_status_t status; + esp_exceptions(esp_netif_dhcpc_get_status(self->netif, &status)); + return mp_obj_new_bool(status == ESP_NETIF_DHCP_STARTED); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + case MP_QSTR_addr4: { + mp_obj_t tuple[2] = { + netutils_format_ipv4_addr((uint8_t *)&info.ip, NETUTILS_BIG), + netutils_format_ipv4_addr((uint8_t *)&info.netmask, NETUTILS_BIG), + }; + return mp_obj_new_tuple(2, tuple); + } + case MP_QSTR_gw4: { + return netutils_format_ipv4_addr((uint8_t *)&info.gw, NETUTILS_BIG); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + return mp_const_none; + } else { + // Set config value(s) + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + int touched_ip_info = 0; + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dhcp4: { + esp_netif_dhcp_status_t status; + if (self->if_id == ESP_IF_WIFI_STA || self->if_id == ESP_IF_ETH) { + esp_exceptions(esp_netif_dhcpc_get_status(self->netif, &status)); + if (mp_obj_is_true(e->value) && status != ESP_NETIF_DHCP_STARTED) { + esp_exceptions(esp_netif_dhcpc_start(self->netif)); + } else if (!mp_obj_is_true(e->value) && status == ESP_NETIF_DHCP_STARTED) { + esp_exceptions(esp_netif_dhcpc_stop(self->netif)); + } + } else { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + break; + } + case MP_QSTR_addr4: { + if (e->value != mp_const_none && mp_obj_is_str(e->value)) { + size_t addr_len; + const char *input_str = mp_obj_str_get_data(e->value, &addr_len); + char *split = strchr(input_str, '/'); + if (split) { + mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL); + int prefix_bits = mp_obj_get_int(prefix_obj); + uint32_t mask = -(1u << (32 - prefix_bits)); + uint32_t *m = (uint32_t *)&info.netmask; + *m = esp_netif_htonl(mask); + } + netutils_parse_ipv4_addr(e->value, (void *)&info.ip, NETUTILS_BIG); + } else if (e->value != mp_const_none) { + mp_obj_t *items; + mp_obj_get_array_fixed_n(e->value, 2, &items); + netutils_parse_ipv4_addr(items[0], (void *)&info.ip, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], (void *)&info.netmask, NETUTILS_BIG); + } + touched_ip_info = 1; + break; + } + case MP_QSTR_gw4: { + netutils_parse_ipv4_addr(e->value, (void *)&info.gw, NETUTILS_BIG); + touched_ip_info = 1; + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + if (self->if_id == ESP_IF_WIFI_STA || self->if_id == ESP_IF_ETH) { + if (touched_ip_info) { + esp_err_t e = esp_netif_dhcpc_stop(self->netif); + if (e != ESP_OK && e != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) { + esp_exceptions_helper(e); + } + esp_exceptions(esp_netif_set_ip_info(self->netif, &info)); + } + } else if (self->if_id == ESP_IF_WIFI_AP) { + esp_err_t e = esp_netif_dhcps_stop(self->netif); + if (e != ESP_OK && e != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) { + esp_exceptions_helper(e); + } + esp_exceptions(esp_netif_set_ip_info(self->netif, &info)); + esp_exceptions(esp_netif_dhcps_start(self->netif)); + } + + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(esp_nic_ipconfig_obj, 1, esp_ipconfig); + + mp_obj_t esp_ifname(esp_netif_t *netif) { char ifname[NETIF_NAMESIZE + 1] = {0}; mp_obj_t ret = mp_const_none; diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c index 570c9a4afd..7e7ebcc929 100644 --- a/ports/esp32/network_lan.c +++ b/ports/esp32/network_lan.c @@ -404,6 +404,7 @@ static const mp_rom_map_elem_t lan_if_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&lan_status_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&lan_config_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_network_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&esp_nic_ipconfig_obj) }, }; static MP_DEFINE_CONST_DICT(lan_if_locals_dict, lan_if_locals_dict_table); diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c index 4e9b2a32ca..1a66adc53f 100644 --- a/ports/esp32/network_ppp.c +++ b/ports/esp32/network_ppp.c @@ -266,6 +266,43 @@ static mp_obj_t ppp_ifconfig(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_ifconfig_obj, 1, 2, ppp_ifconfig); +static mp_obj_t ppp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + + if (kwargs->used == 0) { + ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (self->pcb == NULL) { + mp_raise_ValueError(MP_ERROR_TEXT("PPP not active")); + } + struct netif *netif = ppp_netif(self->pcb); + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_addr4: { + mp_obj_t tuple[2] = { + netutils_format_ipv4_addr((uint8_t *)&netif->ip_addr, NETUTILS_BIG), + netutils_format_ipv4_addr((uint8_t *)&netif->netmask, NETUTILS_BIG), + }; + return mp_obj_new_tuple(2, tuple); + } + case MP_QSTR_gw4: { + return netutils_format_ipv4_addr((uint8_t *)&netif->gw, NETUTILS_BIG); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + return mp_const_none; + } else { + mp_raise_TypeError(MP_ERROR_TEXT("setting properties not supported")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(ppp_ipconfig_obj, 1, ppp_ipconfig); + static mp_obj_t ppp_status(mp_obj_t self_in) { return mp_const_none; } @@ -328,6 +365,7 @@ static const mp_rom_map_elem_t ppp_if_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&ppp_config_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&ppp_ipconfig_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) }, { MP_ROM_QSTR(MP_QSTR_AUTH_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) }, { MP_ROM_QSTR(MP_QSTR_AUTH_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) }, diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index eb2bcda03e..6d051f0256 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -728,6 +728,7 @@ static const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_wlan_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_wlan_config_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_network_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&esp_nic_ipconfig_obj) }, // Constants { MP_ROM_QSTR(MP_QSTR_IF_STA), MP_ROM_INT(WIFI_IF_STA)}, diff --git a/ports/esp8266/modnetwork.h b/ports/esp8266/modnetwork.h index 5fd142e71e..5f451c866a 100644 --- a/ports/esp8266/modnetwork.h +++ b/ports/esp8266/modnetwork.h @@ -1,3 +1,4 @@ extern const mp_obj_type_t esp_network_wlan_type; MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_phy_mode_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(esp_network_ipconfig_obj); diff --git a/ports/esp8266/modnetwork_globals.h b/ports/esp8266/modnetwork_globals.h index 1a04568024..972b0e9806 100644 --- a/ports/esp8266/modnetwork_globals.h +++ b/ports/esp8266/modnetwork_globals.h @@ -1,5 +1,6 @@ { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&esp_network_wlan_type) }, { MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_network_phy_mode_obj) }, +{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&esp_network_ipconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(STATION_IF)}, { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(SOFTAP_IF)}, diff --git a/ports/esp8266/network_wlan.c b/ports/esp8266/network_wlan.c index af1611a249..0ffc898f8e 100644 --- a/ports/esp8266/network_wlan.c +++ b/ports/esp8266/network_wlan.c @@ -31,6 +31,7 @@ #include "py/objlist.h" #include "py/runtime.h" #include "py/mphal.h" +#include "py/parsenum.h" #include "extmod/modnetwork.h" #include "shared/netutils/netutils.h" #include "queue.h" @@ -41,6 +42,8 @@ #include "lwip/dns.h" #include "modnetwork.h" +#define IPADDR_STRLEN_MAX (20) + typedef struct _wlan_if_obj_t { mp_obj_base_t base; int if_id; @@ -330,6 +333,174 @@ static mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig); +static mp_obj_t esp_network_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + if (kwargs->used == 0) { + // Get config value + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[0])) { + case MP_QSTR_dns: { + char addr_str[IPADDR_STRLEN_MAX]; + ip_addr_t dns_addr = dns_getserver(0); + ipaddr_ntoa_r(&dns_addr, addr_str, sizeof(addr_str)); + return mp_obj_new_str(addr_str, strlen(addr_str)); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } else { + // Set config value(s) + if (n_args != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dns: { + ip_addr_t dns; + size_t addr_len; + const char *addr_str = mp_obj_str_get_data(e->value, &addr_len); + if (!ipaddr_aton(addr_str, &dns)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments as dns server")); + } + dns_setserver(0, &dns); + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(esp_network_ipconfig_obj, 0, esp_network_ipconfig); + +static mp_obj_t esp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + struct ip_info info; + wifi_get_ip_info(self->if_id, &info); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_dhcp4: { + if (self->if_id == STATION_IF) { + return mp_obj_new_bool(wifi_station_dhcpc_status() == DHCP_STARTED); + } else if (self->if_id == SOFTAP_IF) { + return mp_obj_new_bool(wifi_softap_dhcps_status() == DHCP_STARTED); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + case MP_QSTR_addr4: { + mp_obj_t tuple[2] = { + netutils_format_ipv4_addr((uint8_t *)&info.ip, NETUTILS_BIG), + netutils_format_ipv4_addr((uint8_t *)&info.netmask, NETUTILS_BIG), + }; + return mp_obj_new_tuple(2, tuple); + } + case MP_QSTR_gw4: { + return netutils_format_ipv4_addr((uint8_t *)&info.gw, NETUTILS_BIG); + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + return mp_const_none; + } else { + // Set config value(s) + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + int touched_ip_info = 0; + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_dhcp4: { + if (self->if_id == STATION_IF) { + enum dhcp_status status = wifi_station_dhcpc_status(); + if (mp_obj_is_true(e->value) && status != DHCP_STARTED) { + wifi_station_dhcpc_start(); + } else if (!mp_obj_is_true(e->value) && status == DHCP_STARTED) { + wifi_station_dhcpc_stop(); + } + } else { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + break; + } + case MP_QSTR_addr4: { + if (e->value != mp_const_none && mp_obj_is_str(e->value)) { + size_t addr_len; + const char *input_str = mp_obj_str_get_data(e->value, &addr_len); + char *split = strchr(input_str, '/'); + if (split) { + mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL); + int prefix_bits = mp_obj_get_int(prefix_obj); + uint32_t mask = -(1u << (32 - prefix_bits)); + uint32_t *m = (uint32_t *)&info.netmask; + *m = htonl(mask); + } + netutils_parse_ipv4_addr(e->value, (void *)&info.ip, NETUTILS_BIG); + } else if (e->value != mp_const_none) { + mp_obj_t *items; + mp_obj_get_array_fixed_n(e->value, 2, &items); + netutils_parse_ipv4_addr(items[0], (void *)&info.ip, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], (void *)&info.netmask, NETUTILS_BIG); + } + touched_ip_info = 1; + break; + } + case MP_QSTR_gw4: { + netutils_parse_ipv4_addr(e->value, (void *)&info.gw, NETUTILS_BIG); + touched_ip_info = 1; + break; + } + default: { + mp_raise_ValueError(MP_ERROR_TEXT("unexpected key")); + break; + } + } + } + } + bool restart_dhcp_server = false; + if (self->if_id == STATION_IF) { + if (touched_ip_info) { + wifi_station_dhcpc_stop(); + wifi_set_ip_info(self->if_id, &info); + } + } else { + restart_dhcp_server = wifi_softap_dhcps_status(); + wifi_softap_dhcps_stop(); + wifi_set_ip_info(self->if_id, &info); + } + if (restart_dhcp_server) { + wifi_softap_dhcps_start(); + } + + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(esp_nic_ipconfig_obj, 1, esp_ipconfig); + + static mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { if (n_args != 1 && kwargs->used != 0) { mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed")); @@ -514,6 +685,7 @@ static const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&esp_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&esp_config_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&esp_nic_ipconfig_obj) }, // Constants { MP_ROM_QSTR(MP_QSTR_IF_STA), MP_ROM_INT(STATION_IF)}, diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index e01079cbf3..7d6ae2d727 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -179,6 +179,12 @@ static mp_obj_t network_lan_ifconfig(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_lan_ifconfig_obj, 1, 2, network_lan_ifconfig); +static mp_obj_t network_lan_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); + return mod_network_nic_ipconfig(eth_netif(self->eth), n_args - 1, args + 1, kwargs); +} +static MP_DEFINE_CONST_FUN_OBJ_KW(network_lan_ipconfig_obj, 1, network_lan_ipconfig); + static mp_obj_t network_lan_status(size_t n_args, const mp_obj_t *args) { network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); (void)self; @@ -241,6 +247,7 @@ static const mp_rom_map_elem_t network_lan_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_lan_active_obj) }, { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_lan_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_lan_ipconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) }, diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c index 27f3e1337e..0ef33e2977 100644 --- a/ports/stm32/network_lan.c +++ b/ports/stm32/network_lan.c @@ -101,6 +101,12 @@ static mp_obj_t network_lan_ifconfig(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_lan_ifconfig_obj, 1, 2, network_lan_ifconfig); +static mp_obj_t network_lan_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); + return mod_network_nic_ipconfig(eth_netif(self->eth), n_args - 1, args + 1, kwargs); +} +static MP_DEFINE_CONST_FUN_OBJ_KW(network_lan_ipconfig_obj, 1, network_lan_ipconfig); + static mp_obj_t network_lan_status(size_t n_args, const mp_obj_t *args) { network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); (void)self; @@ -163,6 +169,7 @@ static const mp_rom_map_elem_t network_lan_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_lan_active_obj) }, { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_lan_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_lan_ipconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) }, diff --git a/shared/netutils/netutils.c b/shared/netutils/netutils.c index 84b4405c41..cd1422f7c8 100644 --- a/shared/netutils/netutils.c +++ b/shared/netutils/netutils.c @@ -63,7 +63,13 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian return; } const char *s = addr_str; - const char *s_top = addr_str + addr_len; + const char *s_top; + // Scan for the end of valid address characters + for (s_top = addr_str; s_top < addr_str + addr_len; s_top++) { + if (!(*s_top == '.' || (*s_top >= '0' && *s_top <= '9'))) { + break; + } + } for (mp_uint_t i = 3; ; i--) { mp_uint_t val = 0; for (; s < s_top && *s != '.'; s++) {