OSDN Git Service

DIP: Implement API to get device identification information
authorFei Zheng <quic_zfei@quicinc.com>
Wed, 25 Dec 2019 02:45:51 +0000 (10:45 +0800)
committerMyles Watson <mylesgw@google.com>
Thu, 17 Dec 2020 22:23:14 +0000 (22:23 +0000)
Bug: 141666056
Test: atest net_test_bta
Sponsor: alainv@
Tag: #feature

Change-Id: I236e6f79a6d8bde640e47f9e30812c19bbcc4a40

bta/Android.bp
bta/sdp/bta_sdp_act.cc
bta/test/bta_dip_test.cc [new file with mode: 0644]
btif/include/btif_sock_sdp.h
include/hardware/bt_sdp.h

index 32d9e77..632705a 100644 (file)
@@ -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",
index f4af4be..3561d6b 100644 (file)
@@ -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 (file)
index 0000000..6e8be14
--- /dev/null
@@ -0,0 +1,106 @@
+#include <gtest/gtest.h>
+#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);
+}
+
index 5421cd1..42a4676 100644 (file)
@@ -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);
index 024ee40..93745bc 100644 (file)
@@ -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 */