8000 Added GETTER method max_stations to wifi Radio objects, returning the · adafruit/circuitpython@d0215aa · GitHub
[go: up one dir, main page]

Skip to content

Commit d0215aa

Browse files
committed
Added GETTER method max_stations to wifi Radio objects, returning the
maximum number of stations that can be associated in AP mode Added GETTER method stations_ap to wifi Radio objects, returning a list of dicts with the MAC address, RSSI and IPV4 address of each associated station. IPV4 addresses may be None if the DHCP server hasn't yet assigned an address or if the station hasn't requested one (for instance if it has a self-assigned or static IP address, or isn't running TCP/IP). Supports Espressif CPUS and the Raspberry Pi Pico W The Pico W doesn't report RSSI values
1 parent a28f853 commit d0215aa

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed

ports/espressif/common-hal/wifi/Radio.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,47 @@ void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) {
250250
set_mode_ap(self, false);
251251
}
252252

253+
mp_obj_t common_hal_wifi_radio_get_stations_ap(wifi_radio_obj_t *self) {
254+
wifi_sta_list_t esp_sta_list;
255+
esp_netif_pair_mac_ip_t mac_ip_pair[ESP_WIFI_MAX_CONN_NUM];
256+
esp_err_t result;
257+
258+
result = esp_wifi_ap_get_sta_list(&esp_sta_list);
259+
if (result == ESP_OK) {
260+
for (int i = 0; i < esp_sta_list.num; i++) {
261+
memcpy(mac_ip_pair[i].mac, esp_sta_list.sta[i].mac, MAC_ADDRESS_LENGTH);
262+
mac_ip_pair[i].ip.addr = 0;
263+
}
264+
265+
result = esp_netif_dhcps_get_clients_by_mac(self->ap_netif, esp_sta_list.num, mac_ip_pair);
266+
}
267+
268+
if (!self->ap_mode || result != ESP_OK) {
269+
mp_raise_RuntimeError(MP_ERROR_TEXT("Interface must be in access point mode"));
270+
}
271+
272+
mp_obj_t mp_sta_list = mp_obj_new_list(0, NULL);
273+
for (int i = 0; i < esp_sta_list.num; i++) {
274+
mp_obj_dict_t *dict = MP_OBJ_TO_PTR(mp_obj_new_dict(3));
275+
276+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_mac), mp_obj_new_bytes(esp_sta_list.sta[i].mac, MAC_ADDRESS_LENGTH));
277+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_rssi), MP_OBJ_NEW_SMALL_INT(esp_sta_list.sta[i].rssi));
278+
if (mac_ip_pair[i].ip.addr) {
279+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_ipv4_address), common_hal_ipaddress_new_ipv4address(mac_ip_pair[i].ip.addr));
280+
} else {
281+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_ipv4_address), mp_const_none);
282+
}
283+
284+
mp_obj_list_append(mp_sta_list, dict);
285+
}
286+
287+
return mp_sta_list;
288+
}
289+
290+
mp_obj_t common_hal_wifi_radio_get_max_stations_ap(wifi_radio_obj_t *self) {
291+
return MP_OBJ_NEW_SMALL_INT(ESP_WIFI_MAX_CONN_NUM);
292+
}
293+
253294
wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t *bssid, size_t bssid_len) {
254295
if (!common_hal_wifi_radio_get_enabled(self)) {
255296
mp_raise_RuntimeError(MP_ERROR_TEXT("wifi is not enabled"));

ports/raspberrypi/common-hal/wifi/Radio.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,60 @@ void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) {
244244
bindings_cyw43_wifi_enforce_pm();
245245
}
246246

247+
// There's no published API for the DHCP server to retrieve lease information
248+
// This code depends on undocumented internal structures and is likely to break in the future
249+
static uint32_t cyw43_dhcps_get_ip_addr(dhcp_server_t *dhcp_server, uint8_t *mac_address) {
250+
for (int i = 0; i < DHCPS_MAX_IP; i++) {
251+
if (memcmp(dhcp_server->lease[i].mac, mac_address, MAC_ADDRESS_LENGTH) == 0) {
252+
return (dhcp_server->ip.addr & 0x00FFFFFF) + ((DHCPS_BASE_IP + i) << 24);
253+
}
254+
}
255+
256+
return 0;
257+
}
258+
259+
mp_obj_t common_hal_wifi_radio_get_stations_ap(wifi_radio_obj_t *self) {
260+
int max_stas;
261+
int num_stas;
262+
263+
if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) != CYW43_LINK_UP) {
264+
mp_raise_RuntimeError(MP_ERROR_TEXT("Interface must be in access point mode"));
265+
}
266+
267+
cyw43_wifi_ap_get_max_stas(&cyw43_state, &max_stas);
268+
269+
uint8_t macs[max_stas * MAC_ADDRESS_LENGTH];
270+
271+
cyw43_wifi_ap_get_stas(&cyw43_state, &num_stas, macs);
272+
273+
mp_obj_t mp_sta_list = mp_obj_new_list(0, NULL);
274+
for (int i = 0; i < num_stas; i++) {
275+
mp_obj_dict_t *dict = MP_OBJ_TO_PTR(mp_obj_new_dict(3));
276+
277+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_mac), mp_obj_new_bytes(&macs[i * MAC_ADDRESS_LENGTH], MAC_ADDRESS_LENGTH));
278+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_rssi), mp_const_none);
279+
280+
uint32_t ipv4_addr = cyw43_dhcps_get_ip_addr(&cyw43_state.dhcp_server, &macs[i * MAC_ADDRESS_LENGTH]);
281+
if (ipv4_addr) {
282+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_ipv4_address), common_hal_ipaddress_new_ipv4address(ipv4_addr));
283+
} else {
284+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_ipv4_address), mp_const_none);
285+
}
286+
287+
mp_obj_list_append(mp_sta_list, dict);
288+
}
289+
290+
return mp_sta_list;
291+
}
292+
293+
mp_obj_t common_hal_wifi_radio_get_max_stations_ap(wifi_radio_obj_t *self) {
294+
int max_stas;
295+
296+
cyw43_wifi_ap_get_max_stas(&cyw43_state, &max_stas);
297+
298+
return MP_OBJ_NEW_SMALL_INT(max_stas);
299+
}
300+
247301
static bool connection_unchanged(wifi_radio_obj_t *self, const uint8_t *ssid, size_t ssid_len) {
248302
if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) {
249303
return false;

shared-bindings/wifi/Radio.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,34 @@ STATIC mp_obj_t wifi_radio_get_ap_info(mp_obj_t self) {
661661
}
662662
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ap_info_obj, wifi_radio_get_ap_info);
663663

664+
//| stations_ap: None
665+
//| """In AP mode, returns list of objects (read-only)
666+
//| mac: bytearray
667+
//| rssi: int
668+
//| ipv4_address: ipv4_address (0.0.0.0 if station connected but no address assigned yet or self-assigned address)
669+
//|
670+
//| .. note::
671+
//|
672+
//| The raspberrypi port (RP2040 CYW43) does not report rssi, so the value will be None"""
673+
STATIC mp_obj_t wifi_radio_get_stations_ap(mp_obj_t self) {
674+
return common_hal_wifi_radio_get_stations_ap(self);
675+
}
676+
677+
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_stations_ap_obj, wifi_radio_get_stations_ap);
678+
679+
MP_PROPERTY_GETTER(wifi_radio_stations_ap_obj,
680+
(mp_obj_t)&wifi_radio_get_stations_ap_obj);
681+
682+
//| max_stations_ap: Optional[Network]
683+
//| """In AP mode, returns the maximum possible number of connected stations (read-only)"""
684+
STATIC mp_obj_t wifi_radio_get_max_stations_ap(mp_obj_t self) {
685+
return common_hal_wifi_radio_get_max_stations_ap(self);
686+
}
687+
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_max_stations_ap_obj, wifi_radio_get_max_stations_ap);
688+
689+
MP_PROPERTY_GETTER(wifi_radio_max_stations_ap_obj,
690+
(mp_obj_t)&wifi_radio_get_max_stations_ap_obj);
691+
664692
//| def start_dhcp(self) -> None:
665693
//| """Starts the station DHCP client."""
666694
//| ...
@@ -750,6 +778,8 @@ STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = {
750778
{ MP_ROM_QSTR(MP_QSTR_start_ap), MP_ROM_PTR(&wifi_radio_start_ap_obj) },
751779
{ MP_ROM_QSTR(MP_QSTR_stop_ap), MP_ROM_PTR(&wifi_radio_stop_ap_obj) },
752780
{ MP_ROM_QSTR(MP_QSTR_ap_active), MP_ROM_PTR(&wifi_radio_ap_active_obj) },
781+
{ MP_ROM_QSTR(MP_QSTR_stations_ap), MP_ROM_PTR(&wifi_radio_stations_ap_obj) },
782+
{ MP_ROM_QSTR(MP_QSTR_max_stations_ap), MP_ROM_PTR(&wifi_radio_max_stations_ap_obj) },
753783

754784
{ MP_ROM_QSTR(MP_QSTR_start_dhcp), MP_ROM_PTR(&wifi_radio_start_dhcp_client_obj) },
755785
{ MP_ROM_QSTR(MP_QSTR_stop_dhcp), MP_ROM_PTR(&wifi_radio_stop_dhcp_client_obj) },

shared-bindings/wifi/Radio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ extern void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self);
9696
extern void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint32_t authmode, uint8_t max_connections);
9797
extern void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self);
9898
extern bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self);
99+
extern mp_obj_t common_hal_wifi_radio_get_stations_ap(wifi_radio_obj_t *self);
100+
extern mp_obj_t common_hal_wifi_radio_get_max_stations_ap(wifi_radio_obj_t *self);
99101

100102
extern void common_hal_wifi_radio_start_dhcp_client(wifi_radio_obj_t *self);
101103
extern void common_hal_wifi_radio_stop_dhcp_client(wifi_radio_obj_t *self);

0 commit comments

Comments
 (0)
0