diff --git a/src/mesh/NextHopRouter.h b/src/mesh/NextHopRouter.h index 57b5e68f0..47cfbfe9b 100644 --- a/src/mesh/NextHopRouter.h +++ b/src/mesh/NextHopRouter.h @@ -2,6 +2,51 @@ #include "FloodingRouter.h" +/** + * An identifier for a globally unique message - a pair of the sending nodenum and the packet id assigned + * to that message + */ +struct GlobalPacketId { + NodeNum node; + PacketId id; + + bool operator==(const GlobalPacketId &p) const { return node == p.node && id == p.id; } + + explicit GlobalPacketId(const meshtastic_MeshPacket *p) + { + node = getFrom(p); + id = p->id; + } + + GlobalPacketId(NodeNum _from, PacketId _id) + { + node = _from; + id = _id; + } +}; + +/** + * A packet queued for retransmission + */ +struct PendingPacket { + meshtastic_MeshPacket *packet; + + /** The next time we should try to retransmit this packet */ + uint32_t nextTxMsec = 0; + + /** Starts at NUM_RETRANSMISSIONS -1(normally 3) and counts down. Once zero it will be removed from the list */ + uint8_t numRetransmissions = 0; + + PendingPacket() {} + explicit PendingPacket(meshtastic_MeshPacket *p); +}; + +class GlobalPacketIdHashFunction +{ + public: + size_t operator()(const GlobalPacketId &p) const { return (std::hash()(p.node)) ^ (std::hash()(p.id)); } +}; + /* Router which only relays if it is the next hop for a packet. The next hop is set by the relay node of a packet, which bases this on information from either the NeighborInfoModule, or a @@ -26,7 +71,23 @@ class NextHopRouter : public FloodingRouter */ virtual ErrorCode send(meshtastic_MeshPacket *p) override; + /** Do our retransmission handling */ + virtual int32_t runOnce() override + { + // Note: We must doRetransmissions FIRST, because it might queue up work for the base class runOnce implementation + auto d = doRetransmissions(); + + int32_t r = FloodingRouter::runOnce(); + + return min(d, r); + } + protected: + /** + * Pending retransmissions + */ + std::unordered_map pending; + /** * Should this incoming filter be dropped? * @@ -42,10 +103,38 @@ class NextHopRouter : public FloodingRouter constexpr static uint8_t NO_NEXT_HOP_PREFERENCE = 0; + /** + * Try to find the pending packet record for this ID (or NULL if not found) + */ + PendingPacket *findPendingPacket(NodeNum from, PacketId id) { return findPendingPacket(GlobalPacketId(from, id)); } + PendingPacket *findPendingPacket(GlobalPacketId p); + + /** + * Add p to the list of packets to retransmit occasionally. We will free it once we stop retransmitting. + */ + PendingPacket *startRetransmission(meshtastic_MeshPacket *p); + private: /** * Get the next hop for a destination, given the relay node * @return the node number of the next hop, 0 if no preference (fallback to FloodingRouter) */ uint8_t getNextHop(NodeNum to, uint8_t relay_node); + + /** + * Stop any retransmissions we are doing of the specified node/packet ID pair + * + * @return true if we found and removed a transmission with this ID + */ + bool stopRetransmission(NodeNum from, PacketId id); + bool stopRetransmission(GlobalPacketId p); + + /** + * Do any retransmissions that are scheduled (FIXME - for the time being called from loop) + * + * @return the number of msecs until our next retransmission or MAXINT if none scheduled + */ + int32_t doRetransmissions(); + + void setNextTx(PendingPacket *pending); }; \ No newline at end of file diff --git a/src/mesh/ReliableRouter.h b/src/mesh/ReliableRouter.h index c5ceff73b..ed278349a 100644 --- a/src/mesh/ReliableRouter.h +++ b/src/mesh/ReliableRouter.h @@ -3,59 +3,11 @@ #include "NextHopRouter.h" #include -/** - * An identifier for a globalally unique message - a pair of the sending nodenum and the packet id assigned - * to that message - */ -struct GlobalPacketId { - NodeNum node; - PacketId id; - - bool operator==(const GlobalPacketId &p) const { return node == p.node && id == p.id; } - - explicit GlobalPacketId(const meshtastic_MeshPacket *p) - { - node = getFrom(p); - id = p->id; - } - - GlobalPacketId(NodeNum _from, PacketId _id) - { - node = _from; - id = _id; - } -}; - -/** - * A packet queued for retransmission - */ -struct PendingPacket { - meshtastic_MeshPacket *packet; - - /** The next time we should try to retransmit this packet */ - uint32_t nextTxMsec = 0; - - /** Starts at NUM_RETRANSMISSIONS -1(normally 3) and counts down. Once zero it will be removed from the list */ - uint8_t numRetransmissions = 0; - - PendingPacket() {} - explicit PendingPacket(meshtastic_MeshPacket *p); -}; - -class GlobalPacketIdHashFunction -{ - public: - size_t operator()(const GlobalPacketId &p) const { return (std::hash()(p.node)) ^ (std::hash()(p.id)); } -}; - /** * This is a mixin that extends Router with the ability to do (one hop only) reliable message sends. */ class ReliableRouter : public NextHopRouter { - private: - std::unordered_map pending; - public: /** * Constructor @@ -70,54 +22,14 @@ class ReliableRouter : public NextHopRouter */ virtual ErrorCode send(meshtastic_MeshPacket *p) override; - /** Do our retransmission handling */ - virtual int32_t runOnce() override - { - // Note: We must doRetransmissions FIRST, because it might queue up work for the base class runOnce implementation - auto d = doRetransmissions(); - - int32_t r = FloodingRouter::runOnce(); - - return min(d, r); - } - protected: /** * Look for acks/naks or someone retransmitting us */ virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override; - /** - * Try to find the pending packet record for this ID (or NULL if not found) - */ - PendingPacket *findPendingPacket(NodeNum from, PacketId id) { return findPendingPacket(GlobalPacketId(from, id)); } - PendingPacket *findPendingPacket(GlobalPacketId p); - /** * We hook this method so we can see packets before FloodingRouter says they should be discarded */ virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) override; - - /** - * Add p to the list of packets to retransmit occasionally. We will free it once we stop retransmitting. - */ - PendingPacket *startRetransmission(meshtastic_MeshPacket *p); - - private: - /** - * Stop any retransmissions we are doing of the specified node/packet ID pair - * - * @return true if we found and removed a transmission with this ID - */ - bool stopRetransmission(NodeNum from, PacketId id); - bool stopRetransmission(GlobalPacketId p); - - /** - * Do any retransmissions that are scheduled (FIXME - for the time being called from loop) - * - * @return the number of msecs until our next retransmission or MAXINT if none scheduled - */ - int32_t doRetransmissions(); - - void setNextTx(PendingPacket *pending); }; \ No newline at end of file