diff --git a/src/mesh/NextHopRouter.cpp b/src/mesh/NextHopRouter.cpp index 0a64a1f1a98..500f19398e0 100644 --- a/src/mesh/NextHopRouter.cpp +++ b/src/mesh/NextHopRouter.cpp @@ -405,8 +405,16 @@ int32_t NextHopRouter::doRetransmissions() bool stillValid = true; // assume we'll keep this record around - // FIXME, handle 51 day rolloever here!!! - if (p.nextTxMsec <= now) { + // Use unsigned half-range comparison so retransmission timing stays correct across the + // ~49.7 day millis() wraparound (previously this FIXME would stall all retx for the + // duration of the wrap or fire them all at once immediately after). + // + // Casting an unsigned difference to int32_t for a "time passed" test is + // implementation-defined in C++ when the value exceeds INT32_MAX. The unsigned + // half-range form below is fully well-defined: nextTxMsec is in the past (or is now) + // iff (now - nextTxMsec) has not wrapped past 2^31 ms. Anything further in the + // future wraps into the top half and reads as "not yet." + if ((uint32_t)(now - p.nextTxMsec) < 0x80000000u) { if (p.numRetransmissions == 0) { if (isFromUs(p.packet)) { LOG_DEBUG("Reliable send failed, returning a nak for fr=0x%08x,to=0x%08x,id=0x%08x", p.packet->from,