fix(firmware): net_guard silent-wifi-death fallback + header hygiene

- net_guard_tick now detects status-vs-event divergence. If s_up is
  true but WiFi.status() says otherwise (rare: driver wedge, silent
  RF failure), force DOWN state and schedule reconnect. Uses 0xFF
  disconnect reason so the event log distinguishes this path.
- Forward-declare DeviceConfig in net_guard.h so consumers that don't
  call net_guard_start don't transitively pull config.h.
This commit is contained in:
2026-04-23 13:41:53 -07:00
parent af3067d481
commit 57129ba078
2 changed files with 11 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ uint32_t net_guard_next_backoff_ms(uint32_t attempt) {
} }
#ifdef ARDUINO #ifdef ARDUINO
#include "config.h"
#include <WiFi.h> #include <WiFi.h>
#include "event_log.h" #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; } uint8_t net_guard_last_disconnect_reason() { return s_last_disconnect; }
extern "C" void net_guard_tick() { 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 (s_up || s_cfg == nullptr) return;
if (millis() < s_next_retry_ms) return; if (millis() < s_next_retry_ms) return;
if (s_up) return; // re-check after the timing gate — closes GOT_IP-vs-tick race if (s_up) return; // re-check after the timing gate — closes GOT_IP-vs-tick race

View File

@@ -7,7 +7,7 @@
uint32_t net_guard_next_backoff_ms(uint32_t attempt); uint32_t net_guard_next_backoff_ms(uint32_t attempt);
#ifdef ARDUINO #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. // Registers WiFi.onEvent() handler and starts auto-reconnect loop.
// Must be called once after WiFi.begin() succeeds. // Must be called once after WiFi.begin() succeeds.