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