8000 Add Monitor Mode by microdev1 · Pull Request #5537 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

Add Monitor Mode #5537

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 8 commits into from
Nov 11, 2021
Merged

Add Monitor Mode #5537

merged 8 commits into from
Nov 11, 2021

Conversation

microdev1
Copy link
Collaborator

Implement an API to monitor WiFi packets.

import wifi
monitor = wifi.Monitor(channel=1, queue=128)
while True:
    packet = monitor.packet()
    if packet != {}:
        print(packet)

Thanks @anecdata for collaborating on this.

microdev1 and others added 3 commits October 22, 2021 20:19
Co-authored-by: anecdata <16617689+anecdata@users.noreply.github.com>
@microdev1 microdev1 added enhancement network espressif applies to multiple Espressif chips labels Nov 2, 2021
@microdev1 microdev1 linked an issue Nov 2, 2021 that may be closed by this pull request
Copy link
Member
@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Overall this looks really good. My only question is whether it should go in a new module so that we can enable/disable the functionality separate from wifi connectivity. That'll make it easier to shrink small builds. It could be a wifimonitor module of its own.

@microdev1
Copy link
Collaborator Author

... whether it should go in a new module ...

This can be considered in future... we have plenty of space to play with on espressif boards for now.

@anecdata
Copy link
Member
anecdata commented Nov 3, 2021

Monitor depends on part of the wifi init. If we want to separate the modules at some point, that could presumably be coordinated, or duplicated with error checks, or split into a separate shared module.

Just a note that Espressif says you can do Station or AP while Monitor is running, I haven't had good experiences with that. First because Monitor processes so many packets, and also if there is an AP or connected Station also running, then Monitor is limited to just that channel.

So currently Monitor is controlled independently of Station/AP. Other than throughput and channel issues, Monitor can be instantiated and deinited without affecting, or being affected by, changes to Station or AP such as wifi.radio.enabled = False that turn wifi off (or on) for Station or AP.

@tannewt
Copy link
Member
tannewt commented Nov 3, 2021

... whether it should go in a new module ...

This can be considered in future... we have plenty of space to play with on espressif boards for now.

Splitting it now is much easier than doing it later. Aren't we running out of space on some boards due to the OTA partition?

@microdev1
Copy link
Collaborator Author

Aren't we running out of space on some boards due to the OTA partition?

I checked the 4MB boards and all of them have upwards of 130000 bytes free.

microdev1 and others added 2 commits November 4, 2021 09:12
Co-authored-by: anecdata <16617689+anecdata@users.noreply.github.com>
- rename loss method to lost
- add method to get queued packet count

Co-authored-by: anecdata <16617689+anecdata@users.noreply.github.com>
@anecdata
Copy link
Member
anecdata commented Nov 4, 2021

queued and lost working great! I am getting hardfault sometimes when autoreloading or going in and out of REPL a bunch of times. Is there anything more to be done to deinit in those cases?

I notice that espidf.heap_caps_get_largest_free_block() value seems to persist across reloads.

When it's running, it's stable and keeps on running.

@microdev1
Copy link
Collaborator Author

I get a crash with just import wifi in code.py, after code execution stops entering and exiting the repl results in a crash.
No idea how to debug this as it doesn't happen in a debug build.

@dhalbert
Copy link
Collaborator
dhalbert commented Nov 5, 2021

I get a crash with just import wifi in code.py, after code execution stops entering and exiting the repl results in a crash. No idea how to debug this as it doesn't happen in a debug build.

I added a lot of ESP_LOGI() statements once to track down exactly what was going wrong when I was debugging the I2C/wifi hangs. Can you do that without invoking the rest of the debug build?

@anecdata
8000 Copy link
Member
anecdata commented Nov 10, 2021

In code, the Singleton behaves without issue through multiple consecutive constructions, and through many cycles of construct and deinit. Normal operation is going well... one unit has been running for almost 6 days and has captured and parsed about 8 million packets.

I've been trying to print-debug this, but I'm at a loss. It doesn't seem to happen with Control-C then Control-D, but does happen with Control-C then key to enter the REPL then Control-D. Something seems to get clobbered along the path from wifi_reset() to its call to common_hal_wifi_monitor_deinit() to its call to common_hal_wifi_monitor_deinited(). Actual hardfault point varies.

I don't fully understand this mechanism: MP_STATE_VM(wifi_monitor_singleton) ...what does it return if there's a fresh VM?

I don't know if this is related, but detecting deinited is challenging since deinit is a multi-step process... if something goes wrong at one of the steps, checking only one of the steps may not give an accurate result. On the other hand, if deinit is defined as completion of all of the steps, then if it doesn't complete then the constructor may have problems or there may be memory issues. But it may not matter in practice if most of the steps are robust.

@microdev1
Copy link
Collaborator Author
microdev1 commented Nov 10, 2021

Found the bug! Well actually two bugs:

  • In wifi/__init__.c, the wifi_inited variable wasn't being reset after wifi_reset routine finished.
  • Above leads to esp_wifi_get_promiscuous throwing ESP_ERR_WIFI_NOT_INIT error, this results in common_hal_wifi_monitor_deinited retuning wrong state and crash happens down the line in queue's deinit routine.

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.

Tested and found no hardfault scenarios.

Also regression-tested going in and out of Station, AP, and Monitor modes repeatedly, no issues found.

Nice work, @microdev1

Copy link
Member
@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Great job fixing the crash! Thanks for continuing to work on this.

@tannewt tannewt merged commit c117766 into adafruit:main Nov 11, 2021
@matthewjerome
Copy link

this is great! thank you for working on this

@ladyada
Copy link
Member
ladyada commented Nov 11, 2021

hihi, i tried this - its nifty and seems to work on the tft feather proto ive got
does it have a plugin with wireshark or something? e.g. what should i use to decode the datadumps?

@anecdata
Copy link
Member

It doesn't output pcap files or anything like that right now. It's raw 802.11 packets, easy to parse (the headers at least) in CircuitPython. I can post some code or a gist.

@ladyada
Copy link
Member
ladyada commented Nov 11, 2021

oh yeah please, that would be cool.

@anecdata
Copy link
Member

Management packets are 24 bytes header, plus 0-12 bytes of fixed length body depending on management subtype, then comes variable body "Information Elements".

OK, not pretty, but a rough parse and dump that I used for testing is here:
https://gist.github.com/anecdata/27aca4a8c8d87a4b3f43d3ee21f90818

@microdev1 microdev1 deleted the monitor-mode branch November 16, 2021 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement espressif applies to multiple Espressif chips network
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ESP32S2: implement API for Promiscuous mode
6 participants
0