diff --git a/src/time_manager.cpp b/src/time_manager.cpp index 6f0144c..17a8110 100644 --- a/src/time_manager.cpp +++ b/src/time_manager.cpp @@ -1,10 +1,15 @@ #include "time_manager.h" #include "config.h" #include +#ifdef ARDUINO_ARCH_ESP32 +#include +#endif static bool g_time_synced = false; +static bool g_clock_plausible = false; static bool g_tz_set = false; 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) { if (epoch == 0) { @@ -13,6 +18,32 @@ static void note_last_sync(uint32_t epoch) { g_last_sync_utc = epoch; } +static bool epoch_is_plausible(time_t epoch) { + return epoch >= static_cast(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(UINT32_MAX)) { + return; + } + mark_synced(static_cast(epoch)); +} +#endif + static void ensure_timezone_set() { if (g_tz_set) { return; @@ -25,24 +56,31 @@ static void ensure_timezone_set() { 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 *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); ensure_timezone_set(); } uint32_t time_get_utc() { time_t now = time(nullptr); - if (now < 1672531200) { + if (!epoch_is_plausible(now)) { + g_clock_plausible = false; return 0; } - if (!g_time_synced) { - g_time_synced = true; - note_last_sync(static_cast(now)); + g_clock_plausible = true; +#ifdef ARDUINO_ARCH_ESP32 + if (!g_time_synced && sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) { + mark_synced(static_cast(now)); } +#endif return static_cast(now); } 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) { @@ -51,8 +89,12 @@ void time_set_utc(uint32_t epoch) { tv.tv_sec = epoch; tv.tv_usec = 0; settimeofday(&tv, nullptr); - g_time_synced = true; - note_last_sync(epoch); + if (epoch_is_plausible(static_cast(epoch))) { + mark_synced(epoch); + } else { + g_clock_plausible = false; + g_time_synced = false; + } } void time_get_local_hhmm(char *out, size_t out_len) {