8000 New methods to get list of associated stations in access point mode and get maximum number of stations that can be associated by romkey · Pull Request #8820 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

New methods to get list of associated stations in access point mode and get maximum number of stations that can be associated #8820

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 22, 2024

Conversation

romkey
Copy link
@romkey romkey commented Jan 22, 2024

Addressing issue 8790. I did this for fun and to learn more about CP internals, hope I'm not stepping on anyone's toes and am fine ignoring this if you'd prefer.

Added a new property max_stations_ap to the Radio object, which returns the maximum number of stations the device supports in AP mode

Added a new property stations_ap to the Radio object, which returns a list of dicts that report the MAC address, RSSI and IPv4 address for each associated station. IPv4 may be reported as 0.0.0.0 if no address has been assigned yet (the device may be associated but not have issued a DHCP request yet, may have a static IP address pre-configured, or may not even speak TCP/IP).

This should work on all Espressif CPUs with WiFi (so not the H2), and the Raspberry Pi Pico.

The Raspberry Pi Pico W doesn't return RSSI values, so those are set to None on the Pico W.

The Pico W's SDK doesn't give much of a documented API to talk to the DHCP server. The code I wrote to retrieve IPv4 addresses for stations uses internal data structures in the DHCP server that could easily change without warning in future updates to the Pico W's SDK. It could be best to just not report IPv4 addresses for associated stations.

stations_ap throws an exception if the device isn't in AP mode.

If you'd prefer different names or behavior I'd be happy to make those changes. I would tend to avoid calling associated stations "clients" as WiFi tends to use station/access point nomenclature rather than client/server. I tried to use names that were consistent with the technology and CircuitPython.

I'm not enough of a Pythonista to be clear on the best form to return results in... I thought that using a dict for the stations would help with future proofing in case more attributes may become available.

Would you rather have the IPv4 address be None if there's not one assigned yet? Would you rather not have an rssi property in the dict on the Pi Pico W?

I'm not at all confident I got the docstrings right.

I've tested on one of each type of CPU this can run on except the ESP32-C3; I have some but haven't been able to find them yet.

Raspberry Pi Pico W

Screenshot 2024-01-21 at 5 19 44 PM

ESP32

Image 1-21-24 at 9 00 PM

ESP32-S2

Image 1-21-24 at 8 44 PM

ESP32-S3

Image 1-21-24 at 8 37 PM

ESP32-C6

Image 1-21-24 at 9 13 PM

@dhalbert
Copy link
Collaborator

Thanks for working on this!

You could use a list of namedtuples instead of a dict, or even create a new native class with appropriate attributes.

If a value isn't available, like rssi or an unknown IP address, None is appropriate and canonical in Python.

Using the internal data structures is probably not bad if that's the only way. It may just stop working later. A PR to the appropriate upstream repo to add an API for that info might make sense. You could see if there's already an open issue or PR for that.

@tannewt tannewt requested a review from dhalbert January 22, 2024 23:58
@romkey romkey marked this pull request as draft January 23, 2024 19:52
@romkey
Copy link
Author
romkey commented Jan 23, 2024

I'd thought about using a class like the Monitor class but it felt heavy for such a simple call. I'm happy to rewrite it to do that if you'd prefer, though.

I'll change the code to return None for the IP address DHCP lease for the station.

If I'm understanding correctly, namedtuples would be immutable, unlike the dict? Maybe that would be preferable.

I'll take a closer look at the Pi Pico SDK re: the DHCP server. I'm much more familiar with Espressif's.

I'm not at all understanding what's going on with the pre-commit fail during CI.

Thanks @dhalbert!

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
@romkey romkey force-pushed the 8790-ap-connected-devices branch from 44daca7 to d0215aa Compare January 23, 2024 20:55
@romkey
Copy link
Author
romkey commented Jan 23, 2024

Figured out the CI issue :)

@romkey
Copy link
Author
romkey commented Jan 31, 2024

@dhalbert how does this sound?

wifi.Radio.stations_ap returns a list of associated wifi.Station objects or throws an exception if not in AP mode (read-only)
wifi.Radio.max_stations_ap returns the maximum number of stations that can be associated in AP mode (read-only)

wifi.Station can't be created by users, has these properties:

  • mac_address - byte array MAC address of the associated station (read-only)
  • rssi - current RSSI of associated station (read-only, None on Pico W)
  • ipv4_address - IPV4Address of associated station (read-only, may be None if station hasn't yet requested or been assigned an IP address)

@tannewt
Copy link
Member
tannewt commented Jan 31, 2024

@dhalbert how does this sound?

wifi.Radio.stations_ap returns a list of associated wifi.Station objects or throws an exception if not in AP mode (read-only) wifi.Radio.max_stations_ap returns the maximum number of stations that can be associated in AP mode (read-only)

wifi.Station can't be created by users, has these properties:

* mac_address - byte array MAC address of the associated station (read-only)

* rssi - current RSSI of associated station (read-only, None on Pico W)

* ipv4_address - IPV4Address of associated station (read-only, may be None if station hasn't yet requested or been assigned an IP address)

This sounds good to me. You can make wifi.Station a named tuple. Here is an example from bitmapfilter: https://github.com/adafruit/circuitpython/blob/main/shared-bindings/bitmapfilter/__init__.c#L170-L196

@dhalbert
Copy link
Collaborator

If you make it a namedtuple then you don't have to create a class.

I would say don't bother to raise an exception if you aren't in AP mode. There are other operations that just return None, etc. if you are in the wrong mode. In this case, just return an empty list.

@romkey
Copy link
Author
romkey commented Jan 31, 2024

Even easier! I'll make it a named tuple (thanks for the example :)) and not raise the exception. Thanks!

…in AP mode

return value is now a list of named tuples with three elements

IP address is now None instead of 0.0.0.0 if there's no lease information
@romkey
Copy link
Author
romkey commented Feb 19, 2024

Sorry for taking so long with this, been busy with other stuff.

  • stations_ap now returns None if not in AP mode
  • stations_ap now returns a list of NamedTuples with mac_address, rssi and ipv4_address elements
  • ipv4_address will now be None rather than 0.0.0.0 if none has been assigned

This is solid with Espressif but I see erratic results from the Pi Pico's cyw43 SDK. You can see them in the screen cap - it sometimes reports 1 station connected despite 2 or 3 (confirmed they really were connected by pinging them). Eventually it reported all 3.

I'm going to investigate more and will file an issue on it if I can confirm this behavior. I saw a bit of this before but it seems more pronounced with the newer version of the SDK.

I understand what this line of code does but I'm not 100% confident it's needed or appropriate for the named tuple's type.

Raspberry Pi Pico W

Screenshot 2024-02-19 at 7 56 33 AM

I expected that each time I printed stations_ap I would see one more station but the SDK kept reporting that the number of stations connected was 1, until the last time when it correctly reported 3.

ESP32

Screenshot 2024-02-19 at 9 48 54 AM

This test also shows a station which had not yet been assigned a DHCP lease and is reporting None as its IP address.

ESP32-S2

Screenshot 2024-02-19 at 9 31 38 AM

ESP32-S3

Screenshot 2024-02-19 at 8 04 52 AM

ESP32-C3

Screenshot 2024-02-19 at 8 13 28 AM

ESP32-C6

Screenshot 2024-02-19 at 9 38 01 AM

@romkey romkey marked this pull request as ready for review February 19, 2024 17:58
Copy link
Member
@anecdata anecdata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the updated code on S3 and PicoW. LGTM! I'll leave code review to core devs.

Copy link
Collaborator
@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! - One suggestion.

romkey and others added 2 commits February 21, 2024 21:42
Co-authored-by: Dan Halbert <halbert@halwitz.org>
… will return an error if we're not in AP mode, which is sufficient
@romkey
Copy link
Author
romkey commented Feb 22, 2024

Made one other small change and removed a superfluous check if we're in AP mode. The ESP-IDF functions will return an error if we're not, which will lead to the correct behavior. Tested to confirm.

8000 Copy link
Collaborator
@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

@dhalbert dhalbert merged commit c219d89 into adafruit:main Feb 22, 2024
@romkey romkey deleted the 8790-ap-connected-devices branch February 22, 2024 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0