Example #1
0
    def test_btp_GATT_CL_GAW_2(self):
        """
        Verify that a Generic Attribute Profile client can write a long
        Characteristic Value selected by handle.
        """

        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        btp.gattc_disc_chrc_uuid(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                 0x0001, 0xffff, PTS_DB.LONG_CHR_READ_WRITE)

        db = GattDB()
        btp.gattc_disc_chrc_uuid_rsp(self.iut1, db)

        db.print_db()

        chr = db.find_chr_by_uuid(PTS_DB.LONG_CHR_READ_WRITE)
        self.assertIsNotNone(chr)

        new_value = "FF" * 100
        btp.gattc_write_long(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                             chr.value_handle, 0, new_value)

        future_iut2 = btp.gatts_attr_value_changed_ev(self.iut2)

        val = GattValue()
        btp.gattc_write_long_rsp(self.iut1, val)
        self.assertEqual(val.att_rsp, "No error")

        wait_futures([future_iut2], timeout=EV_TIMEOUT)

        hdl, data = future_iut2.result()
        self.assertEqual(data, new_value)

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
    def test_btp_GAP_DISC_GENM_1(self):
        """
        Verify the IUT1 in General Discoverable Mode and the Undirected
        Connectable Mode can be discovered by a device performing the General
        Discovery Procedure.

        The IUT1 is operating in the Peripheral role.
        """

        btp.gap_set_conn(self.iut2)
        btp.gap_set_gendiscov(self.iut2)

        uuid = os.urandom(2)
        btp.gap_adv_ind_on(self.iut2, ad=[(AdType.uuid16_some, uuid)])

        def verify_f(args):
            return find_adv_by_uuid(args, btp.btp2uuid(len(uuid), uuid))

        btp.gap_start_discov(self.iut1)
        future = btp.gap_device_found_ev(self.iut1, verify_f)
        wait_futures([future], timeout=EV_TIMEOUT)
        btp.gap_stop_discov(self.iut1)

        found = future.result()
        self.assertIsNotNone(found)
Example #3
0
def connection_procedure(testcase, central, peripheral):
    btp.gap_set_conn(peripheral)
    btp.gap_set_gendiscov(peripheral)

    uuid = os.urandom(2)
    btp.gap_adv_ind_on(peripheral, ad=[(AdType.uuid16_some, uuid)])

    def verify_f(args):
        return find_adv_by_uuid(args, btp.btp2uuid(len(uuid), uuid))

    btp.gap_start_discov(central)
    future = btp.gap_device_found_ev(central, verify_f)
    wait_futures([future], timeout=EV_TIMEOUT)
    btp.gap_stop_discov(central)

    found = future.result()

    testcase.assertIsNotNone(found)
    peripheral.stack.gap.iut_addr_set(found.addr)

    def verify_central(args):
        return verify_address(args, found.addr)

    future_central = btp.gap_connected_ev(central, verify_central)
    future_peripheral = btp.gap_connected_ev(peripheral)

    btp.gap_conn(central, peripheral.stack.gap.iut_addr_get())

    wait_futures([future_central, future_peripheral], timeout=EV_TIMEOUT)

    testcase.assertTrue(central.stack.gap.is_connected())
    testcase.assertTrue(peripheral.stack.gap.is_connected())

    central_addr, _ = future_peripheral.result()
    central.stack.gap.iut_addr_set(central_addr)
Example #4
0
    def test_btp_GATT_CL_GAW_4(self):
        """
        Verify that a Generic Attribute Profile client can write a long
        characteristic descriptor selected by handle.
        """

        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        btp.gattc_disc_prim_uuid(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                 PTS_DB.SVC)

        db = GattDB()
        btp.gattc_disc_prim_uuid_rsp(self.iut1, db)

        svc = db.find_svc_by_uuid(PTS_DB.SVC)
        self.assertIsNotNone(svc)

        start_hdl, end_hdl = svc.handle, svc.end_hdl

        btp.gattc_disc_all_chrc(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                start_hdl, end_hdl)

        btp.gattc_disc_all_chrc_rsp(self.iut1, db)

        db.print_db()

        chr = db.find_chr_by_uuid(PTS_DB.CHR_READ_WRITE)
        self.assertIsNotNone(chr)

        end_hdl = db.find_characteristic_end(chr.handle)
        self.assertIsNotNone(end_hdl)

        btp.gattc_disc_all_desc(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                chr.value_handle + 1, end_hdl)

        btp.gattc_disc_all_desc_rsp(self.iut1, db)

        db.print_db()

        dsc = db.find_dsc_by_uuid(PTS_DB.LONG_DSC_READ_WRITE)
        self.assertIsNotNone(dsc)

        new_value = "FF" * 100
        btp.gattc_write_long(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                             dsc.handle, 0, new_value)

        future_iut2 = btp.gatts_attr_value_changed_ev(self.iut2)

        val = GattValue()
        btp.gattc_write_long_rsp(self.iut1, val)
        self.assertEqual(val.att_rsp, "No error")

        wait_futures([future_iut2], timeout=EV_TIMEOUT)

        hdl, data = future_iut2.result()
        self.assertEqual(data, new_value)

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
Example #5
0
    def send(self, data):
        if not self.is_ready():
            return False

        future = self._ev_handler.wait_for_event(PROPERTIES_CHANGED,
                                                 self._notification_received)
        self.req_char_iface.WriteValue(data, {})
        wait_futures([future], timeout=3)
        result = future.result()
        response = bytes(result[1]["Value"])
        return response
Example #6
0
    def test_SMP_Client_SC_Passkey_Entry(self, iut, valid):
        btp.gap_set_io_cap(iut, IOCap.keyboard_display)
        btp.gap_conn(iut, self.config.tester_addr)
        btp.gap_wait_for_connection(iut)

        future = btp.gap_passkey_entry_req_ev(iut)
        try:
            wait_futures([future], timeout=EV_TIMEOUT)
            btp.gap_passkey_entry_rsp(iut, self.config.tester_addr,
                                      self.config.tester_passkey)
        except (TimeoutError, BTPErrorInvalidStatus) as e:
            if valid:
                raise e
    def test_btp_GAP_CONN_PAIR_2(self):
        """
        Verify the IUT1 can perform the authenticated pairing procedure
        (Numeric Comparison) as the initiator.

        The IUT1 is operating in the Central role and is the initiator
        performing the pairing procedure; the IUT2
        is operating in the Peripheral role and is the responder.
        """

        btp.gap_set_io_cap(self.iut1, IOCap.display_yesno)
        btp.gap_set_io_cap(self.iut2, IOCap.display_yesno)

        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        btp.gap_pair(self.iut1, self.iut2.stack.gap.iut_addr_get())

        future_master = btp.gap_passkey_confirm_req_ev(self.iut1)
        future_slave = btp.gap_passkey_confirm_req_ev(self.iut2)

        wait_futures([future_master, future_slave], timeout=EV_TIMEOUT)

        results_master = future_master.result()
        results_slave = future_slave.result()

        pk_iut1 = results_master[1]
        self.assertIsNotNone(pk_iut1)
        pk_iut2 = results_slave[1]
        self.assertIsNotNone(pk_iut2)
        self.assertEqual(pk_iut1, pk_iut2)

        btp.gap_passkey_confirm(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                1)

        btp.gap_passkey_confirm(self.iut2, self.iut1.stack.gap.iut_addr_get(),
                                1)

        future_master = btp.gap_sec_level_changed_ev(self.iut1)
        future_slave = btp.gap_sec_level_changed_ev(self.iut2)

        wait_futures([future_master, future_slave], timeout=EV_TIMEOUT)

        _, level = future_master.result()
        self.assertEqual(level, 3)

        _, level = future_slave.result()
        self.assertEqual(level, 3)

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
Example #8
0
def disconnection_procedure(testcase, central, peripheral):
    periph_addr = peripheral.stack.gap.iut_addr_get()

    def verify_central(args):
        return verify_address(args, periph_addr)

    future_central = btp.gap_disconnected_ev(central, verify_central)
    future_peripheral = btp.gap_disconnected_ev(peripheral)

    btp.gap_disconn(central, peripheral.stack.gap.iut_addr_get())

    wait_futures([future_central, future_peripheral], timeout=EV_TIMEOUT)

    testcase.assertFalse(peripheral.stack.gap.is_connected())
    testcase.assertFalse(central.stack.gap.is_connected())
Example #9
0
    def test_Advertising_Data(self, iut, valid):
        def verify_f(args):
            return find_adv_by_addr(args, self.config.tester_addr)

        btp.gap_start_discov(iut)
        future = btp.gap_device_found_ev(iut, verify_f)
        try:
            wait_futures([future], timeout=5)
            btp.gap_stop_discov(iut)
            found = future.result()
            assert found
        except TimeoutError as e:
            btp.gap_stop_discov(iut)
            if valid:
                raise e
Example #10
0
    def test_SMP_Client_SC_Numeric_Comparison(self, iut, valid):
        btp.gap_set_io_cap(iut, IOCap.keyboard_display)
        btp.gap_conn(iut, self.config.tester_addr)
        btp.gap_wait_for_connection(iut)

        future = btp.gap_passkey_confirm_req_ev(iut)
        try:
            wait_futures([future], timeout=EV_TIMEOUT)
            results = future.result()
            pk_iut = results[1]
            assert (pk_iut is not None)
            btp.gap_passkey_confirm(iut, self.config.tester_addr, 1)
        except (TimeoutError, BTPErrorInvalidStatus) as e:
            if valid:
                raise e
    def test_btp_GAP_CONN_DCON_1(self):
        """
        Verify the IUT1 in the Directed Connectable Mode can connect with another
        device performing the General Connection Establishment Procedure.

        The IUT1 is operating in the Peripheral role.
        """

        connection_procedure(self, central=self.iut2, peripheral=self.iut1)

        iut_addr = self.iut1.stack.gap.iut_addr_get()
        iut2_addr = self.iut2.stack.gap.iut_addr_get()

        def verify_iut1(args):
            return verify_address(args, iut2_addr)

        def verify_iut2(args):
            return verify_address(args, iut_addr)

        future_iut1 = btp.gap_sec_level_changed_ev(self.iut1, verify_iut1)
        future_iut2 = btp.gap_sec_level_changed_ev(self.iut2, verify_iut2)

        btp.gap_pair(self.iut1, self.iut2.stack.gap.iut_addr_get())

        wait_futures([future_iut1, future_iut2], timeout=EV_TIMEOUT)

        disconnection_procedure(self, central=self.iut2, peripheral=self.iut1)

        btp.gap_start_direct_adv(self.iut1, self.iut2.stack.gap.iut_addr_get())

        def verify_central(args):
            return verify_address(args, self.iut1.stack.gap.iut_addr_get())

        future_central = btp.gap_connected_ev(self.iut2, verify_central)
        future_peripheral = btp.gap_connected_ev(self.iut1)

        btp.gap_conn(self.iut2, self.iut1.stack.gap.iut_addr_get())

        wait_futures([future_central, future_peripheral], timeout=EV_TIMEOUT)

        self.assertTrue(self.iut2.stack.gap.is_connected())
        self.assertTrue(self.iut1.stack.gap.is_connected())

        disconnection_procedure(self, central=self.iut2, peripheral=self.iut1)
    def test_btp_GAP_CONN_CPUP_2(self):
        """
        Verify the IUT1 can perform the Connection Parameter Update Procedure
        using valid parameters for the peer device; the peer device accepts
        the updated connection parameters.

        The IUT1 is operating in the Central role and is the initiator performing
        the Connection Parameter Update Procedure and the IUT2 is
        operating in the Peripheral role and is the responder.
        """

        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        conn_params = self.iut1.stack.gap.get_conn_params()
        iut_addr = self.iut1.stack.gap.iut_addr_get()
        iut2_addr = self.iut2.stack.gap.iut_addr_get()

        conn_itvl_min, conn_itvl_max, latency, supervision_timeout = (
            conn_params.conn_itvl, conn_params.conn_itvl,
            conn_params.conn_latency + 2, conn_params.supervision_timeout)

        btp.gap_conn_param_update(self.iut1,
                                  self.iut2.stack.gap.iut_addr_get(),
                                  conn_itvl_min, conn_itvl_max, latency,
                                  supervision_timeout)

        def verify_iut1(args):
            return verify_conn_params(args, iut2_addr, conn_itvl_min,
                                      conn_itvl_max, latency,
                                      supervision_timeout)

        def verify_iut2(args):
            return verify_conn_params(args, iut_addr, conn_itvl_min,
                                      conn_itvl_max, latency,
                                      supervision_timeout)

        wait_futures([
            btp.gap_conn_param_update_ev(self.iut1, verify_iut1),
            btp.gap_conn_param_update_ev(self.iut2, verify_iut2)
        ],
                     timeout=EV_TIMEOUT)

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
    def test_btp_GAP_CONN_PAIR_3(self):
        """
        Verify the IUT1 can perform the authenticated pairing procedure
        (Keyboard Input) as the initiator.

        The IUT1 is operating in the Central role and is the initiator
        performing the pairing procedure; the IUT2
        is operating in the Peripheral role and is the responder.
        """

        btp.gap_set_io_cap(self.iut1, IOCap.keyboard_only)
        btp.gap_set_io_cap(self.iut2, IOCap.display_only)

        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        btp.gap_pair(self.iut1, self.iut2.stack.gap.iut_addr_get())

        iut2_addr = self.iut2.stack.gap.iut_addr_get()

        future_slave = btp.gap_passkey_disp_ev(self.iut2)
        future_master = btp.gap_passkey_entry_req_ev(self.iut1)

        wait_futures([future_master, future_slave], timeout=EV_TIMEOUT)
        results_slave = future_slave.result()
        pk_iut2 = results_slave[1]
        self.assertIsNotNone(pk_iut2)

        btp.gap_passkey_entry_rsp(self.iut1, iut2_addr, pk_iut2)

        future_master = btp.gap_sec_level_changed_ev(self.iut1)
        future_slave = btp.gap_sec_level_changed_ev(self.iut2)

        wait_futures([future_master, future_slave], timeout=EV_TIMEOUT)

        _, level = future_master.result()
        self.assertEqual(level, 3)

        _, level = future_slave.result()
        self.assertEqual(level, 3)

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
Example #14
0
    def test_btp_GATT_CL_GAI_1(self):
        """
        Verify that a Generic Attribute Profile client can receive
        a Characteristic Value Notification and report that to the Upper Tester.
        """

        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        db = GattDB()
        btp.gattc_disc_chrc_uuid(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                 0x0001, 0xffff, PTS_DB.CHR_NOTIFY)
        btp.gattc_disc_chrc_uuid_rsp(self.iut1, db)
        db.print_db()

        chr = db.find_chr_by_uuid(PTS_DB.CHR_NOTIFY)
        self.assertIsNotNone(chr)
        end_hdl = db.find_characteristic_end(chr.handle)
        self.assertIsNotNone(end_hdl)

        btp.gattc_disc_all_desc(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                                chr.value_handle + 1, end_hdl)
        btp.gattc_disc_all_desc_rsp(self.iut1, db)
        db.print_db()

        dsc = db.find_dsc_by_uuid(UUID.CCC)
        self.assertIsNotNone(dsc)

        future_iut1 = btp.gattc_notification_ev(self.iut1)

        btp.gattc_cfg_indicate(self.iut1, self.iut2.stack.gap.iut_addr_get(),
                               1, dsc.handle)

        wait_futures([future_iut1], timeout=EV_TIMEOUT)
        result = future_iut1.result()

        self.assertTrue(
            verify_notification_ev(result, self.iut2.stack.gap.iut_addr_get(),
                                   0x02, chr.value_handle))

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
Example #15
0
    def run(self):
        self.device_iface, self.device_props = find_device(self.bus,
                                                           self.dev_addr,
                                                           self.adapter_id)

        if not self.device_iface:
            future = self._ev_handler.wait_for_event(INTERFACES_ADDED,
                                                     self._device_added)
            adapter = find_adapter(self.bus, self.adapter_id)
            adapter.StartDiscovery()
            wait_futures([future], timeout=EV_TIMEOUT)
            adapter.StopDiscovery()
            self.device_iface, self.device_props = find_device(self.bus,
                                                               self.dev_addr,
                                                               self.adapter_id)

        if not self.device_props.get('ServicesResolved', None):
            future = self._ev_handler.wait_for_event(PROPERTIES_CHANGED,
                                                     self._device_found)
            adapter = find_adapter(self.bus, self.adapter_id)
            adapter.StartDiscovery()
            wait_futures([future], timeout=EV_TIMEOUT)
            adapter.StopDiscovery()
            self.device_iface, self.device_props = find_device(self.bus,
                                                               self.dev_addr,
                                                               self.adapter_id)

            future = self._ev_handler.wait_for_event(PROPERTIES_CHANGED,
                                                     self._device_connected)
            self.device_iface.Connect()
            wait_futures([future], timeout=EV_TIMEOUT)

            self.device_iface, self.device_props = find_device(self.bus,
                                                               self.dev_addr,
                                                               self.adapter_id)

        print('Connected')

        self.req_char_iface, self.req_char_props = \
            find_characteristic(self.bus,
                                self.device_iface.object_path,
                                COAP_REQUEST_CHAR_UUID)

        if not self.req_char_iface:
            print("Couldn't find CoAP Request characteristic")
            return

        self.rsp_char_iface, self.rsp_char_props = \
            find_characteristic(self.bus,
                                self.device_iface.object_path,
                                COAP_RESPONSE_CHAR_UUID)

        if not self.rsp_char_iface:
            print("Couldn't find CoAP Response characteristic")
            return

        self.rsp_char_iface.StartNotify()

        print('Device ready')
    def test_btp_GAP_CONN_PAIR_1(self):
        """
        Verify the IUT1 can perform the unauthenticated pairing procedure
        (Just Works) as the initiator.

        The IUT1 is operating in the Central role and is the initiator
        performing the pairing procedure; the IUT2
        is operating in the Peripheral role and is the responder.
        """

        btp.gap_set_io_cap(self.iut2, IOCap.no_input_output)
        connection_procedure(self, central=self.iut1, peripheral=self.iut2)

        iut_addr = self.iut1.stack.gap.iut_addr_get()
        iut2_addr = self.iut2.stack.gap.iut_addr_get()

        def verify_iut1(args):
            return verify_address(args, iut2_addr)

        def verify_iut2(args):
            return verify_address(args, iut_addr)

        future_iut1 = btp.gap_sec_level_changed_ev(self.iut1)
        future_iut2 = btp.gap_sec_level_changed_ev(self.iut2)

        btp.gap_pair(self.iut1, self.iut2.stack.gap.iut_addr_get())

        wait_futures([future_iut1, future_iut2], timeout=EV_TIMEOUT)

        _, level = future_iut1.result()
        self.assertEqual(level, 1)

        _, level = future_iut2.result()
        self.assertEqual(level, 1)

        disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)