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 }