diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp index 65cb4ce36..4ebd2f4d7 100644 --- a/src/mesh/MeshPlugin.cpp +++ b/src/mesh/MeshPlugin.cpp @@ -66,7 +66,7 @@ MeshPacket *MeshPlugin::allocErrorResponse(Routing_Error err, const MeshPacket * return r; } -void MeshPlugin::callPlugins(const MeshPacket &mp) +void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src) { // DEBUG_MSG("In call plugins\n"); bool pluginFound = false; @@ -79,6 +79,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) // Was this message directed to us specifically? Will be false if we are sniffing someone elses packets auto ourNodeNum = nodeDB.getNodeNum(); bool toUs = mp.to == NODENUM_BROADCAST || mp.to == ourNodeNum; + for (auto i = plugins->begin(); i != plugins->end(); ++i) { auto &pi = **i; @@ -87,6 +88,11 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) /// We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious) bool wantsPacket = (isDecoded || pi.encryptedOk) && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp); + if ((src == RX_SRC_LOCAL) && !(pi.loopbackOk)) { + // new case, monitor separately for now, then FIXME merge above + wantsPacket = false; + } + assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time if (wantsPacket) { @@ -169,7 +175,9 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) } if (!pluginFound) - DEBUG_MSG("No plugins interested in portnum=%d\n", mp.decoded.portnum); + DEBUG_MSG("No plugins interested in portnum=%d, src=%s\n", + mp.decoded.portnum, + (src == RX_SRC_LOCAL) ? "LOCAL":"REMOTE"); } MeshPacket *MeshPlugin::allocReply() diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index 937c37dfe..2350c951a 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -33,7 +33,7 @@ class MeshPlugin /** For use only by MeshService */ - static void callPlugins(const MeshPacket &mp); + static void callPlugins(const MeshPacket &mp, RxSource src = RX_SRC_RADIO); static std::vector GetMeshPluginsWithUIFrames(); #ifndef NO_SCREEN @@ -48,6 +48,10 @@ class MeshPlugin */ bool isPromiscuous = false; + /** Also receive a copy of LOCALLY GENERATED messages - most plugins should leave + * this setting disabled - see issue #877 */ + bool loopbackOk = false; + /** Most plugins only understand decrypted packets. For plugins that also want to see encrypted packets, they should set this * flag */ bool encryptedOk = false; diff --git a/src/mesh/MeshTypes.h b/src/mesh/MeshTypes.h index 34d4f02c9..d45194d4f 100644 --- a/src/mesh/MeshTypes.h +++ b/src/mesh/MeshTypes.h @@ -15,6 +15,14 @@ typedef uint32_t PacketId; // A packet sequence number #define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER #define ERRNO_DISABLED 34 // the itnerface is disabled +/* + * Source of a received message + */ +enum RxSource { + RX_SRC_LOCAL, // message was generated locally + RX_SRC_RADIO // message was received from radio mesh +}; + /** * the max number of hops a message can pass through, used as the default max for hop_limit in MeshPacket. * diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 1c5d70101..3cf81be2f 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -161,7 +161,7 @@ ErrorCode Router::sendLocal(MeshPacket *p) // If we are sending a broadcast, we also treat it as if we just received it ourself // this allows local apps (and PCs) to see broadcasts sourced locally if (p->to == NODENUM_BROADCAST) { - handleReceived(p); + handleReceived(p, RX_SRC_LOCAL); } return send(p); @@ -324,7 +324,7 @@ NodeNum Router::getNodeNum() * 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. */ -void Router::handleReceived(MeshPacket *p) +void Router::handleReceived(MeshPacket *p, RxSource src) { // Also, we should set the time from the ISR and it should have msec level resolution p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone @@ -333,13 +333,16 @@ void Router::handleReceived(MeshPacket *p) bool decoded = perhapsDecode(p); if (decoded) { // parsing was successful, queue for our recipient - printPacket("handleReceived", p); + if (src == RX_SRC_LOCAL) + printPacket("handleReceived(local)", p); + else + printPacket("handleReceived(remote)", p); } else { printPacket("packet decoding failed (no PSK?)", p); } // call plugins here - MeshPlugin::callPlugins(*p); + MeshPlugin::callPlugins(*p, src); } void Router::perhapsHandleReceived(MeshPacket *p) diff --git a/src/mesh/Router.h b/src/mesh/Router.h index 9d7358af5..519f158f7 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -122,7 +122,7 @@ class Router : protected concurrency::OSThread * 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); + void handleReceived(MeshPacket *p, RxSource src = RX_SRC_RADIO); /** Frees the provided packet, and generates a NAK indicating the speicifed error while sending */ void abortSendAndNak(Routing_Error err, MeshPacket *p);