From 69a11e7375efa1624f1a884b0a35ca80e47b9fdf Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 17 Feb 2021 19:04:41 +0800 Subject: [PATCH] WIP phone api changes for dev1.2 --- src/mesh/MeshPlugin.cpp | 25 +++++++++---- src/mesh/MeshPlugin.h | 2 +- src/mesh/MeshService.cpp | 1 - src/mesh/MeshService.h | 2 -- src/mesh/NodeDB.cpp | 9 +++-- src/mesh/ProtobufPlugin.h | 16 ++++++--- src/mesh/Router.cpp | 5 +-- src/mesh/Router.h | 4 --- src/mesh/SinglePortPlugin.h | 2 +- src/mesh/generated/mesh.pb.h | 52 ++++++++++++++-------------- src/plugins/NodeInfoPlugin.cpp | 6 ++-- src/plugins/NodeInfoPlugin.h | 2 +- src/plugins/PositionPlugin.cpp | 6 ++-- src/plugins/PositionPlugin.h | 2 +- src/plugins/RemoteHardwarePlugin.cpp | 3 +- src/plugins/RemoteHardwarePlugin.h | 2 +- src/plugins/RoutingPlugin.cpp | 4 +-- src/plugins/RoutingPlugin.h | 2 +- 18 files changed, 82 insertions(+), 63 deletions(-) diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp index 7befb6623..763d4d46e 100644 --- a/src/mesh/MeshPlugin.cpp +++ b/src/mesh/MeshPlugin.cpp @@ -28,22 +28,35 @@ void MeshPlugin::callPlugins(const MeshPacket &mp) { // DEBUG_MSG("In call plugins\n"); bool pluginFound = false; + + 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 + bool toUs = mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum(); for (auto i = plugins->begin(); i != plugins->end(); ++i) { auto &pi = **i; pi.currentRequest = ∓ - if (pi.wantPortnum(mp.decoded.portnum)) { + + // 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); + if (wantsPacket) { pluginFound = true; bool handled = pi.handleReceived(mp); - // Possibly send replies - if (mp.decoded.want_response) + // Possibly send replies (but only if the message was directed to us specifically, i.e. not for promiscious sniffing) + if (mp.decoded.want_response && toUs) { pi.sendResponse(mp); - - DEBUG_MSG("Plugin %s handled=%d\n", pi.name, handled); - if (handled) + 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; + } } pi.currentRequest = NULL; diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index 1c90f8829..11f579fa9 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -55,7 +55,7 @@ class MeshPlugin /** * @return true if you want to receive the specified portnum */ - virtual bool wantPortnum(PortNum p) = 0; + virtual bool wantPacket(const MeshPacket *p) = 0; /** Called to handle a particular incoming message diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index ae53e802f..753d942df 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -65,7 +65,6 @@ void MeshService::init() if (gps) gpsObserver.observe(&gps->newStatus); - packetReceivedObserver.observe(&router->notifyPacketReceived); } diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index 8cba07710..6cf52a00e 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -19,8 +19,6 @@ class MeshService { CallbackObserver gpsObserver = CallbackObserver(this, &MeshService::onGPSChanged); - CallbackObserver packetReceivedObserver = - CallbackObserver(this, &MeshService::handleFromRadio); /// received packets waiting for the phone to process them /// FIXME, change to a DropOldestQueue and keep a count of the number of dropped packets to ensure diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 3cc6b000b..6e81acd76 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -357,7 +357,13 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p) DEBUG_MSG("DB update position node=0x%x time=%u, latI=%d, lonI=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i); + auto oldtime = info->position.time; info->position = p; + if(p.time == 0 && oldtime != 0) { + // A lot of position reports don't have time populated. In that case, be careful to not blow away the time we + // recorded based on the packet rxTime + info->position.time = oldtime; + } info->has_position = true; updateGUIforNode = info; notifyObservers(true); // Force an update whether or not our node counts have changed @@ -405,9 +411,6 @@ void NodeDB::updateFrom(const MeshPacket &mp) } info->snr = mp.rx_snr; // keep the most recent SNR we received for this node. - - if (mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum()) - MeshPlugin::callPlugins(mp); } } diff --git a/src/mesh/ProtobufPlugin.h b/src/mesh/ProtobufPlugin.h index d931185e0..c68885df2 100644 --- a/src/mesh/ProtobufPlugin.h +++ b/src/mesh/ProtobufPlugin.h @@ -25,8 +25,11 @@ template class ProtobufPlugin : protected SinglePortPlugin /** * Handle a received message, the data field in the message is already decoded and is provided + * + * In general decoded will always be !NULL. But in some special applications (where you have handling packets + * for multiple port numbers, decoding will ONLY be attempted for packets where the portnum matches our expected ourPortNum. */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const T &decoded) = 0; + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const T *decoded) = 0; /** * Return a mesh packet which has been preinited with a particular protobuf data payload and port number. @@ -58,9 +61,14 @@ template class ProtobufPlugin : protected SinglePortPlugin DEBUG_MSG("Received %s from=0x%0x, id=0x%x, payloadlen=%d\n", name, mp.from, mp.id, p.payload.size); T scratch; - if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) - return handleReceivedProtobuf(mp, scratch); + T *decoded = NULL; + if(mp.decoded.portnum == ourPortNum) { + if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) + decoded = &scratch; + else + DEBUG_MSG("Error decoding protobuf plugin!\n"); + } - return false; // Let others look at this message also if they want + return handleReceivedProtobuf(mp, decoded); } }; diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index f20cf02bf..7876ddde4 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -244,12 +244,13 @@ void Router::handleReceived(MeshPacket *p) if (perhapsDecode(p)) { // parsing was successful, queue for our recipient - assert(0); // FIXME, call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api + // call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api // sniffReceived(p); + MeshPlugin::callPlugins(*p); if (p->to == NODENUM_BROADCAST || p->to == getNodeNum()) { printPacket("Delivering rx packet", p); - notifyPacketReceived.notifyObservers(p); + meshservice.handleFromRadio(p); } } } diff --git a/src/mesh/Router.h b/src/mesh/Router.h index e9a10dae1..17297ba14 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -21,10 +21,6 @@ class Router : protected concurrency::OSThread RadioInterface *iface = NULL; public: - /// Local services that want to see _every_ packet this node receives can observe this. - /// Observers should always return 0 and _copy_ any packets they want to keep for use later (this packet will be getting - /// freed) - Observable notifyPacketReceived; /** * Constructor diff --git a/src/mesh/SinglePortPlugin.h b/src/mesh/SinglePortPlugin.h index 5fa609dd4..305532dc5 100644 --- a/src/mesh/SinglePortPlugin.h +++ b/src/mesh/SinglePortPlugin.h @@ -21,7 +21,7 @@ class SinglePortPlugin : public MeshPlugin /** * @return true if you want to receive the specified portnum */ - virtual bool wantPortnum(PortNum p) { return p == ourPortNum; } + virtual bool wantPacket(const MeshPacket *p) { return p->decoded.portnum == ourPortNum; } /** * Return a mesh packet which has been preinited as a data packet with a particular port number. diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index ca47ffa89..106444eb3 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -240,15 +240,15 @@ typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t; typedef struct _MeshPacket { uint32_t from; uint32_t to; + uint32_t channel_index; pb_size_t which_payloadVariant; union { Data decoded; MeshPacket_encrypted_t encrypted; }; - uint32_t channel_index; uint32_t id; - float rx_snr; uint32_t rx_time; + float rx_snr; uint32_t hop_limit; bool want_ack; MeshPacket_Priority priority; @@ -364,7 +364,7 @@ extern "C" { #define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define Routing_init_default {0, {RouteDiscovery_init_default}, 0} #define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0} -#define MeshPacket_init_default {0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN} +#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN} #define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0} #define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} @@ -379,7 +379,7 @@ extern "C" { #define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define Routing_init_zero {0, {RouteDiscovery_init_zero}, 0} #define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0} -#define MeshPacket_init_zero {0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN} +#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN} #define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0} #define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} @@ -404,9 +404,9 @@ extern "C" { #define ChannelSettings_downlink_enabled_tag 17 #define Data_portnum_tag 1 #define Data_payload_tag 2 -#define Data_want_response_tag 5 -#define Data_dest_tag 9 -#define Data_source_tag 12 +#define Data_want_response_tag 3 +#define Data_dest_tag 4 +#define Data_source_tag 5 #define LogRecord_message_tag 1 #define LogRecord_time_tag 2 #define LogRecord_source_tag 3 @@ -480,15 +480,15 @@ extern "C" { #define Channel_role_tag 3 #define MeshPacket_from_tag 1 #define MeshPacket_to_tag 2 -#define MeshPacket_decoded_tag 3 -#define MeshPacket_encrypted_tag 8 -#define MeshPacket_channel_index_tag 4 +#define MeshPacket_channel_index_tag 3 +#define MeshPacket_decoded_tag 4 +#define MeshPacket_encrypted_tag 5 #define MeshPacket_id_tag 6 -#define MeshPacket_rx_snr_tag 7 -#define MeshPacket_rx_time_tag 9 -#define MeshPacket_hop_limit_tag 10 -#define MeshPacket_want_ack_tag 11 -#define MeshPacket_priority_tag 12 +#define MeshPacket_rx_time_tag 7 +#define MeshPacket_rx_snr_tag 8 +#define MeshPacket_hop_limit_tag 9 +#define MeshPacket_want_ack_tag 10 +#define MeshPacket_priority_tag 11 #define NodeInfo_num_tag 1 #define NodeInfo_user_tag 2 #define NodeInfo_position_tag 3 @@ -554,24 +554,24 @@ X(a, STATIC, SINGULAR, FIXED32, original_id, 6) #define Data_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ X(a, STATIC, SINGULAR, BYTES, payload, 2) \ -X(a, STATIC, SINGULAR, BOOL, want_response, 5) \ -X(a, STATIC, SINGULAR, FIXED32, dest, 9) \ -X(a, STATIC, SINGULAR, FIXED32, source, 12) +X(a, STATIC, SINGULAR, BOOL, want_response, 3) \ +X(a, STATIC, SINGULAR, FIXED32, dest, 4) \ +X(a, STATIC, SINGULAR, FIXED32, source, 5) #define Data_CALLBACK NULL #define Data_DEFAULT NULL #define MeshPacket_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, FIXED32, from, 1) \ X(a, STATIC, SINGULAR, FIXED32, to, 2) \ -X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 3) \ -X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 8) \ -X(a, STATIC, SINGULAR, UINT32, channel_index, 4) \ +X(a, STATIC, SINGULAR, UINT32, channel_index, 3) \ +X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 4) \ +X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 5) \ X(a, STATIC, SINGULAR, FIXED32, id, 6) \ -X(a, STATIC, SINGULAR, FLOAT, rx_snr, 7) \ -X(a, STATIC, SINGULAR, FIXED32, rx_time, 9) \ -X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \ -X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \ -X(a, STATIC, SINGULAR, UENUM, priority, 12) +X(a, STATIC, SINGULAR, FIXED32, rx_time, 7) \ +X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \ +X(a, STATIC, SINGULAR, UINT32, hop_limit, 9) \ +X(a, STATIC, SINGULAR, BOOL, want_ack, 10) \ +X(a, STATIC, SINGULAR, UENUM, priority, 11) #define MeshPacket_CALLBACK NULL #define MeshPacket_DEFAULT NULL #define MeshPacket_payloadVariant_decoded_MSGTYPE Data diff --git a/src/plugins/NodeInfoPlugin.cpp b/src/plugins/NodeInfoPlugin.cpp index a04ec4159..2524ffa58 100644 --- a/src/plugins/NodeInfoPlugin.cpp +++ b/src/plugins/NodeInfoPlugin.cpp @@ -8,10 +8,9 @@ NodeInfoPlugin *nodeInfoPlugin; -bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, const User &p) +bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, const User *pptr) { - // FIXME - we currently update NodeInfo data in the DB only if the message was a broadcast or destined to us - // it would be better to update even if the message was destined to others. + auto p = *pptr; nodeDB.updateUser(mp.from, p); @@ -52,6 +51,7 @@ MeshPacket *NodeInfoPlugin::allocReply() NodeInfoPlugin::NodeInfoPlugin() : ProtobufPlugin("nodeinfo", PortNum_NODEINFO_APP, User_fields), concurrency::OSThread("NodeInfoPlugin") { + isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others setIntervalFromNow(30 * 1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup) } diff --git a/src/plugins/NodeInfoPlugin.h b/src/plugins/NodeInfoPlugin.h index f0a7efebd..eb2a16da1 100644 --- a/src/plugins/NodeInfoPlugin.h +++ b/src/plugins/NodeInfoPlugin.h @@ -26,7 +26,7 @@ class NodeInfoPlugin : public ProtobufPlugin, private concurrency::OSThrea @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const User &p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const User *p); /** 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. */ diff --git a/src/plugins/PositionPlugin.cpp b/src/plugins/PositionPlugin.cpp index 153d20cfc..251605865 100644 --- a/src/plugins/PositionPlugin.cpp +++ b/src/plugins/PositionPlugin.cpp @@ -10,15 +10,15 @@ PositionPlugin *positionPlugin; PositionPlugin::PositionPlugin() : ProtobufPlugin("position", PortNum_POSITION_APP, Position_fields), concurrency::OSThread("PositionPlugin") { + isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup) } -bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Position &p) +bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Position *pptr) { - // FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us - // it would be better to update even if the message was destined to others. + auto p = *pptr; if (p.time) { struct timeval tv; diff --git a/src/plugins/PositionPlugin.h b/src/plugins/PositionPlugin.h index 7a45c23a0..45c4884a5 100644 --- a/src/plugins/PositionPlugin.h +++ b/src/plugins/PositionPlugin.h @@ -33,7 +33,7 @@ class PositionPlugin : public ProtobufPlugin, private concurrency::OST @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Position &p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Position *p); /** 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. */ diff --git a/src/plugins/RemoteHardwarePlugin.cpp b/src/plugins/RemoteHardwarePlugin.cpp index 26b78c800..33130663f 100644 --- a/src/plugins/RemoteHardwarePlugin.cpp +++ b/src/plugins/RemoteHardwarePlugin.cpp @@ -47,8 +47,9 @@ RemoteHardwarePlugin::RemoteHardwarePlugin() { } -bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, const HardwareMessage &p) +bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, const HardwareMessage *pptr) { + auto p = *pptr; DEBUG_MSG("Received RemoteHardware typ=%d\n", p.typ); switch (p.typ) { diff --git a/src/plugins/RemoteHardwarePlugin.h b/src/plugins/RemoteHardwarePlugin.h index 5147a18e8..fad6e8386 100644 --- a/src/plugins/RemoteHardwarePlugin.h +++ b/src/plugins/RemoteHardwarePlugin.h @@ -27,7 +27,7 @@ class RemoteHardwarePlugin : public ProtobufPlugin, private con @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const HardwareMessage &p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const HardwareMessage *p); /** * Periodically read the gpios we have been asked to WATCH, if they have changed, diff --git a/src/plugins/RoutingPlugin.cpp b/src/plugins/RoutingPlugin.cpp index 6f4c2123b..d0bcaf6a9 100644 --- a/src/plugins/RoutingPlugin.cpp +++ b/src/plugins/RoutingPlugin.cpp @@ -8,9 +8,9 @@ RoutingPlugin *routingPlugin; -bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing &p) +bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing *p) { - + assert(0); return false; // Let others look at this message also if they want } diff --git a/src/plugins/RoutingPlugin.h b/src/plugins/RoutingPlugin.h index 080b8fe12..0d987f39e 100644 --- a/src/plugins/RoutingPlugin.h +++ b/src/plugins/RoutingPlugin.h @@ -19,7 +19,7 @@ class RoutingPlugin : public ProtobufPlugin @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Routing &p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Routing *p); /** 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. */