1# Copyright 2016 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
5"""Server side bluetooth tests on adapter ble advertising.
6
7The Mnemonics describing the test cases:
8    CD: check advertising duration and intervals
9    RA: register advertisements
10    UA: unregister advertisements
11    SI: set advertising intervals
12    RS: reset advertising
13    FRA: fail to register extra advertisements when max ones
14         have been registered.
15    FSI: fail to set advertising intervals beyond legitimate range
16         of [20 ms, 10,240 ms].
17    PC: power cycle the bluetooth adapter (controller).
18    SR: suspend and resume the DUT (chromebook)
19
20A test represents a component of a test case which comprises a
21sequence of tests. A test case usually requires a tester (user)
22to perform a sequence of actions and make a sequence of
23observations if the test case is performed manually.
24
25A test consists of an optional action such as "register n
26advertisements" and a number of test criteria such as "verifying
27if min advertising interval is set to an expected value" or
28"verifying if advertising is disabled".
29
30"""
31
32import copy
33import logging
34import time
35
36from autotest_lib.client.common_lib import error
37from autotest_lib.server.cros.bluetooth import bluetooth_adapter_tests
38from autotest_lib.server.cros.multimedia import bluetooth_le_facade_adapter
39
40
41test_case_log = bluetooth_adapter_tests.test_case_log
42UNSUPPORTED_KERNEL = "3.8.11"
43
44
45class bluetooth_AdapterLEAdvertising(
46        bluetooth_adapter_tests.BluetoothAdapterTests):
47    """Server side bluetooth adapter advertising Test.
48
49    This class comprises a number of test cases to verify
50    bluetooth low-energy advertising.
51
52    Refer to BluetoothAdapterTests for the implementation of the tests
53    performed in this autotest test.
54
55    Refer to the design doc for more details:
56    "Test Cases for Bluetooth Low-Energy Advertising".
57
58    """
59
60    @staticmethod
61    def get_instance_ids(advertisements):
62        """Get the list of instace IDs starting at 1.
63
64        @param advertisements: a list of advertisements.
65
66        """
67        return range(1, len(advertisements) + 1)
68
69
70    def register_advertisements(self, advertisements, min_adv_interval_ms,
71                                max_adv_interval_ms, instance_ids=None):
72        """Register multiple advertisements continuously.
73
74        @param advertisements: a list of advertisement instances.
75        @param min_adv_interval_ms: min_adv_interval in milliseconds.
76        @param max_adv_interval_ms: max_adv_interval in milliseconds.
77        @param instance_ids: the list of instance IDs to register.
78
79        """
80        if instance_ids is None:
81            instance_ids = self.get_instance_ids(advertisements)
82
83        for instance_id, advertisement in zip(instance_ids, advertisements):
84            self.test_register_advertisement(advertisement,
85                                             instance_id,
86                                             min_adv_interval_ms,
87                                             max_adv_interval_ms)
88
89
90    def unregister_advertisements(self, advertisements, instance_ids=None):
91        """Register multiple advertisements.
92
93        @param advertisements: a list of advertisement instances.
94        @param min_adv_interval_ms: min_adv_interval in milliseconds.
95        @param max_adv_interval_ms: max_adv_interval in milliseconds.
96        @param instance_ids: the list of instance IDs to unregister.
97
98        """
99        if instance_ids is None:
100            instance_ids = self.get_instance_ids(advertisements)
101
102        count = 0
103        number_advs = len(advertisements)
104        for instance_id, advertisement in zip(instance_ids, advertisements):
105            # Advertising is only disabled at the removal of the
106            # last advertisement.
107            count += 1
108            advertising_disabled = count == number_advs
109            self.test_unregister_advertisement(advertisement,
110                                               instance_id,
111                                               advertising_disabled)
112
113    def get_kernel_version(self, host):
114        """Get the kernel version of the DUT.
115
116        @param host: DUT host
117
118        @returns: kernel version
119        """
120        kernel_command = "uname -r"
121        kernel_version = self.host.run(kernel_command).stdout.strip()
122        return kernel_version
123
124
125    # ---------------------------------------------------------------
126    # Definitions of all test cases
127    # ---------------------------------------------------------------
128
129
130    @test_case_log
131    def test_case_SI200_RA3_CD_UA3(self):
132        """Test Case: SI(200) - RA(3) - CD - UA(3)"""
133        new_min_adv_interval_ms = 200
134        new_max_adv_interval_ms = 200
135        advertisements = self.three_advertisements
136
137        self.test_reset_advertising()
138
139        self.test_set_advertising_intervals(new_min_adv_interval_ms,
140                                            new_max_adv_interval_ms)
141
142        self.register_advertisements(advertisements, new_min_adv_interval_ms,
143                                     new_max_adv_interval_ms)
144
145        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
146                                               new_max_adv_interval_ms,
147                                               len(advertisements))
148
149        self.unregister_advertisements(advertisements)
150
151
152    @test_case_log
153    def test_case_SI200_RA3_CD_RA1_CD_UA1_CD_UA3(self):
154        """Test Case: SI(200) - RA(3) - CD - RA(1) - CD - UA(1) - CD - UA(3)"""
155        new_min_adv_interval_ms = 200
156        new_max_adv_interval_ms = 200
157        # Make a copy of advertisements since we are going to modify it.
158        advertisements = copy.copy(self.three_advertisements)
159        number_advs = len(advertisements)
160        one_more_advertisement = [self.sixth_advertisement]
161
162        self.test_reset_advertising()
163
164        self.test_set_advertising_intervals(new_min_adv_interval_ms,
165                                            new_max_adv_interval_ms)
166
167        self.register_advertisements(advertisements, new_min_adv_interval_ms,
168                                     new_max_adv_interval_ms)
169
170        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
171                                               new_max_adv_interval_ms,
172                                               number_advs)
173
174        # Register one more advertisement.
175        # The instance ID to register is len(advertisements) + 1 = 4
176        self.register_advertisements(one_more_advertisement,
177                                     new_min_adv_interval_ms,
178                                     new_max_adv_interval_ms,
179                                     instance_ids=[number_advs + 1])
180
181        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
182                                               new_max_adv_interval_ms,
183                                               number_advs + 1)
184
185        # Unregister the 3rd advertisement.
186        # After removing the advertisement, the remaining instance IDs
187        # would be [1, 2, 4]
188        instance_id = 3
189        self.test_unregister_advertisement(advertisements.pop(instance_id - 1),
190                                           instance_id,
191                                           advertising_disabled=False)
192
193        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
194                                               new_max_adv_interval_ms,
195                                               number_advs)
196
197        # Unregister all existing advertisements which are [1, 2, 4]
198        # since adv 3 was removed in the previous step.
199        self.unregister_advertisements(advertisements + one_more_advertisement,
200                                       instance_ids=[1, 2, 4])
201
202
203    @test_case_log
204    def test_case_SI200_RA3_CD_RS(self):
205        """Test Case: SI(200) - RA(3) - CD - RS"""
206        new_min_adv_interval_ms = 200
207        new_max_adv_interval_ms = 200
208        advertisements = self.three_advertisements
209        number_advs = len(advertisements)
210
211        self.test_reset_advertising()
212
213        self.test_set_advertising_intervals(new_min_adv_interval_ms,
214                                            new_max_adv_interval_ms)
215
216        self.register_advertisements(advertisements, new_min_adv_interval_ms,
217                                     new_max_adv_interval_ms)
218
219        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
220                                               new_max_adv_interval_ms,
221                                               number_advs)
222
223        self.test_reset_advertising(self.get_instance_ids(advertisements))
224
225
226    @test_case_log
227    def test_case_SI200_RA3_CD_UA1_CD_RS(self):
228        """Test Case: SI(200) - RA(3) - CD - UA(1) - CD - RS"""
229        new_min_adv_interval_ms = 200
230        new_max_adv_interval_ms = 200
231        # Make a copy of advertisements since we are going to modify it.
232        advertisements = copy.copy(self.three_advertisements)
233
234        self.test_reset_advertising()
235
236        self.test_set_advertising_intervals(new_min_adv_interval_ms,
237                                            new_max_adv_interval_ms)
238
239        self.register_advertisements(advertisements, new_min_adv_interval_ms,
240                                     new_max_adv_interval_ms)
241
242        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
243                                               new_max_adv_interval_ms,
244                                               len(advertisements))
245
246        # Unregister the 1st advertisement.
247        # After removing the advertisement, the remaining instance IDs
248        # would be [2, 3]
249        instance_id = 1
250        self.test_unregister_advertisement(advertisements.pop(instance_id - 1),
251                                           instance_id,
252                                           advertising_disabled=False)
253
254        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
255                                               new_max_adv_interval_ms,
256                                               len(advertisements) - 1)
257
258        self.test_reset_advertising([2, 3])
259
260
261    @test_case_log
262    def test_case_SI200_RA3_CD_UA1_CD_RA2_CD_UA4(self):
263        """Test Case: SI(200) - RA(3) - CD - UA(1) - CD - RA(2) - CD - UA(4)"""
264        new_min_adv_interval_ms = 200
265        new_max_adv_interval_ms = 200
266        # Make a copy of three_advertisements since we are going to modify it.
267        advertisements1 = copy.copy(self.three_advertisements)
268        advertisements2 = self.two_advertisements
269        number_advs1 = len(advertisements1)
270        number_advs2 = len(advertisements2)
271
272        self.test_reset_advertising()
273
274        self.test_set_advertising_intervals(new_min_adv_interval_ms,
275                                            new_max_adv_interval_ms)
276
277        self.register_advertisements(advertisements1, new_min_adv_interval_ms,
278                                     new_max_adv_interval_ms)
279
280        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
281                                               new_max_adv_interval_ms,
282                                               number_advs1)
283
284        # Unregister the 2nd advertisement.
285        # After removing the 2nd advertisement, the remaining instance IDs
286        # would be [1, 3]
287        instance_id = 2
288        self.test_unregister_advertisement(advertisements1.pop(instance_id - 1),
289                                           instance_id,
290                                           advertising_disabled=False)
291
292        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
293                                               new_max_adv_interval_ms,
294                                               number_advs1 - 1)
295
296        # Register two more advertisements.
297        # The instance IDs to register would be [2, 4]
298        self.register_advertisements(advertisements2, new_min_adv_interval_ms,
299                                     new_max_adv_interval_ms,
300                                     instance_ids=[2, 4])
301
302        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
303                                               new_max_adv_interval_ms,
304                                               number_advs1 + number_advs2 - 1)
305
306        # Unregister all advertisements.
307        # The instance_ids of advertisements1 is [1, 3].
308        # The instance_ids of advertisements2 is [2, 4].
309        self.unregister_advertisements(advertisements1 + advertisements2,
310                                       instance_ids=[1, 3, 2, 4])
311
312
313    @test_case_log
314    def test_case_SI200_RA5_CD_FRA1_CD_UA5(self):
315        """Test Case: SI(200) - RA(5) - CD - FRA(1) - CD - UA(5)"""
316        new_min_adv_interval_ms = 200
317        new_max_adv_interval_ms = 200
318        advertisements = self.five_advertisements
319        extra_advertisement = self.sixth_advertisement
320        number_advs = len(advertisements)
321
322        self.test_reset_advertising()
323
324        self.test_set_advertising_intervals(new_min_adv_interval_ms,
325                                            new_max_adv_interval_ms)
326
327        self.register_advertisements(advertisements, new_min_adv_interval_ms,
328                                     new_max_adv_interval_ms)
329
330        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
331                                               new_max_adv_interval_ms,
332                                               number_advs)
333
334        self.test_fail_to_register_advertisement(extra_advertisement,
335                                                 new_min_adv_interval_ms,
336                                                 new_max_adv_interval_ms)
337
338        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
339                                               new_max_adv_interval_ms,
340                                               number_advs)
341
342        self.unregister_advertisements(advertisements)
343
344
345    @test_case_log
346    def test_case_SI200_RA3_CD_PC_CD_UA3(self):
347        """Test Case: SI(200) - RA(3) - CD - PC - CD - UA(3)"""
348        new_min_adv_interval_ms = 200
349        new_max_adv_interval_ms = 200
350        advertisements = self.three_advertisements
351
352        self.test_reset_advertising()
353
354        self.test_set_advertising_intervals(new_min_adv_interval_ms,
355                                            new_max_adv_interval_ms)
356
357        self.register_advertisements(advertisements, new_min_adv_interval_ms,
358                                     new_max_adv_interval_ms)
359
360        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
361                                               new_max_adv_interval_ms,
362                                               len(advertisements))
363
364        # Turn off and then turn on the adapter.
365        self.test_power_off_adapter()
366        time.sleep(1)
367        self.test_power_on_adapter()
368
369        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
370                                               new_max_adv_interval_ms,
371                                               len(advertisements))
372
373        self.unregister_advertisements(advertisements)
374
375
376    @test_case_log
377    def test_case_SI200_RA3_CD_SR_CD_UA3(self):
378        """Test Case: SI(200) - RA(3) - CD - SR - CD - UA(3)"""
379        new_min_adv_interval_ms = 200
380        new_max_adv_interval_ms = 200
381        advertisements = self.three_advertisements
382
383        self.test_reset_advertising()
384
385        self.test_set_advertising_intervals(new_min_adv_interval_ms,
386                                            new_max_adv_interval_ms)
387
388        self.register_advertisements(advertisements, new_min_adv_interval_ms,
389                                     new_max_adv_interval_ms)
390
391        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
392                                               new_max_adv_interval_ms,
393                                               len(advertisements))
394
395        # Suspend for a while and resume.
396        self.suspend_resume()
397
398        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
399                                               new_max_adv_interval_ms,
400                                               len(advertisements))
401
402        self.unregister_advertisements(advertisements)
403
404
405    @test_case_log
406    def test_case_RA3_CD_SI200_CD_UA3(self):
407        """Test Case: RA(3) - CD - SI(200) - CD - UA(3)"""
408        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
409        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
410        new_min_adv_interval_ms = 200
411        new_max_adv_interval_ms = 200
412        advertisements = self.three_advertisements
413        number_advs = len(advertisements)
414
415        self.test_reset_advertising()
416
417        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
418                                     orig_max_adv_interval_ms)
419
420        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
421                                               orig_max_adv_interval_ms,
422                                               number_advs)
423
424        self.test_set_advertising_intervals(new_min_adv_interval_ms,
425                                            new_max_adv_interval_ms)
426
427        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
428                                               new_max_adv_interval_ms,
429                                               number_advs)
430
431        self.unregister_advertisements(advertisements)
432
433
434    @test_case_log
435    def test_case_RA3_CD_SI200_CD_RS(self):
436        """Test Case: RA(3) - CD - SI(200) - CD - RS"""
437        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
438        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
439        new_min_adv_interval_ms = 200
440        new_max_adv_interval_ms = 200
441        advertisements = self.three_advertisements
442        number_advs = len(advertisements)
443
444        self.test_reset_advertising()
445
446        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
447                                     orig_max_adv_interval_ms)
448
449        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
450                                               orig_max_adv_interval_ms,
451                                               number_advs)
452
453        self.test_set_advertising_intervals(new_min_adv_interval_ms,
454                                            new_max_adv_interval_ms)
455
456        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
457                                               new_max_adv_interval_ms,
458                                               number_advs)
459
460        self.test_reset_advertising(self.get_instance_ids(advertisements))
461
462
463
464    @test_case_log
465    def test_case_RA3_CD_SI200_CD_UA1_CD_RS(self):
466        """Test Case: RA(3) - CD - SI(200) - CD - UA(1) - CD - RS"""
467        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
468        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
469        new_min_adv_interval_ms = 200
470        new_max_adv_interval_ms = 200
471        advertisements = self.three_advertisements
472        number_advs = len(advertisements)
473
474        self.test_reset_advertising()
475
476        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
477                                     orig_max_adv_interval_ms)
478
479        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
480                                               orig_max_adv_interval_ms,
481                                               number_advs)
482
483        self.test_set_advertising_intervals(new_min_adv_interval_ms,
484                                            new_max_adv_interval_ms)
485
486        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
487                                               new_max_adv_interval_ms,
488                                               number_advs)
489
490        # Unregister the 2nd advertisement.
491        instance_id = 2
492        self.test_unregister_advertisement(advertisements[instance_id - 1],
493                                           instance_id,
494                                           advertising_disabled=False)
495
496        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
497                                               new_max_adv_interval_ms,
498                                               number_advs - 1)
499
500        # Test if advertising is reset correctly.Only instances [1, 3] are left.
501        self.test_reset_advertising([1, 3])
502
503
504    @test_case_log
505    def test_case_RA3_CD_SI200_CD_SI2000_CD_UA3(self):
506        """Test Case: RA(3) - CD - SI(200) - CD - SI(2000) - CD - UA(3)"""
507        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
508        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
509        new_small_min_adv_interval_ms = 200
510        new_small_max_adv_interval_ms = 200
511        new_large_min_adv_interval_ms = 2000
512        new_large_max_adv_interval_ms = 2000
513        advertisements = self.three_advertisements
514        number_advs = len(advertisements)
515
516        self.test_reset_advertising()
517
518        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
519                                     orig_max_adv_interval_ms)
520
521        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
522                                               orig_max_adv_interval_ms,
523                                               number_advs)
524
525        self.test_set_advertising_intervals(new_small_min_adv_interval_ms,
526                                            new_small_max_adv_interval_ms)
527
528        self.test_check_duration_and_intervals(new_small_min_adv_interval_ms,
529                                               new_small_max_adv_interval_ms,
530                                               number_advs)
531
532        self.test_set_advertising_intervals(new_large_min_adv_interval_ms,
533                                            new_large_max_adv_interval_ms)
534
535        self.test_check_duration_and_intervals(new_large_min_adv_interval_ms,
536                                               new_large_max_adv_interval_ms,
537                                               number_advs)
538
539        self.unregister_advertisements(advertisements)
540
541
542    @test_case_log
543    def test_case_RA5_CD_SI200_CD_FRA1_CD_UA5(self):
544        """Test Case: RA(5) - CD - SI(200) - CD - FRA(1) - CD - UA(5)"""
545        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
546        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
547        new_min_adv_interval_ms = 200
548        new_max_adv_interval_ms = 200
549        advertisements = self.five_advertisements
550        extra_advertisement = self.sixth_advertisement
551        number_advs = len(advertisements)
552
553        self.test_reset_advertising()
554
555        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
556                                     orig_max_adv_interval_ms)
557
558        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
559                                               orig_max_adv_interval_ms,
560                                               number_advs)
561
562        self.test_set_advertising_intervals(new_min_adv_interval_ms,
563                                            new_max_adv_interval_ms)
564
565        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
566                                               new_max_adv_interval_ms,
567                                               number_advs)
568
569        self.test_fail_to_register_advertisement(extra_advertisement,
570                                                 new_min_adv_interval_ms,
571                                                 new_max_adv_interval_ms)
572
573        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
574                                               new_max_adv_interval_ms,
575                                               number_advs)
576
577        self.unregister_advertisements(advertisements)
578
579
580    @test_case_log
581    def test_case_RA3_CD_SI200_CD_FSI10_CD_FSI20000_CD_UA3(self):
582        """Test Case: RA(3) - CD - SI(200) - CD - FSI(10) - CD - FSI(20000) - CD
583        - UA(3)
584        """
585        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
586        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
587        new_min_adv_interval_ms = 200
588        new_max_adv_interval_ms = 200
589        invalid_small_min_adv_interval_ms = 10
590        invalid_small_max_adv_interval_ms = 10
591        invalid_large_min_adv_interval_ms = 20000
592        invalid_large_max_adv_interval_ms = 20000
593        advertisements = self.three_advertisements
594        number_advs = len(advertisements)
595
596        self.test_reset_advertising()
597
598        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
599                                     orig_max_adv_interval_ms)
600
601        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
602                                               orig_max_adv_interval_ms,
603                                               number_advs)
604
605        self.test_set_advertising_intervals(new_min_adv_interval_ms,
606                                            new_max_adv_interval_ms)
607
608        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
609                                               new_max_adv_interval_ms,
610                                               number_advs)
611
612        # Fails to set intervals that are too small. Intervals remain the same.
613        self.test_fail_to_set_advertising_intervals(
614                invalid_small_min_adv_interval_ms,
615                invalid_small_max_adv_interval_ms,
616                new_min_adv_interval_ms, new_max_adv_interval_ms)
617
618        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
619                                               new_max_adv_interval_ms,
620                                               number_advs)
621
622        # Fails to set intervals that are too large. Intervals remain the same.
623        self.test_fail_to_set_advertising_intervals(
624                invalid_large_min_adv_interval_ms,
625                invalid_large_max_adv_interval_ms,
626                new_min_adv_interval_ms, new_max_adv_interval_ms)
627
628        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
629                                               new_max_adv_interval_ms,
630                                               number_advs)
631
632        # Unregister all advertisements.
633        self.unregister_advertisements(advertisements)
634
635
636    @test_case_log
637    def test_case_RA3_CD_SI200_CD_PC_CD_UA3(self):
638        """Test Case: RA(3) - CD - SI(200) - CD - PC - CD - UA(3)"""
639        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
640        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
641        new_min_adv_interval_ms = 200
642        new_max_adv_interval_ms = 200
643        advertisements = self.three_advertisements
644        number_advs = len(advertisements)
645
646        self.test_reset_advertising()
647
648        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
649                                     orig_max_adv_interval_ms)
650
651        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
652                                               orig_max_adv_interval_ms,
653                                               number_advs)
654
655        self.test_set_advertising_intervals(new_min_adv_interval_ms,
656                                            new_max_adv_interval_ms)
657
658        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
659                                               new_max_adv_interval_ms,
660                                               number_advs)
661
662        # Turn off and then turn on the adapter.
663        self.test_power_off_adapter()
664        time.sleep(1)
665        self.test_power_on_adapter()
666
667        # Check if the advertising durations remain the same after resume.
668        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
669                                               new_max_adv_interval_ms,
670                                               number_advs)
671
672        # Unregister all advertisements.
673        self.unregister_advertisements(advertisements)
674
675
676    @test_case_log
677    def test_case_RA3_CD_SI200_CD_SR_CD_UA3(self):
678        """Test Case: RA(3) - CD - SI(200) - CD - SR - CD - UA(3)"""
679        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
680        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
681        new_min_adv_interval_ms = 200
682        new_max_adv_interval_ms = 200
683        advertisements = self.three_advertisements
684        number_advs = len(advertisements)
685
686        self.test_reset_advertising()
687
688        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
689                                     orig_max_adv_interval_ms)
690
691        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
692                                               orig_max_adv_interval_ms,
693                                               number_advs)
694
695        self.test_set_advertising_intervals(new_min_adv_interval_ms,
696                                            new_max_adv_interval_ms)
697
698        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
699                                               new_max_adv_interval_ms,
700                                               number_advs)
701
702        # Suspend for a while and resume.
703        self.suspend_resume()
704
705        # Check if the advertising durations remain the same after resume.
706        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
707                                               new_max_adv_interval_ms,
708                                               number_advs)
709
710        # Unregister all advertisements.
711        self.unregister_advertisements(advertisements)
712
713    # SINGLE TEST CASES
714    @test_case_log
715    def test_case_SI200_RA1_CD_UA1(self):
716        """Test Case: SI(200) - RA(1) - CD - UA(1)"""
717        new_min_adv_interval_ms = 200
718        new_max_adv_interval_ms = 200
719        advertisements = [self.sixth_advertisement]
720
721        self.test_reset_advertising()
722
723        self.test_set_advertising_intervals(new_min_adv_interval_ms,
724                                            new_max_adv_interval_ms)
725
726        self.register_advertisements(advertisements, new_min_adv_interval_ms,
727                                     new_max_adv_interval_ms)
728
729        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
730                                               new_max_adv_interval_ms,
731                                               len(advertisements))
732
733        self.unregister_advertisements(advertisements)
734
735
736    @test_case_log
737    def test_case_SI200_RA1_CD_RS(self):
738        """Test Case: SI(200) - RA(1) - CD - RS"""
739        new_min_adv_interval_ms = 200
740        new_max_adv_interval_ms = 200
741        advertisements = [self.first_advertisement]
742
743        self.test_reset_advertising()
744        self.test_set_advertising_intervals(new_min_adv_interval_ms,
745                                            new_max_adv_interval_ms)
746
747        self.register_advertisements(advertisements, new_min_adv_interval_ms,
748                                     new_max_adv_interval_ms)
749
750        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
751                                               new_max_adv_interval_ms,
752                                               len(advertisements))
753
754        self.test_reset_advertising()
755
756
757    @test_case_log
758    def test_case_SI200_RA1_CD_SR_CD_UA1(self):
759        """Test Case: SI(200) - RA(1) - CD - SR - CD - UA(1)"""
760        new_min_adv_interval_ms = 200
761        new_max_adv_interval_ms = 200
762        advertisements = [self.sixth_advertisement]
763
764        self.test_reset_advertising()
765
766        self.test_set_advertising_intervals(new_min_adv_interval_ms,
767                                            new_max_adv_interval_ms)
768
769        self.register_advertisements(advertisements, new_min_adv_interval_ms,
770                                     new_max_adv_interval_ms)
771
772        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
773                                               new_max_adv_interval_ms,
774                                               len(advertisements))
775        self.suspend_resume()
776
777        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
778                                               new_max_adv_interval_ms,
779                                               len(advertisements))
780
781        self.unregister_advertisements(advertisements)
782
783
784    @test_case_log
785    def test_case_RA1_CD_SI200_CD_UA1(self):
786        """Test Case: RA(1) - CD - SI(200) - CD - UA(1)"""
787        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
788        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
789        new_min_adv_interval_ms = 200
790        new_max_adv_interval_ms = 200
791        advertisements = [self.first_advertisement]
792
793        self.test_reset_advertising()
794
795        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
796                                     orig_max_adv_interval_ms)
797
798        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
799                                               orig_max_adv_interval_ms,
800                                               len(advertisements))
801
802        self.test_set_advertising_intervals(new_min_adv_interval_ms,
803                                            new_max_adv_interval_ms)
804
805
806        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
807                                               new_max_adv_interval_ms,
808                                               len(advertisements))
809
810        self.unregister_advertisements(advertisements)
811
812
813    @test_case_log
814    def test_case_RA1_CD_SI200_CD_RS(self):
815        """Test Case: RA(1) - CD - SI(200) - CD - RS"""
816        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
817        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
818        new_min_adv_interval_ms = 200
819        new_max_adv_interval_ms = 200
820        advertisements = [self.sixth_advertisement]
821        self.test_reset_advertising()
822
823        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
824                                     orig_max_adv_interval_ms)
825
826        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
827                                               orig_max_adv_interval_ms,
828                                               len(advertisements))
829
830        self.test_set_advertising_intervals(new_min_adv_interval_ms,
831                                            new_max_adv_interval_ms)
832
833        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
834                                               new_max_adv_interval_ms,
835                                               len(advertisements))
836        self.test_reset_advertising()
837
838
839    @test_case_log
840    def test_case_RA1_CD_SI200_CD_FSI10_UA1_RA1_CD_UA1(self):
841        """Test Case:  RA(1) - CD - SI(200) - CD - FSI(10) - UA(1)
842         - RA(1) - CD - UA(1)"""
843        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
844        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
845        new_min_adv_interval_ms = 200
846        new_max_adv_interval_ms = 200
847        invalid_small_min_adv_interval_ms = 10
848        invalid_small_max_adv_interval_ms = 10
849        advertisements = [self.three_advertisements[1]]
850        new_advertisement = [self.three_advertisements[2]]
851
852        self.test_reset_advertising()
853
854        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
855                                     orig_max_adv_interval_ms)
856
857        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
858                                               orig_max_adv_interval_ms,
859                                               len(advertisements))
860
861        self.test_set_advertising_intervals(new_min_adv_interval_ms,
862                                            new_max_adv_interval_ms)
863
864        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
865                                               new_max_adv_interval_ms,
866                                               len(advertisements))
867
868        # Fails to set intervals that are too small. Intervals remain the same.
869        self.test_fail_to_set_advertising_intervals(
870                invalid_small_min_adv_interval_ms,
871                invalid_small_max_adv_interval_ms,
872                new_min_adv_interval_ms, new_max_adv_interval_ms)
873
874        self.unregister_advertisements(advertisements)
875
876        # Register a new advertisement in order to avoid kernel caching.
877        self.register_advertisements(new_advertisement, new_min_adv_interval_ms,
878                                     new_max_adv_interval_ms)
879
880        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
881                                               new_max_adv_interval_ms,
882                                               len(advertisements))
883
884        self.unregister_advertisements(new_advertisement)
885
886
887    @test_case_log
888    def test_case_RA1_CD_SI200_CD_FSI20000_UA1_RA1_CD_UA1(self):
889        """Test Case:  RA(1) - CD - SI(200) - CD - FSI(20000) - UA(1)
890         - RA(1) - CD - UA(1)"""
891        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
892        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
893        new_min_adv_interval_ms = 200
894        new_max_adv_interval_ms = 200
895        invalid_large_min_adv_interval_ms = 20000
896        invalid_large_max_adv_interval_ms = 20000
897        advertisements = [self.three_advertisements[1]]
898        new_advertisement = [self.three_advertisements[2]]
899
900        self.test_reset_advertising()
901
902        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
903                                     orig_max_adv_interval_ms)
904
905        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
906                                               orig_max_adv_interval_ms,
907                                               len(advertisements))
908
909        self.test_set_advertising_intervals(new_min_adv_interval_ms,
910                                            new_max_adv_interval_ms)
911
912        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
913                                               new_max_adv_interval_ms,
914                                               len(advertisements))
915        # Fails to set intervals that are too large. Intervals remain the same.
916        self.test_fail_to_set_advertising_intervals(
917                invalid_large_min_adv_interval_ms,
918                invalid_large_max_adv_interval_ms,
919                new_min_adv_interval_ms, new_max_adv_interval_ms)
920
921        self.unregister_advertisements(advertisements)
922
923        # Register a new advertisement in order to avoid kernel caching.
924        self.register_advertisements(new_advertisement, new_min_adv_interval_ms,
925                                     new_max_adv_interval_ms)
926
927        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
928                                               new_max_adv_interval_ms,
929                                               len(advertisements))
930
931        self.unregister_advertisements(new_advertisement)
932
933
934    @test_case_log
935    def test_case_RA1_CD_SI200_CD_PC_CD_UA1(self):
936        """Test Case: RA(1) - CD - SI(200) - CD - PC - CD - UA(1)"""
937        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
938        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
939        new_min_adv_interval_ms = 200
940        new_max_adv_interval_ms = 200
941        advertisements = [self.sixth_advertisement]
942        self.test_reset_advertising()
943
944        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
945                                     orig_max_adv_interval_ms)
946
947        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
948                                               orig_max_adv_interval_ms,
949                                               len(advertisements))
950
951        self.test_set_advertising_intervals(new_min_adv_interval_ms,
952                                            new_max_adv_interval_ms)
953
954        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
955                                               new_max_adv_interval_ms,
956                                               len(advertisements))
957
958        # Turn off and then turn on the adapter.
959        self.test_power_off_adapter()
960        time.sleep(1)
961        self.test_power_on_adapter()
962
963        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
964                                               new_max_adv_interval_ms,
965                                               len(advertisements))
966
967        self.unregister_advertisements(advertisements)
968
969
970    @test_case_log
971    def test_case_RA1_CD_SI200_CD_SR_CD_UA1(self):
972        """Test Case: RA(1) - CD - SI(200) - CD - SR - CD - UA(1)"""
973        orig_min_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
974        orig_max_adv_interval_ms = self.DAFAULT_MIN_ADVERTISEMENT_INTERVAL_MS
975        new_min_adv_interval_ms = 200
976        new_max_adv_interval_ms = 200
977        advertisements = [self.first_advertisement]
978        self.test_reset_advertising()
979
980        self.register_advertisements(advertisements, orig_min_adv_interval_ms,
981                                     orig_max_adv_interval_ms)
982
983        self.test_check_duration_and_intervals(orig_min_adv_interval_ms,
984                                               orig_max_adv_interval_ms,
985                                               len(advertisements))
986
987        self.test_set_advertising_intervals(new_min_adv_interval_ms,
988                                            new_max_adv_interval_ms)
989
990        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
991                                               new_max_adv_interval_ms,
992                                               len(advertisements))
993        self.suspend_resume()
994
995        self.test_check_duration_and_intervals(new_min_adv_interval_ms,
996                                               new_max_adv_interval_ms,
997                                               len(advertisements))
998
999        self.unregister_advertisements(advertisements)
1000
1001    def run_once(self, host, advertisements, test_type, num_iterations=1):
1002        """Running Bluetooth adapter LE advertising autotest.
1003
1004        @param host: device under test host.
1005        @param advertisements: a list of advertisement instances.
1006        @param test_type: indicating one of three test types: multi-advertising,
1007                          single-advertising, reboot (stress only), or
1008                          suspend_resume (stress only).
1009
1010        @raises TestNAError: if DUT has low kernel version (<=3.8.11)
1011
1012        """
1013        self.host = host
1014        self.kernel_version = self.get_kernel_version(self.host)
1015        if self.kernel_version == UNSUPPORTED_KERNEL:
1016            # NOTE: Due to crbug/729648, we cannot set advertising intervals
1017            # on kernels that are 3.8.11 and below, so we raise TestNAError.
1018            raise error.TestNAError('Test cannnot proceed on old kernel '
1019                                    ' versions.')
1020
1021        self.advertisements = advertisements
1022        self.first_advertisement = advertisements[0]
1023        self.two_advertisements = advertisements[3:5]
1024        self.three_advertisements = advertisements[0:3]
1025        self.five_advertisements = advertisements[0:5]
1026        self.sixth_advertisement = advertisements[5]
1027
1028        ble_adapter = bluetooth_le_facade_adapter.BluetoothLEFacadeRemoteAdapter
1029        self.bluetooth_le_facade = ble_adapter(self.host)
1030        self.bluetooth_facade = self.bluetooth_le_facade
1031
1032        # Reset the adapter to forget previous stored data and turn it on.
1033        self.test_reset_on_adapter()
1034
1035        if test_type == 'multi_advertising':
1036            # Run all test cases for multiple advertisements.
1037            self.test_case_SI200_RA3_CD_UA3()
1038            self.test_case_SI200_RA3_CD_RA1_CD_UA1_CD_UA3()
1039            self.test_case_SI200_RA3_CD_RS()
1040            self.test_case_SI200_RA3_CD_UA1_CD_RS()
1041            self.test_case_SI200_RA3_CD_UA1_CD_RA2_CD_UA4()
1042            self.test_case_SI200_RA5_CD_FRA1_CD_UA5()
1043            self.test_case_RA3_CD_SI200_CD_UA3()
1044            self.test_case_RA3_CD_SI200_CD_RS()
1045            self.test_case_RA3_CD_SI200_CD_UA1_CD_RS()
1046            self.test_case_RA3_CD_SI200_CD_SI2000_CD_UA3()
1047            self.test_case_RA5_CD_SI200_CD_FRA1_CD_UA5()
1048            self.test_case_RA3_CD_SI200_CD_FSI10_CD_FSI20000_CD_UA3()
1049            self.test_case_SI200_RA3_CD_SR_CD_UA3()
1050            self.test_case_RA3_CD_SI200_CD_SR_CD_UA3()
1051            self.test_case_SI200_RA3_CD_PC_CD_UA3()
1052            self.test_case_RA3_CD_SI200_CD_PC_CD_UA3()
1053
1054        elif test_type == 'single_advertising':
1055            # Run all test cases for single advertisement.
1056            # Note: it is required to change the advertisement instance
1057            #       so that the advertisement data could be monitored by btmon.
1058            #       Otherwise, the advertisement data would be just cached and
1059            #       reused such that the data would not be visible in btmon.
1060            self.test_case_SI200_RA1_CD_UA1()
1061            self.test_case_SI200_RA1_CD_RS()
1062            self.test_case_RA1_CD_SI200_CD_UA1()
1063            self.test_case_RA1_CD_SI200_CD_RS()
1064            self.test_case_RA1_CD_SI200_CD_FSI10_UA1_RA1_CD_UA1()
1065            self.test_case_RA1_CD_SI200_CD_FSI20000_UA1_RA1_CD_UA1()
1066            self.test_case_SI200_RA1_CD_SR_CD_UA1()
1067            self.test_case_RA1_CD_SI200_CD_SR_CD_UA1()
1068            self.test_case_RA1_CD_SI200_CD_PC_CD_UA1()
1069
1070        elif test_type == 'suspend_resume':
1071           # Run all test cases for suspend resume stress testing.
1072            for i in xrange(num_iterations):
1073               logging.info('Starting suspend resume loop #%d', i+1)
1074               self.test_case_SI200_RA3_CD_SR_CD_UA3()
1075               self.test_case_RA3_CD_SI200_CD_SR_CD_UA3()
1076               self.test_case_SI200_RA1_CD_SR_CD_UA1()
1077               self.test_case_RA1_CD_SI200_CD_SR_CD_UA1()
1078
1079        elif test_type == 'reboot':
1080            # Run all test cases for reboot stress testing.
1081            for i in xrange(num_iterations):
1082                logging.info('Starting reboot loop #%d', i+1)
1083                self.test_case_SI200_RA3_CD_PC_CD_UA3()
1084                self.test_case_RA3_CD_SI200_CD_PC_CD_UA3()
1085                self.test_case_RA1_CD_SI200_CD_PC_CD_UA1()
1086
1087        if self.fails:
1088            raise error.TestFail(self.fails)
1089