155 lines
4.1 KiB
Go
155 lines
4.1 KiB
Go
package wpasupplicant
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
)
|
|
|
|
// WPAInterface represents a wpa_supplicant Interface object
|
|
type WPAInterface struct {
|
|
path dbus.ObjectPath
|
|
conn *dbus.Conn
|
|
obj dbus.BusObject
|
|
}
|
|
|
|
// NewWPAInterface creates a new WPAInterface instance
|
|
func NewWPAInterface(conn *dbus.Conn, path dbus.ObjectPath) *WPAInterface {
|
|
return &WPAInterface{
|
|
path: path,
|
|
conn: conn,
|
|
obj: conn.Object(Service, path),
|
|
}
|
|
}
|
|
|
|
// Scan triggers a network scan
|
|
func (i *WPAInterface) Scan(scanType string) error {
|
|
args := map[string]interface{}{
|
|
"Type": scanType, // "active" or "passive"
|
|
}
|
|
|
|
err := i.obj.Call(InterfaceInterface+".Scan", 0, args).Err
|
|
if err != nil {
|
|
return fmt.Errorf("scan failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetBSSs returns a list of BSS (Basic Service Set) object paths
|
|
func (i *WPAInterface) GetBSSs() ([]dbus.ObjectPath, error) {
|
|
prop, err := i.obj.GetProperty(InterfaceInterface + ".BSSs")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get BSSs property: %v", err)
|
|
}
|
|
|
|
bsss, ok := prop.Value().([]dbus.ObjectPath)
|
|
if !ok {
|
|
return nil, fmt.Errorf("BSSs property is not an array of ObjectPath")
|
|
}
|
|
|
|
return bsss, nil
|
|
}
|
|
|
|
// GetState returns the current connection state
|
|
func (i *WPAInterface) GetState() (WPAState, error) {
|
|
prop, err := i.obj.GetProperty(InterfaceInterface + ".State")
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get State property: %v", err)
|
|
}
|
|
|
|
state, ok := prop.Value().(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("State property is not a string")
|
|
}
|
|
|
|
return WPAState(state), nil
|
|
}
|
|
|
|
// GetCurrentBSS returns the currently connected BSS object path
|
|
func (i *WPAInterface) GetCurrentBSS() (dbus.ObjectPath, error) {
|
|
prop, err := i.obj.GetProperty(InterfaceInterface + ".CurrentBSS")
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get CurrentBSS property: %v", err)
|
|
}
|
|
|
|
bss, ok := prop.Value().(dbus.ObjectPath)
|
|
if !ok {
|
|
return "", fmt.Errorf("CurrentBSS property is not an ObjectPath")
|
|
}
|
|
|
|
return bss, nil
|
|
}
|
|
|
|
// AddNetwork creates a new network configuration
|
|
func (i *WPAInterface) AddNetwork(config map[string]interface{}) (dbus.ObjectPath, error) {
|
|
var networkPath dbus.ObjectPath
|
|
|
|
// Convert config to proper DBus variant format
|
|
dbusConfig := make(map[string]dbus.Variant)
|
|
for key, value := range config {
|
|
dbusConfig[key] = dbus.MakeVariant(value)
|
|
}
|
|
|
|
err := i.obj.Call(InterfaceInterface+".AddNetwork", 0, dbusConfig).Store(&networkPath)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to add network: %v", err)
|
|
}
|
|
|
|
return networkPath, nil
|
|
}
|
|
|
|
// SelectNetwork connects to a network
|
|
func (i *WPAInterface) SelectNetwork(networkPath dbus.ObjectPath) error {
|
|
err := i.obj.Call(InterfaceInterface+".SelectNetwork", 0, networkPath).Err
|
|
if err != nil {
|
|
return fmt.Errorf("failed to select network: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemoveNetwork removes a network configuration
|
|
func (i *WPAInterface) RemoveNetwork(networkPath dbus.ObjectPath) error {
|
|
err := i.obj.Call(InterfaceInterface+".RemoveNetwork", 0, networkPath).Err
|
|
if err != nil {
|
|
return fmt.Errorf("failed to remove network: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Disconnect disconnects from the current network
|
|
func (i *WPAInterface) Disconnect() error {
|
|
err := i.obj.Call(InterfaceInterface+".Disconnect", 0).Err
|
|
if err != nil {
|
|
return fmt.Errorf("disconnect failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SaveConfig saves the current configuration to the wpa_supplicant config file
|
|
func (i *WPAInterface) SaveConfig() error {
|
|
err := i.obj.Call(InterfaceInterface+".SaveConfig", 0).Err
|
|
if err != nil {
|
|
return fmt.Errorf("save config failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetPath returns the D-Bus object path for this interface
|
|
func (i *WPAInterface) GetPath() dbus.ObjectPath {
|
|
return i.path
|
|
}
|
|
|
|
// GetScanning returns whether a scan is currently in progress
|
|
func (i *WPAInterface) GetScanning() (bool, error) {
|
|
prop, err := i.obj.GetProperty(InterfaceInterface + ".Scanning")
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to get Scanning property: %v", err)
|
|
}
|
|
|
|
scanning, ok := prop.Value().(bool)
|
|
if !ok {
|
|
return false, fmt.Errorf("Scanning property is not a boolean")
|
|
}
|
|
|
|
return scanning, nil
|
|
}
|