Files
spore/docs/WiFiConfiguration.md
2025-10-15 21:52:24 +02:00

12 KiB

SPORE WiFi Configuration Process

Overview

SPORE implements a WiFi configuration system that handles initial setup, runtime reconfiguration, and automatic fallback mechanisms. The system supports both Station (STA) and Access Point (AP) modes with seamless switching between them.

WiFi Configuration Architecture

Core Components

  • NetworkManager: Handles WiFi operations and configuration
  • NetworkService: Provides HTTP API endpoints for WiFi management
  • Config: Stores WiFi credentials and connection parameters
  • LittleFS: Persistent storage for WiFi configuration
  • ESP8266 WiFi Library: Low-level WiFi operations

Configuration Parameters

Parameter Type Default Description
wifi_ssid String "shroud" Network SSID for connection
wifi_password String "th3r31sn0sp00n" Network password
wifi_connect_timeout_ms uint32_t 15000 Connection timeout (15 seconds)
wifi_retry_delay_ms uint32_t 500 Delay between connection attempts

WiFi Configuration Lifecycle

1. Boot Process

graph TD
    A[System Boot] --> B[Initialize LittleFS]
    B --> C[Load Configuration]
    C --> D[Initialize WiFi Mode]
    D --> E[Set Hostname from MAC]
    E --> F[Attempt STA Connection]
    F --> G{Connection Successful?}
    G -->|Yes| H[STA Mode Active]
    G -->|No| I[Switch to AP Mode]
    I --> J[Create Access Point]
    J --> K[AP Mode Active]
    H --> L[Start UDP Services]
    K --> L
    L --> M[Initialize Node Context]
    M --> N[Start Cluster Services]

Detailed Boot Sequence:

  1. LittleFS Initialization

    if (!LittleFS.begin()) {
        LOG_WARN("Config", "Failed to initialize LittleFS, using defaults");
        setDefaults();
        return;
    }
    
  2. Configuration Loading

    • Load WiFi credentials from /config.json
    • Fall back to defaults if file doesn't exist
    • Validate configuration parameters
  3. WiFi Mode Initialization

    WiFi.mode(WIFI_STA);
    WiFi.begin(ctx.config.wifi_ssid.c_str(), ctx.config.wifi_password.c_str());
    
  4. Hostname Generation

    void NetworkManager::setHostnameFromMac() {
        uint8_t mac[6];
        WiFi.macAddress(mac);
        char buf[32];
        sprintf(buf, "esp-%02X%02X%02X%02X%02X%02X", 
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
        WiFi.hostname(buf);
        ctx.hostname = String(buf);
    }
    
  5. Connection Attempt

    unsigned long startAttemptTime = millis();
    while (WiFi.status() != WL_CONNECTED && 
           millis() - startAttemptTime < ctx.config.wifi_connect_timeout_ms) {
        delay(ctx.config.wifi_retry_delay_ms);
    }
    
  6. Fallback to AP Mode

    if (WiFi.status() != WL_CONNECTED) {
        LOG_WARN("WiFi", "Failed to connect to AP. Creating AP...");
        WiFi.mode(WIFI_AP);
        WiFi.softAP(ctx.config.wifi_ssid.c_str(), ctx.config.wifi_password.c_str());
    }
    

2. Runtime Reconfiguration

graph TD
    A[HTTP API Request] --> B[Validate Parameters]
    B --> C[Update Config Object]
    C --> D[Save to Persistent Storage]
    D --> E[Send Response to Client]
    E --> F[Schedule Node Restart]
    F --> G[Node Restarts]
    G --> H[Apply New Configuration]
    H --> I[Attempt New Connection]

Runtime Reconfiguration Process:

  1. API Request Validation

    if (!request->hasParam("ssid", true) || !request->hasParam("password", true)) {
        request->send(400, "application/json", "{\"error\": \"Missing required parameters\"}");
        return;
    }
    
  2. Configuration Update

    void NetworkManager::setWiFiConfig(const String& ssid, const String& password,
                                       uint32_t connect_timeout_ms, uint32_t retry_delay_ms) {
        ctx.config.wifi_ssid = ssid;
        ctx.config.wifi_password = password;
        ctx.config.wifi_connect_timeout_ms = connect_timeout_ms;
        ctx.config.wifi_retry_delay_ms = retry_delay_ms;
    }
    
  3. Persistent Storage

    bool configSaved = networkManager.saveConfig();
    if (!configSaved) {
        LOG_WARN("NetworkService", "Failed to save WiFi configuration to persistent storage");
    }
    
  4. Restart Scheduling

    request->onDisconnect([this]() {
        LOG_INFO("NetworkService", "Restarting node to apply WiFi configuration...");
        delay(100); // Give time for response to be sent
        networkManager.restartNode();
    });
    

WiFi Modes

Station Mode (STA)

Purpose: Connect to existing WiFi network as a client

Configuration:

  • SSID and password required
  • Automatic IP assignment via DHCP
  • Hostname set from MAC address
  • UDP services on configured port

Connection Process:

  1. Set WiFi mode to STA
  2. Begin connection with credentials
  3. Wait for connection with timeout
  4. Set hostname and start services

Access Point Mode (AP)

Purpose: Create WiFi hotspot when STA connection fails

Configuration:

  • Uses configured SSID/password for AP
  • Fixed IP address (usually 192.168.4.1)
  • Allows other devices to connect
  • Maintains cluster functionality

AP Creation Process:

  1. Switch WiFi mode to AP
  2. Create soft access point
  3. Set AP IP address
  4. Start services on AP IP

HTTP API Endpoints

Network Status

GET /api/network/status

Returns comprehensive WiFi and network status information.

Response Fields:

{
  "wifi": {
    "connected": true,
    "mode": "STA",
    "ssid": "MyNetwork",
    "ip": "192.168.1.100",
    "mac": "AA:BB:CC:DD:EE:FF",
    "hostname": "esp-AABBCCDDEEFF",
    "rssi": -45,
    "ap_ip": "192.168.4.1",
    "ap_mac": "AA:BB:CC:DD:EE:FF",
    "stations_connected": 0
  }
}

WiFi Scanning

GET /api/network/wifi/scan

Returns list of available WiFi networks from last scan.

Response Fields:

{
  "access_points": [
    {
      "ssid": "MyNetwork",
      "rssi": -45,
      "channel": 6,
      "encryption_type": 4,
      "hidden": false,
      "bssid": "AA:BB:CC:DD:EE:FF"
    }
  ]
}

POST /api/network/wifi/scan

Initiates a new WiFi network scan.

Response:

{
  "status": "scanning",
  "message": "WiFi scan started"
}

WiFi Configuration

POST /api/network/wifi/config

Configures WiFi connection with new credentials.

Parameters:

  • ssid (required): Network SSID
  • password (required): Network password
  • connect_timeout_ms (optional): Connection timeout (default: 10000)
  • retry_delay_ms (optional): Retry delay (default: 500)

Request Example:

curl -X POST http://192.168.1.100/api/network/wifi/config \
  -d "ssid=MyNewNetwork&password=newpassword&connect_timeout_ms=15000"

Response:

{
  "status": "success",
  "message": "WiFi configuration updated and saved",
  "config_saved": true,
  "restarting": true
}

WiFi Scanning Process

Scanning Implementation

void NetworkManager::scanWifi() {
    if (!isScanning) {
        isScanning = true;
        LOG_INFO("WiFi", "Starting WiFi scan...");
        WiFi.scanNetworksAsync([this](int networksFound) {
            LOG_INFO("WiFi", "Scan completed, found " + String(networksFound) + " networks");
            this->processAccessPoints();
            this->isScanning = false;
        }, true);
    }
}

Access Point Processing

void NetworkManager::processAccessPoints() {
    int numNetworks = WiFi.scanComplete();
    if (numNetworks <= 0) return;

    accessPoints.clear();
    for (int i = 0; i < numNetworks; i++) {
        AccessPoint ap;
        ap.ssid = WiFi.SSID(i);
        ap.rssi = WiFi.RSSI(i);
        ap.encryptionType = WiFi.encryptionType(i);
        ap.channel = WiFi.channel(i);
        ap.isHidden = ap.ssid.length() == 0;
        
        uint8_t* newBssid = new uint8_t[6];
        memcpy(newBssid, WiFi.BSSID(i), 6);
        ap.bssid = newBssid;

        accessPoints.push_back(ap);
    }
    WiFi.scanDelete();
}

Error Handling

Connection Failures

Error Type Handling Recovery
Invalid Credentials Log error, switch to AP mode Manual reconfiguration via API
Network Unavailable Log warning, switch to AP mode Automatic retry on next boot
Timeout Log timeout, switch to AP mode Increase timeout or check network
Hardware Failure Log error, continue in AP mode Hardware replacement required

API Error Responses

{
  "error": "Missing required parameters",
  "status": "error"
}
{
  "error": "Failed to save configuration",
  "status": "error",
  "config_saved": false
}

Security Considerations

Current Implementation

  • Plain Text Storage: WiFi passwords stored unencrypted
  • Local Network Only: No internet exposure
  • No Authentication: API access without authentication
  • MAC-based Hostnames: Predictable hostname generation

Security Best Practices

  1. Network Isolation: Keep SPORE devices on isolated network
  2. Strong Passwords: Use complex WiFi passwords
  3. Regular Updates: Keep firmware updated
  4. Access Control: Implement network-level access control

Future Security Enhancements

  • Password Encryption: Encrypt stored WiFi credentials
  • API Authentication: Add authentication to configuration API
  • Certificate-based Security: Implement TLS/SSL
  • Access Control Lists: Role-based configuration access

Troubleshooting

Common Issues

  1. WiFi Connection Fails

    • Check SSID and password
    • Verify network availability
    • Check signal strength
    • Increase connection timeout
  2. Configuration Not Persisting

    • Check LittleFS initialization
    • Verify file write permissions
    • Monitor available flash space
  3. AP Mode Not Working

    • Check AP credentials
    • Verify IP address assignment
    • Check for IP conflicts
  4. Scan Not Finding Networks

    • Wait for scan completion
    • Check WiFi hardware
    • Verify scan permissions

Debug Commands

# Check WiFi status
curl -s http://192.168.1.100/api/network/status | jq '.wifi'

# Scan for networks
curl -X POST http://192.168.1.100/api/network/wifi/scan

# View scan results
curl -s http://192.168.1.100/api/network/wifi/scan | jq '.'

# Test configuration
curl -X POST http://192.168.1.100/api/network/wifi/config \
  -d "ssid=TestNetwork&password=testpass"

Log Analysis

Successful Connection:

[INFO] WiFi: Connected to AP, IP: 192.168.1.100
[INFO] WiFi: Hostname set to: esp-AABBCCDDEEFF
[INFO] WiFi: UDP listening on port 4210

Connection Failure:

[WARN] WiFi: Failed to connect to AP. Creating AP...
[INFO] WiFi: AP created, IP: 192.168.4.1

Configuration Update:

[INFO] NetworkService: Restarting node to apply WiFi configuration...
[INFO] WiFi: Connecting to AP...

Performance Considerations

Connection Time

  • STA Connection: 5-15 seconds typical
  • AP Creation: 1-3 seconds
  • Scan Duration: 5-10 seconds
  • Configuration Save: 100-500ms

Memory Usage

  • WiFi Stack: ~20-30KB RAM
  • Scan Results: ~1KB per network
  • Configuration: ~200 bytes
  • API Buffers: ~2-4KB

Network Overhead

  • Scan Packets: Minimal impact
  • Configuration API: ~500 bytes per request
  • Status Updates: ~200 bytes per response

Best Practices

Configuration Management

  1. Use Strong Passwords: Implement password complexity requirements
  2. Set Appropriate Timeouts: Balance connection speed vs reliability
  3. Monitor Connection Quality: Track RSSI and connection stability
  4. Implement Retry Logic: Handle temporary network issues
  5. Log Configuration Changes: Audit trail for troubleshooting

Development Guidelines

  1. Handle All Error Cases: Implement comprehensive error handling
  2. Provide Clear Feedback: Inform users of connection status
  3. Optimize Scan Frequency: Balance discovery vs performance
  4. Test Fallback Scenarios: Ensure AP mode works correctly
  5. Document Configuration Options: Clear parameter documentation