micropython / micropython-esp32

Old port of MicroPython to the ESP32 -- new port is at https://github.com/micropython/micropython
MIT License
673 stars 216 forks source link

How to list devices connected in AP_IF mode? #186

Closed pedrofelipest closed 5 years ago

pedrofelipest commented 6 years ago

How to list the devices that are connected to the device.

import network
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid='mode_ap')
MrSurly commented 6 years ago

Presently with MicroPython, you cannot. The closest thing is ap.isconnected(). Right now ap.status() is hard-coded to return None. Since status() is defined as being dependent on the medium, this might be a good place to hook that in.

MrSurly commented 6 years ago

@dpgeorge or @nickzoic Does it sound reasonable that WLAN.status() should return a tuple of connected clients for AP?

nickzoic commented 6 years ago

As you point out, the status() return value is explicitly not defined, and this isn't really .config()-like information, to my mind, because you can't sensibly set it.

Returning a list of connected clients would seem reasonable, if not very self-documenting. Perhaps it should return something with some structure like:

{ "connected_clients": [ { "mac": "12345678", ... }, { "mac": "23490595", ... } ] }

That way it's a bit more explicit what it's returning, and if there's some other information which doesn't fit the .config() or .isconnected() calls can be usefully returned for a given interface class it can fit into the same general schema.

An alternative would be .scan() which on a Station returns a list of APs, so it kind of seems fitting that on an AP it would return a list of stations.

Are there AP implementations in any of the other ports?

(For example, #172 Wired Ethernet Support may wish to return the PHY interface speed or whatever)

MrSurly commented 6 years ago

On a related note, what's the proper format to return a MAC? For BLE, I used a bytes object of length 6.

nickzoic commented 6 years ago

Eric Poulsen wrote:

On a related note, what's the proper format to return a MAC? For BLE, I used a bytes object of length 6. That's the most sensible to my way of thinking too (my example above is inaccurate). If you need to expand that out for human consumption it's easy to do.

SSIDs are also a bytearray (not a unicode string or a C string, despite appearances and common usage they aren't necessarily UTF-8 and can contain NULs.)

nickzoic commented 6 years ago

@MrSurly were you planning on writing something for this or shall I?

MrSurly commented 6 years ago

@nickzoic

If you have the time/desire, then by all means.

It's on my list, but I'm swamped. My recent PRs are more of a side effect of my current end goal; I have very little discretionary bandwidth ATM. "Pay the bills" and all that.

nickzoic commented 6 years ago

Yeah, me too, I'll put it on my "low hanging fruit" list.

dpgeorge commented 6 years ago

Does it sound reasonable that WLAN.status() should return a tuple of connected clients for AP?

Well, the current docs are pretty vague on what status() returns: "detailed status of the interface" (what it currently says) could indeed cover returning a list of connected clients.

But there's also config() which does mention "Extended status information", so something like ap.config('clients') would also fit within the spec of the AbstractNIC.

nickzoic commented 6 years ago

See https://github.com/micropython/micropython/pull/3351 for more information

nickzoic commented 6 years ago

Incidentally, getting RSSI for the connected AP is easy (esp_wifi_sta_get_ap_info) but getting RSSI for connected stations much less so ... esp_wifi_ap_get_sta_list doesn't return rssi.

There's an asynchronous process esp_wifi_set_vendor_ie_cb which lets you know an RSSI whenever a probe is received. But this is for all visible MACs not just connected stations so matching the data up with the connected stations list is annoying.Every time we get a vendor ie callback we'd have to get the connected stations list, see if the mac is on it, if so update it, etc, etc. It's doable but a pain.

I think if we really need station RSSI we'd be better off asking the vendor to add rssi to wifi_sta_info_t. Sadly this part is in the libnet80211.a blob so I can't just submit an upstream PR ...

nickzoic commented 6 years ago

(This extra information should be available in IDF 3.1 ... see referenced issue above for progress)

nickzoic commented 6 years ago

(okay, looks like that's on its way, so we should be able to add RSSI soon. Thanks Espressif!)

dpgeorge commented 5 years ago

sta.status('stations') will now return a list of MACs of connected stations. See also the issue linked above at upstream.

WaGi-Coding commented 1 year ago

Is it possible to only get stations connected which got authed properly? .status('stations') unfortunately lists also devices which are trying to connect with wrong password

dpgeorge commented 1 year ago

Is it possible to only get stations connected which got authed properly?

I don't think so. It's up to the IDF to provide such functionality. The info it provides is:

typedef struct {
    uint8_t mac[6];  /**< mac address */
    int8_t  rssi;    /**< current average rssi of sta connected */
    uint32_t phy_11b:1;      /**< bit: 0 flag to identify if 11b mode is enabled or not */
    uint32_t phy_11g:1;      /**< bit: 1 flag to identify if 11g mode is enabled or not */
    uint32_t phy_11n:1;      /**< bit: 2 flag to identify if 11n mode is enabled or not */
    uint32_t phy_lr:1;       /**< bit: 3 flag to identify if low rate is enabled or not */
    uint32_t is_mesh_child:1;/**< bit: 4 flag to identify mesh child */
    uint32_t reserved:27;    /**< bit: 5..31 reserved */
} wifi_sta_info_t;
WaGi-Coding commented 1 year ago

Ahh too sad, would have been very handy. Would have used the pico w's WiFi to unlock an e scooter by just connecting to it's AP (then automatically turn off the AP so i am not without internet on the phone). But this way i think the only thing i could do is putting my phones mac address onto a whitelist and check for that instead.

Many thanks for your replies tho