Separate plausible clock from explicit sync state

This commit is contained in:
2026-02-17 00:33:45 +01:00
parent 8d42631045
commit 3ef13bf865

View File

@@ -1,10 +1,15 @@
#include "time_manager.h" #include "time_manager.h"
#include "config.h" #include "config.h"
#include <time.h> #include <time.h>
#ifdef ARDUINO_ARCH_ESP32
#include <esp_sntp.h>
#endif
static bool g_time_synced = false; static bool g_time_synced = false;
static bool g_clock_plausible = false;
static bool g_tz_set = false; static bool g_tz_set = false;
static uint32_t g_last_sync_utc = 0; static uint32_t g_last_sync_utc = 0;
static constexpr uint32_t MIN_PLAUSIBLE_EPOCH_UTC = 1672531200UL; // 2023-01-01 00:00:00 UTC
static void note_last_sync(uint32_t epoch) { static void note_last_sync(uint32_t epoch) {
if (epoch == 0) { if (epoch == 0) {
@@ -13,6 +18,32 @@ static void note_last_sync(uint32_t epoch) {
g_last_sync_utc = epoch; g_last_sync_utc = epoch;
} }
static bool epoch_is_plausible(time_t epoch) {
return epoch >= static_cast<time_t>(MIN_PLAUSIBLE_EPOCH_UTC);
}
static void mark_synced(uint32_t epoch) {
if (epoch == 0) {
return;
}
g_time_synced = true;
g_clock_plausible = true;
note_last_sync(epoch);
}
#ifdef ARDUINO_ARCH_ESP32
static void ntp_sync_notification_cb(struct timeval *tv) {
time_t epoch = tv ? tv->tv_sec : time(nullptr);
if (!epoch_is_plausible(epoch)) {
return;
}
if (epoch > static_cast<time_t>(UINT32_MAX)) {
return;
}
mark_synced(static_cast<uint32_t>(epoch));
}
#endif
static void ensure_timezone_set() { static void ensure_timezone_set() {
if (g_tz_set) { if (g_tz_set) {
return; return;
@@ -25,24 +56,31 @@ static void ensure_timezone_set() {
void time_receiver_init(const char *ntp_server_1, const char *ntp_server_2) { void time_receiver_init(const char *ntp_server_1, const char *ntp_server_2) {
const char *server1 = (ntp_server_1 && ntp_server_1[0] != '\0') ? ntp_server_1 : "pool.ntp.org"; const char *server1 = (ntp_server_1 && ntp_server_1[0] != '\0') ? ntp_server_1 : "pool.ntp.org";
const char *server2 = (ntp_server_2 && ntp_server_2[0] != '\0') ? ntp_server_2 : "time.nist.gov"; const char *server2 = (ntp_server_2 && ntp_server_2[0] != '\0') ? ntp_server_2 : "time.nist.gov";
#ifdef ARDUINO_ARCH_ESP32
sntp_set_time_sync_notification_cb(ntp_sync_notification_cb);
#endif
configTime(0, 0, server1, server2); configTime(0, 0, server1, server2);
ensure_timezone_set(); ensure_timezone_set();
} }
uint32_t time_get_utc() { uint32_t time_get_utc() {
time_t now = time(nullptr); time_t now = time(nullptr);
if (now < 1672531200) { if (!epoch_is_plausible(now)) {
g_clock_plausible = false;
return 0; return 0;
} }
if (!g_time_synced) { g_clock_plausible = true;
g_time_synced = true; #ifdef ARDUINO_ARCH_ESP32
note_last_sync(static_cast<uint32_t>(now)); if (!g_time_synced && sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
mark_synced(static_cast<uint32_t>(now));
} }
#endif
return static_cast<uint32_t>(now); return static_cast<uint32_t>(now);
} }
bool time_is_synced() { bool time_is_synced() {
return g_time_synced || time_get_utc() > 0; (void)time_get_utc();
return g_time_synced && g_clock_plausible;
} }
void time_set_utc(uint32_t epoch) { void time_set_utc(uint32_t epoch) {
@@ -51,8 +89,12 @@ void time_set_utc(uint32_t epoch) {
tv.tv_sec = epoch; tv.tv_sec = epoch;
tv.tv_usec = 0; tv.tv_usec = 0;
settimeofday(&tv, nullptr); settimeofday(&tv, nullptr);
g_time_synced = true; if (epoch_is_plausible(static_cast<time_t>(epoch))) {
note_last_sync(epoch); mark_synced(epoch);
} else {
g_clock_plausible = false;
g_time_synced = false;
}
} }
void time_get_local_hhmm(char *out, size_t out_len) { void time_get_local_hhmm(char *out, size_t out_len) {