From 07777023f3c54ae259308906b3f54d182c2ffd1d Mon Sep 17 00:00:00 2001 From: Fei Zheng Date: Wed, 25 Dec 2019 10:45:51 +0800 Subject: [PATCH] DIP: Implement API to get device identification information Bug: 141666056 Test: atest net_test_bta Sponsor: alainv@ Tag: #feature Change-Id: I236e6f79a6d8bde640e47f9e30812c19bbcc4a40 --- bta/Android.bp | 1 + bta/sdp/bta_sdp_act.cc | 58 +++++++++++++++++++++++ bta/test/bta_dip_test.cc | 106 +++++++++++++++++++++++++++++++++++++++++++ btif/include/btif_sock_sdp.h | 1 + include/hardware/bt_sdp.h | 14 +++++- 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 bta/test/bta_dip_test.cc diff --git a/bta/Android.bp b/bta/Android.bp index 32d9e77b0..632705af6 100644 --- a/bta/Android.bp +++ b/bta/Android.bp @@ -121,6 +121,7 @@ cc_test { srcs: [ "test/bta_hf_client_test.cc", "test/bta_dm_cust_uuid_test.cc", + "test/bta_dip_test.cc", "test/gatt/database_builder_test.cc", "test/gatt/database_builder_sample_device_test.cc", "test/gatt/database_test.cc", diff --git a/bta/sdp/bta_sdp_act.cc b/bta/sdp/bta_sdp_act.cc index f4af4befb..3561d6b39 100644 --- a/bta/sdp/bta_sdp_act.cc +++ b/bta/sdp/bta_sdp_act.cc @@ -40,6 +40,7 @@ static const Uuid UUID_PBAP_PSE = Uuid::From16Bit(0x112F); static const Uuid UUID_MAP_MAS = Uuid::From16Bit(0x1132); static const Uuid UUID_MAP_MNS = Uuid::From16Bit(0x1133); static const Uuid UUID_SAP = Uuid::From16Bit(0x112D); +static const Uuid UUID_DIP = Uuid::From16Bit(0x1200); static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) { @@ -294,6 +295,60 @@ static void bta_create_sap_sdp_record(bluetooth_sdp_record* record, } } +static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, + tSDP_DISC_REC* p_rec) { + tSDP_DISC_ATTR* p_attr; + + APPL_TRACE_DEBUG("%s()", __func__); + + /* hdr is redundancy in dip */ + record->dip.hdr.type = SDP_TYPE_DIP; + record->dip.hdr.service_name_length = 0; + record->dip.hdr.service_name = nullptr; + record->dip.hdr.rfcomm_channel_number = 0; + record->dip.hdr.l2cap_psm = -1; + record->dip.hdr.profile_version = 0; + + p_attr = + SDP_FindAttributeInRec(p_rec, ATTR_ID_SPECIFICATION_ID); + if (p_attr != nullptr) + record->dip.spec_id = p_attr->attr_value.v.u16; + else + APPL_TRACE_ERROR("%s() ATTR_ID_SPECIFICATION_ID not found", __func__); + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID); + if (p_attr != nullptr) + record->dip.vendor = p_attr->attr_value.v.u16; + else + APPL_TRACE_ERROR("%s() ATTR_ID_VENDOR_ID not found", __func__); + + p_attr = + SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID_SOURCE); + if (p_attr != nullptr) + record->dip.vendor_id_source = p_attr->attr_value.v.u16; + else + APPL_TRACE_ERROR("%s() ATTR_ID_VENDOR_ID_SOURCE not found", __func__); + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_ID); + if (p_attr != nullptr) + record->dip.product = p_attr->attr_value.v.u16; + else + APPL_TRACE_ERROR("%s() ATTR_ID_PRODUCT_ID not found", __func__); + + p_attr = + SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_VERSION); + if (p_attr != nullptr) + record->dip.version = p_attr->attr_value.v.u16; + else + APPL_TRACE_ERROR("%s() ATTR_ID_PRODUCT_VERSION not found", __func__); + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRIMARY_RECORD); + if (p_attr != nullptr) + record->dip.primary_record = !(!p_attr->attr_value.v.u8); + else + APPL_TRACE_ERROR("%s() ATTR_ID_PRIMARY_RECORD not found", __func__); +} + static void bta_create_raw_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) { tSDP_DISC_ATTR* p_attr; @@ -366,6 +421,9 @@ static void bta_sdp_search_cback(uint16_t result, void* user_data) { } else if (uuid == UUID_SAP) { APPL_TRACE_DEBUG("%s() - found SAP uuid", __func__); bta_create_sap_sdp_record(&evt_data.records[count], p_rec); + } else if (uuid == UUID_DIP) { + APPL_TRACE_DEBUG("%s() - found DIP uuid", __func__); + bta_create_dip_sdp_record(&evt_data.records[count], p_rec); } else { /* we do not have specific structure for this */ APPL_TRACE_DEBUG("%s() - profile not identified. using raw data", diff --git a/bta/test/bta_dip_test.cc b/bta/test/bta_dip_test.cc new file mode 100644 index 000000000..6e8be140f --- /dev/null +++ b/bta/test/bta_dip_test.cc @@ -0,0 +1,106 @@ +#include +#include "bta/sdp/bta_sdp_act.cc" +#include "stack/sdp/sdp_api.cc" + +namespace { +const RawAddress bdaddr({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); +} // namespace + +extern tBTA_SDP_CB bta_sdp_cb; +extern tBTA_SDP_CFG* p_bta_sdp_cfg; + +static tSDP_DISC_ATTR g_attr_service_class_id_list; +static tSDP_DISC_ATTR g_sub_attr; +static tSDP_DISC_ATTR g_attr_spec_id; +static tSDP_DISC_ATTR g_attr_vendor_id; +static tSDP_DISC_ATTR g_attr_vendor_id_src; +static tSDP_DISC_ATTR g_attr_vendor_product_id; +static tSDP_DISC_ATTR g_attr_vendor_product_version; +static tSDP_DISC_ATTR g_attr_vendor_product_primary_record; +static tSDP_DISC_REC g_rec; + +bool sdpu_compare_uuid_with_attr(const Uuid& uuid, tSDP_DISC_ATTR* p_attr) { + return true; +} + +static void sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, + void* user_data) { + return; +} + +class BtaDipTest : public ::testing::Test { + protected: + void SetUp() override { + g_attr_service_class_id_list.p_next_attr = &g_attr_spec_id; + g_attr_service_class_id_list.attr_id = ATTR_ID_SERVICE_CLASS_ID_LIST; + g_attr_service_class_id_list.attr_len_type = (DATA_ELE_SEQ_DESC_TYPE<<12)|2; + g_attr_service_class_id_list.attr_value.v.p_sub_attr = &g_sub_attr; + g_sub_attr.attr_len_type = (UUID_DESC_TYPE<<12)|2; + g_sub_attr.attr_value.v.u16 = 0x1200; + + g_attr_spec_id.p_next_attr = &g_attr_vendor_id; + g_attr_spec_id.attr_id = ATTR_ID_SPECIFICATION_ID; + g_attr_spec_id.attr_len_type = (UINT_DESC_TYPE<<12)|2; + g_attr_spec_id.attr_value.v.u16 = 0x0103; + + g_attr_vendor_id.p_next_attr = &g_attr_vendor_id_src; + g_attr_vendor_id.attr_id = ATTR_ID_VENDOR_ID; + g_attr_vendor_id.attr_len_type = (UINT_DESC_TYPE<<12)|2; + g_attr_vendor_id.attr_value.v.u16 = 0x18d1; + + // Allocation should succeed + g_attr_vendor_id_src.p_next_attr = &g_attr_vendor_product_id; + g_attr_vendor_id_src.attr_id = ATTR_ID_VENDOR_ID_SOURCE; + g_attr_vendor_id_src.attr_len_type = (UINT_DESC_TYPE<<12)|2; + g_attr_vendor_id_src.attr_value.v.u16 = 1; + + g_attr_vendor_product_id.p_next_attr = &g_attr_vendor_product_version; + g_attr_vendor_product_id.attr_id = ATTR_ID_PRODUCT_ID; + g_attr_vendor_product_id.attr_len_type = (UINT_DESC_TYPE<<12)|2; + g_attr_vendor_product_id.attr_value.v.u16 = 0x1234; + + g_attr_vendor_product_version.p_next_attr = &g_attr_vendor_product_primary_record; + g_attr_vendor_product_version.attr_id = ATTR_ID_PRODUCT_VERSION; + g_attr_vendor_product_version.attr_len_type = (UINT_DESC_TYPE<<12)|2; + g_attr_vendor_product_version.attr_value.v.u16 = 0x0100; + + g_attr_vendor_product_primary_record.p_next_attr = &g_attr_vendor_product_primary_record; + g_attr_vendor_product_primary_record.attr_id = ATTR_ID_PRIMARY_RECORD; + g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE<<12); + g_attr_vendor_product_primary_record.attr_value.v.u8 = 1; + + g_rec.p_first_attr = &g_attr_service_class_id_list; + g_rec.p_next_rec = nullptr; + g_rec.remote_bd_addr = bdaddr; + g_rec.time_read = 0; + + bta_sdp_cb.p_dm_cback = sdp_dm_cback; + bta_sdp_cb.remote_addr = bdaddr; + + p_bta_sdp_cfg->p_sdp_db->p_first_rec = &g_rec; + } + + void TearDown() override {} +}; + +// Test that bta_create_dip_sdp_record can parse sdp record to bluetooth_sdp_record correctly +TEST_F(BtaDipTest, test_bta_create_dip_sdp_record) { + bluetooth_sdp_record record; + + bta_create_dip_sdp_record(&record, &g_rec); + + ASSERT_EQ(record.dip.spec_id, 0x0103); + ASSERT_EQ(record.dip.vendor, 0x18d1); + ASSERT_EQ(record.dip.vendor_id_source, 1); + ASSERT_EQ(record.dip.product, 0x1234); + ASSERT_EQ(record.dip.version, 0x0100); + ASSERT_EQ(record.dip.primary_record, true); +} + +TEST_F(BtaDipTest, test_bta_sdp_search_cback) { + Uuid* userdata = (Uuid*)malloc(sizeof(Uuid)); + + memcpy(userdata, &UUID_DIP, sizeof(UUID_DIP)); + bta_sdp_search_cback(SDP_SUCCESS, userdata); +} + diff --git a/btif/include/btif_sock_sdp.h b/btif/include/btif_sock_sdp.h index 5421cd161..42a4676f1 100644 --- a/btif/include/btif_sock_sdp.h +++ b/btif/include/btif_sock_sdp.h @@ -30,6 +30,7 @@ static const bluetooth::Uuid UUID_PBAP_PSE = bluetooth::Uuid::From16Bit(0x112F); static const bluetooth::Uuid UUID_MAP_MAS = bluetooth::Uuid::From16Bit(0x1132); static const bluetooth::Uuid UUID_SAP = bluetooth::Uuid::From16Bit(0x112D); static const bluetooth::Uuid UUID_SPP = bluetooth::Uuid::From16Bit(0x1101); +static const bluetooth::Uuid UUID_DIP = bluetooth::Uuid::From16Bit(0x1200); int add_rfc_sdp_rec(const char* name, bluetooth::Uuid uuid, int scn); void del_rfc_sdp_rec(int handle); diff --git a/include/hardware/bt_sdp.h b/include/hardware/bt_sdp.h index 024ee40a1..93745bc2a 100644 --- a/include/hardware/bt_sdp.h +++ b/include/hardware/bt_sdp.h @@ -32,7 +32,8 @@ typedef enum { SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client SDP_TYPE_OPP_SERVER, // Object Push Profile - SDP_TYPE_SAP_SERVER // SIM Access Profile + SDP_TYPE_SAP_SERVER, // SIM Access Profile + SDP_TYPE_DIP // Device Identification Profile } bluetooth_sdp_types; typedef struct _bluetooth_sdp_hdr { @@ -97,6 +98,16 @@ typedef struct _bluetooth_sdp_sap_record { bluetooth_sdp_hdr_overlay hdr; } bluetooth_sdp_sap_record; +typedef struct _bluetooth_sdp_dip_record { + bluetooth_sdp_hdr_overlay hdr; + uint16_t spec_id; + uint16_t vendor; + uint16_t vendor_id_source; + uint16_t product; + uint16_t version; + bool primary_record; +} bluetooth_sdp_dip_record; + typedef union { bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_mas_record mas; @@ -105,6 +116,7 @@ typedef union { bluetooth_sdp_pce_record pce; bluetooth_sdp_ops_record ops; bluetooth_sdp_sap_record sap; + bluetooth_sdp_dip_record dip; } bluetooth_sdp_record; /** Callback for SDP search */ -- 2.11.0