add state management

pull/36039/head
Shane Smiskol 5 days ago
parent 3b7b2045bc
commit fdc2e0b8f5
  1. 2
      system/ui/lib/networkmanager.py
  2. 72
      system/ui/lib/wifi_manager_v2.py

@ -6,8 +6,8 @@ class NMDeviceState(IntEnum):
UNKNOWN = 0
DISCONNECTED = 30
PREPARE = 40
NEED_AUTH = 60
STATE_CONFIG = 50
NEED_AUTH = 60
IP_CONFIG = 70
ACTIVATED = 100

@ -1,3 +1,4 @@
import atexit
import copy
import dbus
import threading
@ -111,6 +112,11 @@ class WifiManager:
self._nm = dbus.Interface(self._bus.get_object(NM, NM_PATH), NM_IFACE)
self._props = dbus.Interface(self._bus.get_object(NM, NM_PATH), NM_PROPERTIES_IFACE)
self._bus2 = dbus.SystemBus(private=True)
# State
self._connecting_to_ssid: str = ""
# Callbacks
# TODO: some of these are called from threads, either:
# 1. make sure this is fine
@ -124,6 +130,60 @@ class WifiManager:
self._thread = threading.Thread(target=self._run, daemon=True)
self._thread.start()
self._state_thread = threading.Thread(target=self._monitor_state, daemon=True)
self._state_thread.start()
atexit.register(self.stop)
def __del__(self):
self.stop()
def stop(self):
self._running = False
self._thread.join()
self._state_thread.join()
self._bus.close()
self._bus2.close()
def _monitor_state(self):
prev_state = -1
device_path = self._get_wifi_device()
props_dev = dbus.Interface(self._bus2.get_object(NM, device_path), NM_PROPERTIES_IFACE)
_props = dbus.Interface(self._bus2.get_object(NM, NM_PATH), NM_PROPERTIES_IFACE)
while self._running:
if self._active:
dev_state = int(props_dev.Get(NM_DEVICE_IFACE, "State"))
state_reason = props_dev.Get(NM_DEVICE_IFACE, "StateReason") # (u state, u reason)
reason = int(state_reason[1]) if isinstance(state_reason, (list, tuple)) and len(state_reason) == 2 else 0
if dev_state != prev_state:
print(f" WiFi device state change: {dev_state}, reason: {reason}")
if dev_state == NMDeviceState.NEED_AUTH and reason == NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT and self._connecting_to_ssid:
print('------ NEED AUTH - SUPPLICANT DISCONNECT')
self.forget_connection(self._connecting_to_ssid, block=True)
if self._need_auth is not None:
self._need_auth(self._connecting_to_ssid)
self._connecting_to_ssid = ""
elif dev_state == NMDeviceState.ACTIVATED:
print('------ ACTIVATED')
if self._activated is not None:
self._activated()
self._connecting_to_ssid = ""
elif dev_state == NMDeviceState.DISCONNECTED:
print('------ DISCONNECTED')
self._connecting_to_ssid = ""
print()
if self._connecting_to_ssid:
print(' CONNECTING', self._connecting_to_ssid)
prev_state = dev_state
time.sleep(1 / 2.)
def set_callbacks(self, need_auth: Callable[[str], None],
activated: Callable[[], None] | None,
forgotten: Callable[[str], None],
@ -135,20 +195,12 @@ class WifiManager:
self._networks_updated = networks_updated
self._connection_failed = connection_failed
def __del__(self):
self.stop()
def stop(self):
self._running = False
self._thread.join()
self._bus.close()
def _run(self):
while self._running:
if self._active:
self._update_networks()
time.sleep(1)
time.sleep(3)
def set_active(self, active: bool):
self._active = active
@ -176,6 +228,7 @@ class WifiManager:
t = time.monotonic()
# Clear all connections that may already exist to the network we are connecting
self._connecting_to_ssid = ssid
self.forget_connection(ssid, block=True)
is_hidden = False
@ -255,6 +308,7 @@ class WifiManager:
t = time.monotonic()
conn_path = self._connection_by_ssid(ssid)
if conn_path is not None:
self._connecting_to_ssid = ssid
device_path = self._get_wifi_device()
if device_path is None:
cloudlog.warning("No WiFi device found")

Loading…
Cancel
Save