mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-01 10:21:59 +00:00
fix: settings and lists lost to a restart mid-save on ESP32, LR1121 boards, repeater/room sims
- A restart between commitTempFile()'s remove and rename left only the .tmp; loads now recover it (prefs, contacts, channels, scopes). - CustomLR1121Wrapper lacked readLiveRSSI/readLiveSNR: LR1121 boards didn't compile. - The repeater and room server sims gain DynamicConfigSerializer.cpp and CommonRadioPrefs.cpp (broken since the v1.18 merge). - Comments still describing the removed DualSerialInterface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ protected:
|
||||
}
|
||||
|
||||
// hasConnection() means "a BLE companion app is connected". Not isConnected()
|
||||
// (a dual interface hardcodes that true as a USB send-fallback). Drives the BT
|
||||
// (true whenever the build has a USB serial port). Drives the BT
|
||||
// status indicator, pairing PIN, and the GPX-export collision warning — all
|
||||
// BLE-specific. The Auto buzzer mute / message-wake use isClientConnected()
|
||||
// (BLE *or* an open USB port) directly instead. Each UI calls this at the top
|
||||
@@ -86,9 +86,9 @@ public:
|
||||
}
|
||||
bool hasConnection() const { return _connected; }
|
||||
virtual void onBLEDisconnected() {}
|
||||
// True only when a BLE central is actually bonded/connected. On a dual
|
||||
// (BLE+USB) interface hasConnection() is always true (USB counts), so use
|
||||
// this for BLE-specific UI like the pairing-PIN prompt.
|
||||
// True only when a BLE central is actually bonded/connected, right now
|
||||
// (hasConnection() is the same, as of the last pollConnection()). For
|
||||
// BLE-specific UI like the pairing-PIN prompt.
|
||||
bool isBLEConnected() const { return _serial->isBLEConnected(); }
|
||||
// True when a companion app is connected over any transport (BLE bonded or an
|
||||
// open USB-CDC port). For app-connected behaviour like Auto buzzer mute.
|
||||
|
||||
@@ -60,6 +60,15 @@ static bool commitTempFile(FILESYSTEM* fs, const char* tmp, const char* final_pa
|
||||
#endif
|
||||
}
|
||||
|
||||
// Before a load: a restart between commitTempFile()'s remove and rename leaves
|
||||
// only the temp file, complete. (A save cut short leaves the old file beside
|
||||
// it, and the next save overwrites the temp. Only the very first save, cut
|
||||
// short, leaves a temp alone that is incomplete: the loaders stop at a short
|
||||
// record, and the JSON reader keeps what it read.)
|
||||
static void recoverTempFile(FILESYSTEM* fs, const char* tmp, const char* final_path) {
|
||||
if (!fs->exists(final_path) && fs->exists(tmp)) fs->rename(tmp, final_path);
|
||||
}
|
||||
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
static uint32_t _ContactsChannelsTotalBlocks = 0;
|
||||
#endif
|
||||
@@ -441,6 +450,7 @@ static void removeStrayDir(FILESYSTEM* fs, const char* path) {
|
||||
void DataStore::loadPrefs(NodePrefs& prefs, double& node_lat, double& node_lon) {
|
||||
removeStrayDir(_fs, "/prefs");
|
||||
if (_fs->exists("/prefs")) _fs->remove("/prefs"); // 2.0-rc's binary settings: 2.0 starts from the defaults
|
||||
recoverTempFile(_fs, "/prefs.tmp", "/prefs.json");
|
||||
File file = openRead(_fs, "/prefs.json");
|
||||
if (file) {
|
||||
BufferedFile in(file);
|
||||
@@ -536,6 +546,7 @@ void DataStore::restoreRTCTime() {
|
||||
}
|
||||
|
||||
void DataStore::loadContacts(DataStoreHost* host) {
|
||||
recoverTempFile(_getContactsChannelsFS(), "/contacts3.tmp", "/contacts3");
|
||||
File file = openRead(_getContactsChannelsFS(), "/contacts3");
|
||||
if (file) {
|
||||
bool full = false;
|
||||
@@ -614,6 +625,7 @@ void DataStore::saveContacts(DataStoreHost* host, bool (*filter)(const ContactIn
|
||||
|
||||
bool DataStore::loadChannels(DataStoreHost* host) {
|
||||
FILESYSTEM* fs = _getContactsChannelsFS();
|
||||
recoverTempFile(fs, "/channels3.tmp", "/channels3");
|
||||
File file = openRead(fs, "/channels3");
|
||||
if (file) {
|
||||
// /channels3: the leading 4-byte field's first byte is the channel's
|
||||
@@ -735,6 +747,7 @@ void DataStore::saveChannels(DataStoreHost* host) {
|
||||
}
|
||||
|
||||
bool DataStore::loadScopeList(ScopeList& list, const NodePrefs& prefs) {
|
||||
recoverTempFile(_fs, "/scopes1.tmp", "/scopes1");
|
||||
File file = openRead("/scopes1");
|
||||
if (file) {
|
||||
uint8_t hdr[2] = { 0, 0 }; // default_idx is read back below even if the header read fails
|
||||
|
||||
@@ -335,8 +335,7 @@ class HomeScreen : public UIScreen {
|
||||
if (!on) strcpy(v, "-");
|
||||
else if (_task->isBLEConnected()) strcpy(v, "Connected");
|
||||
// The pairing PIN is BLE-specific: show it while BLE is on but not yet
|
||||
// bonded. (Gating on a plain isConnected() broke this on dual builds,
|
||||
// where it's hardcoded true.)
|
||||
// bonded. (Not a plain isConnected(): a USB port makes that true.)
|
||||
else if (the_mesh.getBLEPin() != 0) snprintf(v, sizeof(rows[0].value), "PIN %d", (int)the_mesh.getBLEPin());
|
||||
else strcpy(v, "Waiting");
|
||||
} else if (page == ADVERT) {
|
||||
|
||||
@@ -16,14 +16,13 @@ public:
|
||||
virtual bool isConnected() const = 0;
|
||||
virtual void loop() {};
|
||||
// Returns true when a BLE companion app is connected. Default delegates to
|
||||
// isConnected(); override in dual-interface wrappers that always report
|
||||
// isConnected()=true but still need to distinguish BLE from USB state.
|
||||
// isConnected(); MultiSerialInterface asks its Bluetooth interfaces only.
|
||||
virtual bool isBLEConnected() const { return isConnected(); }
|
||||
// True when a companion app is actually connected over *any* transport
|
||||
// (BLE bonded or a host holding the USB-CDC port open). Distinct from
|
||||
// isConnected(), which a dual interface hardcodes true as a send fallback.
|
||||
// Used for app-connected UI (Auto buzzer mute, message-wake). Default =
|
||||
// isConnected() so single-transport interfaces are unchanged.
|
||||
// isConnected(), which a USB serial port reports true even with nothing on
|
||||
// the other end (it can't tell). Used for app-connected UI (Auto buzzer
|
||||
// mute, message-wake). Default = isConnected().
|
||||
virtual bool isClientConnected() const { return isConnected(); }
|
||||
|
||||
// For a loop that sleeps between passes: frames waiting to be read or sent.
|
||||
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
|
||||
float getLastRSSI() const override { return ((CustomLR1121 *)_radio)->getRSSI(); }
|
||||
float getLastSNR() const override { return ((CustomLR1121 *)_radio)->getSNR(); }
|
||||
float readLiveRSSI() const override { return ((CustomLR1121 *)_radio)->getRSSI(); }
|
||||
float readLiveSNR() const override { return ((CustomLR1121 *)_radio)->getSNR(); }
|
||||
|
||||
uint8_t getSpreadingFactor() const override { return ((CustomLR1121 *)_radio)->getSpreadingFactor(); }
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ SRCS=(
|
||||
src/helpers/ClientACL.cpp
|
||||
src/helpers/CommonCLI.cpp
|
||||
src/helpers/ConfigSerializer.cpp
|
||||
src/helpers/DynamicConfigSerializer.cpp
|
||||
src/helpers/CommonRadioPrefs.cpp
|
||||
src/helpers/DeviceDiag.cpp
|
||||
src/helpers/IdentityStore.cpp
|
||||
src/helpers/RegionMap.cpp
|
||||
|
||||
@@ -61,6 +61,8 @@ SRCS=(
|
||||
src/helpers/ClientACL.cpp
|
||||
src/helpers/CommonCLI.cpp
|
||||
src/helpers/ConfigSerializer.cpp
|
||||
src/helpers/DynamicConfigSerializer.cpp
|
||||
src/helpers/CommonRadioPrefs.cpp
|
||||
src/helpers/DeviceDiag.cpp
|
||||
src/helpers/IdentityStore.cpp
|
||||
src/helpers/RegionMap.cpp
|
||||
|
||||
Reference in New Issue
Block a user