# 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 ```mermaid 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** ```cpp 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** ```cpp WiFi.mode(WIFI_STA); WiFi.begin(ctx.config.wifi_ssid.c_str(), ctx.config.wifi_password.c_str()); ``` 4. **Hostname Generation** ```cpp 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** ```cpp 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** ```cpp 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 ```mermaid 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** ```cpp if (!request->hasParam("ssid", true) || !request->hasParam("password", true)) { request->send(400, "application/json", "{\"error\": \"Missing required parameters\"}"); return; } ``` 2. **Configuration Update** ```cpp 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** ```cpp bool configSaved = networkManager.saveConfig(); if (!configSaved) { LOG_WARN("NetworkService", "Failed to save WiFi configuration to persistent storage"); } ``` 4. **Restart Scheduling** ```cpp 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**: ```json { "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**: ```json { "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**: ```json { "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**: ```bash curl -X POST http://192.168.1.100/api/network/wifi/config \ -d "ssid=MyNewNetwork&password=newpassword&connect_timeout_ms=15000" ``` **Response**: ```json { "status": "success", "message": "WiFi configuration updated and saved", "config_saved": true, "restarting": true } ``` ## WiFi Scanning Process ### Scanning Implementation ```cpp 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 ```cpp 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 ```json { "error": "Missing required parameters", "status": "error" } ``` ```json { "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 ```bash # 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 ## Related Documentation - **[Configuration Management](./ConfigurationManagement.md)** - Persistent configuration system - **[API Reference](./API.md)** - Complete HTTP API documentation - **[Architecture Overview](./Architecture.md)** - System architecture and components - **[OpenAPI Specification](../api/)** - Machine-readable API specification