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_GATT_CL_GAR_2(self): """ Verify that a Generic Attribute Profile client can read a Characteristic Value by selected handle. The Characteristic Value length is unknown to the client and might be long. """ 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) btp.gattc_read_long(self.iut1, self.iut2.stack.gap.iut_addr_get(), chr.value_handle, 0) val = GattValue() btp.gattc_read_long_rsp(self.iut1, val) self.assertEqual(val.att_rsp, "No error") # self.assertEqual(val.value, value) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
def test_btp_GATT_CL_GAR_1(self): """ Verify that a Generic Attribute Profile client can read a 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.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.CHR_READ_WRITE) self.assertIsNotNone(chr) btp.gattc_read(self.iut1, self.iut2.stack.gap.iut_addr_get(), chr.value_handle) val = GattValue() btp.gattc_read_rsp(self.iut1, val) self.assertEqual(val.att_rsp, "No error") disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
def test_btp_GATT_CL_GAD_3(self): """ Verify that a Generic Attribute Profile client can find include service declarations within a specified service definition on a server. """ connection_procedure(self, central=self.iut1, peripheral=self.iut2) btp.gattc_disc_prim_svcs(self.iut1, self.iut2.stack.gap.iut_addr_get()) db = GattDB() btp.gattc_disc_prim_svcs_rsp(self.iut1, db) for svc in db.get_services(): start_hdl, end_hdl = svc.handle, svc.end_hdl btp.gattc_find_included(self.iut1, self.iut2.stack.gap.iut_addr_get(), start_hdl, end_hdl) btp.gattc_find_included_rsp(self.iut1, db) db.print_db() self.assertIsNotNone(db.find_inc_svc_by_uuid(PTS_DB.INC_SVC)) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
def test_btp_GATT_CL_GAD_4(self): """ Verify that a Generic Attribute Profile client can discover characteristic declarations within a specified service definition. """ 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) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
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)
def test_btp_GAP_CONN_GCEP_1(self): """ Verify the IUT1 can perform the General Connection Establishment Procedure to connect to another device in the Undirected Connectable Mode. The IUT1 is operating in the Central role. """ connection_procedure(self, central=self.iut1, peripheral=self.iut2) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
def test_btp_GATT_CL_GAR_4(self): """ Verify that a Generic Attribute Profile client can read a characteristic descriptor by selected handle. The Characteristic Descriptor length is unknown to the client and might be long. """ 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) btp.gattc_read_long(self.iut1, self.iut2.stack.gap.iut_addr_get(), dsc.handle, 0) val = GattValue() btp.gattc_read_long_rsp(self.iut1, val) self.assertEqual(val.att_rsp, "No error") disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
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)
def test_btp_GATT_CL_GAD_1(self): """ Verify that a Generic Attribute Profile client discovers Primary Services in a GATT server. """ connection_procedure(self, central=self.iut1, peripheral=self.iut2) btp.gattc_disc_prim_svcs(self.iut1, self.iut2.stack.gap.iut_addr_get()) db = GattDB() btp.gattc_disc_prim_svcs_rsp(self.iut1, db) self.assertIsNotNone(db.find_svc_by_uuid(PTS_DB.SVC)) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
def test_btp_GATT_CL_GAD_2(self): """ Verify that a Generic Attribute Profile client can discover Primary Services selected by service UUID, using 16-bit and 128-bit UUIDs. """ 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) self.assertIsNotNone(db.find_svc_by_uuid(PTS_DB.SVC)) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
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_GATT_CL_GAD_6(self): """ Verify that a Generic Attribute Profile client can find all Descriptors of a specified Characteristic. """ 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.DSC_READ_WRITE) self.assertIsNotNone(dsc) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
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)
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)
def test_btp_GATT_CL_GAD_5(self): """ Verify that a Generic Attribute Profile client can discover characteristics of a specified service, using 16-bit and 128-bit characteristic UUIDs. """ 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.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.CHR_READ_WRITE) self.assertIsNotNone(chr) disconnection_procedure(self, central=self.iut1, peripheral=self.iut2)
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)