diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 6f87422f2..715daff1b 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -430,6 +430,14 @@ NodeDB::NodeDB() // likewise - we always want the app requirements to come from the running appload myNodeInfo.min_app_version = 30200; // format is Mmmss (where M is 1+the numeric major number. i.e. 30200 means 2.2.00 + + // likewise the edition: it lives in persisted devicestate, so a vanilla install must + // overwrite the previous event build's value. Before the CRC compare, so the change persists. +#ifdef USERPREFS_FIRMWARE_EDITION + myNodeInfo.firmware_edition = USERPREFS_FIRMWARE_EDITION; +#else + myNodeInfo.firmware_edition = meshtastic_FirmwareEdition_VANILLA; +#endif pickNewNodeNum(); // Set our board type so we can share it with others @@ -615,9 +623,6 @@ NodeDB::NodeDB() config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_enabled = 0; } -#ifdef USERPREFS_FIRMWARE_EDITION - myNodeInfo.firmware_edition = USERPREFS_FIRMWARE_EDITION; -#endif #ifdef USERPREFS_FIXED_GPS if (myNodeInfo.reboot_count == 1) { // Check if First boot ever or after Factory Reset. meshtastic_Position fixedGPS = meshtastic_Position_init_default; diff --git a/test/state-manifest.tsv b/test/state-manifest.tsv index 45a8fa962..7420504e8 100644 --- a/test/state-manifest.tsv +++ b/test/state-manifest.tsv @@ -42,6 +42,7 @@ # suite flags reason test_admin_radio writes=config.proto,module.proto,device.proto,channels.proto,nodes.proto,warm.dat,Messages_default.msgs per-test NodeDB fixture, and the admin handlers under test persist config, channels and node metadata test_admin_session_repro writes=config.proto,module.proto,device.proto,channels.proto,nodes.proto constructs a NodeDB, whose constructor persists a default set when the prefs directory is empty +test_firmware_edition writes=config.proto,module.proto,device.proto,channels.proto,nodes.proto persists an event firmware_edition in devicestate, then reboots a NodeDB to prove a vanilla build resets it test_fuzz_packets writes=config.proto,module.proto,device.proto,channels.proto,nodes.proto,warm.dat,Messages_default.msgs drives decode of fuzzed packets through the real NodeDB and message store test_hop_scaling writes=config.proto,module.proto,device.proto,channels.proto,nodes.proto constructs a NodeDB to hold the hop-distance fixtures test_mesh_beacon writes=module.proto exercises the beacon's module-config save path diff --git a/test/test_firmware_edition/test_main.cpp b/test/test_firmware_edition/test_main.cpp new file mode 100644 index 000000000..949dd0335 --- /dev/null +++ b/test/test_firmware_edition/test_main.cpp @@ -0,0 +1,49 @@ +// devicestate.my_node survives a firmware reinstall, so a vanilla build (no +// USERPREFS_FIRMWARE_EDITION) must reset a persisted event edition at boot. +#include "MeshTypes.h" // Include BEFORE TestUtil.h +#include "TestUtil.h" +#include "mesh/NodeDB.h" +#include + +#if defined(ARCH_PORTDUINO) +#define FE_TEST_ENTRY extern "C" +#else +#define FE_TEST_ENTRY +#endif + +void setUp(void) {} +void tearDown(void) {} + +static meshtastic_FirmwareEdition persistedEdition() +{ + meshtastic_DeviceState saved = meshtastic_DeviceState_init_zero; + TEST_ASSERT_EQUAL(LoadFileResult::LOAD_SUCCESS, nodeDB->loadProto(deviceStateFileName, meshtastic_DeviceState_size, + sizeof(saved), &meshtastic_DeviceState_msg, &saved)); + return saved.my_node.firmware_edition; +} + +static void test_vanillaBoot_resetsPersistedEventEdition(void) +{ + devicestate.my_node.firmware_edition = meshtastic_FirmwareEdition_DEFCON; + TEST_ASSERT_TRUE(nodeDB->saveToDisk(SEGMENT_DEVICESTATE)); + TEST_ASSERT_EQUAL(meshtastic_FirmwareEdition_DEFCON, persistedEdition()); + + NodeDB *rebooted = new NodeDB(); + delete nodeDB; + nodeDB = rebooted; + + TEST_ASSERT_EQUAL(meshtastic_FirmwareEdition_VANILLA, devicestate.my_node.firmware_edition); + // On disk too, not just in RAM: the stamp must land before the boot save decision. + TEST_ASSERT_EQUAL(meshtastic_FirmwareEdition_VANILLA, persistedEdition()); +} + +FE_TEST_ENTRY void setup() +{ + initializeTestEnvironment(); + nodeDB = new NodeDB(); + + UNITY_BEGIN(); + RUN_TEST(test_vanillaBoot_resetsPersistedEventEdition); + exit(UNITY_END()); +} +FE_TEST_ENTRY void loop() {}