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 dbus_std_ifaces
8import utils
9
10import common
11from autotest_lib.client.cros.cellular import mm1_constants
12from autotest_lib.client.cros.cellular import net_interface
13
14class Bearer(dbus_std_ifaces.DBusProperties):
15    """
16    Fake implementation of the org.freedesktop.ModemManager1.Bearer
17    interface. Bearer objects are owned and managed by specific Modem objects.
18    A single Modem may expose one or more Bearer objects, which can then be
19    used to get the modem into connected state.
20
21    """
22
23    count = 0
24
25    def __init__(self, bus, properties, config=None):
26        self._active = False
27        self._bearer_props = properties
28        path = '%s/Bearer/%d' % (mm1_constants.MM1, Bearer.count)
29        Bearer.count += 1
30        dbus_std_ifaces.DBusProperties.__init__(self, path, bus, config)
31
32
33    def _InitializeProperties(self):
34        props = {
35            'Interface': net_interface.PseudoNetInterface.IFACE_NAME,
36            'Connected': dbus.types.Boolean(False),
37            'Suspended': dbus.types.Boolean(False),
38            'Properties': self._bearer_props
39        }
40        return { mm1_constants.I_BEARER: props }
41
42
43    def _AddProperty(self, property_key):
44        self._properties[mm1_constants.I_BEARER][property_key] = None
45
46
47    def _RemoveProperty(self, property_key):
48        try:
49            self._properties[mm1_constants.I_BEARER].pop(property_key)
50        except KeyError:
51            pass
52
53
54    def IsActive(self):
55        """
56        @returns: True, if the bearer is currently active.
57
58        """
59        return self._active
60
61
62    @property
63    def bearer_properties(self):
64        """
65        @returns: The current bearer properties that were set during a call to
66                org.freedesktop.ModemManager1.Modem.Simple.Connect.
67
68        """
69        return self._bearer_props
70
71
72    @utils.log_dbus_method()
73    @dbus.service.method(mm1_constants.I_BEARER)
74    def Connect(self):
75        """
76        Requests activation of a packet data connection with the network using
77        this bearer's properties. Upon successful activation, the modem can
78        send and receive packet data and, depending on the addressing
79        capability of the modem, a connection manager may need to start PPP,
80        perform DHCP, or assign the IP address returned by the modem to the
81        data interface. Upon successful return, the "Ip4Config" and/or
82        "Ip6Config" properties become valid and may contain IP configuration
83        information for the data interface associated with this bearer.
84
85        Since this is a mock implementation, this bearer will not establish
86        a real connection with the outside world. Since shill does not specify
87        IP addressing information to the bearer, we do not need to populate
88        these properties.
89
90        """
91        # Set the ip config property
92        ip_family = self._bearer_props.get('ip-type', None)
93        if ip_family and ip_family >= mm1_constants.MM_BEARER_IP_FAMILY_IPV6:
94            config_prop = 'Ip6Config'
95        else:
96            config_prop = 'Ip4Config'
97
98        self._AddProperty('Ip4Config')
99        self.Set(mm1_constants.I_BEARER, config_prop, {
100            'method': dbus.types.UInt32(mm1_constants.MM_BEARER_IP_METHOD_DHCP,
101                                        variant_level=1)
102        })
103        self._active = True
104        self.Set(mm1_constants.I_BEARER, 'Connected', dbus.types.Boolean(True))
105
106
107    @utils.log_dbus_method()
108    @dbus.service.method(mm1_constants.I_BEARER)
109    def Disconnect(self):
110        """
111        Disconnect and deactivate this packet data connection. In a real bearer,
112        any ongoing data session would be terminated and IP addresses would
113        become invalid when this method is called, however, the fake
114        implementation doesn't set the IP properties.
115
116        """
117        self._RemoveProperty('Ip4Config')
118        self._RemoveProperty('Ip6Config')
119        self._active = False
120        self.Set(mm1_constants.I_BEARER, 'Connected',
121                 dbus.types.Boolean(False))
122