From 75591bce9741a19f9825dd47d43330cdf39ea58f Mon Sep 17 00:00:00 2001 From: Tom Wambold Date: Tue, 24 May 2016 20:58:18 -0400 Subject: [PATCH] Initial commit with not a whole lot of coverage. --- AccessPoint.go | 29 ++++++++++ ActiveConnection.go | 4 ++ Connection.go | 48 ++++++++++++++++ Device.go | 101 ++++++++++++++++++++++++++++++++++ IP4Config.go | 102 ++++++++++++++++++++++++++++++++++ LICENSE | 21 +++++++ NetworkManager.go | 54 ++++++++++++++++++ README.md | 10 ++++ Settings.go | 5 ++ WirelessDevice.go | 47 ++++++++++++++++ enums.go | 67 +++++++++++++++++++++++ errors.go | 9 +++ nmconnectivity_string.go | 16 ++++++ nmdevicestate_string.go | 30 ++++++++++ nmdevicetype_string.go | 16 ++++++ nmstate_string.go | 50 +++++++++++++++++ utils.go | 115 +++++++++++++++++++++++++++++++++++++++ 17 files changed, 724 insertions(+) create mode 100644 AccessPoint.go create mode 100644 ActiveConnection.go create mode 100644 Connection.go create mode 100644 Device.go create mode 100644 IP4Config.go create mode 100644 LICENSE create mode 100644 NetworkManager.go create mode 100644 README.md create mode 100644 Settings.go create mode 100644 WirelessDevice.go create mode 100644 enums.go create mode 100644 errors.go create mode 100644 nmconnectivity_string.go create mode 100644 nmdevicestate_string.go create mode 100644 nmdevicetype_string.go create mode 100644 nmstate_string.go create mode 100644 utils.go diff --git a/AccessPoint.go b/AccessPoint.go new file mode 100644 index 0000000..0d6341e --- /dev/null +++ b/AccessPoint.go @@ -0,0 +1,29 @@ +package gonetworkmanager + +import ( + "github.com/godbus/dbus" +) + +const ( + AccessPointInterface = NetworkManagerInterface + ".AccessPoint" + + AccessPointPropertySSID = AccessPointInterface + ".Ssid" +) + +type AccessPoint interface { + // GetSSID returns the Service Set Identifier identifying the access point. + GetSSID() string +} + +func NewAccessPoint(objectPath dbus.ObjectPath) (AccessPoint, error) { + var a accessPoint + return &a, a.init(NetworkManagerInterface, objectPath) +} + +type accessPoint struct { + dbusBase +} + +func (a *accessPoint) GetSSID() string { + return string(a.getSliceByteProperty(AccessPointPropertySSID)) +} diff --git a/ActiveConnection.go b/ActiveConnection.go new file mode 100644 index 0000000..3444eaa --- /dev/null +++ b/ActiveConnection.go @@ -0,0 +1,4 @@ +package gonetworkmanager + +type ActiveConnection interface { +} diff --git a/Connection.go b/Connection.go new file mode 100644 index 0000000..5882f5b --- /dev/null +++ b/Connection.go @@ -0,0 +1,48 @@ +package gonetworkmanager + +import ( + "github.com/godbus/dbus" +) + +const ( + ConnectionInterface = SettingsInterface + ".Connection" + + ConnectionGetSettings = ConnectionInterface + ".GetSettings" +) + +//type ConnectionSettings map[string]map[string]interface{} +type ConnectionSettings map[string]map[string]interface{} + +type Connection interface { + // GetSettings gets the settings maps describing this network configuration. + // This will never include any secrets required for connection to the + // network, as those are often protected. Secrets must be requested + // separately using the GetSecrets() call. + GetSettings() ConnectionSettings +} + +func NewConnection(objectPath dbus.ObjectPath) (Connection, error) { + var c connection + return &c, c.init(NetworkManagerInterface, objectPath) +} + +type connection struct { + dbusBase +} + +func (c *connection) GetSettings() ConnectionSettings { + var settings map[string]map[string]dbus.Variant + c.call(&settings, ConnectionGetSettings) + + rv := make(ConnectionSettings) + + for k1, v1 := range settings { + rv[k1] = make(map[string]interface{}) + + for k2, v2 := range v1 { + rv[k1][k2] = v2.Value() + } + } + + return rv +} diff --git a/Device.go b/Device.go new file mode 100644 index 0000000..e397d33 --- /dev/null +++ b/Device.go @@ -0,0 +1,101 @@ +package gonetworkmanager + +import ( + "github.com/godbus/dbus" +) + +const ( + DeviceInterface = NetworkManagerInterface + ".Device" + + DevicePropertyInterface = DeviceInterface + ".Interface" + DevicePropertyState = DeviceInterface + ".State" + DevicePropertyIP4Config = DeviceInterface + ".Ip4Config" + DevicePropertyDeviceType = DeviceInterface + ".DeviceType" + DevicePropertyAvailableConnections = DeviceInterface + ".AvailableConnections" +) + +func DeviceFactory(objectPath dbus.ObjectPath) (Device, error) { + d, err := NewDevice(objectPath) + if err != nil { + return nil, err + } + + switch d.GetDeviceType() { + case NmDeviceTypeWifi: + return NewWirelessDevice(objectPath) + } + + return d, nil +} + +type Device interface { + // GetInterface gets the name of the device's control (and often data) + // interface. + GetInterface() string + + // GetState gets the current state of the device. + GetState() NmDeviceState + + // 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 + + // GetDeviceType gets the general type of the network device; ie Ethernet, + // WiFi, etc. + GetDeviceType() NmDeviceType + + // GetAvailableConnections gets an array of object paths of every configured + // connection that is currently 'available' through this device. + GetAvailableConnections() []Connection +} + +func NewDevice(objectPath dbus.ObjectPath) (Device, error) { + var d device + return &d, d.init(NetworkManagerInterface, objectPath) +} + +type device struct { + dbusBase +} + +func (d *device) GetInterface() string { + return d.getStringProperty(DevicePropertyInterface) +} + +func (d *device) GetState() NmDeviceState { + return NmDeviceState(d.getUint32Property(DevicePropertyState)) +} + +func (d *device) GetIP4Config() IP4Config { + path := d.getObjectProperty(DevicePropertyIP4Config) + if path == "/" { + return nil + } + + cfg, err := NewIP4Config(path) + if err != nil { + panic(err) + } + + return cfg +} + +func (d *device) GetDeviceType() NmDeviceType { + return NmDeviceType(d.getUint32Property(DevicePropertyDeviceType)) +} + +func (d *device) GetAvailableConnections() []Connection { + connPaths := d.getSliceObjectProperty(DevicePropertyAvailableConnections) + conns := make([]Connection, len(connPaths)) + + var err error + for i, path := range connPaths { + conns[i], err = NewConnection(path) + if err != nil { + panic(err) + } + } + + return conns +} diff --git a/IP4Config.go b/IP4Config.go new file mode 100644 index 0000000..a674538 --- /dev/null +++ b/IP4Config.go @@ -0,0 +1,102 @@ +package gonetworkmanager + +import ( + "github.com/godbus/dbus" +) + +const ( + IP4ConfigInterface = NetworkManagerInterface + ".IP4Config" + + IP4ConfigPropertyAddresses = IP4ConfigInterface + ".Addresses" + IP4ConfigPropertyRoutes = IP4ConfigInterface + ".Routes" + IP4ConfigPropertyNameservers = IP4ConfigInterface + ".Nameservers" + IP4ConfigPropertyDomains = IP4ConfigInterface + ".Domains" +) + +type IP4Address struct { + Address string + Prefix uint8 + Gateway string +} + +type IP4Route struct { + Route string + Prefix uint8 + NextHop string + Metric uint8 +} + +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 + + // 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 + + // GetNameservers gets the nameservers in use. + GetNameservers() []string + + // GetDomains gets a list of domains this address belongs to. + GetDomains() []string +} + +func NewIP4Config(objectPath dbus.ObjectPath) (IP4Config, error) { + var c ip4Config + return &c, c.init(NetworkManagerInterface, objectPath) +} + +type ip4Config struct { + dbusBase +} + +func (c *ip4Config) GetAddresses() []IP4Address { + addresses := c.getSliceSliceUint32Property(IP4ConfigPropertyAddresses) + ret := make([]IP4Address, len(addresses)) + + for i, parts := range addresses { + ret[i] = IP4Address{ + Address: ip4ToString(parts[0]), + Prefix: uint8(parts[1]), + Gateway: ip4ToString(parts[2]), + } + } + + return ret +} + +func (c *ip4Config) GetRoutes() []IP4Route { + routes := c.getSliceSliceUint32Property(IP4ConfigPropertyRoutes) + ret := make([]IP4Route, len(routes)) + + for i, parts := range routes { + ret[i] = IP4Route{ + Route: ip4ToString(parts[0]), + Prefix: uint8(parts[1]), + NextHop: ip4ToString(parts[2]), + Metric: uint8(parts[3]), + } + } + + return ret +} + +func (c *ip4Config) GetNameservers() []string { + nameservers := c.getSliceUint32Property(IP4ConfigPropertyNameservers) + ret := make([]string, len(nameservers)) + + for i, ns := range nameservers { + ret[i] = ip4ToString(ns) + } + + return ret +} + +func (c *ip4Config) GetDomains() []string { + return c.getSliceStringProperty(IP4ConfigPropertyDomains) +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..86e5a3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Bellerophon Mobile + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NetworkManager.go b/NetworkManager.go new file mode 100644 index 0000000..07e0138 --- /dev/null +++ b/NetworkManager.go @@ -0,0 +1,54 @@ +package gonetworkmanager + +import ( + "github.com/godbus/dbus" +) + +const ( + NetworkManagerInterface = "org.freedesktop.NetworkManager" + NetworkManagerObjectPath = "/org/freedesktop/NetworkManager" + + NetworkManagerGetDevices = NetworkManagerInterface + ".GetDevices" + NetworkManagerPropertyState = NetworkManagerInterface + ".state" +) + +type NetworkManager interface { + + // GetDevices gets the list of network devices. + GetDevices() []Device + + // 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 +} + +func NewNetworkManager() (NetworkManager, error) { + var nm networkManager + return &nm, nm.init(NetworkManagerInterface, NetworkManagerObjectPath) +} + +type networkManager struct { + dbusBase +} + +func (n *networkManager) GetDevices() []Device { + var devicePaths []dbus.ObjectPath + + n.call(&devicePaths, NetworkManagerGetDevices) + devices := make([]Device, len(devicePaths)) + + var err error + for i, path := range devicePaths { + devices[i], err = DeviceFactory(path) + if err != nil { + panic(err) + } + } + + return devices +} + +func (n *networkManager) GetState() NmState { + return NmState(n.getUint32Property(NetworkManagerPropertyState)) +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..1693ce1 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +gonetworkmanager +================ + +Go D-Bus bindings for NetworkManager. + +Currently tested with NetworkManager 0.9.8.10. + +(https://godoc.org/github.com/BellerophonMobile/gonetworkmanager?status.svg)](https://godoc.org/github.com/BellerophonMobile/gonetworkmanager) + +[NetworkManager 0.9 D-Bus Spec](https://developer.gnome.org/NetworkManager/0.9/spec.html) diff --git a/Settings.go b/Settings.go new file mode 100644 index 0000000..4b3df30 --- /dev/null +++ b/Settings.go @@ -0,0 +1,5 @@ +package gonetworkmanager + +const ( + SettingsInterface = NetworkManagerInterface + ".Settings" +) diff --git a/WirelessDevice.go b/WirelessDevice.go new file mode 100644 index 0000000..a712de0 --- /dev/null +++ b/WirelessDevice.go @@ -0,0 +1,47 @@ +package gonetworkmanager + +import ( + "github.com/godbus/dbus" +) + +const ( + WirelessDeviceInterface = DeviceInterface + ".Wireless" + + WirelessDeviceGetAccessPoints = WirelessDeviceInterface + ".GetAccessPoints" +) + +type WirelessDevice interface { + Device + + // GetAccessPoints gets the list of access points visible to this device. + // 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 +} + +func NewWirelessDevice(objectPath dbus.ObjectPath) (WirelessDevice, error) { + var d wirelessDevice + return &d, d.init(NetworkManagerInterface, objectPath) +} + +type wirelessDevice struct { + device +} + +func (d *wirelessDevice) GetAccessPoints() []AccessPoint { + var apPaths []dbus.ObjectPath + + d.call(&apPaths, WirelessDeviceGetAccessPoints) + aps := make([]AccessPoint, len(apPaths)) + + var err error + for i, path := range apPaths { + aps[i], err = NewAccessPoint(path) + if err != nil { + panic(err) + } + } + + return aps +} diff --git a/enums.go b/enums.go new file mode 100644 index 0000000..6bf3d3d --- /dev/null +++ b/enums.go @@ -0,0 +1,67 @@ +package gonetworkmanager + +//go:generate stringer -type=NmConnectivity +type NmConnectivity uint32 + +const ( + NmConnectivityUnknown NmConnectivity = 0 + NmConnectivityNone NmConnectivity = 1 + NmConnectivityPortal NmConnectivity = 2 + NmConnectivityLimited NmConnectivity = 3 + NmConnectivityFull NmConnectivity = 4 +) + +//go:generate stringer -type=NmState +type NmState uint32 + +const ( + NmStateUnknown NmState = 0 + NmStateAsleep NmState = 10 + NmStateDisconnected NmState = 20 + NmStateDisconnecting NmState = 30 + NmStateConnecting NmState = 40 + NmStateConnectedLocal NmState = 50 + NmStateConnectedSite NmState = 60 + NmStateConnectedGlobal NmState = 70 +) + +//go:generate stringer -type=NmDeviceState +type NmDeviceState uint32 + +const ( + NmDeviceStateUnknown NmDeviceState = 0 + NmDeviceStateUnmanaged NmDeviceState = 10 + NmDeviceStateUnavailable NmDeviceState = 20 + NmDeviceStateDisconnected NmDeviceState = 30 + NmDeviceStatePrepare NmDeviceState = 40 + NmDeviceStateConfig NmDeviceState = 50 + NmDeviceStateNeed_auth NmDeviceState = 60 + NmDeviceStateIp_config NmDeviceState = 70 + NmDeviceStateIp_check NmDeviceState = 80 + NmDeviceStateSecondaries NmDeviceState = 90 + NmDeviceStateActivated NmDeviceState = 100 + NmDeviceStateDeactivating NmDeviceState = 110 + NmDeviceStateFailed NmDeviceState = 120 +) + +//go:generate stringer -type=NmDeviceType +type NmDeviceType uint32 + +const ( + NmDeviceTypeUnknown NmDeviceType = 0 + NmDeviceTypeEthernet NmDeviceType = 1 + NmDeviceTypeWifi NmDeviceType = 2 + NmDeviceTypeUnused1 NmDeviceType = 3 + NmDeviceTypeUnused2 NmDeviceType = 4 + NmDeviceTypeBt NmDeviceType = 5 + NmDeviceTypeOlpcMesh NmDeviceType = 6 + NmDeviceTypeWimax NmDeviceType = 7 + NmDeviceTypeModem NmDeviceType = 8 + NmDeviceTypeInfiniband NmDeviceType = 9 + NmDeviceTypeBond NmDeviceType = 10 + NmDeviceTypeVlan NmDeviceType = 11 + NmDeviceTypeAdsl NmDeviceType = 12 + NmDeviceTypeBridge NmDeviceType = 13 + NmDeviceTypeGeneric NmDeviceType = 14 + NmDeviceTypeTeam NmDeviceType = 15 +) diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..990e6ad --- /dev/null +++ b/errors.go @@ -0,0 +1,9 @@ +package gonetworkmanager + +import ( + "errors" +) + +var ( + ErrVariantType = errors.New("unexpected variant type") +) diff --git a/nmconnectivity_string.go b/nmconnectivity_string.go new file mode 100644 index 0000000..c9bc0e1 --- /dev/null +++ b/nmconnectivity_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=NmConnectivity"; DO NOT EDIT + +package gonetworkmanager + +import "fmt" + +const _NmConnectivity_name = "NmConnectivityUnknownNmConnectivityNoneNmConnectivityPortalNmConnectivityLimitedNmConnectivityFull" + +var _NmConnectivity_index = [...]uint8{0, 21, 39, 59, 80, 98} + +func (i NmConnectivity) String() string { + if i >= NmConnectivity(len(_NmConnectivity_index)-1) { + return fmt.Sprintf("NmConnectivity(%d)", i) + } + return _NmConnectivity_name[_NmConnectivity_index[i]:_NmConnectivity_index[i+1]] +} diff --git a/nmdevicestate_string.go b/nmdevicestate_string.go new file mode 100644 index 0000000..c88842d --- /dev/null +++ b/nmdevicestate_string.go @@ -0,0 +1,30 @@ +// Code generated by "stringer -type=NmDeviceState"; DO NOT EDIT + +package gonetworkmanager + +import "fmt" + +const _NmDeviceState_name = "NmDeviceStateUnknownNmDeviceStateUnmanagedNmDeviceStateUnavailableNmDeviceStateDisconnectedNmDeviceStatePrepareNmDeviceStateConfigNmDeviceStateNeed_authNmDeviceStateIp_configNmDeviceStateIp_checkNmDeviceStateSecondariesNmDeviceStateActivatedNmDeviceStateDeactivatingNmDeviceStateFailed" + +var _NmDeviceState_map = map[NmDeviceState]string{ + 0: _NmDeviceState_name[0:20], + 10: _NmDeviceState_name[20:42], + 20: _NmDeviceState_name[42:66], + 30: _NmDeviceState_name[66:91], + 40: _NmDeviceState_name[91:111], + 50: _NmDeviceState_name[111:130], + 60: _NmDeviceState_name[130:152], + 70: _NmDeviceState_name[152:174], + 80: _NmDeviceState_name[174:195], + 90: _NmDeviceState_name[195:219], + 100: _NmDeviceState_name[219:241], + 110: _NmDeviceState_name[241:266], + 120: _NmDeviceState_name[266:285], +} + +func (i NmDeviceState) String() string { + if str, ok := _NmDeviceState_map[i]; ok { + return str + } + return fmt.Sprintf("NmDeviceState(%d)", i) +} diff --git a/nmdevicetype_string.go b/nmdevicetype_string.go new file mode 100644 index 0000000..af9645f --- /dev/null +++ b/nmdevicetype_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=NmDeviceType"; DO NOT EDIT + +package gonetworkmanager + +import "fmt" + +const _NmDeviceType_name = "NmDeviceTypeUnknownNmDeviceTypeEthernetNmDeviceTypeWifiNmDeviceTypeUnused1NmDeviceTypeUnused2NmDeviceTypeBtNmDeviceTypeOlpcMeshNmDeviceTypeWimaxNmDeviceTypeModemNmDeviceTypeInfinibandNmDeviceTypeBondNmDeviceTypeVlanNmDeviceTypeAdslNmDeviceTypeBridgeNmDeviceTypeGenericNmDeviceTypeTeam" + +var _NmDeviceType_index = [...]uint16{0, 19, 39, 55, 74, 93, 107, 127, 144, 161, 183, 199, 215, 231, 249, 268, 284} + +func (i NmDeviceType) String() string { + if i >= NmDeviceType(len(_NmDeviceType_index)-1) { + return fmt.Sprintf("NmDeviceType(%d)", i) + } + return _NmDeviceType_name[_NmDeviceType_index[i]:_NmDeviceType_index[i+1]] +} diff --git a/nmstate_string.go b/nmstate_string.go new file mode 100644 index 0000000..42c467a --- /dev/null +++ b/nmstate_string.go @@ -0,0 +1,50 @@ +// Code generated by "stringer -type=NmState"; DO NOT EDIT + +package gonetworkmanager + +import "fmt" + +const ( + _NmState_name_0 = "NmStateUnknown" + _NmState_name_1 = "NmStateAsleep" + _NmState_name_2 = "NmStateDisconnected" + _NmState_name_3 = "NmStateDisconnecting" + _NmState_name_4 = "NmStateConnecting" + _NmState_name_5 = "NmStateConnectedLocal" + _NmState_name_6 = "NmStateConnectedSite" + _NmState_name_7 = "NmStateConnectedGlobal" +) + +var ( + _NmState_index_0 = [...]uint8{0, 14} + _NmState_index_1 = [...]uint8{0, 13} + _NmState_index_2 = [...]uint8{0, 19} + _NmState_index_3 = [...]uint8{0, 20} + _NmState_index_4 = [...]uint8{0, 17} + _NmState_index_5 = [...]uint8{0, 21} + _NmState_index_6 = [...]uint8{0, 20} + _NmState_index_7 = [...]uint8{0, 22} +) + +func (i NmState) String() string { + switch { + case i == 0: + return _NmState_name_0 + case i == 10: + return _NmState_name_1 + case i == 20: + return _NmState_name_2 + case i == 30: + return _NmState_name_3 + case i == 40: + return _NmState_name_4 + case i == 50: + return _NmState_name_5 + case i == 60: + return _NmState_name_6 + case i == 70: + return _NmState_name_7 + default: + return fmt.Sprintf("NmState(%d)", i) + } +} diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..2f94979 --- /dev/null +++ b/utils.go @@ -0,0 +1,115 @@ +package gonetworkmanager + +import ( + "encoding/binary" + "net" + + "github.com/godbus/dbus" +) + +type dbusBase struct { + conn *dbus.Conn + obj dbus.BusObject +} + +func (d *dbusBase) init(iface string, objectPath dbus.ObjectPath) error { + var err error + + d.conn, err = dbus.SystemBus() + if err != nil { + return err + } + + d.obj = d.conn.Object(iface, objectPath) + + 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 { + return d.obj.Call(method, 0, args...).Store(value) +} + +func (d *dbusBase) getProperty(iface string) interface{} { + variant, err := d.obj.GetProperty(iface) + if err != nil { + panic(err) + } + return variant.Value() +} + +func (d *dbusBase) getObjectProperty(iface string) dbus.ObjectPath { + value, ok := d.getProperty(iface).(dbus.ObjectPath) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getSliceObjectProperty(iface string) []dbus.ObjectPath { + value, ok := d.getProperty(iface).([]dbus.ObjectPath) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getStringProperty(iface string) string { + value, ok := d.getProperty(iface).(string) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getSliceStringProperty(iface string) []string { + value, ok := d.getProperty(iface).([]string) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getUint32Property(iface string) uint32 { + value, ok := d.getProperty(iface).(uint32) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getSliceUint32Property(iface string) []uint32 { + value, ok := d.getProperty(iface).([]uint32) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getSliceSliceUint32Property(iface string) [][]uint32 { + value, ok := d.getProperty(iface).([][]uint32) + if !ok { + panic(ErrVariantType) + } + return value +} + +func (d *dbusBase) getSliceByteProperty(iface string) []byte { + value, ok := d.getProperty(iface).([]byte) + if !ok { + panic(ErrVariantType) + } + return value +} + +func ip4ToString(ip uint32) string { + bs := []byte{0, 0, 0, 0} + binary.LittleEndian.PutUint32(bs, ip) + return net.IP(bs).String() +}