wifi: no NetworkManager#37902
Draft
andiradulescu wants to merge 212 commits intocommaai:masterfrom
Draft
Conversation
- Fix CTRL-EVENT-SSID-TEMP-DISABLED event name (not CTRL-EVENT-TEMP-DISABLED) - Use ADD_NETWORK/SET_NETWORK/SELECT_NETWORK instead of RECONFIGURE (RECONFIGURE fails when NM started wpa_supplicant) - Add IP address fallback from wpa_cli STATUS output - Add wifi_cli.py for on-device testing (status, scan, connect, forget, etc) - Fix ruff lint issues (unused imports, string concatenation, line length) - Fix test string construction for ruff ISC002 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Measures scan, connect (to IP), and disconnect for both wpa_supplicant and NetworkManager backends. Each operation is timed to the user-visible outcome, not internal state changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _sanitize_for_conf() to prevent SSID/PSK injection in wpa_supplicant.conf and wpa_cli SET_NETWORK commands (strips ", \n, \r, \) - Fix parse_scan_results to handle hidden networks with empty SSIDs - Fix incorrect test assertion for callback queue length Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pre-populate network list from cached SCAN_RESULTS during init so the UI has data immediately when the panel opens (no "Scanning..." flash) - Poll for IP after DHCP starts so "obtaining IP..." resolves within ~200ms of lease instead of waiting up to 5s for next scan event Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Networks must be loaded before wifi state so that the connected SSID's strength is available on first render. Also read IP on init when already connected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The standard UI panel relied solely on the async callback to populate its network list, causing a "Scanning..." flash every time the panel opened. Read cached networks immediately in show_event, matching what MICI already does. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The _active flag was gating both scan requests AND result processing. When the panel was hidden, scan results were silently dropped, so _networks went stale. On re-entry the UI read empty/stale data while waiting for an async refresh — causing the "Scanning..." flash. Fix: _active now only controls whether new SCAN commands are issued (in the scanner thread). Scan results from wpa_supplicant events are always processed, keeping _networks fresh regardless of panel visibility. Also guard against replacing _networks with empty data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bugs fixed: - dnsmasq launched with subprocess.run (blocks forever) → subprocess.Popen - save_network overwrites metered/hidden fields → merge instead of replace - DhcpClient.stop() flushes IP even when nothing to stop → guard with proc check Code reuse: - Extract _add_and_select_network helper (was duplicated in connect/activate) - _remove_wpa_network reuses _find_network_id instead of duplicating parser - hardware.py uses parse_status/dbm_to_percent/MeteredType from wpa_ctrl/wifi_manager - Remove redundant _tethering_password field (derive from store) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove dead WPA_CTRL_PATH constant - Fix _remove_wpa_network: single LIST_NETWORKS call instead of while-loop that could infinite-loop if REMOVE_NETWORK failed - Fix _monitor_state: use finally block so monitor socket is always closed (was only closed in except branch) - Store dnsmasq Popen in self._dnsmasq_proc and wait on stop to avoid zombie process / ResourceWarning - Validate ADD_NETWORK response in _add_and_select_network - Optimize networks property: snapshot saved SSIDs once via get_all() instead of N lock acquisitions via is_connection_saved() - Prevent overlapping _poll_for_ip threads on rapid reconnects by capturing user_epoch at poll start Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hardware.py imported WIFI_NETWORKS_JSON and MeteredType from wifi_manager.py, which imports swaglog, which imports hardware — causing a circular import at build time. Inline the constant and use integer literals instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use atomic_write from common/utils instead of hand-rolled tmp+replace - Extract _list_network_ids to deduplicate LIST_NETWORKS parsing in _find_network_id and _remove_wpa_network - Hoist NM DBus constants to _GsmManager class level (were redefined as locals in 3 methods) - Don't block monitor thread on SCAN_RESULTS: call _update_networks with block=False so event processing isn't stalled - Remove dead SecurityType.WPA2 and WPA3 enum values (never used) - Move _tethering_active=True to after AP setup succeeds, so DISCONNECTED events aren't suppressed if tethering setup fails Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…so saved networks survive NM/netplan removal
…s share netplan's runtime naming
…dds SAE handshake support
…disconnect on connect setup failure, epoch-guard reconcile, no-op REASSOCIATE on inactive forget
…of loading them as open networks
… as unmetered, mirroring NM's enum
…ING, defer DHCP flush on transient wpa states, epoch-guard connect/activate workers, fire disconnected on activate failure
…runs, refuse AP adoption when our dnsmasq is dead
…saved entry in memory when sudo rm fails
…ned pytest.main entrypoint
…ill stale AP before relaunch, kill unattachable AP and fall through to STA spawn
…mutation race; bail out of forget_connection when NetworkStore.remove fails
…) before persisting
…toconnect=false, mirror content when migration cleanup fails
…slurp profiles that would later be refused, leaving user with no fallback YAML
…from raw.strip().split to splitlines
… runs; raise on ip addr/link failure during tethering bringup
…ld doesn't race lease renewals on wlan0
…reset, nm_persist mirror autoconnect filter
…tore skips WEP profiles (key-mgmt=none + wep-key*) instead of demoting to open
…dified profile so wifi metered survives /etc keyfiles and duplicate-SSID setups
…ve spaces in stored psk, raise on ip_forward failure, pgrep our AP daemon during bringup verify; nm_persist mirrors WEP filter
…boundary-whitespace SSID/PSK saves; LIST_NETWORKS preserves trailing-space SSIDs via splitlines
… -t 5 -T 3 plus -A 20s backoff can outlive it, leaving wlan0 metric-0 to hijack eth0
… Popen can detach (sudo wrapper dies but child survives) and re-add wlan0 IP/route after teardown
… failures already early-return, so an empty list at this point is real and UI must see vanished SSIDs disappear
…ime would associate but NetworkStore silently rejects the persist, so creds vanish after reboot. Fail loudly with disconnected callback instead
… AGNOS NM 1.46 always writes alias form, so canonical [802-11-wireless] would only ever come from imported/older keyfiles we cannot round-trip
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #37752
Continuation of #37662
Draft, opening for feedback
Summary
Replaces NetworkManager's wifi management with a direct wpa_supplicant ctrl-socket client + udhcpc + dnsmasq. Same architecture as #37662:
start_new_session=True; on UI restart_init_wifi_stateadopts the running daemon via ctrl-socket attach instead of respawning._our_wpa_supplicant_runninggates every attach so we never latch onto NM's systemdwpa_supplicant.servicemode=APon init, we take a dedicated AP-adoption branch rather than falling through to STA DHCPnmcli dev set wlan0 managed no, wait for NM's async teardown (~800ms) to delete the shared ctrl socket, then spawn our own wpa_supplicant against/tmp/wpa_supplicant.conf.nmconnectionkeyfiles for rollback + interop, same as bye bye NetworkManager #37662_GsmManagerstill shells out to nmcli. NM stays for cellular for nowDhcpClient._fix_default_route_metricflush-and-re-adds at 600 (NM's wifi default). Required for dual-uplink to work right-s 192.168.43.0/24 ! -d 192.168.43.0/24), not-o <iface>. Mirrors NM'snm-firewall-utils.c. Tethering survives eth unplug, SIM pull,rmnet_data0rename, no watchdogprintf_encode'd SSIDs in STATUS, SCAN_RESULTS, LIST_NETWORKS, and events. Every ingress runs throughdecode_ssid()so non-ASCII networks round-trip andforget_connection/activate_connectiondon't leak runtime IDsArchitecture
GSM (unchanged, NM still owns):
Benchmark
TODO. Will run the same methodology as #37662 (5 iterations each, on device, scan / connect-to-IP / disconnect)