Public Access
S1 #7 step 3: the Wi-Fi Service applies IP, DNS and NTP settings
Joining a Saved Network uses its Fixed address, mask and gateway, or DHCP. DNS comes from Settings on Fixed networks and when "Always use my DNS" is on; NTP servers come from Settings, after any that DHCP offered. Both are re-checked every 30 s, since a DHCP renewal puts DHCP's DNS back and clears the NTP slots it didn't fill. `wifi status` shows what's in use, where it came from, and which NTP servers answered; `wifi ip`, `wifi dns`, `wifi ntp`. Debug Builds: `wifi ip ... try <s>` reverts unless kept. On knbg-guests (10.39.39.0/24, gateway .1): Fixed .12 and .13 both reach the internet through 9.9.9.9; a wrong gateway on trial cut the device off and came back by itself; back to DHCP; both NTP servers answer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
+95
-1
@@ -18,6 +18,7 @@
|
|||||||
#include "apps/setup_app.h"
|
#include "apps/setup_app.h"
|
||||||
#include "event_bus.h"
|
#include "event_bus.h"
|
||||||
#include "file_receiver.h"
|
#include "file_receiver.h"
|
||||||
|
#include "ipv4.h"
|
||||||
#include "key_mapper.h"
|
#include "key_mapper.h"
|
||||||
#include "platform/console.h"
|
#include "platform/console.h"
|
||||||
#include "platform/crash_report.h"
|
#include "platform/crash_report.h"
|
||||||
@@ -359,6 +360,27 @@ static void uploadStep() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RORO_DEBUG
|
||||||
|
// `wifi ip ... try <seconds>`: a trial IP setting that reverts unless `wifi ip keep` arrives, so a
|
||||||
|
// wrong address tried over Wi-Fi doesn't cut the device off for good.
|
||||||
|
static struct {
|
||||||
|
bool active = false;
|
||||||
|
uint32_t untilMs = 0;
|
||||||
|
std::string ssid;
|
||||||
|
bool wasFixed = false;
|
||||||
|
net::FixedIp was;
|
||||||
|
} ipTrial;
|
||||||
|
|
||||||
|
static void ipTrialStep() {
|
||||||
|
if (!ipTrial.active || static_cast<int32_t>(millis() - ipTrial.untilMs) < 0) return;
|
||||||
|
ipTrial.active = false;
|
||||||
|
savedNetworks->setIp(ipTrial.ssid, ipTrial.wasFixed ? &ipTrial.was : nullptr);
|
||||||
|
console.printf("wifi ip: trial over, %s is back to %s\n", ipTrial.ssid.c_str(),
|
||||||
|
ipTrial.wasFixed ? net::formatFixed(ipTrial.was).c_str() : "Automatic (DHCP)");
|
||||||
|
wifi->ipSettingChanged(ipTrial.ssid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* const kHelp =
|
static const char* const kHelp =
|
||||||
"info firmware, uptime, memory, Wi-Fi, app slots\n"
|
"info firmware, uptime, memory, Wi-Fi, app slots\n"
|
||||||
"tasks FreeRTOS tasks: state, priority, free stack, CPU\n"
|
"tasks FreeRTOS tasks: state, priority, free stack, CPU\n"
|
||||||
@@ -374,12 +396,15 @@ static const char* const kHelp =
|
|||||||
"coredump erase forget the core dump in flash\n"
|
"coredump erase forget the core dump in flash\n"
|
||||||
"key <name|char> press a key: up down left right select back home del tab space, or one character\n"
|
"key <name|char> press a key: up down left right select back home del tab space, or one character\n"
|
||||||
"wifi status | wifi add <ssid><TAB><password>\n"
|
"wifi status | wifi add <ssid><TAB><password>\n"
|
||||||
|
"wifi ip <ssid> dhcp | wifi ip <ssid> <address>/<prefix> [gateway] a Saved Network's IP setting\n"
|
||||||
|
"wifi dns <a> [b] | wifi dns always on|off | wifi ntp <a> [b] DNS and NTP servers\n"
|
||||||
"gemini get <url> fetch a Gemini page and report header, size, certificate, heap\n"
|
"gemini get <url> fetch a Gemini page and report header, size, certificate, heap\n"
|
||||||
"irc start | irc stop | irc dump | irc say <buffer> <text>\n"
|
"irc start | irc stop | irc dump | irc say <buffer> <text>\n"
|
||||||
"ls [folder] | rm <path> | install <path.ota> (Update from SD)\n"
|
"ls [folder] | rm <path> | install <path.ota> (Update from SD)\n"
|
||||||
"sd card | sd list | cat <path> | log <text> | burst | sound on|off | short | normal\n"
|
"sd card | sd list | cat <path> | log <text> | burst | sound on|off | short | normal\n"
|
||||||
#ifdef RORO_DEBUG
|
#ifdef RORO_DEBUG
|
||||||
"crash abort|wdt crash on purpose (to test crash reports and Safe Mode)\n"
|
"crash abort|wdt crash on purpose (to test crash reports and Safe Mode)\n"
|
||||||
|
"wifi ip ... try <seconds> | wifi ip keep a trial IP setting: back to the previous one unless kept\n"
|
||||||
"lora inject <hex> [rssi] [snr] a packet into the LoRa Scanner as if received (nothing is sent)\n"
|
"lora inject <hex> [rssi] [snr] a packet into the LoRa Scanner as if received (nothing is sent)\n"
|
||||||
"coredump get (Debug Console only) send the raw core dump: use scripts/rdbg.py coredump\n"
|
"coredump get (Debug Console only) send the raw core dump: use scripts/rdbg.py coredump\n"
|
||||||
"reset (Debug Console only) restart at once, even if the main loop is stuck\n"
|
"reset (Debug Console only) restart at once, even if the main loop is stuck\n"
|
||||||
@@ -588,11 +613,77 @@ static void runCommand(String line) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (line == "wifi status")
|
if (line == "wifi status") {
|
||||||
console.printf("wifi: state %d ssid '%s' rssi %d ip %s clock %s heap %u min %u | fw %s%s\n",
|
console.printf("wifi: state %d ssid '%s' rssi %d ip %s clock %s heap %u min %u | fw %s%s\n",
|
||||||
(int)wifi->state(), wifi->ssid().c_str(), wifi->rssi(), wifi->ip().c_str(),
|
(int)wifi->state(), wifi->ssid().c_str(), wifi->rssi(), wifi->ip().c_str(),
|
||||||
clockService->displayTime().c_str(), ESP.getFreeHeap(), ESP.getMinFreeHeap(), versionString(),
|
clockService->displayTime().c_str(), ESP.getFreeHeap(), ESP.getMinFreeHeap(), versionString(),
|
||||||
update->onProbation() ? " (on probation)" : "");
|
update->onProbation() ? " (on probation)" : "");
|
||||||
|
WifiService::Connection c = wifi->connection(); // S1, Q115: what's in use and where it came from
|
||||||
|
if (c.connected) {
|
||||||
|
console.printf("wifi: address %s/%d (%s), gateway %s\n", c.address.c_str(), c.prefix, c.fixed ? "fixed" : "DHCP",
|
||||||
|
c.gateway.empty() ? "none" : c.gateway.c_str());
|
||||||
|
console.printf("wifi: dns %s %s (%s)\n", c.dns[0].empty() ? "none" : c.dns[0].c_str(), c.dns[1].c_str(),
|
||||||
|
c.dnsFromSettings ? "Settings" : "DHCP");
|
||||||
|
console.print("wifi: ntp");
|
||||||
|
for (int i = 0; i < c.ntpCount; i++) console.printf(" %s (%s%s)", c.ntp[i].server.c_str(), c.ntp[i].fromDhcp ? "DHCP" : "Settings", c.ntp[i].answered ? ", answered" : "");
|
||||||
|
console.println(c.ntpCount ? "" : " none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line.startsWith("wifi ip ")) { // wifi ip <ssid> dhcp | <address>/<prefix> [gateway] (the SSID may hold spaces)
|
||||||
|
std::string rest = line.substring(8).c_str();
|
||||||
|
#ifdef RORO_DEBUG
|
||||||
|
if (rest == "keep") { // the trial setting stays
|
||||||
|
console.println(ipTrial.active ? "wifi ip: kept" : "wifi ip: no trial running");
|
||||||
|
ipTrial.active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t trialS = 0;
|
||||||
|
size_t tryAt = rest.rfind(" try ");
|
||||||
|
if (tryAt != std::string::npos) {
|
||||||
|
trialS = strtoul(rest.c_str() + tryAt + 5, nullptr, 10);
|
||||||
|
rest = rest.substr(0, tryAt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
std::string ssid, why;
|
||||||
|
net::FixedIp fixed;
|
||||||
|
bool dhcp = rest.size() > 5 && rest.compare(rest.size() - 5, 5, " dhcp") == 0;
|
||||||
|
if (dhcp) ssid = rest.substr(0, rest.size() - 5);
|
||||||
|
else {
|
||||||
|
size_t slash = rest.rfind('/'), space = slash == std::string::npos ? slash : rest.rfind(' ', slash);
|
||||||
|
if (space == std::string::npos) why = "usage: wifi ip <ssid> dhcp | <address>/<prefix> [gateway]";
|
||||||
|
else {
|
||||||
|
ssid = rest.substr(0, space);
|
||||||
|
why = net::parseFixed(rest.substr(space + 1), fixed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const SavedNetwork* before = why.empty() ? savedNetworks->find(ssid) : nullptr;
|
||||||
|
#ifdef RORO_DEBUG
|
||||||
|
if (before && trialS) ipTrial = {true, millis() + trialS * 1000, ssid, before->fixed, before->ip};
|
||||||
|
#endif
|
||||||
|
if (why.empty()) why = savedNetworks->setIp(ssid, dhcp ? nullptr : &fixed);
|
||||||
|
if (!why.empty()) return (void)console.printf("wifi ip: %s\n", why.c_str());
|
||||||
|
console.printf("wifi ip: %s is now %s\n", ssid.c_str(), dhcp ? "Automatic (DHCP)" : net::formatFixed(fixed).c_str());
|
||||||
|
wifi->ipSettingChanged(ssid);
|
||||||
|
}
|
||||||
|
if ((line.startsWith("wifi dns ") && !line.startsWith("wifi dns always")) || line.startsWith("wifi ntp ")) { // <a> [b]
|
||||||
|
bool dns = line.startsWith("wifi dns ");
|
||||||
|
std::string rest = line.substring(9).c_str();
|
||||||
|
size_t space = rest.find(' ');
|
||||||
|
std::string first = rest.substr(0, space), second = space == std::string::npos ? "" : rest.substr(space + 1);
|
||||||
|
Setting a = dns ? Setting::Dns1 : Setting::Ntp1, b = dns ? Setting::Dns2 : Setting::Ntp2;
|
||||||
|
std::string oldFirst = settings.getString(a);
|
||||||
|
// Both or neither: a refused second entry leaves the first as it was.
|
||||||
|
bool ok = settings.setString(a, first) && (settings.setString(b, second) || (settings.setString(a, oldFirst), false));
|
||||||
|
if (!ok) console.printf("wifi %s: %s\n", dns ? "dns" : "ntp", dns ? "an IPv4 address, then a second one if you like" : "a host name or an IPv4 address, then a second one if you like");
|
||||||
|
else {
|
||||||
|
console.printf("wifi %s: %s %s\n", dns ? "dns" : "ntp", first.c_str(), second.c_str());
|
||||||
|
wifi->serversChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line == "wifi dns always on" || line == "wifi dns always off") {
|
||||||
|
settings.setBool(Setting::DnsAlways, line.endsWith("on"));
|
||||||
|
wifi->serversChanged();
|
||||||
|
}
|
||||||
if (line == "sound off") settings.setBool(Setting::Sound, false);
|
if (line == "sound off") settings.setBool(Setting::Sound, false);
|
||||||
if (line == "sound on") settings.setBool(Setting::Sound, true);
|
if (line == "sound on") settings.setBool(Setting::Sound, true);
|
||||||
if (line == "short") {
|
if (line == "short") {
|
||||||
@@ -671,6 +762,9 @@ void loop() {
|
|||||||
|
|
||||||
serialCommands();
|
serialCommands();
|
||||||
remoteCommands();
|
remoteCommands();
|
||||||
|
#ifdef RORO_DEBUG
|
||||||
|
ipTrialStep();
|
||||||
|
#endif
|
||||||
noteStableOnce(now);
|
noteStableOnce(now);
|
||||||
uploadStep();
|
uploadStep();
|
||||||
printListingWhenReady();
|
printListingWhenReady();
|
||||||
|
|||||||
@@ -3,10 +3,121 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <esp_sntp.h>
|
#include <esp_sntp.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "ipv4.h"
|
||||||
|
|
||||||
namespace roro {
|
namespace roro {
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
IPAddress toIp(uint32_t a) { return IPAddress(a >> 24, a >> 16 & 255, a >> 8 & 255, a & 255); }
|
||||||
|
IPAddress toIp(const std::string& text) {
|
||||||
|
uint32_t a = 0;
|
||||||
|
net::parseIpv4(text, a);
|
||||||
|
return toIp(a);
|
||||||
|
}
|
||||||
|
const IPAddress kNoAddress(static_cast<uint32_t>(0));
|
||||||
|
// A slot lwIP filled from DHCP has an address and no name; ours are set by name.
|
||||||
|
bool sntpSlotFromDhcp(int i) {
|
||||||
|
const ip_addr_t* a = esp_sntp_getserver(i);
|
||||||
|
return !esp_sntp_getservername(i) && a && !ip_addr_isany(a);
|
||||||
|
}
|
||||||
|
constexpr int kNtpSlots = 3; // CONFIG_LWIP_SNTP_MAX_SERVERS
|
||||||
|
constexpr uint32_t kServersEveryMs = 30000;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Joins a Saved Network with its IP setting (S1, Q105): Fixed, or DHCP.
|
||||||
|
void WifiService::join(const std::string& ssid, const std::string& password) {
|
||||||
|
const SavedNetwork* n = saved_.find(ssid);
|
||||||
|
fixed_ = n && n->fixed;
|
||||||
|
if (fixed_) {
|
||||||
|
// Nothing comes from DHCP here: forget the NTP servers a previous network offered.
|
||||||
|
for (int i = 0; i < kNtpSlots; i++)
|
||||||
|
if (sntpSlotFromDhcp(i)) esp_sntp_setserver(i, nullptr);
|
||||||
|
WiFi.config(toIp(n->ip.address), toIp(n->ip.gateway), toIp(net::maskOf(n->ip.prefix)),
|
||||||
|
toIp(settings_.getString(Setting::Dns1)), toIp(settings_.getString(Setting::Dns2)));
|
||||||
|
} else {
|
||||||
|
WiFi.config(kNoAddress, kNoAddress, kNoAddress); // DHCP
|
||||||
|
}
|
||||||
|
WiFi.begin(ssid.c_str(), password.empty() ? nullptr : password.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiService::ipSettingChanged(const std::string& ssid) {
|
||||||
|
if (controller_.state() != WifiController::State::Connected || controller_.ssid() != ssid) return;
|
||||||
|
WiFi.disconnect();
|
||||||
|
apply(controller_.disconnected(millis()));
|
||||||
|
controller_.retryNow(millis());
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNS and NTP as decided in Q108 and Q110. Run when connected, when a setting changes, and now
|
||||||
|
// and then: a DHCP renewal puts DHCP's DNS back and clears the NTP slots it didn't fill.
|
||||||
|
void WifiService::applyServers(Why why) {
|
||||||
|
if (controller_.state() != WifiController::State::Connected) return;
|
||||||
|
serversCheckedMs_ = millis();
|
||||||
|
bool changed = why != Why::Check;
|
||||||
|
|
||||||
|
bool wasFromSettings = dnsFromSettings_;
|
||||||
|
dnsFromSettings_ = fixed_ || settings_.getBool(Setting::DnsAlways);
|
||||||
|
if (dnsFromSettings_) {
|
||||||
|
IPAddress dns1 = toIp(settings_.getString(Setting::Dns1)), dns2 = toIp(settings_.getString(Setting::Dns2));
|
||||||
|
if (WiFi.dnsIP(0) != dns1 || WiFi.dnsIP(1) != dns2) WiFi.setDNS(dns1, dns2);
|
||||||
|
} else if (why == Why::SettingsChanged && wasFromSettings) {
|
||||||
|
// "Always use my DNS" was switched off: only a new lease brings DHCP's servers back.
|
||||||
|
ipSettingChanged(controller_.ssid());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NTP: the servers DHCP offered stay first; ours follow.
|
||||||
|
int fromDhcp = 0;
|
||||||
|
while (!fixed_ && fromDhcp < kNtpSlots && sntpSlotFromDhcp(fromDhcp)) fromDhcp++;
|
||||||
|
std::string wanted[2] = {settings_.getString(Setting::Ntp1), settings_.getString(Setting::Ntp2)};
|
||||||
|
bool touched = false;
|
||||||
|
for (int i = fromDhcp, mine = 0; i < kNtpSlots; i++, mine++) {
|
||||||
|
const char* current = esp_sntp_getservername(i);
|
||||||
|
if (mine < 2 && !wanted[mine].empty()) {
|
||||||
|
if (current && wanted[mine] == current) continue;
|
||||||
|
ntpNames_[mine] = wanted[mine];
|
||||||
|
esp_sntp_setservername(i, ntpNames_[mine].c_str());
|
||||||
|
touched = true;
|
||||||
|
} else if (current || sntpSlotFromDhcp(i)) {
|
||||||
|
esp_sntp_setserver(i, nullptr);
|
||||||
|
touched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!esp_sntp_enabled()) {
|
||||||
|
esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
|
||||||
|
esp_sntp_init();
|
||||||
|
} else if (touched || changed) {
|
||||||
|
esp_sntp_restart();
|
||||||
|
}
|
||||||
|
if (touched || changed) ntpWaiting_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiService::Connection WifiService::connection() const {
|
||||||
|
Connection c;
|
||||||
|
c.connected = controller_.state() == WifiController::State::Connected;
|
||||||
|
if (!c.connected) return c;
|
||||||
|
c.fixed = fixed_;
|
||||||
|
c.dnsFromSettings = dnsFromSettings_;
|
||||||
|
c.address = WiFi.localIP().toString().c_str();
|
||||||
|
c.mask = WiFi.subnetMask().toString().c_str();
|
||||||
|
c.prefix = WiFi.subnetCIDR();
|
||||||
|
IPAddress gateway = WiFi.gatewayIP();
|
||||||
|
if (gateway != kNoAddress) c.gateway = gateway.toString().c_str();
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
if (WiFi.dnsIP(i) != kNoAddress) c.dns[i] = WiFi.dnsIP(i).toString().c_str();
|
||||||
|
for (int i = 0; i < kNtpSlots; i++) {
|
||||||
|
const char* name = esp_sntp_getservername(i);
|
||||||
|
bool answered = esp_sntp_getreachability(i) != 0;
|
||||||
|
if (name) c.ntp[c.ntpCount++] = {name, false, answered};
|
||||||
|
else if (sntpSlotFromDhcp(i)) c.ntp[c.ntpCount++] = {ipaddr_ntoa(esp_sntp_getserver(i)), true, answered};
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
std::string WifiService::ip() const {
|
std::string WifiService::ip() const {
|
||||||
return controller_.state() == WifiController::State::Connected ? WiFi.localIP().toString().c_str() : "";
|
return controller_.state() == WifiController::State::Connected ? WiFi.localIP().toString().c_str() : "";
|
||||||
}
|
}
|
||||||
@@ -20,6 +131,7 @@ void WifiService::startScan(int channel) {
|
|||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.setAutoReconnect(false); // the controller decides when to reconnect
|
WiFi.setAutoReconnect(false); // the controller decides when to reconnect
|
||||||
esp_wifi_set_country_code("EU", true);
|
esp_wifi_set_country_code("EU", true);
|
||||||
|
esp_sntp_servermode_dhcp(true); // before DHCP runs: take the NTP servers it offers (Q110)
|
||||||
radioInitialised_ = true;
|
radioInitialised_ = true;
|
||||||
}
|
}
|
||||||
if (scanRunning_) return;
|
if (scanRunning_) return;
|
||||||
@@ -87,13 +199,7 @@ void WifiService::finishScan(uint32_t nowMs) {
|
|||||||
|
|
||||||
void WifiService::startNtp() {
|
void WifiService::startNtp() {
|
||||||
// Not configTime(): it would overwrite the POSIX TZ the Clock applies.
|
// Not configTime(): it would overwrite the POSIX TZ the Clock applies.
|
||||||
if (!esp_sntp_enabled()) {
|
applyServers(Why::Joined);
|
||||||
esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
|
|
||||||
esp_sntp_setservername(0, "pool.ntp.org");
|
|
||||||
esp_sntp_init();
|
|
||||||
} else {
|
|
||||||
esp_sntp_restart();
|
|
||||||
}
|
|
||||||
ntpWaiting_ = true;
|
ntpWaiting_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +208,7 @@ void WifiService::apply(const WifiController::Step& step) {
|
|||||||
switch (step.action) {
|
switch (step.action) {
|
||||||
case Action::None: break;
|
case Action::None: break;
|
||||||
case Action::StartScan: startScan(); break;
|
case Action::StartScan: startScan(); break;
|
||||||
case Action::Connect: WiFi.begin(step.ssid.c_str(), step.password.empty() ? nullptr : step.password.c_str()); break;
|
case Action::Connect: join(step.ssid, step.password); break;
|
||||||
case Action::Disconnect: WiFi.disconnect(); break;
|
case Action::Disconnect: WiFi.disconnect(); break;
|
||||||
case Action::RadioOff:
|
case Action::RadioOff:
|
||||||
WiFi.disconnect(true);
|
WiFi.disconnect(true);
|
||||||
@@ -143,6 +249,8 @@ void WifiService::tick(uint32_t nowMs) {
|
|||||||
|
|
||||||
apply(controller_.update(nowMs, settings_.getBool(Setting::WifiEnabled)));
|
apply(controller_.update(nowMs, settings_.getBool(Setting::WifiEnabled)));
|
||||||
|
|
||||||
|
if (controller_.state() == State::Connected && nowMs - serversCheckedMs_ >= kServersEveryMs) applyServers(Why::Check);
|
||||||
|
|
||||||
if (ntpWaiting_ && sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
|
if (ntpWaiting_ && sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
|
||||||
ntpWaiting_ = false;
|
ntpWaiting_ = false;
|
||||||
clock_.set(static_cast<int64_t>(time(nullptr)), TimeSource::Ntp);
|
clock_.set(static_cast<int64_t>(time(nullptr)), TimeSource::Ntp);
|
||||||
|
|||||||
@@ -36,6 +36,27 @@ class WifiService : public Service {
|
|||||||
// Done with list scans: switch the radio back off if Wi-Fi itself is off.
|
// Done with list scans: switch the radio back off if Wi-Fi itself is off.
|
||||||
void endListScans();
|
void endListScans();
|
||||||
|
|
||||||
|
// What the device is using and where each part came from (S1, Q113).
|
||||||
|
struct Connection {
|
||||||
|
bool connected = false;
|
||||||
|
bool fixed = false; // the address: Fixed, or from DHCP
|
||||||
|
bool dnsFromSettings = false; // DNS: from Settings, or from DHCP
|
||||||
|
std::string address, mask, gateway;
|
||||||
|
int prefix = 0;
|
||||||
|
std::string dns[2];
|
||||||
|
struct Ntp {
|
||||||
|
std::string server;
|
||||||
|
bool fromDhcp = false;
|
||||||
|
bool answered = false; // it has replied since the last (re)start
|
||||||
|
} ntp[3];
|
||||||
|
int ntpCount = 0;
|
||||||
|
};
|
||||||
|
Connection connection() const;
|
||||||
|
// A Saved Network's IP setting changed: if it's the one in use, join it again with it (Q114).
|
||||||
|
void ipSettingChanged(const std::string& ssid);
|
||||||
|
// The DNS or NTP settings changed: use them now.
|
||||||
|
void serversChanged() { applyServers(Why::SettingsChanged); }
|
||||||
|
|
||||||
// A Saved Network was added: try it now rather than after the retry delay.
|
// A Saved Network was added: try it now rather than after the retry delay.
|
||||||
void savedNetworksChanged() { controller_.retryNow(millis()); }
|
void savedNetworksChanged() { controller_.retryNow(millis()); }
|
||||||
|
|
||||||
@@ -47,6 +68,9 @@ class WifiService : public Service {
|
|||||||
void startScan(int channel = 0);
|
void startScan(int channel = 0);
|
||||||
void finishScan(uint32_t nowMs);
|
void finishScan(uint32_t nowMs);
|
||||||
void startNtp();
|
void startNtp();
|
||||||
|
void join(const std::string& ssid, const std::string& password);
|
||||||
|
enum class Why { Joined, SettingsChanged, Check };
|
||||||
|
void applyServers(Why why); // DNS and NTP, as Settings and the network say
|
||||||
|
|
||||||
Settings& settings_;
|
Settings& settings_;
|
||||||
SavedNetworks& saved_;
|
SavedNetworks& saved_;
|
||||||
@@ -58,6 +82,10 @@ class WifiService : public Service {
|
|||||||
uint32_t listScanSeq_ = 0;
|
uint32_t listScanSeq_ = 0;
|
||||||
bool ntpWaiting_ = false;
|
bool ntpWaiting_ = false;
|
||||||
bool radioInitialised_ = false;
|
bool radioInitialised_ = false;
|
||||||
|
bool fixed_ = false; // the network in use has a Fixed address
|
||||||
|
bool dnsFromSettings_ = false;
|
||||||
|
std::string ntpNames_[2]; // lwIP keeps the pointers, so the names live here
|
||||||
|
uint32_t serversCheckedMs_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace roro
|
} // namespace roro
|
||||||
|
|||||||
Reference in New Issue
Block a user