SHARED_GATEWAY_IMPLEMENTATION_PLAN - Alteriom/painlessMesh GitHub Wiki
Shared Gateway Mode - Implementation Plan
Status: Ready for Implementation
Parent Design: SHARED_GATEWAY_DESIGN.md
Estimated Total Effort: 8-13 weeks
Date: November 2025
Overview
This document breaks down the Shared Gateway Mode feature into discrete, implementable GitHub issues. Each phase is designed to be independently testable and deliverable.
Issue Breakdown
Phase 1: Core Shared Gateway Initialization
Issue #1: Add SharedGatewayConfig Structure
- Priority: High
- Estimated Effort: 2-3 days
- Files to Create/Modify:
src/painlessmesh/gateway.hpp(NEW)src/painlessmesh/configuration.hpp(MODIFY)
Tasks:
- Create
SharedGatewayConfigstruct with all configuration fields:struct SharedGatewayConfig { bool enabled = false; TSTRING routerSSID = ""; TSTRING routerPassword = ""; uint32_t internetCheckInterval = 30000; TSTRING internetCheckHost = "8.8.8.8"; uint16_t internetCheckPort = 53; uint32_t internetCheckTimeout = 5000; uint8_t messageRetryCount = 3; uint32_t retryInterval = 1000; uint32_t duplicateTrackingTimeout = 60000; uint16_t maxTrackedMessages = 500; uint32_t gatewayHeartbeatInterval = 15000; uint32_t gatewayFailureTimeout = 45000; bool participateInElection = true; uint8_t relayedMessagePriority = 0; // CRITICAL bool maintainPermanentConnection = true; }; - Add validation methods for configuration
- Add unit tests for configuration validation
Acceptance Criteria:
- SharedGatewayConfig compiles on ESP8266 and ESP32
- Unit tests pass for all configuration scenarios
- Memory footprint documented
Issue #2: Implement initAsSharedGateway() Method
- Priority: High
- Estimated Effort: 1 week
- Dependencies: Issue #1
- Files to Create/Modify:
src/painlessMesh.h(MODIFY)src/arduino/wifi.hpp(MODIFY)src/painlessMeshSTA.cpp(MODIFY)
Tasks:
- Add
initAsSharedGateway()method signature topainlessMeshclass - Configure WiFi in AP+STA mode for all nodes
- Connect to router while maintaining mesh AP
- Ensure mesh and router operate on same channel
- Add router connection monitoring
- Add reconnection logic for router disconnects
Implementation Details:
bool initAsSharedGateway(
String meshPrefix,
String meshPassword,
String routerSSID,
String routerPassword,
Scheduler* userScheduler,
uint16_t port = 5555,
SharedGatewayConfig config = SharedGatewayConfig()
);
Acceptance Criteria:
- All nodes can connect to router and mesh simultaneously
- Mesh communication works between nodes
- Router connection is maintained
- Automatic reconnection on router disconnect
- Works on both ESP8266 and ESP32
Issue #3: Create Shared Gateway Example
- Priority: Medium
- Estimated Effort: 2-3 days
- Dependencies: Issue #2
- Files to Create:
examples/sharedGateway/sharedGateway.ino(NEW)examples/sharedGateway/README.md(NEW)examples/sharedGateway/platformio.ini(NEW)
Tasks:
- Create basic example demonstrating shared gateway mode
- Document configuration options
- Add serial output for debugging
- Include comments explaining each step
Acceptance Criteria:
- Example compiles and runs on ESP32
- Example compiles and runs on ESP8266
- README explains setup and usage
- All nodes connect to router and mesh
Phase 2: Internet Connectivity Monitoring
Issue #4: Implement Internet Health Check
- Priority: High
- Estimated Effort: 3-4 days
- Dependencies: Issue #2
- Files to Create/Modify:
src/painlessmesh/gateway.hpp(MODIFY)src/painlessmesh/mesh.hpp(MODIFY)
Tasks:
- Implement TCP connection test to configurable host/port
- Add periodic health check task
- Track local Internet connectivity status
- Add
hasLocalInternet()method - Fire callback on connectivity change
Implementation Details:
// Check if THIS node has direct Internet access
bool hasLocalInternet();
// Callback when local Internet status changes
void onLocalInternetChanged(std::function<void(bool available)> callback);
// Get last Internet check result
InternetStatus getInternetStatus();
Acceptance Criteria:
- Health check detects Internet availability
- Callback fires on connectivity change
- Works with configurable check interval
- Minimal memory overhead
- Does not block mesh operations
Issue #5: Add Internet Status Broadcasting
- Priority: Medium
- Estimated Effort: 2-3 days
- Dependencies: Issue #4
- Files to Modify:
src/painlessmesh/gateway.hpp(MODIFY)src/painlessmesh/protocol.hpp(MODIFY)
Tasks:
- Broadcast Internet status to mesh periodically
- Track which nodes have Internet access
- Update known gateway list based on broadcasts
- Add
getNodesWithInternet()method
Acceptance Criteria:
- All nodes know which peers have Internet
- Status updates propagate within 30 seconds
- Memory efficient tracking (max 20 nodes)
Phase 3: Failover Routing Through Mesh
Issue #6: Implement GatewayDataPackage
- Priority: High
- Estimated Effort: 3-4 days
- Dependencies: Issue #5
- Files to Create/Modify:
src/painlessmesh/gateway.hpp(MODIFY)src/painlessmesh/protocol.hpp(MODIFY)
Tasks:
- Define
GatewayDataPackage(Type ID 620) - Implement serialization/deserialization
- Add message ID generation (unique per node)
- Include origin node, timestamp, payload fields
- Add unit tests for package serialization
Package Structure:
class GatewayDataPackage : public SinglePackage {
public:
uint32_t messageId; // Unique message ID
uint32_t originNode; // Node that created message
uint32_t timestamp; // Creation timestamp
uint8_t priority; // 0=CRITICAL to 3=LOW
TSTRING destination; // URL/endpoint
TSTRING payload; // Application data
TSTRING contentType; // MIME type
uint8_t retryCount; // Relay attempts
bool requiresAck; // Send acknowledgment?
};
Acceptance Criteria:
- Package serializes/deserializes correctly
- Message IDs are unique per node
- Unit tests pass
- Works with ArduinoJson v6 and v7
Issue #7: Implement GatewayAckPackage
- Priority: High
- Estimated Effort: 2 days
- Dependencies: Issue #6
- Files to Modify:
src/painlessmesh/gateway.hpp(MODIFY)src/painlessmesh/protocol.hpp(MODIFY)
Tasks:
- Define
GatewayAckPackage(Type ID 621) - Include success status, HTTP code, error message
- Route acknowledgment back to origin node
- Add unit tests
Acceptance Criteria:
- Ack packages route back to origin
- Contains delivery status information
- Unit tests pass
Issue #8: Implement sendToInternet() API
- Priority: High
- Estimated Effort: 1 week
- Dependencies: Issues #6, #7
- Files to Modify:
src/painlessmesh/mesh.hpp(MODIFY)src/painlessmesh/gateway.hpp(MODIFY)
Tasks:
- Add
sendToInternet()method - Try local Internet first
- On failure, route through mesh to gateway
- Track pending messages for acknowledgment
- Call user callback with result
- Implement retry logic
API:
uint32_t sendToInternet(
String destination,
String payload,
std::function<void(bool success, uint16_t httpStatus, String error)> callback,
uint8_t priority = PRIORITY_CRITICAL
);
Acceptance Criteria:
- Sends via local Internet when available
- Falls back to mesh routing when unavailable
- Callback receives delivery confirmation
- Supports configurable priority
- Works on ESP8266 and ESP32
Issue #9: Implement Gateway Message Handler
- Priority: High
- Estimated Effort: 3-4 days
- Dependencies: Issue #8
- Files to Modify:
src/painlessmesh/gateway.hpp(MODIFY)src/painlessmesh/mesh.hpp(MODIFY)
Tasks:
- Add handler for incoming
GatewayDataPackage - Extract payload and forward to Internet
- Send
GatewayAckPackageback to origin - Add user callback for custom handling
Acceptance Criteria:
- Gateway receives and processes relayed messages
- Sends to Internet on behalf of origin node
- Returns acknowledgment with status
- User can override default handling
Phase 4: Duplicate Prevention and Acknowledgment
Issue #10: Implement MessageTracker Class
- Priority: High
- Estimated Effort: 3-4 days
- Dependencies: None (can start parallel)
- Files to Create:
src/painlessmesh/message_tracker.hpp(NEW)
Tasks:
- Create
MessageTrackerclass - Track processed message IDs with timestamps
- Implement cleanup of expired entries
- Add memory-efficient storage (configurable max)
- Thread-safe operations for ESP32
Implementation:
class MessageTracker {
public:
MessageTracker(uint16_t maxMessages = 500, uint32_t timeoutMs = 60000);
bool isProcessed(uint32_t messageId, uint32_t originNode);
void markProcessed(uint32_t messageId, uint32_t originNode);
void markAcknowledged(uint32_t messageId, uint32_t originNode);
void cleanup();
size_t size() const;
};
Acceptance Criteria:
- Prevents duplicate message processing
- Automatic cleanup of old entries
- Memory usage within limits
- Unit tests for all scenarios
- Works on ESP8266 (limited RAM)
Issue #11: Integrate Duplicate Prevention
- Priority: High
- Estimated Effort: 2-3 days
- Dependencies: Issues #9, #10
- Files to Modify:
src/painlessmesh/gateway.hpp(MODIFY)
Tasks:
- Check incoming messages against tracker
- Skip already-processed messages
- Track sent acknowledgments
- Add metrics for duplicate detection
Acceptance Criteria:
- Duplicate messages are dropped
- Single acknowledgment per message
- Metrics available for monitoring
Phase 5: Gateway Election and Failover
Issue #12: Implement GatewayHeartbeatPackage
- Priority: High
- Estimated Effort: 2 days
- Dependencies: Issue #5
- Files to Modify:
src/painlessmesh/gateway.hpp(MODIFY)src/painlessmesh/protocol.hpp(MODIFY)
Tasks:
- Define
GatewayHeartbeatPackage(Type ID 622) - Include primary status, Internet availability, RSSI
- Broadcast periodically from primary gateway
- Track heartbeats from all gateways
Acceptance Criteria:
- Primary gateway broadcasts heartbeats
- All nodes track gateway health
- Heartbeat contains election-relevant data
Issue #13: Implement Gateway Election Protocol
- Priority: High
- Estimated Effort: 1 week
- Dependencies: Issue #12
- Files to Modify:
src/painlessmesh/gateway.hpp(MODIFY)
Tasks:
- Detect when primary gateway fails (missed heartbeats)
- Trigger election among nodes with Internet
- Use deterministic algorithm (RSSI, then node ID)
- Handle split-brain scenarios
- Announce new primary to mesh
Election Algorithm:
- Wait for
gatewayFailureTimeoutwithout heartbeat - Each eligible node calculates its score (RSSI)
- Highest RSSI wins; node ID breaks ties
- Winner announces primary status
- Other nodes defer to announced primary
Acceptance Criteria:
- Election triggers on primary failure
- Deterministic winner selection
- New primary starts heartbeats
- Smooth transition without message loss
Issue #14: Implement isPrimaryGateway() and Related APIs
- Priority: Medium
- Estimated Effort: 2 days
- Dependencies: Issue #13
- Files to Modify:
src/painlessmesh/mesh.hpp(MODIFY)
Tasks:
- Add
isPrimaryGateway()method - Add
getPrimaryGateway()method - Add
onGatewayChanged()callback - Add
getGateways()for all known gateways
Acceptance Criteria:
- APIs return correct gateway status
- Callback fires on gateway change
- Documentation updated
Phase 6: Documentation and Examples
Issue #15: Update API Documentation
- Priority: Medium
- Estimated Effort: 2-3 days
- Dependencies: All implementation issues
- Files to Modify:
docs/api/shared-gateway.md(NEW)README.md(MODIFY)- API documentation files
Tasks:
- Document all new methods
- Add usage examples
- Document configuration options
- Add troubleshooting guide
Acceptance Criteria:
- All new APIs documented
- Examples are working and tested
- Doxygen comments complete
Issue #16: Create Advanced Example with HTTP Client
- Priority: Medium
- Estimated Effort: 3-4 days
- Dependencies: Issue #9
- Files to Create:
examples/sharedGatewayHTTP/sharedGatewayHTTP.ino(NEW)examples/sharedGatewayHTTP/README.md(NEW)
Tasks:
- Create example with actual HTTP client
- Demonstrate failover behavior
- Show acknowledgment handling
- Include status monitoring
Acceptance Criteria:
- Example sends real HTTP requests
- Demonstrates mesh failover
- Works on ESP32 with WiFiClientSecure
Implementation Order
Sprint 1 (Weeks 1-2): Foundation
- Issue #1: SharedGatewayConfig Structure
- Issue #2: initAsSharedGateway() Method
- Issue #10: MessageTracker Class (parallel)
Sprint 2 (Weeks 3-4): Connectivity
- Issue #3: Basic Example
- Issue #4: Internet Health Check
- Issue #5: Internet Status Broadcasting
Sprint 3 (Weeks 5-7): Core Messaging
- Issue #6: GatewayDataPackage
- Issue #7: GatewayAckPackage
- Issue #8: sendToInternet() API
- Issue #9: Gateway Message Handler
Sprint 4 (Weeks 8-9): Reliability
- Issue #11: Duplicate Prevention Integration
- Issue #12: GatewayHeartbeatPackage
Sprint 5 (Weeks 10-12): Election & Polish
- Issue #13: Gateway Election Protocol
- Issue #14: Gateway Status APIs
- Issue #15: Documentation
- Issue #16: Advanced Example
Testing Requirements
Unit Tests (per issue)
- Configuration validation
- Package serialization/deserialization
- Message tracker operations
- Election algorithm
Integration Tests
- Multi-node mesh with shared gateway
- Failover scenarios
- Duplicate prevention
- Election convergence
Hardware Tests
- ESP8266 memory limits
- ESP32 multi-threading
- Real Internet connectivity
- Long-running stability
Risk Mitigation
| Risk | Mitigation |
|---|---|
| Memory overflow on ESP8266 | Configurable limits, aggressive cleanup |
| Channel conflicts | Use router channel detection |
| Election race conditions | Deterministic algorithm, random delays |
| Message loss during failover | Acknowledgment system, retry logic |
Success Metrics
- All 16 issues completed and tested
- Works on ESP8266 with <10KB overhead
- Works on ESP32 with <30KB overhead
- Failover time <5 seconds
- Zero duplicate messages delivered
- 95%+ message delivery rate
Related Documents
- SHARED_GATEWAY_DESIGN.md - Feature design document
- BRIDGE_FAILOVER.md - Existing failover documentation