From b74c2da53084de1c239903df08d1e5a3ba58cdb1 Mon Sep 17 00:00:00 2001 From: a-f-G-U-C <65810997+a-f-G-U-C@users.noreply.github.com> Date: Tue, 26 Oct 2021 12:22:34 +0000 Subject: [PATCH 1/2] implement RX_SRC_LOCAL, Position in updatePosition --- src/mesh/NodeDB.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index dc46b7ae..e5594b21 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -451,21 +451,29 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) { NodeInfo *info = getOrCreateNode(nodeId); - DEBUG_MSG("DB update position node=0x%x time=%u, latI=%d, lonI=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i); + if (src == RX_SRC_LOCAL) { + // Local packet, fully authoritative + DEBUG_MSG("updatePosition LOCAL pos@%x:5, time=%u, latI=%d, lonI=%d\n", + p.pos_timestamp, p.time, p.latitude_i, p.longitude_i); + info->position = p; - // Be careful to only update fields that have been set by the sender - // 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 - if (p.time) - info->position.time = p.time; - if (p.battery_level) - info->position.battery_level = p.battery_level; - if (p.latitude_i || p.longitude_i) { - info->position.latitude_i = p.latitude_i; - info->position.longitude_i = p.longitude_i; + } else { + // Be careful to only update fields that have been set by the REMOTE sender + // 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 + DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n", + nodeId, p.time, p.latitude_i, p.longitude_i); + + // First, back up fields that we want to protect from overwrite + uint32_t tmp_time = info->position.time; + + // Next, update atomically + info->position = p; + + // Last, restore any fields that may have been overwritten + if (! info->position.time) + info->position.time = tmp_time; } - if (p.altitude) - info->position.altitude = p.altitude; info->has_position = true; updateGUIforNode = info; notifyObservers(true); // Force an update whether or not our node counts have changed From 24b2fd265796e3cc206972b06f6084e1fe67f21a Mon Sep 17 00:00:00 2001 From: a-f-G-U-C <65810997+a-f-G-U-C@users.noreply.github.com> Date: Tue, 26 Oct 2021 12:41:44 +0000 Subject: [PATCH 2/2] better sanity check, logging of inbound positions --- src/plugins/PositionPlugin.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/plugins/PositionPlugin.cpp b/src/plugins/PositionPlugin.cpp index b772954c..5f03ec6b 100644 --- a/src/plugins/PositionPlugin.cpp +++ b/src/plugins/PositionPlugin.cpp @@ -18,6 +18,32 @@ bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr { auto p = *pptr; + // If inbound message is a replay (or spoof!) of our own messages, do not process + // (why use second-hand sources for our own data?) + if (nodeDB.getNodeNum() == getFrom(&mp)) { + DEBUG_MSG("Ignored an incoming update from MYSELF\n"); + return false; + } + + // Log packet size and list of fields + DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + getFrom(&mp), + mp.decoded.payload.size, + p.latitude_i ? "LAT ":"", + p.longitude_i ? "LON ":"", + p.altitude ? "MSL ":"", + p.altitude_hae ? "HAE ":"", + p.alt_geoid_sep ? "GEO ":"", + p.PDOP ? "PDOP ":"", + p.HDOP ? "HDOP ":"", + p.VDOP ? "VDOP ":"", + p.sats_in_view ? "SIV ":"", + p.fix_quality ? "FXQ ":"", + p.fix_type ? "FXT ":"", + p.pos_timestamp ? "PTS ":"", + p.time ? "TIME ":"", + p.battery_level ? "BAT ":""); + if (p.time) { struct timeval tv; uint32_t secs = p.time; @@ -77,7 +103,6 @@ MeshPacket *PositionPlugin::allocReply() if (pos_flags & PositionFlags_POS_TIMESTAMP) p.pos_timestamp = node->position.pos_timestamp; - // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless // devices can get time. @@ -107,17 +132,20 @@ void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies) int32_t PositionPlugin::runOnce() { + NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); // We limit our GPS broadcasts to a max rate uint32_t now = millis(); if (lastGpsSend == 0 || now - lastGpsSend >= getPref_position_broadcast_secs() * 1000) { + lastGpsSend = now; // If we changed channels, ask everyone else for their latest info bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; - DEBUG_MSG("Sending position to mesh (wantReplies=%d)\n", requestReplies); + DEBUG_MSG("Sending pos@%x:6 to mesh (wantReplies=%d)\n", + node->position.pos_timestamp, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies); }