1# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import dbus
6
7import common
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.cros.cellular import modem
10from autotest_lib.client.cros.cellular import modem1
11
12
13MMPROVIDERS = ['org.chromium', 'org.freedesktop']
14SERVICE_UNKNOWN = 'org.freedesktop.DBus.Error.ServiceUnknown'
15
16
17def GetManager():
18    """Returns a ModemManager object.
19
20    Attempts to connect to various modemmanagers, including
21    ModemManager classic interfaces, ModemManager using the
22    ModemManager1 interfaces and cromo and return the first
23    ModemManager that is found.
24
25    Returns:
26        a ModemManager object.
27    """
28    for provider in MMPROVIDERS:
29        try:
30            return modem.ModemManager(provider)
31        except dbus.exceptions.DBusException, e:
32            if e._dbus_error_name != SERVICE_UNKNOWN:
33                raise
34
35    try:
36        return modem1.ModemManager()
37    except dbus.exceptions.DBusException, e:
38        if e._dbus_error_name != SERVICE_UNKNOWN:
39            raise
40
41    return None
42
43
44def EnumerateDevices(manager=None):
45    """Enumerates all modems in the system.
46
47    Args:
48        manager: the specific manager to use, if None use the first valid
49                 manager
50
51    Returns:
52        a list of (ModemManager object, modem dbus path)
53    """
54    if not manager:
55        manager = GetManager()
56    if not manager:
57        raise error.TestError('Cannot connect to the modem manager, is '
58                              'ModemManager/cromo/PseudoModemManager running?')
59
60    result = []
61    for path in manager.EnumerateDevices():
62        result.append((manager, path))
63
64    return result
65
66
67def PickOneModem(modem_pattern, manager=None):
68    """Pick a modem.
69
70    If a machine has a single modem, managed by one of the MMPROVIDERS,
71    return the dbus path and a ModemManager object for that modem.
72
73    Args:
74        modem_pattern: pattern that should match the modem path
75        manager: the specific manager to use, if None check all known managers
76
77    Returns:
78        (ModemManager, Modem DBUS Path) tuple
79
80    Raises:
81        TestError: if there are no matching modems, or there are more
82                   than one
83    """
84    devices = EnumerateDevices(manager)
85
86    matches = [(m, path) for m, path in devices if modem_pattern in path]
87    if not matches:
88        raise error.TestError('No modems had substring: ' + modem_pattern)
89    if len(matches) > 1:
90        raise error.TestError('Expected only one modem, got: ' +
91                              ', '.join([modem.path for modem in matches]))
92    return matches[0]
93