firmware/src/mesh/MeshPlugin.cpp

109 lines
3.6 KiB
C++
Raw Normal View History

#include "MeshPlugin.h"
#include "NodeDB.h"
2020-12-07 02:18:11 +00:00
#include "MeshService.h"
#include <assert.h>
std::vector<MeshPlugin *> *MeshPlugin::plugins;
2020-12-13 04:57:37 +00:00
const MeshPacket *MeshPlugin::currentRequest;
MeshPlugin::MeshPlugin(const char *_name) : name(_name)
{
// Can't trust static initalizer order, so we check each time
if(!plugins)
plugins = new std::vector<MeshPlugin *>();
plugins->push_back(this);
}
void MeshPlugin::setup() {
}
MeshPlugin::~MeshPlugin()
{
assert(0); // FIXME - remove from list of plugins once someone needs this feature
}
void MeshPlugin::callPlugins(const MeshPacket &mp)
{
// DEBUG_MSG("In call plugins\n");
2020-12-13 07:59:26 +00:00
bool pluginFound = false;
2021-02-17 11:04:41 +00:00
assert(mp.which_payloadVariant == MeshPacket_decoded_tag); // I think we are guarnteed the packet is decoded by this point?
// Was this message directed to us specifically? Will be false if we are sniffing someone elses packets
2021-02-23 03:43:30 +00:00
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;
2020-12-13 04:57:37 +00:00
pi.currentRequest = &mp;
2021-02-17 11:04:41 +00:00
// 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);
2021-02-23 06:35:34 +00:00
// DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
2021-02-17 11:04:41 +00:00
if (wantsPacket) {
2020-12-13 07:59:26 +00:00
pluginFound = true;
bool handled = pi.handleReceived(mp);
2021-02-23 03:43:30 +00:00
// Possibly send replies (but only if the message was directed to us specifically, i.e. not for promiscious sniffing), also not if we sent it
if (mp.decoded.want_response && toUs && mp.from != ourNodeNum) {
2020-12-07 02:18:11 +00:00
pi.sendResponse(mp);
2021-02-17 11:04:41 +00:00
DEBUG_MSG("Plugin %s sent a response\n", pi.name);
}
else {
DEBUG_MSG("Plugin %s considered\n", pi.name);
}
if (handled) {
DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
break;
2021-02-17 11:04:41 +00:00
}
}
2020-12-13 07:59:26 +00:00
2020-12-13 04:57:37 +00:00
pi.currentRequest = NULL;
}
2020-12-13 07:59:26 +00:00
if(!pluginFound)
2021-02-17 05:06:23 +00:00
DEBUG_MSG("No plugins interested in portnum=%d\n", mp.decoded.portnum);
2020-12-07 02:18:11 +00:00
}
/** 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. Implementing this method
* is optional
*/
void MeshPlugin::sendResponse(const MeshPacket &req) {
auto r = allocReply();
if(r) {
DEBUG_MSG("Sending response\n");
setReplyTo(r, req);
service.sendToMesh(r);
}
else {
2021-02-23 06:35:34 +00:00
// 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");
2020-12-07 02:18:11 +00:00
}
}
/** 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) {
p->to = to.from;
p->want_ack = to.want_ack;
}
std::vector<MeshPlugin *> MeshPlugin::GetMeshPluginsWithUIFrames() {
std::vector<MeshPlugin *> pluginsWithUIFrames;
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
auto &pi = **i;
if ( pi.wantUIFrame()) {
DEBUG_MSG("Plugin wants a UI Frame\n");
pluginsWithUIFrames.push_back(&pi);
}
}
return pluginsWithUIFrames;
}