From 92877f9c3656e453aacb59bb3b6e289229b5d0a1 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Thu, 26 Mar 2026 21:55:28 +0100 Subject: [PATCH] Use ntp time sync at end of wifi activities --- lib/hal/HalClock.cpp | 14 ++++++++++++++ lib/hal/HalClock.h | 5 +++++ .../browser/OpdsBookBrowserActivity.cpp | 4 ++-- .../network/CrossPointWebServerActivity.cpp | 12 +++++------- .../reader/KOReaderSyncActivity.cpp | 19 +++---------------- .../settings/DetectTimezoneActivity.cpp | 14 ++------------ .../settings/KOReaderAuthActivity.cpp | 7 ++----- src/activities/settings/OtaUpdateActivity.cpp | 7 ++----- src/activities/settings/SyncTimeActivity.cpp | 17 ++--------------- 9 files changed, 37 insertions(+), 62 deletions(-) diff --git a/lib/hal/HalClock.cpp b/lib/hal/HalClock.cpp index 83042731..f7fec425 100644 --- a/lib/hal/HalClock.cpp +++ b/lib/hal/HalClock.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -260,4 +261,17 @@ void formatLogTime(char* buf, size_t bufSize) { snprintf(buf, bufSize, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); } +void wifiOff(bool skipNtpSync) { + if (!skipNtpSync && isApproximate() && WiFi.getMode() == WIFI_STA && WiFi.status() == WL_CONNECTED) { + syncNtp(); + } + if (esp_sntp_enabled()) { + esp_sntp_stop(); + } + WiFi.disconnect(false); + delay(100); + WiFi.mode(WIFI_OFF); + delay(100); +} + } // namespace HalClock diff --git a/lib/hal/HalClock.h b/lib/hal/HalClock.h index 63428116..cdb49604 100644 --- a/lib/hal/HalClock.h +++ b/lib/hal/HalClock.h @@ -65,4 +65,9 @@ void formatTime(char* buf, size_t bufSize, bool use24h); /// synced, or an empty string if not. void formatLogTime(char* buf, size_t bufSize); +/// Tear down WiFi cleanly. When skipNtpSync is false (default) and the +/// clock is approximate, performs an opportunistic NTP sync before +/// disconnecting — essentially free since we already have a connection. +void wifiOff(bool skipNtpSync = false); + } // namespace HalClock diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index f6a58385..6c7b1d78 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -39,8 +40,7 @@ void OpdsBookBrowserActivity::onEnter() { void OpdsBookBrowserActivity::onExit() { Activity::onExit(); - // Turn off WiFi when exiting - WiFi.mode(WIFI_OFF); + HalClock::wifiOff(); entries.clear(); navigationHistory.clear(); diff --git a/src/activities/network/CrossPointWebServerActivity.cpp b/src/activities/network/CrossPointWebServerActivity.cpp index b3cc8642..fe12b505 100644 --- a/src/activities/network/CrossPointWebServerActivity.cpp +++ b/src/activities/network/CrossPointWebServerActivity.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -86,15 +87,12 @@ void CrossPointWebServerActivity::onExit() { if (isApMode) { LOG_DBG("WEBACT", "Stopping WiFi AP..."); WiFi.softAPdisconnect(true); + delay(30); + WiFi.mode(WIFI_OFF); + delay(30); } else { - LOG_DBG("WEBACT", "Disconnecting WiFi (graceful)..."); - WiFi.disconnect(false); // false = don't erase credentials, send disconnect frame + HalClock::wifiOff(); } - delay(30); // Allow disconnect frame to be sent - - LOG_DBG("WEBACT", "Setting WiFi mode OFF..."); - WiFi.mode(WIFI_OFF); - delay(30); // Allow WiFi hardware to power down LOG_DBG("WEBACT", "Free heap at onExit end: %d bytes", ESP.getFreeHeap()); } diff --git a/src/activities/reader/KOReaderSyncActivity.cpp b/src/activities/reader/KOReaderSyncActivity.cpp index e76116d2..e76e2dba 100644 --- a/src/activities/reader/KOReaderSyncActivity.cpp +++ b/src/activities/reader/KOReaderSyncActivity.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include "KOReaderCredentialStore.h" #include "KOReaderDocumentId.h" @@ -14,18 +13,6 @@ #include "components/UITheme.h" #include "fontIds.h" -namespace { -void wifiOff() { - if (esp_sntp_enabled()) { - esp_sntp_stop(); - } - WiFi.disconnect(false); - delay(100); - WiFi.mode(WIFI_OFF); - delay(100); -} -} // namespace - void KOReaderSyncActivity::onWifiSelectionComplete(const bool success) { if (!success) { LOG_DBG("KOSync", "WiFi connection failed, exiting"); @@ -149,7 +136,7 @@ void KOReaderSyncActivity::performUpload() { const auto result = KOReaderSyncClient::updateProgress(progress); if (result != KOReaderSyncClient::OK) { - wifiOff(); + HalClock::wifiOff(true); { RenderLock lock(*this); state = SYNC_FAILED; @@ -159,7 +146,7 @@ void KOReaderSyncActivity::performUpload() { return; } - wifiOff(); + HalClock::wifiOff(true); { RenderLock lock(*this); state = UPLOAD_COMPLETE; @@ -193,7 +180,7 @@ void KOReaderSyncActivity::onEnter() { void KOReaderSyncActivity::onExit() { Activity::onExit(); - wifiOff(); + HalClock::wifiOff(true); } void KOReaderSyncActivity::render(RenderLock&&) { diff --git a/src/activities/settings/DetectTimezoneActivity.cpp b/src/activities/settings/DetectTimezoneActivity.cpp index a969616d..70859b41 100644 --- a/src/activities/settings/DetectTimezoneActivity.cpp +++ b/src/activities/settings/DetectTimezoneActivity.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include @@ -188,15 +187,6 @@ bool detectTimezoneSetting(uint8_t& outSetting, std::string& outIana, bool& outD return true; } -void wifiOff() { - if (esp_sntp_enabled()) { - esp_sntp_stop(); - } - WiFi.disconnect(false); - delay(100); - WiFi.mode(WIFI_OFF); - delay(100); -} } // namespace void DetectTimezoneActivity::onEnter() { @@ -219,7 +209,7 @@ void DetectTimezoneActivity::onEnter() { void DetectTimezoneActivity::onExit() { Activity::onExit(); - wifiOff(); + HalClock::wifiOff(); } void DetectTimezoneActivity::onWifiSelectionComplete(bool success) { @@ -254,7 +244,7 @@ void DetectTimezoneActivity::performDetect() { state = FAILED; } - wifiOff(); + HalClock::wifiOff(); requestUpdate(); } diff --git a/src/activities/settings/KOReaderAuthActivity.cpp b/src/activities/settings/KOReaderAuthActivity.cpp index 2240ac6e..66ea2f3b 100644 --- a/src/activities/settings/KOReaderAuthActivity.cpp +++ b/src/activities/settings/KOReaderAuthActivity.cpp @@ -1,6 +1,7 @@ #include "KOReaderAuthActivity.h" #include +#include #include #include @@ -65,11 +66,7 @@ void KOReaderAuthActivity::onEnter() { void KOReaderAuthActivity::onExit() { Activity::onExit(); - // Turn off wifi - WiFi.disconnect(false); - delay(100); - WiFi.mode(WIFI_OFF); - delay(100); + HalClock::wifiOff(); } void KOReaderAuthActivity::render(RenderLock&&) { diff --git a/src/activities/settings/OtaUpdateActivity.cpp b/src/activities/settings/OtaUpdateActivity.cpp index c661a618..73082529 100644 --- a/src/activities/settings/OtaUpdateActivity.cpp +++ b/src/activities/settings/OtaUpdateActivity.cpp @@ -1,6 +1,7 @@ #include "OtaUpdateActivity.h" #include +#include #include #include @@ -66,11 +67,7 @@ void OtaUpdateActivity::onEnter() { void OtaUpdateActivity::onExit() { Activity::onExit(); - // Turn off wifi - WiFi.disconnect(false); // false = don't erase credentials, send disconnect frame - delay(100); // Allow disconnect frame to be sent - WiFi.mode(WIFI_OFF); - delay(100); // Allow WiFi hardware to fully power down + HalClock::wifiOff(); } void OtaUpdateActivity::render(RenderLock&&) { diff --git a/src/activities/settings/SyncTimeActivity.cpp b/src/activities/settings/SyncTimeActivity.cpp index 66ca2683..fc81f3aa 100644 --- a/src/activities/settings/SyncTimeActivity.cpp +++ b/src/activities/settings/SyncTimeActivity.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include "CrossPointSettings.h" #include "MappedInputManager.h" @@ -13,18 +12,6 @@ #include "components/UITheme.h" #include "fontIds.h" -namespace { -void wifiOff() { - if (esp_sntp_enabled()) { - esp_sntp_stop(); - } - WiFi.disconnect(false); - delay(100); - WiFi.mode(WIFI_OFF); - delay(100); -} -} // namespace - void SyncTimeActivity::onEnter() { Activity::onEnter(); @@ -45,7 +32,7 @@ void SyncTimeActivity::onEnter() { void SyncTimeActivity::onExit() { Activity::onExit(); - wifiOff(); + HalClock::wifiOff(true); } void SyncTimeActivity::onWifiSelectionComplete(bool success) { @@ -68,7 +55,7 @@ void SyncTimeActivity::onWifiSelectionCancelled() { finish(); } void SyncTimeActivity::performSync() { bool ok = HalClock::syncNtp(); - wifiOff(); + HalClock::wifiOff(true); state = ok ? SUCCESS : FAILED; requestUpdate();