Edit: I suspected promiscuous mode is used internally when performing a passive scan. I have reproduced the same issue while sending data over TCP to an esp32 while doing a passive scan every ~2 seconds or so. Also based on the tcp_performance example. This example also reproduces the issue much faster than the one below. The project can be downloaded here: tcp_perf_passive_scan.zip
use it together with the esp-idf and according to the README I linked below in (Project download).
What we do is to listen for packets for 200ms every 2s on the different channels. This is roughly how we do it:
1. esp_wifi_set_channel(promiscuousChannel)
2. esp_wifi_set_promiscuous(TRUE)
3. esp_wifi_set_promiscuous(FALSE) after 200ms
4. esp_wifi_set_channel(connectedAPChannel) // Change back to ap channel, otherwise we lose connection
5. promiscuousChannel++
6. After 2000ms go to 1.
While doing the above we send data over TCP to the esp32.
This works great, except that after a few minutes esp_wifi_internal_tx starts to give error code -1 (Out Of Memory). It could be fine that the tx_buffer is full, however it doesn't recover. After one error, no new packets can be send. Meaning the connection stops, since we can't ACK the received TCP packets.
I have managed to reproduce a minimal example, based on the example performance\tcp_perf.
The only difference between this reproduce and our application is that the error occurs faster for us, maybe 1 minute instead of ~5-8 minutes.
The whole esp-idf is included since I changed TCP_MSS to 536 (since it speeds up the time until error) in lwipopts.h And added a log in lwip/port/netif/wlanif.c you should be able to do a git diff in the lwip component to see the difference. Our sdkconfig is included, it has our memory configuration and such, which is needed to reproduce.
The necessary information to run and reproduce is found on the top of the README.
Project download
The code, Wireshark logs and debug logs can be found in the folder tcp_perf_promiscuous
ESP-IDF: release/v2.1
If anything is unclear, just comment.
HI @jakkra we will investigate this issue
@jakkra esp_wifi_set_channel is not a normal API, can only be used in promiscuous mode.
That means when we use esp_wifi_set_channel(connectedAPChannel), ESP32 will not send the packets buffered. This is a not implemented feature.
@jack0c
So changing order something like this should solve the problem?
Or are you saying that I can't use promiscuous mode and sending data over TCP at the same time?
1. esp_wifi_set_promiscuous(TRUE)
2. esp_wifi_set_channel(promiscuousChannel)
// wait 200ms
3. esp_wifi_set_channel(connectedAPChannel) // Change back to ap channel, otherwise we lose connection
4. esp_wifi_set_promiscuous(FALSE)
5. promiscuousChannel++
6. After 2000ms go to 1.
By now, yes, you can't use them at the same time.
We will add an API like esp_wifi_goto_home_channel() to support this in idf 3.1.
Will use your code to be a test case.
@jack0c I met the same issue, i can't find the API esp_wifi_goto_home_channel@idf 3.1.
Did you implement esp_wifi_goto_home_channel@idf 3.1? We had the same issue...
We recorded this issue and plan to process it later.
Hi @pierocavalcanti sorry for late response, we still haven't implement this API.
Hi @pierocavalcanti , We optimized the esp_wifi_set_channel() API.
When esp_wifi_set_channel() is used, it will be called to esp_wifi_set_home_channel().
Please verify that the API solve your issue?
esp_err_t esp_wifi_set_home_channel(uint8_t primary, wifi_second_chan_t second);
Thanks for reporting and sorry for the very slow turnaround, the fix is available at https://github.com/espressif/esp-idf/commit/c378bd210c1b79857509beb8807fca2440ed82ef. Feel free to reopen if the issue still happens.
Most helpful comment
By now, yes, you can't use them at the same time.
We will add an API like esp_wifi_goto_home_channel() to support this in idf 3.1.
Will use your code to be a test case.