Skip to content

Commit 7e7cc2b

Browse files
robert-hhdpgeorge
authored andcommitted
extmod/network_ninaw10: Implement the ipconfig methods for ninaw10.
This implements network.ipconfig() and network.WLAN.ipconfig() when the ninaw10 driver is used for WLAN. Due to a omission in the ninaw10 driver stack, setting the DNS address has no effect. But the interface is kept here just in case it's fixed eventually. dhcp4 and has_dhcp4 are dummy arguments. Ninaw10 seems to always use DHCP. Signed-off-by: robert-hh <[email protected]>
1 parent 1f23ab1 commit 7e7cc2b

File tree

4 files changed

+166
-2
lines changed

4 files changed

+166
-2
lines changed

extmod/modnetwork.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,15 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_network_hostname_obj, 0, 1, mod_n
144144
#if LWIP_VERSION_MAJOR >= 2
145145
MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, mod_network_ipconfig);
146146
#endif
147+
#if MICROPY_PY_NETWORK_NINAW10
148+
MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, network_ninaw10_ipconfig);
149+
#endif
147150

148151
static const mp_rom_map_elem_t mp_module_network_globals_table[] = {
149152
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) },
150153
{ MP_ROM_QSTR(MP_QSTR_country), MP_ROM_PTR(&mod_network_country_obj) },
151154
{ MP_ROM_QSTR(MP_QSTR_hostname), MP_ROM_PTR(&mod_network_hostname_obj) },
152-
#if LWIP_VERSION_MAJOR >= 2
155+
#if LWIP_VERSION_MAJOR >= 2 || MICROPY_PY_NETWORK_NINAW10
153156
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&mod_network_ipconfig_obj) },
154157
#endif
155158

extmod/modnetwork.h

+4
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ extern int mp_mod_network_prefer_dns_use_ip_version;
8383
#endif
8484
#elif defined(MICROPY_PORT_NETWORK_INTERFACES)
8585

86+
#if MICROPY_PY_NETWORK_NINAW10
87+
mp_obj_t network_ninaw10_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
88+
#endif
89+
8690
struct _mod_network_socket_obj_t;
8791

8892
typedef struct _mod_network_nic_protocol_t {

extmod/network_ninaw10.c

+151
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "py/runtime.h"
4242
#include "py/misc.h"
4343
#include "py/mperrno.h"
44+
#include "py/parsenum.h"
4445
#include "shared/netutils/netutils.h"
4546
#include "shared/runtime/softtimer.h"
4647
#include "extmod/modnetwork.h"
@@ -75,6 +76,8 @@ typedef struct _nina_obj_t {
7576
#define SO_NO_CHECK (0x100a)
7677
#define NINAW10_POLL_INTERVAL (100)
7778

79+
#define IPADDR_STRLEN_MAX 46
80+
7881
#define is_nonblocking_error(errno) ((errno) == MP_EAGAIN || (errno) == MP_EWOULDBLOCK || (errno) == MP_EINPROGRESS)
7982

8083
#define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__)
@@ -87,6 +90,8 @@ static mp_sched_node_t mp_wifi_poll_node;
8790
static soft_timer_entry_t mp_wifi_poll_timer;
8891
static void network_ninaw10_deinit(void);
8992

93+
static bool network_ninaw10_dhcp_active = false;
94+
9095
static bool network_ninaw10_poll_list_is_empty(void) {
9196
return MP_STATE_PORT(mp_wifi_poll_list) == NULL ||
9297
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) {
199204
mp_raise_msg_varg(&mp_type_OSError,
200205
MP_ERROR_TEXT("failed to initialize Nina-W10 module, error: %d"), error);
201206
}
207+
network_ninaw10_dhcp_active = true;
202208
// check firmware version
203209
uint8_t semver[NINA_FW_VER_LEN];
204210
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) {
367373
netutils_parse_ipv4_addr(items[2], ifconfig.gateway_addr, NETUTILS_BIG);
368374
netutils_parse_ipv4_addr(items[3], ifconfig.dns_addr, NETUTILS_BIG);
369375
nina_ifconfig(&ifconfig, true);
376+
network_ninaw10_dhcp_active = false;
370377
return mp_const_none;
371378
}
372379
}
373380
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_ifconfig_obj, 1, 2, network_ninaw10_ifconfig);
374381

382+
mp_obj_t network_ninaw10_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
383+
nina_ifconfig_t ifconfig;
384+
// get ifconfig info
385+
nina_ifconfig(&ifconfig, false);
386+
387+
if (kwargs->used == 0) {
388+
// Get config value
389+
if (n_args != 1) {
390+
mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
391+
}
392+
switch (mp_obj_str_get_qstr(args[0])) {
393+
case MP_QSTR_dns: {
394+
return netutils_format_ipv4_addr(ifconfig.dns_addr, NETUTILS_BIG);
395+
}
396+
default: {
397+
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
398+
break;
399+
}
400+
}
401+
} else {
402+
// Set config value(s)
403+
if (n_args != 0) {
404+
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
405+
}
406+
407+
for (size_t i = 0; i < kwargs->alloc; ++i) {
408+
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
409+
mp_map_elem_t *e = &kwargs->table[i];
410+
switch (mp_obj_str_get_qstr(e->key)) {
411+
case MP_QSTR_dns: {
412+
netutils_parse_ipv4_addr(e->value, ifconfig.dns_addr, NETUTILS_BIG);
413+
nina_ifconfig(&ifconfig, true);
414+
break;
415+
}
416+
default: {
417+
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
418+
break;
419+
}
420+
}
421+
}
422+
}
423+
}
424+
return mp_const_none;
425+
}
426+
427+
static mp_obj_t network_ninaw10_nic_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
428+
nina_ifconfig_t ifconfig;
429+
// get ifconfig info
430+
nina_ifconfig(&ifconfig, false);
431+
432+
if (kwargs->used == 0) {
433+
// Get config value
434+
if (n_args != 2) {
435+
mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
436+
}
437+
438+
switch (mp_obj_str_get_qstr(args[1])) {
439+
case MP_QSTR_dhcp4: {
440+
return mp_obj_new_bool(network_ninaw10_dhcp_active);
441+
}
442+
case MP_QSTR_has_dhcp4: {
443+
uint16_t ip_sum =
444+
ifconfig.ip_addr[0] + ifconfig.ip_addr[1] + ifconfig.ip_addr[2] + ifconfig.ip_addr[3];
445+
if (network_ninaw10_dhcp_active) {
446+
return mp_obj_new_bool(ip_sum != 0);
447+
} else {
448+
return mp_const_false;
449+
}
450+
}
451+
case MP_QSTR_addr4: {
452+
mp_obj_t tuple[2] = {
453+
netutils_format_ipv4_addr(ifconfig.ip_addr, NETUTILS_BIG),
454+
netutils_format_ipv4_addr(ifconfig.subnet_addr, NETUTILS_BIG),
455+
};
456+
return mp_obj_new_tuple(2, tuple);
457+
}
458+
case MP_QSTR_gw4: {
459+
return netutils_format_ipv4_addr(ifconfig.gateway_addr, NETUTILS_BIG);
460+
}
461+
default: {
462+
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
463+
break;
464+
}
465+
}
466+
return mp_const_none;
467+
} else {
468+
// Set config value(s)
469+
if (n_args != 1) {
470+
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
471+
}
472+
473+
for (size_t i = 0; i < kwargs->alloc; ++i) {
474+
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
475+
mp_map_elem_t *e = &kwargs->table[i];
476+
switch (mp_obj_str_get_qstr(e->key)) {
477+
case MP_QSTR_dhcp4: {
478+
mp_raise_ValueError(MP_ERROR_TEXT("DHCP control unsupported"));
479+
break;
480+
}
481+
case MP_QSTR_addr4: {
482+
int prefix_bits = 32;
483+
if (e->value != mp_const_none && mp_obj_is_str(e->value)) {
484+
size_t addr_len;
485+
const char *input_str = mp_obj_str_get_data(e->value, &addr_len);
486+
char *split = strchr(input_str, '/');
487+
if (split) {
488+
mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL);
489+
prefix_bits = mp_obj_get_int(prefix_obj);
490+
uint32_t mask = -(1u << (32 - prefix_bits));
491+
ifconfig.subnet_addr[0] = (mask >> 24) & 0xFF;
492+
ifconfig.subnet_addr[1] = (mask >> 16) & 0xFF;
493+
ifconfig.subnet_addr[2] = (mask >> 8) & 0xFF;
494+
ifconfig.subnet_addr[3] = mask & 0xFF;
495+
}
496+
netutils_parse_ipv4_addr(e->value, ifconfig.ip_addr, NETUTILS_BIG);
497+
} else if (e->value != mp_const_none) {
498+
mp_obj_t *items;
499+
mp_obj_get_array_fixed_n(e->value, 2, &items);
500+
netutils_parse_ipv4_addr(items[0], ifconfig.ip_addr, NETUTILS_BIG);
501+
netutils_parse_ipv4_addr(items[1], ifconfig.subnet_addr, NETUTILS_BIG);
502+
}
503+
nina_ifconfig(&ifconfig, true);
504+
network_ninaw10_dhcp_active = false;
505+
break;
506+
}
507+
case MP_QSTR_gw4: {
508+
netutils_parse_ipv4_addr(e->value, ifconfig.gateway_addr, NETUTILS_BIG);
509+
nina_ifconfig(&ifconfig, true);
510+
network_ninaw10_dhcp_active = false;
511+
break;
512+
}
513+
default: {
514+
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
515+
break;
516+
}
517+
}
518+
}
519+
}
520+
}
521+
return mp_const_none;
522+
}
523+
static MP_DEFINE_CONST_FUN_OBJ_KW(network_ninaw10_nic_ipconfig_obj, 1, network_ninaw10_nic_ipconfig);
524+
375525
static mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
376526
nina_obj_t *self = MP_OBJ_TO_PTR(args[0]);
377527
(void)self;
@@ -856,6 +1006,7 @@ static const mp_rom_map_elem_t nina_locals_dict_table[] = {
8561006
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ninaw10_disconnect_obj) },
8571007
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ninaw10_isconnected_obj) },
8581008
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ninaw10_ifconfig_obj) },
1009+
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_ninaw10_nic_ipconfig_obj) },
8591010
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ninaw10_config_obj) },
8601011
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ninaw10_status_obj) },
8611012
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&network_ninaw10_ioctl_obj) },

shared/netutils/netutils.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,13 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian
6363
return;
6464
}
6565
const char *s = addr_str;
66-
const char *s_top = addr_str + addr_len;
66+
const char *s_top;
67+
// Scan for the end of valid address characters
68+
for (s_top = addr_str; s_top < addr_str + addr_len; s_top++) {
69+
if (!(*s_top == '.' || (*s_top >= '0' && *s_top <= '9'))) {
70+
break;
71+
}
72+
}
6773
for (mp_uint_t i = 3; ; i--) {
6874
mp_uint_t val = 0;
6975
for (; s < s_top && *s != '.'; s++) {

0 commit comments

Comments
 (0)