This commit is contained in:
Erayd 2025-03-01 12:54:28 +01:00 committed by GitHub
commit fe6afa5856
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 4 deletions

View File

@ -29,6 +29,13 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
if (Router::cancelSending(p->from, p->id))
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 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);

View File

@ -103,12 +103,26 @@ meshtastic_MeshPacket *MeshPacketQueue::getFront()
return p;
}
/** 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)
/** Attempt to find a packet in this queue. Returns a pointer to the found packet, or NULL if not found. */
meshtastic_MeshPacket *MeshPacketQueue::find(NodeNum from, PacketId id)
{
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) {
return p;
}
}
return NULL;
}
/** 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, 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)) &&
(!hop_limit_lt || p->hop_limit < hop_limit_lt)) {
queue.erase(it);
return p;
}

View File

@ -35,6 +35,10 @@ class MeshPacketQueue
meshtastic_MeshPacket *getFront();
/** Attempt to find a packet in this queue. Returns a pointer to the found packet, or NULL if not found. */
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);
};

View File

@ -185,6 +185,12 @@ class RadioInterface
/** If the packet is not already in the late rebroadcast window, move it there */
virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { 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
* https://www.rs-online.com/designspark/rel-assets/ds-assets/uploads/knowledge-items/application-notes-for-the-internet-of-things/LoRa%20Design%20Guide.pdf

View File

@ -348,6 +348,26 @@ void RadioLibInterface::clampToLateRebroadcastWindow(NodeNum from, PacketId id)
}
}
/**
* 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 RadioLibInterface::removePendingTXPacket(NodeNum from, PacketId id, uint32_t hop_limit_lt)
{
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

View File

@ -204,4 +204,10 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
* If the packet is not already in the late rebroadcast window, move it there
*/
void clampToLateRebroadcastWindow(NodeNum from, PacketId id);
/**
* 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);
};