From e79c49d10033259327c94e74e365f22e788667f7 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 12 Feb 2020 14:07:06 -0800 Subject: [PATCH] send network pings when the user does something with their device --- TODO.md | 8 ++++---- src/MeshService.cpp | 49 +++++++++++++++++++++++++++++++++++++++++---- src/MeshService.h | 5 +++++ src/NodeDB.cpp | 8 ++++++++ src/main.ino | 1 + src/mesh.pb.h | 16 +++++++-------- 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/TODO.md b/TODO.md index 3b73c78e..3ab71ce2 100644 --- a/TODO.md +++ b/TODO.md @@ -1,11 +1,7 @@ # High priority -* send user and location events much less often -* send location (or if not available user) when the user wakes the device from display sleep (both for testing and to improve user experience) * have node info screen show real info (including time since last contact, distance and heading) * make debug info screen show real data (including battery level & charging) -* make real implementation of getNumOnlineNodes -* very occasionally send our position and user packet based on the schedule in the radio info (if for nothing else so that other nodes update last_seen) * show real text info on the text screen * retest BLE software update for both board types * turn on screen when a new update arrives @@ -127,3 +123,7 @@ until the phone pulls those packets. Ever so often power on bluetooth just so w * make screen sleep behavior work * make screen advance only when a new node update arrives, a new text arrives or the user presses a button, turn off screen after a while * after reboot, channel number is getting reset to zero! fix! +* send user and location events much less often +* send location (or if not available user) when the user wakes the device from display sleep (both for testing and to improve user experience) +* make real implementation of getNumOnlineNodes +* very occasionally send our position and user packet based on the schedule in the radio info (if for nothing else so that other nodes update last_seen) diff --git a/src/MeshService.cpp b/src/MeshService.cpp index 269756e6..746de39f 100644 --- a/src/MeshService.cpp +++ b/src/MeshService.cpp @@ -153,10 +153,10 @@ void MeshService::loop() handleFromRadio(); - // FIXME, don't send user this often, but for now it is useful for testing + // occasionally send our owner info static uint32_t lastsend; uint32_t now = millis(); - if (now - lastsend > 5 * 60 * 1000) + if (now - lastsend > radioConfig.preferences.send_owner_secs * 1000) { lastsend = now; sendOurOwner(); @@ -193,7 +193,7 @@ void MeshService::handleToRadio(std::string s) void MeshService::sendToMesh(MeshPacket *p) { - nodeDB.updateFrom(*p); + nodeDB.updateFrom(*p); // update our local DB for this packet assert(radio.send(p) == pdTRUE); } @@ -208,8 +208,33 @@ MeshPacket *MeshService::allocForSending() return p; } +void MeshService::sendNetworkPing() +{ + NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); + assert(node); + + if (node->has_position) + sendOurPosition(); + else + sendOurOwner(); +} + +void MeshService::sendOurPosition() +{ + NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); + assert(node); + assert(node->has_position); + + // Update our local node info with our position (even if we don't decide to update anyone else) + MeshPacket *p = allocForSending(); + p->payload.which_variant = SubPacket_position_tag; + p->payload.variant.position = node->position; + sendToMesh(p); +} + void MeshService::onGPSChanged() { + // Update our local node info with our position (even if we don't decide to update anyone else) MeshPacket *p = allocForSending(); p->payload.which_variant = SubPacket_position_tag; Position &pos = p->payload.variant.position; @@ -218,7 +243,23 @@ void MeshService::onGPSChanged() pos.latitude = gps.location.lat(); pos.longitude = gps.location.lng(); - sendToMesh(p); + // We limit our GPS broadcasts to a max rate + static uint32_t lastGpsSend; + uint32_t now = millis(); + if (lastGpsSend == 0 || now - lastGpsSend > radioConfig.preferences.position_broadcast_secs * 1000) + { + lastGpsSend = now; + DEBUG_MSG("Sending position to mesh\n"); + + sendToMesh(p); + } + else + { + // We don't need to send this packet to anyone else, but it still serves as a nice uniform way to update our local state + nodeDB.updateFrom(*p); + + releaseToPool(p); + } } void MeshService::onNotify(Observable *o) diff --git a/src/MeshService.h b/src/MeshService.h index 291472a2..818fa81f 100644 --- a/src/MeshService.h +++ b/src/MeshService.h @@ -60,9 +60,14 @@ public: /// Allocate and return a meshpacket which defaults as send to broadcast from the current node. MeshPacket *allocForSending(); + /// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least sends our owner + void sendNetworkPing(); + /// Send our owner info to a particular node void sendOurOwner(NodeNum dest = NODENUM_BROADCAST); private: + /// Broadcasts our last known position + void sendOurPosition(); /// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after sending. /// This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb cache diff --git a/src/NodeDB.cpp b/src/NodeDB.cpp index 5f5147d8..2dcab873 100644 --- a/src/NodeDB.cpp +++ b/src/NodeDB.cpp @@ -49,6 +49,14 @@ void NodeDB::init() devicestate.node_db_count = 0; devicestate.receive_queue_count = 0; + radioConfig.preferences.send_owner_secs = 60 * 60; // default to once an hour + radioConfig.preferences.position_broadcast_secs = 15 * 60; // default to once every 15 mins + +#ifdef GPS_RX_PIN + // some hardware defaults to have a built in GPS + myNodeInfo.has_gps = true; +#endif + // Init our blank owner info to reasonable defaults esp_efuse_mac_get_default(ourMacAddr); sprintf(owner.id, "!%02x%02x%02x%02x%02x%02x", ourMacAddr[0], diff --git a/src/main.ino b/src/main.ino index d3de5d8e..db6ab664 100644 --- a/src/main.ino +++ b/src/main.ino @@ -442,6 +442,7 @@ void loop() // esp_pm_dump_locks(stdout); // FIXME, do this someplace better wasPressed = true; minPressMs = millis() + 3000; + service.sendNetworkPing(); screen_press(); } } diff --git a/src/mesh.pb.h b/src/mesh.pb.h index 3e45d46d..111a5bbc 100644 --- a/src/mesh.pb.h +++ b/src/mesh.pb.h @@ -34,8 +34,8 @@ typedef enum _ChannelSettings_ModemConfig { typedef enum _DeviceState_Version { DeviceState_Version_Unset = 0, - DeviceState_Version_Minimum = 10, - DeviceState_Version_Current = 10 + DeviceState_Version_Minimum = 11, + DeviceState_Version_Current = 11 } DeviceState_Version; /* Struct definitions */ @@ -67,8 +67,8 @@ typedef struct _Position { } Position; typedef struct _RadioConfig_UserPreferences { - uint32_t position_broadcast_msec; - uint32_t min_broadcast_msec; + uint32_t position_broadcast_secs; + uint32_t send_owner_secs; bool keep_all_packets; bool promiscuous_mode; } RadioConfig_UserPreferences; @@ -206,8 +206,8 @@ typedef struct _ToRadio { #define Position_altitude_tag 3 #define Position_battery_level_tag 4 #define Position_from_hardware_tag 5 -#define RadioConfig_UserPreferences_position_broadcast_msec_tag 1 -#define RadioConfig_UserPreferences_min_broadcast_msec_tag 2 +#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 +#define RadioConfig_UserPreferences_send_owner_secs_tag 2 #define RadioConfig_UserPreferences_keep_all_packets_tag 100 #define RadioConfig_UserPreferences_promiscuous_mode_tag 101 #define User_id_tag 1 @@ -300,8 +300,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, channel_settings, 2) #define RadioConfig_channel_settings_MSGTYPE ChannelSettings #define RadioConfig_UserPreferences_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, position_broadcast_msec, 1) \ -X(a, STATIC, SINGULAR, UINT32, min_broadcast_msec, 2) \ +X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ +X(a, STATIC, SINGULAR, UINT32, send_owner_secs, 2) \ X(a, STATIC, SINGULAR, BOOL, keep_all_packets, 100) \ X(a, STATIC, SINGULAR, BOOL, promiscuous_mode, 101) #define RadioConfig_UserPreferences_CALLBACK NULL