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 <robert@hammelrath.com>
1 parent 1f23ab1 commit 7e7cc2b

File tree

4 files changed

+166
-2
lines changed

4 files changed

+166
-2
lines changed

extmod/modnetwork.c

Lines changed: 4 additions & 1 deletion
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 151 additions & 0 deletions
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

Lines changed: 7 additions & 1 deletion
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy