diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 94dab0bcd6..118aab5a66 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -175,7 +175,7 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl) return msecs; } -uint32_t RadioInterface::getPacketTime(meshtastic_MeshPacket *p) +uint32_t RadioInterface::getPacketTime(const meshtastic_MeshPacket *p) { uint32_t pl = 0; if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag) { diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index b9511fd5de..68dbf3522d 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -154,7 +154,7 @@ class RadioInterface * * @return num msecs for the packet */ - uint32_t getPacketTime(meshtastic_MeshPacket *p); + uint32_t getPacketTime(const meshtastic_MeshPacket *p); uint32_t getPacketTime(uint32_t totalPacketLen); /** diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index 3d07ff77e1..774be9c175 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -24,6 +24,15 @@ ErrorCode ReliableRouter::send(meshtastic_MeshPacket *p) startRetransmission(copy); } + /* If we have pending retransmissions, add the airtime of this packet to it, because during that time we cannot receive an + (implicit) ACK. Otherwise, we might retransmit too early. + */ + for (auto i = pending.begin(); i != pending.end(); i++) { + if (i->first.id != p->id) { + i->second.nextTxMsec += iface->getPacketTime(p); + } + } + return FloodingRouter::send(p); } @@ -53,6 +62,15 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p) } } + /* At this point we have already deleted the pending retransmission if this packet was an (implicit) ACK to it. + Now for all other pending retransmissions, we have to add the airtime of this received packet to the retransmission timer, + because while receiving this packet, we could not have received an (implicit) ACK for it. + If we don't add this, we will likely retransmit too early. + */ + for (auto i = pending.begin(); i != pending.end(); i++) { + i->second.nextTxMsec += iface->getPacketTime(p); + } + /* Resend implicit ACKs for repeated packets (assuming the original packet was sent with HOP_RELIABLE) * this way if an implicit ACK is dropped and a packet is resent we'll rebroadcast again. * Resending real ACKs is omitted, as you might receive a packet multiple times due to flooding and