From 5852676635c8b8f541cd9218c5ce68f48b973876 Mon Sep 17 00:00:00 2001 From: Peter Hommel Date: Fri, 3 May 2019 13:47:35 +0200 Subject: [PATCH 1/7] added AddAndActivateConnection method to NetworkManager --- NetworkManager.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NetworkManager.go b/NetworkManager.go index 6457671..9a2fa53 100644 --- a/NetworkManager.go +++ b/NetworkManager.go @@ -12,6 +12,7 @@ const ( NetworkManagerGetDevices = NetworkManagerInterface + ".GetDevices" NetworkManagerActivateConnection = NetworkManagerInterface + ".ActivateConnection" + NetworkManagerAddAndActivateConnection = NetworkManagerInterface + ".AddAndActivateConnection" NetworkManagerPropertyState = NetworkManagerInterface + ".State" NetworkManagerPropertyActiveConnection = NetworkManagerInterface + ".ActiveConnections" ) @@ -32,6 +33,8 @@ type NetworkManager interface { // ActivateWirelessConnection requests activating access point to network device ActivateWirelessConnection(connection Connection, device Device, accessPoint AccessPoint) ActiveConnection + AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device Device, accessPoint AccessPoint) ActiveConnection + Subscribe() <-chan *dbus.Signal Unsubscribe() @@ -91,6 +94,12 @@ func (n *networkManager) ActivateWirelessConnection(c Connection, d Device, ap A return nil } +func (n *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) ActiveConnection { + var opath dbus.ObjectPath + n.call(&opath, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) + return nil +} + func (n *networkManager) Subscribe() <-chan *dbus.Signal { if n.sigChan != nil { return n.sigChan From 1a95214556f9340b2a740d628d81e5403f4886f2 Mon Sep 17 00:00:00 2001 From: Peter Hommel Date: Thu, 9 May 2019 10:41:57 +0200 Subject: [PATCH 2/7] Added utils method for dbus calls with two return values --- utils.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils.go b/utils.go index 785a86a..b6f73da 100644 --- a/utils.go +++ b/utils.go @@ -41,6 +41,10 @@ func (d *dbusBase) callError(value interface{}, method string, args ...interface return d.obj.Call(method, 0, args...).Store(value) } +func (d *dbusBase) callError2(value1 interface{}, value2 interface{}, method string, args ...interface{}) error { + return d.obj.Call(method, 0, args...).Store(value1, value2) +} + func (d *dbusBase) subscribe(iface, member string) { rule := fmt.Sprintf("type='signal',interface='%s',path='%s',member='%s'", iface, d.obj.Path(), NetworkManagerInterface) From f42ba34c0a7a3eb238f6da94a9ba9cad0bcefb9b Mon Sep 17 00:00:00 2001 From: Peter Hommel Date: Thu, 9 May 2019 10:42:29 +0200 Subject: [PATCH 3/7] AddAndActivateWirelessConnection: documentation, error handling and return value --- NetworkManager.go | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/NetworkManager.go b/NetworkManager.go index 9a2fa53..4dd4ff3 100644 --- a/NetworkManager.go +++ b/NetworkManager.go @@ -2,6 +2,8 @@ package gonetworkmanager import ( "encoding/json" + "errors" + "fmt" "github.com/godbus/dbus" ) @@ -33,7 +35,17 @@ type NetworkManager interface { // ActivateWirelessConnection requests activating access point to network device ActivateWirelessConnection(connection Connection, device Device, accessPoint AccessPoint) ActiveConnection - AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device Device, accessPoint AccessPoint) ActiveConnection + // AddAndActivateWirelessConnection adds a new connection profile to the network device it has been + // passed. It then activates the connection to the passed access point. The first paramter contains + // additional information for the connection (most propably the credentials). + // Example contents for connection are: + // connection := make(map[string]map[string]interface{}) + // connection["802-11-wireless"] = make(map[string]interface{}) + // connection["802-11-wireless"]["security"] = "802-11-wireless-security" + // connection["802-11-wireless-security"] = make(map[string]interface{}) + // connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk" + // connection["802-11-wireless-security"]["psk"] = password + AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device Device, accessPoint AccessPoint) (ac ActiveConnection, err error) Subscribe() <-chan *dbus.Signal Unsubscribe() @@ -94,10 +106,25 @@ func (n *networkManager) ActivateWirelessConnection(c Connection, d Device, ap A return nil } -func (n *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) ActiveConnection { - var opath dbus.ObjectPath - n.call(&opath, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) - return nil +func (n *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) (ac ActiveConnection, err error) { + var opath1 dbus.ObjectPath + var opath2 dbus.ObjectPath + defer func() { + if r := recover(); r != nil { + ap = nil + err = errors.New("panic in " + NetworkManagerAddAndActivateConnection + ": " + fmt.Sprint(r)) + } + }() + err = n.callError2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) + if err != nil { + return + } + + ac, err = NewActiveConnection(opath2) + if err != nil { + return + } + return } func (n *networkManager) Subscribe() <-chan *dbus.Signal { From 54e6cf98e29b7bf190e870b5aa653ccf70bbb50b Mon Sep 17 00:00:00 2001 From: Peter Hommel Date: Mon, 13 May 2019 14:12:35 +0200 Subject: [PATCH 4/7] AddAndActivateWirelessConnection: removed unnecessary recover --- NetworkManager.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/NetworkManager.go b/NetworkManager.go index 4dd4ff3..68843fa 100644 --- a/NetworkManager.go +++ b/NetworkManager.go @@ -2,8 +2,6 @@ package gonetworkmanager import ( "encoding/json" - "errors" - "fmt" "github.com/godbus/dbus" ) @@ -109,12 +107,7 @@ func (n *networkManager) ActivateWirelessConnection(c Connection, d Device, ap A func (n *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) (ac ActiveConnection, err error) { var opath1 dbus.ObjectPath var opath2 dbus.ObjectPath - defer func() { - if r := recover(); r != nil { - ap = nil - err = errors.New("panic in " + NetworkManagerAddAndActivateConnection + ": " + fmt.Sprint(r)) - } - }() + err = n.callError2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) if err != nil { return From 12d19b58ae74d5f0af701daddfab4dfde6a5b30e Mon Sep 17 00:00:00 2001 From: Peter Hommel Date: Wed, 26 Jun 2019 09:24:05 +0200 Subject: [PATCH 5/7] Don't Panic: Forward all errors as error values. Read this for reference: https://dave.cheney.net/2012/01/18/why-go-gets-exceptions-right --- AccessPoint.go | 103 ++++++++++++++++++++++++---------- ActiveConnection.go | 121 ++++++++++++++++++++++++---------------- DHCP4Config.go | 17 ++++-- Device.go | 132 +++++++++++++++++++++++++++++++------------- IP4Config.go | 62 +++++++++++++++------ NetworkManager.go | 60 ++++++++++++-------- Settings.go | 27 +++++---- WirelessDevice.go | 31 +++++++---- utils.go | 117 ++++++++++++++++++--------------------- 9 files changed, 424 insertions(+), 246 deletions(-) diff --git a/AccessPoint.go b/AccessPoint.go index dd03b83..66b8051 100644 --- a/AccessPoint.go +++ b/AccessPoint.go @@ -24,36 +24,36 @@ type AccessPoint interface { GetPath() dbus.ObjectPath // GetFlags gets flags describing the capabilities of the access point. - GetFlags() uint32 + GetFlags() (uint32, error) // GetWPAFlags gets flags describing the access point's capabilities // according to WPA (Wifi Protected Access). - GetWPAFlags() uint32 + GetWPAFlags() (uint32, error) // GetRSNFlags gets flags describing the access point's capabilities // according to the RSN (Robust Secure Network) protocol. - GetRSNFlags() uint32 + GetRSNFlags() (uint32, error) // GetSSID returns the Service Set Identifier identifying the access point. - GetSSID() string + GetSSID() (string, error) // GetFrequency gets the radio channel frequency in use by the access point, // in MHz. - GetFrequency() uint32 + GetFrequency() (uint32, error) // GetHWAddress gets the hardware address (BSSID) of the access point. - GetHWAddress() string + GetHWAddress() (string, error) // GetMode describes the operating mode of the access point. - GetMode() Nm80211Mode + GetMode() (Nm80211Mode, error) // GetMaxBitrate gets the maximum bitrate this access point is capable of, in // kilobits/second (Kb/s). - GetMaxBitrate() uint32 + GetMaxBitrate() (uint32, error) // GetStrength gets the current signal quality of the access point, in // percent. - GetStrength() uint8 + GetStrength() (uint8, error) MarshalJSON() ([]byte, error) } @@ -71,52 +71,97 @@ func (a *accessPoint) GetPath() dbus.ObjectPath { return a.obj.Path() } -func (a *accessPoint) GetFlags() uint32 { +func (a *accessPoint) GetFlags() (uint32, error) { return a.getUint32Property(AccessPointPropertyFlags) } -func (a *accessPoint) GetWPAFlags() uint32 { +func (a *accessPoint) GetWPAFlags() (uint32, error) { return a.getUint32Property(AccessPointPropertyWPAFlags) } -func (a *accessPoint) GetRSNFlags() uint32 { +func (a *accessPoint) GetRSNFlags() (uint32, error) { return a.getUint32Property(AccessPointPropertyRSNFlags) } -func (a *accessPoint) GetSSID() string { - return string(a.getSliceByteProperty(AccessPointPropertySSID)) +func (a *accessPoint) GetSSID() (string, error) { + r, err := a.getSliceByteProperty(AccessPointPropertySSID) + if err != nil { + return "", err + } + return string(r), nil } -func (a *accessPoint) GetFrequency() uint32 { +func (a *accessPoint) GetFrequency() (uint32, error) { return a.getUint32Property(AccessPointPropertyFrequency) } -func (a *accessPoint) GetHWAddress() string { +func (a *accessPoint) GetHWAddress() (string, error) { return a.getStringProperty(AccessPointPropertyHWAddress) } -func (a *accessPoint) GetMode() Nm80211Mode { - return Nm80211Mode(a.getUint32Property(AccessPointPropertyMode)) +func (a *accessPoint) GetMode() (Nm80211Mode, error) { + r, err := a.getUint32Property(AccessPointPropertyMode) + if err != nil { + return Nm80211ModeUnknown, err + } + return Nm80211Mode(r), nil } -func (a *accessPoint) GetMaxBitrate() uint32 { +func (a *accessPoint) GetMaxBitrate() (uint32, error) { return a.getUint32Property(AccessPointPropertyMaxBitrate) } -func (a *accessPoint) GetStrength() uint8 { +func (a *accessPoint) GetStrength() (uint8, error) { return a.getUint8Property(AccessPointPropertyStrength) } func (a *accessPoint) MarshalJSON() ([]byte, error) { + Flags, err := a.GetFlags() + if err != nil { + return nil, err + } + WPAFlags, err := a.GetWPAFlags() + if err != nil { + return nil, err + } + RSNFlags, err := a.GetRSNFlags() + if err != nil { + return nil, err + } + SSID, err := a.GetSSID() + if err != nil { + return nil, err + } + Frequency, err := a.GetFrequency() + if err != nil { + return nil, err + } + HWAddress, err := a.GetHWAddress() + if err != nil { + return nil, err + } + Mode, err := a.GetMode() + if err != nil { + return nil, err + } + MaxBitrate, err := a.GetMaxBitrate() + if err != nil { + return nil, err + } + Strength, err := a.GetStrength() + if err != nil { + return nil, err + } + return json.Marshal(map[string]interface{}{ - "Flags": a.GetFlags(), - "WPAFlags": a.GetWPAFlags(), - "RSNFlags": a.GetRSNFlags(), - "SSID": a.GetSSID(), - "Frequency": a.GetFrequency(), - "HWAddress": a.GetHWAddress(), - "Mode": a.GetMode().String(), - "MaxBitrate": a.GetMaxBitrate(), - "Strength": a.GetStrength(), + "Flags": Flags, + "WPAFlags": WPAFlags, + "RSNFlags": RSNFlags, + "SSID": SSID, + "Frequency": Frequency, + "HWAddress": HWAddress, + "Mode": Mode.String(), + "MaxBitrate": MaxBitrate, + "Strength": Strength, }) } diff --git a/ActiveConnection.go b/ActiveConnection.go index 2ec5d4d..02e3bc2 100644 --- a/ActiveConnection.go +++ b/ActiveConnection.go @@ -24,43 +24,43 @@ const ( type ActiveConnection interface { // GetConnection gets connection object of the connection. - GetConnection() Connection + GetConnection() (Connection, error) // GetSpecificObject gets a specific object associated with the active connection. - GetSpecificObject() AccessPoint + GetSpecificObject() (AccessPoint, error) // GetID gets the ID of the connection. - GetID() string + GetID() (string, error) // GetUUID gets the UUID of the connection. - GetUUID() string + GetUUID() (string, error) // GetType gets the type of the connection. - GetType() string + GetType() (string, error) // GetDevices gets array of device objects which are part of this active connection. - GetDevices() []Device + GetDevices() ([]Device, error) // GetState gets the state of the connection. - GetState() uint32 + GetState() (uint32, error) // GetStateFlags gets the state flags of the connection. - GetStateFlags() uint32 + GetStateFlags() (uint32, error) // GetDefault gets the default IPv4 flag of the connection. - GetDefault() bool + GetDefault() (bool, error) // GetIP4Config gets the IP4Config of the connection. - GetIP4Config() IP4Config + GetIP4Config() (IP4Config, error) // GetDHCP4Config gets the DHCP4Config of the connection. - GetDHCP4Config() DHCP4Config + GetDHCP4Config() (DHCP4Config, error) // GetVPN gets the VPN flag of the connection. - GetVPN() bool + GetVPN() (bool, error) // GetMaster gets the master device of the connection. - GetMaster() Device + GetMaster() (Device, error) } func NewActiveConnection(objectPath dbus.ObjectPath) (ActiveConnection, error) { @@ -72,90 +72,113 @@ type activeConnection struct { dbusBase } -func (a *activeConnection) GetConnection() Connection { - path := a.getObjectProperty(ActiveConnectionProperyConnection) +func (a *activeConnection) GetConnection() (Connection, error) { + path, err := a.getObjectProperty(ActiveConnectionProperyConnection) + if err != nil { + return nil, err + } con, err := NewConnection(path) if err != nil { - panic(err) + return nil, err } - return con + return con, nil } -func (a *activeConnection) GetSpecificObject() AccessPoint { - path := a.getObjectProperty(ActiveConnectionProperySpecificObject) +func (a *activeConnection) GetSpecificObject() (AccessPoint, error) { + path, err := a.getObjectProperty(ActiveConnectionProperySpecificObject) + if err != nil { + return nil, err + } ap, err := NewAccessPoint(path) if err != nil { - panic(err) + return nil, err } - return ap + return ap, nil } -func (a *activeConnection) GetID() string { +func (a *activeConnection) GetID() (string, error) { return a.getStringProperty(ActiveConnectionProperyID) } -func (a *activeConnection) GetUUID() string { +func (a *activeConnection) GetUUID() (string, error) { return a.getStringProperty(ActiveConnectionProperyUUID) } -func (a *activeConnection) GetType() string { +func (a *activeConnection) GetType() (string, error) { return a.getStringProperty(ActiveConnectionProperyType) } -func (a *activeConnection) GetDevices() []Device { - paths := a.getSliceObjectProperty(ActiveConnectionProperyDevices) +func (a *activeConnection) GetDevices() ([]Device, error) { + paths, err := a.getSliceObjectProperty(ActiveConnectionProperyDevices) + if err != nil { + return nil, err + } devices := make([]Device, len(paths)) - var err error for i, path := range paths { devices[i], err = DeviceFactory(path) if err != nil { - panic(err) + return nil, err } } - return devices + return devices, nil } -func (a *activeConnection) GetState() uint32 { +func (a *activeConnection) GetState() (uint32, error) { return a.getUint32Property(ActiveConnectionProperyState) } -func (a *activeConnection) GetStateFlags() uint32 { +func (a *activeConnection) GetStateFlags() (uint32, error) { return a.getUint32Property(ActiveConnectionProperyStateFlags) } -func (a *activeConnection) GetDefault() bool { - b := a.getProperty(ActiveConnectionProperyDefault) - return b.(bool) +func (a *activeConnection) GetDefault() (bool, error) { + b, err := a.getProperty(ActiveConnectionProperyDefault) + if err != nil { + return false, err + } + return b.(bool), nil } -func (a *activeConnection) GetIP4Config() IP4Config { - path := a.getObjectProperty(ActiveConnectionProperyIP4Config) +func (a *activeConnection) GetIP4Config() (IP4Config, error) { + path, err := a.getObjectProperty(ActiveConnectionProperyIP4Config) + if err != nil { + return nil, err + } r, err := NewIP4Config(path) if err != nil { - panic(err) + return nil, err } - return r + return r, nil } -func (a *activeConnection) GetDHCP4Config() DHCP4Config { - path := a.getObjectProperty(ActiveConnectionProperyDHCP4Config) +func (a *activeConnection) GetDHCP4Config() (DHCP4Config, error) { + path, err := a.getObjectProperty(ActiveConnectionProperyDHCP4Config) + if err != nil { + return nil, err + } r, err := NewDHCP4Config(path) if err != nil { - panic(err) + return nil, err } - return r + return r, nil } -func (a *activeConnection) GetVPN() bool { - ret := a.getProperty(ActiveConnectionProperyVPN) - return ret.(bool) +func (a *activeConnection) GetVPN() (bool, error) { + ret, err := a.getProperty(ActiveConnectionProperyVPN) + if err != nil { + return false, err + } + return ret.(bool), nil } -func (a *activeConnection) GetMaster() Device { - path := a.getObjectProperty(ActiveConnectionProperyMaster) +func (a *activeConnection) GetMaster() (Device, error) { + path, err := a.getObjectProperty(ActiveConnectionProperyMaster) + if err != nil { + return nil, err + } r, err := DeviceFactory(path) if err != nil { - panic(err) + return nil, err } - return r + return r, nil } diff --git a/DHCP4Config.go b/DHCP4Config.go index 3b3a1c4..96d3403 100644 --- a/DHCP4Config.go +++ b/DHCP4Config.go @@ -16,7 +16,7 @@ type DHCP4Options map[string]interface{} type DHCP4Config interface { // GetOptions gets options map of configuration returned by the IPv4 DHCP server. - GetOptions() DHCP4Options + GetOptions() (DHCP4Options, error) MarshalJSON() ([]byte, error) } @@ -30,19 +30,26 @@ type dhcp4Config struct { dbusBase } -func (c *dhcp4Config) GetOptions() DHCP4Options { - options := c.getMapStringVariantProperty(DHCP4ConfigPropertyOptions) +func (c *dhcp4Config) GetOptions() (DHCP4Options, error) { + options, err := c.getMapStringVariantProperty(DHCP4ConfigPropertyOptions) + if err != nil { + return nil, err + } rv := make(DHCP4Options) for k, v := range options { rv[k] = v.Value() } - return rv + return rv, nil } func (c *dhcp4Config) MarshalJSON() ([]byte, error) { + Options, err := c.GetOptions() + if err != nil { + return nil, err + } return json.Marshal(map[string]interface{}{ - "Options": c.GetOptions(), + "Options": Options, }) } diff --git a/Device.go b/Device.go index f257722..2fad886 100644 --- a/Device.go +++ b/Device.go @@ -2,6 +2,7 @@ package gonetworkmanager import ( "encoding/json" + "errors" "github.com/godbus/dbus" ) @@ -24,7 +25,11 @@ func DeviceFactory(objectPath dbus.ObjectPath) (Device, error) { return nil, err } - switch d.GetDeviceType() { + dt, err := d.GetDeviceType() + if err != nil { + return nil, err + } + switch dt { case NmDeviceTypeWifi: return NewWirelessDevice(objectPath) } @@ -37,31 +42,31 @@ type Device interface { // GetInterface gets the name of the device's control (and often data) // interface. - GetInterface() string + GetInterface() (string, error) // GetIpInterface gets the IP interface name of the device. - GetIpInterface() string + GetIpInterface() (string, error) // GetState gets the current state of the device. - GetState() NmDeviceState + GetState() (NmDeviceState, error) // GetIP4Config gets the Ip4Config object describing the configuration of the // device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED // state. - GetIP4Config() IP4Config + GetIP4Config() (IP4Config, error) // GetDHCP4Config gets the Dhcp4Config object describing the configuration of the // device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED // state. - GetDHCP4Config() DHCP4Config + GetDHCP4Config() (DHCP4Config, error) // GetDeviceType gets the general type of the network device; ie Ethernet, // WiFi, etc. - GetDeviceType() NmDeviceType + GetDeviceType() (NmDeviceType, error) // GetAvailableConnections gets an array of object paths of every configured // connection that is currently 'available' through this device. - GetAvailableConnections() []Connection + GetAvailableConnections() ([]Connection, error) MarshalJSON() ([]byte, error) } @@ -79,77 +84,126 @@ func (d *device) GetPath() dbus.ObjectPath { return d.obj.Path() } -func (d *device) GetInterface() string { +func (d *device) GetInterface() (string, error) { return d.getStringProperty(DevicePropertyInterface) } -func (d *device) GetIpInterface() string { +func (d *device) GetIpInterface() (string, error) { return d.getStringProperty(DevicePropertyIpInterface) } -func (d *device) GetState() NmDeviceState { - return NmDeviceState(d.getUint32Property(DevicePropertyState)) +func (d *device) GetState() (NmDeviceState, error) { + r, err := d.getUint32Property(DevicePropertyState) + if err != nil { + return NmDeviceStateFailed, err + } + return NmDeviceState(r), nil } -func (d *device) GetIP4Config() IP4Config { - path := d.getObjectProperty(DevicePropertyIP4Config) +func (d *device) GetIP4Config() (IP4Config, error) { + path, err := d.getObjectProperty(DevicePropertyIP4Config) + if err != nil { + return nil, err + } if path == "/" { - return nil + return nil, errors.New("device path was empty") } cfg, err := NewIP4Config(path) if err != nil { - panic(err) + return nil, err } - return cfg + return cfg, nil } -func (d *device) GetDHCP4Config() DHCP4Config { - path := d.getObjectProperty(DevicePropertyDhcp4Config) +func (d *device) GetDHCP4Config() (DHCP4Config, error) { + path, err := d.getObjectProperty(DevicePropertyDhcp4Config) + if err != nil { + return nil, err + } if path == "/" { - return nil + return nil, errors.New("device path was empty") } cfg, err := NewDHCP4Config(path) if err != nil { - panic(err) + return nil, err } - return cfg + return cfg, nil } -func (d *device) GetDeviceType() NmDeviceType { - return NmDeviceType(d.getUint32Property(DevicePropertyDeviceType)) +func (d *device) GetDeviceType() (NmDeviceType, error) { + r, err := d.getUint32Property(DevicePropertyDeviceType) + if err != nil { + return NmDeviceTypeUnknown, err + } + return NmDeviceType(r), nil } -func (d *device) GetAvailableConnections() []Connection { - connPaths := d.getSliceObjectProperty(DevicePropertyAvailableConnections) +func (d *device) GetAvailableConnections() ([]Connection, error) { + connPaths, err := d.getSliceObjectProperty(DevicePropertyAvailableConnections) + if err != nil { + return nil, err + } conns := make([]Connection, len(connPaths)) - var err error for i, path := range connPaths { conns[i], err = NewConnection(path) if err != nil { - panic(err) + return nil, err } } - return conns + return conns, nil } -func (d *device) marshalMap() map[string]interface{} { - return map[string]interface{}{ - "Interface": d.GetInterface(), - "IP interface": d.GetIpInterface(), - "State": d.GetState().String(), - "IP4Config": d.GetIP4Config(), - "DHCP4Config": d.GetDHCP4Config(), - "DeviceType": d.GetDeviceType().String(), - "AvailableConnections": d.GetAvailableConnections(), +func (d *device) marshalMap() (map[string]interface{}, error) { + Interface, err := d.GetInterface() + if err != nil { + return nil, err } + IPinterface, err := d.GetIpInterface() + if err != nil { + return nil, err + } + State, err := d.GetState() + if err != nil { + return nil, err + } + IP4Config, err := d.GetIP4Config() + if err != nil { + return nil, err + } + DHCP4Config, err := d.GetDHCP4Config() + if err != nil { + return nil, err + } + DeviceType, err := d.GetDeviceType() + if err != nil { + return nil, err + } + AvailableConnections, err := d.GetAvailableConnections() + if err != nil { + return nil, err + } + + return map[string]interface{}{ + "Interface": Interface, + "IP interface": IPinterface, + "State": State.String(), + "IP4Config": IP4Config, + "DHCP4Config": DHCP4Config, + "DeviceType": DeviceType.String(), + "AvailableConnections": AvailableConnections, + }, nil } func (d *device) MarshalJSON() ([]byte, error) { - return json.Marshal(d.marshalMap()) + m, err := d.marshalMap() + if err != nil { + return nil, err + } + return json.Marshal(m) } diff --git a/IP4Config.go b/IP4Config.go index e265b74..eb42a6d 100644 --- a/IP4Config.go +++ b/IP4Config.go @@ -32,20 +32,20 @@ type IP4Config interface { // GetAddresses gets an array of tuples of IPv4 address/prefix/gateway. All 3 // elements of each tuple are in network byte order. Essentially: [(addr, // prefix, gateway), (addr, prefix, gateway), ...] - GetAddresses() []IP4Address + GetAddresses() ([]IP4Address, error) // GetRoutes gets tuples of IPv4 route/prefix/next-hop/metric. All 4 elements // of each tuple are in network byte order. 'route' and 'next hop' are IPv4 // addresses, while prefix and metric are simple unsigned integers. // Essentially: [(route, prefix, next-hop, metric), (route, prefix, next-hop, // metric), ...] - GetRoutes() []IP4Route + GetRoutes() ([]IP4Route, error) // GetNameservers gets the nameservers in use. - GetNameservers() []string + GetNameservers() ([]string, error) // GetDomains gets a list of domains this address belongs to. - GetDomains() []string + GetDomains() ([]string, error) MarshalJSON() ([]byte, error) } @@ -59,8 +59,11 @@ type ip4Config struct { dbusBase } -func (c *ip4Config) GetAddresses() []IP4Address { - addresses := c.getSliceSliceUint32Property(IP4ConfigPropertyAddresses) +func (c *ip4Config) GetAddresses() ([]IP4Address, error) { + addresses, err := c.getSliceSliceUint32Property(IP4ConfigPropertyAddresses) + if err != nil { + return nil, err + } ret := make([]IP4Address, len(addresses)) for i, parts := range addresses { @@ -71,11 +74,14 @@ func (c *ip4Config) GetAddresses() []IP4Address { } } - return ret + return ret, nil } -func (c *ip4Config) GetRoutes() []IP4Route { - routes := c.getSliceSliceUint32Property(IP4ConfigPropertyRoutes) +func (c *ip4Config) GetRoutes() ([]IP4Route, error) { + routes, err := c.getSliceSliceUint32Property(IP4ConfigPropertyRoutes) + if err != nil { + return nil, err + } ret := make([]IP4Route, len(routes)) for i, parts := range routes { @@ -87,29 +93,49 @@ func (c *ip4Config) GetRoutes() []IP4Route { } } - return ret + return ret, nil } -func (c *ip4Config) GetNameservers() []string { - nameservers := c.getSliceUint32Property(IP4ConfigPropertyNameservers) +func (c *ip4Config) GetNameservers() ([]string, error) { + nameservers, err := c.getSliceUint32Property(IP4ConfigPropertyNameservers) + if err != nil { + return nil, err + } ret := make([]string, len(nameservers)) for i, ns := range nameservers { ret[i] = ip4ToString(ns) } - return ret + return ret, nil } -func (c *ip4Config) GetDomains() []string { +func (c *ip4Config) GetDomains() ([]string, error) { return c.getSliceStringProperty(IP4ConfigPropertyDomains) } func (c *ip4Config) MarshalJSON() ([]byte, error) { + Addresses, err := c.GetAddresses() + if err != nil { + return nil, err + } + Routes, err := c.GetRoutes() + if err != nil { + return nil, err + } + Nameservers, err := c.GetNameservers() + if err != nil { + return nil, err + } + Domains, err := c.GetDomains() + if err != nil { + return nil, err + } + return json.Marshal(map[string]interface{}{ - "Addresses": c.GetAddresses(), - "Routes": c.GetRoutes(), - "Nameservers": c.GetNameservers(), - "Domains": c.GetDomains(), + "Addresses": Addresses, + "Routes": Routes, + "Nameservers": Nameservers, + "Domains": Domains, }) } diff --git a/NetworkManager.go b/NetworkManager.go index 68843fa..365df35 100644 --- a/NetworkManager.go +++ b/NetworkManager.go @@ -20,18 +20,18 @@ const ( type NetworkManager interface { // GetDevices gets the list of network devices. - GetDevices() []Device + GetDevices() ([]Device, error) // GetState returns the overall networking state as determined by the // NetworkManager daemon, based on the state of network devices under it's // management. - GetState() NmState + GetState() (NmState, error) // GetActiveConnections returns the active connection of network devices. - GetActiveConnections() []ActiveConnection + GetActiveConnections() ([]ActiveConnection, error) // ActivateWirelessConnection requests activating access point to network device - ActivateWirelessConnection(connection Connection, device Device, accessPoint AccessPoint) ActiveConnection + ActivateWirelessConnection(connection Connection, device Device, accessPoint AccessPoint) (ActiveConnection, error) // AddAndActivateWirelessConnection adds a new connection profile to the network device it has been // passed. It then activates the connection to the passed access point. The first paramter contains @@ -62,53 +62,60 @@ type networkManager struct { sigChan chan *dbus.Signal } -func (n *networkManager) GetDevices() []Device { +func (n *networkManager) GetDevices() ([]Device, error) { var devicePaths []dbus.ObjectPath - n.call(&devicePaths, NetworkManagerGetDevices) + err := n.call(&devicePaths, NetworkManagerGetDevices) + if err != nil { + return nil, err + } devices := make([]Device, len(devicePaths)) - var err error for i, path := range devicePaths { devices[i], err = DeviceFactory(path) if err != nil { - panic(err) + return nil, err } } - return devices + return devices, nil } -func (n *networkManager) GetState() NmState { - return NmState(n.getUint32Property(NetworkManagerPropertyState)) +func (n *networkManager) GetState() (NmState, error) { + r, err := n.getUint32Property(NetworkManagerPropertyState) + if err != nil { + return NmStateUnknown, err + } + return NmState(r), nil } -func (n *networkManager) GetActiveConnections() []ActiveConnection { - acPaths := n.getSliceObjectProperty(NetworkManagerPropertyActiveConnection) +func (n *networkManager) GetActiveConnections() ([]ActiveConnection, error) { + acPaths, err := n.getSliceObjectProperty(NetworkManagerPropertyActiveConnection) + if err != nil { + return nil, err + } ac := make([]ActiveConnection, len(acPaths)) - var err error for i, path := range acPaths { ac[i], err = NewActiveConnection(path) if err != nil { - panic(err) + return nil, err } } - return ac + return ac, nil } -func (n *networkManager) ActivateWirelessConnection(c Connection, d Device, ap AccessPoint) ActiveConnection { +func (n *networkManager) ActivateWirelessConnection(c Connection, d Device, ap AccessPoint) (ActiveConnection, error) { var opath dbus.ObjectPath - n.call(&opath, NetworkManagerActivateConnection, c.GetPath(), d.GetPath(), ap.GetPath()) - return nil + return nil, n.call(&opath, NetworkManagerActivateConnection, c.GetPath(), d.GetPath(), ap.GetPath()) } func (n *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) (ac ActiveConnection, err error) { var opath1 dbus.ObjectPath var opath2 dbus.ObjectPath - err = n.callError2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) + err = n.call2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) if err != nil { return } @@ -138,8 +145,17 @@ func (n *networkManager) Unsubscribe() { } func (n *networkManager) MarshalJSON() ([]byte, error) { + NetworkState, err := n.GetState() + if err != nil { + return nil, err + } + Devices, err := n.GetDevices() + if err != nil { + return nil, err + } + return json.Marshal(map[string]interface{}{ - "NetworkState": n.GetState().String(), - "Devices": n.GetDevices(), + "NetworkState": NetworkState.String(), + "Devices": Devices, }) } diff --git a/Settings.go b/Settings.go index 924d849..0d9e134 100644 --- a/Settings.go +++ b/Settings.go @@ -15,10 +15,10 @@ const ( type Settings interface { // ListConnections gets list the saved network connections known to NetworkManager - ListConnections() []Connection + ListConnections() ([]Connection, error) // AddConnection call new connection and save it to disk. - AddConnection(settings ConnectionSettings) Connection + AddConnection(settings ConnectionSettings) (Connection, error) } func NewSettings() (Settings, error) { @@ -30,29 +30,34 @@ type settings struct { dbusBase } -func (s *settings) ListConnections() []Connection { +func (s *settings) ListConnections() ([]Connection, error) { var connectionPaths []dbus.ObjectPath - s.call(&connectionPaths, SettingsListConnections) + err := s.call(&connectionPaths, SettingsListConnections) + if err != nil { + return nil, err + } connections := make([]Connection, len(connectionPaths)) - var err error for i, path := range connectionPaths { connections[i], err = NewConnection(path) if err != nil { - panic(err) + return nil, err } } - return connections + return connections, nil } -func (s *settings) AddConnection(settings ConnectionSettings) Connection { +func (s *settings) AddConnection(settings ConnectionSettings) (Connection, error) { var path dbus.ObjectPath - s.call(&path, SettingsAddConnection, settings) + err := s.call(&path, SettingsAddConnection, settings) + if err != nil { + return nil, err + } con, err := NewConnection(path) if err != nil { - panic(err) + return nil, err } - return con + return con, nil } diff --git a/WirelessDevice.go b/WirelessDevice.go index 9c4adab..5300d12 100644 --- a/WirelessDevice.go +++ b/WirelessDevice.go @@ -20,9 +20,9 @@ type WirelessDevice interface { // Note that this list does not include access points which hide their SSID. // To retrieve a list of all access points (including hidden ones) use the // GetAllAccessPoints() method. - GetAccessPoints() []AccessPoint + GetAccessPoints() ([]AccessPoint, error) - RequestScan() + RequestScan() error } func NewWirelessDevice(objectPath dbus.ObjectPath) (WirelessDevice, error) { @@ -34,30 +34,39 @@ type wirelessDevice struct { device } -func (d *wirelessDevice) GetAccessPoints() []AccessPoint { +func (d *wirelessDevice) GetAccessPoints() ([]AccessPoint, error) { var apPaths []dbus.ObjectPath - d.call(&apPaths, WirelessDeviceGetAccessPoints) + err := d.call(&apPaths, WirelessDeviceGetAccessPoints) + if err != nil { + return nil, err + } aps := make([]AccessPoint, len(apPaths)) - var err error for i, path := range apPaths { aps[i], err = NewAccessPoint(path) if err != nil { - panic(err) + return nil, err } } - return aps + return aps, nil } -func (d *wirelessDevice) RequestScan() { +func (d *wirelessDevice) RequestScan() error { var options map[string]interface{} - d.obj.Call(WirelessDeviceRequestScan, 0, options).Store() + return d.obj.Call(WirelessDeviceRequestScan, 0, options).Store() } func (d *wirelessDevice) MarshalJSON() ([]byte, error) { - m := d.device.marshalMap() - m["AccessPoints"] = d.GetAccessPoints() + m, err := d.device.marshalMap() + if err != nil { + return nil, err + } + aps, err := d.GetAccessPoints() + if err != nil { + return nil, err + } + m["AccessPoints"] = aps return json.Marshal(m) } diff --git a/utils.go b/utils.go index b6f73da..6bb2f66 100644 --- a/utils.go +++ b/utils.go @@ -30,18 +30,11 @@ func (d *dbusBase) init(iface string, objectPath dbus.ObjectPath) error { return nil } -func (d *dbusBase) call(value interface{}, method string, args ...interface{}) { - err := d.callError(value, method, args...) - if err != nil { - panic(err) - } -} - -func (d *dbusBase) callError(value interface{}, method string, args ...interface{}) error { +func (d *dbusBase) call(value interface{}, method string, args ...interface{}) error { return d.obj.Call(method, 0, args...).Store(value) } -func (d *dbusBase) callError2(value1 interface{}, value2 interface{}, method string, args ...interface{}) error { +func (d *dbusBase) call2(value1 interface{}, value2 interface{}, method string, args ...interface{}) error { return d.obj.Call(method, 0, args...).Store(value1, value2) } @@ -56,92 +49,92 @@ func (d *dbusBase) subscribeNamespace(namespace string) { d.conn.BusObject().Call(dbusMethodAddMatch, 0, rule) } -func (d *dbusBase) getProperty(iface string) interface{} { +func (d *dbusBase) getProperty(iface string) (interface{}, error) { variant, err := d.obj.GetProperty(iface) if err != nil { - panic(err) + return nil, err } - return variant.Value() + return variant.Value(), nil } -func (d *dbusBase) getObjectProperty(iface string) dbus.ObjectPath { - value, ok := d.getProperty(iface).(dbus.ObjectPath) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getObjectProperty(iface string) (dbus.ObjectPath, error) { + value, err := d.getProperty(iface) + if err != nil { + return "", makeErrVariantType(iface) } - return value + return value.(dbus.ObjectPath), nil } -func (d *dbusBase) getSliceObjectProperty(iface string) []dbus.ObjectPath { - value, ok := d.getProperty(iface).([]dbus.ObjectPath) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getSliceObjectProperty(iface string) ([]dbus.ObjectPath, error) { + value, err := d.getProperty(iface) + if err != nil { + return nil, makeErrVariantType(iface) } - return value + return value.([]dbus.ObjectPath), nil } -func (d *dbusBase) getStringProperty(iface string) string { - value, ok := d.getProperty(iface).(string) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getStringProperty(iface string) (string, error) { + value, err := d.getProperty(iface) + if err != nil { + return "", makeErrVariantType(iface) } - return value + return value.(string), nil } -func (d *dbusBase) getSliceStringProperty(iface string) []string { - value, ok := d.getProperty(iface).([]string) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getSliceStringProperty(iface string) ([]string, error) { + value, err := d.getProperty(iface) + if err != nil { + return nil, makeErrVariantType(iface) } - return value + return value.([]string), nil } -func (d *dbusBase) getMapStringVariantProperty(iface string) map[string]dbus.Variant { - value, ok := d.getProperty(iface).(map[string]dbus.Variant) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getMapStringVariantProperty(iface string) (map[string]dbus.Variant, error) { + value, err := d.getProperty(iface) + if err != nil { + return nil, makeErrVariantType(iface) } - return value + return value.(map[string]dbus.Variant), nil } -func (d *dbusBase) getUint8Property(iface string) uint8 { - value, ok := d.getProperty(iface).(uint8) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getUint8Property(iface string) (uint8, error) { + value, err := d.getProperty(iface) + if err != nil { + return 0, makeErrVariantType(iface) } - return value + return value.(uint8), nil } -func (d *dbusBase) getUint32Property(iface string) uint32 { - value, ok := d.getProperty(iface).(uint32) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getUint32Property(iface string) (uint32, error) { + value, err := d.getProperty(iface) + if err != nil { + return 0, makeErrVariantType(iface) } - return value + return value.(uint32), nil } -func (d *dbusBase) getSliceUint32Property(iface string) []uint32 { - value, ok := d.getProperty(iface).([]uint32) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getSliceUint32Property(iface string) ([]uint32, error) { + value, err := d.getProperty(iface) + if err != nil { + return nil, makeErrVariantType(iface) } - return value + return value.([]uint32), nil } -func (d *dbusBase) getSliceSliceUint32Property(iface string) [][]uint32 { - value, ok := d.getProperty(iface).([][]uint32) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getSliceSliceUint32Property(iface string) ([][]uint32, error) { + value, err := d.getProperty(iface) + if err != nil { + return nil, makeErrVariantType(iface) } - return value + return value.([][]uint32), nil } -func (d *dbusBase) getSliceByteProperty(iface string) []byte { - value, ok := d.getProperty(iface).([]byte) - if !ok { - panic(makeErrVariantType(iface)) +func (d *dbusBase) getSliceByteProperty(iface string) ([]byte, error) { + value, err := d.getProperty(iface) + if err != nil { + return nil, makeErrVariantType(iface) } - return value + return value.([]byte), nil } func makeErrVariantType(iface string) error { From 4c09e115f8b875adad76d1f8021762d29e509798 Mon Sep 17 00:00:00 2001 From: meskedal Date: Sat, 29 Jun 2019 23:53:31 +0200 Subject: [PATCH 6/7] Fixed duplicate entries in nm and utils After the latest merge there was a duplicate entry of AddAndActivateWirelessConnection in NetworkManager.go which has been removed. There was also duplicate functions call2 and callError2 in utils.go. The duplicate of AddAndActivateWirelessConnection referenced callError2, and both of these duplicates has been removed. --- NetworkManager.go | 28 ---------------------------- utils.go | 4 ---- 2 files changed, 32 deletions(-) diff --git a/NetworkManager.go b/NetworkManager.go index d09d14f..365df35 100644 --- a/NetworkManager.go +++ b/NetworkManager.go @@ -45,18 +45,6 @@ type NetworkManager interface { // connection["802-11-wireless-security"]["psk"] = password AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device Device, accessPoint AccessPoint) (ac ActiveConnection, err error) - // AddAndActivateWirelessConnection adds a new connection profile to the network device it has been - // passed. It then activates the connection to the passed access point. The first paramter contains - // additional information for the connection (most propably the credentials). - // Example contents for connection are: - // connection := make(map[string]map[string]interface{}) - // connection["802-11-wireless"] = make(map[string]interface{}) - // connection["802-11-wireless"]["security"] = "802-11-wireless-security" - // connection["802-11-wireless-security"] = make(map[string]interface{}) - // connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk" - // connection["802-11-wireless-security"]["psk"] = password - AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device Device, accessPoint AccessPoint) (ac ActiveConnection, err error) - Subscribe() <-chan *dbus.Signal Unsubscribe() @@ -139,22 +127,6 @@ func (n *networkManager) AddAndActivateWirelessConnection(connection map[string] return } -func (n *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) (ac ActiveConnection, err error) { - var opath1 dbus.ObjectPath - var opath2 dbus.ObjectPath - - err = n.callError2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath()) - if err != nil { - return - } - - ac, err = NewActiveConnection(opath2) - if err != nil { - return - } - return -} - func (n *networkManager) Subscribe() <-chan *dbus.Signal { if n.sigChan != nil { return n.sigChan diff --git a/utils.go b/utils.go index 97a12ce..6bb2f66 100644 --- a/utils.go +++ b/utils.go @@ -38,10 +38,6 @@ func (d *dbusBase) call2(value1 interface{}, value2 interface{}, method string, return d.obj.Call(method, 0, args...).Store(value1, value2) } -func (d *dbusBase) callError2(value1 interface{}, value2 interface{}, method string, args ...interface{}) error { - return d.obj.Call(method, 0, args...).Store(value1, value2) -} - func (d *dbusBase) subscribe(iface, member string) { rule := fmt.Sprintf("type='signal',interface='%s',path='%s',member='%s'", iface, d.obj.Path(), NetworkManagerInterface) From 4fdc455bc72cac7af2c7521272a8969611e1069c Mon Sep 17 00:00:00 2001 From: Michel Wohlert Date: Tue, 20 Aug 2019 03:22:19 +0200 Subject: [PATCH 7/7] Added connection delete --- Connection.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Connection.go b/Connection.go index 692def0..d43bf72 100644 --- a/Connection.go +++ b/Connection.go @@ -10,6 +10,8 @@ const ( ConnectionInterface = SettingsInterface + ".Connection" ConnectionGetSettings = ConnectionInterface + ".GetSettings" + + ConnectionDelete = ConnectionInterface + ".Delete" ) //type ConnectionSettings map[string]map[string]interface{} @@ -24,6 +26,9 @@ type Connection interface { // separately using the GetSecrets() call. GetSettings() ConnectionSettings + // Delete will delete the connection + Delete() + MarshalJSON() ([]byte, error) } @@ -57,6 +62,10 @@ func (c *connection) GetSettings() ConnectionSettings { return rv } +func (c *connection) Delete() { + c.call(c.GetPath(), ConnectionDelete) +} + func (c *connection) MarshalJSON() ([]byte, error) { return json.Marshal(c.GetSettings()) }