summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2025-02-15 00:58:01 +0100
committerDamien George <damien@micropython.org>2025-03-05 16:15:31 +1100
commit4d034f817c861b90cbe7ab0cb59d85036031750f (patch)
treef8c8162a91376b12a66cb44245ca56de3f18c339
parent6fba1e406bde7ddf00f7cf52bd8c44764c8a1a97 (diff)
esp8266/network_wlan: Allow enumerating connected stations in AP mode.
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 #5395. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
-rw-r--r--docs/library/network.WLAN.rst13
-rw-r--r--ports/esp8266/network_wlan.c29
2 files changed, 41 insertions, 1 deletions
diff --git a/docs/library/network.WLAN.rst b/docs/library/network.WLAN.rst
index 09fefc592..ee0ef490f 100644
--- a/docs/library/network.WLAN.rst
+++ b/docs/library/network.WLAN.rst
@@ -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()
diff --git a/ports/esp8266/network_wlan.c b/ports/esp8266/network_wlan.c
index 7131b88ba..9084f246f 100644
--- a/ports/esp8266/network_wlan.c
+++ b/ports/esp8266/network_wlan.c
@@ -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) {
@@ -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"));
}