19d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 29d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le# Use of this source code is governed by a BSD-style license that can be 39d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le# found in the LICENSE file. 49d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 59d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le""" 69d632a90777f69bb476c06be35a61d5fc338c8b3Thieu LeThis module provides bindings for ModemManager1. 79d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 89d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le""" 99d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 109d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Leimport dbus 119d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Leimport dbus.mainloop.glib 129d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 139d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Lefrom autotest_lib.client.bin import utils 149d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Lefrom autotest_lib.client.cros.cellular import mm1_constants 159d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 169d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 17c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhudef _is_unknown_dbus_binding_exception(e): 18c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return (isinstance(e, dbus.exceptions.DBusException) and 19c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu e.get_dbus_name() in [mm1_constants.DBUS_SERVICE_UNKNOWN, 20c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu mm1_constants.DBUS_UNKNOWN_METHOD, 21c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu mm1_constants.DBUS_UNKNOWN_OBJECT, 22c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu mm1_constants.DBUS_UNKNOWN_INTERFACE]) 23c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 24c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 259d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Leclass ModemManager1ProxyError(Exception): 269d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """Exceptions raised by ModemManager1ProxyError and it's children.""" 279d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le pass 289d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 299d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 309d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Leclass ModemManager1Proxy(object): 319d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """A wrapper around a DBus proxy for ModemManager1.""" 329d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 339d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # Amount of time to wait between attempts to connect to ModemManager1. 349d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le CONNECT_WAIT_INTERVAL_SECONDS = 0.2 359d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 369d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @classmethod 3716f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le def get_proxy(cls, bus=None, timeout_seconds=10): 389d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """Connect to ModemManager1 over DBus, retrying if necessary. 399d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 409d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le After connecting to ModemManager1, this method will verify that 419d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le ModemManager1 is answering RPCs. 429d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 4316f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le @param bus: D-Bus bus to use, or specify None and this object will 4416f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le create a mainloop and bus. 459d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @param timeout_seconds: float number of seconds to try connecting 469d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le A value <= 0 will cause the method to return immediately, 479d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le without trying to connect. 489d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @return a ModemManager1Proxy instance if we connected, or None 499d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le otherwise. 509d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @raise ModemManager1ProxyError if it fails to connect to 519d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le ModemManager1. 529d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 539d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """ 5416f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le def _connect_to_mm1(bus): 559d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le try: 569d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # We create instance of class on which this classmethod was 579d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # called. This way, calling 589d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # SubclassOfModemManager1Proxy.get_proxy() will get a proxy of 599d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # the right type. 6016f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le return cls(bus=bus) 619d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le except dbus.exceptions.DBusException as e: 62c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu if _is_unknown_dbus_binding_exception(e): 63c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return None 64c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu raise ModemManager1ProxyError( 65c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 'Error connecting to ModemManager1. DBus error: |%s|', 66c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu repr(e)) 679d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 689d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le utils.poll_for_condition( 6916f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le lambda: _connect_to_mm1(bus) is not None, 709d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le exception=ModemManager1ProxyError( 719d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'Timed out connecting to ModemManager1'), 729d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le timeout=timeout_seconds, 739d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le sleep_interval=ModemManager1Proxy.CONNECT_WAIT_INTERVAL_SECONDS) 7416f7eebb7d05cdfb4f7dd96316085805291b16b0Thieu Le connection = _connect_to_mm1(bus) 759d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 769d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # Check to make sure ModemManager1 is responding to DBus requests by 779d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # setting the logging to debug. 789d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le connection.manager.SetLogging('DEBUG', timeout=timeout_seconds) 799d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 809d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return connection 819d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 829d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 839d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def __init__(self, bus=None): 849d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le if bus is None: 859d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 869d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le bus = dbus.SystemBus() 879d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self._bus = bus 889d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self._manager = dbus.Interface( 899d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self._bus.get_object(mm1_constants.I_MODEM_MANAGER, 909d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM1), 919d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.I_MODEM_MANAGER) 929d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 939d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 949d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 959d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def manager(self): 969d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return the DBus ModemManager1 Manager object.""" 979d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return self._manager 989d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 999d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1009d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def get_modem(self): 1019d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """ 1029d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le Return the one and only modem object. 1039d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1049d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le This method distinguishes between no modem and more than one modem. 1059d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le In the former, this could happen if the modem has not yet surfaced and 1069d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le is not really considered an error. The caller can wait for the modem 1079d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le by repeatedly calling this method. In the latter, it is a clear error 1089d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le condition and an exception will be raised. 1099d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1109d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le Every call to |get_modem| obtains a fresh DBus proxy for the modem. So, 1119d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le if the modem DBus object has changed between two calls to this method, 1129d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le the proxy returned will be for the currently exported modem. 1139d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1149d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @return a ModemProxy object. Return None if no modem is found. 1159d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @raise ModemManager1ProxyError unless exactly one modem is found. 1169d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1179d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """ 1189d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le try: 1199d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le object_manager = dbus.Interface( 1209d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self._bus.get_object(mm1_constants.I_MODEM_MANAGER, 1219d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM1), 1229d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.I_OBJECT_MANAGER) 1239d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le modems = object_manager.GetManagedObjects() 1249d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le except dbus.exceptions.DBusException as e: 1259d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le raise ModemManager1ProxyError( 1269d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'Failed to list the available modems. DBus error: |%s|', 1279d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le repr(e)) 1289d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1299d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le if not modems: 1309d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return None 1319d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le elif len(modems) > 1: 1329d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le raise ModemManager1ProxyError( 1339d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'Expected one modem object, found %d', len(modems)) 1349d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1359d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le modem_proxy = ModemProxy(self._bus, modems.keys()[0]) 1369d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # Check that this object is valid 1379d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le try: 1389d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le modem_proxy.modem.GetAll(mm1_constants.I_MODEM, 1399d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le dbus_interface=mm1_constants.I_PROPERTIES) 1409d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return modem_proxy 1419d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le except dbus.exceptions.DBusException as e: 142c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu if _is_unknown_dbus_binding_exception(e): 143c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return None 1449d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le raise ModemManager1ProxyError( 1459d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'Failed to obtain dbus object for the modem. DBus error: ' 1469d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le '|%s|', repr(e)) 1479d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1489d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1498f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le def wait_for_modem(self, timeout_seconds): 1508f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le """ 1518f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le Wait for the modem to appear. 1528f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le 1538f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le @param timeout_seconds: Number of seconds to wait for modem to appear. 1548f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le @return a ModemProxy object. 1558f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le @raise ModemManager1ProxyError if no modem is found within the timeout 1568f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le or if more than one modem is found. NOTE: This method does not 1578f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le wait for a second modem. The exception is raised if there is 1588f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le more than one modem at the time of polling. 1598f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le 1608f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le """ 1618f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le return utils.poll_for_condition( 1628f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le self.get_modem, 1638f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le exception=ModemManager1ProxyError('No modem found'), 1648f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le timeout=timeout_seconds) 1658f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le 1668f87650ea068c2b1a7ed5e8d5818f236dd13c8fcThieu Le 1679d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Leclass ModemProxy(object): 1689d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """A wrapper around a DBus proxy for ModemManager1 modem object.""" 1699d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1709d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le # Amount of time to wait for a state transition. 1719d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le STATE_TRANSITION_WAIT_SECONDS = 10 1729d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1739d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def __init__(self, bus, path): 1749d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self._bus = bus 1759d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self._modem = self._bus.get_object(mm1_constants.I_MODEM_MANAGER, path) 1769d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1779d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1789d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 1799d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def modem(self): 1809d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return the DBus modem object.""" 1819d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return self._modem 1829d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1839d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1849d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 1859d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def iface_modem(self): 1869d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return org.freedesktop.ModemManager1.Modem DBus interface.""" 1879d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return dbus.Interface(self._modem, mm1_constants.I_MODEM) 1889d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1899d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1909d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 1919d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def iface_simple_modem(self): 1929d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return org.freedesktop.ModemManager1.Simple DBus interface.""" 1939d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return dbus.Interface(self._modem, mm1_constants.I_MODEM_SIMPLE) 1949d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1959d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 1969d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 1979d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def iface_gsm_modem(self): 1989d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return org.freedesktop.ModemManager1.Modem3gpp DBus interface.""" 1999d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return dbus.Interface(self._modem, mm1_constants.I_MODEM_3GPP) 2009d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2019d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2029d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 2039d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def iface_cdma_modem(self): 2049d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return org.freedesktop.ModemManager1.ModemCdma DBus interface.""" 2059d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return dbus.Interface(self._modem, mm1_constants.I_MODEM_CDMA) 2069d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2079d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2089d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @property 2099d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def iface_properties(self): 2109d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """@return org.freedesktop.DBus.Properties DBus interface.""" 2119d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return dbus.Interface(self._modem, dbus.PROPERTIES_IFACE) 2129d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2139d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2149d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def properties(self, iface): 2159d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """Return the properties associated with the specified interface. 2169d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2179d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @param iface: Name of interface to retrieve the properties from. 2189d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @return array of properties. 2199d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2209d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """ 2219d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le return self.iface_properties.GetAll(iface) 2229d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2239d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 224c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu def get_sim(self): 225c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """ 226c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu Return the SIM proxy object associated with this modem. 227c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 228c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu @return SimProxy object or None if no SIM exists. 229c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 230c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """ 231c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu sim_path = self.properties(mm1_constants.I_MODEM).get('Sim') 232c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu if not sim_path: 233c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return None 234c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu sim_proxy = SimProxy(self._bus, sim_path) 235c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu # Check that this object is valid 236c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu try: 237c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu sim_proxy.properties(mm1_constants.I_SIM) 238c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return sim_proxy 239c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu except dbus.exceptions.DBusException as e: 240c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu if _is_unknown_dbus_binding_exception(e): 241c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return None 242c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu raise ModemManager1ProxyError( 243c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 'Failed to obtain dbus object for the SIM. DBus error: ' 244c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu '|%s|', repr(e)) 245c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 246c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 2479d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le def wait_for_states(self, states, 2489d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le timeout_seconds=STATE_TRANSITION_WAIT_SECONDS): 2499d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """ 2509d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le Wait for the modem to transition to a state in |states|. 2519d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2529d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le This method does not support transitory states (eg. enabling, 2539d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le disabling, connecting, disconnecting, etc). 2549d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2559d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @param states: List of states the modem can transition to. 2569d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @param timeout_seconds: Max number of seconds to wait. 2579d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le @raise ModemManager1ProxyError if the modem does not transition to 2589d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le one of the accepted states. 2599d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2609d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le """ 2619d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le for state in states: 2629d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le if state in [mm1_constants.MM_MODEM_STATE_INITIALIZING, 2639d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_STATE_DISABLING, 2649d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_STATE_ENABLING, 2659d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_STATE_SEARCHING, 2669d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_STATE_DISCONNECTING, 2679d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_STATE_CONNECTING]: 2689d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le raise ModemManager1ProxyError( 2699d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'wait_for_states() does not support transitory states.') 2709d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2719d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le utils.poll_for_condition( 2729d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le lambda: self.properties(mm1_constants.I_MODEM)[ 2739d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_PROPERTY_NAME_STATE] in states, 2749d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le exception=ModemManager1ProxyError( 2759d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'Timed out waiting for modem to enter one of these ' 2769d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 'states: %s, current state=%s', 2779d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le states, 2789d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le self.properties(mm1_constants.I_MODEM)[ 2799d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le mm1_constants.MM_MODEM_PROPERTY_NAME_STATE]), 2809d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le timeout=timeout_seconds) 2819d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 2829d632a90777f69bb476c06be35a61d5fc338c8b3Thieu Le 283c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhuclass SimProxy(object): 284c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """A wrapper around a DBus proxy for ModemManager1 SIM object.""" 285c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 286c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu def __init__(self, bus, path): 287c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu self._bus = bus 288c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu self._sim = self._bus.get_object(mm1_constants.I_MODEM_MANAGER, path) 289c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 290c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 291c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu @property 292c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu def sim(self): 293c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """@return the DBus SIM object.""" 294c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return self._sim 295c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 296c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 297c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu @property 298c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu def iface_properties(self): 299c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """@return org.freedesktop.DBus.Properties DBus interface.""" 300c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return dbus.Interface(self._sim, dbus.PROPERTIES_IFACE) 301c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 302c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 303c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu @property 304c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu def iface_sim(self): 305c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """@return org.freedesktop.ModemManager1.Sim DBus interface.""" 306c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return dbus.Interface(self._sim, mm1_constants.I_SIM) 307c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 308c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 309c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu def properties(self, iface=mm1_constants.I_SIM): 310c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """Return the properties associated with the specified interface. 311c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 312c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu @param iface: Name of interface to retrieve the properties from. 313c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu @return array of properties. 314c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu 315c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu """ 316c62e556725820b3c37c175b7bac8496e42020d4cPrathmesh Prabhu return self.iface_properties.GetAll(iface) 317