From 4ffa9f61840c2c25e6201515e00b01c2bd6f0b25 Mon Sep 17 00:00:00 2001 From: DeFiDude <59237470+DeFiDude@users.noreply.github.com> Date: Sun, 3 May 2026 20:56:37 -0600 Subject: [PATCH] Port reconnect backoff to selected profile --- src/main.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c3af41e..79f2b44 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,6 +57,7 @@ #include "audio/AudioNotify.h" #include #include +#include #include #include #include @@ -133,6 +134,43 @@ bool wifiSTAStarted = false; WiFiMulti wifiMulti; bool wifiSTAConnected = false; unsigned long lastAutoAnnounce = 0; + +// STA reconnects are scheduled from WiFi events and fired from loop(). +std::atomic wifiNeedsReconnect{false}; +std::atomic wifiReconnectAt{0}; +std::atomic wifiReconnectAttempt{0}; +constexpr unsigned long WIFI_BACKOFF_MS[4] = {5000, 15000, 60000, 300000}; +constexpr unsigned long WIFI_NETIF_SETTLE_MS = 1500; + +static void scheduleWiFiReconnect() { + uint8_t attempt = wifiReconnectAttempt.load(); + uint8_t idx = attempt < 4 ? attempt : 3; + unsigned long backoff = WIFI_BACKOFF_MS[idx]; + if (backoff < WIFI_NETIF_SETTLE_MS) backoff = WIFI_NETIF_SETTLE_MS; + wifiReconnectAt.store(millis() + backoff); + wifiNeedsReconnect.store(true); + if (attempt < 4) wifiReconnectAttempt.store(attempt + 1); +} + +static void onWiFiEvent(WiFiEvent_t event) { + switch (event) { + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: + // Our own disconnect() below can emit another disconnect event. + if (wifiNeedsReconnect.load()) break; + scheduleWiFiReconnect(); + // Drop the netif and clear stale AP info before the next connect. + WiFi.disconnect(false, true); + break; + case ARDUINO_EVENT_WIFI_STA_GOT_IP: + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: + wifiNeedsReconnect.store(false); + wifiReconnectAttempt.store(0); + break; + default: + break; + } +} + unsigned long lastStatusUpdate = 0; constexpr unsigned long STATUS_UPDATE_MS = 1000; // 1 Hz status bar update unsigned long lastHeartbeat = 0; @@ -729,15 +767,19 @@ void setup() { // WiFi is enabled but not yet connected — indicator will be yellow if (registered > 0) { WiFi.mode(WIFI_STA); - WiFi.setAutoReconnect(true); + WiFi.onEvent(onWiFiEvent); // AutoInterface needs an IPv6 link-local address. Must be enabled // BEFORE WiFi.begin() so SLAAC starts on STA association. if (userConfig.settings().autoIfaceEnabled) { WiFi.enableIpV6(); Serial.println("[WIFI] IPv6 enabled (AutoInterface ON)"); } - wifiMulti.run(5000); + uint8_t initialStatus = wifiMulti.run(5000); wifiSTAStarted = true; + if (initialStatus != WL_CONNECTED && WiFi.status() != WL_CONNECTED && + !wifiNeedsReconnect.load()) { + scheduleWiFiReconnect(); + } Serial.printf("[WIFI] STA: %d selected profile registered\n", registered); } } else { @@ -1167,6 +1209,17 @@ void loop() { // 7. WiFi STA connection handler if (wifiSTAStarted) { + if (wifiNeedsReconnect.load() && WiFi.status() != WL_CONNECTED && + (long)(millis() - wifiReconnectAt.load()) >= 0) { + wifiNeedsReconnect.store(false); + uint8_t attempt = wifiReconnectAttempt.load(); + Serial.printf("[WIFI] Reconnect attempt #%u\n", (unsigned)attempt); + uint8_t result = wifiMulti.run(2000); + if (result != WL_CONNECTED && WiFi.status() != WL_CONNECTED && + !wifiNeedsReconnect.load()) { + scheduleWiFiReconnect(); + } + } bool connected = (WiFi.status() == WL_CONNECTED); if (connected && !wifiSTAConnected) { wifiSTAConnected = true;