diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index a021ffd1e57a91d89e10918a689829a7209c4667..6d9d986bf3a7ab027e4dc44f8451c41d1dfa246a 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -59,6 +59,7 @@ #include "stack/include/bt_types.h" #include "stack/include/btm_client_interface.h" #include "stack/include/btu.h" // do_in_main_thread +#include "stack/include/srvc_api.h" // DIS_ReadDISInfo #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -1198,6 +1199,21 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { } } while (p_sdp_rec); } + +#if TARGET_FLOSS + tSDP_DI_GET_RECORD di_record; + if (SDP_GetDiRecord(1, &di_record, bta_dm_search_cb.p_sdp_db) == + SDP_SUCCESS) { + tBTA_DM_SEARCH result; + result.did_res.bd_addr = bta_dm_search_cb.peer_bdaddr; + result.did_res.vendor_id_src = di_record.rec.vendor_id_source; + result.did_res.vendor_id = di_record.rec.vendor; + result.did_res.product_id = di_record.rec.product; + result.did_res.version = di_record.rec.version; + bta_dm_search_cb.p_search_cback(BTA_DM_DID_RES_EVT, &result); + } +#endif + /* if there are more services to search for */ if (bta_dm_search_cb.services_to_search) { /* Free up the p_sdp_db before checking the next one */ @@ -1293,6 +1309,26 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { } } +/** Callback of peer's DIS reply. This is only called for floss */ +#if TARGET_FLOSS +static void bta_dm_read_dis_cmpl(const RawAddress& addr, + tDIS_VALUE* p_dis_value) { + if (!p_dis_value) { + LOG_WARN("read DIS failed"); + } else { + tBTA_DM_SEARCH result; + result.did_res.bd_addr = addr; + result.did_res.vendor_id_src = p_dis_value->pnp_id.vendor_id_src; + result.did_res.vendor_id = p_dis_value->pnp_id.vendor_id; + result.did_res.product_id = p_dis_value->pnp_id.product_id; + result.did_res.version = p_dis_value->pnp_id.product_version; + bta_dm_search_cb.p_search_cback(BTA_DM_DID_RES_EVT, &result); + } + + bta_dm_execute_queued_request(); +} +#endif + /******************************************************************************* * * Function bta_dm_search_cmpl @@ -1347,6 +1383,13 @@ void bta_dm_search_cmpl() { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); +#if TARGET_FLOSS + if (DIS_ReadDISInfo(bta_dm_search_cb.peer_bdaddr, bta_dm_read_dis_cmpl, + DIS_ATTR_PNP_ID_BIT)) { + return; + } +#endif + bta_dm_execute_queued_request(); } diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index de1cc993cfeac0422217a7cf41a5187fdd774722..0c433e335117ae99820654b868416101d439b69f 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -423,6 +423,7 @@ typedef void(tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data); 3 /* Discovery result for BLE GATT based servoce on a peer device. */ #define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */ #define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */ +#define BTA_DM_DID_RES_EVT 7 /* Vendor/Product ID search result */ typedef uint8_t tBTA_DM_SEARCH_EVT; @@ -477,6 +478,15 @@ typedef struct { services; /* GATT based Services UUID found on peer device. */ } tBTA_DM_DISC_BLE_RES; +/* Structure associated with tBTA_DM_DID_RES */ +typedef struct { + RawAddress bd_addr; /* BD address peer device. */ + uint8_t vendor_id_src; + uint16_t vendor_id; + uint16_t product_id; + uint16_t version; +} tBTA_DM_DID_RES; + /* Union of all search callback structures */ typedef union { tBTA_DM_INQ_RES inq_res; /* Inquiry result for a peer device. */ @@ -484,6 +494,7 @@ typedef union { tBTA_DM_DISC_RES disc_res; /* Discovery result for a peer device. */ tBTA_DM_DISC_BLE_RES disc_ble_res; /* discovery result for GATT based service */ + tBTA_DM_DID_RES did_res; /* Vendor and Product ID of peer device */ } tBTA_DM_SEARCH; /* Search callback */ diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index c2c7b089a5ae39eda27902a1fbd30b2f819854ed..03910f668c59b0dca76408e696ce6eb51857290b 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -1630,6 +1630,29 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, num_properties, prop); } break; + case BTA_DM_DID_RES_EVT: { + bt_property_t prop_did; + RawAddress& bd_addr = p_data->did_res.bd_addr; + bt_vendor_product_info_t vp_info; + + vp_info.vendor_id_src = p_data->did_res.vendor_id_src; + vp_info.vendor_id = p_data->did_res.vendor_id; + vp_info.product_id = p_data->did_res.product_id; + vp_info.version = p_data->did_res.version; + + prop_did.type = BT_PROPERTY_VENDOR_PRODUCT_INFO; + prop_did.val = &vp_info; + prop_did.len = sizeof(vp_info); + + bt_status_t ret = + btif_storage_set_remote_device_property(&bd_addr, &prop_did); + ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed", ret); + + /* Send the event to the BTIF */ + invoke_remote_device_properties_cb(BT_STATUS_SUCCESS, bd_addr, 1, + &prop_did); + } break; + default: { ASSERTC(0, "unhandled search services event", event); } break; } } diff --git a/system/btif/src/btif_storage.cc b/system/btif/src/btif_storage.cc index df007ead8f2d96d83403f2d925086185fc638a4e..0ed4bba8b6065f26e08f77e69093995f93803f5b 100644 --- a/system/btif/src/btif_storage.cc +++ b/system/btif/src/btif_storage.cc @@ -102,6 +102,11 @@ using bluetooth::groups::DeviceGroups; #define BTIF_STORAGE_CSIS_SET_INFO_BIN "CsisSetInfoBin" #define BTIF_STORAGE_LEAUDIO_AUTOCONNECT "LeAudioAutoconnect" +#define BTIF_STORAGE_PATH_VENDOR_ID_SOURCE "VendorIdSource" +#define BTIF_STORAGE_PATH_VENDOR_ID "VendorId" +#define BTIF_STORAGE_PATH_PRODUCT_ID "ProductId" +#define BTIF_STORAGE_PATH_VERSION "ProductVersion" + /* This is a local property to add a device found */ #define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF @@ -286,6 +291,17 @@ static int prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { int val = *(uint16_t*)prop->val; btif_config_set_int(bdstr, BTIF_STORAGE_PATH_REMOTE_APPEARANCE, val); } break; + case BT_PROPERTY_VENDOR_PRODUCT_INFO: { + bt_vendor_product_info_t* info = (bt_vendor_product_info_t*)prop->val; + if (!info) return false; + + btif_config_set_int(bdstr, BTIF_STORAGE_PATH_VENDOR_ID_SOURCE, + info->vendor_id_src); + btif_config_set_int(bdstr, BTIF_STORAGE_PATH_VENDOR_ID, info->vendor_id); + btif_config_set_int(bdstr, BTIF_STORAGE_PATH_PRODUCT_ID, + info->product_id); + btif_config_set_int(bdstr, BTIF_STORAGE_PATH_VERSION, info->version); + } break; default: BTIF_TRACE_ERROR("Unknown prop type:%d", prop->type); @@ -422,6 +438,30 @@ static int cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { } } break; + case BT_PROPERTY_VENDOR_PRODUCT_INFO: { + bt_vendor_product_info_t* info = (bt_vendor_product_info_t*)prop->val; + int val; + + if (prop->len >= (int)sizeof(bt_vendor_product_info_t)) { + ret = btif_config_get_int(bdstr, BTIF_STORAGE_PATH_VENDOR_ID_SOURCE, + &val); + info->vendor_id_src = (uint8_t)val; + + if (ret) { + ret = btif_config_get_int(bdstr, BTIF_STORAGE_PATH_VENDOR_ID, &val); + info->vendor_id = (uint16_t)val; + } + if (ret) { + ret = btif_config_get_int(bdstr, BTIF_STORAGE_PATH_PRODUCT_ID, &val); + info->product_id = (uint16_t)val; + } + if (ret) { + ret = btif_config_get_int(bdstr, BTIF_STORAGE_PATH_VERSION, &val); + info->version = (uint16_t)val; + } + } + } break; + default: BTIF_TRACE_ERROR("Unknow prop type:%d", prop->type); return false; @@ -1036,7 +1076,7 @@ bt_status_t btif_storage_load_bonded_devices(void) { uint32_t i = 0; bt_property_t adapter_props[6]; uint32_t num_props = 0; - bt_property_t remote_properties[8]; + bt_property_t remote_properties[9]; RawAddress addr; bt_bdname_t name, alias; bt_scan_mode_t mode; @@ -1154,6 +1194,15 @@ bt_status_t btif_storage_load_bonded_devices(void) { remote_properties[num_props]); num_props++; +#if TARGET_FLOSS + // Floss needs VID:PID for metrics purposes + bt_vendor_product_info_t vp_info; + BTIF_STORAGE_GET_REMOTE_PROP( + p_remote_addr, BT_PROPERTY_VENDOR_PRODUCT_INFO, &vp_info, + sizeof(vp_info), remote_properties[num_props]); + num_props++; +#endif + btif_remote_properties_evt(BT_STATUS_SUCCESS, p_remote_addr, num_props, remote_properties); } diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h index 74726d1d5aea0acd6a05824b76d82f4554ca6f8f..98d38fbeb94ceaaf7022ffe12be9bf39110dfa7c 100644 --- a/system/include/hardware/bluetooth.h +++ b/system/include/hardware/bluetooth.h @@ -214,6 +214,14 @@ typedef struct { bool le_periodic_advertising_sync_transfer_recipient_supported; } bt_local_le_features_t; +/** Bluetooth Vendor and Product ID info */ +typedef struct { + uint8_t vendor_id_src; + uint16_t vendor_id; + uint16_t product_id; + uint16_t version; +} bt_vendor_product_info_t; + /* Stored the default/maximum/minimum buffer time for dynamic audio buffer. * For A2DP offload usage, the unit is millisecond. * For A2DP legacy usage, the unit is buffer queue size*/ @@ -347,6 +355,13 @@ typedef enum { */ BT_PROPERTY_APPEARANCE, + /** + * Description - Peer devices' vendor and product ID. + * Access mode - GET. + * Data Type - bt_vendor_product_info_t. + */ + BT_PROPERTY_VENDOR_PRODUCT_INFO, + BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, } bt_property_type_t;