Improve Wi-Fi recovery and reconnect handling
This commit is contained in:
@@ -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}"
|
||||
|
||||
Reference in New Issue
Block a user