ESP32 Firmware

Build, flash, provision, and maintain the WakeLink firmware that bridges encrypted relay traffic to local Wake-on-LAN packets.

💡Tip

The firmware supports both browser-based AP provisioning and a JSON provisioning API used by the Android setup wizard.

Hardware Requirements

ItemDetails
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

bash
# 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 115200

Provisioning

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:

FieldDescription
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.

json
{
"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

InterfaceDetails
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

CommandDescription
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.

bash
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.bin

Use -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 / DirectoryPurpose
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

Continue reading