From ee8f4de5abf33af34ae05d92c425d791392c4cae Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 13 Dec 2020 12:57:37 +0800 Subject: [PATCH] make plugin reply handling simpler --- docs/software/TODO.md | 7 ++++--- src/mesh/MeshPlugin.cpp | 9 +++++++-- src/mesh/MeshPlugin.h | 9 +++++++++ src/plugins/ReplyPlugin.cpp | 12 ++++++------ src/plugins/ReplyPlugin.h | 7 +++---- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 46f943c07..50796ef1b 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -11,8 +11,9 @@ For app cleanup: * DONE update android code: https://developer.android.com/topic/libraries/view-binding/migration * only do wantReplies once per packet type, if we change network settings force it again * test GPIO watch -* DONE make hello world example service +* writeup docs on gpio * make python ping command +* DONE make hello world example service * DONE have python tool check max packet size before sending to device * DONE if request was sent reliably, send reply reliably * DONE require a recent python api to talk to these new device loads @@ -20,8 +21,8 @@ For app cleanup: * DONE fix handleIncomingPosition * DONE move want_replies handling into plugins * DONE on android for received positions handle either old or new positions / user messages -* on android side send old or new positions as needed / user messages -* test python side handle new position/user messages +* DONE on android side send old or new positions as needed / user messages +* DONE test python side handle new position/user messages * DONE make a gpio example. --gpiowrb 4 1, --gpiord 0x444, --gpiowatch 0x3ff * DONE fix position sending to use new plugin * DONE Add SinglePortNumPlugin - as the new most useful baseclass diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp index 5320b7ae1..e2a6bf289 100644 --- a/src/mesh/MeshPlugin.cpp +++ b/src/mesh/MeshPlugin.cpp @@ -5,6 +5,8 @@ std::vector *MeshPlugin::plugins; +const MeshPacket *MeshPlugin::currentRequest; + MeshPlugin::MeshPlugin(const char *_name) : name(_name) { // Can't trust static initalizer order, so we check each time @@ -27,11 +29,13 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) // DEBUG_MSG("In call plugins\n"); for (auto i = plugins->begin(); i != plugins->end(); ++i) { auto &pi = **i; + + pi.currentRequest = ∓ if (pi.wantPortnum(mp.decoded.data.portnum)) { bool handled = pi.handleReceived(mp); - // Possibly send replies (unless we are handling a locally generated message) - if (mp.decoded.want_response && mp.from != nodeDB.getNodeNum()) + // Possibly send replies + if (mp.decoded.want_response) pi.sendResponse(mp); DEBUG_MSG("Plugin %s handled=%d\n", pi.name, handled); @@ -41,6 +45,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) else { DEBUG_MSG("Plugin %s not interested\n", pi.name); } + pi.currentRequest = NULL; } } diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index f753651ec..01af58114 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -31,6 +31,15 @@ class MeshPlugin protected: const char *name; + /** + * 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. + */ + static const MeshPacket *currentRequest; + /** * Initialize your plugin. This setup function is called once after all hardware and mesh protocol layers have * been initialized diff --git a/src/plugins/ReplyPlugin.cpp b/src/plugins/ReplyPlugin.cpp index d5c9e727d..788edc55e 100644 --- a/src/plugins/ReplyPlugin.cpp +++ b/src/plugins/ReplyPlugin.cpp @@ -1,6 +1,6 @@ -#include "configuration.h" #include "ReplyPlugin.h" #include "MeshService.h" +#include "configuration.h" #include "main.h" #include @@ -8,8 +8,10 @@ // Create an a static instance of our plugin - this registers with the plugin system ReplyPlugin replyPlugin; -bool ReplyPlugin::handleReceived(const MeshPacket &req) +MeshPacket *ReplyPlugin::allocReply() { + assert(currentRequest); // should always be !NULL + auto req = *currentRequest; auto &p = req.decoded.data; // The incoming message is in p.payload DEBUG_MSG("Received message from=0x%0x, id=%d, msg=%.*s\n", req.from, req.id, p.payload.size, p.payload.bytes); @@ -17,11 +19,9 @@ bool ReplyPlugin::handleReceived(const MeshPacket &req) screen->print("Sending reply\n"); const char *replyStr = "Message Received"; - auto reply = allocDataPacket(); // Allocate a packet for sending + auto reply = allocDataPacket(); // Allocate a packet for sending reply->decoded.data.payload.size = strlen(replyStr); // You must specify how many bytes are in the reply memcpy(reply->decoded.data.payload.bytes, replyStr, reply->decoded.data.payload.size); - setReplyTo(reply, req); // Set packet params so that this packet is marked as a reply to a previous request - service.sendToMesh(reply); // Queue the reply for sending - return true; // We handled it + return reply; } diff --git a/src/plugins/ReplyPlugin.h b/src/plugins/ReplyPlugin.h index 0d3686b57..7d0ff8b71 100644 --- a/src/plugins/ReplyPlugin.h +++ b/src/plugins/ReplyPlugin.h @@ -15,9 +15,8 @@ class ReplyPlugin : public SinglePortPlugin protected: - /** Called to handle a particular incoming message - - @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + /** For reply plugin we do all of our processing in the (normally optional) + * want_replies handling */ - virtual bool handleReceived(const MeshPacket &mp); + virtual MeshPacket *allocReply(); };