@@ -104,6 +104,60 @@ def __init__(self) -> None:
104104 self ._nm_settings = NetworkManagerSettings (self ._bus )
105105 logger .info ("NetworkManagerWifi initialized" )
106106
107+ def _save_interface_mode (self , interface : str , mode : WifiInterfaceMode ) -> None :
108+ """Persist the interface mode to settings."""
109+ interface_modes = getattr (self ._settings_manager .settings , "interface_modes" , {}) or {}
110+ interface_modes [interface ] = mode .value
111+ self ._settings_manager .settings .interface_modes = interface_modes
112+ self ._settings_manager .save ()
113+ logger .info (f"Saved { interface } mode: { mode .value } " )
114+
115+ def _get_stored_interface_mode (self , interface : str ) -> Optional [WifiInterfaceMode ]:
116+ """Get the stored mode for an interface from settings, or None if not set."""
117+ interface_modes = getattr (self ._settings_manager .settings , "interface_modes" , {}) or {}
118+ mode_str = interface_modes .get (interface )
119+ if mode_str :
120+ try :
121+ return WifiInterfaceMode (mode_str )
122+ except ValueError :
123+ logger .warning (f"Invalid stored mode '{ mode_str } ' for { interface } " )
124+ return None
125+
126+ async def get_default_mode_for_interface (self , interface : str ) -> WifiInterfaceMode :
127+ """Get the default mode for an interface based on stored setting or capabilities."""
128+ caps = await self .get_interface_capabilities (interface )
129+
130+ # First check if user has explicitly set a mode
131+ stored_mode = self ._get_stored_interface_mode (interface )
132+ if stored_mode is not None :
133+ # Verify the stored mode is still supported by this hardware
134+ if stored_mode in caps .available_modes :
135+ return stored_mode
136+ logger .warning (f"Stored mode { stored_mode } no longer supported on { interface } , using default" )
137+
138+ # No stored preference or stored mode not supported - determine based on capabilities
139+ if caps .supports_dual_mode :
140+ return WifiInterfaceMode .DUAL
141+ return WifiInterfaceMode .NORMAL
142+
143+ async def restore_interface_modes (self ) -> None :
144+ """Restore interface modes from settings on startup."""
145+ for interface in list (self ._device_paths .keys ()):
146+ try :
147+ default_mode = await self .get_default_mode_for_interface (interface )
148+ current_mode = self ._interface_modes .get (interface , WifiInterfaceMode .NORMAL )
149+ if default_mode != current_mode :
150+ logger .info (f"Restoring { interface } to { default_mode } mode" )
151+ success = await self .set_interface_mode (interface , default_mode )
152+ if not success :
153+ logger .warning (f"Failed to restore { interface } to { default_mode } mode, defaulting to NORMAL" )
154+ self ._interface_modes [interface ] = WifiInterfaceMode .NORMAL
155+ else :
156+ self ._interface_modes [interface ] = default_mode
157+ except Exception as e :
158+ logger .error (f"Error restoring mode for { interface } : { e } " )
159+ self ._interface_modes [interface ] = WifiInterfaceMode .NORMAL
160+
107161 async def _set_interface_managed (self , interface : str , managed : bool ) -> None :
108162 """Set the NetworkManager 'Managed' property for an interface via D-Bus."""
109163 device_path = self ._device_paths .get (interface )
@@ -259,6 +313,10 @@ async def start(self) -> None:
259313
260314 # Create virtual AP interface if needed
261315 await self ._create_virtual_interface ()
316+
317+ # Restore interface modes from settings
318+ await self .restore_interface_modes ()
319+
262320 self ._tasks .append (asyncio .get_event_loop ().create_task (self ._autoscan ()))
263321 self ._tasks .append (asyncio .get_event_loop ().create_task (self .hotspot_watchdog ()))
264322
@@ -1102,6 +1160,7 @@ async def set_interface_mode(self, interface: str, mode: WifiInterfaceMode) -> b
11021160 if mode == WifiInterfaceMode .NORMAL :
11031161 # Just disable hotspot (already done above), interface returns to normal
11041162 self ._interface_modes [interface ] = mode
1163+ self ._save_interface_mode (interface , mode )
11051164 return True
11061165
11071166 if mode == WifiInterfaceMode .HOTSPOT :
@@ -1114,13 +1173,15 @@ async def set_interface_mode(self, interface: str, mode: WifiInterfaceMode) -> b
11141173 success = await self ._enable_hotspot_direct (interface )
11151174 if success :
11161175 self ._interface_modes [interface ] = mode
1176+ self ._save_interface_mode (interface , mode )
11171177 return success
11181178
11191179 # mode == WifiInterfaceMode.DUAL
11201180 # Enable hotspot using virtual interface (existing behavior)
11211181 success = await self .enable_hotspot_on_interface (interface , save_settings = True )
11221182 if success :
11231183 self ._interface_modes [interface ] = mode
1184+ self ._save_interface_mode (interface , mode )
11241185 return success
11251186
11261187 async def _enable_hotspot_direct (self , interface : str , save_settings : bool = True ) -> bool :
0 commit comments