def test_le_pairing(self):
        """Test LE pairing transport stress

        This will test LE pairing between two android devices.

        Steps:
        1. Start an LE advertisement on secondary device.
        2. Find address from primary device.
        3. Discover and bond to LE address.
        4. Stop LE advertisement on secondary device.
        5. Repeat steps 1-4 100 times

        Expected Result:
        LE pairing should pass 100 times.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Scanning, Stress, Pairing
        Priority: 1
        """
        iterations = 100
        for i in range(iterations):
            try:
                target_address, adv_callback, scan_callback = get_mac_address_of_generic_advertisement(
                    self.scn_ad, self.adv_ad)
            except BtTestUtilsError as err:
                self.log.error(err)
                return False
            self.log.info("Begin interation {}/{}".format(i + 1, iterations))
            self.scn_ad.droid.bluetoothStartPairingHelper()
            self.adv_ad.droid.bluetoothStartPairingHelper()
            start_time = self.start_timer()
            self.scn_ad.droid.bluetoothDiscoverAndBond(target_address)
            if not self._verify_successful_bond(target_address):
                self.log.error("Failed to bond devices.")
                return False
            self.log.info("Total time (ms): {}".format(self.end_timer()))
            if not self._verify_successful_bond(
                    self.adv_ad.droid.bluetoothGetLocalAddress()):
                self.log.error("Failed to bond BREDR devices.")
                return False
            if not self.scn_ad.droid.bluetoothUnbond(target_address):
                self.log.error("Failed to unbond device from scanner.")
                return False
            time.sleep(2)
            if not self.adv_ad.droid.bluetoothUnbond(
                    self.scn_ad.droid.bluetoothGetLocalAddress()):
                self.log.error("Failed to unbond device from advertiser.")
                return False
            self.adv_ad.droid.bleStopBleAdvertising(adv_callback)
            self.scn_ad.droid.bleStopBleScan(scan_callback)
            # Magic sleep to let unbonding finish
            time.sleep(2)
        return True
Пример #2
0
    def test_gatt_connect_in_quick_succession(self):
        """Test GATT connections multiple times.

        Test establishing a gatt connection between a GATT server and GATT
        client with multiple iterations.

        Steps:
        1. Start a generic advertisement.
        2. Start a generic scanner.
        3. Find the advertisement and extract the mac address.
        4. Stop the first scanner.
        5. Create a GATT connection between the scanner and advertiser.
        6. Disconnect the GATT connection.
        7. Repeat steps 5 and 6 twenty times.

        Expected Result:
        Verify that a connection was established and then disconnected
        successfully twenty times.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, GATT, Stress
        Priority: 1
        """
        gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
        gatt_server = self.per_ad.droid.gattServerOpenGattServer(
            gatt_server_cb)
        self.gatt_server_list.append(gatt_server)
        mac_address, adv_callback = get_mac_address_of_generic_advertisement(
            self.cen_ad, self.per_ad)
        autoconnect = False
        for i in range(1000):
            self.log.info("Starting connection iteration {}".format(i + 1))
            try:
                bluetooth_gatt, gatt_callback = setup_gatt_connection(
                    self.cen_ad, mac_address, autoconnect)
            except GattTestUtilsError as err:
                self.log.error(err)
                return False
            test_result = self._orchestrate_gatt_disconnection(bluetooth_gatt,
                                                               gatt_callback)
            self.cen_ad.droid.gattClientClose(bluetooth_gatt)
            if not test_result:
                self.log.info("Failed to disconnect from peripheral device.")
                return False
        self.adv_instances.append(adv_callback)
        return True
Пример #3
0
def orchestrate_gatt_connection(cen_ad,
                                per_ad,
                                transport=GattTransport.TRANSPORT_LE.value,
                                mac_address=None,
                                autoconnect=False):
    adv_callback = None
    if mac_address is None:
        if transport == GattTransport.TRANSPORT_LE.value:
            try:
                mac_address, adv_callback = (
                    get_mac_address_of_generic_advertisement(cen_ad, per_ad))
            except BtTestUtilsError as err:
                raise GattTestUtilsError(
                    "Error in getting mac address: {}".format(err))
        else:
            mac_address = per_ad.droid.bluetoothGetLocalAddress()
            adv_callback = None
    bluetooth_gatt, gatt_callback = setup_gatt_connection(
        cen_ad, mac_address, autoconnect, transport)
    return bluetooth_gatt, gatt_callback, adv_callback
Пример #4
0
def orchestrate_coc_connection(
        client_ad,
        server_ad,
        is_ble,
        secured_conn=False,
        le_connection_interval=0,
        le_tx_data_length=default_le_data_length,
        accept_timeout_ms=default_bluetooth_socket_timeout_ms,
        le_min_ce_len=0,
        le_max_ce_len=0,
        gatt_disconnection=True):
    """Sets up the CoC connection between two Android devices.

    Args:
        client_ad: the Android device performing the connection.
        server_ad: the Android device accepting the connection.
        is_ble: using LE transport.
        secured_conn: using secured connection
        le_connection_interval: LE Connection interval. 0 means use default.
        le_tx_data_length: LE Data Length used by BT Controller to transmit.
        accept_timeout_ms: timeout while waiting for incoming connection.
        gatt_disconnection: LE GATT disconnection, default is True, False will return
        bluetooth_gatt and gatt_callback
    Returns:
        True if connection was successful or false if unsuccessful,
        client connection ID,
        and server connection ID
    """
    server_ad.droid.bluetoothStartPairingHelper()
    client_ad.droid.bluetoothStartPairingHelper()

    adv_callback = None
    mac_address = None
    if is_ble:
        try:
            # This will start advertising and scanning. Will fail if it could
            # not find the advertisements from server_ad
            client_ad.log.info(
                "Orchestrate_coc_connection: Start BLE advertisement and"
                "scanning. Secured Connection={}".format(secured_conn))
            mac_address, adv_callback, scan_callback = (
                get_mac_address_of_generic_advertisement(client_ad, server_ad))
        except BtTestUtilsError as err:
            raise BtCoCTestUtilsError(
                "Orchestrate_coc_connection: Error in getting mac address: {}".
                format(err))
    else:
        mac_address = server_ad.droid.bluetoothGetLocalAddress()
        adv_callback = None

    # Adjust the Connection Interval (if necessary)
    bluetooth_gatt_1 = -1
    gatt_callback_1 = -1
    gatt_connected = False
    if is_ble and (le_connection_interval != 0 or le_min_ce_len != 0 or le_max_ce_len != 0):
        client_ad.log.info(
            "Adjusting connection interval={}, le_min_ce_len={}, le_max_ce_len={}"
            .format(le_connection_interval, le_min_ce_len, le_max_ce_len))
        try:
            bluetooth_gatt_1, gatt_callback_1 = setup_gatt_connection(
                client_ad,
                mac_address,
                False,
                transport=gatt_transport['le'],
                opportunistic=False)
            client_ad.droid.bleStopBleScan(scan_callback)
        except GattTestUtilsError as err:
            client_ad.log.error(err)
            if (adv_callback != None):
                server_ad.droid.bleStopBleAdvertising(adv_callback)
            return False, None, None
        client_ad.log.info("setup_gatt_connection returns success")
        if (le_connection_interval != 0):
            minInterval = le_connection_interval / le_connection_interval_time_step_ms
            maxInterval = le_connection_interval / le_connection_interval_time_step_ms
        else:
            minInterval = default_le_connection_interval_ms / le_connection_interval_time_step_ms
            maxInterval = default_le_connection_interval_ms / le_connection_interval_time_step_ms
        if (le_min_ce_len != 0):
            le_min_ce_len = le_min_ce_len / le_connection_event_time_step_ms
        if (le_max_ce_len != 0):
            le_max_ce_len = le_max_ce_len / le_connection_event_time_step_ms

        return_status = client_ad.droid.gattClientRequestLeConnectionParameters(
            bluetooth_gatt_1, minInterval, maxInterval, 0,
            le_default_supervision_timeout, le_min_ce_len, le_max_ce_len)
        if not return_status:
            client_ad.log.error(
                "gattClientRequestLeConnectionParameters returns failure")
            if (adv_callback != None):
                server_ad.droid.bleStopBleAdvertising(adv_callback)
            return False, None, None
        client_ad.log.info(
            "gattClientRequestLeConnectionParameters returns success. Interval={}"
            .format(minInterval))
        gatt_connected = True
        # For now, we will only test with 1 Mbit Phy.
        # TODO: Add explicit tests with 2 MBit Phy.
        client_ad.droid.gattClientSetPreferredPhy(
            bluetooth_gatt_1, gatt_phy['1m'], gatt_phy['1m'], 0)

    server_ad.droid.bluetoothSocketConnBeginAcceptThreadPsm(
        accept_timeout_ms, is_ble, secured_conn)

    psm_value = server_ad.droid.bluetoothSocketConnGetPsm()
    client_ad.log.info("Assigned PSM value={}".format(psm_value))

    client_ad.droid.bluetoothSocketConnBeginConnectThreadPsm(
        mac_address, is_ble, psm_value, secured_conn)

    if (le_tx_data_length != default_le_data_length) and is_ble:
        client_ad.log.info("orchestrate_coc_connection: call "
                           "bluetoothSocketRequestMaximumTxDataLength")
        client_ad.droid.bluetoothSocketRequestMaximumTxDataLength()

    end_time = time.time() + bt_default_timeout
    test_result = False
    while time.time() < end_time:
        if len(server_ad.droid.bluetoothSocketConnActiveConnections()) > 0:
            server_ad.log.info("CoC Server Connection Active")
            if len(client_ad.droid.bluetoothSocketConnActiveConnections()) > 0:
                client_ad.log.info("CoC Client Connection Active")
                test_result = True
                break
        time.sleep(1)

    if (adv_callback != None):
        server_ad.droid.bleStopBleAdvertising(adv_callback)

    if not test_result:
        client_ad.log.error("Failed to establish an CoC connection")
        return False, None, None

    if len(client_ad.droid.bluetoothSocketConnActiveConnections()) > 0:
        server_ad.log.info(
            "CoC client_ad Connection Active, num=%d",
            len(client_ad.droid.bluetoothSocketConnActiveConnections()))
    else:
        server_ad.log.info("Error CoC client_ad Connection Inactive")
        client_ad.log.info("Error CoC client_ad Connection Inactive")

    # Wait for the client to be ready
    client_conn_id = None
    while (client_conn_id == None):
        client_conn_id = client_ad.droid.bluetoothGetLastConnId()
        if (client_conn_id != None):
            break
        time.sleep(1)

    # Wait for the server to be ready
    server_conn_id = None
    while (server_conn_id == None):
        server_conn_id = server_ad.droid.bluetoothGetLastConnId()
        if (server_conn_id != None):
            break
        time.sleep(1)

    client_ad.log.info(
        "orchestrate_coc_connection: client conn id={}, server conn id={}".
        format(client_conn_id, server_conn_id))

    if gatt_disconnection:

        if gatt_connected:
            disconnect_gatt_connection(client_ad, bluetooth_gatt_1,
                                       gatt_callback_1)
            client_ad.droid.gattClientClose(bluetooth_gatt_1)

        return True, client_conn_id, server_conn_id

    else:
        return True, client_conn_id, server_conn_id, bluetooth_gatt_1, gatt_callback_1
Пример #5
0
    def test_gatt_connect_autoconnect(self):
        """Test GATT connection over LE.

        Test re-establishing a gat connection using autoconnect
        set to True in order to test connection whitelist.

        Steps:
        1. Start a generic advertisement.
        2. Start a generic scanner.
        3. Find the advertisement and extract the mac address.
        4. Stop the first scanner.
        5. Create a GATT connection between the scanner and advertiser.
        6. Disconnect the GATT connection.
        7. Create a GATT connection with autoconnect set to True
        8. Disconnect the GATT connection.

        Expected Result:
        Verify that a connection was re-established and then disconnected
        successfully.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, GATT
        Priority: 0
        """
        gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
        gatt_server = self.per_ad.droid.gattServerOpenGattServer(
            gatt_server_cb)
        self.gatt_server_list.append(gatt_server)
        autoconnect = False
        mac_address, adv_callback = (
            get_mac_address_of_generic_advertisement(self.cen_ad, self.per_ad))
        try:
            bluetooth_gatt, gatt_callback = setup_gatt_connection(
                self.cen_ad, mac_address, autoconnect)
            self.bluetooth_gatt_list.append(bluetooth_gatt)
        except GattTestUtilsError as err:
            self.log.error(err)
            return False
        try:
            disconnect_gatt_connection(self.cen_ad, bluetooth_gatt,
                                       gatt_callback)
            if bluetooth_gatt in self.bluetooth_gatt_list:
                self.bluetooth_gatt_list.remove(bluetooth_gatt)
        except GattTestUtilsError as err:
            self.log.error(err)
            return False
        autoconnect = True
        bluetooth_gatt = self.cen_ad.droid.gattClientConnectGatt(
            gatt_callback, mac_address, autoconnect,
            GattTransport.TRANSPORT_AUTO.value)
        self.bluetooth_gatt_list.append(bluetooth_gatt)
        expected_event = GattCbStrings.GATT_CONN_CHANGE.value.format(
            gatt_callback)
        try:
            event = self.cen_ad.ed.pop_event(expected_event,
                                             self.default_timeout)
        except Empty:
            self.log.error(
                GattCbErr.GATT_CONN_CHANGE_ERR.value.format(expected_event))
            test_result = False
        return True
Пример #6
0
    def test_gatt_connect_opportunistic(self):
        """Test opportunistic GATT connection over LE.

        Test establishing a gatt connection between a GATT server and GATT
        client in opportunistic mode.

        Steps:
        1. Start a generic advertisement.
        2. Start a generic scanner.
        3. Find the advertisement and extract the mac address.
        4. Stop the first scanner.
        5. Create GATT connection 1 between the scanner and advertiser normally
        6. Create GATT connection 2 between the scanner and advertiser using
           opportunistic mode
        7. Disconnect GATT connection 1

        Expected Result:
        Verify GATT connection 2 automatically disconnects when GATT connection
        1 disconnect

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, GATT
        Priority: 0
        """
        gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
        gatt_server = self.per_ad.droid.gattServerOpenGattServer(
            gatt_server_cb)
        self.gatt_server_list.append(gatt_server)
        mac_address, adv_callback = (
            get_mac_address_of_generic_advertisement(self.cen_ad, self.per_ad))
        # Make GATT connection 1
        try:
            bluetooth_gatt_1, gatt_callback_1 = setup_gatt_connection(
                self.cen_ad,
                mac_address,
                False,
                transport=gatt_transport['auto'],
                opportunistic=False)
            self.bluetooth_gatt_list.append(bluetooth_gatt_1)
        except GattTestUtilsError as err:
            self.log.error(err)
            return False
        # Make GATT connection 2
        try:
            bluetooth_gatt_2, gatt_callback_2 = setup_gatt_connection(
                self.cen_ad,
                mac_address,
                False,
                transport=gatt_transport['auto'],
                opportunistic=True)
            self.bluetooth_gatt_list.append(bluetooth_gatt_2)
        except GattTestUtilsError as err:
            self.log.error(err)
            return False
        # Disconnect GATT connection 1
        try:
            disconnect_gatt_connection(self.cen_ad, bluetooth_gatt_1,
                                       gatt_callback_1)
            close_gatt_client(self.cen_ad, bluetooth_gatt_1)
            if bluetooth_gatt_1 in self.bluetooth_gatt_list:
                self.bluetooth_gatt_list.remove(bluetooth_gatt_1)
        except GattTestUtilsError as err:
            self.log.error(err)
            return False
        # Confirm that GATT connection 2 also disconnects
        wait_for_gatt_disconnect_event(self.cen_ad, gatt_callback_2)
        close_gatt_client(self.cen_ad, bluetooth_gatt_2)
        if bluetooth_gatt_2 in self.bluetooth_gatt_list:
            self.bluetooth_gatt_list.remove(bluetooth_gatt_2)
        return True