diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 565b27378f..997b1d6fe0 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -252,21 +252,14 @@ void RadioLibInterface::onNotify(uint32_t notification) } else { meshtastic_MeshPacket *txp = txQueue.getFront(); assert(txp); - // check for any remaining delay, and abort if we're still supposed to be waiting - if (txp->tx_after > millis()) { + long delay_remaining = txp->tx_after ? txp->tx_after - millis() : 0; + if (delay_remaining > 0) { // There's still some delay pending on this packet, so resume waiting for it to elapse - notifyLater(txp->tx_after - millis(), TRANSMIT_DELAY_COMPLETED, false); + notifyLater(delay_remaining, TRANSMIT_DELAY_COMPLETED, false); } else { if (isChannelActive()) { // check if there is currently a LoRa packet on the channel startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again - if (txp->tx_after) { - // If we're using the late rebroadcast window, kick it down the road some more - txp->tx_after = max(txp->tx_after, (uint32_t)millis()) + - (txp->rx_snr ? getTxDelayMsecWeighted(txp->rx_snr) : getTxDelayMsec()); - notifyLater(txp->tx_after - millis(), TRANSMIT_DELAY_COMPLETED, false); - } else { - setTransmitDelay(); - } + setTransmitDelay(); } else { // Send any outgoing packets we have ready as fast as possible to keep the time between channel scan and // actual transmission as short as possible @@ -293,11 +286,20 @@ void RadioLibInterface::onNotify(uint32_t notification) void RadioLibInterface::setTransmitDelay() { meshtastic_MeshPacket *p = txQueue.getFront(); + if (!p) { + return; // noop if there's nothing in the queue + } + // We want all sending/receiving to be done by our daemon thread. // We use a delay here because this packet might have been sent in response to a packet we just received. // So we want to make sure the other side has had a chance to reconfigure its radio. - if (p->rx_snr == 0 && p->rx_rssi == 0) { + if (p->tx_after) { + unsigned long add_delay = p->rx_rssi ? getTxDelayMsecWeighted(p->rx_snr) : getTxDelayMsec(); + unsigned long now = millis(); + p->tx_after = max(p->tx_after + add_delay, now + add_delay); + notifyLater(now - p->tx_after, TRANSMIT_DELAY_COMPLETED, false); + } else if (p->rx_snr == 0 && p->rx_rssi == 0) { /* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally. * This assumption is valid because of the offset generated by the radio to account for the noise * floor. @@ -336,7 +338,7 @@ void RadioLibInterface::clampToLateRebroadcastWindow(NodeNum from, PacketId id) // Look for non-late packets only, so we don't do this twice! meshtastic_MeshPacket *p = txQueue.remove(from, id, true, false); if (p) { - p->tx_after = millis() + getTxDelayMsecWeightedWorst(p->rx_snr) + getTxDelayMsecWeighted(p->rx_snr); + p->tx_after = millis() + getTxDelayMsecWeightedWorst(p->rx_snr); txQueue.enqueue(p); LOG_DEBUG("Move existing queued packet to the late rebroadcast window %dms from now", p->tx_after - millis()); }