From d47858c19d73df36f705cc1ffc3a32809c5b80c0 Mon Sep 17 00:00:00 2001 From: Martin Dobrev Date: Sat, 5 Sep 2026 15:40:17 +0100 Subject: [PATCH] portal: the split left two unlabelled switches and a warning that could not fire MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Splitting Wi-Fi into an access point and a station changed the keys the API publishes, and the page had two places that still knew the old one. The label table did not, so the new switches rendered under their raw keys — "wifi_ap" and "wifi_sta" — with no word about what either does or which one is worth turning off. They are named now, and the note says the useful thing: the access point is the one to switch off on a battery, because it must beacon and cannot sleep, and it frees only a couple of kilobytes so it is worth doing for the power rather than the memory. The second is the one that matters. Saving the links form used to ask "Turn Wi-Fi off?" before cutting the connection this page is usually being read over. That check tested a key called "wifi", which no longer exists — so it had quietly stopped firing, and the portal would take away its own access without a word. It now asks whenever the save would leave both Wi-Fi links down, which includes turning one off while the other is already off: the case that locks somebody out by changing a single switch, and one the old single-key check could not have expressed even before the split. Also says what the section is. "Local links" is how a phone or laptop reaches this node, not where Reticulum routes — that is the transport form above — and the name invites the other reading. Verified headless against a stub: the guard warns when both links end up down and when the second is already down, and stays quiet when the station survives or nothing changes. --- data/settings.html | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/data/settings.html b/data/settings.html index 105d64a..0164338 100644 --- a/data/settings.html +++ b/data/settings.html @@ -209,17 +209,23 @@

Backup & provisioning

Local links

-
The ways a computer or phone reaches this node directly. Every service — this page, the API, Reticulum TCP on - :4242 — answers on whichever of them is up; LoRa is not one of them and never carries IP. A switch that is greyed out names +
The ways a computer or phone reaches this node directly — not where Reticulum routes, which is + Reticulum transport above. Every service — this page, the API, Reticulum TCP on :4242 — answers on whichever of + these is up; nothing here chooses what Reticulum binds to, it simply answers wherever it can. LoRa is not one of them and never + carries IP. A switch that is greyed out names the reason: the board lacks the hardware, or this firmware build has no driver for it.
-
Switching Wi-Fi off restarts the node without its access point. It stays reachable over USB or PPP where the board - has them, and always through the serial maintenance console: WIFI ON there turns the access point back on. - USB and PPP apply without a restart. With PPP on, the serial speed is the whole port's — the console and the log run at it too - — and the console goes quiet while a host has PPP open on the port.
+
The two Wi-Fi links switch separately. Turning the access point off is the one worth doing on a battery: it + must beacon continuously and cannot sleep, so it draws current whether or not anyone is connected, while a station dozes + between beacons. It frees only a couple of kilobytes of memory — the radio driver is the bulk of that and the station needs it + too — so switch it off for the power, not for the RAM.
+
Either Wi-Fi change restarts the node, because the radio's mode is chosen once at start-up. It stays reachable over + USB or PPP where the board has them, and always through the serial maintenance console: WIFI ON there turns both back + on, or SET links.wifi_ap on just the one. USB and PPP apply without a restart. With PPP on, the serial speed is the + whole port's — the console and the log run at it too — and the console goes quiet while a host has PPP open on it.

Maintenance

@@ -292,6 +298,10 @@

Danger zone

return data; } +// The links as the page last loaded them, so a save that changes one Wi-Fi +// switch can tell whether the other one is already off. +let lastLinks = {}; + function fill(form, obj) { for (const el of form.elements) { if (!el.name || !(el.name in obj)) continue; @@ -438,11 +448,15 @@

Danger zone

// firmware learns to offer appears here without an edit. The only thing // this page adds is the human wording for each key. const LINK_LABELS = { - wifi: ["Wi-Fi (access point & station)", "Off — USB/PPP or the serial console only"], - usb: ["USB networking (CDC-NCM)", "Off"], - ppp: ["PPP over the serial bridge", "Off"], + wifi_ap: ["Wi-Fi access point — this node offers its own network", + "Off — saves the most power of the two: an access point must beacon and cannot sleep"], + wifi_sta: ["Wi-Fi station — this node joins your network", + "Off — nothing is reachable over the LAN"], + usb: ["USB networking (CDC-NCM)", "Off"], + ppp: ["PPP over the serial bridge", "Off"], }; const lk = cfg.links || {}; + lastLinks = lk; // the submit handler compares against these const fields = $("linkFields"); fields.replaceChildren(); for (const [key, l] of Object.entries(lk)) { const [label, offText] = LINK_LABELS[key] || [key, "Off"]; @@ -549,7 +563,15 @@

Danger zone

const body = {}; for (const sel of ev.target.querySelectorAll("#linkFields select")) if (!sel.disabled) body[sel.name] = sel.name === "ppp_baud" ? Number(sel.value) : sel.value === "1"; - if (body.wifi === false && !confirm("Turn Wi-Fi off? The access point and this page go away until it is turned back on over USB, PPP or the serial console (WIFI ON).")) return; + // Both Wi-Fi links going down is the case worth stopping on, because this + // page is usually being read over one of them. The check used to be on a + // single "wifi" key; splitting the switches left it testing a key that no + // longer exists, so the warning silently stopped appearing — on the one + // action that can lock somebody out of the node they are configuring. + const wifiOff = k => body[k] === false || (!(k in body) && !(lastLinks[k] || {}).enabled); + if (("wifi_ap" in body || "wifi_sta" in body) && wifiOff("wifi_ap") && wifiOff("wifi_sta") && + !confirm("Turn both Wi-Fi links off? The access point and the LAN connection go away, and this page with them, " + + "until Wi-Fi is turned back on over USB, PPP or the serial console (WIFI ON).")) return; try { const r = await api("/api/settings/links", body); setMsg("linksMsg", (r.restart ? "Saved. Restarting… " : "Saved. ") + (r.note || ""), r.restart ? "warn" : "ok");