Skip to content

Commit

Permalink
esp8266/network_wlan: Allow enumerating connected stations in AP mode.
Browse files Browse the repository at this point in the history
This commit introduces the ability to obtain a list of stations
connected to the device when in soft-AP mode.

A new parameter ("stations") to pass to WLAN.status is supported,
returning a tuple of (bssid, ipv4) entries, one per connected station.
An empty tuple is returned if no stations are connected, and an
exception is raised if an error occurred whilst building the python
objects to return to the interpreter.

Documentation is also updated to cover the new parameter.

This fixes micropython#5395.

Signed-off-by: Alessandro Gatti <[email protected]>
  • Loading branch information
agatti authored and dpgeorge committed Mar 5, 2025
1 parent 6fba1e4 commit 4d034f8
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
13 changes: 12 additions & 1 deletion docs/library/network.WLAN.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,18 @@ Methods
* ``STAT_GOT_IP`` -- connection successful.

When called with one argument *param* should be a string naming the status
parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``.
parameter to retrieve, and different parameters are supported depending on the
mode the WiFi is in.

In STA mode, passing ``'rssi'`` returns a signal strength indicator value, whose
format varies depending on the port (this is available on all ports that support
WiFi network interfaces, except for CC3200).

In AP mode, passing ``'stations'`` returns a list of connected WiFi stations
(this is available on all ports that support WiFi network interfaces, except for
CC3200). The format of the station information entries varies across ports,
providing either the raw BSSID of the connected station, the IP address of the
connected station, or both.

.. method:: WLAN.isconnected()

Expand Down
29 changes: 29 additions & 0 deletions ports/esp8266/network_wlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,29 @@ static mp_obj_t esp_disconnect(mp_obj_t self_in) {
}
static MP_DEFINE_CONST_FUN_OBJ_1(esp_disconnect_obj, esp_disconnect);

static void build_stations_list_cleanup_callback(void *station_info) {
if (station_info != NULL) {
wifi_softap_free_station_info();
}
}

static mp_obj_t build_stations_list(void) {
struct station_info *info = wifi_softap_get_station_info();
MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, build_stations_list_cleanup_callback, (void *)info);
nlr_push_jump_callback(&ctx.callback, mp_call_function_1_from_nlr_jump_callback);
mp_obj_list_t *stations = MP_OBJ_TO_PTR(mp_obj_new_list(0, NULL));
struct station_info *current = info;
mp_obj_t entry[2] = { 0 };
while (current != NULL) {
entry[0] = mp_obj_new_bytes(current->bssid, sizeof(current->bssid));
entry[1] = netutils_format_ipv4_addr((uint8_t *)&current->ip.addr, NETUTILS_BIG);
mp_obj_list_append(stations, mp_obj_new_tuple(2, entry));
current = STAILQ_NEXT(current, next);
}
nlr_pop_jump_callback(true);
return MP_OBJ_FROM_PTR(stations);
}

static mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
if (n_args == 1) {
Expand All @@ -185,6 +208,12 @@ static mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
if (self->if_id == STATION_IF) {
return MP_OBJ_NEW_SMALL_INT(wifi_station_get_rssi());
}
break;
case MP_QSTR_stations:
if (self->if_id == SOFTAP_IF) {
return build_stations_list();
}
break;
}
mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
}
Expand Down

0 comments on commit 4d034f8

Please sign in to comment.