From c9cb293bf25bca0fb9f3d2588dc28c05d2af045c Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 23 May 2020 09:24:22 -0700 Subject: [PATCH] cleanup virtual inheritence for Router/Reliable/Flooding/DSR --- src/mesh/DSRRouter.cpp | 14 ++++++--- src/mesh/FloodingRouter.cpp | 60 ++++++++++++++++++------------------- src/mesh/FloodingRouter.h | 14 +++++---- src/mesh/ReliableRouter.cpp | 30 +++++++++---------- src/mesh/ReliableRouter.h | 8 ++--- src/mesh/Router.cpp | 8 ++++- src/mesh/Router.h | 31 +++++++++++++++---- 7 files changed, 96 insertions(+), 69 deletions(-) diff --git a/src/mesh/DSRRouter.cpp b/src/mesh/DSRRouter.cpp index 00c2a80d3..60630b20d 100644 --- a/src/mesh/DSRRouter.cpp +++ b/src/mesh/DSRRouter.cpp @@ -48,7 +48,8 @@ void DSRRouter::sniffReceived(const MeshPacket *p) if (weAreInRoute(p->decoded.request)) { DEBUG_MSG("Ignoring a route request that contains us\n"); } else { - updateRoutes(p->decoded.request, false); // Update our routing tables based on the route that came in so far on this request + updateRoutes(p->decoded.request, + false); // Update our routing tables based on the route that came in so far on this request if (p->decoded.dest == getNodeNum()) { // They were looking for us, send back a route reply (the sender address will be first in the list) @@ -67,12 +68,17 @@ void DSRRouter::sniffReceived(const MeshPacket *p) } } + // Handle route reply packets + if (p->decoded.which_payload == SubPacket_reply_tag) { + updateRoutes(p->decoded.reply, true); + } + // Handle regular packets if (p->to == getNodeNum()) { // Destined for us (at least for this hop) - // We need to route this packet - if (p->decoded.dest != p->to) { - // FIXME + // We need to route this packet to some other node + if (p->decoded.dest && p->decoded.dest != p->to) { + // FIXME if we have a route out, resend the packet to the next hop, otherwise return a nak with no-route available } } diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index d3cc5cbde..0b7aea64a 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -17,39 +17,37 @@ ErrorCode FloodingRouter::send(MeshPacket *p) return Router::send(p); } -/** - * Called from loop() - * Handle any packet that is received by an interface on this node. - * Note: some packets may merely being passed through this node and will be forwarded elsewhere. - * - * Note: this method will free the provided packet - */ -void FloodingRouter::handleReceived(MeshPacket *p) +bool FloodingRouter::shouldFilterReceived(const MeshPacket *p) { if (wasSeenRecently(p)) { DEBUG_MSG("Ignoring incoming msg, because we've already seen it\n"); - packetPool.release(p); - } else { - // If a broadcast, possibly _also_ send copies out into the mesh. - // (FIXME, do something smarter than naive flooding here) - if (p->to == NODENUM_BROADCAST && p->hop_limit > 0) { - if (p->id != 0) { - MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it - - tosend->hop_limit--; // bump down the hop count - - DEBUG_MSG("Rebroadcasting received floodmsg to neighbors, fr=0x%x,to=0x%x,id=%d,hop_limit=%d\n", p->from, p->to, - p->id, tosend->hop_limit); - // Note: we are careful to resend using the original senders node id - // We are careful not to call our hooked version of send() - because we don't want to check this again - Router::send(tosend); - - } else { - DEBUG_MSG("Ignoring a simple (0 id) broadcast\n"); - } - } - - // handle the packet as normal - Router::handleReceived(p); + return true; } + + return Router::shouldFilterReceived(p); +} + +void FloodingRouter::sniffReceived(const MeshPacket *p) +{ + // If a broadcast, possibly _also_ send copies out into the mesh. + // (FIXME, do something smarter than naive flooding here) + if (p->to == NODENUM_BROADCAST && p->hop_limit > 0) { + if (p->id != 0) { + MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it + + tosend->hop_limit--; // bump down the hop count + + DEBUG_MSG("Rebroadcasting received floodmsg to neighbors, fr=0x%x,to=0x%x,id=%d,hop_limit=%d\n", p->from, p->to, + p->id, tosend->hop_limit); + // Note: we are careful to resend using the original senders node id + // We are careful not to call our hooked version of send() - because we don't want to check this again + Router::send(tosend); + + } else { + DEBUG_MSG("Ignoring a simple (0 id) broadcast\n"); + } + } + + // handle the packet as normal + Router::sniffReceived(p); } diff --git a/src/mesh/FloodingRouter.h b/src/mesh/FloodingRouter.h index 48a8f0bc7..699508d23 100644 --- a/src/mesh/FloodingRouter.h +++ b/src/mesh/FloodingRouter.h @@ -46,11 +46,15 @@ class FloodingRouter : public Router, protected PacketHistory protected: /** - * Called from loop() - * Handle any packet that is received by an interface on this node. - * Note: some packets may merely being passed through this node and will be forwarded elsewhere. + * Should this incoming filter be dropped? * - * Note: this method will free the provided packet + * Called immedately on receiption, before any further processing. + * @return true to abandon the packet */ - virtual void handleReceived(MeshPacket *p); + virtual bool shouldFilterReceived(const MeshPacket *p); + + /** + * Look for broadcasts we need to rebroadcast + */ + virtual void sniffReceived(const MeshPacket *p); }; diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index 0500f2799..c8e45a604 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -36,7 +36,7 @@ ErrorCode ReliableRouter::send(MeshPacket *p) * * Otherwise, let superclass handle it. */ -void ReliableRouter::handleReceived(MeshPacket *p) +void ReliableRouter::sniffReceived(const MeshPacket *p) { NodeNum ourNode = getNodeNum(); @@ -55,28 +55,26 @@ void ReliableRouter::handleReceived(MeshPacket *p) sendAckNak(true, p->from, p->id); } - if (perhapsDecode(p)) { - // If the payload is valid, look for ack/nak + // If the payload is valid, look for ack/nak - PacketId ackId = p->decoded.which_ack == SubPacket_success_id_tag ? p->decoded.ack.success_id : 0; - PacketId nakId = p->decoded.which_ack == SubPacket_fail_id_tag ? p->decoded.ack.fail_id : 0; + PacketId ackId = p->decoded.which_ack == SubPacket_success_id_tag ? p->decoded.ack.success_id : 0; + PacketId nakId = p->decoded.which_ack == SubPacket_fail_id_tag ? p->decoded.ack.fail_id : 0; - // we are careful to only read/update wasSeenRecently _after_ confirming this is an ack (to not mess - // up broadcasts) - if ((ackId || nakId) && !wasSeenRecently(p, false)) { - if (ackId) { - DEBUG_MSG("Received a ack=%d, stopping retransmissions\n", ackId); - stopRetransmission(p->to, ackId); - } else { - DEBUG_MSG("Received a nak=%d, stopping retransmissions\n", nakId); - stopRetransmission(p->to, nakId); - } + // we are careful to only read/update wasSeenRecently _after_ confirming this is an ack (to not mess + // up broadcasts) + if ((ackId || nakId) && !wasSeenRecently(p, false)) { + if (ackId) { + DEBUG_MSG("Received a ack=%d, stopping retransmissions\n", ackId); + stopRetransmission(p->to, ackId); + } else { + DEBUG_MSG("Received a nak=%d, stopping retransmissions\n", nakId); + stopRetransmission(p->to, nakId); } } } // handle the packet as normal - FloodingRouter::handleReceived(p); + FloodingRouter::sniffReceived(p); } /** diff --git a/src/mesh/ReliableRouter.h b/src/mesh/ReliableRouter.h index 7030793ae..f8a238341 100644 --- a/src/mesh/ReliableRouter.h +++ b/src/mesh/ReliableRouter.h @@ -88,13 +88,9 @@ class ReliableRouter : public FloodingRouter protected: /** - * Called from loop() - * Handle any packet that is received by an interface on this node. - * Note: some packets may merely being passed through this node and will be forwarded elsewhere. - * - * Note: this method will free the provided packet + * Look for acks/naks or someone retransmitting us */ - virtual void handleReceived(MeshPacket *p); + virtual void sniffReceived(const MeshPacket *p); private: /** diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 0ef7b8333..0b63247e9 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -40,7 +40,7 @@ void Router::loop() { MeshPacket *mp; while ((mp = fromRadioQueue.dequeuePtr(0)) != NULL) { - handleReceived(mp); + perhapsHandleReceived(mp); } } @@ -191,6 +191,12 @@ void Router::handleReceived(MeshPacket *p) notifyPacketReceived.notifyObservers(p); } } +} + +void Router::perhapsHandleReceived(MeshPacket *p) +{ + if (!shouldFilterReceived(p)) + handleReceived(p); packetPool.release(p); } \ No newline at end of file diff --git a/src/mesh/Router.h b/src/mesh/Router.h index 8c811667e..45f0b762c 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -67,14 +67,12 @@ class Router virtual ErrorCode send(MeshPacket *p); /** - * Called from loop() - * Handle any packet that is received by an interface on this node. - * Note: some packets may merely being passed through this node and will be forwarded elsewhere. + * Should this incoming filter be dropped? * - * Note: this packet will never be called for messages sent/generated by this node. - * Note: this method will free the provided packet. + * Called immedately on receiption, before any further processing. + * @return true to abandon the packet */ - virtual void handleReceived(MeshPacket *p); + virtual bool shouldFilterReceived(const MeshPacket *p) { return false; } /** * Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to @@ -88,6 +86,27 @@ class Router * @return true for success, false for corrupt packet. */ bool perhapsDecode(MeshPacket *p); + + private: + /** + * Called from loop() + * Handle any packet that is received by an interface on this node. + * Note: some packets may merely being passed through this node and will be forwarded elsewhere. + * + * Note: this packet will never be called for messages sent/generated by this node. + * Note: this method will free the provided packet. + */ + void perhapsHandleReceived(MeshPacket *p); + + /** + * Called from perhapsHandleReceived() - allows subclass message delivery behavior. + * Handle any packet that is received by an interface on this node. + * Note: some packets may merely being passed through this node and will be forwarded elsewhere. + * + * Note: this packet will never be called for messages sent/generated by this node. + * Note: this method will free the provided packet. + */ + void handleReceived(MeshPacket *p); }; extern Router &router;