wpa_supplicant: Reuse existing networks and preserve saved ones on connect
Connect() called AddNetwork unconditionally, creating duplicate entries for the same SSID, and SelectNetwork's side-effect of disabling all other networks was being persisted by SaveConfig — making previously saved networks appear erased. Disconnect() also removed the current network from the config. Now reuse an existing network entry when the SSID matches, re-enable other networks after SelectNetwork, and keep entries on disconnect. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
08cbe4f9ff
commit
77370eff19
3 changed files with 102 additions and 23 deletions
|
|
@ -152,35 +152,69 @@ func (b *WPABackend) IsScanning() (bool, error) {
|
|||
|
||||
// Connect connects to a WiFi network
|
||||
func (b *WPABackend) Connect(ssid, password string) error {
|
||||
// Create network configuration
|
||||
config := make(map[string]interface{})
|
||||
config["ssid"] = ssid // Raw SSID string, no quotes
|
||||
|
||||
if password != "" {
|
||||
// For WPA/WPA2-PSK networks
|
||||
config["psk"] = password // Raw password string, no quotes
|
||||
} else {
|
||||
// For open networks
|
||||
config["key_mgmt"] = "NONE"
|
||||
}
|
||||
|
||||
// Add network
|
||||
networkPath, err := b.iface.AddNetwork(config)
|
||||
// Look up existing network with the same SSID to avoid creating duplicates
|
||||
existingNetworks, err := b.iface.GetNetworks()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add network: %v", err)
|
||||
return fmt.Errorf("failed to list configured networks: %v", err)
|
||||
}
|
||||
|
||||
// Store current network path for cleanup
|
||||
var networkPath dbus.ObjectPath
|
||||
createdNew := false
|
||||
|
||||
for _, p := range existingNetworks {
|
||||
net := NewNetwork(b.conn, p)
|
||||
netSSID, err := net.GetSSID()
|
||||
if err != nil || netSSID != ssid {
|
||||
continue
|
||||
}
|
||||
networkPath = p
|
||||
break
|
||||
}
|
||||
|
||||
if networkPath == "" {
|
||||
// Create network configuration
|
||||
config := make(map[string]interface{})
|
||||
config["ssid"] = ssid // Raw SSID string, no quotes
|
||||
|
||||
if password != "" {
|
||||
// For WPA/WPA2-PSK networks
|
||||
config["psk"] = password // Raw password string, no quotes
|
||||
} else {
|
||||
// For open networks
|
||||
config["key_mgmt"] = "NONE"
|
||||
}
|
||||
|
||||
networkPath, err = b.iface.AddNetwork(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add network: %v", err)
|
||||
}
|
||||
createdNew = true
|
||||
}
|
||||
|
||||
// Store current network path
|
||||
b.currentNetwork = networkPath
|
||||
|
||||
// Select (connect to) the network
|
||||
// Select (connect to) the network. Note: SelectNetwork disables every
|
||||
// other configured network as a side-effect.
|
||||
err = b.iface.SelectNetwork(networkPath)
|
||||
if err != nil {
|
||||
// Clean up network on failure
|
||||
b.iface.RemoveNetwork(networkPath)
|
||||
if createdNew {
|
||||
b.iface.RemoveNetwork(networkPath)
|
||||
}
|
||||
return fmt.Errorf("failed to select network: %v", err)
|
||||
}
|
||||
|
||||
// Re-enable previously configured networks so SelectNetwork's side-effect
|
||||
// doesn't mark them all as disabled in the persisted config.
|
||||
for _, p := range existingNetworks {
|
||||
if p == networkPath {
|
||||
continue
|
||||
}
|
||||
if err := b.iface.EnableNetwork(p); err != nil {
|
||||
fmt.Printf("Warning: failed to re-enable network %s: %v\n", p, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Save the configuration to persist it across reboots
|
||||
if err := b.iface.SaveConfig(); err != nil {
|
||||
// Log warning but don't fail - connection still works
|
||||
|
|
@ -197,11 +231,7 @@ func (b *WPABackend) Disconnect() error {
|
|||
return fmt.Errorf("failed to disconnect: %v", err)
|
||||
}
|
||||
|
||||
// Remove the network configuration if we have one
|
||||
if b.currentNetwork != "" && b.currentNetwork != "/" {
|
||||
b.iface.RemoveNetwork(b.currentNetwork)
|
||||
b.currentNetwork = ""
|
||||
}
|
||||
b.currentNetwork = ""
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue