diff --git a/src/helpers/NetworkPrefs.cpp b/src/helpers/NetworkPrefs.cpp index 02f0f295..f48a48e9 100644 --- a/src/helpers/NetworkPrefs.cpp +++ b/src/helpers/NetworkPrefs.cpp @@ -56,15 +56,39 @@ bool loadLegacyWebWifiPrefs(FILESYSTEM* fs, NetworkPrefs& prefs) { } #if defined(ESP_PLATFORM) +// Upper bound on the stored blob we are willing to read. NetworkPrefs only ever +// grows by APPENDING fields (see NetworkPrefs.h), so this just needs headroom +// above the current struct size to guard against corruption. +static constexpr size_t kNetworkPrefsMaxBlob = 1024; + bool loadNvsNetworkPrefs(NetworkPrefs& prefs) { + static_assert(sizeof(NetworkPrefs) <= kNetworkPrefsMaxBlob, + "NetworkPrefs grew past kNetworkPrefsMaxBlob"); Preferences nvs; if (!nvs.begin("eastmesh-net", true)) { return false; } - NetworkPrefs stored{}; - const size_t read = nvs.getBytes("prefs", &stored, sizeof(stored)); + // Tolerate the struct having grown or shrunk between firmware versions instead + // of rejecting on an exact size match (which silently wiped WiFi creds across + // any layout change). Read whatever blob is stored, then copy the overlapping + // prefix into a zero-initialised struct: appended fields stay zero (and get + // defaulted by the caller), trailing bytes from a newer layout are ignored. + const size_t blob_len = nvs.getBytesLength("prefs"); + if (blob_len < sizeof(prefs.magic) || blob_len > kNetworkPrefsMaxBlob) { + nvs.end(); + return false; + } + uint8_t buf[kNetworkPrefsMaxBlob]; + memset(buf, 0, sizeof(buf)); + const size_t read = nvs.getBytes("prefs", buf, blob_len); nvs.end(); - if (read != sizeof(stored) || stored.magic != NetworkPrefsStore::magicValue()) { + if (read != blob_len) { + return false; + } + NetworkPrefs stored{}; + const size_t copy_len = blob_len < sizeof(stored) ? blob_len : sizeof(stored); + memcpy(&stored, buf, copy_len); + if (stored.magic != NetworkPrefsStore::magicValue()) { return false; } prefs = stored; diff --git a/src/helpers/NetworkPrefs.h b/src/helpers/NetworkPrefs.h index 9aaeefac..0b81e977 100644 --- a/src/helpers/NetworkPrefs.h +++ b/src/helpers/NetworkPrefs.h @@ -3,6 +3,11 @@ #include #include +// IMPORTANT: persisted to NVS and LittleFS as a raw byte blob. To keep saved +// WiFi credentials across firmware updates, ONLY ever APPEND new fields to the +// end of this struct, and never reorder, resize, or remove existing fields or +// change `magic`. The loaders copy the overlapping prefix, so appended fields +// load as zero on older saves and are then filled in by the *Defaults helpers. struct NetworkPrefs { uint32_t magic; uint8_t wifi_powersave; diff --git a/variants/lilygo_tbeam_1w/platformio.ini b/variants/lilygo_tbeam_1w/platformio.ini index 17dcda9a..11be2726 100644 --- a/variants/lilygo_tbeam_1w/platformio.ini +++ b/variants/lilygo_tbeam_1w/platformio.ini @@ -28,7 +28,7 @@ build_flags = -D SX126X_REGISTER_PATCH=1 -D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_RXEN=21 - -D SX126X_DIO3_TCXO_VOLTAGE=3.0 + -D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_CURRENT_LIMIT=140 -D SX126X_RX_BOOSTED_GAIN=1 diff --git a/variants/lilygo_tbeam_1w/variant.h b/variants/lilygo_tbeam_1w/variant.h index f6807e56..c05b1696 100644 --- a/variants/lilygo_tbeam_1w/variant.h +++ b/variants/lilygo_tbeam_1w/variant.h @@ -62,7 +62,7 @@ #define SX126X_RXEN 21 // LNA enable - HIGH during RX // TCXO voltage - required for radio init -#define SX126X_DIO3_TCXO_VOLTAGE 3.0 +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define SX126X_MAX_POWER 22 #endif