diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp index e17cc5475..68a63116e 100644 --- a/src/mesh/MeshPlugin.cpp +++ b/src/mesh/MeshPlugin.cpp @@ -1,4 +1,5 @@ #include "MeshPlugin.h" +#include "Channels.h" #include "MeshService.h" #include "NodeDB.h" #include @@ -11,7 +12,7 @@ const MeshPacket *MeshPlugin::currentRequest; * If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow * the RoutingPlugin to avoid sending redundant acks */ - MeshPacket *MeshPlugin::currentReply; +MeshPacket *MeshPlugin::currentReply; MeshPlugin::MeshPlugin(const char *_name) : name(_name) { @@ -46,8 +47,15 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) pi.currentRequest = ∓ - // We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious) - bool wantsPacket = (pi.isPromiscuous || toUs) && pi.wantPacket(&mp); + /// received channel + auto ch = channels.getByIndex(mp.channel); + assert(ch.has_settings); + + /// Is the channel this packet arrived on acceptable? (security check) + bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcmp(ch.settings.name, pi.boundChannel) == 0); + + /// We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious) + bool wantsPacket = rxChannelOk && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp); // DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket); if (wantsPacket) { pluginFound = true; @@ -76,8 +84,8 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) pi.currentRequest = NULL; } - if(currentReply) { - DEBUG_MSG("Sending response\n"); + if (currentReply) { + DEBUG_MSG("Sending response\n"); service.sendToMesh(currentReply); currentReply = NULL; } @@ -95,7 +103,7 @@ void MeshPlugin::sendResponse(const MeshPacket &req) auto r = allocReply(); if (r) { setReplyTo(r, req); - currentReply = r; + currentReply = r; } else { // Ignore - this is now expected behavior for routing plugin (because it ignores some replies) // DEBUG_MSG("WARNING: Client requested response but this plugin did not provide\n"); @@ -109,10 +117,11 @@ void setReplyTo(MeshPacket *p, const MeshPacket &to) { assert(p->which_payloadVariant == MeshPacket_decoded_tag); // Should already be set by now p->to = getFrom(&to); + p->channel = to.channel; // Use the same channel that the request came in on // No need for an ack if we are just delivering locally (it just generates an ignored ack) p->want_ack = (to.from != 0) ? to.want_ack : false; - if(p->priority == MeshPacket_Priority_UNSET) + if (p->priority == MeshPacket_Priority_UNSET) p->priority = MeshPacket_Priority_RELIABLE; p->decoded.request_id = to.id; } diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index 7234b6b0a..dc905a0e5 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -1,9 +1,9 @@ #pragma once #include "mesh/MeshTypes.h" -#include #include #include +#include /** A baseclass for any mesh "plugin". * * A plugin allows you to add new features to meshtastic device code, without needing to know messaging details. @@ -16,7 +16,7 @@ */ class MeshPlugin { - static std::vector *plugins; + static std::vector *plugins; public: /** Constructor @@ -37,16 +37,24 @@ class MeshPlugin protected: const char *name; - /* Most plugins only care about packets that are destined for their node (i.e. broadcasts or has their node as the specific recipient) - But some plugs might want to 'sniff' packets that are merely being routed (passing through the current node). Those plugins can set this to - true and their handleReceived() will be called for every packet. + /* Most plugins only care about packets that are destined for their node (i.e. broadcasts or has their node as the specific + recipient) But some plugs might want to 'sniff' packets that are merely being routed (passing through the current node). Those + plugins can set this to true and their handleReceived() will be called for every packet. */ bool isPromiscuous = false; + /** If a bound channel name is set, we will only accept received packets that come in on that channel. + * A special exception (FIXME, not sure if this is a good idea) - packets that arrive on the local interface + * are allowed on any channel (this lets the local user do anything). + * + * We will send responses on the same channel that the request arrived on. + */ + const char *boundChannel = NULL; + /** * If this plugin is currently handling a request currentRequest will be preset * to the packet with the request. This is mostly useful for reply handlers. - * + * * Note: this can be static because we are guaranteed to be processing only one * plugin at a time. */ @@ -78,16 +86,13 @@ class MeshPlugin */ virtual bool wantUIFrame() { return false; } - - private: - /** - * If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow + * If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow * the RoutingPlugin to avoid sending redundant acks */ static MeshPacket *currentReply; - friend class ReliableRouter; + friend class ReliableRouter; /** Messages can be received that have the want_response bit set. If set, this callback will be invoked * so that subclasses can (optionally) send a response back to the original sender. This method calls allocReply() @@ -96,7 +101,7 @@ class MeshPlugin void sendResponse(const MeshPacket &req); }; -/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet +/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet * This ensures that if the request packet was sent reliably, the reply is sent that way as well. -*/ + */ void setReplyTo(MeshPacket *p, const MeshPacket &to); \ No newline at end of file diff --git a/src/plugins/AdminPlugin.cpp b/src/plugins/AdminPlugin.cpp index 7e0a67074..f45f61655 100644 --- a/src/plugins/AdminPlugin.cpp +++ b/src/plugins/AdminPlugin.cpp @@ -8,8 +8,9 @@ AdminPlugin *adminPlugin; -void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) { - if (req.decoded.want_response) { +void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) +{ + if (req.decoded.want_response) { // We create the reply here AdminMessage r = AdminMessage_init_default; r.get_channel_response = channels.getByIndex(channelIndex); @@ -121,5 +122,6 @@ MeshPacket *AdminPlugin::allocReply() AdminPlugin::AdminPlugin() : ProtobufPlugin("Admin", PortNum_ADMIN_APP, AdminMessage_fields) { - // FIXME, restrict to the admin channel for rx + // restrict to the admin channel for rx + boundChannel = "admin"; }