feat(ota): persist ota_channel selector in NodePrefs

(cherry picked from commit db1db5b57ecce408c7441cb6aa70f29608b09603)
This commit is contained in:
Elektr0Vodka authored and agessaman committed 2026-10-03 15:17:36 -07:00
1 parent b98d8daa65
commit d88f1ff68b
2 files changed
+31

No files matched your search

+2
View File
@@ -70,6 +70,7 @@ public:
uint8_t path_hash_mode = 0; // which path mode to use when sending
uint8_t loop_detect = 0;
uint8_t cad_enabled = 0; // hardware Channel Activity Detection before TX (boolean)
uint8_t ota_channel = 0; // OTA release channel selector: 0=native, 1=stable, 2=dev
uint8_t extra_sf[4];
// NOTE: observer settings (MQTT/WiFi/timezone/SNMP/alert) are not in NodePrefs.
@@ -182,6 +183,7 @@ protected:
def("lat", node_lat);
def("lon", node_lon);
def("disc_mod", discovery_mod_timestamp); // gates 'since'-filtered DISCOVER replies
def("ota_ch", ota_channel); // OTA release channel: 0=native, 1=stable, 2=dev
def("radio", radio);
def("bridge", bridge);
def("gps", gps);
@@ -214,6 +214,35 @@ TEST(NodePrefs, FemGainSettingsRoundTrip) {
EXPECT_EQ(1, loaded.radio_fem_txgain);
}
TEST(NodePrefs, OtaChannelDefaultsToNative) {
NodePrefs prefs;
EXPECT_EQ(0, prefs.ota_channel); // 0 == native
}
TEST(NodePrefs, OtaChannelRoundTrip) {
NodePrefs saved;
saved.ota_channel = 2; // dev
MockPrintStream output;
ASSERT_TRUE(saved.saveSerial(output));
std::string serialised(reinterpret_cast<const char*>(output.getBytes()), output.getLength());
EXPECT_NE(std::string::npos, serialised.find("ota_ch:2"));
MockInputStream input(serialised.c_str());
NodePrefs loaded;
loaded.ota_channel = 1; // start different
ASSERT_TRUE(loaded.loadSerial(input)) << serialised;
EXPECT_EQ(2, loaded.ota_channel);
}
TEST(NodePrefs, OtaChannelMissingKeyKeepsDefault) {
// A /prefs.json written before this field existed has no ota_ch key.
MockInputStream input("{name:\"n\"}");
NodePrefs loaded; // ota_channel default 0 (native)
ASSERT_TRUE(loaded.loadSerial(input));
EXPECT_EQ(0, loaded.ota_channel);
}
// ── main ───────────────────────────────────────────────────────