diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 22f581a6..a1a5d4ee 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -304,6 +304,16 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no _prefs.page_order_set = NodePrefs::PAGE_ORDER_MAGIC; } + // Schema sentinel: bumped on layout changes. Mismatch means an older file + // (or a different schema); rd() already zero-inits any fields not present, + // so we just log it — next savePrefs writes the current sentinel. + uint32_t sentinel = 0; + rd(&sentinel, sizeof(sentinel)); + if (sentinel != NodePrefs::SCHEMA_SENTINEL) { + MESH_DEBUG_PRINTLN("prefs schema sentinel mismatch: got 0x%08X, expected 0x%08X — re-saving on next change", + (unsigned)sentinel, (unsigned)NodePrefs::SCHEMA_SENTINEL); + } + file.close(); } @@ -385,6 +395,10 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_ file.write((uint8_t *)&_prefs.eink_full_refresh_every, sizeof(_prefs.eink_full_refresh_every)); file.write((uint8_t *)&_prefs.page_order_set, sizeof(_prefs.page_order_set)); + // Tail sentinel — must be last. See NodePrefs::SCHEMA_SENTINEL. + uint32_t sentinel = NodePrefs::SCHEMA_SENTINEL; + file.write((uint8_t *)&sentinel, sizeof(sentinel)); + file.close(); } } diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index d3a2328c..88f0e2d1 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -90,6 +90,12 @@ struct NodePrefs { // persisted to file uint8_t page_order_set; // 0xA5 = page_order is user-configured; anything else = use default static const uint8_t PAGE_ORDER_MAGIC = 0xA5; + // Tail sentinel written at the end of /new_prefs. Bump the low byte when + // adding/removing/reordering fields in DataStore::savePrefs/loadPrefsInt so + // older saves are detected on load and skipped (zero-init defaults kept). + // High 24 bits identify the file format; low byte is the schema revision. + static const uint32_t SCHEMA_SENTINEL = 0xC0DE0001; + // Bitmasks for home_pages_mask (bit=1 → page visible; 0 field = all visible). static const uint16_t HP_CLOCK = 1 << 0; static const uint16_t HP_RECENT = 1 << 1;