Home | History | Annotate | Download | only in gatt
      1 #/usr/bin/env python3.4
      2 #
      3 # Copyright (C) 2016 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
      6 # use this file except in compliance with the License. You may obtain a copy of
      7 # the License at
      8 #
      9 # http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     14 # License for the specific language governing permissions and limitations under
     15 # the License.
     16 """
     17 This test script exercises different GATT connection tests.
     18 """
     19 
     20 import pprint
     21 from queue import Empty
     22 import time
     23 
     24 from acts.test_decorators import test_tracker_info
     25 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     26 from acts.test_utils.bt.bt_constants import ble_advertise_settings_modes
     27 from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
     28 from acts.test_utils.bt.bt_constants import ble_scan_settings_match_nums
     29 from acts.test_utils.bt.bt_constants import bt_profile_constants
     30 from acts.test_utils.bt.bt_constants import gatt_characteristic
     31 from acts.test_utils.bt.bt_constants import gatt_descriptor
     32 from acts.test_utils.bt.bt_constants import gatt_service_types
     33 from acts.test_utils.bt.bt_constants import gatt_cb_err
     34 from acts.test_utils.bt.bt_constants import gatt_cb_strings
     35 from acts.test_utils.bt.bt_constants import gatt_connection_state
     36 from acts.test_utils.bt.bt_constants import gatt_mtu_size
     37 from acts.test_utils.bt.bt_constants import gatt_phy_mask
     38 from acts.test_utils.bt.bt_constants import gatt_transport
     39 from acts.test_utils.bt.bt_constants import scan_result
     40 from acts.test_utils.bt.bt_gatt_utils import GattTestUtilsError
     41 from acts.test_utils.bt.bt_gatt_utils import disconnect_gatt_connection
     42 from acts.test_utils.bt.bt_gatt_utils import wait_for_gatt_disconnect_event
     43 from acts.test_utils.bt.bt_gatt_utils import close_gatt_client
     44 from acts.test_utils.bt.bt_gatt_utils import log_gatt_server_uuids
     45 from acts.test_utils.bt.bt_gatt_utils import orchestrate_gatt_connection
     46 from acts.test_utils.bt.bt_gatt_utils import setup_gatt_connection
     47 from acts.test_utils.bt.bt_gatt_utils import setup_multiple_services
     48 from acts.test_utils.bt.bt_test_utils import get_mac_address_of_generic_advertisement
     49 from acts.test_utils.bt.bt_test_utils import clear_bonded_devices
     50 
     51 PHYSICAL_DISCONNECT_TIMEOUT = 5
     52 
     53 
     54 class GattConnectTest(BluetoothBaseTest):
     55     adv_instances = []
     56     bluetooth_gatt_list = []
     57     gatt_server_list = []
     58     default_timeout = 10
     59     default_discovery_timeout = 3
     60 
     61     def __init__(self, controllers):
     62         BluetoothBaseTest.__init__(self, controllers)
     63         self.cen_ad = self.android_devices[0]
     64         self.per_ad = self.android_devices[1]
     65 
     66     def setup_test(self):
     67         super(BluetoothBaseTest, self).setup_test()
     68         bluetooth_gatt_list = []
     69         self.gatt_server_list = []
     70         self.adv_instances = []
     71         # Ensure there is ample time for a physical disconnect in between
     72         # testcases.
     73         self.log.info(
     74             "Waiting for {} seconds for physical GATT disconnections".format(
     75                 PHYSICAL_DISCONNECT_TIMEOUT))
     76         time.sleep(PHYSICAL_DISCONNECT_TIMEOUT)
     77 
     78     def teardown_test(self):
     79         for bluetooth_gatt in self.bluetooth_gatt_list:
     80             self.cen_ad.droid.gattClientClose(bluetooth_gatt)
     81         for gatt_server in self.gatt_server_list:
     82             self.per_ad.droid.gattServerClose(gatt_server)
     83         for adv in self.adv_instances:
     84             self.per_ad.droid.bleStopBleAdvertising(adv)
     85         return True
     86 
     87     def _orchestrate_gatt_disconnection(self, bluetooth_gatt, gatt_callback):
     88         self.log.info("Disconnecting from peripheral device.")
     89         try:
     90             disconnect_gatt_connection(self.cen_ad, bluetooth_gatt,
     91                                        gatt_callback)
     92             close_gatt_client(self.cen_ad, bluetooth_gatt)
     93             if bluetooth_gatt in self.bluetooth_gatt_list:
     94                 self.bluetooth_gatt_list.remove(bluetooth_gatt)
     95         except GattTestUtilsError as err:
     96             self.log.error(err)
     97             return False
     98         return True
     99 
    100     def _find_service_added_event(self, gatt_server_cb, uuid):
    101         expected_event = gatt_cb_strings['serv_added'].format(gatt_server_cb)
    102         try:
    103             event = self.per_ad.ed.pop_event(expected_event,
    104                                              self.default_timeout)
    105         except Empty:
    106             self.log.error(
    107                 gatt_cb_strings['serv_added_err'].format(expected_event))
    108             return False
    109         if event['data']['serviceUuid'].lower() != uuid.lower():
    110             self.log.error("Uuid mismatch. Found: {}, Expected {}.".format(
    111                 event['data']['serviceUuid'], uuid))
    112             return False
    113         return True
    114 
    115     def _verify_mtu_changed_on_client_and_server(
    116             self, expected_mtu, gatt_callback, gatt_server_callback):
    117         expected_event = gatt_cb_strings['mtu_changed'].format(gatt_callback)
    118         try:
    119             mtu_event = self.cen_ad.ed.pop_event(expected_event,
    120                                                  self.default_timeout)
    121             mtu_size_found = mtu_event['data']['MTU']
    122             if mtu_size_found != expected_mtu:
    123                 self.log.error("MTU size found: {}, expected: {}".format(
    124                     mtu_size_found, expected_mtu))
    125                 return False
    126         except Empty:
    127             self.log.error(
    128                 gatt_cb_err['mtu_changed_err'].format(expected_event))
    129             return False
    130 
    131         expected_event = gatt_cb_strings['mtu_serv_changed'].format(
    132             gatt_server_callback)
    133         try:
    134             mtu_event = self.per_ad.ed.pop_event(expected_event,
    135                                                  self.default_timeout)
    136             mtu_size_found = mtu_event['data']['MTU']
    137             if mtu_size_found != expected_mtu:
    138                 self.log.error("MTU size found: {}, expected: {}".format(
    139                     mtu_size_found, expected_mtu))
    140                 return False
    141         except Empty:
    142             self.log.error(
    143                 gatt_cb_err['mtu_serv_changed_err'].format(expected_event))
    144             return False
    145         return True
    146 
    147     @BluetoothBaseTest.bt_test_wrap
    148     @test_tracker_info(uuid='8a3530a3-c8bb-466b-9710-99e694c38618')
    149     def test_gatt_connect(self):
    150         """Test GATT connection over LE.
    151 
    152         Test establishing a gatt connection between a GATT server and GATT
    153         client.
    154 
    155         Steps:
    156         1. Start a generic advertisement.
    157         2. Start a generic scanner.
    158         3. Find the advertisement and extract the mac address.
    159         4. Stop the first scanner.
    160         5. Create a GATT connection between the scanner and advertiser.
    161         6. Disconnect the GATT connection.
    162 
    163         Expected Result:
    164         Verify that a connection was established and then disconnected
    165         successfully.
    166 
    167         Returns:
    168           Pass if True
    169           Fail if False
    170 
    171         TAGS: LE, Advertising, Filtering, Scanning, GATT
    172         Priority: 0
    173         """
    174         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    175         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    176             gatt_server_cb)
    177         self.gatt_server_list.append(gatt_server)
    178         try:
    179             bluetooth_gatt, gatt_callback, adv_callback = (
    180                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    181             self.bluetooth_gatt_list.append(bluetooth_gatt)
    182         except GattTestUtilsError as err:
    183             self.log.error(err)
    184             return False
    185         self.adv_instances.append(adv_callback)
    186         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    187                                                     gatt_callback)
    188 
    189     @BluetoothBaseTest.bt_test_wrap
    190     @test_tracker_info(uuid='a839b505-03ac-4783-be7e-1d43129a1948')
    191     def test_gatt_connect_stop_advertising(self):
    192         """Test GATT connection over LE then stop advertising
    193 
    194         A test case that verifies the GATT connection doesn't
    195         disconnect when LE advertisement is stopped.
    196 
    197         Steps:
    198         1. Start a generic advertisement.
    199         2. Start a generic scanner.
    200         3. Find the advertisement and extract the mac address.
    201         4. Stop the first scanner.
    202         5. Create a GATT connection between the scanner and advertiser.
    203         6. Stop the advertiser.
    204         7. Verify no connection state changed happened.
    205         8. Disconnect the GATT connection.
    206 
    207         Expected Result:
    208         Verify that a connection was established and not disconnected
    209         when advertisement stops.
    210 
    211         Returns:
    212           Pass if True
    213           Fail if False
    214 
    215         TAGS: LE, Advertising, Filtering, Scanning, GATT
    216         Priority: 0
    217         """
    218         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    219         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    220             gatt_server_cb)
    221         self.gatt_server_list.append(gatt_server)
    222         try:
    223             bluetooth_gatt, gatt_callback, adv_callback = (
    224                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    225             self.bluetooth_gatt_list.append(bluetooth_gatt)
    226         except GattTestUtilsError as err:
    227             self.log.error(err)
    228             return False
    229         self.per_ad.droid.bleStopBleAdvertising(adv_callback)
    230         try:
    231             event = self.cen_ad.ed.pop_event(
    232                 gatt_cb_strings['gatt_conn_change'].format(
    233                     gatt_callback, self.default_timeout))
    234             self.log.error(
    235                 "Connection event found when not expected: {}".format(event))
    236             return False
    237         except Empty:
    238             self.log.info("No connection state change as expected")
    239         try:
    240             self._orchestrate_gatt_disconnection(bluetooth_gatt, gatt_callback)
    241         except Exception as err:
    242             self.log.info("Failed to orchestrate disconnect: {}".format(err))
    243             return False
    244         return True
    245 
    246     @BluetoothBaseTest.bt_test_wrap
    247     @test_tracker_info(uuid='b82f91a8-54bb-4779-a117-73dc7fdb28cc')
    248     def test_gatt_connect_autoconnect(self):
    249         """Test GATT connection over LE.
    250 
    251         Test re-establishing a gatt connection using autoconnect
    252         set to True in order to test connection whitelist.
    253 
    254         Steps:
    255         1. Start a generic advertisement.
    256         2. Start a generic scanner.
    257         3. Find the advertisement and extract the mac address.
    258         4. Stop the first scanner.
    259         5. Create a GATT connection between the scanner and advertiser.
    260         6. Disconnect the GATT connection.
    261         7. Create a GATT connection with autoconnect set to True
    262         8. Disconnect the GATT connection.
    263 
    264         Expected Result:
    265         Verify that a connection was re-established and then disconnected
    266         successfully.
    267 
    268         Returns:
    269           Pass if True
    270           Fail if False
    271 
    272         TAGS: LE, Advertising, Filtering, Scanning, GATT
    273         Priority: 0
    274         """
    275         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    276         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    277             gatt_server_cb)
    278         self.gatt_server_list.append(gatt_server)
    279         autoconnect = False
    280         mac_address, adv_callback, scan_callback = (
    281             get_mac_address_of_generic_advertisement(self.cen_ad, self.per_ad))
    282         try:
    283             bluetooth_gatt, gatt_callback = setup_gatt_connection(
    284                 self.cen_ad, mac_address, autoconnect)
    285             self.cen_ad.droid.bleStopBleScan(scan_callback)
    286             self.bluetooth_gatt_list.append(bluetooth_gatt)
    287         except GattTestUtilsError as err:
    288             self.log.error(err)
    289             return False
    290         try:
    291             disconnect_gatt_connection(self.cen_ad, bluetooth_gatt,
    292                                        gatt_callback)
    293             close_gatt_client(self.cen_ad, bluetooth_gatt)
    294             if bluetooth_gatt in self.bluetooth_gatt_list:
    295                 self.bluetooth_gatt_list.remove(bluetooth_gatt)
    296         except GattTestUtilsError as err:
    297             self.log.error(err)
    298             return False
    299         autoconnect = True
    300         bluetooth_gatt = self.cen_ad.droid.gattClientConnectGatt(
    301             gatt_callback, mac_address, autoconnect, gatt_transport['auto'],
    302             False, gatt_phy_mask['1m_mask'])
    303         self.bluetooth_gatt_list.append(bluetooth_gatt)
    304         expected_event = gatt_cb_strings['gatt_conn_change'].format(
    305             gatt_callback)
    306         try:
    307             event = self.cen_ad.ed.pop_event(expected_event,
    308                                              self.default_timeout)
    309         except Empty:
    310             self.log.error(
    311                 gatt_cb_err['gatt_conn_change_err'].format(expected_event))
    312             test_result = False
    313         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    314                                                     gatt_callback)
    315 
    316     @BluetoothBaseTest.bt_test_wrap
    317     @test_tracker_info(uuid='e506fa50-7cd9-4bd8-938a-6b85dcfe6bc6')
    318     def test_gatt_connect_opportunistic(self):
    319         """Test opportunistic GATT connection over LE.
    320 
    321         Test establishing a gatt connection between a GATT server and GATT
    322         client in opportunistic mode.
    323 
    324         Steps:
    325         1. Start a generic advertisement.
    326         2. Start a generic scanner.
    327         3. Find the advertisement and extract the mac address.
    328         4. Stop the first scanner.
    329         5. Create GATT connection 1 between the scanner and advertiser normally
    330         6. Create GATT connection 2 between the scanner and advertiser using
    331            opportunistic mode
    332         7. Disconnect GATT connection 1
    333 
    334         Expected Result:
    335         Verify GATT connection 2 automatically disconnects when GATT connection
    336         1 disconnect
    337 
    338         Returns:
    339           Pass if True
    340           Fail if False
    341 
    342         TAGS: LE, Advertising, Filtering, Scanning, GATT
    343         Priority: 0
    344         """
    345         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    346         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    347             gatt_server_cb)
    348         self.gatt_server_list.append(gatt_server)
    349         mac_address, adv_callback, scan_callback = (
    350             get_mac_address_of_generic_advertisement(self.cen_ad, self.per_ad))
    351         # Make GATT connection 1
    352         try:
    353             bluetooth_gatt_1, gatt_callback_1 = setup_gatt_connection(
    354                 self.cen_ad,
    355                 mac_address,
    356                 False,
    357                 transport=gatt_transport['auto'],
    358                 opportunistic=False)
    359             self.cen_ad.droid.bleStopBleScan(scan_callback)
    360             self.bluetooth_gatt_list.append(bluetooth_gatt_1)
    361         except GattTestUtilsError as err:
    362             self.log.error(err)
    363             return False
    364         # Make GATT connection 2
    365         try:
    366             bluetooth_gatt_2, gatt_callback_2 = setup_gatt_connection(
    367                 self.cen_ad,
    368                 mac_address,
    369                 False,
    370                 transport=gatt_transport['auto'],
    371                 opportunistic=True)
    372             self.bluetooth_gatt_list.append(bluetooth_gatt_2)
    373         except GattTestUtilsError as err:
    374             self.log.error(err)
    375             return False
    376         # Disconnect GATT connection 1
    377         try:
    378             disconnect_gatt_connection(self.cen_ad, bluetooth_gatt_1,
    379                                        gatt_callback_1)
    380             close_gatt_client(self.cen_ad, bluetooth_gatt_1)
    381             if bluetooth_gatt_1 in self.bluetooth_gatt_list:
    382                 self.bluetooth_gatt_list.remove(bluetooth_gatt_1)
    383         except GattTestUtilsError as err:
    384             self.log.error(err)
    385             return False
    386         # Confirm that GATT connection 2 also disconnects
    387         wait_for_gatt_disconnect_event(self.cen_ad, gatt_callback_2)
    388         close_gatt_client(self.cen_ad, bluetooth_gatt_2)
    389         if bluetooth_gatt_2 in self.bluetooth_gatt_list:
    390             self.bluetooth_gatt_list.remove(bluetooth_gatt_2)
    391         return True
    392 
    393     @BluetoothBaseTest.bt_test_wrap
    394     @test_tracker_info(uuid='1e01838e-c4de-4720-9adf-9e0419378226')
    395     def test_gatt_request_min_mtu(self):
    396         """Test GATT connection over LE and exercise MTU sizes.
    397 
    398         Test establishing a gatt connection between a GATT server and GATT
    399         client. Request an MTU size that matches the correct minimum size.
    400 
    401         Steps:
    402         1. Start a generic advertisement.
    403         2. Start a generic scanner.
    404         3. Find the advertisement and extract the mac address.
    405         4. Stop the first scanner.
    406         5. Create a GATT connection between the scanner and advertiser.
    407         6. From the scanner (client) request MTU size change to the
    408         minimum value.
    409         7. Find the MTU changed event on the client.
    410         8. Disconnect the GATT connection.
    411 
    412         Expected Result:
    413         Verify that a connection was established and the MTU value found
    414         matches the expected MTU value.
    415 
    416         Returns:
    417           Pass if True
    418           Fail if False
    419 
    420         TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
    421         Priority: 0
    422         """
    423         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    424         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    425             gatt_server_cb)
    426         self.gatt_server_list.append(gatt_server)
    427         try:
    428             bluetooth_gatt, gatt_callback, adv_callback = (
    429                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    430             self.bluetooth_gatt_list.append(bluetooth_gatt)
    431         except GattTestUtilsError as err:
    432             self.log.error(err)
    433             return False
    434         self.adv_instances.append(adv_callback)
    435         expected_mtu = gatt_mtu_size['min']
    436         self.cen_ad.droid.gattClientRequestMtu(bluetooth_gatt, expected_mtu)
    437         if not self._verify_mtu_changed_on_client_and_server(
    438                 expected_mtu, gatt_callback, gatt_server_cb):
    439             return False
    440         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    441                                                     gatt_callback)
    442 
    443     @BluetoothBaseTest.bt_test_wrap
    444     @test_tracker_info(uuid='c1fa3a2d-fb47-47db-bdd1-458928cd6a5f')
    445     def test_gatt_request_max_mtu(self):
    446         """Test GATT connection over LE and exercise MTU sizes.
    447 
    448         Test establishing a gatt connection between a GATT server and GATT
    449         client. Request an MTU size that matches the correct maximum size.
    450 
    451         Steps:
    452         1. Start a generic advertisement.
    453         2. Start a generic scanner.
    454         3. Find the advertisement and extract the mac address.
    455         4. Stop the first scanner.
    456         5. Create a GATT connection between the scanner and advertiser.
    457         6. From the scanner (client) request MTU size change to the
    458         maximum value.
    459         7. Find the MTU changed event on the client.
    460         8. Disconnect the GATT connection.
    461 
    462         Expected Result:
    463         Verify that a connection was established and the MTU value found
    464         matches the expected MTU value.
    465 
    466         Returns:
    467           Pass if True
    468           Fail if False
    469 
    470         TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
    471         Priority: 0
    472         """
    473         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    474         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    475             gatt_server_cb)
    476         self.gatt_server_list.append(gatt_server)
    477         try:
    478             bluetooth_gatt, gatt_callback, adv_callback = (
    479                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    480             self.bluetooth_gatt_list.append(bluetooth_gatt)
    481         except GattTestUtilsError as err:
    482             self.log.error(err)
    483             return False
    484         self.adv_instances.append(adv_callback)
    485         expected_mtu = gatt_mtu_size['max']
    486         self.cen_ad.droid.gattClientRequestMtu(bluetooth_gatt, expected_mtu)
    487         if not self._verify_mtu_changed_on_client_and_server(
    488                 expected_mtu, gatt_callback, gatt_server_cb):
    489             return False
    490         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    491                                                     gatt_callback)
    492 
    493     @BluetoothBaseTest.bt_test_wrap
    494     @test_tracker_info(uuid='4416d483-dec3-46cb-8038-4d82620f873a')
    495     def test_gatt_request_out_of_bounds_mtu(self):
    496         """Test GATT connection over LE and exercise an out of bound MTU size.
    497 
    498         Test establishing a gatt connection between a GATT server and GATT
    499         client. Request an MTU size that is the MIN value minus 1.
    500 
    501         Steps:
    502         1. Start a generic advertisement.
    503         2. Start a generic scanner.
    504         3. Find the advertisement and extract the mac address.
    505         4. Stop the first scanner.
    506         5. Create a GATT connection between the scanner and advertiser.
    507         6. From the scanner (client) request MTU size change to the
    508         minimum value minus one.
    509         7. Find the MTU changed event on the client.
    510         8. Disconnect the GATT connection.
    511 
    512         Expected Result:
    513         Verify that an MTU changed event was not discovered and that
    514         it didn't cause an exception when requesting an out of bounds
    515         MTU.
    516 
    517         Returns:
    518           Pass if True
    519           Fail if False
    520 
    521         TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
    522         Priority: 0
    523         """
    524         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    525         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    526             gatt_server_cb)
    527         self.gatt_server_list.append(gatt_server)
    528         try:
    529             bluetooth_gatt, gatt_callback, adv_callback = (
    530                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    531             self.bluetooth_gatt_list.append(bluetooth_gatt)
    532         except GattTestUtilsError as err:
    533             self.log.error(err)
    534             return False
    535         self.adv_instances.append(adv_callback)
    536         unexpected_mtu = gatt_mtu_size['min'] - 1
    537         self.cen_ad.droid.gattClientRequestMtu(bluetooth_gatt, unexpected_mtu)
    538         if self._verify_mtu_changed_on_client_and_server(
    539                 unexpected_mtu, gatt_callback, gatt_server_cb):
    540             return False
    541         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    542                                                     gatt_callback)
    543 
    544     @BluetoothBaseTest.bt_test_wrap
    545     @test_tracker_info(uuid='31ffb9ca-cc75-43fb-9802-c19f1c5856b6')
    546     def test_gatt_connect_trigger_on_read_rssi(self):
    547         """Test GATT connection over LE read RSSI.
    548 
    549         Test establishing a gatt connection between a GATT server and GATT
    550         client then read the RSSI.
    551 
    552         Steps:
    553         1. Start a generic advertisement.
    554         2. Start a generic scanner.
    555         3. Find the advertisement and extract the mac address.
    556         4. Stop the first scanner.
    557         5. Create a GATT connection between the scanner and advertiser.
    558         6. From the scanner, request to read the RSSI of the advertiser.
    559         7. Disconnect the GATT connection.
    560 
    561         Expected Result:
    562         Verify that a connection was established and then disconnected
    563         successfully. Verify that the RSSI was ready correctly.
    564 
    565         Returns:
    566           Pass if True
    567           Fail if False
    568 
    569         TAGS: LE, Advertising, Filtering, Scanning, GATT, RSSI
    570         Priority: 1
    571         """
    572         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    573         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    574             gatt_server_cb)
    575         self.gatt_server_list.append(gatt_server)
    576         try:
    577             bluetooth_gatt, gatt_callback, adv_callback = (
    578                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    579             self.bluetooth_gatt_list.append(bluetooth_gatt)
    580         except GattTestUtilsError as err:
    581             self.log.error(err)
    582             return False
    583         self.adv_instances.append(adv_callback)
    584         expected_event = gatt_cb_strings['rd_remote_rssi'].format(
    585             gatt_callback)
    586         if self.cen_ad.droid.gattClientReadRSSI(bluetooth_gatt):
    587             try:
    588                 self.cen_ad.ed.pop_event(expected_event, self.default_timeout)
    589             except Empty:
    590                 self.log.error(
    591                     gatt_cb_err['rd_remote_rssi_err'].format(expected_event))
    592         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    593                                                     gatt_callback)
    594 
    595     @BluetoothBaseTest.bt_test_wrap
    596     @test_tracker_info(uuid='dee9ef28-b872-428a-821b-cc62f27ba936')
    597     def test_gatt_connect_trigger_on_services_discovered(self):
    598         """Test GATT connection and discover services of peripheral.
    599 
    600         Test establishing a gatt connection between a GATT server and GATT
    601         client the discover all services from the connected device.
    602 
    603         Steps:
    604         1. Start a generic advertisement.
    605         2. Start a generic scanner.
    606         3. Find the advertisement and extract the mac address.
    607         4. Stop the first scanner.
    608         5. Create a GATT connection between the scanner and advertiser.
    609         6. From the scanner (central device), discover services.
    610         7. Disconnect the GATT connection.
    611 
    612         Expected Result:
    613         Verify that a connection was established and then disconnected
    614         successfully. Verify that the service were discovered.
    615 
    616         Returns:
    617           Pass if True
    618           Fail if False
    619 
    620         TAGS: LE, Advertising, Filtering, Scanning, GATT, Services
    621         Priority: 1
    622         """
    623         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    624         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    625             gatt_server_cb)
    626         self.gatt_server_list.append(gatt_server)
    627         try:
    628             bluetooth_gatt, gatt_callback, adv_callback = (
    629                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    630             self.bluetooth_gatt_list.append(bluetooth_gatt)
    631         except GattTestUtilsError as err:
    632             self.log.error(err)
    633             return False
    634         self.adv_instances.append(adv_callback)
    635         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    636             expected_event = gatt_cb_strings['gatt_serv_disc'].format(
    637                 gatt_callback)
    638             try:
    639                 event = self.cen_ad.ed.pop_event(expected_event,
    640                                                  self.default_timeout)
    641             except Empty:
    642                 self.log.error(
    643                     gatt_cb_err['gatt_serv_disc'].format(expected_event))
    644                 return False
    645         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    646                                                     gatt_callback)
    647 
    648     @BluetoothBaseTest.bt_test_wrap
    649     @test_tracker_info(uuid='01883bdd-0cf8-48fb-bf15-467bbd4f065b')
    650     def test_gatt_connect_trigger_on_services_discovered_iterate_attributes(
    651             self):
    652         """Test GATT connection and iterate peripherals attributes.
    653 
    654         Test establishing a gatt connection between a GATT server and GATT
    655         client and iterate over all the characteristics and descriptors of the
    656         discovered services.
    657 
    658         Steps:
    659         1. Start a generic advertisement.
    660         2. Start a generic scanner.
    661         3. Find the advertisement and extract the mac address.
    662         4. Stop the first scanner.
    663         5. Create a GATT connection between the scanner and advertiser.
    664         6. From the scanner (central device), discover services.
    665         7. Iterate over all the characteristics and descriptors of the
    666         discovered features.
    667         8. Disconnect the GATT connection.
    668 
    669         Expected Result:
    670         Verify that a connection was established and then disconnected
    671         successfully. Verify that the services, characteristics, and descriptors
    672         were discovered.
    673 
    674         Returns:
    675           Pass if True
    676           Fail if False
    677 
    678         TAGS: LE, Advertising, Filtering, Scanning, GATT, Services
    679         Characteristics, Descriptors
    680         Priority: 1
    681         """
    682         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    683         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    684             gatt_server_cb)
    685         self.gatt_server_list.append(gatt_server)
    686         try:
    687             bluetooth_gatt, gatt_callback, adv_callback = (
    688                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    689             self.bluetooth_gatt_list.append(bluetooth_gatt)
    690         except GattTestUtilsError as err:
    691             self.log.error(err)
    692             return False
    693         self.adv_instances.append(adv_callback)
    694         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    695             expected_event = gatt_cb_strings['gatt_serv_disc'].format(
    696                 gatt_callback)
    697             try:
    698                 event = self.cen_ad.ed.pop_event(expected_event,
    699                                                  self.default_timeout)
    700                 discovered_services_index = event['data']['ServicesIndex']
    701             except Empty:
    702                 self.log.error(
    703                     gatt_cb_err['gatt_serv_disc'].format(expected_event))
    704                 return False
    705             log_gatt_server_uuids(self.cen_ad, discovered_services_index)
    706         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    707                                                     gatt_callback)
    708 
    709     @BluetoothBaseTest.bt_test_wrap
    710     @test_tracker_info(uuid='d4277bee-da99-4f48-8a4d-f81b5389da18')
    711     def test_gatt_connect_with_service_uuid_variations(self):
    712         """Test GATT connection with multiple service uuids.
    713 
    714         Test establishing a gatt connection between a GATT server and GATT
    715         client with multiple service uuid variations.
    716 
    717         Steps:
    718         1. Start a generic advertisement.
    719         2. Start a generic scanner.
    720         3. Find the advertisement and extract the mac address.
    721         4. Stop the first scanner.
    722         5. Create a GATT connection between the scanner and advertiser.
    723         6. From the scanner (central device), discover services.
    724         7. Verify that all the service uuid variations are found.
    725         8. Disconnect the GATT connection.
    726 
    727         Expected Result:
    728         Verify that a connection was established and then disconnected
    729         successfully. Verify that the service uuid variations are found.
    730 
    731         Returns:
    732           Pass if True
    733           Fail if False
    734 
    735         TAGS: LE, Advertising, Filtering, Scanning, GATT, Services
    736         Priority: 2
    737         """
    738         try:
    739             gatt_server_cb, gatt_server = setup_multiple_services(self.per_ad)
    740             self.gatt_server_list.append(gatt_server)
    741         except GattTestUtilsError as err:
    742             self.log.error(err)
    743             return False
    744         try:
    745             bluetooth_gatt, gatt_callback, adv_callback = (
    746                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    747             self.bluetooth_gatt_list.append(bluetooth_gatt)
    748         except GattTestUtilsError as err:
    749             self.log.error(err)
    750             return False
    751         self.adv_instances.append(adv_callback)
    752         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    753             expected_event = gatt_cb_strings['gatt_serv_disc'].format(
    754                 gatt_callback)
    755             try:
    756                 event = self.cen_ad.ed.pop_event(expected_event,
    757                                                  self.default_timeout)
    758             except Empty:
    759                 self.log.error(
    760                     gatt_cb_err['gatt_serv_disc'].format(expected_event))
    761                 return False
    762             discovered_services_index = event['data']['ServicesIndex']
    763             log_gatt_server_uuids(self.cen_ad, discovered_services_index)
    764 
    765         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    766                                                     gatt_callback)
    767 
    768     @BluetoothBaseTest.bt_test_wrap
    769     @test_tracker_info(uuid='7d3442c5-f71f-44ae-bd35-f2569f01b3b8')
    770     def test_gatt_connect_in_quick_succession(self):
    771         """Test GATT connections multiple times.
    772 
    773         Test establishing a gatt connection between a GATT server and GATT
    774         client with multiple iterations.
    775 
    776         Steps:
    777         1. Start a generic advertisement.
    778         2. Start a generic scanner.
    779         3. Find the advertisement and extract the mac address.
    780         4. Stop the first scanner.
    781         5. Create a GATT connection between the scanner and advertiser.
    782         6. Disconnect the GATT connection.
    783         7. Repeat steps 5 and 6 twenty times.
    784 
    785         Expected Result:
    786         Verify that a connection was established and then disconnected
    787         successfully twenty times.
    788 
    789         Returns:
    790           Pass if True
    791           Fail if False
    792 
    793         TAGS: LE, Advertising, Filtering, Scanning, GATT, Stress
    794         Priority: 1
    795         """
    796         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    797         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    798             gatt_server_cb)
    799         self.gatt_server_list.append(gatt_server)
    800         mac_address, adv_callback, scan_callback = get_mac_address_of_generic_advertisement(
    801             self.cen_ad, self.per_ad)
    802         autoconnect = False
    803         for i in range(1000):
    804             self.log.info("Starting connection iteration {}".format(i + 1))
    805             try:
    806                 bluetooth_gatt, gatt_callback = setup_gatt_connection(
    807                     self.cen_ad, mac_address, autoconnect)
    808                 self.cen_ad.droid.bleStopBleScan(scan_callback)
    809             except GattTestUtilsError as err:
    810                 self.log.error(err)
    811                 return False
    812             test_result = self._orchestrate_gatt_disconnection(
    813                 bluetooth_gatt, gatt_callback)
    814             if not test_result:
    815                 self.log.info("Failed to disconnect from peripheral device.")
    816                 return False
    817         self.adv_instances.append(adv_callback)
    818         return True
    819 
    820     @BluetoothBaseTest.bt_test_wrap
    821     @test_tracker_info(uuid='148469d9-7ab0-4c08-b2e9-7e49e88da1fc')
    822     def test_gatt_connect_mitm_attack(self):
    823         """Test GATT connection with permission write encrypted mitm.
    824 
    825         Test establishing a gatt connection between a GATT server and GATT
    826         client while the GATT server's characteristic includes the property
    827         write value and the permission write encrypted mitm value. This will
    828         prompt LE pairing and then the devices will create a bond.
    829 
    830         Steps:
    831         1. Create a GATT server and server callback on the peripheral device.
    832         2. Create a unique service and characteristic uuid on the peripheral.
    833         3. Create a characteristic on the peripheral with these properties:
    834             gatt_characteristic['property_write'],
    835             gatt_characteristic['permission_write_encrypted_mitm']
    836         4. Create a GATT service on the peripheral.
    837         5. Add the characteristic to the GATT service.
    838         6. Create a GATT connection between your central and peripheral device.
    839         7. From the central device, discover the peripheral's services.
    840         8. Iterate the services found until you find the unique characteristic
    841             created in step 3.
    842         9. Once found, write a random but valid value to the characteristic.
    843         10. Start pairing helpers on both devices immediately after attempting
    844             to write to the characteristic.
    845         11. Within 10 seconds of writing the characteristic, there should be
    846             a prompt to bond the device from the peripheral. The helpers will
    847             handle the UI interaction automatically. (see
    848             BluetoothConnectionFacade.java bluetoothStartPairingHelper).
    849         12. Verify that the two devices are bonded.
    850 
    851         Expected Result:
    852         Verify that a connection was established and the devices are bonded.
    853 
    854         Returns:
    855           Pass if True
    856           Fail if False
    857 
    858         TAGS: LE, Advertising, Filtering, Scanning, GATT, Characteristic, MITM
    859         Priority: 1
    860         """
    861         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    862         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    863             gatt_server_cb)
    864         self.gatt_server_list.append(gatt_server)
    865         service_uuid = "3846D7A0-69C8-11E4-BA00-0002A5D5C51B"
    866         test_uuid = "aa7edd5a-4d1d-4f0e-883a-d145616a1630"
    867         bonded = False
    868         characteristic = self.per_ad.droid.gattServerCreateBluetoothGattCharacteristic(
    869             test_uuid, gatt_characteristic['property_write'],
    870             gatt_characteristic['permission_write_encrypted_mitm'])
    871         gatt_service = self.per_ad.droid.gattServerCreateService(
    872             service_uuid, gatt_service_types['primary'])
    873         self.per_ad.droid.gattServerAddCharacteristicToService(
    874             gatt_service, characteristic)
    875         self.per_ad.droid.gattServerAddService(gatt_server, gatt_service)
    876         result = self._find_service_added_event(gatt_server_cb, service_uuid)
    877         if not result:
    878             return False
    879         bluetooth_gatt, gatt_callback, adv_callback = (
    880             orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    881         self.bluetooth_gatt_list.append(bluetooth_gatt)
    882         self.adv_instances.append(adv_callback)
    883         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    884             expected_event = gatt_cb_strings['gatt_serv_disc'].format(
    885                 gatt_callback)
    886             try:
    887                 event = self.cen_ad.ed.pop_event(expected_event,
    888                                                  self.default_timeout)
    889             except Empty:
    890                 self.log.error(
    891                     gatt_cb_err['gatt_serv_disc'].format(expected_event))
    892                 return False
    893             discovered_services_index = event['data']['ServicesIndex']
    894         else:
    895             self.log.info("Failed to discover services.")
    896             return False
    897         test_value = [1, 2, 3, 4, 5, 6, 7]
    898         services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount(
    899             discovered_services_index)
    900         for i in range(services_count):
    901             characteristic_uuids = (
    902                 self.cen_ad.droid.gattClientGetDiscoveredCharacteristicUuids(
    903                     discovered_services_index, i))
    904             for characteristic_uuid in characteristic_uuids:
    905                 if characteristic_uuid == test_uuid:
    906                     self.cen_ad.droid.bluetoothStartPairingHelper()
    907                     self.per_ad.droid.bluetoothStartPairingHelper()
    908                     self.cen_ad.droid.gattClientCharacteristicSetValue(
    909                         bluetooth_gatt, discovered_services_index, i,
    910                         characteristic_uuid, test_value)
    911                     self.cen_ad.droid.gattClientWriteCharacteristic(
    912                         bluetooth_gatt, discovered_services_index, i,
    913                         characteristic_uuid)
    914                     start_time = time.time() + self.default_timeout
    915                     target_name = self.per_ad.droid.bluetoothGetLocalName()
    916                     while time.time() < start_time and bonded == False:
    917                         bonded_devices = \
    918                             self.cen_ad.droid.bluetoothGetBondedDevices()
    919                         for device in bonded_devices:
    920                             if ('name' in device.keys()
    921                                     and device['name'] == target_name):
    922                                 bonded = True
    923                                 break
    924                     bonded = False
    925                     target_name = self.cen_ad.droid.bluetoothGetLocalName()
    926                     while time.time() < start_time and bonded == False:
    927                         bonded_devices = \
    928                             self.per_ad.droid.bluetoothGetBondedDevices()
    929                         for device in bonded_devices:
    930                             if ('name' in device.keys()
    931                                     and device['name'] == target_name):
    932                                 bonded = True
    933                                 break
    934         for ad in [self.cen_ad, self.per_ad]:
    935             if not clear_bonded_devices(ad):
    936                 return False
    937             # Necessary sleep time for entries to update unbonded state
    938             time.sleep(2)
    939             bonded_devices = ad.droid.bluetoothGetBondedDevices()
    940             if len(bonded_devices) > 0:
    941                 self.log.error(
    942                     "Failed to unbond devices: {}".format(bonded_devices))
    943                 return False
    944         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    945                                                     gatt_callback)
    946 
    947     @BluetoothBaseTest.bt_test_wrap
    948     @test_tracker_info(uuid='cc3fc361-7bf1-4ee2-9e46-4a27c88ce6a8')
    949     def test_gatt_connect_get_connected_devices(self):
    950         """Test GATT connections show up in getConnectedDevices
    951 
    952         Test establishing a gatt connection between a GATT server and GATT
    953         client. Verify that active connections show up using
    954         BluetoothManager.getConnectedDevices API.
    955 
    956         Steps:
    957         1. Start a generic advertisement.
    958         2. Start a generic scanner.
    959         3. Find the advertisement and extract the mac address.
    960         4. Stop the first scanner.
    961         5. Create a GATT connection between the scanner and advertiser.
    962         7. Verify the GATT Client has an open connection to the GATT Server.
    963         8. Verify the GATT Server has an open connection to the GATT Client.
    964         9. Disconnect the GATT connection.
    965 
    966         Expected Result:
    967         Verify that a connection was established, connected devices are found
    968         on both the central and peripheral devices, and then disconnected
    969         successfully.
    970 
    971         Returns:
    972           Pass if True
    973           Fail if False
    974 
    975         TAGS: LE, Advertising, Scanning, GATT
    976         Priority: 2
    977         """
    978         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
    979         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    980             gatt_server_cb)
    981         self.gatt_server_list.append(gatt_server)
    982         try:
    983             bluetooth_gatt, gatt_callback, adv_callback = (
    984                 orchestrate_gatt_connection(self.cen_ad, self.per_ad))
    985             self.bluetooth_gatt_list.append(bluetooth_gatt)
    986         except GattTestUtilsError as err:
    987             self.log.error(err)
    988             return False
    989         conn_cen_devices = self.cen_ad.droid.bluetoothGetConnectedLeDevices(
    990             bt_profile_constants['gatt'])
    991         conn_per_devices = self.per_ad.droid.bluetoothGetConnectedLeDevices(
    992             bt_profile_constants['gatt_server'])
    993         target_name = self.per_ad.droid.bluetoothGetLocalName()
    994         error_message = ("Connected device {} not found in list of connected "
    995                          "devices {}")
    996         if not any(d['name'] == target_name for d in conn_cen_devices):
    997             self.log.error(error_message.format(target_name, conn_cen_devices))
    998             return False
    999         # For the GATT server only check the size of the list since
   1000         # it may or may not include the device name.
   1001         target_name = self.cen_ad.droid.bluetoothGetLocalName()
   1002         if not conn_per_devices:
   1003             self.log.error(error_message.format(target_name, conn_per_devices))
   1004             return False
   1005         self.adv_instances.append(adv_callback)
   1006         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
   1007                                                     gatt_callback)
   1008 
   1009     @BluetoothBaseTest.bt_test_wrap
   1010     @test_tracker_info(uuid='a0a37ca6-9fa8-4d35-9fdb-0e25b4b8a363')
   1011     def test_gatt_connect_second_adv_after_canceling_first_adv(self):
   1012         """Test GATT connection to peripherals second advertising address.
   1013 
   1014         The the ability of cancelling GATT connections and trying to reconnect
   1015         to the same device via a different address.
   1016 
   1017         Steps:
   1018         1. A starts advertising
   1019         2. B starts scanning and finds A's mac address
   1020         3. Stop advertisement from step 1. Start a new advertisement on A and
   1021             find the new new mac address, B knows of both old and new address.
   1022         4. B1 sends connect request to old address of A
   1023         5. B1 cancel connect attempt after 10 seconds
   1024         6. B1 sends connect request to new address of A
   1025         7. Verify B1 establish connection to A in less than 10 seconds
   1026 
   1027         Expected Result:
   1028         Verify that a connection was established only on the second
   1029             advertisement's mac address.
   1030 
   1031         Returns:
   1032           Pass if True
   1033           Fail if False
   1034 
   1035         TAGS: LE, Advertising, Scanning, GATT
   1036         Priority: 3
   1037         """
   1038         autoconnect = False
   1039         transport = gatt_transport['auto']
   1040         opportunistic = False
   1041         # Setup a basic Gatt server on the peripheral
   1042         gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
   1043         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
   1044             gatt_server_cb)
   1045 
   1046         # Set advertisement settings to include local name in advertisement
   1047         # and set the advertising mode to low_latency.
   1048         self.per_ad.droid.bleSetAdvertiseSettingsIsConnectable(True)
   1049         self.per_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
   1050         self.per_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
   1051             ble_advertise_settings_modes['low_latency'])
   1052 
   1053         # Setup necessary advertisement objects.
   1054         advertise_data = self.per_ad.droid.bleBuildAdvertiseData()
   1055         advertise_settings = self.per_ad.droid.bleBuildAdvertiseSettings()
   1056         advertise_callback = self.per_ad.droid.bleGenBleAdvertiseCallback()
   1057 
   1058         # Step 1: Start advertisement
   1059         self.per_ad.droid.bleStartBleAdvertising(
   1060             advertise_callback, advertise_data, advertise_settings)
   1061 
   1062         # Setup scan settings for low_latency scanning and to include the local name
   1063         # of the advertisement started in step 1.
   1064         filter_list = self.cen_ad.droid.bleGenFilterList()
   1065         self.cen_ad.droid.bleSetScanSettingsNumOfMatches(
   1066             ble_scan_settings_match_nums['one'])
   1067         self.cen_ad.droid.bleSetScanFilterDeviceName(
   1068             self.per_ad.droid.bluetoothGetLocalName())
   1069         self.cen_ad.droid.bleBuildScanFilter(filter_list)
   1070         self.cen_ad.droid.bleSetScanSettingsScanMode(
   1071             ble_scan_settings_modes['low_latency'])
   1072 
   1073         # Setup necessary scan objects.
   1074         scan_settings = self.cen_ad.droid.bleBuildScanSetting()
   1075         scan_callback = self.cen_ad.droid.bleGenScanCallback()
   1076 
   1077         # Step 2: Start scanning on central Android device and find peripheral
   1078         # address.
   1079         self.cen_ad.droid.bleStartBleScan(filter_list, scan_settings,
   1080                                           scan_callback)
   1081         expected_event_name = scan_result.format(scan_callback)
   1082         try:
   1083             mac_address_pre_restart = self.cen_ad.ed.pop_event(
   1084                 expected_event_name, self.default_timeout)['data']['Result'][
   1085                     'deviceInfo']['address']
   1086             self.log.info(
   1087                 "Peripheral advertisement found with mac address: {}".format(
   1088                     mac_address_pre_restart))
   1089         except Empty:
   1090             self.log.info("Peripheral advertisement not found")
   1091             test_result = False
   1092 
   1093         # Step 3: Restart peripheral advertising such that a new mac address is
   1094         # created.
   1095         self.per_ad.droid.bleStopBleAdvertising(advertise_callback)
   1096         self.per_ad.droid.bleStartBleAdvertising(
   1097             advertise_callback, advertise_data, advertise_settings)
   1098 
   1099         try:
   1100             mac_address_post_restart = self.cen_ad.ed.pop_event(
   1101                 expected_event_name, self.default_timeout)['data']['Result'][
   1102                     'deviceInfo']['address']
   1103             self.log.info(
   1104                 "Peripheral advertisement found with mac address: {}".format(
   1105                     mac_address_post_restart))
   1106         except Empty:
   1107             self.log.info("Peripheral advertisement not found")
   1108             test_result = False
   1109 
   1110         # Steps 4: Try to connect to the first mac address
   1111         gatt_callback = self.cen_ad.droid.gattCreateGattCallback()
   1112         self.log.info(
   1113             "Gatt Connect to mac address {}.".format(mac_address_pre_restart))
   1114         bluetooth_gatt = self.cen_ad.droid.gattClientConnectGatt(
   1115             gatt_callback, mac_address_pre_restart, autoconnect, transport,
   1116             opportunistic, gatt_phy_mask['1m_mask'])
   1117         self.bluetooth_gatt_list.append(bluetooth_gatt)
   1118         expected_event = gatt_cb_strings['gatt_conn_change'].format(
   1119             gatt_callback)
   1120         try:
   1121             event = self.cen_ad.ed.pop_event(expected_event,
   1122                                              self.default_timeout)
   1123             self.log.error(
   1124                 "Connection callback updated unexpectedly: {}".format(event))
   1125             return False
   1126         except Empty:
   1127             self.log.info("No connection update as expected.")
   1128 
   1129         # Step 5: Cancel connection request.
   1130         self.cen_ad.droid.gattClientDisconnect(bluetooth_gatt)
   1131 
   1132         # Step 6: Connect to second mac address.
   1133         self.log.info(
   1134             "Gatt Connect to mac address {}.".format(mac_address_post_restart))
   1135         bluetooth_gatt = self.cen_ad.droid.gattClientConnectGatt(
   1136             gatt_callback, mac_address_post_restart, autoconnect, transport,
   1137             opportunistic, gatt_phy_mask['1m_mask'])
   1138         self.bluetooth_gatt_list.append(bluetooth_gatt)
   1139         expected_event = gatt_cb_strings['gatt_conn_change'].format(
   1140             gatt_callback)
   1141 
   1142         # Step 7: Verify connection was setup successfully.
   1143         try:
   1144             event = self.cen_ad.ed.pop_event(expected_event,
   1145                                              self.default_timeout)
   1146             self.log.info(
   1147                 "Connection callback updated successfully: {}".format(event))
   1148             if event['data']['State'] != gatt_connection_state['connected']:
   1149                 self.log.error(
   1150                     "Could not establish a connection to the peripheral.")
   1151                 return False
   1152         except Empty:
   1153             self.log.error("No connection update was found.")
   1154             return False
   1155         return self.cen_ad.droid.gattClientDisconnect(bluetooth_gatt)
   1156