WIP phone api changes for dev1.2

This commit is contained in:
Kevin Hester 2021-02-17 19:04:41 +08:00
parent 60a01567d9
commit 69a11e7375
18 changed files with 82 additions and 63 deletions

View File

@ -28,22 +28,35 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
{ {
// DEBUG_MSG("In call plugins\n"); // DEBUG_MSG("In call plugins\n");
bool pluginFound = false; 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) { for (auto i = plugins->begin(); i != plugins->end(); ++i) {
auto &pi = **i; auto &pi = **i;
pi.currentRequest = ∓ 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; pluginFound = true;
bool handled = pi.handleReceived(mp); bool handled = pi.handleReceived(mp);
// Possibly send replies // Possibly send replies (but only if the message was directed to us specifically, i.e. not for promiscious sniffing)
if (mp.decoded.want_response) if (mp.decoded.want_response && toUs) {
pi.sendResponse(mp); pi.sendResponse(mp);
DEBUG_MSG("Plugin %s sent a response\n", pi.name);
DEBUG_MSG("Plugin %s handled=%d\n", pi.name, handled); }
if (handled) else {
DEBUG_MSG("Plugin %s considered\n", pi.name);
}
if (handled) {
DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
break; break;
}
} }
pi.currentRequest = NULL; pi.currentRequest = NULL;

View File

@ -55,7 +55,7 @@ class MeshPlugin
/** /**
* @return true if you want to receive the specified portnum * @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 /** Called to handle a particular incoming message

View File

@ -65,7 +65,6 @@ void MeshService::init()
if (gps) if (gps)
gpsObserver.observe(&gps->newStatus); gpsObserver.observe(&gps->newStatus);
packetReceivedObserver.observe(&router->notifyPacketReceived);
} }

View File

@ -19,8 +19,6 @@ class MeshService
{ {
CallbackObserver<MeshService, const meshtastic::GPSStatus *> gpsObserver = CallbackObserver<MeshService, const meshtastic::GPSStatus *> gpsObserver =
CallbackObserver<MeshService, const meshtastic::GPSStatus *>(this, &MeshService::onGPSChanged); CallbackObserver<MeshService, const meshtastic::GPSStatus *>(this, &MeshService::onGPSChanged);
CallbackObserver<MeshService, const MeshPacket *> packetReceivedObserver =
CallbackObserver<MeshService, const MeshPacket *>(this, &MeshService::handleFromRadio);
/// received packets waiting for the phone to process them /// 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 /// FIXME, change to a DropOldestQueue and keep a count of the number of dropped packets to ensure

View File

@ -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); 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; 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; info->has_position = true;
updateGUIforNode = info; updateGUIforNode = info;
notifyObservers(true); // Force an update whether or not our node counts have changed 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. 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);
} }
} }

View File

@ -25,8 +25,11 @@ template <class T> class ProtobufPlugin : protected SinglePortPlugin
/** /**
* Handle a received message, the data field in the message is already decoded and is provided * 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. * Return a mesh packet which has been preinited with a particular protobuf data payload and port number.
@ -58,9 +61,14 @@ template <class T> 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); DEBUG_MSG("Received %s from=0x%0x, id=0x%x, payloadlen=%d\n", name, mp.from, mp.id, p.payload.size);
T scratch; T scratch;
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) T *decoded = NULL;
return handleReceivedProtobuf(mp, scratch); 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);
} }
}; };

View File

@ -244,12 +244,13 @@ void Router::handleReceived(MeshPacket *p)
if (perhapsDecode(p)) { if (perhapsDecode(p)) {
// parsing was successful, queue for our recipient // 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); // sniffReceived(p);
MeshPlugin::callPlugins(*p);
if (p->to == NODENUM_BROADCAST || p->to == getNodeNum()) { if (p->to == NODENUM_BROADCAST || p->to == getNodeNum()) {
printPacket("Delivering rx packet", p); printPacket("Delivering rx packet", p);
notifyPacketReceived.notifyObservers(p); meshservice.handleFromRadio(p);
} }
} }
} }

View File

@ -21,10 +21,6 @@ class Router : protected concurrency::OSThread
RadioInterface *iface = NULL; RadioInterface *iface = NULL;
public: 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<const MeshPacket *> notifyPacketReceived;
/** /**
* Constructor * Constructor

View File

@ -21,7 +21,7 @@ class SinglePortPlugin : public MeshPlugin
/** /**
* @return true if you want to receive the specified portnum * @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. * Return a mesh packet which has been preinited as a data packet with a particular port number.

View File

@ -240,15 +240,15 @@ typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
typedef struct _MeshPacket { typedef struct _MeshPacket {
uint32_t from; uint32_t from;
uint32_t to; uint32_t to;
uint32_t channel_index;
pb_size_t which_payloadVariant; pb_size_t which_payloadVariant;
union { union {
Data decoded; Data decoded;
MeshPacket_encrypted_t encrypted; MeshPacket_encrypted_t encrypted;
}; };
uint32_t channel_index;
uint32_t id; uint32_t id;
float rx_snr;
uint32_t rx_time; uint32_t rx_time;
float rx_snr;
uint32_t hop_limit; uint32_t hop_limit;
bool want_ack; bool want_ack;
MeshPacket_Priority priority; MeshPacket_Priority priority;
@ -364,7 +364,7 @@ extern "C" {
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_default {0, {RouteDiscovery_init_default}, 0} #define Routing_init_default {0, {RouteDiscovery_init_default}, 0}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 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 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 Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} #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 RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_zero {0, {RouteDiscovery_init_zero}, 0} #define Routing_init_zero {0, {RouteDiscovery_init_zero}, 0}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 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 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 Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
@ -404,9 +404,9 @@ extern "C" {
#define ChannelSettings_downlink_enabled_tag 17 #define ChannelSettings_downlink_enabled_tag 17
#define Data_portnum_tag 1 #define Data_portnum_tag 1
#define Data_payload_tag 2 #define Data_payload_tag 2
#define Data_want_response_tag 5 #define Data_want_response_tag 3
#define Data_dest_tag 9 #define Data_dest_tag 4
#define Data_source_tag 12 #define Data_source_tag 5
#define LogRecord_message_tag 1 #define LogRecord_message_tag 1
#define LogRecord_time_tag 2 #define LogRecord_time_tag 2
#define LogRecord_source_tag 3 #define LogRecord_source_tag 3
@ -480,15 +480,15 @@ extern "C" {
#define Channel_role_tag 3 #define Channel_role_tag 3
#define MeshPacket_from_tag 1 #define MeshPacket_from_tag 1
#define MeshPacket_to_tag 2 #define MeshPacket_to_tag 2
#define MeshPacket_decoded_tag 3 #define MeshPacket_channel_index_tag 3
#define MeshPacket_encrypted_tag 8 #define MeshPacket_decoded_tag 4
#define MeshPacket_channel_index_tag 4 #define MeshPacket_encrypted_tag 5
#define MeshPacket_id_tag 6 #define MeshPacket_id_tag 6
#define MeshPacket_rx_snr_tag 7 #define MeshPacket_rx_time_tag 7
#define MeshPacket_rx_time_tag 9 #define MeshPacket_rx_snr_tag 8
#define MeshPacket_hop_limit_tag 10 #define MeshPacket_hop_limit_tag 9
#define MeshPacket_want_ack_tag 11 #define MeshPacket_want_ack_tag 10
#define MeshPacket_priority_tag 12 #define MeshPacket_priority_tag 11
#define NodeInfo_num_tag 1 #define NodeInfo_num_tag 1
#define NodeInfo_user_tag 2 #define NodeInfo_user_tag 2
#define NodeInfo_position_tag 3 #define NodeInfo_position_tag 3
@ -554,24 +554,24 @@ X(a, STATIC, SINGULAR, FIXED32, original_id, 6)
#define Data_FIELDLIST(X, a) \ #define Data_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
X(a, STATIC, SINGULAR, BYTES, payload, 2) \ X(a, STATIC, SINGULAR, BYTES, payload, 2) \
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \ X(a, STATIC, SINGULAR, BOOL, want_response, 3) \
X(a, STATIC, SINGULAR, FIXED32, dest, 9) \ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 12) X(a, STATIC, SINGULAR, FIXED32, source, 5)
#define Data_CALLBACK NULL #define Data_CALLBACK NULL
#define Data_DEFAULT NULL #define Data_DEFAULT NULL
#define MeshPacket_FIELDLIST(X, a) \ #define MeshPacket_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, FIXED32, from, 1) \ X(a, STATIC, SINGULAR, FIXED32, from, 1) \
X(a, STATIC, SINGULAR, FIXED32, to, 2) \ X(a, STATIC, SINGULAR, FIXED32, to, 2) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 3) \ X(a, STATIC, SINGULAR, UINT32, channel_index, 3) \
X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 8) \ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 4) \
X(a, STATIC, SINGULAR, UINT32, channel_index, 4) \ X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 5) \
X(a, STATIC, SINGULAR, FIXED32, id, 6) \ X(a, STATIC, SINGULAR, FIXED32, id, 6) \
X(a, STATIC, SINGULAR, FLOAT, rx_snr, 7) \ X(a, STATIC, SINGULAR, FIXED32, rx_time, 7) \
X(a, STATIC, SINGULAR, FIXED32, rx_time, 9) \ X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \ X(a, STATIC, SINGULAR, UINT32, hop_limit, 9) \
X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \ X(a, STATIC, SINGULAR, BOOL, want_ack, 10) \
X(a, STATIC, SINGULAR, UENUM, priority, 12) X(a, STATIC, SINGULAR, UENUM, priority, 11)
#define MeshPacket_CALLBACK NULL #define MeshPacket_CALLBACK NULL
#define MeshPacket_DEFAULT NULL #define MeshPacket_DEFAULT NULL
#define MeshPacket_payloadVariant_decoded_MSGTYPE Data #define MeshPacket_payloadVariant_decoded_MSGTYPE Data

View File

@ -8,10 +8,9 @@
NodeInfoPlugin *nodeInfoPlugin; 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 auto p = *pptr;
// it would be better to update even if the message was destined to others.
nodeDB.updateUser(mp.from, p); nodeDB.updateUser(mp.from, p);
@ -52,6 +51,7 @@ MeshPacket *NodeInfoPlugin::allocReply()
NodeInfoPlugin::NodeInfoPlugin() NodeInfoPlugin::NodeInfoPlugin()
: ProtobufPlugin("nodeinfo", PortNum_NODEINFO_APP, User_fields), concurrency::OSThread("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 * setIntervalFromNow(30 *
1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup) 1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup)
} }

View File

@ -26,7 +26,7 @@ class NodeInfoPlugin : public ProtobufPlugin<User>, private concurrency::OSThrea
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @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 /** 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. */ * so that subclasses can (optionally) send a response back to the original sender. */

View File

@ -10,15 +10,15 @@ PositionPlugin *positionPlugin;
PositionPlugin::PositionPlugin() PositionPlugin::PositionPlugin()
: ProtobufPlugin("position", PortNum_POSITION_APP, Position_fields), concurrency::OSThread("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 * setIntervalFromNow(60 *
1000); // Send our initial position 60 seconds after we start (to give GPS time to setup) 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 auto p = *pptr;
// it would be better to update even if the message was destined to others.
if (p.time) { if (p.time) {
struct timeval tv; struct timeval tv;

View File

@ -33,7 +33,7 @@ class PositionPlugin : public ProtobufPlugin<Position>, private concurrency::OST
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @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 /** 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. */ * so that subclasses can (optionally) send a response back to the original sender. */

View File

@ -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); DEBUG_MSG("Received RemoteHardware typ=%d\n", p.typ);
switch (p.typ) { switch (p.typ) {

View File

@ -27,7 +27,7 @@ class RemoteHardwarePlugin : public ProtobufPlugin<HardwareMessage>, private con
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @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, * Periodically read the gpios we have been asked to WATCH, if they have changed,

View File

@ -8,9 +8,9 @@
RoutingPlugin *routingPlugin; 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 return false; // Let others look at this message also if they want
} }

View File

@ -19,7 +19,7 @@ class RoutingPlugin : public ProtobufPlugin<Routing>
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @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 /** 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. */ * so that subclasses can (optionally) send a response back to the original sender. */