• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#/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"""
17Test script to exercises different ways Ble Advertisements can run in
18concurrency. This test was designed to be run in a shield box.
19"""
20
21import concurrent
22import os
23import time
24
25from queue import Empty
26from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
27from acts.test_utils.bt.bt_test_utils import BtTestUtilsError
28from acts.test_utils.bt.BleEnum import AdvertiseSettingsAdvertiseMode
29from acts.test_utils.bt.BleEnum import ScanSettingsCallbackType
30from acts.test_utils.bt.BleEnum import ScanSettingsScanMode
31from acts.test_utils.bt.bt_test_utils import adv_succ
32from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
33from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
34from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
35from acts.test_utils.bt.bt_test_utils import reset_bluetooth
36from acts.test_utils.bt.bt_test_utils import scan_and_verify_n_advertisements
37from acts.test_utils.bt.bt_test_utils import scan_result
38from acts.test_utils.bt.bt_test_utils import setup_n_advertisements
39from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
40from acts.test_utils.bt.bt_test_utils import teardown_n_advertisements
41
42
43class ConcurrentBleAdvertisingTest(BluetoothBaseTest):
44    default_timeout = 10
45    max_advertisements = -1
46
47    def __init__(self, controllers):
48        BluetoothBaseTest.__init__(self, controllers)
49        self.droid_list = get_advanced_droid_list(self.android_devices)
50        self.scn_ad = self.android_devices[0]
51        self.adv_ad = self.android_devices[1]
52        self.max_advertisements = self.droid_list[1]['max_advertisements']
53
54    def setup_test(self):
55        super(BluetoothBaseTest, self).setup_test()
56        return reset_bluetooth(self.android_devices)
57
58    def _verify_n_advertisements(self, num_advertisements):
59        try:
60            advertise_callback_list = setup_n_advertisements(
61                self.adv_ad, num_advertisements)
62        except BtTestUtilsError:
63            return False
64        try:
65            scan_and_verify_n_advertisements(self.scn_ad, num_advertisements)
66        except BtTestUtilsError:
67            return False
68        teardown_n_advertisements(self.adv_ad, len(advertise_callback_list),
69                                  advertise_callback_list)
70        return True
71
72    @BluetoothBaseTest.bt_test_wrap
73    def test_max_advertisements_defaults(self):
74        """Testing max advertisements.
75
76        Test that a single device can have the max advertisements
77        concurrently advertising.
78
79        Steps:
80        1. Setup the scanning android device.
81        2. Setup the advertiser android device.
82        3. Start scanning on the max_advertisements as defined in the script.
83        4. Verify that all advertisements are found.
84
85        Expected Result:
86        All advertisements should start without errors.
87
88        Returns:
89          Pass if True
90          Fail if False
91
92        TAGS: LE, Advertising, Concurrency
93        Priority: 0
94        """
95        return self._verify_n_advertisements(self.max_advertisements)
96
97    @BluetoothBaseTest.bt_test_wrap
98    def test_max_advertisements_include_device_name_and_filter_device_name(
99            self):
100        """Testing max advertisement variant.
101
102        Test that a single device can have the max advertisements
103        concurrently advertising. Include the device name as a part of the filter
104        and advertisement data.
105
106        Steps:
107        1. Setup the scanning android device.
108        2. Setup the advertiser android device.
109        3. Include device name in each advertisement.
110        4. Include device name filter in the scanner.
111        5. Start scanning on the max_advertisements as defined in the script.
112        6. Verify that all advertisements are found.
113
114        Expected Result:
115        All advertisements should start without errors.
116
117        Returns:
118          Pass if True
119          Fail if False
120
121        TAGS: LE, Advertising, Concurrency
122        Priority: 2
123        """
124        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
125        self.scn_ad.droid.bleSetScanFilterDeviceName(
126            self.adv_ad.droid.bluetoothGetLocalName())
127        return self._verify_n_advertisements(self.max_advertisements)
128
129    @BluetoothBaseTest.bt_test_wrap
130    def test_max_advertisements_exclude_device_name_and_filter_device_name(
131            self):
132        """Test max advertisement variant.
133
134        Test that a single device can have the max advertisements concurrently
135        advertising. Include the device name as a part of the filter but not the
136        advertisement data.
137
138        Steps:
139        1. Setup the scanning android device.
140        2. Setup the advertiser android device.
141        3. Include device name filter in the scanner.
142        4. Start scanning on the max_advertisements as defined in the script.
143        5. Verify that no advertisements are found.
144
145        Expected Result:
146        All advertisements should start without errors.
147
148        Returns:
149          Pass if True
150          Fail if False
151
152        TAGS: LE, Advertising, Concurrency
153        Priority: 2
154        """
155        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(False)
156        self.scn_ad.droid.bleSetScanFilterDeviceName(
157            self.adv_ad.droid.bluetoothGetLocalName())
158        return not self._verify_n_advertisements(self.max_advertisements)
159
160    @BluetoothBaseTest.bt_test_wrap
161    def test_max_advertisements_with_manufacturer_data(self):
162        """Test max advertisement variant.
163
164        Test that a single device can have the max advertisements concurrently
165        advertising. Include the manufacturer data as a part of the filter and
166        advertisement data.
167
168        Steps:
169        1. Setup the scanning android device.
170        2. Setup the advertiser android device.
171        3. Include manufacturer data in each advertisement.
172        4. Include manufacturer data filter in the scanner.
173        5. Start scanning on the max_advertisements as defined in the script.
174        6. Verify that all advertisements are found.
175
176        Expected Result:
177        All advertisements should start without errors.
178
179        Returns:
180          Pass if True
181          Fail if False
182
183        TAGS: LE, Advertising, Concurrency
184        Priority: 2
185        """
186        self.scn_ad.droid.bleSetScanFilterManufacturerData(1, [1])
187        self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(1, [1])
188        return self._verify_n_advertisements(self.max_advertisements)
189
190    @BluetoothBaseTest.bt_test_wrap
191    def test_max_advertisements_with_manufacturer_data_mask(self):
192        """Test max advertisements variant.
193
194        Test that a single device can have the max advertisements concurrently
195        advertising. Include the manufacturer data mask as a part of the filter
196        and advertisement data.
197
198        Steps:
199        1. Setup the scanning android device.
200        2. Setup the advertiser android device.
201        3. Include manufacturer data in each advertisement.
202        4. Include manufacturer data mask filter in the scanner.
203        5. Start scanning on the max_advertisements as defined in the script.
204        6. Verify that all advertisements are found.
205
206        Expected Result:
207        All advertisements should start without errors.
208
209        Returns:
210          Pass if True
211          Fail if False
212
213        TAGS: LE, Advertising, Concurrency
214        Priority: 2
215        """
216        self.scn_ad.droid.bleSetScanFilterManufacturerData(1, [1], [1])
217        self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(1, [1])
218        return self._verify_n_advertisements(self.max_advertisements)
219
220    @BluetoothBaseTest.bt_test_wrap
221    def test_max_advertisements_with_service_data(self):
222        """Test max advertisement variant.
223
224        Test that a single device can have the max advertisements concurrently
225        advertising. Include the service data as a part of the filter and
226        advertisement data.
227
228        Steps:
229        1. Setup the scanning android device.
230        2. Setup the advertiser android device.
231        3. Include service data in each advertisement.
232        4. Include service data filter in the scanner.
233        5. Start scanning on the max_advertisements as defined in the script.
234        6. Verify that all advertisements are found.
235
236        Expected Result:
237        All advertisements should start without errors.
238
239        Returns:
240          Pass if True
241          Fail if False
242
243        TAGS: LE, Advertising, Concurrency
244        Priority: 2
245        """
246        test_result = True
247        filter_list = self.scn_ad.droid.bleGenFilterList()
248        self.scn_ad.droid.bleSetScanFilterServiceData(
249            "0000110A-0000-1000-8000-00805F9B34FB", [11,17,80])
250        self.adv_ad.droid.bleAddAdvertiseDataServiceData(
251            "0000110A-0000-1000-8000-00805F9B34FB", [11,17,80])
252        return self._verify_n_advertisements(self.max_advertisements)
253
254    @BluetoothBaseTest.bt_test_wrap
255    def test_max_advertisements_with_manufacturer_data_mask_and_include_device_name(
256            self):
257        """Test max advertisement variant.
258
259        Test that a single device can have the max advertisements concurrently
260        advertising. Include the device name and manufacturer data as a part of
261        the filter and advertisement data.
262
263        Steps:
264        1. Setup the scanning android device.
265        2. Setup the advertiser android device.
266        3. Include device name and manufacturer data in each advertisement.
267        4. Include device name and manufacturer data filter in the scanner.
268        5. Start scanning on the max_advertisements as defined in the script.
269        6. Verify that all advertisements are found.
270
271        Expected Result:
272        All advertisements should start without errors.
273
274        Returns:
275          Pass if True
276          Fail if False
277
278        TAGS: LE, Advertising, Concurrency
279        Priority: 2
280        """
281        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
282        self.scn_ad.droid.bleSetScanFilterDeviceName(
283            self.adv_ad.droid.bluetoothGetLocalName())
284        self.scn_ad.droid.bleSetScanFilterManufacturerData(1, [1], [1])
285        self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(1, [1])
286        return self._verify_n_advertisements(self.max_advertisements)
287
288    @BluetoothBaseTest.bt_test_wrap
289    def test_max_advertisements_with_service_uuids(self):
290        """Test max advertisement variant.
291
292        Test that a single device can have the max advertisements concurrently
293        advertising. Include the service uuid as a part of the filter and
294        advertisement data.
295
296        Steps:
297        1. Setup the scanning android device.
298        2. Setup the advertiser android device.
299        3. Include service uuid in each advertisement.
300        4. Include service uuid filter in the scanner.
301        5. Start scanning on the max_advertisements as defined in the script.
302        6. Verify that all advertisements are found.
303
304        Expected Result:
305        All advertisements should start without errors.
306
307        Returns:
308          Pass if True
309          Fail if False
310
311        TAGS: LE, Advertising, Concurrency
312        Priority: 1
313        """
314        self.scn_ad.droid.bleSetScanFilterServiceUuid(
315            "00000000-0000-1000-8000-00805f9b34fb")
316        self.adv_ad.droid.bleSetAdvertiseDataSetServiceUuids(
317            ["00000000-0000-1000-8000-00805f9b34fb"])
318        return self._verify_n_advertisements(self.max_advertisements)
319
320    @BluetoothBaseTest.bt_test_wrap
321    def test_max_advertisements_with_service_uuid_and_service_mask(self):
322        """Test max advertisements variant.
323
324        Test that a single device can have the max advertisements concurrently
325        advertising. Include the service mask as a part of the filter and
326        advertisement data.
327
328        Steps:
329        1. Setup the scanning android device.
330        2. Setup the advertiser android device.
331        3. Include service uuid in each advertisement.
332        4. Include service mask filter in the scanner.
333        5. Start scanning on the max_advertisements as defined in the script.
334        6. Verify that all advertisements are found.
335
336        Expected Result:
337        All advertisements should start without errors.
338
339        Returns:
340          Pass if True
341          Fail if False
342
343        TAGS: LE, Advertising, Concurrency
344        Priority: 2
345        """
346        self.scn_ad.droid.bleSetScanFilterServiceUuid(
347            "00000000-0000-1000-8000-00805f9b34fb",
348            "00000000-0000-1000-8000-00805f9b34fb")
349        self.adv_ad.droid.bleSetAdvertiseDataSetServiceUuids(
350            ["00000000-0000-1000-8000-00805f9b34fb"])
351        return self._verify_n_advertisements(self.max_advertisements)
352
353    @BluetoothBaseTest.bt_test_wrap
354    def test_max_advertisements_plus_one(self):
355        """Test max advertisements plus one.
356
357        Test that a single device can have the max advertisements concurrently
358        advertising but fail on starting the max advertisements plus one.
359        filter and advertisement data.
360
361        Steps:
362        1. Setup the scanning android device.
363        2. Setup the advertiser android device.
364        3. Start max_advertisements + 1.
365
366        Expected Result:
367        The last advertisement should fail.
368
369        Returns:
370          Pass if True
371          Fail if False
372
373        TAGS: LE, Advertising, Concurrency
374        Priority: 0
375        """
376        return not self._verify_n_advertisements(self.max_advertisements + 1)
377
378    @BluetoothBaseTest.bt_test_wrap
379    def test_start_two_advertisements_on_same_callback(self):
380        """Test invalid advertisement scenario.
381
382        Test that a single device cannot have two advertisements start on the
383        same callback.
384
385        Steps:
386        1. Setup the scanning android device.
387        2. Setup the advertiser android device.
388        3. Call start ble advertising on the same callback.
389
390        Expected Result:
391        The second call of start advertising on the same callback should fail.
392
393        Returns:
394          Pass if True
395          Fail if False
396
397        TAGS: LE, Advertising, Concurrency
398        Priority: 1
399        """
400        test_result = True
401        advertise_callback, advertise_data, advertise_settings = (
402            generate_ble_advertise_objects(self.adv_ad.droid))
403        self.adv_ad.droid.bleStartBleAdvertising(
404            advertise_callback, advertise_data, advertise_settings)
405        try:
406            self.adv_ad.ed.pop_event(
407                adv_succ.format(advertise_callback), self.default_timeout)
408        except Empty as error:
409            self.log.error("Test failed with Empty error: {}".format(error))
410            return False
411        except concurrent.futures._base.TimeoutError as error:
412            self.log.debug(
413                "Test failed, filtering callback onSuccess never occurred: {}"
414                .format(error))
415        try:
416            self.adv_ad.droid.bleStartBleAdvertising(
417                advertise_callback, advertise_data, advertise_settings)
418            self.adv_ad.ed.pop_event(
419                adv_succ.format(advertise_callback), self.default_timeout)
420            test_result = False
421        except Empty as error:
422            self.log.debug("Test passed with Empty error: {}".format(error))
423        except concurrent.futures._base.TimeoutError as error:
424            self.log.debug(
425                "Test passed, filtering callback onSuccess never occurred: {}"
426                .format(error))
427
428        return test_result
429
430    @BluetoothBaseTest.bt_test_wrap
431    def test_toggle_advertiser_bt_state(self):
432        """Test forcing stopping advertisements.
433
434        Test that a single device resets its callbacks when the bluetooth state is
435        reset. There should be no advertisements.
436
437        Steps:
438        1. Setup the scanning android device.
439        2. Setup the advertiser android device.
440        3. Call start ble advertising.
441        4. Toggle bluetooth on and off.
442        5. Scan for any advertisements.
443
444        Expected Result:
445        No advertisements should be found after toggling Bluetooth on the
446        advertising device.
447
448        Returns:
449          Pass if True
450          Fail if False
451
452        TAGS: LE, Advertising, Concurrency
453        Priority: 2
454        """
455        test_result = True
456        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
457        advertise_callback, advertise_data, advertise_settings = (
458            generate_ble_advertise_objects(self.adv_ad.droid))
459        self.adv_ad.droid.bleStartBleAdvertising(
460            advertise_callback, advertise_data, advertise_settings)
461        try:
462            self.adv_ad.ed.pop_event(
463                adv_succ.format(advertise_callback), self.default_timeout)
464        except Empty as error:
465            self.log.error("Test failed with Empty error: {}".format(error))
466            return False
467        except concurrent.futures._base.TimeoutError as error:
468            self.log.error(
469                "Test failed, filtering callback onSuccess never occurred: {}".format(
470                    error))
471        self.scn_ad.droid.bleSetScanFilterDeviceName(
472            self.adv_ad.droid.bluetoothGetLocalName())
473        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
474            self.scn_ad.droid)
475        self.scn_ad.droid.bleBuildScanFilter(filter_list)
476        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
477                                          scan_callback)
478        try:
479            self.scn_ad.ed.pop_event(
480                scan_result.format(scan_callback), self.default_timeout)
481        except Empty as error:
482            self.log.error("Test failed with: {}".format(error))
483            return False
484        self.scn_ad.droid.bleStopBleScan(scan_callback)
485        test_result = reset_bluetooth([self.android_devices[1]])
486        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
487                                          scan_callback)
488        if not test_result:
489            return False
490        try:
491            expected_event = scan_result.format(scan_callback)
492            event = self.scn_ad.ed.pop_event(expected_event,
493                                             self.default_timeout)
494            self.log.error("Event {} not expected. Found: {}".format(
495                expected_event, event))
496            return False
497        except Empty as error:
498            self.log.debug("Test passed with: {}".format(error))
499        self.scn_ad.droid.bleStopBleScan(scan_callback)
500        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
501        return True
502
503    @BluetoothBaseTest.bt_test_wrap
504    def test_restart_advertise_callback_after_bt_toggle(self):
505        """Test starting an advertisement on a cleared out callback.
506
507        Test that a single device resets its callbacks when the bluetooth state
508        is reset.
509
510        Steps:
511        1. Setup the scanning android device.
512        2. Setup the advertiser android device.
513        3. Call start ble advertising.
514        4. Toggle bluetooth on and off.
515        5. Call start ble advertising on the same callback.
516
517        Expected Result:
518        Starting an advertisement on a callback id after toggling bluetooth
519        should fail.
520
521        Returns:
522          Pass if True
523          Fail if False
524
525        TAGS: LE, Advertising, Concurrency
526        Priority: 1
527        """
528        test_result = True
529        advertise_callback, advertise_data, advertise_settings = (
530            generate_ble_advertise_objects(self.adv_ad.droid))
531        self.adv_ad.droid.bleStartBleAdvertising(
532            advertise_callback, advertise_data, advertise_settings)
533        try:
534            self.adv_ad.ed.pop_event(
535                adv_succ.format(advertise_callback), self.default_timeout)
536        except Empty as error:
537            self.log.error("Test failed with Empty error: {}".format(error))
538            test_result = False
539        except concurrent.futures._base.TimeoutError as error:
540            self.log.debug(
541                "Test failed, filtering callback onSuccess never occurred: {}".format(
542                    error))
543        test_result = reset_bluetooth([self.android_devices[1]])
544        if not test_result:
545            return test_result
546        self.adv_ad.droid.bleStartBleAdvertising(
547            advertise_callback, advertise_data, advertise_settings)
548        try:
549            self.adv_ad.ed.pop_event(
550                adv_succ.format(advertise_callback), self.default_timeout)
551        except Empty as error:
552            self.log.error("Test failed with Empty error: {}".format(error))
553            test_result = False
554        except concurrent.futures._base.TimeoutError as error:
555            self.log.debug(
556                "Test failed, filtering callback onSuccess never occurred: {}".format(
557                    error))
558        return test_result
559