• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 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 json
6
7from autotest_lib.client.cros import constants
8from autotest_lib.server import autotest
9
10
11class BluetoothDevice(object):
12    """BluetoothDevice is a thin layer of logic over a remote DUT.
13
14    The Autotest host object representing the remote DUT, passed to this
15    class on initialization, can be accessed from its host property.
16
17    """
18
19    XMLRPC_BRINGUP_TIMEOUT_SECONDS = 60
20    XMLRPC_LOG_PATH = '/var/log/bluetooth_xmlrpc_device.log'
21
22    def __init__(self, device_host):
23        """Construct a BluetoothDevice.
24
25        @param device_host: host object representing a remote host.
26
27        """
28        self.host = device_host
29        # Make sure the client library is on the device so that the proxy code
30        # is there when we try to call it.
31        client_at = autotest.Autotest(self.host)
32        client_at.install()
33        # Start up the XML-RPC proxy on the client.
34        self._proxy = self.host.rpc_server_tracker.xmlrpc_connect(
35                constants.BLUETOOTH_DEVICE_XMLRPC_SERVER_COMMAND,
36                constants.BLUETOOTH_DEVICE_XMLRPC_SERVER_PORT,
37                command_name=
38                  constants.BLUETOOTH_DEVICE_XMLRPC_SERVER_CLEANUP_PATTERN,
39                ready_test_name=
40                  constants.BLUETOOTH_DEVICE_XMLRPC_SERVER_READY_METHOD,
41                timeout_seconds=self.XMLRPC_BRINGUP_TIMEOUT_SECONDS,
42                logfile=self.XMLRPC_LOG_PATH)
43
44
45    def reset_on(self):
46        """Reset the adapter and settings and power up the adapter.
47
48        @return True on success, False otherwise.
49
50        """
51        return self._proxy.reset_on()
52
53
54    def reset_off(self):
55        """Reset the adapter and settings, leave the adapter powered off.
56
57        @return True on success, False otherwise.
58
59        """
60        return self._proxy.reset_off()
61
62
63    def has_adapter(self):
64        """@return True if an adapter is present, False if not."""
65        return self._proxy.has_adapter()
66
67
68    def set_powered(self, powered):
69        """Set the adapter power state.
70
71        @param powered: adapter power state to set (True or False).
72
73        @return True on success, False otherwise.
74
75        """
76        return self._proxy.set_powered(powered)
77
78
79    def set_discoverable(self, discoverable):
80        """Set the adapter discoverable state.
81
82        @param discoverable: adapter discoverable state to set (True or False).
83
84        @return True on success, False otherwise.
85
86        """
87        return self._proxy.set_discoverable(discoverable)
88
89
90    def set_pairable(self, pairable):
91        """Set the adapter pairable state.
92
93        @param pairable: adapter pairable state to set (True or False).
94
95        @return True on success, False otherwise.
96
97        """
98        return self._proxy.set_pairable(pairable)
99
100
101    def get_adapter_properties(self):
102        """Read the adapter properties from the Bluetooth Daemon.
103
104        @return the properties as a dictionary on success,
105            the value False otherwise.
106
107        """
108        return json.loads(self._proxy.get_adapter_properties())
109
110
111    def read_version(self):
112        """Read the version of the management interface from the Kernel.
113
114        @return the version as a tuple of:
115          ( version, revision )
116
117        """
118        return json.loads(self._proxy.read_version())
119
120
121    def read_supported_commands(self):
122        """Read the set of supported commands from the Kernel.
123
124        @return set of supported commands as arrays in a tuple of:
125          ( commands, events )
126
127        """
128        return json.loads(self._proxy.read_supported_commands())
129
130
131    def read_index_list(self):
132        """Read the list of currently known controllers from the Kernel.
133
134        @return array of controller indexes.
135
136        """
137        return json.loads(self._proxy.read_index_list())
138
139
140    def read_info(self):
141        """Read the adapter information from the Kernel.
142
143        @return the information as a tuple of:
144          ( address, bluetooth_version, manufacturer_id,
145            supported_settings, current_settings, class_of_device,
146            name, short_name )
147
148        """
149        return json.loads(self._proxy.read_info())
150
151
152    def add_device(self, address, address_type, action):
153        """Add a device to the Kernel action list.
154
155        @param address: Address of the device to add.
156        @param address_type: Type of device in @address.
157        @param action: Action to take.
158
159        @return tuple of ( address, address_type ) on success,
160          None on failure.
161
162        """
163        return json.loads(self._proxy.add_device(address, address_type, action))
164
165
166    def remove_device(self, address, address_type):
167        """Remove a device from the Kernel action list.
168
169        @param address: Address of the device to remove.
170        @param address_type: Type of device in @address.
171
172        @return tuple of ( address, address_type ) on success,
173          None on failure.
174
175        """
176        return json.loads(self._proxy.remove_device(address, address_type))
177
178
179    def get_devices(self):
180        """Read information about remote devices known to the adapter.
181
182        @return the properties of each device as an array of
183            dictionaries on success, the value False otherwise.
184
185        """
186        return json.loads(self._proxy.get_devices())
187
188
189    def start_discovery(self):
190        """Start discovery of remote devices.
191
192        Obtain the discovered device information using get_devices(), called
193        stop_discovery() when done.
194
195        @return True on success, False otherwise.
196
197        """
198        return self._proxy.start_discovery()
199
200
201    def stop_discovery(self):
202        """Stop discovery of remote devices.
203
204        @return True on success, False otherwise.
205
206        """
207        return self._proxy.stop_discovery()
208
209
210    def get_dev_info(self):
211        """Read raw HCI device information.
212
213        @return tuple of (index, name, address, flags, device_type, bus_type,
214                       features, pkt_type, link_policy, link_mode,
215                       acl_mtu, acl_pkts, sco_mtu, sco_pkts,
216                       err_rx, err_tx, cmd_tx, evt_rx, acl_tx, acl_rx,
217                       sco_tx, sco_rx, byte_rx, byte_tx) on success,
218                None on failure.
219
220        """
221        return json.loads(self._proxy.get_dev_info())
222
223
224    def register_profile(self, path, uuid, options):
225        """Register new profile (service).
226
227        @param path: Path to the profile object.
228        @param uuid: Service Class ID of the service as string.
229        @param options: Dictionary of options for the new service, compliant
230                        with BlueZ D-Bus Profile API standard.
231
232        @return True on success, False otherwise.
233
234        """
235        return self._proxy.register_profile(path, uuid, options)
236
237
238    def has_device(self, address):
239        """Checks if the device with a given address exists.
240
241        @param address: Address of the device.
242
243        @returns: True if there is a device with that address.
244                  False otherwise.
245
246        """
247        return self._proxy.has_device(address)
248
249
250    def pair_legacy_device(self, address, pin, timeout):
251        """Pairs a device with a given pin code.
252
253        Registers an agent who handles pin code request and
254        pairs a device with known pin code.
255
256        @param address: Address of the device to pair.
257        @param pin: The pin code of the device to pair.
258        @param timeout: The timeout in seconds for pairing.
259
260        @returns: True on success. False otherwise.
261
262        """
263        return self._proxy.pair_legacy_device(address, pin, timeout)
264
265
266    def connect_device(self, address):
267        """Connects a device.
268
269        Connects a device if it is not connected.
270
271        @param address: Address of the device to connect.
272
273        @returns: True on success. False otherwise.
274
275        """
276        return self._proxy.connect_device(address)
277
278
279    def device_is_connected(self, address):
280        """Checks if a device is connected.
281
282        @param address: Address of the device to check if it is connected.
283
284        @returns: True if device is connected. False otherwise.
285
286        """
287        return self._proxy.device_is_connected(address)
288
289
290    def disconnect_device(self, address):
291        """Disconnects a device.
292
293        Disconnects a device if it is connected.
294
295        @param address: Address of the device to disconnect.
296
297        @returns: True on success. False otherwise.
298
299        """
300        return self._proxy.disconnect_device(address)
301
302
303    def copy_logs(self, destination):
304        """Copy the logs generated by this device to a given location.
305
306        @param destination: destination directory for the logs.
307
308        """
309        self.host.collect_logs(self.XMLRPC_LOG_PATH, destination)
310
311
312    def close(self):
313        """Tear down state associated with the client."""
314        # Turn off the discoverable flag since it may affect future tests.
315        self._proxy.set_discoverable(False)
316        # Leave the adapter powered off, but don't do a full reset.
317        self._proxy.set_powered(False)
318        # This kills the RPC server.
319        self.host.close()
320