Fix WiFi TCP/HTTP services not starting without USB serial connected#10460
Conversation
|
|
There was a problem hiding this comment.
Pull request overview
This PR addresses an ESP32 boot-time race in initWifi() where WiFi can auto-reconnect (and emit ARDUINO_EVENT_WIFI_STA_GOT_IP) before the firmware registers its WiFi event handler, preventing onNetworkConnected() from running and leaving TCP/HTTP services uninitialized.
Changes:
- Registers the ESP32 WiFi event handler earlier (before SSL cert creation) to avoid missing
GOT_IPduring boot. - Calls
onNetworkConnected()fromreconnectWiFi()on all platforms as a one-time safety net for bringing up network services. - Moves
createSSLCert()later in theinitWifi()flow to occur after event registration.
| // Register WiFi event handler BEFORE createSSLCert() to prevent race condition: | ||
| // Without this, WiFi can auto-reconnect during cert generation and fire GOT_IP | ||
| // before the handler is registered, causing onNetworkConnected() to never run. | ||
| WiFi.onEvent(WiFiEvent); | ||
| WiFi.setAutoReconnect(true); |
|
Good catch, but this is safe in practice for two reasons: When the cert is already cached in NVS (every boot after the first), createSSLCert() completes in under a second. WiFi reconnection takes 5 to 10 seconds. So the cert is always ready before GOT_IP fires. Even on a cold first boot (no cached cert), the cert generation task assigns the global The second change (calling onNetworkConnected from reconnectWiFi) provides an additional safety net: if the event is ever missed for any reason, the next periodic check picks it up. The function is guarded by APStartupComplete so it only runs once. Tested with 3 consecutive cold reboots without USB serial on Heltec V3. TCP 4403 and web API came up correctly every time. |
Move WiFi.onEvent(WiFiEvent) registration before createSSLCert() to prevent a race where the ESP32 auto-reconnects during cert generation and fires GOT_IP before the handler is attached, causing onNetworkConnected() to never run and the TCP/HTTP API services to never initialize when booting without USB serial. Also call onNetworkConnected() from reconnectWiFi() on all platforms (not just RP2040) as a safety net; it is already guarded by APStartupComplete so it only runs once.
3402787 to
dca50c5
Compare
…10460) Move WiFi.onEvent(WiFiEvent) registration before createSSLCert() to prevent a race where the ESP32 auto-reconnects during cert generation and fires GOT_IP before the handler is attached, causing onNetworkConnected() to never run and the TCP/HTTP API services to never initialize when booting without USB serial. Also call onNetworkConnected() from reconnectWiFi() on all platforms (not just RP2040) as a safety net; it is already guarded by APStartupComplete so it only runs once.
Что вошло из апстрима (40 коммитов): - Position precision security fix: утечка координат через PRIMARY канал (meshtastic#10509) - T-Echo-Card поддержка + OLED_TINY guard для компаса - ThinkNode M7, Station G3 варианты - SX_LNA_EN включён по умолчанию (meshtastic#10469) - WiFi TCP/HTTP fix при отсутствии USB serial (meshtastic#10460) - Rework clock renderer (70% max) - Обновлены protobufs → 59cb394 Конфликты разрешены: - UIRenderer.cpp: взята версия апстрима (OLED_TINY) вместо 2.8-ветки - PositionPrecision.{cpp,h}: взят upstream security fix (meshtastic#10509) - admin.pb.h, cardputer variant.cpp, test_position_precision: взят апстрим - protobufs submodule: обновлён до 59cb394 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eshtastic#10460) Move WiFi.onEvent(WiFiEvent) registration before createSSLCert() to prevent a race where the ESP32 auto-reconnects during cert generation and fires GOT_IP before the handler is attached, causing onNetworkConnected() to never run and the TCP/HTTP API services to never initialize when booting without USB serial. Also call onNetworkConnected() from reconnectWiFi() on all platforms (not just RP2040) as a safety net; it is already guarded by APStartupComplete so it only runs once.
Fixes a race condition in
initWifi()that preventsonNetworkConnected()from ever being called when the device boots without a USB serial connection. This causes the TCP API server (port 4403) and HTTP API handlers to never initialize, even though WiFi connects successfully.In
initWifi(),WiFi.onEvent(WiFiEvent)is registered aftercreateSSLCert(). ThecreateSSLCert()function blocks withyield()calls while generating/loading the SSL certificate.Without USB serial, the
SerialConsoleconstructor delays boot by up to 5 seconds (while (!Port)timeout). By the timeinitWifi()runs, the ESP32 WiFi subsystem has had time to auto-reconnect using credentials stored in NVS. DuringcreateSSLCert()'syield()calls, WiFi firesARDUINO_EVENT_WIFI_STA_GOT_IP, but the event handler isn't registered yet, so the event is lost.onNetworkConnected()never runs, and the web/TCP services never start.With USB serial connected, the serial port becomes ready immediately (no 5-second timeout), so
initWifi()runs earlier andWiFi.onEvent()is registered before WiFi can auto-reconnect.Two changes in
WiFiAPClient.cpp:Move
WiFi.onEvent(WiFiEvent)beforecreateSSLCert()so the event handler is ready before any blocking call that could allow WiFi to reconnect.Call
onNetworkConnected()fromreconnectWiFi()on all platforms (not just RP2040) as a safety net. The function is already guarded byAPStartupCompleteso it only runs once.Tested on Heltec V3 (ESP32-S3) with firmware 2.7.23:
Possibly related issues
Reports describing the same end-user symptom (WiFi connects and the device gets an IP, but no client can connect because TCP/HTTP services never come up) that this PR may fix. I do not own these specific boards, so confirmation from affected users would be appreciated:
🤝 Attestations