summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKausik Sinnaswamy <kausik@broadcom.com>2012-04-24 22:42:52 +0530
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:18 -0700
commit4ccd6261b39fef1854761442b10deac3490be623 (patch)
tree874cbd1400d6691939e8654d08dbaa72e2e435fe
parentc6be83856892327f88002191b0c067e1e26d0d9e (diff)
downloadexternal_bluetooth_bluedroid-4ccd6261b39fef1854761442b10deac3490be623.zip
external_bluetooth_bluedroid-4ccd6261b39fef1854761442b10deac3490be623.tar.gz
external_bluetooth_bluedroid-4ccd6261b39fef1854761442b10deac3490be623.tar.bz2
Support added to report custom 128-bit UUIDs as part of the BT_PROPERTY_UUIDS of the remote device
Change-Id: I1facd9238cf847915df4c01b33c77b2fdaa168cb
-rw-r--r--bta/dm/bta_dm_act.c51
-rw-r--r--bta/include/bta_api.h6
-rwxr-xr-xbtif/src/btif_dm.c56
-rw-r--r--stack/include/sdp_api.h29
-rw-r--r--stack/sdp/sdp_api.c122
-rw-r--r--stack/sdp/sdp_utils.c22
-rw-r--r--stack/sdp/sdpint.h2
7 files changed, 267 insertions, 21 deletions
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index f43a5c7..347a3f7 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -88,12 +88,14 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
#endif
#endif
+extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128);
+
const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] =
{
UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */
UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */
- UUID_SERVCLASS_FAX, /* BTA_FAX_SERVICE_ID */
+ UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */
UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */
UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
@@ -136,7 +138,7 @@ const UINT32 bta_service_id_to_btm_srv_id_lkup_tbl [BTA_MAX_SERVICE_ID] =
0, /* Reserved */
BTM_SEC_SERVICE_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
BTM_SEC_SERVICE_DUN, /* BTA_DUN_SERVICE_ID */
- BTM_SEC_SERVICE_FAX, /* BTA_FAX_SERVICE_ID */
+ BTM_SEC_SERVICE_AVDTP, /* BTA_AUDIO_SOURCE_SERVICE_ID */
BTM_SEC_SERVICE_LAN_ACCESS, /* BTA_LAP_SERVICE_ID */
BTM_SEC_SERVICE_HEADSET_AG, /* BTA_HSP_SERVICE_ID */
BTM_SEC_SERVICE_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
@@ -1458,6 +1460,9 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
tBT_UUID service_uuid;
#endif
+ UINT32 num_uuids = 0;
+ UINT8 uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services
+
if((p_data->sdp_event.sdp_result == SDP_SUCCESS)
|| (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH)
|| (p_data->sdp_event.sdp_result == SDP_DB_FULL))
@@ -1480,10 +1485,9 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
}
else
{
- service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
+ service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
}
-
#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
/* finished with BR/EDR services, now we check the result for GATT based service UUID */
if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID)
@@ -1547,8 +1551,13 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
if (service_found)
{
+ UINT16 tmp_svc = 0xFFFF;
bta_dm_search_cb.services_found |=
(tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index-1));
+ tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
+ /* Add to the list of UUIDs */
+ sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
+ num_uuids++;
}
}
}
@@ -1576,6 +1585,25 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
// bta_dm_search_cb.p_sdp_db = NULL;
APPL_TRACE_DEBUG1("bta_dm_sdp_result services_found = %04x", bta_dm_search_cb.services_found);
+ /* Collect the 128-bit services here and put them into the list */
+ if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK)
+ {
+ p_sdp_rec = NULL;
+ do
+ {
+ tBT_UUID temp_uuid;
+ /* find a service record, report it */
+ p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
+ if (p_sdp_rec)
+ {
+ if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid))
+ {
+ memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
+ num_uuids++;
+ }
+ }
+ } while (p_sdp_rec);
+ }
/* if there are more services to search for */
if(bta_dm_search_cb.services_to_search)
{
@@ -1597,7 +1625,18 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
p_msg->disc_result.result.disc_res.p_raw_data = NULL;
p_msg->disc_result.result.disc_res.raw_data_size = 0;
-
+ p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
+ p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
+ if (num_uuids > 0) {
+ p_msg->disc_result.result.disc_res.p_uuid_list = (UINT8*)GKI_getbuf(num_uuids*MAX_UUID_SIZE);
+ if (p_msg->disc_result.result.disc_res.p_uuid_list) {
+ memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list,
+ num_uuids*MAX_UUID_SIZE);
+ } else {
+ p_msg->disc_result.result.disc_res.num_uuids = 0;
+ APPL_TRACE_ERROR1("%s: Unable to allocate memory for uuid_list", __FUNCTION__);
+ }
+ }
//copy the raw_data to the discovery result structure
//
APPL_TRACE_DEBUG2("bta_dm_sdp_result (raw_data used = 0x%x raw_data_ptr = 0x%x)\r\n",bta_dm_search_cb.p_sdp_db->raw_used, bta_dm_search_cb.p_sdp_db->raw_data);
@@ -1635,7 +1674,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
{
p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
-
+
APPL_TRACE_EVENT1(" Piggy back the SCN over result field SCN=%d", bta_dm_search_cb.peer_scn);
}
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 57baa4d..ebc4f14 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -47,7 +47,7 @@ typedef UINT8 tBTA_STATUS;
#define BTA_RES_SERVICE_ID 0 /* Reserved */
#define BTA_SPP_SERVICE_ID 1 /* Serial port profile. */
#define BTA_DUN_SERVICE_ID 2 /* Dial-up networking profile. */
-#define BTA_FAX_SERVICE_ID 3 /* Fax profile. */
+#define BTA_A2DP_SOURCE_SERVICE_ID 3 /* A2DP Source profile. */
#define BTA_LAP_SERVICE_ID 4 /* LAN access profile. */
#define BTA_HSP_SERVICE_ID 5 /* Headset profile. */
#define BTA_HFP_SERVICE_ID 6 /* Hands-free profile. */
@@ -62,7 +62,7 @@ typedef UINT8 tBTA_STATUS;
#define BTA_NAP_SERVICE_ID 15 /* PAN Network access point */
#define BTA_GN_SERVICE_ID 16 /* PAN Group Ad-hoc networks */
#define BTA_SAP_SERVICE_ID 17 /* SIM Access profile */
-#define BTA_A2DP_SERVICE_ID 18 /* Advanced audio distribution */
+#define BTA_A2DP_SERVICE_ID 18 /* A2DP Sink */
#define BTA_AVRCP_SERVICE_ID 19 /* A/V remote control */
#define BTA_HID_SERVICE_ID 20 /* HID */
#define BTA_VDP_SERVICE_ID 21 /* Video distribution */
@@ -751,6 +751,8 @@ typedef struct
UINT8 * p_raw_data; /* Raw data for discovery DB */
UINT32 raw_data_size; /* size of raw data */
tBT_DEVICE_TYPE device_type; /* device type in case it is BLE device */
+ UINT32 num_uuids;
+ UINT8 *p_uuid_list;
// btla-specific --
tBTA_STATUS result;
} tBTA_DM_DISC_RES;
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index b74b734..55300d5 100755
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -456,6 +456,25 @@ static void search_devices_copy_cb(UINT16 event, char *p_dest, char *p_src)
}
}
+static void search_services_copy_cb(UINT16 event, char *p_dest, char *p_src)
+{
+ tBTA_DM_SEARCH *p_dest_data = (tBTA_DM_SEARCH *) p_dest;
+ tBTA_DM_SEARCH *p_src_data = (tBTA_DM_SEARCH *) p_src;
+
+ if (!p_src)
+ return;
+ memcpy(p_dest_data, p_src_data, sizeof(tBTA_DM_SEARCH));
+ switch (event)
+ {
+ case BTA_DM_DISC_RES_EVT:
+ {
+ if (p_src_data->disc_res.num_uuids > 0)
+ p_dest_data->disc_res.p_uuid_list = (UINT8*)(p_dest + sizeof(tBTA_DM_SEARCH));
+ memcpy(p_dest_data->disc_res.p_uuid_list, p_src_data->disc_res.p_uuid_list,
+ p_src_data->disc_res.num_uuids*MAX_UUID_SIZE);
+ } break;
+ }
+}
/******************************************************************************
**
** BTIF DM callback events
@@ -824,18 +843,17 @@ static void btif_dm_search_services_evt(UINT16 event, char *p_param)
BTIF_TRACE_DEBUG3("%s:(result=0x%x, services 0x%x)", __FUNCTION__,
p_data->disc_res.result, p_data->disc_res.services);
prop.type = BT_PROPERTY_UUIDS;
- prop.val = (void*)uuid_arr;
prop.len = 0;
- for (i=0; i < BTA_MAX_SERVICE_ID; i++)
+ if (p_data->disc_res.num_uuids > 0)
{
- if(p_data->disc_res.services
- &(tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i)))
- {
- memset(&uuid_arr[j], 0, sizeof(bt_uuid_t));
- uuid16_to_uuid128(bta_service_id_to_uuid_lkup_tbl[i], &uuid_arr[j]);
- prop.len += sizeof(bt_uuid_t);
- j++;
- }
+ prop.val = p_data->disc_res.p_uuid_list;
+ prop.len = p_data->disc_res.num_uuids * MAX_UUID_SIZE;
+ for (i=0; i < p_data->disc_res.num_uuids; i++)
+ {
+ char temp[256];
+ uuid_to_string((bt_uuid_t*)(p_data->disc_res.p_uuid_list + (i*MAX_UUID_SIZE)), temp);
+ BTIF_TRACE_ERROR2("Index: %d uuid:%s", i, temp);
+ }
}
/* Also write this to the NVRAM */
ret = btif_storage_set_remote_device_property(&bd_addr, &prop);
@@ -1207,8 +1225,22 @@ static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_d
*******************************************************************************/
static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
- /* TODO: The only member that needs a deep copy is the p_raw_data. But not sure yet if this is needed. */
- btif_transfer_context(btif_dm_search_services_evt, event, (char*)p_data, sizeof(tBTA_DM_SEARCH), NULL);
+ UINT16 param_len = 0;
+ if (p_data)
+ param_len += sizeof(tBTA_DM_SEARCH);
+ switch (event)
+ {
+ case BTA_DM_DISC_RES_EVT:
+ {
+ if (p_data->disc_res.num_uuids > 0) {
+ param_len += (p_data->disc_res.num_uuids * MAX_UUID_SIZE);
+ }
+ } break;
+ }
+ /* TODO: The only other member that needs a deep copy is the p_raw_data. But not sure
+ * if raw_data is needed. */
+ btif_transfer_context(btif_dm_search_services_evt, event, (char*)p_data, param_len,
+ (param_len > sizeof(tBTA_DM_SEARCH)) ? search_services_copy_cb : NULL);
}
/*******************************************************************************
diff --git a/stack/include/sdp_api.h b/stack/include/sdp_api.h
index e4774c3..121afd4 100644
--- a/stack/include/sdp_api.h
+++ b/stack/include/sdp_api.h
@@ -330,6 +330,35 @@ SDP_API extern tSDP_DISC_REC *SDP_FindServiceUUIDInDb (tSDP_DISCOVERY_DB *p_db,
tBT_UUID *p_uuid,
tSDP_DISC_REC *p_start_rec);
+/*******************************************************************************
+**
+** Function SDP_FindServiceUUIDInRec_128bit
+**
+** Description This function is called to read the 128-bit service UUID within a record
+** if there is any.
+**
+** Parameters: p_rec - pointer to a SDP record.
+** p_uuid - output parameter to save the UUID found.
+**
+** Returns TRUE if found, otherwise FALSE.
+**
+*******************************************************************************/
+SDP_API extern BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID * p_uuid);
+
+/*******************************************************************************
+**
+** Function SDP_FindServiceInDb_128bit
+**
+** Description This function queries an SDP database for a specific service.
+** If the p_start_rec pointer is NULL, it looks from the beginning
+** of the database, else it continues from the next record after
+** p_start_rec.
+**
+** Returns Pointer to record containing service class, or NULL
+**
+*******************************************************************************/
+SDP_API extern tSDP_DISC_REC *SDP_FindServiceInDb_128bit(tSDP_DISCOVERY_DB *p_db,
+ tSDP_DISC_REC *p_start_rec);
/*******************************************************************************
**
diff --git a/stack/sdp/sdp_api.c b/stack/sdp/sdp_api.c
index ef13f15..fc2324a 100644
--- a/stack/sdp/sdp_api.c
+++ b/stack/sdp/sdp_api.c
@@ -392,6 +392,63 @@ BOOLEAN SDP_FindServiceUUIDInRec(tSDP_DISC_REC *p_rec, tBT_UUID * p_uuid)
/*******************************************************************************
**
+** Function SDP_FindServiceUUIDInRec_128bit
+**
+** Description This function is called to read the 128-bit service UUID within a record
+** if there is any.
+**
+** Parameters: p_rec - pointer to a SDP record.
+** p_uuid - output parameter to save the UUID found.
+**
+** Returns TRUE if found, otherwise FALSE.
+**
+*******************************************************************************/
+BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID * p_uuid)
+{
+#if SDP_CLIENT_ENABLED == TRUE
+ tSDP_DISC_ATTR *p_attr, *p_sattr, *p_extra_sattr;
+
+ p_attr = p_rec->p_first_attr;
+
+ while (p_attr)
+ {
+ if ((p_attr->attr_id == ATTR_ID_SERVICE_CLASS_ID_LIST)
+ && (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE))
+ {
+ for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr; p_sattr = p_sattr->p_next_attr)
+ {
+ if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE)
+ {
+ /* only support 128 bits UUID for now */
+ if (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 16)
+ {
+ p_uuid->len = 16;
+ memcpy(p_uuid->uu.uuid128, p_sattr->attr_value.v.array, MAX_UUID_SIZE);
+ }
+ return (TRUE);
+ }
+ }
+ break;
+ }
+ else if (p_attr->attr_id == ATTR_ID_SERVICE_ID)
+ {
+ if ((SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UUID_DESC_TYPE)
+ /* only support 128 bits UUID for now */
+ && (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == 16))
+ {
+ p_uuid->len = 16;
+ memcpy(p_uuid->uu.uuid128, p_sattr->attr_value.v.array, MAX_UUID_SIZE);
+ return (TRUE);
+ }
+ }
+ p_attr = p_attr->p_next_attr;
+ }
+ return FALSE;
+#endif
+}
+
+/*******************************************************************************
+**
** Function SDP_FindServiceInDb
**
** Description This function queries an SDP database for a specific service.
@@ -479,6 +536,71 @@ tSDP_DISC_REC *SDP_FindServiceInDb (tSDP_DISCOVERY_DB *p_db, UINT16 service_uuid
return (NULL);
}
+/*******************************************************************************
+**
+** Function SDP_FindServiceInDb_128bit
+**
+** Description This function queries an SDP database for a specific service.
+** If the p_start_rec pointer is NULL, it looks from the beginning
+** of the database, else it continues from the next record after
+** p_start_rec.
+**
+** This function is kept separate from SDP_FindServiceInDb since
+** that API is expected to return only 16-bit UUIDs
+**
+** Returns Pointer to record containing service class, or NULL
+**
+*******************************************************************************/
+tSDP_DISC_REC *SDP_FindServiceInDb_128bit(tSDP_DISCOVERY_DB *p_db, tSDP_DISC_REC *p_start_rec)
+{
+#if SDP_CLIENT_ENABLED == TRUE
+ tSDP_DISC_REC *p_rec;
+ tSDP_DISC_ATTR *p_attr, *p_sattr, *p_extra_sattr;
+
+ /* Must have a valid database */
+ if (p_db == NULL)
+ return (NULL);
+
+ if (!p_start_rec)
+ p_rec = p_db->p_first_rec;
+ else
+ p_rec = p_start_rec->p_next_rec;
+
+ while (p_rec)
+ {
+ p_attr = p_rec->p_first_attr;
+ while (p_attr)
+ {
+ if ((p_attr->attr_id == ATTR_ID_SERVICE_CLASS_ID_LIST)
+ && (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE))
+ {
+ for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr; p_sattr = p_sattr->p_next_attr)
+ {
+ if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE)
+ && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 16))
+ {
+ return (p_rec);
+ }
+ }
+ break;
+ }
+ else if (p_attr->attr_id == ATTR_ID_SERVICE_ID)
+ {
+ if ((SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UUID_DESC_TYPE)
+ && (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == 16))
+ return (p_rec);
+ }
+
+ p_attr = p_attr->p_next_attr;
+ }
+
+ p_rec = p_rec->p_next_rec;
+ }
+#endif
+ /* If here, no matching UUID found */
+ return (NULL);
+}
+
/*******************************************************************************
**
diff --git a/stack/sdp/sdp_utils.c b/stack/sdp/sdp_utils.c
index 2e0fdd8..d98a30c 100644
--- a/stack/sdp/sdp_utils.c
+++ b/stack/sdp/sdp_utils.c
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <string.h>
+#include <netinet/in.h>
#include <stdio.h>
#include "gki.h"
@@ -1002,3 +1003,24 @@ UINT8 *sdpu_build_partial_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr, UI
return p_out;
}
+/*******************************************************************************
+**
+** Function sdpu_uuid16_to_uuid128
+**
+** Description This function converts UUID-16 to UUID-128 by including the base UUID
+**
+** uuid16: 2-byte UUID
+** p_uuid128: Expanded 128-bit UUID
+**
+** Returns None
+**
+*******************************************************************************/
+void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128)
+{
+ UINT16 uuid16_bo;
+ memset(p_uuid128, 0, 16);
+
+ memcpy(p_uuid128, sdp_base_uuid, MAX_UUID_SIZE);
+ uuid16_bo = ntohs(uuid16);
+ memcpy(p_uuid128+ 2, &uuid16_bo, sizeof(uint16_t));
+}
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index f4416d0..60b9f4e 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -283,7 +283,7 @@ extern UINT16 sdpu_get_list_len( tSDP_UUID_SEQ *uid_seq, tSDP_ATTR_SEQ *attr
extern UINT16 sdpu_get_attrib_seq_len(tSDP_RECORD *p_rec, tSDP_ATTR_SEQ *attr_seq);
extern UINT16 sdpu_get_attrib_entry_len(tSDP_ATTRIBUTE *p_attr);
extern UINT8 *sdpu_build_partial_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr, UINT16 len, UINT16 *offset);
-
+extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128);
/* Functions provided by sdp_db.c
*/