blob: 3d71ebc3e19104cbd1f6849967df52130f5f71f6 [file] [log] [blame]
Jakub Pawlowskie6578d92017-03-09 15:29:59 -08001#/usr/bin/env python3.4
2#
3# Copyright (C) 2016 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16"""
17This test script exercises different Bluetooth 5 specific scan scenarios.
18It is expected that the second AndroidDevice is able to advertise.
19
20This test script was designed with this setup in mind:
21Shield box one: Android Device, Android Device
22"""
23
24from queue import Empty
25
26from acts import asserts
27from acts.test_decorators import test_tracker_info
28from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
29from acts.test_utils.bt.BleEnum import ScanSettingsPhy
30from acts.test_utils.bt.BleEnum import ScanSettingsScanMode
31from acts.test_utils.bt.bt_test_utils import batch_scan_result
32from acts.test_utils.bt.bt_test_utils import cleanup_scanners_and_advertisers
33from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
34from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
35from acts.test_utils.bt.bt_test_utils import reset_bluetooth
36from acts.test_utils.bt.bt_test_utils import scan_result
Jakub Pawlowski2cc87a22017-04-24 08:33:27 -070037from acts.test_utils.bt.bt_test_utils import advertising_set_on_own_address_read
38from acts.test_utils.bt.bt_test_utils import advertising_set_started
Jakub Pawlowskie6578d92017-03-09 15:29:59 -080039from acts import signals
40
41
42class Bt5ScanTest(BluetoothBaseTest):
43 default_timeout = 10
44 max_scan_instances = 28
45 report_delay = 2000
46 scan_callbacks = []
47 adv_callbacks = []
48 active_scan_callback_list = []
49 big_adv_data = {
50 "includeDeviceName": True,
51 "manufacturerData": [0x0123, "00112233445566778899AABBCCDDEE"],
52 "manufacturerData2": [0x2540, [0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
53 0x66, 0x77, 0x88, 0xFF]],
54 "serviceData": ["b19d42dc-58ba-4b20-b6c1-6628e7d21de4",
55 "00112233445566778899AABBCCDDEE"],
56 "serviceData2":
57 ["000042dc-58ba-4b20-b6c1-6628e7d21de4",
58 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xFF]]
59 }
60
61 def __init__(self, controllers):
62 BluetoothBaseTest.__init__(self, controllers)
63 self.scn_ad = self.android_devices[0]
64 self.adv_ad = self.android_devices[1]
65
66 def setup_class(self):
67 if not self.scn_ad.droid.bluetoothIsLeExtendedAdvertisingSupported():
68 raise signals.TestSkipClass(
69 "Scanner does not support LE Extended Advertising")
70
71 if not self.adv_ad.droid.bluetoothIsLeExtendedAdvertisingSupported():
72 raise signals.TestSkipClass(
73 "Advertiser does not support LE Extended Advertising")
74
75 def teardown_test(self):
76 cleanup_scanners_and_advertisers(
77 self.scn_ad, self.active_scan_callback_list, self.adv_ad, [])
78 self.active_scan_callback_list = []
79
80 def on_exception(self, test_name, begin_time):
81 reset_bluetooth(self.android_devices)
82
83 # This one does not relly test anything, but display very helpful
84 # information that might help with debugging.
85 @BluetoothBaseTest.bt_test_wrap
86 def test_capabilities(self):
87 d = self.scn_ad.droid
88 sup2M = d.bluetoothIsLe2MPhySupported()
89 supCoded = d.bluetoothIsLeCodedPhySupported()
90 supExt = d.bluetoothIsLeExtendedAdvertisingSupported()
91 supPeriodic = d.bluetoothIsLePeriodicAdvertisingSupported()
92 maxDataLen = d.bluetoothGetLeMaximumAdvertisingDataLength()
93 self.log.info("Scanner capabilities:")
94 self.log.info("LE 2M: " + str(sup2M) + ", LE Coded: " + str(supCoded) +
95 ", LE Extended Advertising: " + str(supExt) +
96 ", LE Periodic Advertising: " + str(supPeriodic) +
97 ", maximum advertising data length: " + str(maxDataLen))
98 d = self.adv_ad.droid
99 sup2M = d.bluetoothIsLe2MPhySupported()
100 supCoded = d.bluetoothIsLeCodedPhySupported()
101 supExt = d.bluetoothIsLeExtendedAdvertisingSupported()
102 supPeriodic = d.bluetoothIsLePeriodicAdvertisingSupported()
103 maxDataLen = d.bluetoothGetLeMaximumAdvertisingDataLength()
104 self.log.info("Advertiser capabilities:")
105 self.log.info("LE 2M: " + str(sup2M) + ", LE Coded: " + str(supCoded) +
106 ", LE Extended Advertising: " + str(supExt) +
107 ", LE Periodic Advertising: " + str(supPeriodic) +
108 ", maximum advertising data length: " + str(maxDataLen))
109 return True
110
111 def test_1m_1m_extended_scan(self):
112 """Test scan on LE 1M PHY using LE 1M PHY as secondary.
113
114 Tests test verify that device is able to receive extended advertising
115 on 1M PHY when secondary is 1M PHY.
116
117 Steps:
118 1. Start advertising set on dut1
119 2. Start scanning on dut0, scan filter set to advertiser's device name
120 3. Try to find an event, expect found
121 4. Stop advertising
122
123 Expected Result:
124 Scan finds a advertisement.
125
126 Returns:
127 Pass if True
128 Fail if False
129
130 TAGS: LE Advertising Extension, BT5, LE, Advertising, Scanning
131 Priority: 1
132 """
133 adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
134 self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
135 {"connectable": True,
136 "legacyMode": False,
137 "primaryPhy": "PHY_LE_1M",
138 "secondaryPhy": "PHY_LE_1M",
139 "interval": 320}, self.big_adv_data, None, None, None, 0, 0,
140 adv_callback)
141
142 self.scn_ad.droid.bleSetScanSettingsLegacy(False)
143 self.scn_ad.droid.bleSetScanSettingsPhy(
144 ScanSettingsPhy.PHY_LE_1M.value)
145
146 filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
147 self.scn_ad.droid)
148
149 adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
150 self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
151 self.scn_ad.droid.bleBuildScanFilter(filter_list)
152 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
153 scan_callback)
154 self.active_scan_callback_list.append(scan_callback)
155
156 try:
157 self.scn_ad.ed.pop_event(
158 scan_result.format(scan_callback), self.default_timeout)
159 except Empty:
160 self.log.error("Scan result not found")
161 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
162 return False
163
164 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
165 return True
166
167 def test_1m_2m_extended_scan(self):
168 """Test scan on LE 1M PHY using LE 2M PHY as secondary.
169
170 Tests test verify that device is able to receive extended advertising
171 on 1M PHY when secondary is 2M PHY.
172
173 Steps:
174 1. Start advertising set on dut1
175 2. Start scanning on dut0, scan filter set to advertiser's device name
176 3. Try to find an event, expect found
177 4. Stop advertising
178
179 Expected Result:
180 Scan finds a advertisement.
181
182 Returns:
183 Pass if True
184 Fail if False
185
186 TAGS: LE Advertising Extension, BT5, LE, Advertising, Scanning
187 Priority: 1
188 """
189 adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
190 self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
191 {"connectable": True,
192 "legacyMode": False,
193 "primaryPhy": "PHY_LE_1M",
194 "secondaryPhy": "PHY_LE_2M",
195 "interval": 320}, self.big_adv_data, None, None, None, 0, 0,
196 adv_callback)
197
198 self.scn_ad.droid.bleSetScanSettingsLegacy(False)
199 self.scn_ad.droid.bleSetScanSettingsPhy(
200 ScanSettingsPhy.PHY_LE_1M.value)
201
202 filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
203 self.scn_ad.droid)
204
205 adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
206 self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
207 self.scn_ad.droid.bleBuildScanFilter(filter_list)
208 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
209 scan_callback)
210 self.active_scan_callback_list.append(scan_callback)
211
212 try:
213 self.scn_ad.ed.pop_event(
214 scan_result.format(scan_callback), self.default_timeout)
215 except Empty:
216 self.log.error("Scan result not found")
217 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
218 return False
219
220 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
221 return True
222
223
224 def test_legacy_scan_result_raw_length(self):
225 """Test that raw scan record data in legacy scan is 62 bytes long. This is required for compability with older apps that make this assumption.
226
227 Steps:
228 1. Start legacy advertising set on dut1
229 2. Start scanning on dut0, scan filter set to advertiser's device name
230 3. Try to find an event, expect found, verify scan recurd data length
231 4. Stop advertising
232
233 Expected Result:
234 Scan finds a legacy advertisement of proper size
235
236 Returns:
237 Pass if True
238 Fail if False
239
240 TAGS: LE Advertising Extension, BT5, LE, Advertising, Scanning
241 Priority: 1
242 """
243 adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
244 self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
245 {"connectable": True,
246 "scannable": True,
247 "legacyMode": True,
248 "interval": 320}, {"includeDeviceName": True}, None, None, None, 0, 0,
249 adv_callback)
250
251 self.scn_ad.droid.bleSetScanSettingsLegacy(True)
252 self.scn_ad.droid.bleSetScanSettingsPhy(
253 ScanSettingsPhy.PHY_LE_1M.value)
254
255 filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
256 self.scn_ad.droid)
257
258 adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
259 self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
260 self.scn_ad.droid.bleBuildScanFilter(filter_list)
261 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
262 scan_callback)
263 self.active_scan_callback_list.append(scan_callback)
264
265 try:
266 evt = self.scn_ad.ed.pop_event(
267 scan_result.format(scan_callback), self.default_timeout)
268 rawData = evt['data']['Result']['scanRecord']
269 asserts.assert_true(
270 62 == len(rawData.split(",")),
271 "Raw data should be 62 bytes long.")
272 except Empty:
273 self.log.error("Scan result not found")
274 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
275 return False
276
277 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
278 return True
279
280
281 def test_duration(self):
282 adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
283 self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
284 {"connectable": True,
285 "legacyMode": False,
286 "primaryPhy": "PHY_LE_1M",
287 "secondaryPhy": "PHY_LE_2M",
288 "interval": 320}, self.big_adv_data, None, None, None, 0, 0,
289 adv_callback)
290
291 self.scn_ad.droid.bleSetScanSettingsLegacy(False)
292 self.scn_ad.droid.bleSetScanSettingsPhy(
293 ScanSettingsPhy.PHY_LE_1M.value)
294
295 filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
296 self.scn_ad.droid)
297
298 adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
299 self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
300 self.scn_ad.droid.bleBuildScanFilter(filter_list)
301 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
302 scan_callback)
303 self.active_scan_callback_list.append(scan_callback)
304
305 try:
306 self.scn_ad.ed.pop_event(
307 scan_result.format(scan_callback), self.default_timeout)
308 except Empty:
309 self.log.error("Scan result not found")
310 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
311 return False
312
313 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
314 return True
315
316
317 def test_anonymous_advertising(self):
318 """Test anonymous advertising.
319
320 Tests test verify that device is able to receive anonymous advertising
321 on 1M PHY when secondary is 2M PHY.
322
323 Steps:
324 1. Start anonymous advertising set on dut1
325 2. Start scanning on dut0, scan filter set to advertiser's device name
326 3. Try to find an event, expect found
327 4. Stop advertising
328
329 Expected Result:
330 Scan finds a advertisement.
331
332 Returns:
333 Pass if True
334 Fail if False
335
336 TAGS: LE Advertising Extension, BT5, LE, Advertising, Scanning
337 Priority: 1
338 """
339 adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
340 self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
341 {"connectable": False,
342 "anonymous": True,
343 "legacyMode": False,
344 "primaryPhy": "PHY_LE_1M",
345 "secondaryPhy": "PHY_LE_2M",
346 "interval": 320}, self.big_adv_data, None, None, None, 0, 0,
347 adv_callback)
348
349 self.scn_ad.droid.bleSetScanSettingsLegacy(False)
350 self.scn_ad.droid.bleSetScanSettingsPhy(
351 ScanSettingsPhy.PHY_LE_1M.value)
352
353 filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
354 self.scn_ad.droid)
355
356 adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
357 self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
358 self.scn_ad.droid.bleBuildScanFilter(filter_list)
359 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
360 scan_callback)
361 self.active_scan_callback_list.append(scan_callback)
362
363 try:
364 evt = self.scn_ad.ed.pop_event(
365 scan_result.format(scan_callback), self.default_timeout)
366 address = evt['data']['Result']['deviceInfo']['address']
367 asserts.assert_true(
368 '00:00:00:00:00:00' == address,
369 "Anonymous address should be 00:00:00:00:00:00, but was " + str(address))
370 except Empty:
371 self.log.error("Scan result not found")
372 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
373 return False
374
375 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
376 return True
Jakub Pawlowski2cc87a22017-04-24 08:33:27 -0700377
378 @BluetoothBaseTest.bt_test_wrap
379 def test_get_own_address(self):
380 """Test obtaining own address for PTS.
381
382 Steps:
383 1. Start advertising set dut1
384 2. Grab address
385 3. Stop advertising
386
387 Expected Result:
388 Callback with address is received.
389
390 Returns:
391 Pass if True
392 Fail if False
393
394 TAGS: LE Advertising Extension, BT5, LE, Advertising
395 Priority: 1
396 """
397 adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
398 self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
399 {"connectable": False,
400 "anonymous": True,
401 "legacyMode": False,
402 "primaryPhy": "PHY_LE_1M",
403 "secondaryPhy": "PHY_LE_2M",
404 "interval": 320}, self.big_adv_data, None, None, None, 0, 0,
405 adv_callback)
406
407 set_id = -1
408
409 try:
410 evt = self.adv_ad.ed.pop_event(
411 advertising_set_started.format(adv_callback), self.default_timeout)
412 self.log.info("data: " + str(evt['data']))
413 set_id = evt['data']['setId']
414 except Empty:
415 self.log.error("did not receive the set started event!")
416 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
417 return False
418
419 self.adv_ad.droid.bleAdvSetGetOwnAddress(set_id)
420
421 try:
422 evt = self.adv_ad.ed.pop_event(
423 advertising_set_on_own_address_read.format(set_id), self.default_timeout)
424 address = evt['data']['address']
425 self.log.info("Advertiser address is: " + str(address))
426 except Empty:
427 self.log.error("onOwnAddressRead not received.")
428 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
429 return False
430
431
432 self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
433 return True