Repository navigation
BRIDGE_STATUS_SELF_REGISTRATION_FIX
Problem: After successfully promoting to bridge via election, the node reports:
I am bridge: YES
Internet available: NO
Known bridges: 0
No primary bridge available! ❌
When a node becomes a bridge (either via initAsBridge() or election promotion), it broadcasts bridge status messages to the mesh network, but it does not add itself to its own knownBridges list.
- Node wins election and promotes to bridge ✅
- Node calls
initBridgeStatusBroadcast()✅ - Node sends bridge status broadcasts ✅
- Other nodes receive broadcasts and update their
knownBridges✅ - Bridge node itself never receives its own broadcast ❌
- Bridge node's
knownBridgesremains empty ❌ -
getPrimaryBridge()returnsnullptrbecause list is empty ❌
// When bridge promotes
promoteToBridge()
→ initAsBridge()
→ initBridgeStatusBroadcast()
→ sendBridgeStatus() // Broadcasts to network
→ sendBroadcast(msg) // Bridge doesn't receive its own broadcastsAdded self-registration during bridge initialization:
void initBridgeStatusBroadcast() {
using namespace logger;
if (!this->isBridge() || !this->bridgeStatusBroadcastEnabled) {
return;
}
Log(STARTUP, "initBridgeStatusBroadcast(): Setting up bridge status broadcast\n");
// NEW: Register ourselves as a bridge in the knownBridges list
// This ensures the bridge knows about itself and reports correct status
this->addTask([this]() {
bool hasInternet = (WiFi.status() == WL_CONNECTED) &&
(WiFi.localIP() != IPAddress(0, 0, 0, 0));
this->updateBridgeStatus(
this->nodeId, // bridgeNodeId
hasInternet, // internetConnected
WiFi.RSSI(), // routerRSSI
WiFi.channel(), // routerChannel
millis(), // uptime
WiFi.gatewayIP().toString(),// gatewayIP
this->getNodeTime() // timestamp
);
Log(STARTUP, "initBridgeStatusBroadcast(): Registered self as bridge (nodeId: %u)\n",
this->nodeId);
});
// ... rest of method unchanged
}Added self-update before broadcasting:
void sendBridgeStatus() {
using namespace logger;
if (!this->bridgeStatusBroadcastEnabled) {
return;
}
// ... create JSON message ...
bool hasInternet = (WiFi.status() == WL_CONNECTED) &&
(WiFi.localIP() != IPAddress(0, 0, 0, 0));
int8_t rssi = WiFi.RSSI();
uint8_t channel = WiFi.channel();
uint32_t uptime = millis();
TSTRING gatewayIP = WiFi.gatewayIP().toString();
// ... add to JSON ...
Log(GENERAL, "sendBridgeStatus(): Broadcasting status (Internet: %s)\n",
hasInternet ? "Connected" : "Disconnected");
Log(GENERAL, "sendBridgeStatus(): WiFi status=%d, localIP=%s, gatewayIP=%s\n",
WiFi.status(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str());
// NEW: Update our own bridge status in knownBridges list
// This ensures the bridge reports itself correctly when queried
this->updateBridgeStatus(this->nodeId, hasInternet, rssi, channel,
uptime, gatewayIP, this->getNodeTime());
this->sendBroadcast(msg);
}--- Bridge Status ---
I am bridge: YES
Internet available: NO
Known bridges: 0
No primary bridge available! ❌
--------------------
--- Bridge Status ---
I am bridge: YES
Internet available: NO ⚠️ (May be YES if router has internet)
Known bridges: 1
Primary bridge: 3394043125 (RSSI: -36 dBm) ✅
--------------------
-
initBridgeStatusBroadcast()- Initial registration when bridge first starts- Ensures bridge is in
knownBridgesimmediately after promotion - Provides accurate status for early queries
- Ensures bridge is in
-
sendBridgeStatus()- Periodic updates- Keeps bridge info current in
knownBridges - Updates RSSI, uptime, internet connectivity dynamically
- Ensures consistency between broadcast and local state
- Keeps bridge info current in
The "Internet available: NO" in @woodlist's log may be accurate depending on:
- Router has active internet connection
- DHCP has assigned valid IP address (not 0.0.0.0)
-
WiFi.localIP()returns valid address
Check with:
Log(GENERAL, "sendBridgeStatus(): WiFi status=%d, localIP=%s, gatewayIP=%s\n",
WiFi.status(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str());This log line was present in the code but not visible in the serial output @woodlist provided.
✅ Bridge nodes now correctly report themselves in knownBridges
✅ getPrimaryBridge() returns valid bridge pointer for bridge nodes
✅ Bridge status displays accurately show "Known bridges: 1" minimum
✅ Regular nodes can immediately discover newly promoted bridges
✅ No breaking changes to existing API
✅ Compatible with existing bridge setups
✅ Works with both manual initAsBridge() and election-based promotion
✅ Multi-bridge configurations continue to function normally
- Flash bridge_failover example to ESP32/ESP8266
- Start all nodes without pre-configured bridge
- Wait for 60-second grace period
- Observe election and promotion
- Check bridge status output
Expected to see:
- "Known bridges: 1" or more
- Valid primary bridge with node ID and RSSI
- No "No primary bridge available!" error
Existing tests in test/catch/catch_diagnostics_api.cpp verify:
-
updateBridgeStatus()adds bridges correctly -
getPrimaryBridge()returns correct bridge based on RSSI/health - Bridge tracking and health monitoring work as expected
-
src/arduino/wifi.hpp-
initBridgeStatusBroadcast()- Added self-registration -
sendBridgeStatus()- Added periodic self-update
-
- Fixes "No primary bridge available" on bridge nodes
- Related to bridge election feature (v1.8.6)
- Complements bridge failover implementation
Reported by: @woodlist
Analysis: GitHub Copilot
Fix: Self-registration pattern for bridge tracking
Version: To be included in v1.8.7+
Date: November 12, 2025
Status: Implementation complete, pending testing