Add wifi.radio.addresses, .addresses_ap, .dns

This commit is contained in:
Jeff Epler 2024-07-17 12:08:13 -05:00
parent 9088488d1c
commit 86f7a38ff4
7 changed files with 170 additions and 24 deletions

View file

@ -26,11 +26,11 @@
#include "components/lwip/lwip/src/include/lwip/netdb.h"
#include "components/vfs/include/esp_vfs_eventfd.h"
static void resolve_host_or_throw(socketpool_socket_obj_t *self, const char *hostname, struct sockaddr_storage *addr, int port) {
void socketpool_resolve_host_or_throw(int family, int type, const char *hostname, struct sockaddr_storage *addr, int port) {
struct addrinfo *result_i;
const struct addrinfo hints = {
.ai_family = self->family,
.ai_socktype = self->type,
.ai_family = family,
.ai_socktype = type,
};
int error = socketpool_getaddrinfo_common(hostname, port, &hints, &result_i);
if (error != 0 || result_i == NULL) {
@ -40,6 +40,10 @@ static void resolve_host_or_throw(socketpool_socket_obj_t *self, const char *hos
lwip_freeaddrinfo(result_i);
}
static void resolve_host_or_throw(socketpool_socket_obj_t *self, const char *hostname, struct sockaddr_storage *addr, int port) {
socketpool_resolve_host_or_throw(self->family, self->type, hostname, addr, port);
}
StackType_t socket_select_stack[2 * configMINIMAL_STACK_SIZE];
/* Socket state table:

View file

@ -9,3 +9,4 @@
struct addrinfo;
int socketpool_getaddrinfo_common(const char *host, int service, const struct addrinfo *hints, struct addrinfo **res);
void socketpool_resolve_host_or_throw(int family, int type, const char *hostname, struct sockaddr_storage *addr, int port);

View file

@ -20,6 +20,7 @@
#include "shared-bindings/wifi/AuthMode.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/ipaddress/__init__.h"
#include "common-hal/socketpool/__init__.h"
#include "components/esp_netif/include/esp_netif_net_stack.h"
#include "components/esp_wifi/include/esp_wifi.h"
@ -452,24 +453,38 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self) {
return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.netmask.addr);
}
mp_obj_t common_hal_wifi_radio_get_ipv6_addresses(wifi_radio_obj_t *self) {
if (!esp_netif_is_netif_up(self->netif)) {
return mp_const_none;
static mp_obj_t common_hal_wifi_radio_get_addresses_netif(wifi_radio_obj_t *self, esp_netif_t *netif) {
if (!esp_netif_is_netif_up(netif)) {
return mp_const_empty_tuple;
}
esp_netif_ip_info_t ip_info;
esp_netif_get_ip_info(netif, &ip_info);
int n_addresses4 = ip_info.ip.addr != INADDR_NONE;
esp_ip6_addr_t addresses[LWIP_IPV6_NUM_ADDRESSES];
int n_addresses = esp_netif_get_all_ip6(self->netif, &addresses[0]);
if (!n_addresses) {
return mp_const_none;
}
int n_addresses6 = esp_netif_get_all_ip6(netif, &addresses[0]);
int n_addresses = n_addresses4 + n_addresses6;
mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(n_addresses, NULL));
for (int i = 0; i < n_addresses; i++) {
char buf[IP6ADDR_STRLEN_MAX];
inet_ntop(AF_INET6, &addresses[i], buf, sizeof(buf));
result->items[i] = mp_obj_new_str(buf, strlen(buf));
for (int i = 0; i < n_addresses6; i++) {
result->items[i] = espaddr6_to_str(&addresses[i]);
}
if (n_addresses4) {
result->items[n_addresses6] = espaddr4_to_str(&ip_info.ip);
}
return MP_OBJ_FROM_PTR(result);
}
mp_obj_t common_hal_wifi_radio_get_addresses(wifi_radio_obj_t *self) {
return common_hal_wifi_radio_get_addresses_netif(self, self->netif);
}
mp_obj_t common_hal_wifi_radio_get_addresses_ap(wifi_radio_obj_t *self) {
return common_hal_wifi_radio_get_addresses_netif(self, self->ap_netif);
}
uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) {
if (!esp_netif_is_netif_up(self->netif)) {
return 0;
@ -501,6 +516,9 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_dns(wifi_radio_obj_t *self) {
esp_netif_get_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &self->dns_info);
if (self->dns_info.ip.type != ESP_IPADDR_TYPE_V4) {
return mp_const_none;
}
// dns_info is of type esp_netif_dns_info_t, which is just ever so slightly
// different than esp_netif_ip_info_t used for
// common_hal_wifi_radio_get_ipv4_address (includes both ipv4 and 6),
@ -621,3 +639,21 @@ void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self) {
// Only bother to scan the actual object references.
gc_collect_ptr(self->current_scan);
}
mp_obj_t common_hal_wifi_radio_get_dns(wifi_radio_obj_t *self) {
if (!esp_netif_is_netif_up(self->netif)) {
return mp_const_none;
}
esp_netif_get_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &self->dns_info);
return espaddr_to_str(&self->dns_info.ip);
}
void common_hal_wifi_radio_set_dns(wifi_radio_obj_t *self, mp_obj_t dns_addr_obj) {
struct sockaddr_storage addr_storage;
socketpool_resolve_host_or_throw(AF_UNSPEC, SOCK_STREAM, mp_obj_str_get_str(dns_addr_obj), &addr_storage, 1);
esp_netif_dns_info_t dns_info;
sockaddr_to_espaddr(&addr_storage, &dns_info.ip);
esp_netif_set_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &dns_info);
}

View file

@ -27,6 +27,8 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
#include "supervisor/port.h"
#include "supervisor/workflow.h"
#include "lwip/sockets.h"
#if CIRCUITPY_STATUS_BAR
#include "supervisor/shared/status_bar.h"
#endif
@ -255,3 +257,61 @@ void ipaddress_ipaddress_to_esp_idf_ip4(mp_obj_t ip_address, esp_ip4_addr_t *esp
void common_hal_wifi_gc_collect(void) {
common_hal_wifi_radio_gc_collect(&common_hal_wifi_radio_obj);
}
static mp_obj_t espaddrx_to_str(const void *espaddr, uint8_t esptype) {
char buf[IPADDR_STRLEN_MAX];
inet_ntop(esptype == ESP_IPADDR_TYPE_V6 ? AF_INET6 : AF_INET, espaddr, buf, sizeof(buf));
return mp_obj_new_str(buf, strlen(buf));
}
mp_obj_t espaddr_to_str(const esp_ip_addr_t *espaddr) {
return espaddrx_to_str(espaddr, espaddr->type);
}
mp_obj_t espaddr4_to_str(const esp_ip4_addr_t *espaddr) {
return espaddrx_to_str(espaddr, ESP_IPADDR_TYPE_V4);
}
mp_obj_t espaddr6_to_str(const esp_ip6_addr_t *espaddr) {
return espaddrx_to_str(espaddr, ESP_IPADDR_TYPE_V6);
}
mp_obj_t sockaddr_to_str(const struct sockaddr_storage *sockaddr) {
char buf[IPADDR_STRLEN_MAX];
if (sockaddr->ss_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const void *)sockaddr;
inet_ntop(AF_INET6, &addr6->sin6_addr, buf, sizeof(buf));
} else {
const struct sockaddr_in *addr = (const void *)sockaddr;
inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf));
}
return mp_obj_new_str(buf, strlen(buf));
}
void sockaddr_to_espaddr(const struct sockaddr_storage *sockaddr, esp_ip_addr_t *espaddr) {
if (sockaddr->ss_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const void *)sockaddr;
MP_STATIC_ASSERT(sizeof(espaddr->u_addr.ip6.addr) == sizeof(addr6->sin6_addr));
memcpy(&espaddr->u_addr.ip6.addr, &addr6->sin6_addr, sizeof(espaddr->u_addr.ip6.addr));
espaddr->u_addr.ip6.zone = addr6->sin6_scope_id;
espaddr->type = ESP_IPADDR_TYPE_V6;
} else {
const struct sockaddr_in *addr = (const void *)sockaddr;
MP_STATIC_ASSERT(sizeof(espaddr->u_addr.ip4.addr) == sizeof(addr->sin_addr));
memcpy(&espaddr->u_addr.ip4.addr, &addr->sin_addr, sizeof(espaddr->u_addr.ip4.addr));
espaddr->type = ESP_IPADDR_TYPE_V4;
}
}
void espaddr_to_sockaddr(const esp_ip_addr_t *espaddr, struct sockaddr_storage *sockaddr, int port) {
if (espaddr->type == ESP_IPADDR_TYPE_V6) {
struct sockaddr_in6 *addr6 = (void *)sockaddr;
MP_STATIC_ASSERT(sizeof(espaddr->u_addr.ip6.addr) == sizeof(addr6->sin6_addr));
memcpy(&addr6->sin6_addr, &espaddr->u_addr.ip6.addr, sizeof(espaddr->u_addr.ip6.addr));
addr6->sin6_scope_id = espaddr->u_addr.ip6.zone;
} else {
struct sockaddr_in *addr = (void *)sockaddr;
MP_STATIC_ASSERT(sizeof(espaddr->u_addr.ip4.addr) == sizeof(addr->sin_addr));
memcpy(&addr->sin_addr, &espaddr->u_addr.ip4.addr, sizeof(espaddr->u_addr.ip4.addr));
}
}

View file

@ -11,7 +11,16 @@
#include "lwip/api.h"
#include "components/esp_wifi/include/esp_wifi.h"
struct sockaddr_storage;
void wifi_reset(void);
void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address);
void ipaddress_ipaddress_to_esp_idf_ip4(mp_obj_t ip_address, esp_ip4_addr_t *esp_ip_address);
mp_obj_t sockaddr_to_str(const struct sockaddr_storage *addr);
mp_obj_t espaddr_to_str(const esp_ip_addr_t *espaddr);
mp_obj_t espaddr4_to_str(const esp_ip4_addr_t *espaddr);
mp_obj_t espaddr6_to_str(const esp_ip6_addr_t *espaddr);
void sockaddr_to_espaddr(const struct sockaddr_storage *sockaddr, esp_ip_addr_t *espaddr);
void espaddr_to_sockaddr(const esp_ip_addr_t *espaddr, struct sockaddr_storage *sockaddr, int port);

View file

@ -596,18 +596,29 @@ static mp_obj_t wifi_radio_set_ipv4_address_ap(size_t n_args, const mp_obj_t *po
}
static MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_set_ipv4_address_ap_obj, 1, wifi_radio_set_ipv4_address_ap);
//| ipv6_addresses: Sequence[str]
//| """IPv6 address(es) of the station when connected to an access point. None otherwise. (read-only)"""
static mp_obj_t _wifi_radio_get_ipv6_addresses(mp_obj_t self) {
return common_hal_wifi_radio_get_ipv6_addresses(self);
//| addresses: Sequence[str]
//| """Address(es) of the station when connected to an access point. Empty sequence when not connected. (read-only)"""
static mp_obj_t _wifi_radio_get_addresses(mp_obj_t self) {
return common_hal_wifi_radio_get_addresses(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv6_addresses_obj, _wifi_radio_get_ipv6_addresses);
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_addresses_obj, _wifi_radio_get_addresses);
MP_PROPERTY_GETTER(wifi_radio_addresses_obj,
(mp_obj_t)&wifi_radio_get_addresses_obj);
//| addresses_ap: Sequence[str]
//| """Address(es) of the access point when enabled. Empty sequence when disabled. (read-only)"""
static mp_obj_t _wifi_radio_get_addresses_ap(mp_obj_t self) {
return common_hal_wifi_radio_get_addresses_ap(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_addresses_ap_obj, _wifi_radio_get_addresses_ap);
MP_PROPERTY_GETTER(wifi_radio_addresses_ap_obj,
(mp_obj_t)&wifi_radio_get_addresses_ap_obj);
MP_PROPERTY_GETTER(wifi_radio_ipv6_addresses_obj,
(mp_obj_t)&wifi_radio_get_ipv6_addresses_obj);
#if 0
MP_WEAK mp_obj_t common_hal_wifi_radio_get_ipv6_addresses(wifi_radio_obj_t *self) {
MP_WEAK mp_obj_t common_hal_wifi_radio_get_addresses(wifi_radio_obj_t *self) {
return mp_const_none;
}
#endif
@ -650,6 +661,24 @@ MP_PROPERTY_GETSET(wifi_radio_ipv4_dns_obj,
(mp_obj_t)&wifi_radio_get_ipv4_dns_obj,
(mp_obj_t)&wifi_radio_set_ipv4_dns_obj);
//| dns: str
//| """Address of the DNS server to be used."""
static mp_obj_t wifi_radio_get_dns(mp_obj_t self) {
return common_hal_wifi_radio_get_dns(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_dns_obj, wifi_radio_get_dns);
static mp_obj_t wifi_radio_set_dns(mp_obj_t self, mp_obj_t dns_addr) {
common_hal_wifi_radio_set_dns(self, dns_addr);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_dns_obj, wifi_radio_set_dns);
MP_PROPERTY_GETSET(wifi_radio_dns_obj,
(mp_obj_t)&wifi_radio_get_dns_obj,
(mp_obj_t)&wifi_radio_set_dns_obj);
//| ap_info: Optional[Network]
//| """Network object containing BSSID, SSID, authmode, channel, country and RSSI when connected to an access point. None otherwise."""
static mp_obj_t wifi_radio_get_ap_info(mp_obj_t self) {
@ -784,11 +813,14 @@ static const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ipv4_subnet_ap), MP_ROM_PTR(&wifi_radio_ipv4_subnet_ap_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipv4_address), MP_ROM_PTR(&wifi_radio_ipv4_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipv4_address_ap), MP_ROM_PTR(&wifi_radio_ipv4_address_ap_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipv6_addresses), MP_ROM_PTR(&wifi_radio_ipv6_addresses_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_ipv4_address), MP_ROM_PTR(&wifi_radio_set_ipv4_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_ipv4_address_ap), MP_ROM_PTR(&wifi_radio_set_ipv4_address_ap_obj) },
{ MP_ROM_QSTR(MP_QSTR_addresses), MP_ROM_PTR(&wifi_radio_addresses_obj) },
{ MP_ROM_QSTR(MP_QSTR_addresses_ap), MP_ROM_PTR(&wifi_radio_addresses_ap_obj) },
{ MP_ROM_QSTR(MP_QSTR_dns), MP_ROM_PTR(&wifi_radio_dns_obj) },
{ MP_ROM_QSTR(MP_QSTR_ping), MP_ROM_PTR(&wifi_radio_ping_obj) },
};

View file

@ -105,7 +105,11 @@ uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self);
extern mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self);
extern mp_obj_t common_hal_wifi_radio_get_ipv4_address_ap(wifi_radio_obj_t *self);
mp_obj_t common_hal_wifi_radio_get_ipv6_addresses(wifi_radio_obj_t *self);
mp_obj_t common_hal_wifi_radio_get_addresses(wifi_radio_obj_t *self);
mp_obj_t common_hal_wifi_radio_get_addresses_ap(wifi_radio_obj_t *self);
extern mp_obj_t common_hal_wifi_radio_get_dns(wifi_radio_obj_t *self);
extern void common_hal_wifi_radio_set_dns(wifi_radio_obj_t *self, mp_obj_t dns_addr);
extern void common_hal_wifi_radio_set_ipv4_address(wifi_radio_obj_t *self, mp_obj_t ipv4, mp_obj_t netmask, mp_obj_t gateway, mp_obj_t ipv4_dns_addr);
extern void common_hal_wifi_radio_set_ipv4_address_ap(wifi_radio_obj_t *self, mp_obj_t ipv4, mp_obj_t netmask, mp_obj_t gateway);