blob: a23f7f547848b41dd5389f1fba7d967ead80f851 [file] [log] [blame]
Scott James Remnant4dcd73f2013-07-22 15:00:24 -07001# 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
Scott James Remnantda9f43c2013-08-07 17:53:14 -07005import base64
6import json
7
Scott James Remnant4dcd73f2013-07-22 15:00:24 -07008from autotest_lib.client.cros import constants
Scott James Remnant1ca2e0e2013-07-31 16:49:07 -07009from autotest_lib.server import autotest, hosts
Scott James Remnant4dcd73f2013-07-22 15:00:24 -070010
11
12class BluetoothTester(object):
Scott James Remnant1c72d7a2013-07-29 15:00:04 -070013 """BluetoothTester is a thin layer of logic over a remote tester.
14
15 The Autotest host object representing the remote tester, passed to this
16 class on initialization, can be accessed from its host property.
17
18 """
19
Scott James Remnant4dcd73f2013-07-22 15:00:24 -070020
21 XMLRPC_BRINGUP_TIMEOUT_SECONDS = 60
22
Scott James Remnant4dcd73f2013-07-22 15:00:24 -070023 def __init__(self, tester_host):
24 """Construct a BluetoothTester.
25
Scott James Remnant1c72d7a2013-07-29 15:00:04 -070026 @param tester_host: host object representing a remote host.
Scott James Remnant4dcd73f2013-07-22 15:00:24 -070027
28 """
Scott James Remnant1c72d7a2013-07-29 15:00:04 -070029 self.host = tester_host
Scott James Remnant4dcd73f2013-07-22 15:00:24 -070030 # Make sure the client library is on the device so that the proxy code
31 # is there when we try to call it.
32 client_at = autotest.Autotest(self.host)
33 client_at.install()
34 # Start up the XML-RPC proxy on the tester.
35 self._proxy = self.host.xmlrpc_connect(
36 constants.BLUETOOTH_TESTER_XMLRPC_SERVER_COMMAND,
37 constants.BLUETOOTH_TESTER_XMLRPC_SERVER_PORT,
38 command_name=
39 constants.BLUETOOTH_TESTER_XMLRPC_SERVER_CLEANUP_PATTERN,
40 ready_test_name=
41 constants.BLUETOOTH_TESTER_XMLRPC_SERVER_READY_METHOD,
42 timeout_seconds=self.XMLRPC_BRINGUP_TIMEOUT_SECONDS)
43
Scott James Remnant1c72d7a2013-07-29 15:00:04 -070044
Scott James Remnantda9f43c2013-08-07 17:53:14 -070045 def setup(self, profile):
46 """Set up the tester with the given profile.
47
48 @param profile: Profile to use for this test, valid values are:
49 computer - a standard computer profile
50
51 @return True on success, False otherwise.
52
53 """
54 return self._proxy.setup(profile)
55
56
Scott James Remnantaec4edd2013-08-26 18:47:11 -070057 def set_discoverable(self, discoverable, timeout=0):
58 """Set the discoverable state of the controller.
59
60 @param discoverable: Whether controller should be discoverable.
61 @param timeout: Timeout in seconds before disabling discovery again,
62 ignored when discoverable is False, must not be zero when
63 discoverable is True.
64
65 @return True on success, False otherwise.
66
67 """
68 return self._proxy.set_discoverable(discoverable, timeout)
69
70
71 def read_info(self):
72 """Read the adapter information from the Kernel.
73
74 @return the information as a JSON-encoded tuple of:
75 ( address, bluetooth_version, manufacturer_id,
76 supported_settings, current_settings, class_of_device,
77 name, short_name )
78
79 """
80 return json.loads(self._proxy.read_info())
81
82
Scott James Remnantda9f43c2013-08-07 17:53:14 -070083 def discover_devices(self, br_edr=True, le_public=True, le_random=True):
84 """Discover remote devices.
85
86 Activates device discovery and collects the set of devices found,
87 returning them as a list.
88
89 @param br_edr: Whether to detect BR/EDR devices.
90 @param le_public: Whether to detect LE Public Address devices.
91 @param le_random: Whether to detect LE Random Address devices.
92
93 @return List of devices found as tuples with the format
94 (address, address_type, rssi, flags, base64-encoded eirdata),
95 or False if discovery could not be started.
96
97 """
98 devices = self._proxy.discover_devices(br_edr, le_public, le_random)
99 if devices == False:
100 return False
101
102 return (
103 (address, address_type, rssi, flags,
104 base64.decodestring(eirdata))
105 for address, address_type, rssi, flags, eirdata
106 in json.loads(devices)
107 )
108
109
Scott James Remnant4dcd73f2013-07-22 15:00:24 -0700110 def close(self):
111 """Tear down state associated with the client."""
112 # This kills the RPC server.
Scott James Remnant1c72d7a2013-07-29 15:00:04 -0700113 self.host.close()
Scott James Remnant1ca2e0e2013-07-31 16:49:07 -0700114
115
Artem Rakhov448d52c2013-12-03 16:38:36 -0800116 def connect(self, address):
117 """Connect to device with the given address
118
119 @param address: Bluetooth address.
120
121 """
122 self._proxy.connect(address)
123
124
Artem Rakhovca443b52014-01-10 17:18:24 -0800125 def service_search_request(self, uuids, max_rec_cnt, preferred_size=32):
Artem Rakhov448d52c2013-12-03 16:38:36 -0800126 """Send a Service Search Request
127
128 @param uuids: List of UUIDs (in 32-bit format) to look for.
129 @param max_rec_cnt: Maximum count of returned service records.
Artem Rakhovca443b52014-01-10 17:18:24 -0800130 @param preferred_size: Preffered size of UUIDs in bits (16, 32, or 128).
Artem Rakhov448d52c2013-12-03 16:38:36 -0800131
132 @return list of found services' service record handles
133
134 """
Artem Rakhovca443b52014-01-10 17:18:24 -0800135 return self._proxy.service_search_request(uuids, max_rec_cnt,
136 preferred_size)
Artem Rakhov448d52c2013-12-03 16:38:36 -0800137
138
Scott James Remnant8d2cbf32013-11-12 11:00:25 -0800139def create_host_from(device_host):
Scott James Remnant1ca2e0e2013-07-31 16:49:07 -0700140 """Creates a host object for the Tester associated with a DUT.
141
142 Will raise an exception if there isn't a tester for the DUT.
143
Scott James Remnant8d2cbf32013-11-12 11:00:25 -0800144 @param device_host: Autotest host object for the DUT.
Scott James Remnant1ca2e0e2013-07-31 16:49:07 -0700145
146 @return Autotest host object for the Tester.
147
148 """
149
Scott James Remnant8d2cbf32013-11-12 11:00:25 -0800150 device_hostname = device_host.hostname
Scott James Remnant1ca2e0e2013-07-31 16:49:07 -0700151
Scott James Remnant8d2cbf32013-11-12 11:00:25 -0800152 parts = device_hostname.split('.')
Scott James Remnant1ca2e0e2013-07-31 16:49:07 -0700153 parts[0] = parts[0] + '-bluetooth'
154 tester_hostname = '.'.join(parts)
155
156 return hosts.create_host(tester_hostname)