Skip to content

Conversation

gschorcht
Copy link
Contributor

@gschorcht gschorcht commented Jan 13, 2019

Contribution description

Even though this netdev driver was already part of the initial PR for ESP32, it was in an experimental state and officially not supported.

This PR fixes a lot of problems and makes the driver operational. ESP32 can now be used with infrastructure mode WiFi. If the router of the LAN is IPv6 capable and provides a global routing prefix, EPS32 gets global connectivity.

The PR contains the following changes in detail:

  • Fix of a serious memory leak. The buffer given by the WiFi driver has to be freed explicitly. Otherwise the esp_wifi_netdev stops working after some seconds.
  • Fix of frame size handling. Although the MTU is 1500, it used uint8_t for transmitted and received frames before.
  • Automatic reconnect after disconnect. If WiFi is disconnected, e.g., because of timeout for beacon frame, it is tried to reconnect automatically.
  • Static WiFi configuration. The WiFi configuration has to be static to avoid memory access problems when WiFi AP is reconnected.
  • Registration of RX callback. RX callback function should be registered when WiFi has been connected to AP successfully and should be unregistered when WiFi disconnects from AP.
  • Call of wifi_connect in event handler. Before function wifi_connect is executed, starting the WiFi driver should have been finished. This is indicated by the WiFi driver by sending event SYSTEM_EVENT_STA_START. Function wifi_connect is moved therefore to the event handler for SYSTEM_EVENT_STA_START.
  • Fix of handling NETOPT_IS_WIRED. Although esp_wifi is a wireless interface, it returned true instead of false.
  • Fix of handling NETOPT_LINK_CONNECTED. esp_wifi was simply returning the connection state instead of filling the referenced value.
  • Fix of event types in event handler.
  • Improvement of some debug messages.

Testing procedure

  • Compile and flash example/gnrc_networking to at least one ESP32 node using your AP configuration, e.g.,
    CFLAGS='-DESP_WIFI_SSID=\"<your SSID>\" -DESP_WIFI_PASS=\"your passphrase\"' USEMODULE="esp_wifi" make BOARD=esp32-wroom-32 -C examples/gnrc_networking flash
    
  • Once the application is flashed connect the ESP32 node with any terminal programm with a default baudrate of 115.200 bps. You should be able to observe an output as follows:
     I (1885949) [      wifi]: mode : sta (30:ae:a4:41:60:f8)
     I (1885950) [     event]: system_event_sta_start_handle_default
     I (1885958) [main_trampoline]: main(): This is RIOT! (Version: 2018.10-RC1-947...)
     RIOT network stack example application
     All up, running the shell now
     >
     I (1888371) [      wifi]: n:8 0, o:1 0, ap:255 255, sta:8 0, prof:1
     I (1890036) [      wifi]: state: init -> auth (b0)
     I (1890045) [      wifi]: state: auth -> assoc (0)
     I (1890121) [      wifi]: state: assoc -> run (10)
     I (1890143) [      wifi]: connected with <your SSID>, channel 8
     I (1890144) [      wifi]: pm start, type: 1
     I (1890144) [     event]: system_event_sta_connected_handle_default
    
  • Ping any host in your LAN.
  • If your router provides a global routing prefix, check with ifconfig that the prefix is set.
  • Stress testing from LAN with sudo ping6 fe80::<IID> -Ieth0 -s1392 -i 0.0001 should be stable over hours.

Issues/PRs references

This PR depends on PR #10766

@gschorcht gschorcht added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: network Area: Networking Platform: ESP Platform: This PR/issue effects ESP-based platforms Area: cpu Area: CPU/MCU ports labels Jan 13, 2019
@gschorcht
Copy link
Contributor Author

gschorcht commented Jan 13, 2019

@TimoRoth Might be interesting for you 😉

@TimoRoth
Copy link
Contributor

Indeed. I wonder, would this work in parallel with ESP-NOW?

@gschorcht
Copy link
Contributor Author

@TimoRoth Theoretically yes, since ESP-NOW is using Vendor Action Frames which are management frames that can be transmitted/received in parallel to an association a station has to an AP.

However, the implementation does not support it at the moment. The reason is that each module has its own WiFi initialization. While esp_wifi initializes the WiFi interface in Station mode, esp-now has to operate in in SoftAP+Station mode. So, one prerequisite will be to find a common initialization. You will already find an according comment int esp_now_setup.

Trying esp_wif in parallel to esp_now is the next item on my todo list. At the moment, it is a bit difficult to work on different drivers and merge them together since the dependencies increase and PRs are pending long time.

If it is possible to use esp_wifi and esp_now in parallel, you would have two netifs so that one ESP node could act as a border router without having an Ethernet interface.

@gschorcht
Copy link
Contributor Author

@TimoRoth BTW, I have a working esp_wifi for ESP8266 under test here.

@gschorcht
Copy link
Contributor Author

@TimoRoth Good news, I had success with a modified version of your border router that is working with esp_wifi at outer interface and esp_now at inner interface. The only prerequisite is that ESP-NOW uses the same channel as the AP to which esp_wifi is associated. This can be configured by compile time parameter ESP_NOW_CHANNEL.

@TimoRoth
Copy link
Contributor

We kind of gave up on esp8266 after the majority of our devices turned into unflashable bricks within weeks of experimenting with them, but having more feature support for them is definitely nice.

Being able to use a single ESP32 board as border router would definitely be amazing. I'm wondering a bit what the advantage of ESP-NOW would be though, as there does not seem to be a massively reduced power draw over a normal WiFi connection.

I'll give this all a test run soon!

@gschorcht
Copy link
Contributor Author

@TimoRoth

I'm wondering a bit what the advantage of ESP-NOW would be though, as there does not seem to be a massively reduced power draw over a normal WiFi connection.

The advantage of using GNRC and RPL over ESP-NOW would be that you can span a mesh network without having access to the AP from all nodes.

@smlng smlng requested a review from MrKevinWeiss January 16, 2019 08:03
@smlng smlng self-assigned this Jan 16, 2019
Copy link
Member

@smlng smlng left a comment

Choose a reason for hiding this comment

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

code wise this looks pretty much okay and ready to go, however we really need some testing on this one: @MrKevinWeiss and @MichelRottleuthner can you give it quick try, our working group AP should distribute an IPv6 ULA prefix (fd.. something) so you can use that for testing.

@smlng smlng added the State: waiting for other PR State: The PR requires another PR to be merged first label Jan 16, 2019
@smlng
Copy link
Member

smlng commented Jan 16, 2019

merge #10766 before this one

@MrKevinWeiss
Copy link
Contributor

I can do some testing later in the week, pretty busy now...

@gschorcht
Copy link
Contributor Author

@smlng Thank you for your review. Let's hope that we get merged it in short term.

@MrKevinWeiss
Copy link
Contributor

@gschorcht are you trying to get this in the release?
@aabadie is this an issue?

@gschorcht
Copy link
Contributor Author

@MrKevinWeiss

are you trying to get this in the release?

I'm not sure, even though it was there it was not supported officially til now. But it would be an enhancement if ESP32 could communicate using an infrastructure mode WiFi.

@MrKevinWeiss
Copy link
Contributor

Either way I should be able to do some testing tomorrow morning and ask @jia200x to get the other PR in. I know lots of people are interested in this!

@MrKevinWeiss
Copy link
Contributor

I was able to flash but every second or two I get
INFO # I (184295) [ event]: system_event_sta_disconnected_handle_default

Here is a bit more info:

Starting RIOT kernel on PRO cpu
2019-01-16 18:44:59,068 - INFO # I (428) [      wifi]: wifi driver task: 7, prio:30, stack:3584, core=0
2019-01-16 18:44:59,069 - INFO # I (433) [      wifi]: wifi firmware version: b987c01
2019-01-16 18:44:59,081 - INFO # I (437) [      wifi]: config NVS flash: disabled
2019-01-16 18:44:59,082 - INFO # I (442) [      wifi]: config nano formating: disabled
2019-01-16 18:44:59,084 - INFO # I (447) [system_api]: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
2019-01-16 18:44:59,099 - INFO # I (455) [system_api]: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
2019-01-16 18:44:59,100 - INFO # I (465) [      wifi]: Init dynamic tx buffer num: 48
2019-01-16 18:44:59,113 - INFO # I (469) [      wifi]: Init data frame dynamic rx buffer num: 64
2019-01-16 18:44:59,115 - INFO # I (474) [      wifi]: Init management frame dynamic rx buffer num: 64
2019-01-16 18:44:59,116 - INFO # I (481) [      wifi]: Init static rx buffer size: 1600
2019-01-16 18:44:59,129 - INFO # I (486) [      wifi]: Init static rx buffer num: 10
2019-01-16 18:44:59,130 - INFO # I (490) [      wifi]: Init dynamic rx buffer num: 64
2019-01-16 18:44:59,307 - INFO # I (675) [       phy]: phy_version: 3910, c0c45a3, May 21 2018, 18:07:06, 0, 2
2019-01-16 18:44:59,309 - INFO # I (678) [      wifi]: mode : sta (84:0d:8e:18:7e:30)
2019-01-16 18:44:59,321 - INFO # I (678) [     event]: system_event_sta_start_handle_default
2019-01-16 18:44:59,324 - INFO # I (685) [main_trampoline]: main(): This is RIOT! (Version: 2018.10-RC1-965-g4d1a0-test/10762)
2019-01-16 18:44:59,326 - INFO # RIOT network stack example application
2019-01-16 18:44:59,327 - INFO # All up, running the shell now
> 2019-01-16 18:45:01,722 - INFO #  I (3098) [     event]: system_event_sta_disconnected_handle_default

@MrKevinWeiss
Copy link
Contributor

I am pretty sure it's me, I think the router is ipv4 only. I will try more tomorrow...

@gschorcht
Copy link
Contributor Author

@MrKevinWeiss Thank you for trying 😄

Once the ESP32 can establish an association with the AP and can pass the authentication, it doesn't matter for link local IPv6 communication whether the router provides a global routing prefix or not. Since the IPv6 link local address fe80::<IID>/64 is generated from the MAC address, you should be able to ping another node in your LAN using its fe80::... address without router support.

From your log, I can see that your problem is definitely that your ESP32 node cannot establish the association to the AP. If it could establish an association but the authentication fails, your log would looks like as follows:

I (672) [     event]: system_event_sta_start_handle_default
I (679) [main_trampoline]: main(): This is RIOT! (Version: 2018.10-RC1-965-g4d1a0-esp32_esp_wifi_fix)
RIOT network stack example application
All up, running the shell now
> I (3090) [      wifi]: n:8 0, o:1 0, ap:255 255, sta:8 0, prof:1
I (5053) [      wifi]: state: init -> auth (b0)
I (5062) [      wifi]: state: auth -> assoc (0)
I (5136) [      wifi]: state: assoc -> run (10)
I (8191) [      wifi]: state: run -> auth (7c0)
I (8192) [      wifi]: n:8 0, o:8 0, ap:255 255, sta:8 0, prof:1
I (8192) [     event]: system_event_sta_disconnected_handle_default
I (8196) [      wifi]: state: auth -> init (0)
I (8201) [     event]: system_event_sta_disconnected_handle_default
I (10642) [      wifi]: n:8 0, o:8 0, ap:255 255, sta:8 0, prof:1
I (10643) [      wifi]: state: init -> auth (b0)
I (10650) [      wifi]: state: auth -> assoc (0)
I (10726) [      wifi]: state: assoc -> run (10)
I (13781) [      wifi]: state: run -> auth (7c0)
I (13782) [      wifi]: n:8 0, o:8 0, ap:255 255, sta:8 0, prof:1
I (13783) [     event]: system_event_sta_disconnected_handle_default
I (13787) [      wifi]: state: auth -> init (0)
I (13792) [     event]: system_event_sta_disconnected_handle_default
I (16211) [      wifi]: n:8 0, o:8 0, ap:255 255, sta:8 0, prof:1
I (16212) [      wifi]: state: init -> auth (b0)
...

Please double check your ESP_WIFI_SSID parameter setting.

The size of received and transmitted frames was stored in an uint8_t, which did not allow to process frames larger than 255 octets. However, WiFi has an MTU of 1500 octets.
esp_wifi was simply returning the connection state instead of filling the referenced value.
The WiFi configuration has to be static to avoid memory access problems when WiFi AP is reconnected.
The buffer given by the WiFi driver as parameter eb has to be freed explicitly. Otherwise the esp_wifi_netdev stops working after some seconds.
Before function wifi_connect is executed, starting the WiFi driver should have been finished. This is indicated by the WiFi driver by sending event SYSTEM_EVENT_STA_START. Function wifi_connect is moved therefore to the event handler for SYSTEM_EVENT_STA_START.
RX callback function should be register when WiFi has been connected to AP successfully and should be unregistered when WiFi disconnects from AP. Therefore, esp_wifi_internal_reg_rxcb is called now in event handler on event SYSTEM_EVENT_STA_CONNECTED. It is reset now on event SYSTEM_EVENT_STA_DISCONNECTED.
If WiFi is disconnected, e.g., because of timeout for beacon frame, it is tried to reconnect automatically.
To avoid further inconsistencies in documentation, README.md is not provided any longer
Fixes sporadic blocking of the wifi thread in esp_wifi_recv_cb function under heavy network load conditions when frames are coming in faster than they can be processed. Since esp_wifi_recv_cb function is not executed in interrupt context, the msg_send function used for ISR event can block when the message queue is full. With this change esp_wifi can be flooded with icmpv6 packets of maximum size without any problems over hours.
ESP-IDF heap handling has to be used for esp_wifi for stability reasons. Otherwise, heap is corrupted sporadically
@smlng smlng added Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines labels Jan 17, 2019
@smlng smlng merged commit 495607d into RIOT-OS:master Jan 17, 2019
@gschorcht
Copy link
Contributor Author

@MrKevinWeiss @smlng Thanks for your support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ESP Platform: This PR/issue effects ESP-based platforms Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants