| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #include "network.h"
- #include <WiFi.h>
- #include <time.h>
- #include "config.h"
- #include "rtc.h"
- namespace {
- bool g_synced = false;
- uint32_t g_lastAttemptMs = 0;
- uint32_t g_lastSyncMs = 0;
- bool g_connecting = false;
- void startConnect()
- {
- Serial.printf("[net] connecting to %s\n", WIFI_SSID);
- WiFi.disconnect();
- WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
- g_lastAttemptMs = millis();
- g_connecting = true;
- }
- } // namespace
- namespace network {
- void begin()
- {
- WiFi.mode(WIFI_STA);
- WiFi.setHostname(WIFI_HOSTNAME);
- WiFi.setAutoReconnect(true);
- WiFi.setSleep(true); // the display is idle most of the time
- // Timezone is applied to the system clock regardless of connectivity, so the
- // RTC-derived time renders correctly offline.
- setenv("TZ", TIMEZONE_POSIX, 1);
- tzset();
- startConnect();
- }
- void loop()
- {
- const uint32_t nowMs = millis();
- if (WiFi.status() == WL_CONNECTED) {
- if (g_connecting) {
- g_connecting = false;
- Serial.printf("[net] connected, ip=%s\n", WiFi.localIP().toString().c_str());
- syncTimeNow();
- }
- if (g_synced && nowMs - g_lastSyncMs >= NTP_RESYNC_MS) {
- syncTimeNow();
- }
- return;
- }
- // Not connected: retry, but never more often than WIFI_RETRY_MS.
- const uint32_t since = nowMs - g_lastAttemptMs;
- if (g_connecting && since < WIFI_CONNECT_TIMEOUT_MS) {
- return;
- }
- if (since >= WIFI_RETRY_MS || (g_connecting && since >= WIFI_CONNECT_TIMEOUT_MS)) {
- if (g_connecting) {
- Serial.println("[net] connect attempt timed out");
- g_connecting = false;
- g_lastAttemptMs = nowMs; // hold off for WIFI_RETRY_MS before retrying
- return;
- }
- startConnect();
- }
- }
- bool isConnected()
- {
- return WiFi.status() == WL_CONNECTED;
- }
- bool syncTimeNow()
- {
- if (!isConnected()) {
- return false;
- }
- configTzTime(TIMEZONE_POSIX, NTP_SERVER_1, NTP_SERVER_2);
- // Wait briefly for the first SNTP response. A plausible year means the
- // system clock has been set from the network rather than left at the epoch.
- struct tm local = {};
- const uint32_t deadline = millis() + 10000UL;
- bool got = false;
- while (millis() < deadline) {
- if (getLocalTime(&local, 200) && local.tm_year + 1900 >= 2024) {
- got = true;
- break;
- }
- delay(100);
- }
- if (!got) {
- Serial.println("[net] NTP sync failed");
- return false;
- }
- // Persist UTC into the RTC so timekeeping survives the next outage.
- const time_t utcNow = time(nullptr);
- struct tm utc;
- gmtime_r(&utcNow, &utc);
- if (!rtc::setTime(utc)) {
- Serial.println("[net] NTP ok but RTC write failed");
- }
- g_synced = true;
- g_lastSyncMs = millis();
- Serial.printf("[net] time synced: %04d-%02d-%02d %02d:%02d local\n",
- local.tm_year + 1900, local.tm_mon + 1, local.tm_mday,
- local.tm_hour, local.tm_min);
- return true;
- }
- bool hasSyncedTime()
- {
- return g_synced;
- }
- } // namespace network
|