2014-01-09 21:19:07 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
from gi.repository import GLib
|
2014-01-09 21:19:07 +00:00
|
|
|
import sys
|
|
|
|
import dbus
|
|
|
|
import dbus.service
|
|
|
|
import dbus.mainloop.glib
|
|
|
|
import random
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
mainloop = GLib.MainLoop()
|
2014-01-09 21:19:07 +00:00
|
|
|
|
|
|
|
# NM State
|
|
|
|
NM_STATE_UNKNOWN = 0
|
|
|
|
NM_STATE_ASLEEP = 10
|
|
|
|
NM_STATE_DISCONNECTED = 20
|
|
|
|
NM_STATE_DISCONNECTING = 30
|
|
|
|
NM_STATE_CONNECTING = 40
|
|
|
|
NM_STATE_CONNECTED_LOCAL = 50
|
|
|
|
NM_STATE_CONNECTED_SITE = 60
|
|
|
|
NM_STATE_CONNECTED_GLOBAL = 70
|
|
|
|
|
|
|
|
# Device state
|
|
|
|
NM_DEVICE_STATE_UNKNOWN = 0
|
|
|
|
NM_DEVICE_STATE_UNMANAGED = 10
|
|
|
|
NM_DEVICE_STATE_UNAVAILABLE = 20
|
|
|
|
NM_DEVICE_STATE_DISCONNECTED = 30
|
|
|
|
NM_DEVICE_STATE_PREPARE = 40
|
|
|
|
NM_DEVICE_STATE_CONFIG = 50
|
|
|
|
NM_DEVICE_STATE_NEED_AUTH = 60
|
|
|
|
NM_DEVICE_STATE_IP_CONFIG = 70
|
|
|
|
NM_DEVICE_STATE_IP_CHECK = 80
|
|
|
|
NM_DEVICE_STATE_SECONDARIES = 90
|
|
|
|
NM_DEVICE_STATE_ACTIVATED = 100
|
|
|
|
NM_DEVICE_STATE_DEACTIVATING = 110
|
|
|
|
NM_DEVICE_STATE_FAILED = 120
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
# Device type
|
2014-01-09 21:19:07 +00:00
|
|
|
NM_DEVICE_TYPE_UNKNOWN = 0
|
|
|
|
NM_DEVICE_TYPE_ETHERNET = 1
|
|
|
|
NM_DEVICE_TYPE_WIFI = 2
|
|
|
|
NM_DEVICE_TYPE_UNUSED1 = 3
|
|
|
|
NM_DEVICE_TYPE_UNUSED2 = 4
|
|
|
|
NM_DEVICE_TYPE_BT = 5
|
|
|
|
NM_DEVICE_TYPE_OLPC_MESH = 6
|
|
|
|
NM_DEVICE_TYPE_WIMAX = 7
|
|
|
|
NM_DEVICE_TYPE_MODEM = 8
|
|
|
|
NM_DEVICE_TYPE_INFINIBAND = 9
|
|
|
|
NM_DEVICE_TYPE_BOND = 10
|
|
|
|
NM_DEVICE_TYPE_VLAN = 11
|
|
|
|
NM_DEVICE_TYPE_ADSL = 12
|
|
|
|
NM_DEVICE_TYPE_BRIDGE = 13
|
|
|
|
NM_DEVICE_TYPE_GENERIC = 14
|
|
|
|
NM_DEVICE_TYPE_TEAM = 15
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
# AC state
|
|
|
|
NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0
|
|
|
|
NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
|
|
|
|
NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
|
|
|
|
NM_ACTIVE_CONNECTION_STATE_DEACTIVATING = 3
|
|
|
|
NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
#########################################################
|
|
|
|
IFACE_DBUS = 'org.freedesktop.DBus'
|
|
|
|
|
|
|
|
class UnknownInterfaceException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_DBUS + '.UnknownInterface'
|
|
|
|
|
|
|
|
class UnknownPropertyException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_DBUS + '.UnknownProperty'
|
|
|
|
|
|
|
|
def to_path_array(src):
|
|
|
|
array = dbus.Array([], signature=dbus.Signature('o'))
|
|
|
|
for o in src:
|
|
|
|
array.append(o.path)
|
|
|
|
return array
|
|
|
|
|
|
|
|
def to_path(src):
|
|
|
|
if src:
|
|
|
|
return dbus.ObjectPath(src.path)
|
|
|
|
return dbus.ObjectPath("/")
|
|
|
|
|
|
|
|
class ExportedObj(dbus.service.Object):
|
|
|
|
def __init__(self, bus, object_path):
|
|
|
|
dbus.service.Object.__init__(self, bus, object_path)
|
|
|
|
self._bus = bus
|
|
|
|
self.path = object_path
|
|
|
|
self.__dbus_ifaces = {}
|
|
|
|
|
|
|
|
def add_dbus_interface(self, dbus_iface, get_props_func):
|
|
|
|
self.__dbus_ifaces[dbus_iface] = get_props_func
|
|
|
|
|
|
|
|
def _get_dbus_properties(self, iface):
|
|
|
|
return self.__dbus_ifaces[iface]()
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
|
|
|
|
def GetAll(self, iface):
|
|
|
|
if iface not in self.__dbus_ifaces.keys():
|
|
|
|
raise UnknownInterfaceException()
|
|
|
|
return self._get_dbus_properties(iface)
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
|
|
|
|
def Get(self, iface, name):
|
|
|
|
if iface not in self.__dbus_ifaces.keys():
|
|
|
|
raise UnknownInterfaceException()
|
|
|
|
props = self._get_dbus_properties(iface)
|
|
|
|
if not name in props.keys():
|
|
|
|
raise UnknownPropertyException()
|
|
|
|
return props[name]
|
|
|
|
|
|
|
|
###################################################################
|
|
|
|
IFACE_DEVICE = 'org.freedesktop.NetworkManager.Device'
|
|
|
|
|
|
|
|
PD_UDI = "Udi"
|
|
|
|
PD_IFACE = "Interface"
|
|
|
|
PD_DRIVER = "Driver"
|
|
|
|
PD_STATE = "State"
|
|
|
|
PD_ACTIVE_CONNECTION = "ActiveConnection"
|
|
|
|
PD_IP4_CONFIG = "Ip4Config"
|
|
|
|
PD_IP6_CONFIG = "Ip6Config"
|
|
|
|
PD_DHCP4_CONFIG = "Dhcp4Config"
|
|
|
|
PD_DHCP6_CONFIG = "Dhcp6Config"
|
|
|
|
PD_MANAGED = "Managed"
|
|
|
|
PD_AUTOCONNECT = "Autoconnect"
|
|
|
|
PD_DEVICE_TYPE = "DeviceType"
|
|
|
|
PD_AVAILABLE_CONNECTIONS = "AvailableConnections"
|
|
|
|
|
|
|
|
class Device(ExportedObj):
|
|
|
|
counter = 1
|
|
|
|
|
|
|
|
def __init__(self, bus, iface, devtype):
|
|
|
|
object_path = "/org/freedesktop/NetworkManager/Devices/%d" % Device.counter
|
|
|
|
Device.counter = Device.counter + 1
|
|
|
|
ExportedObj.__init__(self, bus, object_path)
|
|
|
|
self.add_dbus_interface(IFACE_DEVICE, self.__get_props)
|
|
|
|
|
|
|
|
self.iface = iface
|
|
|
|
self.udi = "/sys/devices/virtual/%s" % iface
|
|
|
|
self.devtype = devtype
|
|
|
|
self.active_connection = None
|
|
|
|
self.state = NM_DEVICE_STATE_UNAVAILABLE
|
|
|
|
self.ip4_config = None
|
|
|
|
self.ip6_config = None
|
|
|
|
self.dhcp4_config = None
|
|
|
|
self.dhcp6_config = None
|
|
|
|
self.available_connections = []
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PD_UDI] = self.udi
|
|
|
|
props[PD_IFACE] = self.iface
|
|
|
|
props[PD_DRIVER] = "virtual"
|
|
|
|
props[PD_STATE] = dbus.UInt32(self.state)
|
|
|
|
props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection)
|
|
|
|
props[PD_IP4_CONFIG] = to_path(self.ip4_config)
|
|
|
|
props[PD_IP6_CONFIG] = to_path(self.ip6_config)
|
|
|
|
props[PD_DHCP4_CONFIG] = to_path(self.dhcp4_config)
|
|
|
|
props[PD_DHCP6_CONFIG] = to_path(self.dhcp6_config)
|
|
|
|
props[PD_MANAGED] = True
|
|
|
|
props[PD_AUTOCONNECT] = True
|
|
|
|
props[PD_DEVICE_TYPE] = dbus.UInt32(self.devtype)
|
|
|
|
props[PD_AVAILABLE_CONNECTIONS] = to_path_array(self.available_connections)
|
|
|
|
return props
|
|
|
|
|
|
|
|
# methods
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='')
|
|
|
|
def Disconnect(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_DEVICE)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
Device.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_DEVICE, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
def set_active_connection(self, ac):
|
|
|
|
self.active_connection = ac
|
|
|
|
self.__notify(PD_ACTIVE_CONNECTION)
|
2014-01-09 21:19:07 +00:00
|
|
|
|
|
|
|
###################################################################
|
|
|
|
|
|
|
|
def random_mac():
|
|
|
|
return '%02X:%02X:%02X:%02X:%02X:%02X' % (
|
|
|
|
random.randint(0, 255), random.randint(0, 255), random.randint(0, 255),
|
|
|
|
random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
|
|
|
|
)
|
|
|
|
|
|
|
|
###################################################################
|
|
|
|
IFACE_WIRED = 'org.freedesktop.NetworkManager.Device.Wired'
|
|
|
|
|
|
|
|
PE_HW_ADDRESS = "HwAddress"
|
|
|
|
PE_PERM_HW_ADDRESS = "PermHwAddress"
|
|
|
|
PE_SPEED = "Speed"
|
|
|
|
PE_CARRIER = "Carrier"
|
|
|
|
|
|
|
|
class WiredDevice(Device):
|
|
|
|
def __init__(self, bus, iface):
|
|
|
|
Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET)
|
|
|
|
self.add_dbus_interface(IFACE_WIRED, self.__get_props)
|
|
|
|
|
|
|
|
self.mac = random_mac()
|
|
|
|
self.carrier = False
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PE_HW_ADDRESS] = self.mac
|
|
|
|
props[PE_PERM_HW_ADDRESS] = self.mac
|
|
|
|
props[PE_SPEED] = dbus.UInt32(100)
|
|
|
|
props[PE_CARRIER] = self.carrier
|
|
|
|
return props
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_WIRED)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
WiredDevice.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIRED, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
2014-10-08 22:15:23 +00:00
|
|
|
###################################################################
|
|
|
|
IFACE_VLAN = 'org.freedesktop.NetworkManager.Device.Vlan'
|
|
|
|
|
|
|
|
PV_HW_ADDRESS = "HwAddress"
|
|
|
|
PV_CARRIER = "Carrier"
|
|
|
|
PV_VLAN_ID = "VlanId"
|
|
|
|
|
|
|
|
class VlanDevice(Device):
|
|
|
|
def __init__(self, bus, iface):
|
|
|
|
Device.__init__(self, bus, iface, NM_DEVICE_TYPE_VLAN)
|
|
|
|
self.add_dbus_interface(IFACE_VLAN, self.__get_props)
|
|
|
|
|
|
|
|
self.mac = random_mac()
|
|
|
|
self.carrier = False
|
|
|
|
self.vlan_id = 1
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PV_HW_ADDRESS] = self.mac
|
|
|
|
props[PV_CARRIER] = self.carrier
|
|
|
|
props[PV_VLAN_ID] = self.vlan_id
|
|
|
|
return props
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_VLAN, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
###################################################################
|
|
|
|
IFACE_WIFI_AP = 'org.freedesktop.NetworkManager.AccessPoint'
|
|
|
|
|
|
|
|
PP_FLAGS = "Flags"
|
|
|
|
PP_WPA_FLAGS = "WpaFlags"
|
|
|
|
PP_RSN_FLAGS = "RsnFlags"
|
|
|
|
PP_SSID = "Ssid"
|
|
|
|
PP_FREQUENCY = "Frequency"
|
|
|
|
PP_HW_ADDRESS = "HwAddress"
|
|
|
|
PP_MODE = "Mode"
|
|
|
|
PP_MAX_BITRATE = "MaxBitrate"
|
|
|
|
PP_STRENGTH = "Strength"
|
|
|
|
|
|
|
|
class WifiAp(ExportedObj):
|
|
|
|
counter = 0
|
|
|
|
|
|
|
|
def __init__(self, bus, ssid, mac, flags, wpaf, rsnf, freq):
|
|
|
|
path = "/org/freedesktop/NetworkManager/AccessPoint/%d" % WifiAp.counter
|
|
|
|
WifiAp.counter = WifiAp.counter + 1
|
|
|
|
ExportedObj.__init__(self, bus, path)
|
|
|
|
self.add_dbus_interface(IFACE_WIFI_AP, self.__get_props)
|
|
|
|
|
|
|
|
self.ssid = ssid
|
|
|
|
if mac:
|
|
|
|
self.bssid = mac
|
|
|
|
else:
|
|
|
|
self.bssid = random_mac()
|
|
|
|
self.flags = flags
|
|
|
|
self.wpaf = wpaf
|
|
|
|
self.rsnf = rsnf
|
|
|
|
self.freq = freq
|
|
|
|
self.strength = random.randint(0, 100)
|
|
|
|
self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None)
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
if self.strength_id > 0:
|
|
|
|
GLib.source_remove(self.strength_id)
|
|
|
|
self.strength_id = 0
|
|
|
|
|
|
|
|
def strength_cb(self, ignored):
|
|
|
|
self.strength = random.randint(0, 100)
|
|
|
|
self.__notify(PP_STRENGTH)
|
|
|
|
return True
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PP_FLAGS] = dbus.UInt32(self.flags)
|
|
|
|
props[PP_WPA_FLAGS] = dbus.UInt32(self.wpaf)
|
|
|
|
props[PP_RSN_FLAGS] = dbus.UInt32(self.rsnf)
|
|
|
|
props[PP_SSID] = dbus.ByteArray(self.ssid)
|
|
|
|
props[PP_FREQUENCY] = dbus.UInt32(self.freq)
|
|
|
|
props[PP_HW_ADDRESS] = self.bssid
|
|
|
|
props[PP_MODE] = dbus.UInt32(2) # NM_802_11_MODE_INFRA
|
|
|
|
props[PP_MAX_BITRATE] = dbus.UInt32(54000)
|
|
|
|
props[PP_STRENGTH] = dbus.Byte(self.strength)
|
|
|
|
return props
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_WIFI_AP)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
WifiAp.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIFI_AP, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
|
|
|
###################################################################
|
|
|
|
IFACE_WIFI = 'org.freedesktop.NetworkManager.Device.Wireless'
|
|
|
|
|
|
|
|
class ApNotFoundException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_WIFI + '.AccessPointNotFound'
|
|
|
|
|
|
|
|
PW_HW_ADDRESS = "HwAddress"
|
|
|
|
PW_PERM_HW_ADDRESS = "PermHwAddress"
|
|
|
|
PW_MODE = "Mode"
|
|
|
|
PW_BITRATE = "Bitrate"
|
|
|
|
PW_ACCESS_POINTS = "AccessPoints"
|
|
|
|
PW_ACTIVE_ACCESS_POINT = "ActiveAccessPoint"
|
|
|
|
PW_WIRELESS_CAPABILITIES = "WirelessCapabilities"
|
|
|
|
|
|
|
|
class WifiDevice(Device):
|
|
|
|
def __init__(self, bus, iface):
|
|
|
|
Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIFI)
|
|
|
|
self.add_dbus_interface(IFACE_WIFI, self.__get_props)
|
|
|
|
|
|
|
|
self.mac = random_mac()
|
|
|
|
self.aps = []
|
|
|
|
self.active_ap = None
|
|
|
|
|
|
|
|
# methods
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao')
|
|
|
|
def GetAccessPoints(self):
|
|
|
|
# only include non-hidden APs
|
|
|
|
array = []
|
|
|
|
for a in self.aps:
|
|
|
|
if a.ssid():
|
|
|
|
array.append(a)
|
|
|
|
return to_path_array(array)
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao')
|
|
|
|
def GetAllAccessPoints(self):
|
|
|
|
# include all APs including hidden ones
|
|
|
|
return to_path_array(self.aps)
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='a{sv}', out_signature='')
|
|
|
|
def RequestScan(self, props):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIFI, signature='o')
|
|
|
|
def AccessPointAdded(self, ap_path):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def add_ap(self, ap):
|
|
|
|
self.aps.append(ap)
|
|
|
|
self.__notify(PW_ACCESS_POINTS)
|
|
|
|
self.AccessPointAdded(to_path(ap))
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIFI, signature='o')
|
|
|
|
def AccessPointRemoved(self, ap_path):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def remove_ap(self, ap):
|
|
|
|
self.aps.remove(ap)
|
|
|
|
self.__notify(PW_ACCESS_POINTS)
|
|
|
|
self.AccessPointRemoved(to_path(ap))
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PW_HW_ADDRESS] = self.mac
|
|
|
|
props[PW_PERM_HW_ADDRESS] = self.mac
|
|
|
|
props[PW_MODE] = dbus.UInt32(3) # NM_802_11_MODE_INFRA
|
|
|
|
props[PW_BITRATE] = dbus.UInt32(21000)
|
|
|
|
props[PW_WIRELESS_CAPABILITIES] = dbus.UInt32(0xFF)
|
|
|
|
props[PW_ACCESS_POINTS] = to_path_array(self.aps)
|
|
|
|
props[PW_ACTIVE_ACCESS_POINT] = to_path(self.active_ap)
|
|
|
|
return props
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_WIFI)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
WifiDevice.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIFI, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
|
|
|
# test functions
|
|
|
|
def add_test_ap(self, ssid, mac):
|
|
|
|
ap = WifiAp(self._bus, ssid, mac, 0x1, 0x1cc, 0x1cc, 2412)
|
|
|
|
self.add_ap(ap)
|
|
|
|
return ap.path
|
|
|
|
|
|
|
|
def remove_ap_by_path(self, path):
|
|
|
|
for ap in self.aps:
|
|
|
|
if ap.path == path:
|
|
|
|
self.remove_ap(ap)
|
|
|
|
return
|
|
|
|
raise ApNotFoundException("AP %s not found" % path)
|
|
|
|
|
|
|
|
|
|
|
|
###################################################################
|
|
|
|
IFACE_WIMAX_NSP = 'org.freedesktop.NetworkManager.WiMax.Nsp'
|
|
|
|
|
|
|
|
PN_NAME = "Name"
|
|
|
|
PN_SIGNAL_QUALITY = "SignalQuality"
|
|
|
|
PN_NETWORK_TYPE = "NetworkType"
|
|
|
|
|
|
|
|
class WimaxNsp(ExportedObj):
|
|
|
|
counter = 0
|
|
|
|
|
|
|
|
def __init__(self, bus, name):
|
|
|
|
path = "/org/freedesktop/NetworkManager/Nsp/%d" % WimaxNsp.counter
|
|
|
|
WimaxNsp.counter = WimaxNsp.counter + 1
|
|
|
|
ExportedObj.__init__(self, bus, path)
|
|
|
|
self.add_dbus_interface(IFACE_WIMAX_NSP, self.__get_props)
|
|
|
|
|
|
|
|
self.name = name
|
|
|
|
self.strength = random.randint(0, 100)
|
|
|
|
self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None)
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
if self.strength_id > 0:
|
|
|
|
GLib.source_remove(self.strength_id)
|
|
|
|
self.strength_id = 0
|
|
|
|
|
|
|
|
def strength_cb(self, ignored):
|
|
|
|
self.strength = random.randint(0, 100)
|
|
|
|
self.__notify(PN_SIGNAL_QUALITY)
|
|
|
|
return True
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PN_NAME] = self.name
|
|
|
|
props[PN_SIGNAL_QUALITY] = dbus.UInt32(self.strength)
|
|
|
|
props[PN_NETWORK_TYPE] = dbus.UInt32(0x1) # NM_WIMAX_NSP_NETWORK_TYPE_HOME
|
|
|
|
return props
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_WIMAX_NSP)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
WimaxNsp.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIMAX_NSP, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
|
|
|
###################################################################
|
|
|
|
IFACE_WIMAX = 'org.freedesktop.NetworkManager.Device.WiMax'
|
|
|
|
|
|
|
|
class NspNotFoundException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_WIMAX + '.NspNotFound'
|
|
|
|
|
|
|
|
PX_NSPS = "Nsps"
|
|
|
|
PX_HW_ADDRESS = "HwAddress"
|
|
|
|
PX_CENTER_FREQUENCY = "CenterFrequency"
|
|
|
|
PX_RSSI = "Rssi"
|
|
|
|
PX_CINR = "Cinr"
|
|
|
|
PX_TX_POWER = "TxPower"
|
|
|
|
PX_BSID = "Bsid"
|
|
|
|
PX_ACTIVE_NSP = "ActiveNsp"
|
|
|
|
|
|
|
|
class WimaxDevice(Device):
|
|
|
|
def __init__(self, bus, iface):
|
|
|
|
Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIMAX)
|
|
|
|
self.add_dbus_interface(IFACE_WIMAX, self.__get_props)
|
|
|
|
|
|
|
|
self.mac = random_mac()
|
|
|
|
self.bsid = random_mac()
|
|
|
|
self.nsps = []
|
|
|
|
self.active_nsp = None
|
|
|
|
|
|
|
|
# methods
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_WIMAX, in_signature='', out_signature='ao')
|
|
|
|
def GetNspList(self):
|
|
|
|
# include all APs including hidden ones
|
|
|
|
return to_path_array(self.nsps)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIMAX, signature='o')
|
|
|
|
def NspAdded(self, nsp_path):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def add_nsp(self, nsp):
|
|
|
|
self.nsps.append(nsp)
|
|
|
|
self.__notify(PX_NSPS)
|
|
|
|
self.NspAdded(to_path(nsp))
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIMAX, signature='o')
|
|
|
|
def NspRemoved(self, nsp_path):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def remove_nsp(self, nsp):
|
|
|
|
self.nsps.remove(nsp)
|
|
|
|
self.__notify(PX_NSPS)
|
|
|
|
self.NspRemoved(to_path(nsp))
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PX_HW_ADDRESS] = self.mac
|
|
|
|
props[PX_CENTER_FREQUENCY] = dbus.UInt32(2525)
|
|
|
|
props[PX_RSSI] = dbus.Int32(-48)
|
|
|
|
props[PX_CINR] = dbus.Int32(24)
|
|
|
|
props[PX_TX_POWER] = dbus.Int32(9)
|
|
|
|
props[PX_BSID] = self.bsid
|
|
|
|
props[PX_NSPS] = to_path_array(self.nsps)
|
|
|
|
props[PX_ACTIVE_NSP] = to_path(self.active_nsp)
|
|
|
|
return props
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_WIMAX)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
WimaxDevice.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_WIMAX, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
|
|
|
# test functions
|
|
|
|
def add_test_nsp(self, name):
|
|
|
|
nsp = WimaxNsp(self._bus, name)
|
|
|
|
self.add_nsp(nsp)
|
|
|
|
return nsp.path
|
|
|
|
|
|
|
|
def remove_nsp_by_path(self, path):
|
|
|
|
for nsp in self.nsps:
|
|
|
|
if nsp.path == path:
|
|
|
|
self.remove_nsp(nsp)
|
|
|
|
return
|
|
|
|
raise NspNotFoundException("NSP %s not found" % path)
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
###################################################################
|
|
|
|
IFACE_ACTIVE_CONNECTION = 'org.freedesktop.NetworkManager.Connection.Active'
|
|
|
|
|
|
|
|
PAC_CONNECTION = "Connection"
|
|
|
|
PAC_SPECIFIC_OBJECT = "SpecificObject"
|
|
|
|
PAC_ID = "Id"
|
|
|
|
PAC_UUID = "Uuid"
|
|
|
|
PAC_TYPE = "Type"
|
|
|
|
PAC_DEVICES = "Devices"
|
|
|
|
PAC_STATE = "State"
|
|
|
|
PAC_DEFAULT = "Default"
|
|
|
|
PAC_IP4CONFIG = "Ip4Config"
|
|
|
|
PAC_DHCP4CONFIG = "Dhcp4Config"
|
|
|
|
PAC_DEFAULT6 = "Default6"
|
|
|
|
PAC_IP6CONFIG = "Ip6Config"
|
|
|
|
PAC_DHCP6CONFIG = "Dhcp6Config"
|
|
|
|
PAC_VPN = "Vpn"
|
|
|
|
PAC_MASTER = "Master"
|
|
|
|
|
|
|
|
class ActiveConnection(ExportedObj):
|
|
|
|
counter = 1
|
|
|
|
|
|
|
|
def __init__(self, bus, device, connection, specific_object):
|
|
|
|
object_path = "/org/freedesktop/NetworkManager/ActiveConnection/%d" % ActiveConnection.counter
|
|
|
|
ActiveConnection.counter = ActiveConnection.counter + 1
|
|
|
|
ExportedObj.__init__(self, bus, object_path)
|
|
|
|
self.add_dbus_interface(IFACE_ACTIVE_CONNECTION, self.__get_props)
|
|
|
|
|
|
|
|
self.device = device
|
|
|
|
self.conn = connection
|
|
|
|
self.specific_object = specific_object
|
|
|
|
self.state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN
|
|
|
|
self.default = False
|
|
|
|
self.ip4config = None
|
|
|
|
self.dhcp4config = None
|
|
|
|
self.default6 = False
|
|
|
|
self.ip6config = None
|
|
|
|
self.dhcp6config = None
|
|
|
|
self.vpn = False
|
|
|
|
self.master = None
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PAC_CONNECTION] = to_path(self.conn)
|
|
|
|
props[PAC_SPECIFIC_OBJECT] = to_path(self.specific_object)
|
|
|
|
conn_settings = self.conn.GetSettings()
|
|
|
|
s_con = conn_settings['connection']
|
|
|
|
props[PAC_ID] = s_con['id']
|
|
|
|
props[PAC_UUID] = s_con['uuid']
|
|
|
|
props[PAC_TYPE] = s_con['type']
|
|
|
|
props[PAC_DEVICES] = to_path_array([self.device])
|
|
|
|
props[PAC_STATE] = dbus.UInt32(self.state)
|
|
|
|
props[PAC_DEFAULT] = self.default
|
|
|
|
props[PAC_IP4CONFIG] = to_path(self.ip4config)
|
|
|
|
props[PAC_DHCP4CONFIG] = to_path(self.dhcp4config)
|
|
|
|
props[PAC_DEFAULT6] = self.default6
|
|
|
|
props[PAC_IP6CONFIG] = to_path(self.ip6config)
|
|
|
|
props[PAC_DHCP6CONFIG] = to_path(self.dhcp6config)
|
|
|
|
props[PAC_VPN] = self.vpn
|
|
|
|
props[PAC_MASTER] = to_path(self.master)
|
|
|
|
return props
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_ACTIVE_CONNECTION, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
###################################################################
|
|
|
|
IFACE_TEST = 'org.freedesktop.NetworkManager.LibnmGlibTest'
|
|
|
|
IFACE_NM = 'org.freedesktop.NetworkManager'
|
|
|
|
|
|
|
|
class PermissionDeniedException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_NM + '.PermissionDenied'
|
|
|
|
|
|
|
|
class UnknownDeviceException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_NM + '.UnknownDevice'
|
|
|
|
|
2014-08-29 16:27:47 +00:00
|
|
|
class UnknownConnectionException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_NM + '.UnknownConnection'
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
PM_DEVICES = 'Devices'
|
|
|
|
PM_NETWORKING_ENABLED = 'NetworkingEnabled'
|
|
|
|
PM_WWAN_ENABLED = 'WwanEnabled'
|
|
|
|
PM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled'
|
|
|
|
PM_WIRELESS_ENABLED = 'WirelessEnabled'
|
|
|
|
PM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled'
|
|
|
|
PM_WIMAX_ENABLED = 'WimaxEnabled'
|
|
|
|
PM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled'
|
|
|
|
PM_ACTIVE_CONNECTIONS = 'ActiveConnections'
|
|
|
|
PM_PRIMARY_CONNECTION = 'PrimaryConnection'
|
|
|
|
PM_ACTIVATING_CONNECTION = 'ActivatingConnection'
|
|
|
|
PM_STARTUP = 'Startup'
|
|
|
|
PM_STATE = 'State'
|
|
|
|
PM_VERSION = 'Version'
|
|
|
|
PM_CONNECTIVITY = 'Connectivity'
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
def set_device_ac_cb(device, ac):
|
|
|
|
device.set_active_connection(ac)
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
class NetworkManager(ExportedObj):
|
|
|
|
def __init__(self, bus, object_path):
|
|
|
|
ExportedObj.__init__(self, bus, object_path)
|
|
|
|
self.add_dbus_interface(IFACE_NM, self.__get_props)
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
self._bus = bus;
|
2014-01-09 21:19:07 +00:00
|
|
|
self.devices = []
|
|
|
|
self.active_connections = []
|
|
|
|
self.primary_connection = None
|
|
|
|
self.activating_connection = None
|
|
|
|
self.state = NM_STATE_DISCONNECTED
|
|
|
|
self.connectivity = 1
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_NM, signature='u')
|
|
|
|
def StateChanged(self, new_state):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def set_state(self, new_state):
|
|
|
|
self.state = new_state
|
|
|
|
self.__notify(PM_STATE)
|
|
|
|
self.StateChanged(dbus.UInt32(self.state))
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao')
|
|
|
|
def GetDevices(self):
|
|
|
|
return self._get_dbus_properties(IFACE_NM)[PM_DEVICES]
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='s', out_signature='o')
|
|
|
|
def GetDeviceByIpIface(self, ip_iface):
|
|
|
|
for d in self.devices:
|
|
|
|
# ignore iface/ip_iface distinction for now
|
|
|
|
if d.iface == ip_iface:
|
|
|
|
return d.path
|
|
|
|
raise UnknownDeviceException("No device found for the requested iface.")
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='ooo', out_signature='o')
|
|
|
|
def ActivateConnection(self, conpath, devpath, specific_object):
|
2014-10-08 22:15:23 +00:00
|
|
|
try:
|
|
|
|
connection = settings.get_connection(conpath)
|
|
|
|
except Exception as e:
|
|
|
|
raise UnknownConnectionException("Connection not found")
|
|
|
|
|
|
|
|
hash = connection.GetSettings()
|
|
|
|
s_con = hash['connection']
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
device = None
|
|
|
|
for d in self.devices:
|
|
|
|
if d.path == devpath:
|
|
|
|
device = d
|
|
|
|
break
|
2014-10-08 22:15:23 +00:00
|
|
|
if not device and s_con['type'] == 'vlan':
|
|
|
|
ifname = s_con['interface-name']
|
|
|
|
device = VlanDevice(self._bus, ifname)
|
|
|
|
self.add_device(device)
|
2014-01-09 21:19:07 +00:00
|
|
|
if not device:
|
|
|
|
raise UnknownDeviceException("No device found for the requested iface.")
|
2014-08-29 16:27:47 +00:00
|
|
|
|
|
|
|
# See if we need secrets. For the moment, we only support WPA
|
|
|
|
if hash.has_key('802-11-wireless-security'):
|
|
|
|
s_wsec = hash['802-11-wireless-security']
|
|
|
|
if (s_wsec['key-mgmt'] == 'wpa-psk' and not s_wsec.has_key('psk')):
|
|
|
|
secrets = agent_manager.get_secrets(hash, conpath, '802-11-wireless-security')
|
|
|
|
if secrets is None:
|
|
|
|
raise NoSecretsException("No secret agent available")
|
|
|
|
if not secrets.has_key('802-11-wireless-security'):
|
|
|
|
raise NoSecretsException("No secrets provided")
|
|
|
|
s_wsec = secrets['802-11-wireless-security']
|
|
|
|
if not s_wsec.has_key('psk'):
|
|
|
|
raise NoSecretsException("No secrets provided")
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
ac = ActiveConnection(self._bus, device, connection, None)
|
|
|
|
self.active_connections.append(ac)
|
|
|
|
self.__notify(PM_ACTIVE_CONNECTIONS)
|
2014-10-10 21:10:28 +00:00
|
|
|
|
|
|
|
if s_con['id'] == 'object-creation-failed-test':
|
|
|
|
self.active_connections.remove(ac)
|
|
|
|
ac.remove_from_connection()
|
|
|
|
else:
|
|
|
|
GLib.timeout_add(50, set_device_ac_cb, device, ac)
|
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
return to_path(ac)
|
2014-01-09 21:19:07 +00:00
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo')
|
|
|
|
def AddAndActivateConnection(self, connection, devpath, specific_object):
|
|
|
|
device = None
|
|
|
|
for d in self.devices:
|
|
|
|
if d.path == devpath:
|
|
|
|
device = d
|
|
|
|
break
|
|
|
|
if not device:
|
|
|
|
raise UnknownDeviceException("No device found for the requested iface.")
|
2014-08-29 16:27:47 +00:00
|
|
|
|
2014-10-06 17:35:03 +00:00
|
|
|
conpath = settings.AddConnection(connection)
|
|
|
|
return (conpath, self.ActivateConnection(conpath, devpath, specific_object))
|
2014-01-09 21:19:07 +00:00
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='')
|
|
|
|
def DeactivateConnection(self, active_connection):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='')
|
|
|
|
def Sleep(self, do_sleep):
|
|
|
|
if do_sleep:
|
|
|
|
self.state = NM_STATE_ASLEEP
|
|
|
|
else:
|
|
|
|
self.state = NM_STATE_DISCONNECTED
|
|
|
|
self.__notify(PM_STATE)
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='')
|
|
|
|
def Enable(self, do_enable):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='a{ss}')
|
|
|
|
def GetPermissions(self):
|
|
|
|
return { "org.freedesktop.NetworkManager.enable-disable-network": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.sleep-wake": "no",
|
|
|
|
"org.freedesktop.NetworkManager.enable-disable-wifi": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.enable-disable-wwan": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.enable-disable-wimax": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.network-control": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.wifi.share.protected": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.wifi.share.open": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.settings.modify.own": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.settings.modify.system": "yes",
|
|
|
|
"org.freedesktop.NetworkManager.settings.modify.hostname": "yes" }
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='ss', out_signature='')
|
|
|
|
def SetLogging(self, level, domains):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ss')
|
|
|
|
def GetLogging(self):
|
|
|
|
return ("info", "HW,RFKILL,CORE,DEVICE,WIFI,ETHER")
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='u')
|
|
|
|
def CheckConnectivity(self):
|
|
|
|
raise PermissionDeniedException("You fail")
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_NM, signature='o')
|
|
|
|
def DeviceAdded(self, devpath):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def add_device(self, device):
|
|
|
|
self.devices.append(device)
|
|
|
|
self.__notify(PM_DEVICES)
|
|
|
|
self.DeviceAdded(to_path(device))
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_NM, signature='o')
|
|
|
|
def DeviceRemoved(self, devpath):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def remove_device(self, device):
|
|
|
|
self.devices.remove(device)
|
|
|
|
self.__notify(PM_DEVICES)
|
|
|
|
self.DeviceRemoved(to_path(device))
|
|
|
|
|
|
|
|
################# D-Bus Properties interface
|
|
|
|
def __get_props(self):
|
|
|
|
props = {}
|
|
|
|
props[PM_DEVICES] = to_path_array(self.devices)
|
|
|
|
props[PM_NETWORKING_ENABLED] = True
|
|
|
|
props[PM_WWAN_ENABLED] = True
|
|
|
|
props[PM_WWAN_HARDWARE_ENABLED] = True
|
|
|
|
props[PM_WIRELESS_ENABLED] = True
|
|
|
|
props[PM_WIRELESS_HARDWARE_ENABLED] = True
|
|
|
|
props[PM_WIMAX_ENABLED] = True
|
|
|
|
props[PM_WIMAX_HARDWARE_ENABLED] = True
|
|
|
|
props[PM_ACTIVE_CONNECTIONS] = to_path_array(self.active_connections)
|
|
|
|
props[PM_PRIMARY_CONNECTION] = to_path(self.primary_connection)
|
|
|
|
props[PM_ACTIVATING_CONNECTION] = to_path(self.activating_connection)
|
|
|
|
props[PM_STARTUP] = False
|
|
|
|
props[PM_STATE] = dbus.UInt32(self.state)
|
|
|
|
props[PM_VERSION] = "0.9.9.0"
|
|
|
|
props[PM_CONNECTIVITY] = dbus.UInt32(self.connectivity)
|
|
|
|
return props
|
|
|
|
|
|
|
|
def __notify(self, propname):
|
|
|
|
props = self._get_dbus_properties(IFACE_NM)
|
|
|
|
changed = { propname: props[propname] }
|
|
|
|
NetworkManager.PropertiesChanged(self, changed)
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_NM, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, changed):
|
|
|
|
pass
|
|
|
|
|
|
|
|
################# Testing methods
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='', out_signature='')
|
|
|
|
def Quit(self):
|
|
|
|
mainloop.quit()
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
|
|
|
|
def AddWiredDevice(self, ifname):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
2014-07-22 22:22:23 +00:00
|
|
|
raise PermissionDeniedException("Device already added")
|
2014-01-09 21:19:07 +00:00
|
|
|
dev = WiredDevice(self._bus, ifname)
|
|
|
|
self.add_device(dev)
|
|
|
|
return dbus.ObjectPath(dev.path)
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
|
|
|
|
def AddWifiDevice(self, ifname):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
2014-07-22 22:22:23 +00:00
|
|
|
raise PermissionDeniedException("Device already added")
|
2014-01-09 21:19:07 +00:00
|
|
|
dev = WifiDevice(self._bus, ifname)
|
|
|
|
self.add_device(dev)
|
|
|
|
return dbus.ObjectPath(dev.path)
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
|
|
|
|
def AddWimaxDevice(self, ifname):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
2014-07-22 22:22:23 +00:00
|
|
|
raise PermissionDeniedException("Device already added")
|
2014-01-09 21:19:07 +00:00
|
|
|
dev = WimaxDevice(self._bus, ifname)
|
|
|
|
self.add_device(dev)
|
|
|
|
return dbus.ObjectPath(dev.path)
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='o', out_signature='')
|
|
|
|
def RemoveDevice(self, path):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.path == path:
|
|
|
|
self.remove_device(d)
|
|
|
|
return
|
|
|
|
raise UnknownDeviceException("Device not found")
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='sss', out_signature='o')
|
|
|
|
def AddWifiAp(self, ifname, ssid, mac):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
|
|
|
return dbus.ObjectPath(d.add_test_ap(ssid, mac))
|
|
|
|
raise UnknownDeviceException("Device not found")
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='so', out_signature='')
|
|
|
|
def RemoveWifiAp(self, ifname, ap_path):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
|
|
|
d.remove_ap_by_path(ap_path)
|
|
|
|
return
|
|
|
|
raise UnknownDeviceException("Device not found")
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='ss', out_signature='o')
|
|
|
|
def AddWimaxNsp(self, ifname, name):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
|
|
|
return dbus.ObjectPath(d.add_test_nsp(name))
|
|
|
|
raise UnknownDeviceException("Device not found")
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='so', out_signature='')
|
|
|
|
def RemoveWimaxNsp(self, ifname, nsp_path):
|
|
|
|
for d in self.devices:
|
|
|
|
if d.iface == ifname:
|
|
|
|
d.remove_nsp_by_path(nsp_path)
|
|
|
|
return
|
|
|
|
raise UnknownDeviceException("Device not found")
|
|
|
|
|
2014-08-06 22:07:42 +00:00
|
|
|
@dbus.service.method(IFACE_TEST, in_signature='', out_signature='')
|
|
|
|
def AutoRemoveNextConnection(self):
|
|
|
|
settings.auto_remove_next_connection()
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
###################################################################
|
|
|
|
IFACE_CONNECTION = 'org.freedesktop.NetworkManager.Settings.Connection'
|
|
|
|
|
2014-10-15 18:55:41 +00:00
|
|
|
class InvalidPropertyException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_CONNECTION + '.InvalidProperty'
|
|
|
|
|
|
|
|
class MissingPropertyException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_CONNECTION + '.MissingProperty'
|
|
|
|
|
|
|
|
class InvalidSettingException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_CONNECTION + '.InvalidSetting'
|
|
|
|
|
|
|
|
class MissingSettingException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_CONNECTION + '.MissingSetting'
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
class Connection(dbus.service.Object):
|
|
|
|
def __init__(self, bus, object_path, settings, remove_func):
|
|
|
|
dbus.service.Object.__init__(self, bus, object_path)
|
2014-10-15 18:55:41 +00:00
|
|
|
|
|
|
|
if not settings.has_key('connection'):
|
|
|
|
raise MissingSettingException('connection: setting is required')
|
|
|
|
s_con = settings['connection']
|
|
|
|
if not s_con.has_key('type'):
|
|
|
|
raise MissingPropertyException('connection.type: property is required')
|
|
|
|
type = s_con['type']
|
|
|
|
if not type in ['802-3-ethernet', '802-11-wireless', 'vlan', 'wimax']:
|
|
|
|
raise InvalidPropertyException('connection.type: unsupported connection type')
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
self.path = object_path
|
|
|
|
self.settings = settings
|
|
|
|
self.remove_func = remove_func
|
|
|
|
self.visible = True
|
|
|
|
self.props = {}
|
|
|
|
self.props['Unsaved'] = False
|
|
|
|
|
|
|
|
# Properties interface
|
|
|
|
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
|
|
|
|
def GetAll(self, iface):
|
|
|
|
if iface != IFACE_CONNECTION:
|
|
|
|
raise UnknownInterfaceException()
|
|
|
|
return self.props
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
|
|
|
|
def Get(self, iface, name):
|
|
|
|
if iface != IFACE_CONNECTION:
|
|
|
|
raise UnknownInterfaceException()
|
|
|
|
if not name in self.props.keys():
|
|
|
|
raise UnknownPropertyException()
|
|
|
|
return self.props[name]
|
|
|
|
|
|
|
|
# Connection methods
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}')
|
|
|
|
def GetSettings(self):
|
|
|
|
if not self.visible:
|
|
|
|
raise PermissionDeniedException()
|
|
|
|
return self.settings
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='b', out_signature='')
|
|
|
|
def SetVisible(self, vis):
|
|
|
|
self.visible = vis
|
|
|
|
self.Updated()
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='')
|
|
|
|
def Delete(self):
|
|
|
|
self.remove_func(self)
|
|
|
|
self.Removed()
|
2014-08-08 09:31:43 +00:00
|
|
|
self.remove_from_connection()
|
2014-07-22 22:22:23 +00:00
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_CONNECTION, signature='')
|
|
|
|
def Removed(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_CONNECTION, signature='')
|
|
|
|
def Updated(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
###################################################################
|
|
|
|
IFACE_SETTINGS = 'org.freedesktop.NetworkManager.Settings'
|
|
|
|
|
|
|
|
class Settings(dbus.service.Object):
|
|
|
|
def __init__(self, bus, object_path):
|
|
|
|
dbus.service.Object.__init__(self, bus, object_path)
|
|
|
|
self.connections = {}
|
|
|
|
self.bus = bus
|
|
|
|
self.counter = 1
|
2014-08-06 22:07:42 +00:00
|
|
|
self.remove_next_connection = False
|
2014-07-22 22:22:23 +00:00
|
|
|
self.props = {}
|
|
|
|
self.props['Hostname'] = "foobar.baz"
|
|
|
|
self.props['CanModify'] = True
|
2014-09-10 13:30:09 +00:00
|
|
|
self.props['Connections'] = dbus.Array([], 'o')
|
2014-07-22 22:22:23 +00:00
|
|
|
|
2014-08-06 22:07:42 +00:00
|
|
|
def auto_remove_next_connection(self):
|
|
|
|
self.remove_next_connection = True;
|
|
|
|
|
2014-08-29 16:27:47 +00:00
|
|
|
def get_connection(self, path):
|
|
|
|
return self.connections[path]
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
@dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='', out_signature='ao')
|
|
|
|
def ListConnections(self):
|
|
|
|
return self.connections.keys()
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='a{sa{sv}}', out_signature='o')
|
|
|
|
def AddConnection(self, settings):
|
|
|
|
path = "/org/freedesktop/NetworkManager/Settings/Connection/{0}".format(self.counter)
|
|
|
|
self.counter = self.counter + 1
|
|
|
|
self.connections[path] = Connection(self.bus, path, settings, self.delete_connection)
|
2014-09-10 13:30:09 +00:00
|
|
|
self.props['Connections'] = dbus.Array(self.connections.keys(), 'o')
|
2014-07-22 22:22:23 +00:00
|
|
|
self.NewConnection(path)
|
2014-09-10 13:30:09 +00:00
|
|
|
self.PropertiesChanged({ 'connections': self.props['Connections'] })
|
2014-08-06 22:07:42 +00:00
|
|
|
|
|
|
|
if self.remove_next_connection:
|
|
|
|
self.remove_next_connection = False
|
|
|
|
self.connections[path].Delete()
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
return path
|
|
|
|
|
|
|
|
def delete_connection(self, connection):
|
|
|
|
del self.connections[connection.path]
|
2014-09-10 13:30:09 +00:00
|
|
|
self.props['Connections'] = dbus.Array(self.connections.keys(), 'o')
|
|
|
|
self.PropertiesChanged({ 'connections': self.props['Connections'] })
|
2014-07-22 22:22:23 +00:00
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
|
|
|
|
def GetAll(self, iface):
|
|
|
|
if iface != IFACE_SETTINGS:
|
|
|
|
raise UnknownInterfaceException()
|
|
|
|
return self.props
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
|
|
|
|
def Get(self, iface, name):
|
|
|
|
if iface != IFACE_SETTINGS:
|
|
|
|
raise UnknownInterfaceException()
|
|
|
|
if not name in self.props.keys():
|
|
|
|
raise UnknownPropertyException()
|
|
|
|
return self.props[name]
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_SETTINGS, signature='o')
|
|
|
|
def NewConnection(self, path):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.signal(IFACE_SETTINGS, signature='a{sv}')
|
|
|
|
def PropertiesChanged(self, path):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@dbus.service.method(IFACE_SETTINGS, in_signature='', out_signature='')
|
|
|
|
def Quit(self):
|
|
|
|
mainloop.quit()
|
|
|
|
|
2014-08-29 16:27:47 +00:00
|
|
|
###################################################################
|
|
|
|
IFACE_AGENT_MANAGER = 'org.freedesktop.NetworkManager.AgentManager'
|
|
|
|
IFACE_AGENT = 'org.freedesktop.NetworkManager.SecretAgent'
|
|
|
|
|
|
|
|
PATH_SECRET_AGENT = '/org/freedesktop/NetworkManager/SecretAgent'
|
|
|
|
|
|
|
|
FLAG_ALLOW_INTERACTION = 0x1
|
|
|
|
FLAG_REQUEST_NEW = 0x2
|
|
|
|
FLAG_USER_REQUESTED = 0x4
|
|
|
|
|
|
|
|
class NoSecretsException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_AGENT_MANAGER + '.NoSecrets'
|
|
|
|
|
|
|
|
class UserCanceledException(dbus.DBusException):
|
|
|
|
_dbus_error_name = IFACE_AGENT_MANAGER + '.UserCanceled'
|
|
|
|
|
|
|
|
class AgentManager(dbus.service.Object):
|
|
|
|
def __init__(self, bus, object_path):
|
|
|
|
dbus.service.Object.__init__(self, bus, object_path)
|
|
|
|
self.agents = {}
|
|
|
|
self.bus = bus
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER,
|
|
|
|
in_signature='s', out_signature='',
|
|
|
|
sender_keyword='sender')
|
|
|
|
def Register(self, name, sender=None):
|
|
|
|
self.RegisterWithCapabilities(name, 0, sender)
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER,
|
|
|
|
in_signature='su', out_signature='',
|
|
|
|
sender_keyword='sender')
|
|
|
|
def RegisterWithCapabilities(self, name, caps, sender=None):
|
|
|
|
self.agents[sender] = self.bus.get_object(sender, PATH_SECRET_AGENT)
|
|
|
|
|
|
|
|
@dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER,
|
|
|
|
in_signature='', out_signature='',
|
|
|
|
sender_keyword='sender')
|
|
|
|
def Unregister(self, sender=None):
|
|
|
|
del self.agents[sender]
|
|
|
|
|
|
|
|
def get_secrets(self, connection, path, setting_name):
|
|
|
|
if len(self.agents) == 0:
|
|
|
|
return None
|
|
|
|
|
|
|
|
secrets = {}
|
|
|
|
for sender in self.agents:
|
|
|
|
agent = self.agents[sender]
|
|
|
|
try:
|
|
|
|
secrets = agent.GetSecrets(connection, path, setting_name,
|
|
|
|
dbus.Array([], 's'),
|
|
|
|
FLAG_ALLOW_INTERACTION | FLAG_USER_REQUESTED,
|
|
|
|
dbus_interface=IFACE_AGENT)
|
|
|
|
break
|
|
|
|
except dbus.DBusException as e:
|
|
|
|
if e.get_dbus_name() == IFACE_AGENT + '.UserCanceled':
|
|
|
|
raise UserCanceledException('User canceled')
|
|
|
|
continue
|
|
|
|
return secrets
|
|
|
|
|
2014-07-22 22:22:23 +00:00
|
|
|
###################################################################
|
|
|
|
|
2014-07-31 18:00:22 +00:00
|
|
|
def stdin_cb(io, condition):
|
|
|
|
mainloop.quit()
|
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
def quit_cb(user_data):
|
|
|
|
mainloop.quit()
|
|
|
|
|
|
|
|
def main():
|
|
|
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
|
|
|
|
|
|
|
random.seed()
|
|
|
|
|
|
|
|
bus = dbus.SessionBus()
|
2014-08-06 22:07:42 +00:00
|
|
|
|
2014-08-29 16:27:47 +00:00
|
|
|
global manager, settings, agent_manager
|
2014-07-22 22:22:23 +00:00
|
|
|
manager = NetworkManager(bus, "/org/freedesktop/NetworkManager")
|
|
|
|
settings = Settings(bus, "/org/freedesktop/NetworkManager/Settings")
|
2014-08-29 16:27:47 +00:00
|
|
|
agent_manager = AgentManager(bus, "/org/freedesktop/NetworkManager/AgentManager")
|
2014-08-06 22:07:42 +00:00
|
|
|
|
2014-01-09 21:19:07 +00:00
|
|
|
if not bus.request_name("org.freedesktop.NetworkManager"):
|
|
|
|
sys.exit(1)
|
|
|
|
|
2014-07-31 18:00:22 +00:00
|
|
|
# Watch stdin; if it closes, assume our parent has crashed, and exit
|
|
|
|
io = GLib.IOChannel.unix_new(0)
|
|
|
|
io.add_watch(GLib.IOCondition.HUP, stdin_cb)
|
|
|
|
|
|
|
|
# also quit after inactivity to ensure we don't stick around if the above fails somehow
|
2014-07-22 22:22:23 +00:00
|
|
|
GLib.timeout_add_seconds(20, quit_cb, None)
|
2014-01-09 21:19:07 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
mainloop.run()
|
|
|
|
except Exception as e:
|
|
|
|
pass
|
|
|
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|
|
|
|
|