2023-05-31 13:18:09 +02:00
|
|
|
#include "NeighborInfoModule.h"
|
2024-03-17 08:18:30 -05:00
|
|
|
#include "Default.h"
|
2023-05-31 13:18:09 +02:00
|
|
|
#include "MeshService.h"
|
|
|
|
|
#include "NodeDB.h"
|
|
|
|
|
#include "RTC.h"
|
2024-09-23 08:58:14 -05:00
|
|
|
#include <Throttle.h>
|
2023-05-31 13:18:09 +02:00
|
|
|
|
|
|
|
|
NeighborInfoModule *neighborInfoModule;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Prints a single neighbor info packet and associated neighbors
|
|
|
|
|
Uses LOG_DEBUG, which equates to Console.log
|
|
|
|
|
NOTE: For debugging only
|
|
|
|
|
*/
|
|
|
|
|
void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np)
|
|
|
|
|
{
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("%s NEIGHBORINFO PACKET from Node 0x%x to Node 0x%x (last sent by 0x%x)", header, np->node_id, nodeDB->getNodeNum(),
|
|
|
|
|
np->last_sent_by_id);
|
|
|
|
|
LOG_DEBUG("Packet contains %d neighbors", np->neighbors_count);
|
2023-05-31 13:18:09 +02:00
|
|
|
for (int i = 0; i < np->neighbors_count; i++) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Neighbor %d: node_id=0x%x, snr=%.2f", i, np->neighbors[i].node_id, np->neighbors[i].snr);
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Prints the nodeDB neighbors
|
|
|
|
|
NOTE: for debugging only
|
|
|
|
|
*/
|
2024-03-23 13:31:58 +01:00
|
|
|
void NeighborInfoModule::printNodeDBNeighbors()
|
2023-05-31 13:18:09 +02:00
|
|
|
{
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Our NodeDB contains %d neighbors", neighbors.size());
|
2024-04-18 23:16:50 +02:00
|
|
|
for (size_t i = 0; i < neighbors.size(); i++) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Node %d: node_id=0x%x, snr=%.2f", i, neighbors[i].node_id, neighbors[i].snr);
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-16 12:49:46 +11:00
|
|
|
/* Send our initial owner announcement 35 seconds after we start (to give
|
|
|
|
|
* network time to setup) */
|
2023-05-31 13:18:09 +02:00
|
|
|
NeighborInfoModule::NeighborInfoModule()
|
2023-08-16 03:17:15 +02:00
|
|
|
: ProtobufModule("neighborinfo", meshtastic_PortNum_NEIGHBORINFO_APP, &meshtastic_NeighborInfo_msg),
|
2024-11-04 12:16:25 -06:00
|
|
|
concurrency::OSThread("NeighborInfo")
|
2023-05-31 13:18:09 +02:00
|
|
|
{
|
|
|
|
|
ourPortNum = meshtastic_PortNum_NEIGHBORINFO_APP;
|
2024-07-13 05:59:19 -05:00
|
|
|
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
2023-05-31 13:18:09 +02:00
|
|
|
|
|
|
|
|
if (moduleConfig.neighbor_info.enabled) {
|
2024-03-08 14:13:57 +01:00
|
|
|
isPromiscuous = true; // Update neighbors from all packets
|
2024-07-13 05:59:19 -05:00
|
|
|
setIntervalFromNow(Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval,
|
|
|
|
|
default_telemetry_broadcast_interval_secs));
|
2023-05-31 13:18:09 +02:00
|
|
|
} else {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("NeighborInfoModule is disabled");
|
2023-05-31 13:18:09 +02:00
|
|
|
disable();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2025-11-16 12:49:46 +11:00
|
|
|
Collect neighbor info from the nodeDB's history, capping at a maximum number of
|
|
|
|
|
entries and max time Assumes that the neighborInfo packet has been allocated
|
2023-05-31 13:18:09 +02:00
|
|
|
@returns the number of entries collected
|
|
|
|
|
*/
|
|
|
|
|
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
|
|
|
|
|
{
|
2024-04-18 23:16:50 +02:00
|
|
|
NodeNum my_node_id = nodeDB->getNodeNum();
|
2023-05-31 13:18:09 +02:00
|
|
|
neighborInfo->node_id = my_node_id;
|
|
|
|
|
neighborInfo->last_sent_by_id = my_node_id;
|
2024-10-04 04:17:23 -07:00
|
|
|
neighborInfo->node_broadcast_interval_secs =
|
|
|
|
|
Default::getConfiguredOrDefault(moduleConfig.neighbor_info.update_interval, default_telemetry_broadcast_interval_secs);
|
2023-05-31 13:18:09 +02:00
|
|
|
|
2024-04-18 23:16:50 +02:00
|
|
|
cleanUpNeighbors();
|
2023-07-30 16:54:39 +02:00
|
|
|
|
2024-04-18 23:16:50 +02:00
|
|
|
for (auto nbr : neighbors) {
|
|
|
|
|
if ((neighborInfo->neighbors_count < MAX_NUM_NEIGHBORS) && (nbr.node_id != my_node_id)) {
|
|
|
|
|
neighborInfo->neighbors[neighborInfo->neighbors_count].node_id = nbr.node_id;
|
|
|
|
|
neighborInfo->neighbors[neighborInfo->neighbors_count].snr = nbr.snr;
|
2025-11-16 12:49:46 +11:00
|
|
|
// Note: we don't set the last_rx_time and node_broadcast_intervals_secs
|
|
|
|
|
// here, because we don't want to send this over the mesh
|
2023-05-31 13:18:09 +02:00
|
|
|
neighborInfo->neighbors_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-23 13:31:58 +01:00
|
|
|
printNodeDBNeighbors();
|
2023-05-31 13:18:09 +02:00
|
|
|
return neighborInfo->neighbors_count;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-30 16:54:39 +02:00
|
|
|
/*
|
2024-04-18 23:16:50 +02:00
|
|
|
Remove neighbors from the database that we haven't heard from in a while
|
2023-07-30 16:54:39 +02:00
|
|
|
*/
|
2024-04-18 23:16:50 +02:00
|
|
|
void NeighborInfoModule::cleanUpNeighbors()
|
2023-07-30 16:54:39 +02:00
|
|
|
{
|
2024-10-04 04:17:23 -07:00
|
|
|
uint32_t now = getTime();
|
2024-03-21 09:06:37 -05:00
|
|
|
NodeNum my_node_id = nodeDB->getNodeNum();
|
2024-04-18 23:16:50 +02:00
|
|
|
for (auto it = neighbors.rbegin(); it != neighbors.rend();) {
|
2025-11-16 12:49:46 +11:00
|
|
|
// We will remove a neighbor if we haven't heard from them in twice the
|
|
|
|
|
// broadcast interval cannot use isWithinTimespanMs() as it->last_rx_time is
|
|
|
|
|
// seconds since 1970
|
2024-10-04 04:17:23 -07:00
|
|
|
if ((now - it->last_rx_time > it->node_broadcast_interval_secs * 2) && (it->node_id != my_node_id)) {
|
2024-11-04 19:15:59 -06:00
|
|
|
LOG_DEBUG("Remove neighbor with node ID 0x%x", it->node_id);
|
2024-04-18 23:16:50 +02:00
|
|
|
it = std::vector<meshtastic_Neighbor>::reverse_iterator(
|
|
|
|
|
neighbors.erase(std::next(it).base())); // Erase the element and update the iterator
|
|
|
|
|
} else {
|
|
|
|
|
++it;
|
2023-07-30 16:54:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 13:18:09 +02:00
|
|
|
/* Send neighbor info to the mesh */
|
|
|
|
|
void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies)
|
|
|
|
|
{
|
2023-09-05 01:38:16 +02:00
|
|
|
meshtastic_NeighborInfo neighborInfo = meshtastic_NeighborInfo_init_zero;
|
|
|
|
|
collectNeighborInfo(&neighborInfo);
|
Backmerge (#7782)
* Merge pull request #7777 from meshtastic/create-pull-request/bump-version
Bump release version
* Only send Neighbours if we have some to send. (#7493)
* Only send Neighbours if we have some to send.
The original intent of NeighborInfo was that when a NeighbourInfo
was sent all of the nodes that saw it would reply with NeighbourInfo.
So, NeighbourInfo was sent even if there were no hop-zero nodes in
the NodeDB.
Since 2023, when this was implemented, our understanding of running city-wide
meshes has improved substantially. We have taken steps to reduce the impact
of NeighborInfo over LoRa.
This change aligns with those ideas: we will now only send NeighborInfo
if we have some neighbors to contribute.
The impact of this change is that a node must first see another directly
connected node in another packet type before NeighborInfo is sent. This means
that a node with no neighbors is no longer able to trigger other nodes
to broadcast NeighborInfo. It will, however, receive the regular periodic
broadcast of NeighborInfo, and will be able to send NeighborInfo if it
has at least 1 neighbor.
* Include all the things
* AvOid memleak
* We don't gotTime if time is 2019. (#7772)
There are certain GPS chips that have a hard-coded time in firmware
that they will return before lock. We set our own hard-coded time,
BUILD_EPOCH, that should be newer and use the comparison to not set
a bad time.
In https://github.com/meshtastic/firmware/pull/7261 we introduced
the RTCSetResult and improved it in https://github.com/meshtastic/firmware/pull/7375 .
However, the original try-fix left logic in GPS.cpp that could
still result in broadcasting the bad time.
Further, as part of our fix we cleared the GPS buffer if we didn't
get a good time. The mesh was hurting at the time, so this was a reasonable
approach. However, given time tends to come in when we're trying to get
early lock, this had the potential side effect of throwing away valuable
information to get position lock.
This change reverses the clearBuffer and changes the logic so if time
is not set it will not be broadcast.
Fixes https://github.com/meshtastic/firmware/issues/7771
Fixes https://github.com/meshtastic/firmware/issues/7750
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
2025-08-29 10:31:55 -05:00
|
|
|
// only send neighbours if we have some to send
|
|
|
|
|
if (neighborInfo.neighbors_count > 0) {
|
|
|
|
|
meshtastic_MeshPacket *p = allocDataProtobuf(neighborInfo);
|
|
|
|
|
p->to = dest;
|
|
|
|
|
p->decoded.want_response = wantReplies;
|
|
|
|
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
|
|
|
|
printNeighborInfo("SENDING", &neighborInfo);
|
|
|
|
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
|
|
|
|
}
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Encompasses the full construction and sending packet to mesh
|
|
|
|
|
Will be used for broadcast.
|
|
|
|
|
*/
|
|
|
|
|
int32_t NeighborInfoModule::runOnce()
|
|
|
|
|
{
|
2025-02-15 14:55:51 +01:00
|
|
|
if (moduleConfig.neighbor_info.transmit_over_lora &&
|
|
|
|
|
(!channels.isDefaultChannel(channels.getPrimaryIndex()) || !RadioInterface::uses_default_frequency_slot) &&
|
2024-11-09 02:38:48 +01:00
|
|
|
airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
|
|
|
|
|
sendNeighborInfo(NODENUM_BROADCAST, false);
|
|
|
|
|
} else {
|
|
|
|
|
sendNeighborInfo(NODENUM_BROADCAST_NO_LORA, false);
|
|
|
|
|
}
|
2024-08-19 07:04:48 -05:00
|
|
|
return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_neighbor_info_broadcast_secs);
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
|
2025-11-16 12:49:46 +11:00
|
|
|
meshtastic_MeshPacket *NeighborInfoModule::allocReply()
|
|
|
|
|
{
|
|
|
|
|
LOG_INFO("NeighborInfoRequested.");
|
|
|
|
|
if (lastSentReply && Throttle::isWithinTimespanMs(lastSentReply, 3 * 60 * 1000)) {
|
|
|
|
|
LOG_DEBUG("Skip Neighbors reply since we sent a reply <3min ago");
|
|
|
|
|
ignoreRequest = true; // Mark it as ignored for MeshModule
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
meshtastic_NeighborInfo neighborInfo = meshtastic_NeighborInfo_init_zero;
|
|
|
|
|
collectNeighborInfo(&neighborInfo);
|
|
|
|
|
|
|
|
|
|
meshtastic_MeshPacket *reply = allocDataProtobuf(neighborInfo);
|
|
|
|
|
|
|
|
|
|
if (reply) {
|
|
|
|
|
lastSentReply = millis(); // Track when we sent this reply
|
|
|
|
|
}
|
|
|
|
|
return reply;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 13:18:09 +02:00
|
|
|
/*
|
2024-11-02 20:25:05 -05:00
|
|
|
Collect a received neighbor info packet from another node
|
2023-05-31 13:18:09 +02:00
|
|
|
Pass it to an upper client; do not persist this data on the mesh
|
|
|
|
|
*/
|
|
|
|
|
bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np)
|
|
|
|
|
{
|
2025-11-16 12:49:46 +11:00
|
|
|
LOG_DEBUG("NeighborInfo: handleReceivedProtobuf");
|
2024-03-08 14:13:57 +01:00
|
|
|
if (np) {
|
2023-09-05 19:56:42 +02:00
|
|
|
printNeighborInfo("RECEIVED", np);
|
2025-11-16 12:49:46 +11:00
|
|
|
// Ignore dummy/interceptable packets: single neighbor with nodeId 0 and snr 0
|
|
|
|
|
if (np->neighbors_count != 1 || np->neighbors[0].node_id != 0 || np->neighbors[0].snr != 0.0f) {
|
|
|
|
|
LOG_DEBUG(" Updating neighbours");
|
|
|
|
|
updateNeighbors(mp, np);
|
|
|
|
|
} else {
|
|
|
|
|
LOG_DEBUG(" Ignoring dummy neighbor info packet (single neighbor with nodeId 0, snr 0)");
|
|
|
|
|
}
|
2024-03-08 14:13:57 +01:00
|
|
|
} else if (mp.hop_start != 0 && mp.hop_start == mp.hop_limit) {
|
2025-11-16 12:49:46 +11:00
|
|
|
LOG_DEBUG("Get or create neighbor: %u with snr %f", mp.from, mp.rx_snr);
|
2024-03-08 14:13:57 +01:00
|
|
|
// If the hopLimit is the same as hopStart, then it is a neighbor
|
2025-11-16 12:49:46 +11:00
|
|
|
getOrCreateNeighbor(mp.from, mp.from, 0,
|
|
|
|
|
mp.rx_snr); // Set the broadcast interval to 0, as we don't know it
|
2023-09-05 19:56:42 +02:00
|
|
|
}
|
2023-05-31 13:18:09 +02:00
|
|
|
// Allow others to handle this packet
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 20:02:36 +02:00
|
|
|
/*
|
2025-11-16 12:49:46 +11:00
|
|
|
Copy the content of a current NeighborInfo packet into a new one and update the
|
|
|
|
|
last_sent_by_id to our NodeNum
|
2023-06-08 20:02:36 +02:00
|
|
|
*/
|
2024-03-23 13:31:58 +01:00
|
|
|
void NeighborInfoModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_NeighborInfo *n)
|
2023-06-08 20:02:36 +02:00
|
|
|
{
|
2024-03-23 13:31:58 +01:00
|
|
|
n->last_sent_by_id = nodeDB->getNodeNum();
|
2023-06-08 20:02:36 +02:00
|
|
|
|
|
|
|
|
// Set updated last_sent_by_id to the payload of the to be flooded packet
|
2024-03-23 13:31:58 +01:00
|
|
|
p.decoded.payload.size =
|
|
|
|
|
pb_encode_to_bytes(p.decoded.payload.bytes, sizeof(p.decoded.payload.bytes), &meshtastic_NeighborInfo_msg, n);
|
2023-06-08 20:02:36 +02:00
|
|
|
}
|
|
|
|
|
|
2023-05-31 13:18:09 +02:00
|
|
|
void NeighborInfoModule::resetNeighbors()
|
|
|
|
|
{
|
2024-04-18 23:16:50 +02:00
|
|
|
neighbors.clear();
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-12 09:29:19 -05:00
|
|
|
void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np)
|
2023-05-31 13:18:09 +02:00
|
|
|
{
|
2025-11-16 12:49:46 +11:00
|
|
|
LOG_DEBUG("updateNeighbors");
|
|
|
|
|
// The last sent ID will be 0 if the packet is from the phone, which we don't
|
|
|
|
|
// count as an edge. So we assume that if it's zero, then this packet is from
|
|
|
|
|
// our node.
|
2023-05-31 13:18:09 +02:00
|
|
|
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
|
2023-07-30 16:54:39 +02:00
|
|
|
getOrCreateNeighbor(mp.from, np->last_sent_by_id, np->node_broadcast_interval_secs, mp.rx_snr);
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-30 16:54:39 +02:00
|
|
|
meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n,
|
2023-08-22 15:43:21 +02:00
|
|
|
uint32_t node_broadcast_interval_secs, float snr)
|
2023-05-31 13:18:09 +02:00
|
|
|
{
|
|
|
|
|
// our node and the phone are the same node (not neighbors)
|
|
|
|
|
if (n == 0) {
|
2024-03-21 09:06:37 -05:00
|
|
|
n = nodeDB->getNodeNum();
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
// look for one in the existing list
|
2024-04-18 23:16:50 +02:00
|
|
|
for (size_t i = 0; i < neighbors.size(); i++) {
|
|
|
|
|
if (neighbors[i].node_id == n) {
|
2023-05-31 13:18:09 +02:00
|
|
|
// if found, update it
|
2024-04-18 23:16:50 +02:00
|
|
|
neighbors[i].snr = snr;
|
|
|
|
|
neighbors[i].last_rx_time = getTime();
|
2025-11-16 12:49:46 +11:00
|
|
|
// Only if this is the original sender, the broadcast interval corresponds
|
|
|
|
|
// to it
|
2024-03-08 14:13:57 +01:00
|
|
|
if (originalSender == n && node_broadcast_interval_secs != 0)
|
2024-04-18 23:16:50 +02:00
|
|
|
neighbors[i].node_broadcast_interval_secs = node_broadcast_interval_secs;
|
|
|
|
|
return &neighbors[i];
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// otherwise, allocate one and assign data to it
|
2024-04-18 23:16:50 +02:00
|
|
|
|
|
|
|
|
meshtastic_Neighbor new_nbr = meshtastic_Neighbor_init_zero;
|
|
|
|
|
new_nbr.node_id = n;
|
|
|
|
|
new_nbr.snr = snr;
|
|
|
|
|
new_nbr.last_rx_time = getTime();
|
2025-11-16 12:49:46 +11:00
|
|
|
// Only if this is the original sender, the broadcast interval corresponds to
|
|
|
|
|
// it
|
2024-03-08 14:13:57 +01:00
|
|
|
if (originalSender == n && node_broadcast_interval_secs != 0)
|
2024-04-18 23:16:50 +02:00
|
|
|
new_nbr.node_broadcast_interval_secs = node_broadcast_interval_secs;
|
2025-11-16 12:49:46 +11:00
|
|
|
else // Assume the same broadcast interval as us for the neighbor if we don't
|
|
|
|
|
// know it
|
2024-04-18 23:16:50 +02:00
|
|
|
new_nbr.node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
2023-05-31 13:18:09 +02:00
|
|
|
|
2024-04-18 23:16:50 +02:00
|
|
|
if (neighbors.size() < MAX_NUM_NEIGHBORS) {
|
|
|
|
|
neighbors.push_back(new_nbr);
|
|
|
|
|
} else {
|
|
|
|
|
// If we have too many neighbors, replace the oldest one
|
2024-11-04 19:15:59 -06:00
|
|
|
LOG_WARN("Neighbor DB is full, replace oldest neighbor");
|
2024-04-18 23:16:50 +02:00
|
|
|
neighbors.erase(neighbors.begin());
|
|
|
|
|
neighbors.push_back(new_nbr);
|
2023-05-31 13:18:09 +02:00
|
|
|
}
|
2024-04-18 23:16:50 +02:00
|
|
|
return &neighbors.back();
|
Backmerge (#7782)
* Merge pull request #7777 from meshtastic/create-pull-request/bump-version
Bump release version
* Only send Neighbours if we have some to send. (#7493)
* Only send Neighbours if we have some to send.
The original intent of NeighborInfo was that when a NeighbourInfo
was sent all of the nodes that saw it would reply with NeighbourInfo.
So, NeighbourInfo was sent even if there were no hop-zero nodes in
the NodeDB.
Since 2023, when this was implemented, our understanding of running city-wide
meshes has improved substantially. We have taken steps to reduce the impact
of NeighborInfo over LoRa.
This change aligns with those ideas: we will now only send NeighborInfo
if we have some neighbors to contribute.
The impact of this change is that a node must first see another directly
connected node in another packet type before NeighborInfo is sent. This means
that a node with no neighbors is no longer able to trigger other nodes
to broadcast NeighborInfo. It will, however, receive the regular periodic
broadcast of NeighborInfo, and will be able to send NeighborInfo if it
has at least 1 neighbor.
* Include all the things
* AvOid memleak
* We don't gotTime if time is 2019. (#7772)
There are certain GPS chips that have a hard-coded time in firmware
that they will return before lock. We set our own hard-coded time,
BUILD_EPOCH, that should be newer and use the comparison to not set
a bad time.
In https://github.com/meshtastic/firmware/pull/7261 we introduced
the RTCSetResult and improved it in https://github.com/meshtastic/firmware/pull/7375 .
However, the original try-fix left logic in GPS.cpp that could
still result in broadcasting the bad time.
Further, as part of our fix we cleared the GPS buffer if we didn't
get a good time. The mesh was hurting at the time, so this was a reasonable
approach. However, given time tends to come in when we're trying to get
early lock, this had the potential side effect of throwing away valuable
information to get position lock.
This change reverses the clearBuffer and changes the logic so if time
is not set it will not be broadcast.
Fixes https://github.com/meshtastic/firmware/issues/7771
Fixes https://github.com/meshtastic/firmware/issues/7750
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
2025-08-29 10:31:55 -05:00
|
|
|
}
|