WiFi: adapter chooser, optional wifis, wrong-password diagnosis
- Menu asks which adapter when several exist (shows USB/PCI); the web UI helper prefers the adapter already configured. - Stale-entry cleanup also marks remaining installer wifis optional so a dead WiFi entry can't hold up boot. - After a failed connect, read wpa_supplicant's log to say wrong password / network not found / rejected. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A97KUggSE3rBL8veDM5Mr4
This commit is contained in:
@@ -107,8 +107,40 @@ except Exception:
|
||||
pass' "$WIFI_NETPLAN_FILE" 2>/dev/null
|
||||
}
|
||||
|
||||
# Why a connect attempt failed, from wpa_supplicant's own log lines in
|
||||
# the journal (netplan runs it as netplan-wpa-<iface>.service). Prints a
|
||||
# short human-readable reason, or nothing if the log says nothing useful.
|
||||
diagnose_failure() {
|
||||
local log
|
||||
log=$(journalctl -b -u "netplan-wpa-$1" -n 150 --no-pager 2>/dev/null) || return 0
|
||||
if grep -q "reason=WRONG_KEY\|pre-shared key may be incorrect" <<< "$log"; then
|
||||
echo "wrong password (the network rejected the key)"
|
||||
elif grep -q "CTRL-EVENT-NETWORK-NOT-FOUND" <<< "$log"; then
|
||||
echo "network not found - wrong name, or out of range of this adapter"
|
||||
elif grep -q "CTRL-EVENT-ASSOC-REJECT\|CTRL-EVENT-AUTH-REJECT" <<< "$log"; then
|
||||
echo "the access point refused the connection (MAC filter, or WPA3-only/unsupported security)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Prefer the adapter our netplan file already configures (if it's still
|
||||
# there) over "first one found", so a built-in card plus a USB dongle
|
||||
# don't swap places between calls.
|
||||
prefer_configured_iface() {
|
||||
[[ -f "$WIFI_NETPLAN_FILE" ]] || return 1
|
||||
python3 -I -c '
|
||||
import sys, os, yaml
|
||||
try:
|
||||
d = yaml.safe_load(open(sys.argv[1]))
|
||||
for n in (d.get("network", {}).get("wifis") or {}):
|
||||
if os.path.exists(sys.argv[2] + "/net/" + str(n)):
|
||||
print(n); sys.exit(0)
|
||||
except Exception:
|
||||
pass
|
||||
sys.exit(1)' "$WIFI_NETPLAN_FILE" "$SYS_CLASS" 2>/dev/null
|
||||
}
|
||||
|
||||
need_iface() {
|
||||
IFACE=$(detect_iface) || reply_error "No WiFi adapter found. If it's a USB adapter, check it's plugged in."
|
||||
IFACE=$(prefer_configured_iface || detect_iface) || reply_error "No WiFi adapter found. If it's a USB adapter, check it's plugged in."
|
||||
command -v iw >/dev/null || reply_error "WiFi support (iw, wpasupplicant) isn't installed - run Core Settings -> WiFi once from the admin menu"
|
||||
}
|
||||
|
||||
@@ -191,11 +223,18 @@ try:
|
||||
del w[n]
|
||||
if not w:
|
||||
del d["network"]["wifis"]
|
||||
# Not "optional" = the boot waits (up to ~2 min) for it to get an address.
|
||||
opt = [n for n, v in w.items() if isinstance(v, dict) and not v.get("optional")]
|
||||
for n in opt:
|
||||
w[n]["optional"] = True
|
||||
if stale or opt:
|
||||
if not stale:
|
||||
shutil.copy2(p, p + ".kiosk-bak")
|
||||
mode = os.stat(p).st_mode & 0o777
|
||||
with open(p, "w") as fh:
|
||||
yaml.safe_dump(d, fh, default_flow_style=False)
|
||||
os.chmod(p, mode)
|
||||
print("Removed stale WiFi entries from %s: %s" % (p, ", ".join(map(str, stale))))
|
||||
print("Fixed WiFi entries in %s (removed: %s)" % (p, ", ".join(map(str, stale)) or "none"))
|
||||
except Exception:
|
||||
pass
|
||||
PYEOF
|
||||
@@ -271,6 +310,11 @@ do_connect() {
|
||||
|
||||
if [[ -z "$addr" ]]; then
|
||||
restore "$backup"
|
||||
local why
|
||||
why=$(diagnose_failure "$IFACE")
|
||||
if [[ -n "$why" ]]; then
|
||||
reply_error "Couldn't connect to \"$ssid\": $why."
|
||||
fi
|
||||
if [[ -n "$backup" ]]; then
|
||||
reply_error "Couldn't connect to \"$ssid\" - wrong password, or out of range. The previous WiFi setting was put back."
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user