feat(companion-wifi): pin-derived recovery AP password with on-screen pin

Mirror the BLE pin rules on WiFi builds so the recovery AP always has a
knowable password: devices with a display get a random per-session pin
shown as Pin:NNNNNN on the home screen, headless devices default to
123456, and 'set pin' overrides both persistently. The AP password is
the active pin zero-padded to 8 digits (WPA2 minimum), so a fresh
device is never an open AP.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jared Dohrman
2026-08-09 16:56:24 +10:00
co-authored by Claude Fable 5
parent a5c9ba3e01
commit 4c8ddbd29f
2 changed files with 52 additions and 13 deletions
+20 -2
View File
@@ -1041,6 +1041,24 @@ void MyMesh::begin(bool has_display) {
} else {
_active_ble_pin = _prefs.ble_pin;
}
#elif defined(ESP32) && defined(WIFI_SSID)
// WiFi builds: the pin doubles as the recovery AP password (zero-padded to 8 digits),
// mirroring the BLE pin rules: shown on the display when there is one (random per
// session), static default 123456 on headless devices, 'set pin' overrides both.
if (_prefs.ble_pin == 0) {
#ifdef DISPLAY_CLASS
if (has_display) {
StdRNG rng;
_active_ble_pin = rng.nextInt(100000, 999999); // random pin each session
} else {
_active_ble_pin = 123456;
}
#else
_active_ble_pin = 123456;
#endif
} else {
_active_ble_pin = _prefs.ble_pin;
}
#else
_active_ble_pin = 0;
#endif
@@ -2370,8 +2388,8 @@ void MyMesh::startRecoveryAP() {
char ap_pwd[12];
const char* pwd = NULL;
if (_prefs.ble_pin != 0) { // WPA2 needs >= 8 chars, so zero-pad the pin
sprintf(ap_pwd, "%08lu", (unsigned long) _prefs.ble_pin);
if (_active_ble_pin != 0) { // WPA2 needs >= 8 chars, so zero-pad the pin
sprintf(ap_pwd, "%08lu", (unsigned long) _active_ble_pin);
pwd = ap_pwd;
}