From 8fa3efc06708c84c102b5e55e3c01d8e493f390b Mon Sep 17 00:00:00 2001 From: DatanoiseTV <6614616+DatanoiseTV@users.noreply.github.com> Date: Fri, 8 May 2026 21:36:03 +0200 Subject: [PATCH] router: don't evict ACKs when a background-priority packet arrives full MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromRadioQueue is a plain FIFO of size 4. When it fills, the prior behaviour was to drop the oldest packet — usually a routing ACK or reply — to make room for whatever just arrived, even if the new packet was BACKGROUND priority. Reverse that for the low-priority case: if the incoming packet's priority is at or below BACKGROUND, drop it instead. Higher-priority arrivals still evict to fit. PointerQueue doesn't expose iteration, so a full priority-queue refactor would be a larger change; this addresses the worst case. --- src/mesh/Router.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index ffeb7c5393d..2f7bf8b2d9d 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -168,13 +168,22 @@ int32_t Router::runOnce() */ void Router::enqueueReceivedMessage(meshtastic_MeshPacket *p) { - // Try enqueue until successful - while (!fromRadioQueue.enqueue(p, 0)) { - meshtastic_MeshPacket *old_p; - old_p = fromRadioQueue.dequeuePtr(0); // Dequeue and discard the oldest packet - if (old_p) { - printPacket("fromRadioQ full, drop oldest!", old_p); - packetPool.release(old_p); + // Try enqueue, but if the queue is full and the incoming packet is itself + // low priority, drop *it* rather than evicting an older (likely higher- + // priority) packet such as an ACK or routing reply. + if (!fromRadioQueue.enqueue(p, 0)) { + if (p->priority != meshtastic_MeshPacket_Priority_UNSET && p->priority <= meshtastic_MeshPacket_Priority_BACKGROUND) { + printPacket("fromRadioQ full, drop incoming low-prio!", p); + packetPool.release(p); + return; + } + // Higher-priority packet — fall back to evicting until it fits. + while (!fromRadioQueue.enqueue(p, 0)) { + meshtastic_MeshPacket *old_p = fromRadioQueue.dequeuePtr(0); + if (old_p) { + printPacket("fromRadioQ full, drop oldest!", old_p); + packetPool.release(old_p); + } } } // Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME