From f0a78f70e11c71d7fa23cd8da4fd62addaae642f Mon Sep 17 00:00:00 2001 From: "torlando-agent[bot]" <281092095+torlando-agent[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:48:46 -0400 Subject: [PATCH] fix: derive OS::time() offset from the 64-bit rolling uptime, not millis() The offset was computed as unix_ms - millis() (32-bit) but ltime() adds it to a 64-bit (high32<<32|low32) counter. Once high32 != 0 (a millis() rollover, or an erratic screen-off/wake tripping ltime()'s roll-over check) OS::time() was wrong by high32*49.7 days -- surfacing as garbage "Nw ago" timestamps in the conversation list. Compute the offset from OS::ltime()-getTimeOffset() at both the GPS and NTP sync sites; add a diagnostic logging OS::time() after each sync. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5 --- src/main.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 50cc9110..1bdcf49c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -322,11 +322,23 @@ bool sync_time_from_gps(uint32_t timeout_ms = 30000) { tzset(); } - // Set the time offset for Utilities::OS::time() + // Set the time offset for Utilities::OS::time(). + // Derive the current uptime from the SAME 64-bit rolling counter OS::time() + // uses (ltime() = (high32<<32|low32) + _time_offset), not raw 32-bit + // millis(). If we used millis() here, then once high32 != 0 (after a + // millis() rollover, or an erratic screen-off/wake that trips ltime()'s + // roll-over check) OS::time() would be wrong by high32*49.7 days — surfacing + // as garbage "Nw ago" timestamps in the conversation list. time_t now = time(nullptr); - uint64_t uptime_ms = millis(); + uint64_t uptime_ms = RNS::Utilities::OS::ltime() - RNS::Utilities::OS::getTimeOffset(); uint64_t unix_ms = (uint64_t)now * 1000; RNS::Utilities::OS::setTimeOffset(unix_ms - uptime_ms); + { + char tbuf[96]; + snprintf(tbuf, sizeof(tbuf), " GPS time offset set: OS::time()=%lu (unix=%lu)", + (unsigned long)RNS::Utilities::OS::time(), (unsigned long)now); + INFO(tbuf); + } // Display synced time struct tm timeinfo; @@ -684,9 +696,11 @@ static void pump_ntp_sync_if_pending() { struct tm timeinfo; if (getLocalTime(&timeinfo, 0)) { - // Set the time offset for Utilities::OS::time() + // Set the time offset for Utilities::OS::time(). Use the 64-bit rolling + // uptime OS::time() uses, not raw 32-bit millis() — see the GPS path for + // why (a high32 != 0 would otherwise skew OS::time() by 49.7-day units). time_t now = time(nullptr); - uint64_t uptime_ms = millis(); + uint64_t uptime_ms = RNS::Utilities::OS::ltime() - RNS::Utilities::OS::getTimeOffset(); uint64_t unix_ms = (uint64_t)now * 1000; RNS::Utilities::OS::setTimeOffset(unix_ms - uptime_ms); @@ -694,6 +708,12 @@ static void pump_ntp_sync_if_pending() { strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S %Z", &timeinfo); String msg = " NTP time synced: " + String(time_str); INFO(msg.c_str()); + { + char tbuf[96]; + snprintf(tbuf, sizeof(tbuf), " NTP time offset set: OS::time()=%lu (unix=%lu)", + (unsigned long)RNS::Utilities::OS::time(), (unsigned long)now); + INFO(tbuf); + } _ntp_pending = false; return; }