Loading system/common/metrics.cc +22 −0 Original line number Diff line number Diff line Loading @@ -779,6 +779,28 @@ void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, } } void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id, size_t attribute_size, const char* attribute_value) { std::string obfuscated_id; if (!address.IsEmpty()) { obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address); } // nullptr and size 0 represent missing value for obfuscated_id android::util::BytesField obfuscated_id_field( address.IsEmpty() ? nullptr : obfuscated_id.c_str(), address.IsEmpty() ? 0 : obfuscated_id.size()); android::util::BytesField attribute_field(attribute_value, attribute_size); int ret = android::util::stats_write( android::util::BLUETOOTH_SDP_ATTRIBUTE_REPORTED, obfuscated_id_field, protocol_uuid, attribute_id, attribute_field); if (ret < 0) { LOG(WARNING) << __func__ << ": failed for " << address << ", protocol_uuid " << loghex(protocol_uuid) << ", attribute_id " << loghex(attribute_id) << ", error " << ret; } } } // namespace common } // namespace bluetooth system/common/metrics.h +14 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,20 @@ void LogSmpPairingEvent(const RawAddress& address, uint8_t smp_cmd, void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, uint32_t hci_cmd, uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code); /** * Logs when certain Bluetooth SDP attributes are discovered * * @param address address of associated device * @param protocol_uuid 16 bit protocol UUID from Bluetooth Assigned Numbers * @param attribute_id 16 bit attribute ID from Bluetooth Assigned Numbers * @param attribute_size size of this attribute * @param attribute_value pointer to the attribute data, must be larger than * attribute_size */ void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id, size_t attribute_size, const char* attribute_value); } // namespace common } // namespace bluetooth system/stack/sdp/sdp_discovery.cc +2 −0 Original line number Diff line number Diff line Loading @@ -484,6 +484,7 @@ static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS, sdp_conn_timer_timeout, p_ccb); } else { sdpu_log_attribute_metrics(p_ccb->device_address, p_ccb->p_db); sdp_disconnect(p_ccb, SDP_SUCCESS); return; } Loading Loading @@ -648,6 +649,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, } /* Since we got everything we need, disconnect the call */ sdpu_log_attribute_metrics(p_ccb->device_address, p_ccb->p_db); sdp_disconnect(p_ccb, SDP_SUCCESS); } Loading system/stack/sdp/sdp_utils.cc +220 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <utility> #include <vector> #include "bt_common.h" #include "bt_types.h" Loading @@ -38,12 +40,230 @@ #include "sdpint.h" #include "btu.h" #include "common/metrics.h" using bluetooth::Uuid; static const uint8_t sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; template <typename T> static std::array<char, sizeof(T)> to_little_endian_array(T x) { static_assert(std::is_integral<T>::value, "to_little_endian_array parameter must be integral."); std::array<char, sizeof(T)> array = {}; for (size_t i = 0; i < array.size(); i++) { array[i] = static_cast<char>((x >> (8 * i)) & 0xFF); } return array; } /** * Find the list of profile versions from Bluetooth Profile Descriptor list * attribute in a SDP record * * @param p_rec SDP record to search * @return a vector of <UUID, VERSION> pairs, empty if not found */ static std::vector<std::pair<uint16_t, uint16_t>> sdpu_find_profile_version( tSDP_DISC_REC* p_rec) { std::vector<std::pair<uint16_t, uint16_t>> result; for (tSDP_DISC_ATTR* p_attr = p_rec->p_first_attr; p_attr != nullptr; p_attr = p_attr->p_next_attr) { // Find the profile descriptor list */ if (p_attr->attr_id != ATTR_ID_BT_PROFILE_DESC_LIST || SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { continue; } // Walk through the protocol descriptor list for (tSDP_DISC_ATTR* p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr != nullptr; p_sattr = p_sattr->p_next_attr) { // Safety check - each entry should itself be a sequence if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { LOG(WARNING) << __func__ << ": Descriptor type is not sequence: " << loghex(SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type)); return std::vector<std::pair<uint16_t, uint16_t>>(); } // Now, see if the entry contains the profile UUID we are interested in for (tSDP_DISC_ATTR* p_ssattr = p_sattr->attr_value.v.p_sub_attr; p_ssattr != nullptr; p_ssattr = p_ssattr->p_next_attr) { if (SDP_DISC_ATTR_TYPE(p_ssattr->attr_len_type) != UUID_DESC_TYPE || SDP_DISC_ATTR_LEN(p_ssattr->attr_len_type) != 2) { continue; } uint16_t uuid = p_ssattr->attr_value.v.u16; // Next attribute should be the version attribute tSDP_DISC_ATTR* version_attr = p_ssattr->p_next_attr; if (SDP_DISC_ATTR_TYPE(version_attr->attr_len_type) != UINT_DESC_TYPE || SDP_DISC_ATTR_LEN(version_attr->attr_len_type) != 2) { LOG(WARNING) << __func__ << ": Bad version type " << loghex( SDP_DISC_ATTR_TYPE(version_attr->attr_len_type)) << ", or length " << SDP_DISC_ATTR_LEN(version_attr->attr_len_type); return std::vector<std::pair<uint16_t, uint16_t>>(); } // High order 8 bits is the major number, low order is the // minor number (big endian) uint16_t version = version_attr->attr_value.v.u16; result.emplace_back(uuid, version); } } } return result; } /** * Find the most specific 16-bit service uuid represented by a SDP record * * @param p_rec pointer to a SDP record * @return most specific 16-bit service uuid, 0 if not found */ static uint16_t sdpu_find_most_specific_service_uuid(tSDP_DISC_REC* p_rec) { for (tSDP_DISC_ATTR* p_attr = p_rec->p_first_attr; p_attr != nullptr; p_attr = p_attr->p_next_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) { tSDP_DISC_ATTR* p_first_attr = p_attr->attr_value.v.p_sub_attr; if (SDP_DISC_ATTR_TYPE(p_first_attr->attr_len_type) == UUID_DESC_TYPE && SDP_DISC_ATTR_LEN(p_first_attr->attr_len_type) == 2) { return p_first_attr->attr_value.v.u16; } else if (SDP_DISC_ATTR_TYPE(p_first_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) { // Workaround for Toyota G Block car kit: // It incorrectly puts an extra data element sequence in this attribute for (tSDP_DISC_ATTR* p_extra_sattr = p_first_attr->attr_value.v.p_sub_attr; p_extra_sattr != nullptr; p_extra_sattr = p_extra_sattr->p_next_attr) { // Return the first UUID data element if (SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) == UUID_DESC_TYPE && SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2) { return p_extra_sattr->attr_value.v.u16; } } } else { LOG(WARNING) << __func__ << ": Bad Service Class ID list attribute"; return 0; } } 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) == 2) { return p_attr->attr_value.v.u16; } } } return 0; } void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db) { CHECK_NE(p_db, nullptr); for (tSDP_DISC_REC* p_rec = p_db->p_first_rec; p_rec != nullptr; p_rec = p_rec->p_next_rec) { uint16_t service_uuid = sdpu_find_most_specific_service_uuid(p_rec); if (service_uuid == 0) { LOG(INFO) << __func__ << ": skipping record without service uuid " << bda; continue; } // Log the existence of a profile role // This can be different from Bluetooth Profile Descriptor List bluetooth::common::LogSdpAttribute(bda, service_uuid, 0, 0, nullptr); // Log profile version from Bluetooth Profile Descriptor List auto uuid_version_array = sdpu_find_profile_version(p_rec); for (const auto& uuid_version_pair : uuid_version_array) { uint16_t profile_uuid = uuid_version_pair.first; uint16_t version = uuid_version_pair.second; auto version_array = to_little_endian_array(version); bluetooth::common::LogSdpAttribute( bda, profile_uuid, ATTR_ID_BT_PROFILE_DESC_LIST, version_array.size(), version_array.data()); } // Log protocol version from Protocol Descriptor List uint16_t protocol_uuid = 0; switch (service_uuid) { case UUID_SERVCLASS_AUDIO_SOURCE: case UUID_SERVCLASS_AUDIO_SINK: protocol_uuid = UUID_PROTOCOL_AVDTP; break; case UUID_SERVCLASS_AV_REMOTE_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_TARGET: protocol_uuid = UUID_PROTOCOL_AVCTP; break; case UUID_SERVCLASS_PANU: case UUID_SERVCLASS_GN: protocol_uuid = UUID_PROTOCOL_BNEP; break; } if (protocol_uuid != 0) { tSDP_PROTOCOL_ELEM protocol_elements = {}; if (SDP_FindProtocolListElemInRec(p_rec, protocol_uuid, &protocol_elements)) { if (protocol_elements.num_params >= 1) { uint16_t version = protocol_elements.params[0]; auto version_array = to_little_endian_array(version); bluetooth::common::LogSdpAttribute( bda, protocol_uuid, ATTR_ID_PROTOCOL_DESC_LIST, version_array.size(), version_array.data()); } } } // Log profile supported features from various supported feature attributes switch (service_uuid) { case UUID_SERVCLASS_AG_HANDSFREE: case UUID_SERVCLASS_HF_HANDSFREE: case UUID_SERVCLASS_AV_REMOTE_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_TARGET: case UUID_SERVCLASS_AUDIO_SOURCE: case UUID_SERVCLASS_AUDIO_SINK: { tSDP_DISC_ATTR* p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES); if (p_attr == nullptr) { break; } uint16_t supported_features = p_attr->attr_value.v.u16; auto version_array = to_little_endian_array(supported_features); bluetooth::common::LogSdpAttribute( bda, service_uuid, ATTR_ID_SUPPORTED_FEATURES, version_array.size(), version_array.data()); break; } case UUID_SERVCLASS_MESSAGE_NOTIFICATION: case UUID_SERVCLASS_MESSAGE_ACCESS: { tSDP_DISC_ATTR* p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES); if (p_attr == nullptr) { break; } uint32_t map_supported_features = p_attr->attr_value.v.u32; auto features_array = to_little_endian_array(map_supported_features); bluetooth::common::LogSdpAttribute( bda, service_uuid, ATTR_ID_MAP_SUPPORTED_FEATURES, features_array.size(), features_array.data()); break; } case UUID_SERVCLASS_PBAP_PCE: case UUID_SERVCLASS_PBAP_PSE: { tSDP_DISC_ATTR* p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES); if (p_attr == nullptr) { break; } uint32_t pbap_supported_features = p_attr->attr_value.v.u32; auto features_array = to_little_endian_array(pbap_supported_features); bluetooth::common::LogSdpAttribute( bda, service_uuid, ATTR_ID_PBAP_SUPPORTED_FEATURES, features_array.size(), features_array.data()); break; } } } } /******************************************************************************* * * Function sdpu_find_ccb_by_cid Loading system/stack/sdp/sdpint.h +2 −0 Original line number Diff line number Diff line Loading @@ -247,6 +247,8 @@ extern tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr); /* Functions provided by sdp_utils.cc */ extern void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db); extern tCONN_CB* sdpu_find_ccb_by_cid(uint16_t cid); extern tCONN_CB* sdpu_find_ccb_by_db(tSDP_DISCOVERY_DB* p_db); extern tCONN_CB* sdpu_allocate_ccb(void); Loading Loading
system/common/metrics.cc +22 −0 Original line number Diff line number Diff line Loading @@ -779,6 +779,28 @@ void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, } } void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id, size_t attribute_size, const char* attribute_value) { std::string obfuscated_id; if (!address.IsEmpty()) { obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address); } // nullptr and size 0 represent missing value for obfuscated_id android::util::BytesField obfuscated_id_field( address.IsEmpty() ? nullptr : obfuscated_id.c_str(), address.IsEmpty() ? 0 : obfuscated_id.size()); android::util::BytesField attribute_field(attribute_value, attribute_size); int ret = android::util::stats_write( android::util::BLUETOOTH_SDP_ATTRIBUTE_REPORTED, obfuscated_id_field, protocol_uuid, attribute_id, attribute_field); if (ret < 0) { LOG(WARNING) << __func__ << ": failed for " << address << ", protocol_uuid " << loghex(protocol_uuid) << ", attribute_id " << loghex(attribute_id) << ", error " << ret; } } } // namespace common } // namespace bluetooth
system/common/metrics.h +14 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,20 @@ void LogSmpPairingEvent(const RawAddress& address, uint8_t smp_cmd, void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, uint32_t hci_cmd, uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code); /** * Logs when certain Bluetooth SDP attributes are discovered * * @param address address of associated device * @param protocol_uuid 16 bit protocol UUID from Bluetooth Assigned Numbers * @param attribute_id 16 bit attribute ID from Bluetooth Assigned Numbers * @param attribute_size size of this attribute * @param attribute_value pointer to the attribute data, must be larger than * attribute_size */ void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id, size_t attribute_size, const char* attribute_value); } // namespace common } // namespace bluetooth
system/stack/sdp/sdp_discovery.cc +2 −0 Original line number Diff line number Diff line Loading @@ -484,6 +484,7 @@ static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS, sdp_conn_timer_timeout, p_ccb); } else { sdpu_log_attribute_metrics(p_ccb->device_address, p_ccb->p_db); sdp_disconnect(p_ccb, SDP_SUCCESS); return; } Loading Loading @@ -648,6 +649,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, } /* Since we got everything we need, disconnect the call */ sdpu_log_attribute_metrics(p_ccb->device_address, p_ccb->p_db); sdp_disconnect(p_ccb, SDP_SUCCESS); } Loading
system/stack/sdp/sdp_utils.cc +220 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <utility> #include <vector> #include "bt_common.h" #include "bt_types.h" Loading @@ -38,12 +40,230 @@ #include "sdpint.h" #include "btu.h" #include "common/metrics.h" using bluetooth::Uuid; static const uint8_t sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; template <typename T> static std::array<char, sizeof(T)> to_little_endian_array(T x) { static_assert(std::is_integral<T>::value, "to_little_endian_array parameter must be integral."); std::array<char, sizeof(T)> array = {}; for (size_t i = 0; i < array.size(); i++) { array[i] = static_cast<char>((x >> (8 * i)) & 0xFF); } return array; } /** * Find the list of profile versions from Bluetooth Profile Descriptor list * attribute in a SDP record * * @param p_rec SDP record to search * @return a vector of <UUID, VERSION> pairs, empty if not found */ static std::vector<std::pair<uint16_t, uint16_t>> sdpu_find_profile_version( tSDP_DISC_REC* p_rec) { std::vector<std::pair<uint16_t, uint16_t>> result; for (tSDP_DISC_ATTR* p_attr = p_rec->p_first_attr; p_attr != nullptr; p_attr = p_attr->p_next_attr) { // Find the profile descriptor list */ if (p_attr->attr_id != ATTR_ID_BT_PROFILE_DESC_LIST || SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { continue; } // Walk through the protocol descriptor list for (tSDP_DISC_ATTR* p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr != nullptr; p_sattr = p_sattr->p_next_attr) { // Safety check - each entry should itself be a sequence if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { LOG(WARNING) << __func__ << ": Descriptor type is not sequence: " << loghex(SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type)); return std::vector<std::pair<uint16_t, uint16_t>>(); } // Now, see if the entry contains the profile UUID we are interested in for (tSDP_DISC_ATTR* p_ssattr = p_sattr->attr_value.v.p_sub_attr; p_ssattr != nullptr; p_ssattr = p_ssattr->p_next_attr) { if (SDP_DISC_ATTR_TYPE(p_ssattr->attr_len_type) != UUID_DESC_TYPE || SDP_DISC_ATTR_LEN(p_ssattr->attr_len_type) != 2) { continue; } uint16_t uuid = p_ssattr->attr_value.v.u16; // Next attribute should be the version attribute tSDP_DISC_ATTR* version_attr = p_ssattr->p_next_attr; if (SDP_DISC_ATTR_TYPE(version_attr->attr_len_type) != UINT_DESC_TYPE || SDP_DISC_ATTR_LEN(version_attr->attr_len_type) != 2) { LOG(WARNING) << __func__ << ": Bad version type " << loghex( SDP_DISC_ATTR_TYPE(version_attr->attr_len_type)) << ", or length " << SDP_DISC_ATTR_LEN(version_attr->attr_len_type); return std::vector<std::pair<uint16_t, uint16_t>>(); } // High order 8 bits is the major number, low order is the // minor number (big endian) uint16_t version = version_attr->attr_value.v.u16; result.emplace_back(uuid, version); } } } return result; } /** * Find the most specific 16-bit service uuid represented by a SDP record * * @param p_rec pointer to a SDP record * @return most specific 16-bit service uuid, 0 if not found */ static uint16_t sdpu_find_most_specific_service_uuid(tSDP_DISC_REC* p_rec) { for (tSDP_DISC_ATTR* p_attr = p_rec->p_first_attr; p_attr != nullptr; p_attr = p_attr->p_next_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) { tSDP_DISC_ATTR* p_first_attr = p_attr->attr_value.v.p_sub_attr; if (SDP_DISC_ATTR_TYPE(p_first_attr->attr_len_type) == UUID_DESC_TYPE && SDP_DISC_ATTR_LEN(p_first_attr->attr_len_type) == 2) { return p_first_attr->attr_value.v.u16; } else if (SDP_DISC_ATTR_TYPE(p_first_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) { // Workaround for Toyota G Block car kit: // It incorrectly puts an extra data element sequence in this attribute for (tSDP_DISC_ATTR* p_extra_sattr = p_first_attr->attr_value.v.p_sub_attr; p_extra_sattr != nullptr; p_extra_sattr = p_extra_sattr->p_next_attr) { // Return the first UUID data element if (SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) == UUID_DESC_TYPE && SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2) { return p_extra_sattr->attr_value.v.u16; } } } else { LOG(WARNING) << __func__ << ": Bad Service Class ID list attribute"; return 0; } } 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) == 2) { return p_attr->attr_value.v.u16; } } } return 0; } void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db) { CHECK_NE(p_db, nullptr); for (tSDP_DISC_REC* p_rec = p_db->p_first_rec; p_rec != nullptr; p_rec = p_rec->p_next_rec) { uint16_t service_uuid = sdpu_find_most_specific_service_uuid(p_rec); if (service_uuid == 0) { LOG(INFO) << __func__ << ": skipping record without service uuid " << bda; continue; } // Log the existence of a profile role // This can be different from Bluetooth Profile Descriptor List bluetooth::common::LogSdpAttribute(bda, service_uuid, 0, 0, nullptr); // Log profile version from Bluetooth Profile Descriptor List auto uuid_version_array = sdpu_find_profile_version(p_rec); for (const auto& uuid_version_pair : uuid_version_array) { uint16_t profile_uuid = uuid_version_pair.first; uint16_t version = uuid_version_pair.second; auto version_array = to_little_endian_array(version); bluetooth::common::LogSdpAttribute( bda, profile_uuid, ATTR_ID_BT_PROFILE_DESC_LIST, version_array.size(), version_array.data()); } // Log protocol version from Protocol Descriptor List uint16_t protocol_uuid = 0; switch (service_uuid) { case UUID_SERVCLASS_AUDIO_SOURCE: case UUID_SERVCLASS_AUDIO_SINK: protocol_uuid = UUID_PROTOCOL_AVDTP; break; case UUID_SERVCLASS_AV_REMOTE_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_TARGET: protocol_uuid = UUID_PROTOCOL_AVCTP; break; case UUID_SERVCLASS_PANU: case UUID_SERVCLASS_GN: protocol_uuid = UUID_PROTOCOL_BNEP; break; } if (protocol_uuid != 0) { tSDP_PROTOCOL_ELEM protocol_elements = {}; if (SDP_FindProtocolListElemInRec(p_rec, protocol_uuid, &protocol_elements)) { if (protocol_elements.num_params >= 1) { uint16_t version = protocol_elements.params[0]; auto version_array = to_little_endian_array(version); bluetooth::common::LogSdpAttribute( bda, protocol_uuid, ATTR_ID_PROTOCOL_DESC_LIST, version_array.size(), version_array.data()); } } } // Log profile supported features from various supported feature attributes switch (service_uuid) { case UUID_SERVCLASS_AG_HANDSFREE: case UUID_SERVCLASS_HF_HANDSFREE: case UUID_SERVCLASS_AV_REMOTE_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_CONTROL: case UUID_SERVCLASS_AV_REM_CTRL_TARGET: case UUID_SERVCLASS_AUDIO_SOURCE: case UUID_SERVCLASS_AUDIO_SINK: { tSDP_DISC_ATTR* p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES); if (p_attr == nullptr) { break; } uint16_t supported_features = p_attr->attr_value.v.u16; auto version_array = to_little_endian_array(supported_features); bluetooth::common::LogSdpAttribute( bda, service_uuid, ATTR_ID_SUPPORTED_FEATURES, version_array.size(), version_array.data()); break; } case UUID_SERVCLASS_MESSAGE_NOTIFICATION: case UUID_SERVCLASS_MESSAGE_ACCESS: { tSDP_DISC_ATTR* p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES); if (p_attr == nullptr) { break; } uint32_t map_supported_features = p_attr->attr_value.v.u32; auto features_array = to_little_endian_array(map_supported_features); bluetooth::common::LogSdpAttribute( bda, service_uuid, ATTR_ID_MAP_SUPPORTED_FEATURES, features_array.size(), features_array.data()); break; } case UUID_SERVCLASS_PBAP_PCE: case UUID_SERVCLASS_PBAP_PSE: { tSDP_DISC_ATTR* p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES); if (p_attr == nullptr) { break; } uint32_t pbap_supported_features = p_attr->attr_value.v.u32; auto features_array = to_little_endian_array(pbap_supported_features); bluetooth::common::LogSdpAttribute( bda, service_uuid, ATTR_ID_PBAP_SUPPORTED_FEATURES, features_array.size(), features_array.data()); break; } } } } /******************************************************************************* * * Function sdpu_find_ccb_by_cid Loading
system/stack/sdp/sdpint.h +2 −0 Original line number Diff line number Diff line Loading @@ -247,6 +247,8 @@ extern tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr); /* Functions provided by sdp_utils.cc */ extern void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db); extern tCONN_CB* sdpu_find_ccb_by_cid(uint16_t cid); extern tCONN_CB* sdpu_find_ccb_by_db(tSDP_DISCOVERY_DB* p_db); extern tCONN_CB* sdpu_allocate_ccb(void); Loading