142 lines
3.3 KiB
Go
142 lines
3.3 KiB
Go
package iwd
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
)
|
|
|
|
// Station represents an iwd Station interface
|
|
type Station struct {
|
|
path dbus.ObjectPath
|
|
conn *dbus.Conn
|
|
obj dbus.BusObject
|
|
}
|
|
|
|
// NewStation creates a new Station instance
|
|
func NewStation(conn *dbus.Conn, path dbus.ObjectPath) *Station {
|
|
return &Station{
|
|
path: path,
|
|
conn: conn,
|
|
obj: conn.Object(Service, path),
|
|
}
|
|
}
|
|
|
|
// Scan triggers a network scan
|
|
func (s *Station) Scan() error {
|
|
err := s.obj.Call(StationInterface+".Scan", 0).Err
|
|
if err != nil {
|
|
return fmt.Errorf("scan failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IsScanning checks if a scan is currently in progress
|
|
func (s *Station) IsScanning() (bool, error) {
|
|
prop, err := s.obj.GetProperty(StationInterface + ".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
|
|
}
|
|
|
|
// GetOrderedNetworks returns networks sorted by signal strength
|
|
func (s *Station) GetOrderedNetworks() ([]NetworkInfo, error) {
|
|
var result []struct {
|
|
Path dbus.ObjectPath
|
|
Signal int16
|
|
}
|
|
|
|
err := s.obj.Call(StationInterface+".GetOrderedNetworks", 0).Store(&result)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get ordered networks: %v", err)
|
|
}
|
|
|
|
networks := make([]NetworkInfo, len(result))
|
|
for i, r := range result {
|
|
networks[i] = NetworkInfo{
|
|
Path: r.Path,
|
|
Signal: r.Signal,
|
|
}
|
|
}
|
|
|
|
return networks, nil
|
|
}
|
|
|
|
// GetState returns the current connection state
|
|
func (s *Station) GetState() (StationState, error) {
|
|
prop, err := s.obj.GetProperty(StationInterface + ".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 StationState(state), nil
|
|
}
|
|
|
|
// Disconnect disconnects from the current network
|
|
func (s *Station) Disconnect() error {
|
|
err := s.obj.Call(StationInterface+".Disconnect", 0).Err
|
|
if err != nil {
|
|
return fmt.Errorf("disconnect failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetNetwork finds and returns a Network object by SSID
|
|
func (s *Station) GetNetwork(ssid string) (*Network, error) {
|
|
networks, err := s.GetOrderedNetworks()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Find the network with matching SSID
|
|
for _, netInfo := range networks {
|
|
network := NewNetwork(s.conn, netInfo.Path)
|
|
props, err := network.GetProperties()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
if props.Name == ssid {
|
|
return network, nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("network '%s' not found", ssid)
|
|
}
|
|
|
|
// GetConnectedNetwork returns the currently connected network
|
|
func (s *Station) GetConnectedNetwork() (*Network, error) {
|
|
prop, err := s.obj.GetProperty(StationInterface + ".ConnectedNetwork")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get ConnectedNetwork property: %v", err)
|
|
}
|
|
|
|
path, ok := prop.Value().(dbus.ObjectPath)
|
|
if !ok {
|
|
return nil, fmt.Errorf("ConnectedNetwork property is not an ObjectPath")
|
|
}
|
|
|
|
// Check if path is empty (not connected)
|
|
if path == "/" || path == "" {
|
|
return nil, fmt.Errorf("not connected to any network")
|
|
}
|
|
|
|
return NewNetwork(s.conn, path), nil
|
|
}
|
|
|
|
// GetPath returns the D-Bus object path for this station
|
|
func (s *Station) GetPath() dbus.ObjectPath {
|
|
return s.path
|
|
}
|