2026-08-03 10:49:58 -04:00
|
|
|
#include "wifi_manager.h"
|
|
|
|
|
#include <WiFi.h>
|
|
|
|
|
#include <ESPmDNS.h>
|
2026-08-04 20:57:59 -04:00
|
|
|
#include <M5Unified.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <sys/time.h>
|
2026-08-03 10:49:58 -04:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
|
|
void WiFiManager::begin(SettingsManager& settings) {
|
|
|
|
|
_settings = &settings;
|
|
|
|
|
|
|
|
|
|
if (!_settings->isProvisioned()) {
|
|
|
|
|
Serial.println("[wifi] Not provisioned — starting AP");
|
|
|
|
|
startAP();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startStation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WiFiManager::isConnected() {
|
|
|
|
|
return WiFi.status() == WL_CONNECTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WiFiManager::isAPMode() {
|
|
|
|
|
return _apMode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String WiFiManager::getIP() {
|
|
|
|
|
if (_apMode) {
|
|
|
|
|
return WiFi.softAPIP().toString();
|
|
|
|
|
}
|
|
|
|
|
return WiFi.localIP().toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int WiFiManager::getRSSI() {
|
|
|
|
|
if (_apMode) return 0;
|
|
|
|
|
return WiFi.RSSI();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WiFiManager::startAP() {
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
WiFi.mode(WIFI_AP);
|
|
|
|
|
WiFi.softAP("PaperColor-Setup");
|
|
|
|
|
_apMode = true;
|
|
|
|
|
Serial.printf("[wifi] AP started: PaperColor-Setup, IP: %s\n",
|
|
|
|
|
WiFi.softAPIP().toString().c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WiFiManager::startStation() {
|
|
|
|
|
Settings s = _settings->get();
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
|
|
|
_apMode = false;
|
|
|
|
|
|
|
|
|
|
Serial.printf("[wifi] Connecting to: %s\n", s.wifi_ssid.c_str());
|
|
|
|
|
|
|
|
|
|
for (_retryCount = 0; _retryCount < WIFI_MAX_RETRIES; _retryCount++) {
|
|
|
|
|
if (attemptConnection(s.wifi_ssid, s.wifi_pass)) {
|
|
|
|
|
Serial.printf("[wifi] Connected! IP: %s, RSSI: %d\n",
|
|
|
|
|
WiFi.localIP().toString().c_str(), WiFi.RSSI());
|
|
|
|
|
WiFi.setSleep(WIFI_PS_MIN_MODEM);
|
2026-08-04 20:57:59 -04:00
|
|
|
syncNTP();
|
2026-08-03 10:49:58 -04:00
|
|
|
setupMDNS("papercolor");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Serial.printf("[wifi] Attempt %d/%d failed\n", _retryCount + 1, WIFI_MAX_RETRIES);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Serial.println("[wifi] All attempts failed — falling back to AP mode");
|
|
|
|
|
startAP();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WiFiManager::setupMDNS(const char* hostname) {
|
|
|
|
|
if (MDNS.begin(hostname)) {
|
|
|
|
|
MDNS.addService("http", "tcp", 80);
|
|
|
|
|
Serial.printf("[wifi] mDNS: %s.local\n", hostname);
|
|
|
|
|
} else {
|
|
|
|
|
Serial.println("[wifi] mDNS failed to start");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WiFiManager::attemptConnection(const String& ssid, const String& pass) {
|
|
|
|
|
WiFi.begin(ssid.c_str(), pass.c_str());
|
|
|
|
|
|
|
|
|
|
unsigned long start = millis();
|
|
|
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
|
|
|
if (millis() - start > WIFI_CONNECT_TIMEOUT_MS) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
delay(100);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2026-08-04 20:57:59 -04:00
|
|
|
|
|
|
|
|
void WiFiManager::syncNTP() {
|
|
|
|
|
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
|
|
|
|
|
|
|
|
|
|
// Wait up to 5 seconds for NTP sync
|
|
|
|
|
unsigned long start = millis();
|
|
|
|
|
time_t now = 0;
|
|
|
|
|
while (now < 1600000000 && (millis() - start) < 5000) {
|
|
|
|
|
delay(100);
|
|
|
|
|
time(&now);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (now < 1600000000) {
|
|
|
|
|
Serial.println("[wifi] NTP sync timed out");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write synced time to hardware RTC
|
|
|
|
|
struct tm t;
|
|
|
|
|
gmtime_r(&now, &t);
|
|
|
|
|
|
|
|
|
|
m5::rtc_datetime_t dt;
|
|
|
|
|
dt.date.year = t.tm_year + 1900;
|
|
|
|
|
dt.date.month = t.tm_mon + 1;
|
|
|
|
|
dt.date.date = t.tm_mday;
|
|
|
|
|
dt.time.hours = t.tm_hour;
|
|
|
|
|
dt.time.minutes = t.tm_min;
|
|
|
|
|
dt.time.seconds = t.tm_sec;
|
|
|
|
|
M5.Rtc.setDateTime(dt);
|
|
|
|
|
|
|
|
|
|
Serial.printf("[wifi] NTP synced: %04d-%02d-%02d %02d:%02d:%02d UTC, written to RTC\n",
|
|
|
|
|
dt.date.year, dt.date.month, dt.date.date,
|
|
|
|
|
dt.time.hours, dt.time.minutes, dt.time.seconds);
|
|
|
|
|
}
|