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 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); }