Improve Wi-Fi recovery and reconnect handling

This commit is contained in:
2026-04-25 15:00:45 -04:00
parent 18cc9b6bab
commit 94952c7136
4 changed files with 99 additions and 12 deletions

View File

@@ -13,7 +13,10 @@ from .windows import (
ensure_hardware_mac,
get_wifi_status,
randomize_mac,
request_wifi_scan,
restart_adapter,
set_interface_enabled,
set_wlan_autoconfig,
test_connectivity,
wait_for_ssid,
)
@@ -149,9 +152,24 @@ class WifiBackgroundService:
self.state.last_mac_refresh_monotonic = time.monotonic()
self.logger.info("Randomized MAC to %s", mac_address)
disconnect_wifi(interface_name)
restart_adapter(interface_name)
self._prepare_interface_for_connect(interface_name)
try:
disconnect_wifi(interface_name)
except WifiCommandError as exc:
self.logger.warning("Wi-Fi disconnect before recovery failed, continuing: %s", exc)
try:
self.logger.info("Restarting Wi-Fi adapter %s", interface_name)
restart_adapter(interface_name)
except WifiCommandError as exc:
self.logger.warning(
"Adapter restart failed, continuing with direct reconnect attempt: %s",
exc,
)
time.sleep(self.config.monitor.reconnect_wait_seconds)
self.logger.info("Reconnecting to %s after recovery actions", network.ssid)
connect_wifi(
network.profile_name,
interface_name,
@@ -166,7 +184,9 @@ class WifiBackgroundService:
self.state.last_recovery_monotonic = time.monotonic()
if not status.is_connected or status.ssid != network.ssid:
raise WifiCommandError(f"Failed to reconnect to {network.ssid}")
raise WifiCommandError(
f"Failed to reconnect to {network.ssid}; final status: {self._format_status(status)}",
)
self.logger.info("Reconnected to %s on interface %s", status.ssid, interface_name)
@@ -186,13 +206,14 @@ class WifiBackgroundService:
network.ssid,
interface_name,
)
self.state.last_connect_attempt_monotonic = time.monotonic()
self._prepare_interface_for_connect(interface_name)
connect_wifi(
network.profile_name,
interface_name,
ssid=network.ssid,
auto_create_open_profile=network.auto_create_open_profile,
)
self.state.last_connect_attempt_monotonic = time.monotonic()
new_status = wait_for_ssid(
network.ssid,
@@ -200,7 +221,11 @@ class WifiBackgroundService:
interface_name,
)
if not new_status.is_connected or new_status.ssid != network.ssid:
self.logger.warning("Direct Wi-Fi connection to %s did not succeed", network.ssid)
self.logger.warning(
"Direct Wi-Fi connection to %s did not succeed; final status: %s",
network.ssid,
self._format_status(new_status),
)
return False
self.logger.info("Connected to %s without adapter reset", network.ssid)
@@ -249,3 +274,18 @@ class WifiBackgroundService:
return (
now - self.state.last_connect_attempt_monotonic
) >= self.config.monitor.connect_retry_cooldown_seconds
def _prepare_interface_for_connect(self, interface_name: str) -> None:
for action_name, action in (
("enable interface", lambda: set_interface_enabled(interface_name, True)),
("enable WLAN autoconfig", lambda: set_wlan_autoconfig(interface_name, True)),
("scan Wi-Fi networks", lambda: request_wifi_scan(interface_name)),
):
try:
action()
except WifiCommandError as exc:
self.logger.warning("Could not %s for %s: %s", action_name, interface_name, exc)
@staticmethod
def _format_status(status) -> str:
return f"interface={status.interface_name} state={status.state} ssid={status.ssid}"