@alteriom/painlessmesh 1.8.7 → 1.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +221 -0
- package/examples/bridge_failover/README.md +10 -4
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +1 -1
- package/src/AlteriomPainlessMesh.h +2 -2
- package/src/arduino/wifi.hpp +54 -6
- package/src/painlessMesh.h +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.8.9] - 2025-11-12
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Bridge Self-Registration (Type 610 & 613)** - Bridge nodes now properly track themselves in status and coordination
|
|
15
|
+
- **Bridge Status Broadcasting (Type 610)**: Fixed bridge nodes reporting "Known bridges: 0" despite being active
|
|
16
|
+
- Added immediate self-registration task in `initBridgeStatusBroadcast()` (line ~746)
|
|
17
|
+
- Bridge now calls `updateBridgeStatus()` with own nodeId immediately after initialization
|
|
18
|
+
- Added self-update in `sendBridgeStatus()` (line ~1192) before broadcasting
|
|
19
|
+
- Ensures bridge appears in its own `knownBridges` list from the start
|
|
20
|
+
- **Bridge Coordination (Type 613)**: Fixed multi-bridge priority tracking
|
|
21
|
+
- Added self-registration in `initBridgeCoordination()` (line ~803)
|
|
22
|
+
- Bridge now adds own priority to `bridgePriorities` map: `bridgePriorities[this->nodeId] = bridgePriority`
|
|
23
|
+
- Added priority self-update in `sendBridgeCoordination()` (line ~869) before broadcasting
|
|
24
|
+
- Ensures primary bridge selection works correctly with multiple bridges
|
|
25
|
+
- **Root Cause**: Mesh networks don't loop broadcasts back to sender by design
|
|
26
|
+
- Nodes receive broadcasts from other nodes but not their own messages
|
|
27
|
+
- Requires explicit local state management for any tracking data
|
|
28
|
+
- **Before Fix**:
|
|
29
|
+
- Bridge reports "Known bridges: 0" and "No primary bridge available!"
|
|
30
|
+
- Multi-bridge setups fail to select primary bridge (missing own priority)
|
|
31
|
+
- Bridge failover unreliable due to incomplete bridge tracking
|
|
32
|
+
- **After Fix**:
|
|
33
|
+
- Bridge correctly reports "Known bridges: 1" (or more in multi-bridge setups)
|
|
34
|
+
- Primary bridge selection works properly with all bridge priorities present
|
|
35
|
+
- Self-tracking pattern now consistent across all periodic broadcast types
|
|
36
|
+
- Core fixes in `src/arduino/wifi.hpp`
|
|
37
|
+
- Resolves @woodlist GitHub issue - bridge showing "Known bridges: 0"
|
|
38
|
+
- Comprehensive analysis documented in COMPREHENSIVE_BROADCAST_ANALYSIS.md
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- **Build System** - Switched Docker compiler from clang++ to g++
|
|
43
|
+
- Changed ENV CXX in Dockerfile from clang++ to g++
|
|
44
|
+
- Resolves template instantiation crashes during Docker builds
|
|
45
|
+
- Build verification confirms successful compilation with g++
|
|
46
|
+
|
|
47
|
+
### Documentation
|
|
48
|
+
|
|
49
|
+
- **Broadcast Message Analysis** - Added comprehensive review documentation
|
|
50
|
+
- Created COMPREHENSIVE_BROADCAST_ANALYSIS.md with full analysis of all 4 broadcast types
|
|
51
|
+
- Documents self-tracking requirements for Type 610 (STATUS) and 613 (COORDINATION)
|
|
52
|
+
- Confirms Type 611 (ELECTION) already implements correct self-registration
|
|
53
|
+
- Confirms Type 612 (TAKEOVER) doesn't require self-tracking (notification only)
|
|
54
|
+
- Establishes pattern guidelines for future broadcast implementations
|
|
55
|
+
|
|
56
|
+
## [1.8.8] - 2025-11-12
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- **Bridge Internet Connectivity Detection (Mobile Hotspot Compatibility)** - Fixed false negative with mobile hotspots
|
|
61
|
+
- Changed internet detection from checking gateway IP to checking local IP address
|
|
62
|
+
- Gateway IP may not be immediately available after connection, especially with mobile hotspots
|
|
63
|
+
- Some networks (mobile tethering) may not provide gateway IP via DHCP at all
|
|
64
|
+
- **Before**: Bridge connected to mobile hotspot → gets local IP → reports "Internet: NO" (gateway IP not available)
|
|
65
|
+
- **After**: Bridge connected to mobile hotspot → gets local IP → correctly reports "Internet: YES"
|
|
66
|
+
- Having a valid local IP + WiFi connected status is sufficient to indicate internet access
|
|
67
|
+
- Enhanced logging to show WiFi status, local IP, and gateway IP for better debugging
|
|
68
|
+
- Core fix in `src/arduino/wifi.hpp` line 1189-1191
|
|
69
|
+
- Improves upon 1.8.7 gateway IP check which didn't work with all network types
|
|
70
|
+
- Resolves issue where bridge connects successfully but still reports no internet
|
|
71
|
+
- Fixes Alteriom/painlessMesh#129
|
|
72
|
+
|
|
10
73
|
## [1.8.7] - 2025-11-12
|
|
11
74
|
|
|
12
75
|
### Fixed
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Bridge Status Self-Registration Fix
|
|
2
|
+
|
|
3
|
+
## Issue Reported by @woodlist
|
|
4
|
+
|
|
5
|
+
**Problem**: After successfully promoting to bridge via election, the node reports:
|
|
6
|
+
```
|
|
7
|
+
I am bridge: YES
|
|
8
|
+
Internet available: NO
|
|
9
|
+
Known bridges: 0
|
|
10
|
+
No primary bridge available! ❌
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Root Cause
|
|
14
|
+
|
|
15
|
+
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**.
|
|
16
|
+
|
|
17
|
+
### Why This Happens
|
|
18
|
+
|
|
19
|
+
1. Node wins election and promotes to bridge ✅
|
|
20
|
+
2. Node calls `initBridgeStatusBroadcast()` ✅
|
|
21
|
+
3. Node sends bridge status broadcasts ✅
|
|
22
|
+
4. **Other nodes receive broadcasts and update their `knownBridges` ✅**
|
|
23
|
+
5. **Bridge node itself never receives its own broadcast ❌**
|
|
24
|
+
6. Bridge node's `knownBridges` remains empty ❌
|
|
25
|
+
7. `getPrimaryBridge()` returns `nullptr` because list is empty ❌
|
|
26
|
+
|
|
27
|
+
### Code Flow
|
|
28
|
+
|
|
29
|
+
```cpp
|
|
30
|
+
// When bridge promotes
|
|
31
|
+
promoteToBridge()
|
|
32
|
+
→ initAsBridge()
|
|
33
|
+
→ initBridgeStatusBroadcast()
|
|
34
|
+
→ sendBridgeStatus() // Broadcasts to network
|
|
35
|
+
→ sendBroadcast(msg) // Bridge doesn't receive its own broadcasts
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## The Fix
|
|
39
|
+
|
|
40
|
+
### Changes to `src/arduino/wifi.hpp`
|
|
41
|
+
|
|
42
|
+
#### 1. Modified `initBridgeStatusBroadcast()`
|
|
43
|
+
|
|
44
|
+
Added self-registration during bridge initialization:
|
|
45
|
+
|
|
46
|
+
```cpp
|
|
47
|
+
void initBridgeStatusBroadcast() {
|
|
48
|
+
using namespace logger;
|
|
49
|
+
|
|
50
|
+
if (!this->isBridge() || !this->bridgeStatusBroadcastEnabled) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Log(STARTUP, "initBridgeStatusBroadcast(): Setting up bridge status broadcast\n");
|
|
55
|
+
|
|
56
|
+
// NEW: Register ourselves as a bridge in the knownBridges list
|
|
57
|
+
// This ensures the bridge knows about itself and reports correct status
|
|
58
|
+
this->addTask([this]() {
|
|
59
|
+
bool hasInternet = (WiFi.status() == WL_CONNECTED) &&
|
|
60
|
+
(WiFi.localIP() != IPAddress(0, 0, 0, 0));
|
|
61
|
+
|
|
62
|
+
this->updateBridgeStatus(
|
|
63
|
+
this->nodeId, // bridgeNodeId
|
|
64
|
+
hasInternet, // internetConnected
|
|
65
|
+
WiFi.RSSI(), // routerRSSI
|
|
66
|
+
WiFi.channel(), // routerChannel
|
|
67
|
+
millis(), // uptime
|
|
68
|
+
WiFi.gatewayIP().toString(),// gatewayIP
|
|
69
|
+
this->getNodeTime() // timestamp
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
Log(STARTUP, "initBridgeStatusBroadcast(): Registered self as bridge (nodeId: %u)\n",
|
|
73
|
+
this->nodeId);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// ... rest of method unchanged
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### 2. Modified `sendBridgeStatus()`
|
|
81
|
+
|
|
82
|
+
Added self-update before broadcasting:
|
|
83
|
+
|
|
84
|
+
```cpp
|
|
85
|
+
void sendBridgeStatus() {
|
|
86
|
+
using namespace logger;
|
|
87
|
+
|
|
88
|
+
if (!this->bridgeStatusBroadcastEnabled) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ... create JSON message ...
|
|
93
|
+
|
|
94
|
+
bool hasInternet = (WiFi.status() == WL_CONNECTED) &&
|
|
95
|
+
(WiFi.localIP() != IPAddress(0, 0, 0, 0));
|
|
96
|
+
|
|
97
|
+
int8_t rssi = WiFi.RSSI();
|
|
98
|
+
uint8_t channel = WiFi.channel();
|
|
99
|
+
uint32_t uptime = millis();
|
|
100
|
+
TSTRING gatewayIP = WiFi.gatewayIP().toString();
|
|
101
|
+
|
|
102
|
+
// ... add to JSON ...
|
|
103
|
+
|
|
104
|
+
Log(GENERAL, "sendBridgeStatus(): Broadcasting status (Internet: %s)\n",
|
|
105
|
+
hasInternet ? "Connected" : "Disconnected");
|
|
106
|
+
Log(GENERAL, "sendBridgeStatus(): WiFi status=%d, localIP=%s, gatewayIP=%s\n",
|
|
107
|
+
WiFi.status(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str());
|
|
108
|
+
|
|
109
|
+
// NEW: Update our own bridge status in knownBridges list
|
|
110
|
+
// This ensures the bridge reports itself correctly when queried
|
|
111
|
+
this->updateBridgeStatus(this->nodeId, hasInternet, rssi, channel,
|
|
112
|
+
uptime, gatewayIP, this->getNodeTime());
|
|
113
|
+
|
|
114
|
+
this->sendBroadcast(msg);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Expected Behavior After Fix
|
|
119
|
+
|
|
120
|
+
### Before Fix
|
|
121
|
+
```
|
|
122
|
+
--- Bridge Status ---
|
|
123
|
+
I am bridge: YES
|
|
124
|
+
Internet available: NO
|
|
125
|
+
Known bridges: 0
|
|
126
|
+
No primary bridge available! ❌
|
|
127
|
+
--------------------
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### After Fix
|
|
131
|
+
```
|
|
132
|
+
--- Bridge Status ---
|
|
133
|
+
I am bridge: YES
|
|
134
|
+
Internet available: NO ⚠️ (May be YES if router has internet)
|
|
135
|
+
Known bridges: 1
|
|
136
|
+
Primary bridge: 3394043125 (RSSI: -36 dBm) ✅
|
|
137
|
+
--------------------
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Technical Details
|
|
141
|
+
|
|
142
|
+
### Why Two Registration Points?
|
|
143
|
+
|
|
144
|
+
1. **`initBridgeStatusBroadcast()`** - Initial registration when bridge first starts
|
|
145
|
+
- Ensures bridge is in `knownBridges` immediately after promotion
|
|
146
|
+
- Provides accurate status for early queries
|
|
147
|
+
|
|
148
|
+
2. **`sendBridgeStatus()`** - Periodic updates
|
|
149
|
+
- Keeps bridge info current in `knownBridges`
|
|
150
|
+
- Updates RSSI, uptime, internet connectivity dynamically
|
|
151
|
+
- Ensures consistency between broadcast and local state
|
|
152
|
+
|
|
153
|
+
### Internet Connectivity
|
|
154
|
+
|
|
155
|
+
The "Internet available: NO" in @woodlist's log may be accurate depending on:
|
|
156
|
+
- Router has active internet connection
|
|
157
|
+
- DHCP has assigned valid IP address (not 0.0.0.0)
|
|
158
|
+
- `WiFi.localIP()` returns valid address
|
|
159
|
+
|
|
160
|
+
Check with:
|
|
161
|
+
```cpp
|
|
162
|
+
Log(GENERAL, "sendBridgeStatus(): WiFi status=%d, localIP=%s, gatewayIP=%s\n",
|
|
163
|
+
WiFi.status(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str());
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
This log line was present in the code but not visible in the serial output @woodlist provided.
|
|
167
|
+
|
|
168
|
+
## Impact
|
|
169
|
+
|
|
170
|
+
### Fixed Issues
|
|
171
|
+
✅ Bridge nodes now correctly report themselves in `knownBridges`
|
|
172
|
+
✅ `getPrimaryBridge()` returns valid bridge pointer for bridge nodes
|
|
173
|
+
✅ Bridge status displays accurately show "Known bridges: 1" minimum
|
|
174
|
+
✅ Regular nodes can immediately discover newly promoted bridges
|
|
175
|
+
|
|
176
|
+
### Backward Compatibility
|
|
177
|
+
✅ No breaking changes to existing API
|
|
178
|
+
✅ Compatible with existing bridge setups
|
|
179
|
+
✅ Works with both manual `initAsBridge()` and election-based promotion
|
|
180
|
+
✅ Multi-bridge configurations continue to function normally
|
|
181
|
+
|
|
182
|
+
## Testing
|
|
183
|
+
|
|
184
|
+
### Manual Test Procedure
|
|
185
|
+
1. Flash bridge_failover example to ESP32/ESP8266
|
|
186
|
+
2. Start all nodes without pre-configured bridge
|
|
187
|
+
3. Wait for 60-second grace period
|
|
188
|
+
4. Observe election and promotion
|
|
189
|
+
5. Check bridge status output
|
|
190
|
+
|
|
191
|
+
Expected to see:
|
|
192
|
+
- "Known bridges: 1" or more
|
|
193
|
+
- Valid primary bridge with node ID and RSSI
|
|
194
|
+
- No "No primary bridge available!" error
|
|
195
|
+
|
|
196
|
+
### Unit Tests
|
|
197
|
+
Existing tests in `test/catch/catch_diagnostics_api.cpp` verify:
|
|
198
|
+
- `updateBridgeStatus()` adds bridges correctly
|
|
199
|
+
- `getPrimaryBridge()` returns correct bridge based on RSSI/health
|
|
200
|
+
- Bridge tracking and health monitoring work as expected
|
|
201
|
+
|
|
202
|
+
## Files Modified
|
|
203
|
+
- `src/arduino/wifi.hpp`
|
|
204
|
+
- `initBridgeStatusBroadcast()` - Added self-registration
|
|
205
|
+
- `sendBridgeStatus()` - Added periodic self-update
|
|
206
|
+
|
|
207
|
+
## Related Issues
|
|
208
|
+
- Fixes "No primary bridge available" on bridge nodes
|
|
209
|
+
- Related to bridge election feature (v1.8.6)
|
|
210
|
+
- Complements bridge failover implementation
|
|
211
|
+
|
|
212
|
+
## Credits
|
|
213
|
+
**Reported by**: @woodlist
|
|
214
|
+
**Analysis**: GitHub Copilot
|
|
215
|
+
**Fix**: Self-registration pattern for bridge tracking
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
**Version**: To be included in v1.8.7+
|
|
220
|
+
**Date**: November 12, 2025
|
|
221
|
+
**Status**: Implementation complete, pending testing
|
|
@@ -344,12 +344,18 @@ bool amBridge = mesh.isBridge();
|
|
|
344
344
|
|
|
345
345
|
**Symptoms**: Bridge shows "Internet available: NO" or `hasInternet: false` despite router having Internet
|
|
346
346
|
|
|
347
|
-
**Cause**: Fixed in v1.8.5
|
|
347
|
+
**Cause**: Fixed progressively in v1.8.5+ and v1.8.7+.
|
|
348
|
+
|
|
349
|
+
**Historical Fixes**:
|
|
350
|
+
- **v1.8.5**: Added gateway IP check in addition to WiFi connection status
|
|
351
|
+
- **v1.8.7**: Improved gateway IP checking logic
|
|
352
|
+
- **v1.8.8+**: Changed to check local IP instead of gateway IP for better mobile hotspot compatibility
|
|
348
353
|
|
|
349
354
|
**Solutions**:
|
|
350
|
-
- Update to painlessMesh
|
|
351
|
-
- Bridge now checks
|
|
352
|
-
-
|
|
355
|
+
- Update to latest painlessMesh version
|
|
356
|
+
- Bridge now checks WiFi connection AND valid local IP address
|
|
357
|
+
- Works reliably with all network types including mobile hotspots and tethering
|
|
358
|
+
- Local IP check is more reliable than gateway IP, which may not be available on all network types
|
|
353
359
|
|
|
354
360
|
### Election Doesn't Start
|
|
355
361
|
|
package/library.json
CHANGED
package/library.properties
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name=Alteriom PainlessMesh
|
|
2
|
-
version=1.8.
|
|
2
|
+
version=1.8.9
|
|
3
3
|
author=Coopdis,Scotty Franzyshen,Edwin van Leeuwen,Germán Martín,Maximilian Schwarz,Doanh Doanh,Alteriom
|
|
4
4
|
maintainer=Alteriom
|
|
5
5
|
sentence=A painless way to setup a mesh with ESP8266 and ESP32 devices with Alteriom extensions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alteriom/painlessmesh",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.9",
|
|
4
4
|
"description": "painlessMesh is a user-friendly library for creating mesh networks with ESP8266 and ESP32 devices. This Alteriom fork includes additional packages for sensor data (SensorPackage), device commands (CommandPackage), and status monitoring (StatusPackage). It handles routing and network management automatically, so you can focus on your application. The library uses JSON-based messaging and syncs time across all nodes, making it ideal for coordinated behaviour like synchronized light displays or sensor networks reporting to a central node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arduino",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
/**
|
|
30
30
|
* @brief AlteriomPainlessMesh library version information
|
|
31
31
|
*/
|
|
32
|
-
#define ALTERIOM_PAINLESS_MESH_VERSION "1.8.
|
|
32
|
+
#define ALTERIOM_PAINLESS_MESH_VERSION "1.8.9"
|
|
33
33
|
#define ALTERIOM_PAINLESS_MESH_VERSION_MAJOR 1
|
|
34
34
|
#define ALTERIOM_PAINLESS_MESH_VERSION_MINOR 8
|
|
35
|
-
#define ALTERIOM_PAINLESS_MESH_VERSION_PATCH
|
|
35
|
+
#define ALTERIOM_PAINLESS_MESH_VERSION_PATCH 9
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* @brief Library description and usage information
|
package/src/arduino/wifi.hpp
CHANGED
|
@@ -752,6 +752,27 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
752
752
|
|
|
753
753
|
Log(STARTUP, "initBridgeStatusBroadcast(): Setting up bridge status broadcast\n");
|
|
754
754
|
|
|
755
|
+
// Register ourselves as a bridge in the knownBridges list
|
|
756
|
+
// This ensures the bridge knows about itself and reports correct status
|
|
757
|
+
this->addTask([this]() {
|
|
758
|
+
// Check Internet connectivity: WiFi connected AND valid IP address
|
|
759
|
+
bool hasInternet = (WiFi.status() == WL_CONNECTED) &&
|
|
760
|
+
(WiFi.localIP() != IPAddress(0, 0, 0, 0));
|
|
761
|
+
|
|
762
|
+
this->updateBridgeStatus(
|
|
763
|
+
this->nodeId, // bridgeNodeId
|
|
764
|
+
hasInternet, // internetConnected
|
|
765
|
+
WiFi.RSSI(), // routerRSSI
|
|
766
|
+
WiFi.channel(), // routerChannel
|
|
767
|
+
millis(), // uptime
|
|
768
|
+
WiFi.gatewayIP().toString(),// gatewayIP
|
|
769
|
+
this->getNodeTime() // timestamp
|
|
770
|
+
);
|
|
771
|
+
|
|
772
|
+
Log(STARTUP, "initBridgeStatusBroadcast(): Registered self as bridge (nodeId: %u)\n",
|
|
773
|
+
this->nodeId);
|
|
774
|
+
});
|
|
775
|
+
|
|
755
776
|
// Create periodic task to broadcast bridge status
|
|
756
777
|
bridgeStatusTask = this->addTask(
|
|
757
778
|
this->bridgeStatusIntervalMs,
|
|
@@ -791,6 +812,12 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
791
812
|
|
|
792
813
|
Log(STARTUP, "initBridgeCoordination(): Setting up multi-bridge coordination\n");
|
|
793
814
|
|
|
815
|
+
// Register our own priority in the bridgePriorities map
|
|
816
|
+
// This ensures getRecommendedBridge() with PRIORITY_BASED strategy works correctly
|
|
817
|
+
bridgePriorities[this->nodeId] = bridgePriority;
|
|
818
|
+
Log(STARTUP, "initBridgeCoordination(): Registered self priority (nodeId: %u, priority: %d)\n",
|
|
819
|
+
this->nodeId, bridgePriority);
|
|
820
|
+
|
|
794
821
|
// Register handler for incoming coordination messages (Type 613)
|
|
795
822
|
this->callbackList.onPackage(
|
|
796
823
|
613, // BRIDGE_COORDINATION type
|
|
@@ -881,6 +908,11 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
881
908
|
|
|
882
909
|
String msg;
|
|
883
910
|
serializeJson(doc, msg);
|
|
911
|
+
|
|
912
|
+
// Update our own priority in bridgePriorities map
|
|
913
|
+
// This ensures priority-based selection always has current data
|
|
914
|
+
bridgePriorities[this->nodeId] = bridgePriority;
|
|
915
|
+
|
|
884
916
|
this->sendBroadcast(msg);
|
|
885
917
|
|
|
886
918
|
Log(CONNECTION, "Bridge coordination sent: priority=%d, role=%s, load=%d%%\n",
|
|
@@ -1186,15 +1218,24 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
1186
1218
|
obj["routing"] = 2; // BROADCAST routing
|
|
1187
1219
|
obj["timestamp"] = this->getNodeTime();
|
|
1188
1220
|
|
|
1189
|
-
// Check Internet connectivity: WiFi connected AND valid
|
|
1221
|
+
// Check Internet connectivity: WiFi connected AND valid IP address
|
|
1222
|
+
// We check for valid local IP instead of gateway IP because:
|
|
1223
|
+
// 1. Gateway IP might not be immediately available after connection
|
|
1224
|
+
// 2. Some networks (mobile hotspots) may not provide gateway IP via DHCP
|
|
1225
|
+
// 3. Having a valid local IP + being connected is sufficient for internet access
|
|
1190
1226
|
bool hasInternet = (WiFi.status() == WL_CONNECTED) &&
|
|
1191
|
-
(WiFi.
|
|
1227
|
+
(WiFi.localIP() != IPAddress(0, 0, 0, 0));
|
|
1192
1228
|
obj["internetConnected"] = hasInternet;
|
|
1193
1229
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1230
|
+
int8_t rssi = WiFi.RSSI();
|
|
1231
|
+
uint8_t channel = WiFi.channel();
|
|
1232
|
+
uint32_t uptime = millis();
|
|
1233
|
+
TSTRING gatewayIP = WiFi.gatewayIP().toString();
|
|
1234
|
+
|
|
1235
|
+
obj["routerRSSI"] = rssi;
|
|
1236
|
+
obj["routerChannel"] = channel;
|
|
1237
|
+
obj["uptime"] = uptime;
|
|
1238
|
+
obj["gatewayIP"] = gatewayIP;
|
|
1198
1239
|
obj["message_type"] = 610;
|
|
1199
1240
|
|
|
1200
1241
|
String msg;
|
|
@@ -1202,6 +1243,13 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
1202
1243
|
|
|
1203
1244
|
Log(GENERAL, "sendBridgeStatus(): Broadcasting status (Internet: %s)\n",
|
|
1204
1245
|
hasInternet ? "Connected" : "Disconnected");
|
|
1246
|
+
Log(GENERAL, "sendBridgeStatus(): WiFi status=%d, localIP=%s, gatewayIP=%s\n",
|
|
1247
|
+
WiFi.status(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str());
|
|
1248
|
+
|
|
1249
|
+
// Update our own bridge status in knownBridges list
|
|
1250
|
+
// This ensures the bridge reports itself correctly when queried
|
|
1251
|
+
this->updateBridgeStatus(this->nodeId, hasInternet, rssi, channel,
|
|
1252
|
+
uptime, gatewayIP, this->getNodeTime());
|
|
1205
1253
|
|
|
1206
1254
|
this->sendBroadcast(msg);
|
|
1207
1255
|
}
|
package/src/painlessMesh.h
CHANGED