Preserve OTA block progress and channel checks during radio recovery

Drain received packets in single-profile radio fault backoff as well as
dual-profile mode. Share the normal channel-clear and bounded busy policy
with driver retries so a failed send cannot retry blindly or bypass the
existing single-retry limit.

Retain an unadmitted OTA request flight and count v2 fallback evidence only
after a sparse retry enters the transmit queue. Local queue congestion no
longer disables v2 before a request was sent or discards received fragments.

Include primary airtime when temporary RX-only radio2 crosses requests onto
that channel, keeping response allowances conservative on slower profiles.

Add six native regressions, including five failing-before cases, and document
the queue-admission and crossover timing behavior.

Validation: 1,502 native tests, 29 integration checks, and five firmware
builds passed across ESP32-S3, nRF52, and STM32.
This commit is contained in:
mikecarper committed 2026-09-15 07:54:16 -07:00
1 parent 0582366527
commit dde87f1d15
9 files changed
+216 -44

No files matched your search

+5 -1
View File
@@ -640,7 +640,11 @@ uint32_t Mesh::getOtaPacketAirtime() const {
// Replies may occupy both profiles even with crossing off or radio2 RX-only.
uint8_t mask = (profiles->primary_temporary ? 1 : 0) | (profiles->secondary_temporary ? 2 : 0);
if (!mask) mask = 1;
if (profiles->canCross() && profiles->canTransmit(1)) mask |= 3;
// Each temporary origin can cross independently. In particular, an RX-only
// secondary can still send requests over the primary when crossing is on.
for (uint8_t origin = 0; origin < 2; ++origin) {
if (mask & (1U << origin)) mask |= profiles->transmitMask(origin);
}
if (profiles->reply_tx != RADIO_TX_AUTO) {
mask |= explicitRadioTxMask(profiles->reply_tx, profiles->canTransmit(1, profiles->reply_force));
}