Skip to content

Commit

Permalink
If a packet is heard multiple times, rebroadcast using the highest ho…
Browse files Browse the repository at this point in the history
…p limit

Sometimes a packet will be in the TX queue waiting to be transmitted,
when it is overheard being rebroadcast by another node, with a higher
hop limit remaining. When this occurs, modify the pending packet in
the TX queue to avoid unnecessarily wasting hops.
  • Loading branch information
erayd committed Dec 9, 2024
1 parent f81d3b0 commit ea42503
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/mesh/FloodingRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ 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 update the hop limit of the packet currently sitting in the TX queue.
iface->clampHopsToMax(getFrom(p), p->id, p->hop_limit - 1);
}

/* If the original transmitter is doing retransmissions (hopStart equals hopLimit) for a reliable transmission, e.g., when
Expand Down
13 changes: 13 additions & 0 deletions src/mesh/MeshPacketQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ meshtastic_MeshPacket *MeshPacketQueue::getFront()
return p;
}

/** 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) {
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)
{
Expand Down
3 changes: 3 additions & 0 deletions src/mesh/MeshPacketQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ 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);
};
3 changes: 3 additions & 0 deletions src/mesh/RadioInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ class RadioInterface
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
uint32_t getTxDelayMsecWeighted(float snr);

/** 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; }

/**
* 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
Expand Down
12 changes: 12 additions & 0 deletions src/mesh/RadioLibInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,18 @@ void RadioLibInterface::startTransmitTimerSNR(float snr)
}
}

/**
* Clamp the hop limit to the greater of the hop count provided, or the hop count in the queue
*/
void RadioLibInterface::clampHopsToMax(NodeNum from, PacketId id, uint32_t hop_limit)
{
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;
}
}

void RadioLibInterface::handleTransmitInterrupt()
{
// This can be null if we forced the device to enter standby mode. In that case
Expand Down
5 changes: 5 additions & 0 deletions src/mesh/RadioLibInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,9 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
virtual void setStandby();

const char *radioLibErr = "RadioLib err=";

/**
* Clamp the hop limit to the greater of the hop count provided, or the hop count in the queue
*/
void clampHopsToMax(NodeNum from, PacketId id, uint32_t hop_limit);
};

0 comments on commit ea42503

Please sign in to comment.