From 89bd6c3416252365cf596f9e9e0fba590a1e934c Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 28 Mar 2025 20:50:42 +1100 Subject: [PATCH] * Dispatcher: now impose a max time for CAD fail (ie. channel busy), defined by getCADFailMaxDuration(), default 4 seconds. (an sx126x bug _might_ be making radio->isReceiving() return true indefinitely) --- src/Dispatcher.cpp | 18 ++++++++++++++++-- src/Dispatcher.h | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Dispatcher.cpp b/src/Dispatcher.cpp index 65f9687f..ae225d36 100644 --- a/src/Dispatcher.cpp +++ b/src/Dispatcher.cpp @@ -29,6 +29,9 @@ int Dispatcher::calcRxDelay(float score, uint32_t air_time) const { uint32_t Dispatcher::getCADFailRetryDelay() const { return 200; } +uint32_t Dispatcher::getCADFailMaxDuration() const { + return 4000; // 4 seconds +} void Dispatcher::loop() { if (outbound) { // waiting for outbound send to be completed @@ -185,9 +188,20 @@ void Dispatcher::checkSend() { if (_mgr->getOutboundCount() == 0) return; // nothing waiting to send if (!millisHasNowPassed(next_tx_time)) return; // still in 'radio silence' phase (from airtime budget setting) if (_radio->isReceiving()) { // LBT - check if radio is currently mid-receive, or if channel activity - next_tx_time = futureMillis(getCADFailRetryDelay()); - return; + if (cad_busy_start == 0) { + cad_busy_start = _ms->getMillis(); // record when CAD busy state started + } + + if (_ms->getMillis() - cad_busy_start > getCADFailMaxDuration()) { + MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): CAD busy max duration reached!", getLogDateTime()); + // channel activity has gone on too long... (Radio might be in a bad state) + // force the pending transmit below... + } else { + next_tx_time = futureMillis(getCADFailRetryDelay()); + return; + } } + cad_busy_start = 0; // reset busy state outbound = _mgr->getNextOutbound(_ms->getMillis()); if (outbound) { diff --git a/src/Dispatcher.h b/src/Dispatcher.h index 0b00f1a9..393d0856 100644 --- a/src/Dispatcher.h +++ b/src/Dispatcher.h @@ -98,6 +98,7 @@ class Dispatcher { Packet* outbound; // current outbound packet unsigned long outbound_expiry, outbound_start, total_air_time; unsigned long next_tx_time; + unsigned long cad_busy_start; uint32_t n_sent_flood, n_sent_direct; uint32_t n_recv_flood, n_recv_direct; uint32_t n_full_events; @@ -113,6 +114,7 @@ protected: : _radio(&radio), _ms(&ms), _mgr(&mgr) { outbound = NULL; total_air_time = 0; next_tx_time = 0; + cad_busy_start = 0; } virtual DispatcherAction onRecvPacket(Packet* pkt) = 0; @@ -127,6 +129,7 @@ protected: virtual float getAirtimeBudgetFactor() const; virtual int calcRxDelay(float score, uint32_t air_time) const; virtual uint32_t getCADFailRetryDelay() const; + virtual uint32_t getCADFailMaxDuration() const; public: void begin();