mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-13 00:42:49 -05:00
switch hto monorepo structure
This commit is contained in:
662
backend/internal/server/network/backend_iwd_wifi.go
Normal file
662
backend/internal/server/network/backend_iwd_wifi.go
Normal file
@@ -0,0 +1,662 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/backend/internal/errdefs"
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
func (b *IWDBackend) updateState() error {
|
||||
if b.devicePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
obj := b.conn.Object(iwdBusName, b.devicePath)
|
||||
|
||||
poweredVar, err := obj.GetProperty(iwdDeviceInterface + ".Powered")
|
||||
if err == nil {
|
||||
if powered, ok := poweredVar.Value().(bool); ok {
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiEnabled = powered
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
if b.stationPath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
stationObj := b.conn.Object(iwdBusName, b.stationPath)
|
||||
|
||||
stateVar, err := stationObj.GetProperty(iwdStationInterface + ".State")
|
||||
if err == nil {
|
||||
if state, ok := stateVar.Value().(string); ok {
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiConnected = (state == "connected")
|
||||
if state == "connected" {
|
||||
b.state.NetworkStatus = StatusWiFi
|
||||
} else {
|
||||
b.state.NetworkStatus = StatusDisconnected
|
||||
}
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
connNetVar, err := stationObj.GetProperty(iwdStationInterface + ".ConnectedNetwork")
|
||||
if err == nil && connNetVar.Value() != nil {
|
||||
if netPath, ok := connNetVar.Value().(dbus.ObjectPath); ok && netPath != "/" {
|
||||
netObj := b.conn.Object(iwdBusName, netPath)
|
||||
|
||||
nameVar, err := netObj.GetProperty(iwdNetworkInterface + ".Name")
|
||||
if err == nil {
|
||||
if name, ok := nameVar.Value().(string); ok {
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiSSID = name
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
var orderedNetworks [][]dbus.Variant
|
||||
err = stationObj.Call(iwdStationInterface+".GetOrderedNetworks", 0).Store(&orderedNetworks)
|
||||
if err == nil {
|
||||
for _, netData := range orderedNetworks {
|
||||
if len(netData) < 2 {
|
||||
continue
|
||||
}
|
||||
currentNetPath, ok := netData[0].Value().(dbus.ObjectPath)
|
||||
if !ok || currentNetPath != netPath {
|
||||
continue
|
||||
}
|
||||
signalStrength, ok := netData[1].Value().(int16)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
signalDbm := signalStrength / 100
|
||||
signal := uint8(signalDbm + 100)
|
||||
if signalDbm > 0 {
|
||||
signal = 100
|
||||
} else if signalDbm < -100 {
|
||||
signal = 0
|
||||
}
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiSignal = signal
|
||||
b.stateMutex.Unlock()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
networks, err := b.updateWiFiNetworks()
|
||||
if err == nil {
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiNetworks = networks
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) GetWiFiEnabled() (bool, error) {
|
||||
b.stateMutex.RLock()
|
||||
defer b.stateMutex.RUnlock()
|
||||
return b.state.WiFiEnabled, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) SetWiFiEnabled(enabled bool) error {
|
||||
if b.devicePath == "" {
|
||||
return fmt.Errorf("no WiFi device available")
|
||||
}
|
||||
|
||||
obj := b.conn.Object(iwdBusName, b.devicePath)
|
||||
call := obj.Call(dbusPropertiesInterface+".Set", 0, iwdDeviceInterface, "Powered", dbus.MakeVariant(enabled))
|
||||
if call.Err != nil {
|
||||
return fmt.Errorf("failed to set WiFi enabled: %w", call.Err)
|
||||
}
|
||||
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiEnabled = enabled
|
||||
b.stateMutex.Unlock()
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) ScanWiFi() error {
|
||||
if b.stationPath == "" {
|
||||
return fmt.Errorf("no WiFi device available")
|
||||
}
|
||||
|
||||
obj := b.conn.Object(iwdBusName, b.stationPath)
|
||||
|
||||
scanningVar, err := obj.GetProperty(iwdStationInterface + ".Scanning")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check scanning state: %w", err)
|
||||
}
|
||||
|
||||
if scanning, ok := scanningVar.Value().(bool); ok && scanning {
|
||||
return fmt.Errorf("scan already in progress")
|
||||
}
|
||||
|
||||
call := obj.Call(iwdStationInterface+".Scan", 0)
|
||||
if call.Err != nil {
|
||||
return fmt.Errorf("scan request failed: %w", call.Err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) updateWiFiNetworks() ([]WiFiNetwork, error) {
|
||||
if b.stationPath == "" {
|
||||
return nil, fmt.Errorf("no WiFi device available")
|
||||
}
|
||||
|
||||
obj := b.conn.Object(iwdBusName, b.stationPath)
|
||||
|
||||
var orderedNetworks [][]dbus.Variant
|
||||
err := obj.Call(iwdStationInterface+".GetOrderedNetworks", 0).Store(&orderedNetworks)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get networks: %w", err)
|
||||
}
|
||||
|
||||
knownNetworks, err := b.getKnownNetworks()
|
||||
if err != nil {
|
||||
knownNetworks = make(map[string]bool)
|
||||
}
|
||||
|
||||
autoconnectMap, err := b.getAutoconnectSettings()
|
||||
if err != nil {
|
||||
autoconnectMap = make(map[string]bool)
|
||||
}
|
||||
|
||||
b.stateMutex.RLock()
|
||||
currentSSID := b.state.WiFiSSID
|
||||
wifiConnected := b.state.WiFiConnected
|
||||
b.stateMutex.RUnlock()
|
||||
|
||||
networks := make([]WiFiNetwork, 0, len(orderedNetworks))
|
||||
for _, netData := range orderedNetworks {
|
||||
if len(netData) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
networkPath, ok := netData[0].Value().(dbus.ObjectPath)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
signalStrength, ok := netData[1].Value().(int16)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
netObj := b.conn.Object(iwdBusName, networkPath)
|
||||
|
||||
nameVar, err := netObj.GetProperty(iwdNetworkInterface + ".Name")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
name, ok := nameVar.Value().(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
typeVar, err := netObj.GetProperty(iwdNetworkInterface + ".Type")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
netType, ok := typeVar.Value().(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
signalDbm := signalStrength / 100
|
||||
signal := uint8(signalDbm + 100)
|
||||
if signalDbm > 0 {
|
||||
signal = 100
|
||||
} else if signalDbm < -100 {
|
||||
signal = 0
|
||||
}
|
||||
|
||||
secured := netType != "open"
|
||||
|
||||
network := WiFiNetwork{
|
||||
SSID: name,
|
||||
Signal: signal,
|
||||
Secured: secured,
|
||||
Connected: wifiConnected && name == currentSSID,
|
||||
Saved: knownNetworks[name],
|
||||
Autoconnect: autoconnectMap[name],
|
||||
Enterprise: netType == "8021x",
|
||||
}
|
||||
|
||||
networks = append(networks, network)
|
||||
}
|
||||
|
||||
sortWiFiNetworks(networks)
|
||||
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiNetworks = networks
|
||||
b.stateMutex.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
b.recentScansMu.Lock()
|
||||
for _, net := range networks {
|
||||
b.recentScans[net.SSID] = now
|
||||
}
|
||||
b.recentScansMu.Unlock()
|
||||
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) getKnownNetworks() (map[string]bool, error) {
|
||||
obj := b.conn.Object(iwdBusName, iwdObjectPath)
|
||||
|
||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||
err := obj.Call(dbusObjectManager+".GetManagedObjects", 0).Store(&objects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
known := make(map[string]bool)
|
||||
for _, interfaces := range objects {
|
||||
if knownProps, ok := interfaces[iwdKnownNetworkInterface]; ok {
|
||||
if nameVar, ok := knownProps["Name"]; ok {
|
||||
if name, ok := nameVar.Value().(string); ok {
|
||||
known[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return known, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) getAutoconnectSettings() (map[string]bool, error) {
|
||||
obj := b.conn.Object(iwdBusName, iwdObjectPath)
|
||||
|
||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||
err := obj.Call(dbusObjectManager+".GetManagedObjects", 0).Store(&objects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
autoconnectMap := make(map[string]bool)
|
||||
for _, interfaces := range objects {
|
||||
if knownProps, ok := interfaces[iwdKnownNetworkInterface]; ok {
|
||||
if nameVar, ok := knownProps["Name"]; ok {
|
||||
if name, ok := nameVar.Value().(string); ok {
|
||||
autoconnect := true
|
||||
if acVar, ok := knownProps["AutoConnect"]; ok {
|
||||
if ac, ok := acVar.Value().(bool); ok {
|
||||
autoconnect = ac
|
||||
}
|
||||
}
|
||||
autoconnectMap[name] = autoconnect
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return autoconnectMap, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) GetWiFiNetworkDetails(ssid string) (*NetworkInfoResponse, error) {
|
||||
b.stateMutex.RLock()
|
||||
networks := b.state.WiFiNetworks
|
||||
b.stateMutex.RUnlock()
|
||||
|
||||
var found *WiFiNetwork
|
||||
for i := range networks {
|
||||
if networks[i].SSID == ssid {
|
||||
found = &networks[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("network not found: %s", ssid)
|
||||
}
|
||||
|
||||
return &NetworkInfoResponse{
|
||||
SSID: ssid,
|
||||
Bands: []WiFiNetwork{*found},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) setConnectError(code string) {
|
||||
b.stateMutex.Lock()
|
||||
b.state.IsConnecting = false
|
||||
b.state.ConnectingSSID = ""
|
||||
b.state.LastError = code
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
|
||||
func (b *IWDBackend) seenInRecentScan(ssid string) bool {
|
||||
b.recentScansMu.Lock()
|
||||
defer b.recentScansMu.Unlock()
|
||||
lastSeen, ok := b.recentScans[ssid]
|
||||
return ok && time.Since(lastSeen) < 30*time.Second
|
||||
}
|
||||
|
||||
func (b *IWDBackend) classifyAttempt(att *connectAttempt) string {
|
||||
att.mu.Lock()
|
||||
defer att.mu.Unlock()
|
||||
|
||||
if att.sawPromptRetry {
|
||||
return errdefs.ErrBadCredentials
|
||||
}
|
||||
|
||||
if !att.connectedAt.IsZero() && !att.sawIPConfig {
|
||||
connDuration := time.Since(att.connectedAt)
|
||||
if connDuration > 500*time.Millisecond && connDuration < 3*time.Second {
|
||||
return errdefs.ErrBadCredentials
|
||||
}
|
||||
}
|
||||
|
||||
if (att.sawAuthish || !att.connectedAt.IsZero()) && !att.sawIPConfig {
|
||||
if time.Since(att.start) > 12*time.Second {
|
||||
return errdefs.ErrDhcpTimeout
|
||||
}
|
||||
}
|
||||
|
||||
if !att.sawAuthish && att.connectedAt.IsZero() {
|
||||
if !b.seenInRecentScan(att.ssid) {
|
||||
return errdefs.ErrNoSuchSSID
|
||||
}
|
||||
return errdefs.ErrAssocTimeout
|
||||
}
|
||||
|
||||
return errdefs.ErrAssocTimeout
|
||||
}
|
||||
|
||||
func (b *IWDBackend) finalizeAttempt(att *connectAttempt, code string) {
|
||||
att.mu.Lock()
|
||||
if att.finalized {
|
||||
att.mu.Unlock()
|
||||
return
|
||||
}
|
||||
att.finalized = true
|
||||
att.mu.Unlock()
|
||||
|
||||
b.stateMutex.Lock()
|
||||
b.state.IsConnecting = false
|
||||
b.state.ConnectingSSID = ""
|
||||
b.state.LastError = code
|
||||
b.stateMutex.Unlock()
|
||||
|
||||
b.updateState()
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) startAttemptWatchdog(att *connectAttempt) {
|
||||
b.sigWG.Add(1)
|
||||
go func() {
|
||||
defer b.sigWG.Done()
|
||||
|
||||
ticker := time.NewTicker(250 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
att.mu.Lock()
|
||||
finalized := att.finalized
|
||||
att.mu.Unlock()
|
||||
|
||||
if finalized || time.Now().After(att.deadline) {
|
||||
if !finalized {
|
||||
b.finalizeAttempt(att, b.classifyAttempt(att))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
station := b.conn.Object(iwdBusName, b.stationPath)
|
||||
stVar, err := station.GetProperty(iwdStationInterface + ".State")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
state, _ := stVar.Value().(string)
|
||||
|
||||
cnVar, err := station.GetProperty(iwdStationInterface + ".ConnectedNetwork")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var connPath dbus.ObjectPath
|
||||
if cnVar.Value() != nil {
|
||||
connPath, _ = cnVar.Value().(dbus.ObjectPath)
|
||||
}
|
||||
|
||||
att.mu.Lock()
|
||||
if connPath == att.netPath && state == "connected" && att.connectedAt.IsZero() {
|
||||
att.connectedAt = time.Now()
|
||||
}
|
||||
if state == "configuring" {
|
||||
att.sawIPConfig = true
|
||||
}
|
||||
att.mu.Unlock()
|
||||
|
||||
case <-b.stopChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (b *IWDBackend) mapIwdDBusError(name string) string {
|
||||
switch name {
|
||||
case "net.connman.iwd.Error.AlreadyConnected":
|
||||
return errdefs.ErrAlreadyConnected
|
||||
case "net.connman.iwd.Error.AuthenticationFailed",
|
||||
"net.connman.iwd.Error.InvalidKey",
|
||||
"net.connman.iwd.Error.IncorrectPassphrase":
|
||||
return errdefs.ErrBadCredentials
|
||||
case "net.connman.iwd.Error.NotFound":
|
||||
return errdefs.ErrNoSuchSSID
|
||||
case "net.connman.iwd.Error.NotSupported":
|
||||
return errdefs.ErrConnectionFailed
|
||||
case "net.connman.iwd.Agent.Error.Canceled":
|
||||
return errdefs.ErrUserCanceled
|
||||
default:
|
||||
return errdefs.ErrConnectionFailed
|
||||
}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) ConnectWiFi(req ConnectionRequest) error {
|
||||
if b.stationPath == "" {
|
||||
b.setConnectError(errdefs.ErrWifiDisabled)
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
return fmt.Errorf("no WiFi device available")
|
||||
}
|
||||
|
||||
networkPath, err := b.findNetworkPath(req.SSID)
|
||||
if err != nil {
|
||||
b.setConnectError(errdefs.ErrNoSuchSSID)
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
return fmt.Errorf("network not found: %w", err)
|
||||
}
|
||||
|
||||
att := &connectAttempt{
|
||||
ssid: req.SSID,
|
||||
netPath: networkPath,
|
||||
start: time.Now(),
|
||||
deadline: time.Now().Add(15 * time.Second),
|
||||
}
|
||||
|
||||
b.attemptMutex.Lock()
|
||||
b.curAttempt = att
|
||||
b.attemptMutex.Unlock()
|
||||
|
||||
b.stateMutex.Lock()
|
||||
b.state.IsConnecting = true
|
||||
b.state.ConnectingSSID = req.SSID
|
||||
b.state.LastError = ""
|
||||
b.stateMutex.Unlock()
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
|
||||
netObj := b.conn.Object(iwdBusName, networkPath)
|
||||
go func() {
|
||||
call := netObj.Call(iwdNetworkInterface+".Connect", 0)
|
||||
if call.Err != nil {
|
||||
var code string
|
||||
if dbusErr, ok := call.Err.(dbus.Error); ok {
|
||||
code = b.mapIwdDBusError(dbusErr.Name)
|
||||
} else if dbusErrPtr, ok := call.Err.(*dbus.Error); ok {
|
||||
code = b.mapIwdDBusError(dbusErrPtr.Name)
|
||||
} else {
|
||||
code = errdefs.ErrConnectionFailed
|
||||
}
|
||||
|
||||
att.mu.Lock()
|
||||
if att.sawPromptRetry {
|
||||
code = errdefs.ErrBadCredentials
|
||||
}
|
||||
att.mu.Unlock()
|
||||
|
||||
b.finalizeAttempt(att, code)
|
||||
return
|
||||
}
|
||||
|
||||
b.startAttemptWatchdog(att)
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) findNetworkPath(ssid string) (dbus.ObjectPath, error) {
|
||||
obj := b.conn.Object(iwdBusName, iwdObjectPath)
|
||||
|
||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||
err := obj.Call(dbusObjectManager+".GetManagedObjects", 0).Store(&objects)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for path, interfaces := range objects {
|
||||
if netProps, ok := interfaces[iwdNetworkInterface]; ok {
|
||||
if nameVar, ok := netProps["Name"]; ok {
|
||||
if name, ok := nameVar.Value().(string); ok && name == ssid {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("network not found")
|
||||
}
|
||||
|
||||
func (b *IWDBackend) DisconnectWiFi() error {
|
||||
if b.stationPath == "" {
|
||||
return fmt.Errorf("no WiFi device available")
|
||||
}
|
||||
|
||||
obj := b.conn.Object(iwdBusName, b.stationPath)
|
||||
call := obj.Call(iwdStationInterface+".Disconnect", 0)
|
||||
if call.Err != nil {
|
||||
return fmt.Errorf("failed to disconnect: %w", call.Err)
|
||||
}
|
||||
|
||||
b.updateState()
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) ForgetWiFiNetwork(ssid string) error {
|
||||
b.stateMutex.RLock()
|
||||
currentSSID := b.state.WiFiSSID
|
||||
isConnected := b.state.WiFiConnected
|
||||
b.stateMutex.RUnlock()
|
||||
|
||||
obj := b.conn.Object(iwdBusName, iwdObjectPath)
|
||||
|
||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||
err := obj.Call(dbusObjectManager+".GetManagedObjects", 0).Store(&objects)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for path, interfaces := range objects {
|
||||
if knownProps, ok := interfaces[iwdKnownNetworkInterface]; ok {
|
||||
if nameVar, ok := knownProps["Name"]; ok {
|
||||
if name, ok := nameVar.Value().(string); ok && name == ssid {
|
||||
knownObj := b.conn.Object(iwdBusName, path)
|
||||
call := knownObj.Call(iwdKnownNetworkInterface+".Forget", 0)
|
||||
if call.Err != nil {
|
||||
return fmt.Errorf("failed to forget network: %w", call.Err)
|
||||
}
|
||||
|
||||
if isConnected && currentSSID == ssid {
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiConnected = false
|
||||
b.state.WiFiSSID = ""
|
||||
b.state.WiFiSignal = 0
|
||||
b.state.WiFiIP = ""
|
||||
b.state.NetworkStatus = StatusDisconnected
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("network not found")
|
||||
}
|
||||
|
||||
func (b *IWDBackend) SetWiFiAutoconnect(ssid string, autoconnect bool) error {
|
||||
obj := b.conn.Object(iwdBusName, iwdObjectPath)
|
||||
|
||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||
err := obj.Call(dbusObjectManager+".GetManagedObjects", 0).Store(&objects)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for path, interfaces := range objects {
|
||||
if knownProps, ok := interfaces[iwdKnownNetworkInterface]; ok {
|
||||
if nameVar, ok := knownProps["Name"]; ok {
|
||||
if name, ok := nameVar.Value().(string); ok && name == ssid {
|
||||
knownObj := b.conn.Object(iwdBusName, path)
|
||||
call := knownObj.Call(dbusPropertiesInterface+".Set", 0, iwdKnownNetworkInterface, "AutoConnect", dbus.MakeVariant(autoconnect))
|
||||
if call.Err != nil {
|
||||
return fmt.Errorf("failed to set autoconnect: %w", call.Err)
|
||||
}
|
||||
|
||||
b.updateState()
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("network not found")
|
||||
}
|
||||
Reference in New Issue
Block a user