Description
Hardware:
Board: Adafruit ESP32 Feather
Core Installation version: Core v1.0.2 in Arduino 1.8.9, espressif32@1.8.0 and framework-arduinoespressif32@2.10002.190416 in PlatformIO
IDE name: Arduino v1.8.9 and PlatformIO v3.6.7 in VSCode v1.35.1
Flash Frequency: 80MHz
PSRAM enabled: Don't know
Upload Speed: 921600
Computer OS: Mac OSX v10.14.5
Description:
The network stack never recovers if it receives just tens of larger UDP packets greater than 1024 bytes. This detail got lost in the discussion of #2871, so I'm creating this new bug.
I see this problem almost every time I send somewhere between 20-80 larger UDP packets in non-softAP mode. I see this problem sometimes but rarely when using softAP mode. Sometimes, if I repeatedly run the program, see the network stack crash, and then hard reset the device, I won't see the network stack failure and it will recover from seeing a bunch of large packets. But only sometimes.
To reiterate: The network stack does not recover after receiving a bunch of large packets. Some people see that it recovers just fine if the packets stop, but I never see this. Yes, the device stops seeing packets if it's flooded with them, and yes, some people will see the network stack recover after a short period, but I never do. A hard reset is required.
To continuously send closely-spaced packets, this Bash script is useful:
while true; do echo -n $(printf '.%.0s' {1..1400}) > /dev/udp/192.168.1.9/8000; sleep 0.05; done
The 1400
is the UDP size; I find that 1025 and greater causes the problem for me. Also, change the IP address and sleep (in seconds) to play with different network loads.
The crux is this: I see onPacket
never called again once a bunch of large packets are received, even if no more packets are sent. I've tried on three different ESP32 Feathers and three different network setups for non-softAP mode.
The effect: The device becomes permanently unusable on the network, without a hard reset, if it sees lots of larger UDP packets in a row.
Sketch:
#include <AsyncUDP.h>
#include <Esp.h>
#include <WiFi.h>
constexpr char kAPName[] = "ChangeMe";
constexpr char kAPPassword[] = "ChangeMe";
constexpr bool isSoftAP = false; // Change to true for SoftAP mode
AsyncUDP udp;
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 4000) {
// Wait for Serial
}
Serial.println("Starting.");
if (isSoftAP) {
Serial.println("Starting SoftAP...");
if (WiFi.softAP(kAPName, kAPPassword)) {
Serial.print(" IP: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("ERROR: Starting SoftAP!");
}
} else {
if (WiFi.begin(kAPName, kAPPassword)) {
while (!WiFi.isConnected()) {
delay(500);
}
Serial.print(" IP: ");
Serial.println(WiFi.localIP());
Serial.print(" Subnet: ");
Serial.println(WiFi.subnetMask());
Serial.print(" Gateway: ");
Serial.println(WiFi.gatewayIP());
} else {
Serial.println(" ERROR: Connecting to AP!");
}
}
if (!udp.listen(8000)) {
Serial.println("ERROR: Starting UDP server!");
}
udp.onPacket(onPacket);
}
int counter = 0;
void onPacket(AsyncUDPPacket &packet) {
Serial.printf("%d: %d\n", ++counter, packet.length());
}
void loop() {
// Print some status every 5s
Serial.printf("Free heap: %d\n", ESP.getFreeHeap());
delay(5000);
}