1import dbus 2from dbus.service import Object, method, signal 3 4import sys 5 6class FakeConnectivity(object): 7 NM_BUS_NAME = 'org.freedesktop.NetworkManager' 8 NM_PATH = '/org/freedesktop/NetworkManager' 9 NM_PATH_SETTINGS = NM_PATH + '/Settings' 10 NM_INTERFACE = NM_BUS_NAME 11 NM_INTERFACE_SETTINGS = NM_INTERFACE + '.Settings' 12 13 NM_STATE_UNKNOWN = 0 14 NM_STATE_ASLEEP = 10 15 NM_STATE_DISCONNECTED = 20 16 NM_STATE_DISCONNECTING = 30 17 NM_STATE_CONNECTING = 40 18 NM_STATE_CONNECTED_LOCAL = 50 19 NM_STATE_CONNECTED_SITE = 60 20 NM_STATE_CONNECTED_GLOBAL = 70 21 22 # Our fake GNetworkMonitor uses the ConnMan 0.79 D-Bus API - we don't 23 # have any special support for ConnMan any more, but it's as good an 24 # API as any. The important thing is that it's not NM, because we *do* 25 # have a bit of special support for that. 26 CONNMAN_BUS_NAME = 'net.connman' 27 CONNMAN_PATH = '/' 28 CONNMAN_INTERFACE = 'net.connman.Manager' 29 30 CONNMAN_OFFLINE = "offline" 31 CONNMAN_ONLINE = "online" 32 33 def __init__(self, q, bus, initially_online): 34 self.q = q 35 self.bus = bus 36 37 self.nm_name_ref = dbus.service.BusName(self.NM_BUS_NAME, bus) 38 self.connman_name_ref = dbus.service.BusName(self.CONNMAN_BUS_NAME, bus) 39 40 q.add_dbus_method_impl(self.NM_GetPermissions, 41 path=self.NM_PATH, interface=self.NM_INTERFACE, 42 method='GetPermissions') 43 q.add_dbus_method_impl(self.NM_Get, 44 path=self.NM_PATH, interface=dbus.PROPERTIES_IFACE, method='Get', 45 predicate=lambda e: e.args[0] == self.NM_INTERFACE) 46 q.add_dbus_method_impl(self.NM_GetAll, 47 path=self.NM_PATH, interface=dbus.PROPERTIES_IFACE, method='GetAll', 48 predicate=lambda e: e.args[0] == self.NM_INTERFACE) 49 q.add_dbus_method_impl(self.NM_GetDevices, 50 path=self.NM_PATH, interface=self.NM_INTERFACE, method='GetDevices') 51 52 q.add_dbus_method_impl(self.NM_Settings_Get, 53 path=self.NM_PATH_SETTINGS, interface=dbus.PROPERTIES_IFACE, method='Get', 54 predicate=lambda e: e.args[0] == self.NM_INTERFACE_SETTINGS) 55 q.add_dbus_method_impl(self.NM_Settings_GetAll, 56 path=self.NM_PATH_SETTINGS, interface=dbus.PROPERTIES_IFACE, method='GetAll', 57 predicate=lambda e: e.args[0] == self.NM_INTERFACE_SETTINGS) 58 59 q.add_dbus_method_impl(self.ConnMan_GetProperties, 60 path=self.CONNMAN_PATH, interface=self.CONNMAN_INTERFACE, 61 method='GetProperties') 62 63 self.change_state(initially_online) 64 65 def NM_GetPermissions(self, e): 66 permissions = { 67 self.NM_INTERFACE + '.network-control': 'yes', 68 self.NM_INTERFACE + '.enable-disable-wwan': 'yes', 69 self.NM_INTERFACE + '.settings.modify.own': 'yes', 70 self.NM_INTERFACE + '.wifi.share.protected': 'yes', 71 self.NM_INTERFACE + '.wifi.share.open': 'yes', 72 self.NM_INTERFACE + '.enable-disable-network': 'yes', 73 self.NM_INTERFACE + '.enable-disable-wimax': 'yes', 74 self.NM_INTERFACE + '.sleep-wake': 'no', 75 self.NM_INTERFACE + '.enable-disable-wifi': 'yes', 76 self.NM_INTERFACE + '.settings.modify.system': 'auth', 77 self.NM_INTERFACE + '.settings.modify.hostname': 'auth', 78 } 79 self.q.dbus_return(e.message, permissions, signature='a{ss}') 80 81 def nm_props(self): 82 return { 83 'NetworkingEnabled': True, 84 'WirelessEnabled': True, 85 'WirelessHardwareEnabled': True, 86 'WwanEnabled': False, 87 'WwanHardwareEnabled': True, 88 'WimaxEnabled': True, 89 'WimaxHardwareEnabled': True, 90 'ActiveConnections': dbus.Array([], signature='o'), 91 'Version': '0.9.0', 92 'State': dbus.UInt32(self.nm_state), 93 } 94 95 def NM_Get(self, e): 96 self.q.dbus_return(e.message, self.nm_props()[e.args[1]], signature='v') 97 98 def NM_GetAll(self, e): 99 self.q.dbus_return(e.message, self.nm_props(), signature='a{sv}') 100 101 def NM_GetDevices(self, e): 102 self.q.dbus_return(e.message, [], signature='ao') 103 104 def nm_settings_props(self): 105 return { 106 'CanModify': False, 107 'Hostname': 'localhost', 108 'Connections': dbus.Array([], signature='o'), 109 } 110 111 def NM_Settings_Get(self, e): 112 self.q.dbus_return(e.message, self.nm_settings_props()[e.args[1]], signature='v') 113 114 def NM_Settings_GetAll(self, e): 115 self.q.dbus_return(e.message, self.nm_settings_props(), signature='a{sv}') 116 117 def Connman_props(self): 118 return { 119 'OfflineMode': False, 120 'SessionMode': False, 121 'State': self.connman_state, 122 } 123 124 def ConnMan_GetProperties(self, e): 125 self.q.dbus_return(e.message, self.Connman_props(), signature='a{sv}') 126 127 def change_state(self, online, indeterminate=False): 128 if indeterminate: 129 self.nm_state = self.NM_STATE_DISCONNECTING 130 # keep the previous "ConnMan" (GNetworkMonitor) state; 131 # any other GNetworkMonitor would probably do the same 132 # while trying to disconnect, because e.g. netlink will say the 133 # interface is still up 134 elif online: 135 self.nm_state = self.NM_STATE_CONNECTED_GLOBAL 136 self.connman_state = self.CONNMAN_ONLINE 137 else: 138 self.nm_state = self.NM_STATE_DISCONNECTED 139 self.connman_state = self.CONNMAN_OFFLINE 140 141 self.q.dbus_emit(self.NM_PATH, self.NM_INTERFACE, 142 'PropertiesChanged', { "State": dbus.UInt32(self.nm_state) }, 143 signature='a{sv}') 144 self.q.dbus_emit(self.NM_PATH, self.NM_INTERFACE, 145 'StateChanged', self.nm_state, 146 signature='u') 147 148 if not indeterminate: 149 self.q.dbus_emit(self.CONNMAN_PATH, self.CONNMAN_INTERFACE, 150 'PropertyChanged', "State", self.connman_state, signature='sv') 151 152 def go_online(self): 153 self.change_state(True) 154 155 def go_offline(self): 156 self.change_state(False) 157 158 def go_indeterminate(self): 159 self.change_state(None, True) 160