Harden retry, region, radio, and alert logic

This commit is contained in:
mikecarper
2026-07-13 13:18:49 -07:00
parent 5a2aa592ea
commit b9e7e416be
37 changed files with 1192 additions and 311 deletions
+58 -10
View File
@@ -750,6 +750,9 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise
last_read_time = 0;
num_alert_tasks = 0;
set_radio_at = revert_radio_at = 0;
active_cr = LORA_CR;
temp_radio_applied = false;
saved_radio_apply_pending = false;
// defaults
memset(&_prefs, 0, sizeof(_prefs));
@@ -816,8 +819,10 @@ void SensorMesh::begin(FILESYSTEM* fs) {
}
}
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
radio_driver.setTxPower(_prefs.tx_power_dbm);
saved_radio_apply_pending = !applySavedRadioParams();
if (!saved_radio_apply_pending) {
radio_driver.setTxPower(_prefs.tx_power_dbm);
}
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain); // LoRa FEM LNA (FEM boards only)
setRxPowerSaving(_prefs.rx_powersaving_enabled, _prefs.rx_ps_rx_us, _prefs.rx_ps_sleep_us);
@@ -831,6 +836,18 @@ void SensorMesh::begin(FILESYSTEM* fs) {
#endif
}
bool SensorMesh::applySavedRadioParams() {
uint32_t timings[2] = {_prefs.rx_ps_rx_us, _prefs.rx_ps_sleep_us};
const uint32_t* applied_timings = _prefs.rx_powersaving_enabled
&& radio_driver.supportsRxPowerSaving() ? timings : NULL;
if (!radio_driver.setParams(
_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr, applied_timings)) {
return false;
}
active_cr = _prefs.cr;
return true;
}
bool SensorMesh::formatFileSystem() {
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
return InternalFS.format();
@@ -969,16 +986,47 @@ void SensorMesh::loop() {
updateAdvertTimer(); // schedule next local advert
}
if (set_radio_at && millisHasNowPassed(set_radio_at)) { // apply pending (temporary) radio params
set_radio_at = 0; // clear timer
radio_driver.setParams(pending_freq, pending_bw, pending_sf, pending_cr);
MESH_DEBUG_PRINTLN("Temp radio params");
const bool revert_radio_due = revert_radio_at && millisHasNowPassed(revert_radio_at);
if (revert_radio_due && !temp_radio_applied) {
// Never apply a temporary channel after its window has already ended.
set_radio_at = revert_radio_at = 0;
MESH_DEBUG_PRINTLN("Temp radio params expired before apply");
} else if (revert_radio_due && !hasOutbound()) {
if (applySavedRadioParams()) {
if (saved_radio_apply_pending) {
radio_driver.setTxPower(_prefs.tx_power_dbm);
}
set_radio_at = revert_radio_at = 0;
temp_radio_applied = false;
saved_radio_apply_pending = false;
MESH_DEBUG_PRINTLN("Radio params restored");
}
} else if (set_radio_at && millisHasNowPassed(set_radio_at) && !hasOutbound()) {
uint32_t rx_us = _prefs.rx_ps_rx_us;
uint32_t sleep_us = _prefs.rx_ps_sleep_us;
bool timing_ok = true;
if (_prefs.rx_powersaving_enabled && _prefs.rx_ps_level != 0) {
uint32_t preamble = _prefs.rx_ps_preamble ? _prefs.rx_ps_preamble
: (pending_sf <= 8 ? 32UL : 16UL);
timing_ok = CommonCLI::calculateRxPowerSavingLevel(
_prefs.rx_ps_level, pending_sf, pending_bw, preamble, &rx_us, &sleep_us);
}
uint32_t timings[2] = {rx_us, sleep_us};
const uint32_t* applied_timings = _prefs.rx_powersaving_enabled
&& radio_driver.supportsRxPowerSaving() ? timings : NULL;
if (timing_ok && radio_driver.setParams(
pending_freq, pending_bw, pending_sf, pending_cr, applied_timings)) {
set_radio_at = 0;
active_cr = pending_cr;
temp_radio_applied = true;
MESH_DEBUG_PRINTLN("Temp radio params");
}
}
if (revert_radio_at && millisHasNowPassed(revert_radio_at) && !hasOutbound()) { // revert radio params to orig
revert_radio_at = 0; // clear timer
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
MESH_DEBUG_PRINTLN("Radio params restored");
if (saved_radio_apply_pending && !temp_radio_applied && !hasOutbound()
&& applySavedRadioParams()) {
radio_driver.setTxPower(_prefs.tx_power_dbm);
saved_radio_apply_pending = false;
}
uint32_t curr = getRTCClock()->getCurrentTime();