1*9c5db199SXin Li# Lint as: python2, python3 2*9c5db199SXin Li# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Lifrom __future__ import absolute_import 7*9c5db199SXin Lifrom __future__ import division 8*9c5db199SXin Lifrom __future__ import print_function 9*9c5db199SXin Li 10*9c5db199SXin Liimport dbus 11*9c5db199SXin Liimport dbus.service 12*9c5db199SXin Liimport dbus.types 13*9c5db199SXin Li# AU tests use ToT client code, but ToT -3 client version. 14*9c5db199SXin Litry: 15*9c5db199SXin Li from gi.repository import GObject 16*9c5db199SXin Liexcept ImportError: 17*9c5db199SXin Li import gobject as GObject 18*9c5db199SXin Liimport logging 19*9c5db199SXin Liimport random 20*9c5db199SXin Li 21*9c5db199SXin Liimport six 22*9c5db199SXin Li 23*9c5db199SXin Liimport common 24*9c5db199SXin Li 25*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import bearer 26*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import dbus_std_ifaces 27*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import messaging 28*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import modem_simple 29*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import pm_constants 30*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import pm_errors 31*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import sms_handler 32*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import state_machine_factory as smf 33*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import utils 34*9c5db199SXin Li 35*9c5db199SXin Lifrom autotest_lib.client.cros.cellular import mm1_constants 36*9c5db199SXin Lifrom autotest_lib.client.cros.cellular import net_interface 37*9c5db199SXin Li 38*9c5db199SXin LiALLOWED_BEARER_PROPERTIES = [ 39*9c5db199SXin Li 'apn', 40*9c5db199SXin Li 'operator-id', 41*9c5db199SXin Li 'allowed-modes', 42*9c5db199SXin Li 'preferred-mode', 43*9c5db199SXin Li 'bands', 44*9c5db199SXin Li 'ip-type', 45*9c5db199SXin Li 'user', 46*9c5db199SXin Li 'password', 47*9c5db199SXin Li 'allow-roaming', 48*9c5db199SXin Li 'rm-protocol', 49*9c5db199SXin Li 'number' 50*9c5db199SXin Li] 51*9c5db199SXin Li 52*9c5db199SXin Liclass Modem(dbus_std_ifaces.DBusProperties, 53*9c5db199SXin Li modem_simple.ModemSimple, 54*9c5db199SXin Li messaging.Messaging): 55*9c5db199SXin Li """ 56*9c5db199SXin Li Pseudomodem implementation of the org.freedesktop.ModemManager1.Modem 57*9c5db199SXin Li interface. This class serves as the abstract base class of all fake modem 58*9c5db199SXin Li implementations. 59*9c5db199SXin Li 60*9c5db199SXin Li """ 61*9c5db199SXin Li 62*9c5db199SXin Li SUPPORTS_MULTIPLE_OBJECT_PATHS = True 63*9c5db199SXin Li 64*9c5db199SXin Li def __init__(self, 65*9c5db199SXin Li state_machine_factory=None, 66*9c5db199SXin Li bus=None, 67*9c5db199SXin Li device='pseudomodem0', 68*9c5db199SXin Li device_port_type=mm1_constants.MM_MODEM_PORT_TYPE_AT, 69*9c5db199SXin Li index=0, 70*9c5db199SXin Li roaming_networks=None, 71*9c5db199SXin Li config=None): 72*9c5db199SXin Li """ 73*9c5db199SXin Li Initializes the fake modem object. kwargs can contain the optional 74*9c5db199SXin Li argument |config|, which is a dictionary of property-value mappings. 75*9c5db199SXin Li These properties will be added to the underlying property dictionary, 76*9c5db199SXin Li and must be one of the properties listed in the ModemManager Reference 77*9c5db199SXin Li Manual. See _InitializeProperties for all of the properties that belong 78*9c5db199SXin Li to this interface. Possible values for each are enumerated in 79*9c5db199SXin Li mm1_constants.py. 80*9c5db199SXin Li 81*9c5db199SXin Li """ 82*9c5db199SXin Li if state_machine_factory: 83*9c5db199SXin Li self._state_machine_factory = state_machine_factory 84*9c5db199SXin Li else: 85*9c5db199SXin Li self._state_machine_factory = smf.StateMachineFactory() 86*9c5db199SXin Li self.device = device 87*9c5db199SXin Li self.device_port_type = device_port_type 88*9c5db199SXin Li self.index = index 89*9c5db199SXin Li self.sim = None 90*9c5db199SXin Li 91*9c5db199SXin Li # The superclass construct will call _InitializeProperties 92*9c5db199SXin Li dbus_std_ifaces.DBusProperties.__init__(self, 93*9c5db199SXin Li mm1_constants.MM1 + '/Modem/' + str(index), bus, config) 94*9c5db199SXin Li 95*9c5db199SXin Li if roaming_networks is None: 96*9c5db199SXin Li roaming_networks = [] 97*9c5db199SXin Li self.roaming_networks = roaming_networks 98*9c5db199SXin Li 99*9c5db199SXin Li self.bearers = {} 100*9c5db199SXin Li self.active_bearers = {} 101*9c5db199SXin Li self.enable_step = None 102*9c5db199SXin Li self.disable_step = None 103*9c5db199SXin Li self.connect_step = None 104*9c5db199SXin Li self.disconnect_step = None 105*9c5db199SXin Li self.register_step = None 106*9c5db199SXin Li 107*9c5db199SXin Li self._modemmanager = None 108*9c5db199SXin Li self.resetting = False 109*9c5db199SXin Li 110*9c5db199SXin Li self._sms_handler = sms_handler.SmsHandler(self, bus) 111*9c5db199SXin Li 112*9c5db199SXin Li 113*9c5db199SXin Li def _InitializeProperties(self): 114*9c5db199SXin Li """ Sets up the default values for the properties. """ 115*9c5db199SXin Li props = { 116*9c5db199SXin Li 'Manufacturer' : 'Banana Technologies', # be creative here 117*9c5db199SXin Li 'Model' : 'Banana Peel 3000', # yep 118*9c5db199SXin Li 'Revision' : '1.0', 119*9c5db199SXin Li 'DeviceIdentifier' : 'Banana1234567890', 120*9c5db199SXin Li 'Device' : self.device, 121*9c5db199SXin Li 'Ports': [dbus.types.Struct( 122*9c5db199SXin Li [self.device, 123*9c5db199SXin Li dbus.types.UInt32(self.device_port_type)], 124*9c5db199SXin Li signature='su'), 125*9c5db199SXin Li dbus.types.Struct( 126*9c5db199SXin Li [net_interface.PseudoNetInterface.IFACE_NAME, 127*9c5db199SXin Li dbus.types.UInt32( 128*9c5db199SXin Li mm1_constants.MM_MODEM_PORT_TYPE_NET)], 129*9c5db199SXin Li signature='su')], 130*9c5db199SXin Li 'Drivers' : ['FakeDriver'], 131*9c5db199SXin Li 'Plugin' : 'Banana Plugin', 132*9c5db199SXin Li 'UnlockRequired' : 133*9c5db199SXin Li dbus.types.UInt32(mm1_constants.MM_MODEM_LOCK_NONE), 134*9c5db199SXin Li 'UnlockRetries' : dbus.Dictionary(signature='uu'), 135*9c5db199SXin Li 'State' : dbus.types.Int32(mm1_constants.MM_MODEM_STATE_DISABLED), 136*9c5db199SXin Li 'SignalQuality' : dbus.types.Struct( 137*9c5db199SXin Li [dbus.types.UInt32(100), True], 138*9c5db199SXin Li signature='ub'), 139*9c5db199SXin Li 'OwnNumbers' : ['5555555555'], 140*9c5db199SXin Li 'PowerState' : 141*9c5db199SXin Li dbus.types.UInt32(mm1_constants.MM_MODEM_POWER_STATE_ON), 142*9c5db199SXin Li 'SupportedIpFamilies' : 143*9c5db199SXin Li dbus.types.UInt32(mm1_constants.MM_BEARER_IP_FAMILY_ANY), 144*9c5db199SXin Li 'Bearers' : dbus.Array([], signature='o'), 145*9c5db199SXin Li 146*9c5db199SXin Li # specified by subclass: 147*9c5db199SXin Li 'SupportedCapabilities' : 148*9c5db199SXin Li [dbus.types.UInt32(mm1_constants.MM_MODEM_CAPABILITY_NONE)], 149*9c5db199SXin Li 'CurrentCapabilities' : 150*9c5db199SXin Li dbus.types.UInt32(mm1_constants.MM_MODEM_CAPABILITY_NONE), 151*9c5db199SXin Li 'MaxBearers' : dbus.types.UInt32(0), 152*9c5db199SXin Li 'MaxActiveBearers' : dbus.types.UInt32(0), 153*9c5db199SXin Li 'EquipmentIdentifier' : '', 154*9c5db199SXin Li 'AccessTechnologies' : 155*9c5db199SXin Li dbus.types.UInt32( 156*9c5db199SXin Li mm1_constants.MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN), 157*9c5db199SXin Li 'SupportedModes' : [ 158*9c5db199SXin Li dbus.types.Struct( 159*9c5db199SXin Li [dbus.types.UInt32( 160*9c5db199SXin Li mm1_constants.MM_MODEM_MODE_NONE), 161*9c5db199SXin Li dbus.types.UInt32( 162*9c5db199SXin Li mm1_constants.MM_MODEM_MODE_NONE)], 163*9c5db199SXin Li signature='uu') 164*9c5db199SXin Li ], 165*9c5db199SXin Li 'CurrentModes' : 166*9c5db199SXin Li dbus.types.Struct( 167*9c5db199SXin Li [dbus.types.UInt32( 168*9c5db199SXin Li mm1_constants.MM_MODEM_MODE_NONE), 169*9c5db199SXin Li dbus.types.UInt32( 170*9c5db199SXin Li mm1_constants.MM_MODEM_MODE_NONE)], 171*9c5db199SXin Li signature='uu'), 172*9c5db199SXin Li 'SupportedBands' : 173*9c5db199SXin Li [dbus.types.UInt32(mm1_constants.MM_MODEM_BAND_UNKNOWN)], 174*9c5db199SXin Li 'CurrentBands' : 175*9c5db199SXin Li [dbus.types.UInt32(mm1_constants.MM_MODEM_BAND_UNKNOWN)], 176*9c5db199SXin Li 'Sim' : dbus.types.ObjectPath(mm1_constants.ROOT_PATH) 177*9c5db199SXin Li } 178*9c5db199SXin Li return { 179*9c5db199SXin Li mm1_constants.I_MODEM : props, 180*9c5db199SXin Li mm1_constants.I_MODEM_SIMPLE : {} 181*9c5db199SXin Li } 182*9c5db199SXin Li 183*9c5db199SXin Li 184*9c5db199SXin Li def IncrementPath(self): 185*9c5db199SXin Li """ 186*9c5db199SXin Li Increments the current index at which this modem is exposed on DBus. 187*9c5db199SXin Li E.g. if the current path is org/freedesktop/ModemManager/Modem/0, the 188*9c5db199SXin Li path will change to org/freedesktop/ModemManager/Modem/1. 189*9c5db199SXin Li 190*9c5db199SXin Li Calling this method does not remove the object from its current path, 191*9c5db199SXin Li which means that it will be available via both the old and the new 192*9c5db199SXin Li paths. This is currently only used by Reset, in conjunction with 193*9c5db199SXin Li dbus_std_ifaces.DBusObjectManager.[Add|Remove]. 194*9c5db199SXin Li 195*9c5db199SXin Li """ 196*9c5db199SXin Li self.index += 1 197*9c5db199SXin Li path = mm1_constants.MM1 + '/Modem/' + str(self.index) 198*9c5db199SXin Li logging.info('Modem coming back as: ' + path) 199*9c5db199SXin Li self.SetPath(path) 200*9c5db199SXin Li 201*9c5db199SXin Li 202*9c5db199SXin Li @property 203*9c5db199SXin Li def manager(self): 204*9c5db199SXin Li """ 205*9c5db199SXin Li The current modemmanager.ModemManager instance that is managing this 206*9c5db199SXin Li modem. 207*9c5db199SXin Li 208*9c5db199SXin Li @returns: A modemmanager.ModemManager object. 209*9c5db199SXin Li 210*9c5db199SXin Li """ 211*9c5db199SXin Li return self._modemmanager 212*9c5db199SXin Li 213*9c5db199SXin Li 214*9c5db199SXin Li @manager.setter 215*9c5db199SXin Li def manager(self, manager): 216*9c5db199SXin Li """ 217*9c5db199SXin Li Sets the current modemmanager.ModemManager instance that is managing 218*9c5db199SXin Li this modem. 219*9c5db199SXin Li 220*9c5db199SXin Li @param manager: A modemmanager.ModemManager object. 221*9c5db199SXin Li 222*9c5db199SXin Li """ 223*9c5db199SXin Li self._modemmanager = manager 224*9c5db199SXin Li 225*9c5db199SXin Li 226*9c5db199SXin Li @property 227*9c5db199SXin Li def sms_handler(self): 228*9c5db199SXin Li """ 229*9c5db199SXin Li @returns: sms_handler.SmsHandler responsible for handling SMS. 230*9c5db199SXin Li 231*9c5db199SXin Li """ 232*9c5db199SXin Li return self._sms_handler 233*9c5db199SXin Li 234*9c5db199SXin Li 235*9c5db199SXin Li def IsPendingEnable(self): 236*9c5db199SXin Li """ 237*9c5db199SXin Li @returns: True, if a current enable state machine is active and hasn't 238*9c5db199SXin Li been cancelled. 239*9c5db199SXin Li 240*9c5db199SXin Li """ 241*9c5db199SXin Li return self.enable_step and not self.enable_step.cancelled 242*9c5db199SXin Li 243*9c5db199SXin Li 244*9c5db199SXin Li def IsPendingDisable(self): 245*9c5db199SXin Li """ 246*9c5db199SXin Li @returns: True, if a current disable state machine is active and hasn't 247*9c5db199SXin Li been cancelled. 248*9c5db199SXin Li 249*9c5db199SXin Li """ 250*9c5db199SXin Li return self.disable_step and not self.disable_step.cancelled 251*9c5db199SXin Li 252*9c5db199SXin Li 253*9c5db199SXin Li def IsPendingConnect(self): 254*9c5db199SXin Li """ 255*9c5db199SXin Li @returns: True, if a current connect state machine is active and hasn't 256*9c5db199SXin Li been cancelled. 257*9c5db199SXin Li 258*9c5db199SXin Li """ 259*9c5db199SXin Li return self.connect_step and not self.connect_step.cancelled 260*9c5db199SXin Li 261*9c5db199SXin Li 262*9c5db199SXin Li def IsPendingDisconnect(self): 263*9c5db199SXin Li """ 264*9c5db199SXin Li @returns: True, if a current disconnect state machine is active and 265*9c5db199SXin Li hasn't been cancelled. 266*9c5db199SXin Li 267*9c5db199SXin Li """ 268*9c5db199SXin Li return self.disconnect_step and not self.disconnect_step.cancelled 269*9c5db199SXin Li 270*9c5db199SXin Li 271*9c5db199SXin Li def IsPendingRegister(self): 272*9c5db199SXin Li """ 273*9c5db199SXin Li @returns: True, if a current register state machine is active and hasn't 274*9c5db199SXin Li been cancelled. 275*9c5db199SXin Li 276*9c5db199SXin Li """ 277*9c5db199SXin Li return self.register_step and not self.register_step.cancelled 278*9c5db199SXin Li 279*9c5db199SXin Li 280*9c5db199SXin Li def CancelAllStateMachines(self): 281*9c5db199SXin Li """ Cancels all state machines that are active. """ 282*9c5db199SXin Li if self.IsPendingEnable(): 283*9c5db199SXin Li self.enable_step.Cancel() 284*9c5db199SXin Li if self.IsPendingDisable(): 285*9c5db199SXin Li self.disable_step.Cancel() 286*9c5db199SXin Li if self.IsPendingConnect(): 287*9c5db199SXin Li self.connect_step.Cancel() 288*9c5db199SXin Li if self.IsPendingDisconnect(): 289*9c5db199SXin Li self.disconnect_step.Cancel() 290*9c5db199SXin Li if self.IsPendingRegister(): 291*9c5db199SXin Li self.register_step.Cancel() 292*9c5db199SXin Li 293*9c5db199SXin Li 294*9c5db199SXin Li def SetSignalQuality(self, quality): 295*9c5db199SXin Li """ 296*9c5db199SXin Li Sets the 'SignalQuality' property to the given value. 297*9c5db199SXin Li 298*9c5db199SXin Li @param quality: An integer value in the range 0-100. 299*9c5db199SXin Li Emits: 300*9c5db199SXin Li PropertiesChanged 301*9c5db199SXin Li 302*9c5db199SXin Li """ 303*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 'SignalQuality', (dbus.types.Struct( 304*9c5db199SXin Li [dbus.types.UInt32(quality), True], signature='ub'))) 305*9c5db199SXin Li 306*9c5db199SXin Li 307*9c5db199SXin Li def ChangeState(self, state, reason): 308*9c5db199SXin Li """ 309*9c5db199SXin Li Changes the modem state and emits the StateChanged signal. 310*9c5db199SXin Li 311*9c5db199SXin Li @param state: A MMModemState value. 312*9c5db199SXin Li @param reason: A MMModemStateChangeReason value. 313*9c5db199SXin Li Emits: 314*9c5db199SXin Li PropertiesChanged 315*9c5db199SXin Li StateChanged 316*9c5db199SXin Li 317*9c5db199SXin Li """ 318*9c5db199SXin Li old_state = self.Get(mm1_constants.I_MODEM, 'State') 319*9c5db199SXin Li self.SetInt32(mm1_constants.I_MODEM, 'State', state) 320*9c5db199SXin Li self.StateChanged(old_state, state, dbus.types.UInt32(reason)) 321*9c5db199SXin Li 322*9c5db199SXin Li 323*9c5db199SXin Li def SetSIM(self, sim): 324*9c5db199SXin Li """ 325*9c5db199SXin Li Assigns a SIM object to this Modem. It exposes the SIM object via DBus 326*9c5db199SXin Li and sets 'Sim' property of this Modem to the path of the SIM. 327*9c5db199SXin Li 328*9c5db199SXin Li @param sim: An instance of sim.SIM. 329*9c5db199SXin Li Emits: 330*9c5db199SXin Li PropertiesChanged 331*9c5db199SXin Li 332*9c5db199SXin Li """ 333*9c5db199SXin Li self.sim = sim 334*9c5db199SXin Li if not sim: 335*9c5db199SXin Li val = mm1_constants.ROOT_PATH 336*9c5db199SXin Li else: 337*9c5db199SXin Li val = sim.path 338*9c5db199SXin Li self.sim.SetBus(self.bus) 339*9c5db199SXin Li self.sim.modem = self 340*9c5db199SXin Li self.UpdateLockStatus() 341*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 'Sim', dbus.types.ObjectPath(val)) 342*9c5db199SXin Li 343*9c5db199SXin Li 344*9c5db199SXin Li def SetBus(self, bus): 345*9c5db199SXin Li """ 346*9c5db199SXin Li Overridden from dbus_std_ifaces.DBusProperties. 347*9c5db199SXin Li 348*9c5db199SXin Li @param bus 349*9c5db199SXin Li 350*9c5db199SXin Li """ 351*9c5db199SXin Li dbus_std_ifaces.DBusProperties.SetBus(self, bus) 352*9c5db199SXin Li self._state_machine_factory.SetBus(bus) 353*9c5db199SXin Li self._sms_handler.bus = bus 354*9c5db199SXin Li 355*9c5db199SXin Li 356*9c5db199SXin Li def UpdateLockStatus(self): 357*9c5db199SXin Li """ 358*9c5db199SXin Li Tells the modem to update the current lock status. This method will 359*9c5db199SXin Li update the modem state and the relevant modem properties. 360*9c5db199SXin Li 361*9c5db199SXin Li """ 362*9c5db199SXin Li if not self.sim: 363*9c5db199SXin Li logging.info('SIM lock is the only kind of lock that is currently ' 364*9c5db199SXin Li 'supported. No SIM present, nothing to do.') 365*9c5db199SXin Li return 366*9c5db199SXin Li self.SetUInt32(mm1_constants.I_MODEM, 'UnlockRequired', 367*9c5db199SXin Li self.sim.lock_type) 368*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 'UnlockRetries', 369*9c5db199SXin Li self.sim.unlock_retries) 370*9c5db199SXin Li if self.sim.locked: 371*9c5db199SXin Li def _SetLocked(): 372*9c5db199SXin Li logging.info('There is a SIM lock in place. Setting state to ' 373*9c5db199SXin Li 'LOCKED') 374*9c5db199SXin Li self.ChangeState( 375*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_LOCKED, 376*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN) 377*9c5db199SXin Li 378*9c5db199SXin Li # If the modem is currently in an enabled state, disable it before 379*9c5db199SXin Li # setting the modem state to LOCKED. 380*9c5db199SXin Li if (self.Get(mm1_constants.I_MODEM, 'State') >= 381*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_ENABLED): 382*9c5db199SXin Li logging.info('SIM got locked. Disabling modem.') 383*9c5db199SXin Li self.Enable(False, return_cb=_SetLocked) 384*9c5db199SXin Li else: 385*9c5db199SXin Li _SetLocked() 386*9c5db199SXin Li elif (self.Get(mm1_constants.I_MODEM, 'State') == 387*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_LOCKED): 388*9c5db199SXin Li # Change the state to DISABLED. Shill will see the property change 389*9c5db199SXin Li # and automatically attempt to enable the modem. 390*9c5db199SXin Li logging.info('SIM became unlocked! Setting state to INITIALIZING.') 391*9c5db199SXin Li self.ChangeState(mm1_constants.MM_MODEM_STATE_INITIALIZING, 392*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN) 393*9c5db199SXin Li logging.info('SIM became unlocked! Setting state to DISABLED.') 394*9c5db199SXin Li self.ChangeState(mm1_constants.MM_MODEM_STATE_DISABLED, 395*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN) 396*9c5db199SXin Li 397*9c5db199SXin Li 398*9c5db199SXin Li @utils.log_dbus_method(return_cb_arg='return_cb', raise_cb_arg='raise_cb') 399*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, 400*9c5db199SXin Li in_signature='b', async_callbacks=('return_cb', 401*9c5db199SXin Li 'raise_cb')) 402*9c5db199SXin Li def Enable(self, enable, return_cb=None, raise_cb=None): 403*9c5db199SXin Li """ 404*9c5db199SXin Li Enables or disables the modem. 405*9c5db199SXin Li 406*9c5db199SXin Li When enabled, the modem's radio is powered on and data sessions, voice 407*9c5db199SXin Li calls, location services, and Short Message Service may be available. 408*9c5db199SXin Li 409*9c5db199SXin Li When disabled, the modem enters low-power state and no network-related 410*9c5db199SXin Li operations are available. 411*9c5db199SXin Li 412*9c5db199SXin Li @param enable: True to enable the modem and False to disable it. 413*9c5db199SXin Li @param return_cb: The asynchronous callback to invoke on success. 414*9c5db199SXin Li @param raise_cb: The asynchronous callback to invoke on failure. Has to 415*9c5db199SXin Li take a python Exception or Error as its single argument. 416*9c5db199SXin Li 417*9c5db199SXin Li """ 418*9c5db199SXin Li if enable: 419*9c5db199SXin Li logging.info('Modem enable') 420*9c5db199SXin Li machine = self._state_machine_factory.CreateMachine( 421*9c5db199SXin Li pm_constants.STATE_MACHINE_ENABLE, 422*9c5db199SXin Li self, 423*9c5db199SXin Li return_cb, 424*9c5db199SXin Li raise_cb) 425*9c5db199SXin Li else: 426*9c5db199SXin Li logging.info('Modem disable') 427*9c5db199SXin Li machine = self._state_machine_factory.CreateMachine( 428*9c5db199SXin Li pm_constants.STATE_MACHINE_DISABLE, 429*9c5db199SXin Li self, 430*9c5db199SXin Li return_cb, 431*9c5db199SXin Li raise_cb) 432*9c5db199SXin Li machine.Start() 433*9c5db199SXin Li 434*9c5db199SXin Li 435*9c5db199SXin Li def RegisterWithNetwork( 436*9c5db199SXin Li self, operator_id="", return_cb=None, raise_cb=None): 437*9c5db199SXin Li """ 438*9c5db199SXin Li Register with the network specified by the given |operator_id|. 439*9c5db199SXin Li |operator_id| should be an MCCMNC value (for 3GPP) or an empty string. 440*9c5db199SXin Li An implementation of this method must set the state to SEARCHING first, 441*9c5db199SXin Li and eventually to REGISTERED, also setting technology specific 442*9c5db199SXin Li registration state properties. Technology specific error cases need to 443*9c5db199SXin Li be handled here (such as activation, the presence of a valid SIM card, 444*9c5db199SXin Li etc). 445*9c5db199SXin Li 446*9c5db199SXin Li Must be implemented by a subclass. 447*9c5db199SXin Li 448*9c5db199SXin Li @param operator_id: String containing the operator code. This method 449*9c5db199SXin Li will typically initiate a network scan, yielding a list of 450*9c5db199SXin Li networks. If |operator_id| is non-empty, the modem will register 451*9c5db199SXin Li with the network in the scanned list that matches |operator_id|. 452*9c5db199SXin Li An empty |operator_id| means that registration should be 453*9c5db199SXin Li "automatic". In this case the implementation would typically 454*9c5db199SXin Li register with the home network. If a home network is not 455*9c5db199SXin Li available than any network that is returned by a network scan 456*9c5db199SXin Li can be registered with. 457*9c5db199SXin Li 458*9c5db199SXin Li Note: CDMA doesn't support a network scan. In this case, the 459*9c5db199SXin Li only possible option is to register with the home network and 460*9c5db199SXin Li ignore the value of |operator_id|. 461*9c5db199SXin Li @param return_cb: Async success callback. 462*9c5db199SXin Li @param raise_cb: Async failure callback. 463*9c5db199SXin Li 464*9c5db199SXin Li """ 465*9c5db199SXin Li raise NotImplementedError() 466*9c5db199SXin Li 467*9c5db199SXin Li 468*9c5db199SXin Li def UnregisterWithNetwork(self): 469*9c5db199SXin Li """ 470*9c5db199SXin Li Unregisters with the currently registered network. This should 471*9c5db199SXin Li transition the modem to the ENABLED state. 472*9c5db199SXin Li 473*9c5db199SXin Li Must be implemented by a subclass. 474*9c5db199SXin Li 475*9c5db199SXin Li """ 476*9c5db199SXin Li raise NotImplementedError() 477*9c5db199SXin Li 478*9c5db199SXin Li 479*9c5db199SXin Li def ValidateBearerProperties(self, properties): 480*9c5db199SXin Li """ 481*9c5db199SXin Li The default implementation makes sure that all keys in properties are 482*9c5db199SXin Li one of the allowed bearer properties. Subclasses can override this 483*9c5db199SXin Li method to provide CDMA/3GPP specific checks. 484*9c5db199SXin Li 485*9c5db199SXin Li @param properties: The dictionary of properties and values to validate. 486*9c5db199SXin Li @raises: MMCoreError, if one or more properties are invalid. 487*9c5db199SXin Li 488*9c5db199SXin Li """ 489*9c5db199SXin Li for key in six.iterkeys(properties): 490*9c5db199SXin Li if key not in ALLOWED_BEARER_PROPERTIES: 491*9c5db199SXin Li raise pm_errors.MMCoreError( 492*9c5db199SXin Li pm_errors.MMCoreError.INVALID_ARGS, 493*9c5db199SXin Li 'Invalid property "%s", not creating bearer.' % key) 494*9c5db199SXin Li 495*9c5db199SXin Li 496*9c5db199SXin Li @utils.log_dbus_method() 497*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, out_signature='ao') 498*9c5db199SXin Li def ListBearers(self): 499*9c5db199SXin Li """ 500*9c5db199SXin Li Lists configured packet data bearers (EPS Bearers, PDP Contexts, or 501*9c5db199SXin Li CDMA2000 Packet Data Sessions). 502*9c5db199SXin Li 503*9c5db199SXin Li @returns: A list of bearer object paths. 504*9c5db199SXin Li 505*9c5db199SXin Li """ 506*9c5db199SXin Li return self.Get(mm1_constants.I_MODEM, 'Bearers') 507*9c5db199SXin Li 508*9c5db199SXin Li 509*9c5db199SXin Li @utils.log_dbus_method() 510*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='a{sv}', 511*9c5db199SXin Li out_signature='o') 512*9c5db199SXin Li def CreateBearer(self, properties): 513*9c5db199SXin Li """ 514*9c5db199SXin Li Creates a new packet data bearer using the given characteristics. 515*9c5db199SXin Li 516*9c5db199SXin Li This request may fail if the modem does not support additional bearers, 517*9c5db199SXin Li if too many bearers are already defined, or if properties are invalid. 518*9c5db199SXin Li 519*9c5db199SXin Li @param properties: A dictionary containing the properties to assign to 520*9c5db199SXin Li the bearer after creating it. The allowed property values are 521*9c5db199SXin Li contained in modem.ALLOWED_PROPERTIES. 522*9c5db199SXin Li @returns: On success, the object path of the newly created bearer. 523*9c5db199SXin Li 524*9c5db199SXin Li """ 525*9c5db199SXin Li logging.info('CreateBearer') 526*9c5db199SXin Li maxbearers = self.Get(mm1_constants.I_MODEM, 'MaxBearers') 527*9c5db199SXin Li if len(self.bearers) == maxbearers: 528*9c5db199SXin Li raise pm_errors.MMCoreError( 529*9c5db199SXin Li pm_errors.MMCoreError.TOO_MANY, 530*9c5db199SXin Li ('Maximum number of bearers reached. Cannot create new ' 531*9c5db199SXin Li 'bearer.')) 532*9c5db199SXin Li else: 533*9c5db199SXin Li self.ValidateBearerProperties(properties) 534*9c5db199SXin Li bearer_obj = bearer.Bearer(self.bus, properties) 535*9c5db199SXin Li logging.info('Created bearer with path "%s".', bearer_obj.path) 536*9c5db199SXin Li self.bearers[bearer_obj.path] = bearer_obj 537*9c5db199SXin Li self._UpdateBearersProperty() 538*9c5db199SXin Li return bearer_obj.path 539*9c5db199SXin Li 540*9c5db199SXin Li 541*9c5db199SXin Li def ActivateBearer(self, bearer_path): 542*9c5db199SXin Li """ 543*9c5db199SXin Li Activates a data bearer by setting its 'Connected' property to True. 544*9c5db199SXin Li 545*9c5db199SXin Li This request may fail if the modem does not support additional active 546*9c5db199SXin Li bearers, if too many bearers are already active, if the requested 547*9c5db199SXin Li bearer doesn't exist, or if the requested bearer is already active. 548*9c5db199SXin Li 549*9c5db199SXin Li @param bearer_path: DBus path of the bearer to activate. 550*9c5db199SXin Li 551*9c5db199SXin Li """ 552*9c5db199SXin Li logging.info('ActivateBearer: %s', bearer_path) 553*9c5db199SXin Li bearer = self.bearers.get(bearer_path, None) 554*9c5db199SXin Li if bearer is None: 555*9c5db199SXin Li message = 'Could not find bearer with path "%s"' % bearer_path 556*9c5db199SXin Li logging.info(message) 557*9c5db199SXin Li raise pm_errors.MMCoreError(pm_errors.MMCoreError.NOT_FOUND, 558*9c5db199SXin Li message) 559*9c5db199SXin Li 560*9c5db199SXin Li max_active_bearers = self.Get(mm1_constants.I_MODEM, 'MaxActiveBearers') 561*9c5db199SXin Li if len(self.active_bearers) >= max_active_bearers: 562*9c5db199SXin Li message = ('Cannot activate bearer: maximum active bearer count ' 563*9c5db199SXin Li 'reached.') 564*9c5db199SXin Li logging.info(message) 565*9c5db199SXin Li raise pm_errors.MMCoreError(pm_errors.MMCoreError.TOO_MANY, message) 566*9c5db199SXin Li if bearer.IsActive(): 567*9c5db199SXin Li message = 'Bearer with path "%s" already active.', bearer_path 568*9c5db199SXin Li logging.info(message) 569*9c5db199SXin Li raise pm_errors.MMCoreError(pm_errors.MMCoreError.CONNECTED, 570*9c5db199SXin Li message) 571*9c5db199SXin Li 572*9c5db199SXin Li self.active_bearers[bearer_path] = bearer 573*9c5db199SXin Li bearer.Connect() 574*9c5db199SXin Li 575*9c5db199SXin Li 576*9c5db199SXin Li def DeactivateBearer(self, bearer_path): 577*9c5db199SXin Li """ 578*9c5db199SXin Li Deactivates data bearer by setting its 'Connected' property to False. 579*9c5db199SXin Li 580*9c5db199SXin Li This request may fail if the modem with the requested path doesn't 581*9c5db199SXin Li exist, or if the bearer is not active. 582*9c5db199SXin Li 583*9c5db199SXin Li @param bearer_path: DBus path of the bearer to activate. 584*9c5db199SXin Li 585*9c5db199SXin Li """ 586*9c5db199SXin Li logging.info('DeactivateBearer: %s', bearer_path) 587*9c5db199SXin Li bearer = self.bearers.get(bearer_path, None) 588*9c5db199SXin Li if bearer is None: 589*9c5db199SXin Li raise pm_errors.MMCoreError( 590*9c5db199SXin Li pm_errors.MMCoreError.NOT_FOUND, 591*9c5db199SXin Li 'Could not find bearer with path "%s".' % bearer_path) 592*9c5db199SXin Li if not bearer.IsActive(): 593*9c5db199SXin Li assert bearer_path not in self.active_bearers 594*9c5db199SXin Li raise pm_errors.MMCoreError( 595*9c5db199SXin Li pm_errors.MMCoreError.WRONG_STATE, 596*9c5db199SXin Li 'Bearer with path "%s" is not active.' % bearer_path) 597*9c5db199SXin Li assert bearer_path in self.active_bearers 598*9c5db199SXin Li bearer.Disconnect() 599*9c5db199SXin Li self.active_bearers.pop(bearer_path) 600*9c5db199SXin Li 601*9c5db199SXin Li 602*9c5db199SXin Li @utils.log_dbus_method() 603*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='o') 604*9c5db199SXin Li def DeleteBearer(self, bearer): 605*9c5db199SXin Li """ 606*9c5db199SXin Li Deletes an existing packet data bearer. 607*9c5db199SXin Li 608*9c5db199SXin Li If the bearer is currently active, it will be deactivated. 609*9c5db199SXin Li 610*9c5db199SXin Li @param bearer: Object path of the bearer to delete. 611*9c5db199SXin Li 612*9c5db199SXin Li """ 613*9c5db199SXin Li logging.info('Modem.DeleteBearer: ' + str(bearer)) 614*9c5db199SXin Li if not bearer in self.bearers: 615*9c5db199SXin Li logging.info('Unknown bearer. Nothing to do.') 616*9c5db199SXin Li return 617*9c5db199SXin Li bearer_object = self.bearers[bearer] 618*9c5db199SXin Li bearer_object.remove_from_connection() 619*9c5db199SXin Li self.bearers.pop(bearer) 620*9c5db199SXin Li self._UpdateBearersProperty() 621*9c5db199SXin Li if bearer in self.active_bearers: 622*9c5db199SXin Li self.active_bearers.pop(bearer) 623*9c5db199SXin Li 624*9c5db199SXin Li 625*9c5db199SXin Li def ClearBearers(self): 626*9c5db199SXin Li """ Deletes all bearers that are managed by this modem. """ 627*9c5db199SXin Li for b in self.bearers.keys(): 628*9c5db199SXin Li self.DeleteBearer(b) 629*9c5db199SXin Li 630*9c5db199SXin Li 631*9c5db199SXin Li @utils.log_dbus_method() 632*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM) 633*9c5db199SXin Li def Reset(self): 634*9c5db199SXin Li """ 635*9c5db199SXin Li Clears non-persistent configuration and state, and returns the device to 636*9c5db199SXin Li a newly-powered-on state. 637*9c5db199SXin Li 638*9c5db199SXin Li As a result of this operation, the modem will be removed from its 639*9c5db199SXin Li current path and will be exposed on an incremented path. It will be 640*9c5db199SXin Li enabled afterwards. 641*9c5db199SXin Li 642*9c5db199SXin Li """ 643*9c5db199SXin Li logging.info('Resetting modem.') 644*9c5db199SXin Li 645*9c5db199SXin Li if self.resetting: 646*9c5db199SXin Li raise pm_errors.MMCoreError(pm_errors.MMCoreError.IN_PROGRESS, 647*9c5db199SXin Li 'Reset already in progress.') 648*9c5db199SXin Li 649*9c5db199SXin Li self.resetting = True 650*9c5db199SXin Li 651*9c5db199SXin Li self.CancelAllStateMachines() 652*9c5db199SXin Li 653*9c5db199SXin Li def _ResetFunc(): 654*9c5db199SXin Li # Disappear. 655*9c5db199SXin Li manager = self.manager 656*9c5db199SXin Li if manager: 657*9c5db199SXin Li manager.Remove(self) 658*9c5db199SXin Li if self.sim: 659*9c5db199SXin Li manager.Remove(self.sim) 660*9c5db199SXin Li 661*9c5db199SXin Li self.ClearBearers() 662*9c5db199SXin Li 663*9c5db199SXin Li # Reappear. 664*9c5db199SXin Li def _DelayedReappear(): 665*9c5db199SXin Li self.IncrementPath() 666*9c5db199SXin Li 667*9c5db199SXin Li # Reset to defaults. 668*9c5db199SXin Li if self.sim: 669*9c5db199SXin Li self.sim.Reset() 670*9c5db199SXin Li self._properties = self._InitializeProperties() 671*9c5db199SXin Li if self.sim: 672*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 673*9c5db199SXin Li 'Sim', 674*9c5db199SXin Li dbus.types.ObjectPath(self.sim.path)) 675*9c5db199SXin Li self.UpdateLockStatus() 676*9c5db199SXin Li 677*9c5db199SXin Li if manager: 678*9c5db199SXin Li manager.Add(self) 679*9c5db199SXin Li 680*9c5db199SXin Li self.resetting = False 681*9c5db199SXin Li 682*9c5db199SXin Li def _DelayedEnable(): 683*9c5db199SXin Li state = self.Get(mm1_constants.I_MODEM, 'State') 684*9c5db199SXin Li if not self.IsPendingEnable() and \ 685*9c5db199SXin Li state == mm1_constants.MM_MODEM_STATE_DISABLED: 686*9c5db199SXin Li self.Enable(True) 687*9c5db199SXin Li return False 688*9c5db199SXin Li 689*9c5db199SXin Li GObject.timeout_add(1000, _DelayedEnable) 690*9c5db199SXin Li return False 691*9c5db199SXin Li 692*9c5db199SXin Li GObject.timeout_add(2000, _DelayedReappear) 693*9c5db199SXin Li 694*9c5db199SXin Li def _ErrorCallback(error): 695*9c5db199SXin Li raise error 696*9c5db199SXin Li 697*9c5db199SXin Li if (self.Get(mm1_constants.I_MODEM, 'State') == 698*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_CONNECTED): 699*9c5db199SXin Li self.Disconnect('/', _ResetFunc, _ErrorCallback) 700*9c5db199SXin Li else: 701*9c5db199SXin Li GObject.idle_add(_ResetFunc) 702*9c5db199SXin Li 703*9c5db199SXin Li 704*9c5db199SXin Li @utils.log_dbus_method() 705*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='s') 706*9c5db199SXin Li def FactoryReset(self, code): 707*9c5db199SXin Li """ 708*9c5db199SXin Li Clears the modem's configuration (including persistent configuration and 709*9c5db199SXin Li state), and returns the device to a factory-default state. 710*9c5db199SXin Li 711*9c5db199SXin Li If not required by the modem, code may be ignored. 712*9c5db199SXin Li 713*9c5db199SXin Li This command may or may not power-cycle the device. 714*9c5db199SXin Li 715*9c5db199SXin Li @param code: Carrier specific activation code. 716*9c5db199SXin Li 717*9c5db199SXin Li """ 718*9c5db199SXin Li raise NotImplementedError() 719*9c5db199SXin Li 720*9c5db199SXin Li 721*9c5db199SXin Li @utils.log_dbus_method() 722*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='(uu)') 723*9c5db199SXin Li def SetCurrentModes(self, modes): 724*9c5db199SXin Li """ 725*9c5db199SXin Li Sets the access technologies (eg 2G/3G/4G preference) the device is 726*9c5db199SXin Li currently allowed to use when connecting to a network. 727*9c5db199SXin Li 728*9c5db199SXin Li @param modes: Specifies all the modes allowed in the modem as a bitmask 729*9c5db199SXin Li of MMModemModem values. 730*9c5db199SXin Li @param preferred: Specific MMModemMode preferred among the ones allowed, 731*9c5db199SXin Li if any. 732*9c5db199SXin Li 733*9c5db199SXin Li """ 734*9c5db199SXin Li allowed = self.Get(mm1_constants.I_MODEM, 'SupportedModes') 735*9c5db199SXin Li if not modes in allowed: 736*9c5db199SXin Li raise pm_errors.MMCoreError(pm_errors.MMCoreError.FAILED, 737*9c5db199SXin Li 'Mode not supported: ' + repr(modes)) 738*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 'CurrentModes', modes) 739*9c5db199SXin Li 740*9c5db199SXin Li 741*9c5db199SXin Li @utils.log_dbus_method() 742*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='au') 743*9c5db199SXin Li def SetCurrentBands(self, bands): 744*9c5db199SXin Li """ 745*9c5db199SXin Li Sets the radio frequency and technology bands the device is currently 746*9c5db199SXin Li allowed to use when connecting to a network. 747*9c5db199SXin Li 748*9c5db199SXin Li @param bands: Specifies the bands to be used as a list of MMModemBand 749*9c5db199SXin Li values. 750*9c5db199SXin Li 751*9c5db199SXin Li """ 752*9c5db199SXin Li band_list = [dbus.types.UInt32(band) for band in bands] 753*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 'CurrentBands', band_list) 754*9c5db199SXin Li 755*9c5db199SXin Li 756*9c5db199SXin Li @utils.log_dbus_method() 757*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='su', 758*9c5db199SXin Li out_signature='s') 759*9c5db199SXin Li def Command(self, cmd, timeout): 760*9c5db199SXin Li """ 761*9c5db199SXin Li Allows clients to send commands to the modem. By default, this method 762*9c5db199SXin Li does nothing, but responds by telling the client's fortune to brighten 763*9c5db199SXin Li the client's day. 764*9c5db199SXin Li 765*9c5db199SXin Li @param cmd: Command to send to the modem. 766*9c5db199SXin Li @param timeout: The timeout interval for the command. 767*9c5db199SXin Li @returns: A string containing the response from the modem. 768*9c5db199SXin Li 769*9c5db199SXin Li """ 770*9c5db199SXin Li messages = ['Bananas are tasty and fresh. Have one!', 771*9c5db199SXin Li 'A soft voice may be awfully persuasive.', 772*9c5db199SXin Li 'Be careful or you could fall for some tricks today.', 773*9c5db199SXin Li 'Believe in yourself and others will too.', 774*9c5db199SXin Li 'Carve your name on your heart and not on marble.'] 775*9c5db199SXin Li return random.choice(messages) 776*9c5db199SXin Li 777*9c5db199SXin Li 778*9c5db199SXin Li @utils.log_dbus_method() 779*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='u') 780*9c5db199SXin Li def SetPowerState(self, power_state): 781*9c5db199SXin Li """ 782*9c5db199SXin Li Sets the power state of the modem. This action can only be run when the 783*9c5db199SXin Li modem is in the MM_MODEM_STATE_DISABLED state. 784*9c5db199SXin Li 785*9c5db199SXin Li @param power_state: Specifies the desired power state as a 786*9c5db199SXin Li MMModemPowerState value. 787*9c5db199SXin Li @raises: MMCoreError if state is not DISABLED. 788*9c5db199SXin Li 789*9c5db199SXin Li """ 790*9c5db199SXin Li if (self.Get(mm1_constants.I_MODEM, 'State') != 791*9c5db199SXin Li mm1_constants.MM_MODEM_STATE_DISABLED): 792*9c5db199SXin Li raise pm_errors.MMCoreError( 793*9c5db199SXin Li pm_errors.MMCoreError.WRONG_STATE, 794*9c5db199SXin Li 'Cannot set the power state if modem is not DISABLED.') 795*9c5db199SXin Li self.SetUInt32(mm1_constants.I_MODEM, 'PowerState', power_state); 796*9c5db199SXin Li 797*9c5db199SXin Li 798*9c5db199SXin Li @utils.log_dbus_method() 799*9c5db199SXin Li @dbus.service.method(mm1_constants.I_MODEM, in_signature='u') 800*9c5db199SXin Li def SetCurrentCapabilities(self, capabilities): 801*9c5db199SXin Li """ 802*9c5db199SXin Li Set the capabilities of the device. A restart of the modem may be 803*9c5db199SXin Li required. 804*9c5db199SXin Li 805*9c5db199SXin Li @param capabilities: Bitmask of MMModemCapability values, to specify the 806*9c5db199SXin Li capabilities to use. 807*9c5db199SXin Li 808*9c5db199SXin Li """ 809*9c5db199SXin Li supported = self.Get(mm1_constants.I_MODEM, 'SupportedCapabilities') 810*9c5db199SXin Li if not capabilities in supported: 811*9c5db199SXin Li raise pm_errors.MMCoreError( 812*9c5db199SXin Li pm_errors.MMCoreError.FAILED, 813*9c5db199SXin Li 'Given capabilities not supported: ' + capabilities) 814*9c5db199SXin Li self.SetUInt32(mm1_constants.I_MODEM, 'CurrentCapabilities', 815*9c5db199SXin Li capabilities) 816*9c5db199SXin Li 817*9c5db199SXin Li 818*9c5db199SXin Li @dbus.service.signal(mm1_constants.I_MODEM, signature='iiu') 819*9c5db199SXin Li def StateChanged(self, old, new, reason): 820*9c5db199SXin Li """ 821*9c5db199SXin Li Signals that the modem's 'State' property has changed. 822*9c5db199SXin Li 823*9c5db199SXin Li @param old: Specifies the old state, as a MMModemState value. 824*9c5db199SXin Li @param new: Specifies the new state, as a MMModemState value. 825*9c5db199SXin Li @param reason: Specifies the reason for this state change as a 826*9c5db199SXin Li MMModemStateChangeReason value. 827*9c5db199SXin Li 828*9c5db199SXin Li """ 829*9c5db199SXin Li logging.info('Modem state changed from %u to %u for reason %u', 830*9c5db199SXin Li old, new, reason) 831*9c5db199SXin Li 832*9c5db199SXin Li 833*9c5db199SXin Li # org.freedesktop.ModemManager1.Messaging 834*9c5db199SXin Li 835*9c5db199SXin Li def List(self): 836*9c5db199SXin Li """ 837*9c5db199SXin Li Overriden from messaging.Messaging. 838*9c5db199SXin Li 839*9c5db199SXin Li """ 840*9c5db199SXin Li return self._sms_handler.list_messages() 841*9c5db199SXin Li 842*9c5db199SXin Li 843*9c5db199SXin Li def Delete(self, path): 844*9c5db199SXin Li """ 845*9c5db199SXin Li Overriden from messaging.Messaging. 846*9c5db199SXin Li 847*9c5db199SXin Li @param path 848*9c5db199SXin Li 849*9c5db199SXin Li """ 850*9c5db199SXin Li self._sms_handler.delete_message(path) 851*9c5db199SXin Li 852*9c5db199SXin Li 853*9c5db199SXin Li @dbus.service.signal(mm1_constants.I_MODEM_MESSAGING, signature='ob') 854*9c5db199SXin Li def Added(self, path, received): 855*9c5db199SXin Li """ 856*9c5db199SXin Li Overriden from messaging.Messaging. 857*9c5db199SXin Li 858*9c5db199SXin Li @param path 859*9c5db199SXin Li @param received 860*9c5db199SXin Li 861*9c5db199SXin Li """ 862*9c5db199SXin Li logging.info('New SMS added: path: ' + path + ' received: ' + 863*9c5db199SXin Li str(received)) 864*9c5db199SXin Li 865*9c5db199SXin Li 866*9c5db199SXin Li def _UpdateBearersProperty(self): 867*9c5db199SXin Li """ 868*9c5db199SXin Li Update the 'Bearers' property on |I_MODEM| interface to match the 869*9c5db199SXin Li internal list. 870*9c5db199SXin Li 871*9c5db199SXin Li """ 872*9c5db199SXin Li bearers = dbus.Array( 873*9c5db199SXin Li [dbus.types.ObjectPath(key) for key in six.iterkeys(self.bearers)], 874*9c5db199SXin Li signature='o') 875*9c5db199SXin Li self.Set(mm1_constants.I_MODEM, 'Bearers', bearers) 876