Skip to content

Commit 4d034f8

Browse files
agattidpgeorge
authored andcommitted
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 micropython#5395. Signed-off-by: Alessandro Gatti <[email protected]>
1 parent 6fba1e4 commit 4d034f8

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

docs/library/network.WLAN.rst

+12-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,18 @@ Methods
8585
* ``STAT_GOT_IP`` -- connection successful.
8686

8787
When called with one argument *param* should be a string naming the status
88-
parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``.
88+
parameter to retrieve, and different parameters are supported depending on the
89+
mode the WiFi is in.
90+
91+
In STA mode, passing ``'rssi'`` returns a signal strength indicator value, whose
92+
format varies depending on the port (this is available on all ports that support
93+
WiFi network interfaces, except for CC3200).
94+
95+
In AP mode, passing ``'stations'`` returns a list of connected WiFi stations
96+
(this is available on all ports that support WiFi network interfaces, except for
97+
CC3200). The format of the station information entries varies across ports,
98+
providing either the raw BSSID of the connected station, the IP address of the
99+
connected station, or both.
89100

90101
.. method:: WLAN.isconnected()
91102

ports/esp8266/network_wlan.c

+29
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,29 @@ static mp_obj_t esp_disconnect(mp_obj_t self_in) {
170170
}
171171
static MP_DEFINE_CONST_FUN_OBJ_1(esp_disconnect_obj, esp_disconnect);
172172

173+
static void build_stations_list_cleanup_callback(void *station_info) {
174+
if (station_info != NULL) {
175+
wifi_softap_free_station_info();
176+
}
177+
}
178+
179+
static mp_obj_t build_stations_list(void) {
180+
struct station_info *info = wifi_softap_get_station_info();
181+
MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, build_stations_list_cleanup_callback, (void *)info);
182+
nlr_push_jump_callback(&ctx.callback, mp_call_function_1_from_nlr_jump_callback);
183+
mp_obj_list_t *stations = MP_OBJ_TO_PTR(mp_obj_new_list(0, NULL));
184+
struct station_info *current = info;
185+
mp_obj_t entry[2] = { 0 };
186+
while (current != NULL) {
187+
entry[0] = mp_obj_new_bytes(current->bssid, sizeof(current->bssid));
188+
entry[1] = netutils_format_ipv4_addr((uint8_t *)&current->ip.addr, NETUTILS_BIG);
189+
mp_obj_list_append(stations, mp_obj_new_tuple(2, entry));
190+
current = STAILQ_NEXT(current, next);
191+
}
192+
nlr_pop_jump_callback(true);
193+
return MP_OBJ_FROM_PTR(stations);
194+
}
195+
173196
static mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
174197
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
175198
if (n_args == 1) {
@@ -185,6 +208,12 @@ static mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
185208
if (self->if_id == STATION_IF) {
186209
return MP_OBJ_NEW_SMALL_INT(wifi_station_get_rssi());
187210
}
211+
break;
212+
case MP_QSTR_stations:
213+
if (self->if_id == SOFTAP_IF) {
214+
return build_stations_list();
215+
}
216+
break;
188217
}
189218
mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
190219
}

0 commit comments

Comments
 (0)