From a8d4665ad99b5769d949d0dbb0042adad99f9076 Mon Sep 17 00:00:00 2001 From: Nikolai Vincent Vaags Date: Wed, 29 Jul 2026 11:30:34 +0200 Subject: [PATCH] do not bootstrap companion rtc Bootstrapping companion RTC from contact lastmod time meant that if/when the companion clock strayed into future time because of clock drift, contacts would get a future/corrupted timestamp -- which the companion would happily restore upon reboot. And since the firmware rejects setting time backwards, it could never be fixed even when rebooting, causing the companion clock to ever drift further ahead. Resolves #3050 --- examples/companion_radio/MyMesh.cpp | 1 - src/helpers/BaseChatMesh.cpp | 18 +++--------------- src/helpers/BaseChatMesh.h | 3 +-- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 6fbb0f74..763c2c28 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -957,7 +957,6 @@ void MyMesh::begin(bool has_display) { resetContacts(); _store->loadContacts(this); - bootstrapRTCfromContacts(); addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel _store->loadChannels(this); diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index d3ef034e..b275ec67 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -55,18 +55,6 @@ void BaseChatMesh::sendAckTo(const ContactInfo& dest, const uint8_t* ack_hash, u } } -void BaseChatMesh::bootstrapRTCfromContacts() { - uint32_t latest = 0; - for (int i = 0; i < num_contacts; i++) { - if (contacts[i].lastmod > latest) { - latest = contacts[i].lastmod; - } - } - if (latest != 0) { - getRTCClock()->setCurrentTime(latest + 1); - } -} - ContactInfo* BaseChatMesh::allocateContactSlot(bool transient_only) { if (num_contacts < MAX_CONTACTS) { return &contacts[num_contacts++]; @@ -166,7 +154,7 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, MESH_DEBUG_PRINTLN("onAdvertRecv: unable to allocate contact slot for new contact"); return; } - + populateContactFromAdvert(*from, id, parser, timestamp); from->sync_since = 0; from->shared_secret_valid = false; @@ -773,7 +761,7 @@ void BaseChatMesh::checkConnections() { memcpy(data, &now, 4); data[4] = REQ_TYPE_KEEP_ALIVE; memcpy(&data[5], &contact->sync_since, 4); - + // calc expected ACK reply mesh::Utils::sha256((uint8_t *)&connections[i].expected_ack, 4, data, 9, self_id.pub_key, PUB_KEY_SIZE); @@ -781,7 +769,7 @@ void BaseChatMesh::checkConnections() { if (pkt) { sendDirect(pkt, contact->out_path, contact->out_path_len); } - + // schedule next KEEP_ALIVE connections[i].next_ping = futureMillis(connections[i].keep_alive_millis); } diff --git a/src/helpers/BaseChatMesh.h b/src/helpers/BaseChatMesh.h index c04bfda3..d3d6890a 100644 --- a/src/helpers/BaseChatMesh.h +++ b/src/helpers/BaseChatMesh.h @@ -79,7 +79,7 @@ class BaseChatMesh : public mesh::Mesh { protected: BaseChatMesh(mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::PacketManager& mgr, mesh::MeshTables& tables) : mesh::Mesh(radio, ms, rng, rtc, mgr, tables) - { + { num_contacts = 0; #ifdef MAX_GROUP_CHANNELS memset(channels, 0, sizeof(channels)); @@ -90,7 +90,6 @@ protected: memset(connections, 0, sizeof(connections)); } - void bootstrapRTCfromContacts(); void resetContacts() { num_contacts = 0; } void populateContactFromAdvert(ContactInfo& ci, const mesh::Identity& id, const AdvertDataParser& parser, uint32_t timestamp); ContactInfo* allocateContactSlot(bool transient_only=false); // helper to find slot for new contact