From 3041ac6c09062dac3b9f6296a98bf87f060b0f44 Mon Sep 17 00:00:00 2001 From: Steve Gilberd Date: Sat, 28 Dec 2024 16:55:52 +1300 Subject: [PATCH] Reprocess instead of modifying queued packet In order to ensure that the traceroute module works correctly, rather than modifying the hop limnit of the existing queued version of the packet, simply drop it ifrom the queue and reprocess the version of the packet with the superior hop limit. --- src/mesh/FloodingRouter.cpp | 7 +++++-- src/mesh/MeshPacketQueue.cpp | 5 +++-- src/mesh/MeshPacketQueue.h | 3 ++- src/mesh/RadioInterface.h | 7 +++++-- src/mesh/RadioLibInterface.cpp | 20 ++++++++++++++------ src/mesh/RadioLibInterface.h | 5 +++-- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index 64280f3fe..bf106a55e 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -31,8 +31,11 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p) txRelayCanceled++; } else if (iface && p->hop_limit > 0) { // If we overhear a duplicate copy of the packet with more hops left than the one we are waiting to - // rebroadcast, then update the hop limit of the packet currently sitting in the TX queue. - iface->clampHopsToMax(getFrom(p), p->id, p->hop_limit - 1); + // rebroadcast, then remove the packet currently sitting in the TX queue and use this one instead. + if (iface->removePendingTXPacket(getFrom(p), p->id, p->hop_limit - 1)) { + LOG_DEBUG("Processing packet %d again for rebroadcast with with better hop limit (%d)", p->hop_limit - 1); + return false; + } } if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE && iface) { iface->clampToLateRebroadcastWindow(getFrom(p), p->id); diff --git a/src/mesh/MeshPacketQueue.cpp b/src/mesh/MeshPacketQueue.cpp index 282d27b40..6bf9b915f 100644 --- a/src/mesh/MeshPacketQueue.cpp +++ b/src/mesh/MeshPacketQueue.cpp @@ -113,11 +113,12 @@ meshtastic_MeshPacket *MeshPacketQueue::find(NodeNum from, PacketId id) } /** Attempt to find and remove a packet from this queue. Returns a pointer to the removed packet, or NULL if not found */ -meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id, bool tx_normal, bool tx_late) +meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id, bool tx_normal, bool tx_late, uint8_t hop_limit_lt) { for (auto it = queue.begin(); it != queue.end(); it++) { auto p = (*it); - if (getFrom(p) == from && p->id == id && ((tx_normal && !p->tx_after) || (tx_late && p->tx_after))) { + if (getFrom(p) == from && p->id == id && ((tx_normal && !p->tx_after) || (tx_late && p->tx_after)) && + (!hop_limit_lt || p->hop_limit < hop_limit_lt)) { queue.erase(it); return p; } diff --git a/src/mesh/MeshPacketQueue.h b/src/mesh/MeshPacketQueue.h index 578280ef7..b76aee583 100644 --- a/src/mesh/MeshPacketQueue.h +++ b/src/mesh/MeshPacketQueue.h @@ -39,5 +39,6 @@ class MeshPacketQueue meshtastic_MeshPacket *find(NodeNum from, PacketId id); /** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */ - meshtastic_MeshPacket *remove(NodeNum from, PacketId id, bool tx_normal = true, bool tx_late = true); + meshtastic_MeshPacket *remove(NodeNum from, PacketId id, bool tx_normal = true, bool tx_late = true, + uint8_t hop_limit_lt = 0); }; \ No newline at end of file diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index 90f958c00..acb923a4f 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -185,8 +185,11 @@ class RadioInterface /** If the packet is not already in the late rebroadcast window, move it there */ virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { return; } - /** Clamp the hop limit to the greater of the hop count provided, or the hop count in the queue */ - virtual void clampHopsToMax(NodeNum from, PacketId id, uint32_t hop_limit) { return; } + /** + * If there is a packet pending TX in the queue with a worse hop limit, remove it pending replacement with a better version + * @return Whether a pending packet was removed + */ + bool removePendingTXPacket(NodeNum from, PacketId id, uint32_t hop_limit_lt) { return false; } /** * Calculate airtime per diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 7b972cad4..c99aa756b 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -345,17 +345,25 @@ void RadioLibInterface::clampToLateRebroadcastWindow(NodeNum from, PacketId id) } /** - * Clamp the hop limit to the greater of the hop count provided, or the hop count in the queue + * If there is a packet pending TX in the queue with a worse hop limit, remove it pending replacement with a better version + * @return Whether a pending packet was removed */ -void RadioLibInterface::clampHopsToMax(NodeNum from, PacketId id, uint32_t hop_limit) +bool RadioLibInterface::removePendingTXPacket(NodeNum from, PacketId id, uint32_t hop_limit_lt) { - meshtastic_MeshPacket *p = txQueue.find(from, id); - if (p && p->hop_limit < hop_limit) { - LOG_DEBUG("Increasing hop limit for packet from %d to %d", p->hop_limit, hop_limit); - p->hop_limit = hop_limit; + meshtastic_MeshPacket *p = txQueue.remove(from, id, true, true, hop_limit_lt); + if (p) { + LOG_DEBUG("Dropping pending-TX packet %d with hop limit %d", p->id, p->hop_limit); + packetPool.release(p); + return true; } + return false; } +/** + * Remove a packet that is eligible for replacement from the TX queue + */ +// void RadioLibInterface::removePending + void RadioLibInterface::handleTransmitInterrupt() { // This can be null if we forced the device to enter standby mode. In that case diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index affb00609..c819ae4eb 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -206,7 +206,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified void clampToLateRebroadcastWindow(NodeNum from, PacketId id); /** - * Clamp the hop limit to the greater of the hop count provided, or the hop count in the queue + * If there is a packet pending TX in the queue with a worse hop limit, remove it pending replacement with a better version + * @return Whether a pending packet was removed */ - void clampHopsToMax(NodeNum from, PacketId id, uint32_t hop_limit); + bool removePendingTXPacket(NodeNum from, PacketId id, uint32_t hop_limit_lt); }; \ No newline at end of file