Fix radio profile reconfiguration transaction results

This commit is contained in:
mikecarper
2026-10-03 18:25:22 -07:00
parent 18f7edcf82
commit 06fc2d58d1
2 changed files with 65 additions and 3 deletions
+8 -3
View File
@@ -409,9 +409,10 @@ mesh::RadioParamApplyResult RadioLibWrapper::prepareTransmitProfile(uint8_t prof
mesh::RadioParamApplyResult RadioLibWrapper::tryRestoreCodingRate(uint8_t cr) {
const uint8_t resume_rx = beginReconfigure();
if (resume_rx > 1) return mesh::RadioParamApplyResult::BUSY;
const bool applied = setCodingRate(cr);
if (!applied) _profile_refresh_required = true;
bool applied = setCodingRate(cr);
endReconfigure(resume_rx);
applied = applied && (!resume_rx || isInRecvMode());
if (!applied) _profile_refresh_required = true;
return applied ? mesh::RadioParamApplyResult::APPLIED : mesh::RadioParamApplyResult::FAILED;
}
@@ -552,7 +553,11 @@ mesh::RadioParamApplyResult RadioLibWrapper::trySetPrimaryParams(const mesh::Rad
_profiles.primary_temporary = was_temp;
_profiles.generation[0] = generation;
} else {
_profiles.generation[0] = generation + (previous != p || was_temp != temporary);
const bool changed = previous != p || was_temp != temporary;
_profiles.generation[0] = generation + changed;
// Preamble and lease flags are staged before trySetParams(), so its
// setPrimary() cannot detect a change limited to those fields.
if (changed) _profiles.resetSwitchTest();
_profile_generation = _profiles.generation[0];
}
return result;
+57
View File
@@ -153,6 +153,22 @@ int main() {
assert(w.coding_writes==1 && state==STATE_RX);
assert(w._profile_refresh_required==!success);
}
{
RadioLibWrapper w; state=STATE_IDLE;
assert(w.tryRestoreCodingRate(5)==Result::APPLIED);
assert(w.coding_writes==1 && state==STATE_IDLE && !w._profile_refresh_required);
}
{
RadioLibWrapper w; w.failRxStarts=1;
assert(w.tryRestoreCodingRate(5)==Result::FAILED);
assert(w.coding_writes==1 && state==STATE_IDLE && w._profile_refresh_required);
// The normal receive re-arm and profile refresh can recover after a
// transient restart failure; a later coding-rate restore then succeeds.
w.startRecv(); w.serviceProfileScan();
assert(w.isInRecvMode() && !w._profile_refresh_required);
assert(w.tryRestoreCodingRate(5)==Result::APPLIED);
assert(w.coding_writes==2 && w.isInRecvMode() && !w._profile_refresh_required);
}
{
// Force only admits a reply on an active RX-only profile. It cannot
// enable a disabled profile or erase an in-progress reception.
@@ -329,6 +345,47 @@ int main() {
assert(w.chip.standbyXOSC && !w._profile_standby_held && !w._rx_ps_enabled);
w.setProfileStandbyWarm(false); assert(w.chip.standbyXOSC);
}
for (bool preamble_only : {false,true}) {
RadioLibWrapper w; w.enable();
const auto original=w._profiles;
auto requested=original.primary;
if (preamble_only) requested.preamble=64;
assert(w.trySetPrimaryParams(requested,!preamble_only)==Result::APPLIED);
assert(w._profiles.primary==requested && w._profiles.primary_temporary==!preamble_only);
assert(w._profiles.generation[0]==original.generation[0]+1);
assert(!w._profiles.switchTestReady() && w._profiles.switchBudgetUs()==0);
assert(w._profiles.switch_test_samples[0]==0 && w._profiles.switch_test_samples[1]==0);
w.serviceProfileScan(); assert(w._profiles.switchTestReady());
}
{
RadioLibWrapper w; w.enable();
const auto original=w._profiles;
assert(w.trySetPrimaryParams(original.primary,false)==Result::APPLIED);
assert(w._profiles.generation[0]==original.generation[0]);
assert(w._profiles.switchTestReady() && w._profiles.switchBudgetUs()==original.switchBudgetUs());
for (unsigned i=0;i<2;++i) {
assert(w._profiles.switch_test_samples[i]==original.switch_test_samples[i]);
assert(w._profiles.switch_test_max_us[i]==original.switch_test_max_us[i]);
}
}
for (bool preamble_only : {false,true}) for (bool busy : {false,true}) {
RadioLibWrapper w; w.enable();
const auto original=w._profiles;
const auto original_preamble=w._physical_preamble;
auto requested=original.primary;
if (preamble_only) requested.preamble=64;
w.packet=busy;
if (!busy) w.failRxStarts=1;
assert(w.trySetPrimaryParams(requested,!preamble_only)==(busy?Result::BUSY:Result::FAILED));
assert(w._profiles.primary==original.primary && !w._profiles.primary_temporary);
assert(w._profiles.generation[0]==original.generation[0]);
assert(w._physical_preamble==original_preamble);
assert(w._profiles.switchTestReady() && w._profiles.switchBudgetUs()==original.switchBudgetUs());
for (unsigned i=0;i<2;++i) {
assert(w._profiles.switch_test_samples[i]==original.switch_test_samples[i]);
assert(w._profiles.switch_test_max_us[i]==original.switch_test_max_us[i]);
}
}
for (int reason=0;reason<4;++reason) {
RadioLibWrapper w;
if (reason==0) w.busy=true;