Default radio profile crossover to off

This commit is contained in:
mikecarper committed 2026-10-19 21:11:44 -07:00
1 parent 21a4474577
commit 21a588ca09
6 files changed
+19 -9

No files matched your search

+2 -2
View File
@@ -20,7 +20,7 @@ Frequencies are MHz; bandwidths are kHz. The driver validates each tuple against
Modes are `rx`, `rxtx` and `off`; `rx&tx` aliases `rxtx`. Bare `tempradio ...` remains supported. Temporary durations are 1–10080 minutes.
`cross auto` permits crossover when both profiles are permanent or both are temporary. `on` always permits it; `off` keeps traffic on its originating profile. An RX-only profile never transmits. Replies follow receive affinity and crossover policy; queued packets from replaced sessions are discarded.
Crossover defaults to `off`. `cross auto` permits crossover when both profiles are permanent or both are temporary. `on` always permits it; `off` keeps traffic on its originating profile. An RX-only profile never transmits. Replies follow receive affinity and crossover policy; queued packets from replaced sessions are discarded.
```text
set radio2 915,125,8,5,rxtx
@@ -60,4 +60,4 @@ SX1262 and LR1110 switches reuse acknowledged RX settings and keep the oscillato
Scanning and pending timers keep the MCU awake. One transceiver cannot receive both profiles simultaneously; acquisition still depends on peer preambles, traffic and application delays.
Permanent settings use existing preferences JSON. Missing fields default to secondary off and automatic timing/crossover. Temporary settings and schedules disappear on reboot. Scheduled permanent settings are saved only after application.
Permanent settings use existing preferences JSON. Missing fields default to secondary off, crossover off and automatic timing. Temporary settings and schedules disappear on reboot. Scheduled permanent settings are saved only after application.
+1 -1
View File
@@ -61,7 +61,7 @@ class RadioProfiles {
RadioProfileConfig secondary;
bool primary_temporary = false;
bool secondary_temporary = false;
RadioCrossMode cross = RadioCrossMode::Auto;
RadioCrossMode cross = RadioCrossMode::Off;
uint32_t generation[2] = {1, 1};
uint32_t switches = 0;
uint32_t rx_packets[2] = {};
+2 -2
View File
@@ -100,8 +100,8 @@ void RadioProfileCLI::begin(CommonRadioPrefs& prefs, Radio& radio, RTCClock& clo
if (primary_preamble_ && (primary_preamble_ < 8 || primary_preamble_ > RadioProfiles::MaxPreamble)) primary_preamble_ = 0;
if (uint8_t(saved_.mode) > uint8_t(RadioProfileMode::RxTx)
|| (saved_.mode != RadioProfileMode::Off && !radio.validateProfile(saved_.params))) saved_ = {};
if (cross_ > uint8_t(RadioCrossMode::Off)) cross_ = 0;
radio.profiles()->cross = cross_ <= uint8_t(RadioCrossMode::Off) ? RadioCrossMode(cross_) : RadioCrossMode::Auto;
if (cross_ > uint8_t(RadioCrossMode::Off)) cross_ = uint8_t(RadioCrossMode::Off);
radio.profiles()->cross = RadioCrossMode(cross_);
RadioProfileConfig primary; primary.params = savedPrimary(); primary.mode = RadioProfileMode::RxTx;
queue(0, primary, false, false, uint32_t(millis()));
if (uint8_t(saved_.mode) <= uint8_t(RadioProfileMode::RxTx)
+1 -1
View File
@@ -31,7 +31,7 @@ class RadioProfileCLI : public ConfigSerializer {
bool restoring_[2] = {};
RadioProfileConfig saved_;
uint16_t primary_preamble_ = 0;
uint8_t cross_ = 0;
uint8_t cross_ = uint8_t(RadioCrossMode::Off);
CommonRadioPrefs* prefs_ = nullptr;
Radio* radio_ = nullptr;
RTCClock* rtc_ = nullptr;
+11 -1
View File
@@ -60,6 +60,8 @@ public:
int main(int argc,char**argv) {
assert(argc==2);std::string name=argv[1]; Rig r;
if(name=="parse") {
assert(r.cmd("get radio2.cross")=="> off");
assert(r.radio.state.cross==mesh::RadioCrossMode::Off&&!r.radio.state.canCross());
const char* bad[]={"set radio2 915,125,8,5", "set radio2 nan,125,8,5,rx", "set radio2 1e3,125,8,5,rx",
"set radio2 +915,125,8,5,rx", "set radio2 915,124,8,5,rx", "set radio2 915,125,256,5,rx",
"set radio2 915,125,8,261,rx", "set radio2 915,125,8,5,both", "set radio2 915,125,8,5,rx,7",
@@ -132,7 +134,15 @@ int main(int argc,char**argv) {
assert(radio.state.secondary.params.preamble==40&&radio.state.secondary.mode==mesh::RadioProfileMode::RxTx&&radio.state.cross==mesh::RadioCrossMode::Off);
char reply[160];loaded.profileCLI().handle("get radio2at",reply);assert(!strcmp(reply,"> off"));loaded.profileCLI().handle("get tempradio",reply);assert(!strcmp(reply,"> off"));
Prefs legacy;MemoryStream old("{freq:868.5,bw:125,sf:9,cr:5}");assert(legacy.loadSerial(old));mesh::Radio oldradio;legacy.profileCLI().begin(legacy,oldradio,rtc);legacy.profileCLI().loop();
assert(!oldradio.state.enabled()&&oldradio.state.primary.preamble==0&&oldradio.state.cross==mesh::RadioCrossMode::Auto);
assert(!oldradio.state.enabled()&&oldradio.state.primary.preamble==0&&oldradio.state.cross==mesh::RadioCrossMode::Off);
const char* saved_cross[]={"{profiles:{cross:0}}","{profiles:{cross:1}}","{profiles:{cross:2}}","{profiles:{cross:255}}","{profiles:{mode:0}}"};
for(unsigned value=0;value<5;++value) {
Prefs prefs;MemoryStream input(saved_cross[value]);assert(prefs.loadSerial(input));mesh::Radio restored;
prefs.profileCLI().begin(prefs,restored,rtc);
assert(restored.state.cross==(value<3?mesh::RadioCrossMode(value):mesh::RadioCrossMode::Off));
MemoryStream output;assert(prefs.saveSerial(output));
assert(output.text.find(value==0?"cross:0":value==1?"cross:1":"cross:2")!=std::string::npos);
}
test_millis=UINT32_MAX-500;r.ok("set radio2.cross on");assert(r.cli.saveDue());assert(!r.cli.saveDue());
test_millis+=1000;assert(r.cli.saveDue());r.prefs.clearDirty();assert(!r.cli.saveDue());
} else if(name=="legacy") {
@@ -111,7 +111,7 @@ TEST(CompanionNodePrefs, RadioProfilesRoundTripInExistingPrefs) {
EXPECT_NE(std::string::npos, output.text().find("cross:2"));
}
TEST(CompanionNodePrefs, LegacyPrefsDefaultToOneProfileAndAutomaticPreamble) {
TEST(CompanionNodePrefs, LegacyPrefsDefaultToOneProfileNoCrossoverAndAutomaticPreamble) {
NodePrefs prefs;
ReplayStream input("{radio:{freq:869.525,bw:125,sf:8,cr:5}}");
ASSERT_TRUE(prefs.loadSerial(input));
@@ -121,7 +121,7 @@ TEST(CompanionNodePrefs, LegacyPrefsDefaultToOneProfileAndAutomaticPreamble) {
EXPECT_EQ(0, profiles.savedPrimary().preamble);
CaptureStream output;
ASSERT_TRUE(prefs.saveSerial(output));
EXPECT_NE(std::string::npos, output.text().find("cross:0"));
EXPECT_NE(std::string::npos, output.text().find("cross:2"));
}
int main(int argc, char** argv) {