ESP32 Firmware
Build, flash, provision, and maintain the WakeLink firmware that bridges encrypted relay traffic to local Wake-on-LAN packets.
The firmware supports both browser-based AP provisioning and a JSON provisioning API used by the Android setup wizard.
Hardware Requirements
| Item | Details |
|---|---|
MCU | ESP32 (tested on ESP32-WROOM-32) |
Flash | 4 MB recommended |
Wi-Fi | 2.4 GHz 802.11 b/g/n |
Status LED | GPIO2 by default |
Build
# Arduino CLI
arduino-cli core install esp32:esp32
arduino-cli lib install "ArduinoJson" "WebSockets" "ArduinoHttpClient"
arduino-cli compile --fqbn esp32:esp32:esp32 WakeLink/
# PlatformIO
pio run -e esp32dev
pio run -e esp32dev --target upload
pio device monitor --baud 115200Provisioning
On first boot, the device starts an AP named WakeLink-Setup. The AP password is
an 8-character random string stored in NVS and printed to the serial console on
first boot.
Browser portal
Open http://192.168.4.1 and fill in:
| Field | Description |
|---|---|
wifi_ssid | Your Wi-Fi network name |
wifi_pass | Wi-Fi password |
server_host | WakeLink relay hostname |
server_port | Usually 443 |
tls_enabled | Enable WSS/TLS |
agent_id | Registered agent identifier |
agent_token | EWSP shared secret |
api_token | Relay API token used for the WebSocket auth step |
JSON API
The Android wizard authenticates to the AP JSON API with the AP password and then sends the same fields programmatically.
{
"wifi_ssid": "MyNetwork",
"wifi_pass": "secret",
"server_host": "wakelink-project.org",
"server_port": 443,
"tls_enabled": true,
"agent_id": "esp32-living-room",
"agent_token": "your-ewsp-secret",
"api_token": "wld_your_device_relay_token"
}Local Interfaces
| Interface | Details |
|---|---|
TCP command port | Port 7625 for direct LAN EWSP commands |
Status HTTP endpoint | GET /api/info for discovery and health checks |
Provisioning portal | http://192.168.4.1 while AP mode is active |
Local WebSocket server | Port 81 for LAN EWSP sessions when enabled |
Supported Commands
| Command | Description |
|---|---|
ping | Round-trip latency test |
info | Return firmware version, uptime, and identifiers |
status | Return Wi-Fi RSSI, heap, and connection state |
wake | Send a Wake-on-LAN magic packet |
reboot | Restart the ESP32 |
ota | Download and flash a new firmware image |
update_token | Replace the stored per-device relay token used for WebSocket auth |
OTA Signing
Production OTA images are verified with an Ed25519 public key baked into the firmware.
pip install pynacl
python3 scripts/sign_ota.py --gen-key ota_private.key
python3 scripts/sign_ota.py --key ota_private.key --bin WakeLink/.pio/build/esp32/firmware.binUse -DWAKELINK_OTA_PUBKEY_HEX=... to embed the matching public key. Developer
builds can bypass signature checks with -DWAKELINK_OTA_ALLOW_UNSIGNED=1, but
that should never be enabled in production.
Source Layout
| File / Directory | Purpose |
|---|---|
WakeLink.ino | Firmware entry point |
config.* | Persistent configuration and NVS helpers |
provisioning.* | AP portal and JSON provisioning API |
cloud.* | Relay WebSocket client and reconnect logic |
commands.* | EWSP command handlers |
ota_manager.* | OTA download and verification |
ws_server.* | Local WebSocket server |
web_server.* | Status and provisioning HTTP endpoints |