diff --git a/firmware/lib/net_guard/net_guard.cpp b/firmware/lib/net_guard/net_guard.cpp index f0e0cf1..36b4f3e 100644 --- a/firmware/lib/net_guard/net_guard.cpp +++ b/firmware/lib/net_guard/net_guard.cpp @@ -7,6 +7,7 @@ uint32_t net_guard_next_backoff_ms(uint32_t attempt) { } #ifdef ARDUINO +#include "config.h" #include #include "event_log.h" @@ -52,6 +53,15 @@ bool net_guard_is_up() { return s_up; } uint8_t net_guard_last_disconnect_reason() { return s_last_disconnect; } extern "C" void net_guard_tick() { + // Watchdog against silent WiFi death: if we think we're up but the radio + // disagrees, force the DOWN state so reconnect scheduling kicks in. + if (s_up && WiFi.status() != WL_CONNECTED) { + s_up = false; + s_last_disconnect = 0xFF; // 0xFF = "silent death, no event" + event_log_write(EVT_WIFI_DOWN, s_last_disconnect, 0); + s_next_retry_ms = millis() + net_guard_next_backoff_ms(s_attempts); + } + if (s_up || s_cfg == nullptr) return; if (millis() < s_next_retry_ms) return; if (s_up) return; // re-check after the timing gate — closes GOT_IP-vs-tick race diff --git a/firmware/lib/net_guard/net_guard.h b/firmware/lib/net_guard/net_guard.h index 915b483..9b9fc66 100644 --- a/firmware/lib/net_guard/net_guard.h +++ b/firmware/lib/net_guard/net_guard.h @@ -7,7 +7,7 @@ uint32_t net_guard_next_backoff_ms(uint32_t attempt); #ifdef ARDUINO -#include "config.h" +struct DeviceConfig; // forward-decl; only net_guard_start needs the full type // Registers WiFi.onEvent() handler and starts auto-reconnect loop. // Must be called once after WiFi.begin() succeeds.