diff --git a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_profile.cpp b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_profile.cpp index 70793617a139aa66923f700a3bb02b700cec3a7e..e57bb901e0826806aefba7ef16abfca814ff4930 100644 --- a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_profile.cpp +++ b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_profile.cpp @@ -91,23 +91,12 @@ int AvrcCtProfile::Enable(bool isTgEnabled) int result = BT_SUCCESS; SetEnableFlag(true); - - if (!isTgEnabled) { - /// If the following statement in the debt_config.xml. That means that TG allows to enable. CT do not - /// allow the passive connection. Because if CT and TG are registered passive connections, it will case that the - /// inability to distinguish between the end device - /// "true" - AVCT_Register(controlMtu_, browseMtu_, AVCT_CT); - - AvctConnectParam param = {eventCallback_, msgCallback_, AVRC_CT_AV_REMOTE_CONTROL, AVCT_ACPT, nullptr}; - BtAddr btAddr = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x00}; - if (AVCT_ConnectReq(&connectId_, ¶m, &btAddr) != AVCT_SUCCESS) { - result = RET_BAD_STATUS; - } - } else { - /// CT is only allowed the active connection. + AVCT_Register(controlMtu_, browseMtu_, AVCT_CT); + AvctConnectParam param = {eventCallback_, msgCallback_, AVRC_CT_AV_REMOTE_CONTROL, AVCT_ACPT, nullptr}; + BtAddr btAddr = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x00}; + if (AVCT_ConnectReq(&connectId_, ¶m, &btAddr) != AVCT_SUCCESS) { + result = RET_BAD_STATUS; } - return result; } diff --git a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.cpp b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.cpp index 761368762f28fae62200ad647392dcbc993eed29..2de031a33075d50b619c07f638feb8225f2cecf3 100644 --- a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.cpp +++ b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.cpp @@ -18,6 +18,8 @@ namespace OHOS { namespace bluetooth { +const int ATTR_NUMBER2 = 2; +const int ATTR_NUMBER1 = 1; /// Number of items when add service class id list. const uint16_t AVRC_SERVICE_CLASS_ID_LIST_NUMBER = 0x0002; /// Number of items when add protocol descriptor. @@ -114,19 +116,30 @@ int AvrcCtSdpManager::UnregisterService(void) const } int AvrcCtSdpManager::FindTgService(const RawAddress &rawAddr, - void (*callback)(const BtAddr *btAddr, const uint32_t *handleArray, uint16_t handleNum, void *context)) + void (*callback)(const BtAddr *btAddr, const SdpService *serviceArray, uint16_t serviceNum, void *context)) { HILOGI("address: %{public}s", GET_ENCRYPT_AVRCP_ADDR(rawAddr)); BtAddr btAddr; rawAddr.ConvertToUint8(btAddr.addr); - BtUuid classIdList[AVRC_SERVICE_CLASS_ID_LIST_NUMBER - 1]; + BtUuid classIdList[AVRC_SERVICE_CLASS_ID_LIST_NUMBER]; classIdList[0].type = BT_UUID_16; - classIdList[0].uuid16 = AVRC_CT_AV_REMOTE_CONTROL_TARGET; - SdpUuid sdpUuid = {.uuidNum = AVRC_SERVICE_CLASS_ID_LIST_NUMBER - 1, .uuid = classIdList}; + classIdList[0].uuid16 = AVRC_CT_AV_REMOTE_CONTROL; + SdpUuid sdpUuid = { + .uuidNum = AVRC_SERVICE_CLASS_ID_LIST_NUMBER, + .uuid = classIdList + }; + + SdpAttributeIdList attributeIdList; + attributeIdList.type = SDP_TYPE_LIST; + + attributeIdList.attributeIdList.attributeIdNumber = AVRC_SDP_ATTRIBUTE_NUM; + attributeIdList.attributeIdList.attributeId[0] = SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST; + attributeIdList.attributeIdList.attributeId[ATTR_NUMBER1] = SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST; + attributeIdList.attributeIdList.attributeId[ATTR_NUMBER2] = AVRC_CT_ATTRIBUTE_ID_SUPPORTED_FEATURES; - int result = SDP_ServiceSearch(&btAddr, &sdpUuid, nullptr, callback); + int result = SDP_ServiceSearchAttribute(&btAddr, &sdpUuid, attributeIdList, nullptr, callback); (result == BT_SUCCESS) ? (result = BT_SUCCESS) : (result = RET_BAD_STATUS); return result; diff --git a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.h b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.h index fc6b1f71814144bc56a9ecc349886b9e1d327439..9ba85c10cf7958a6680174a0f0fee1fcdc9e2452 100644 --- a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.h +++ b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_sdp.h @@ -17,6 +17,8 @@ #define AVRCP_CT_SDP_H #include "avrcp_ct_internal.h" +#include "sdp.h" +#define AVRC_SDP_ATTRIBUTE_NUM 3 namespace OHOS { namespace bluetooth { @@ -71,7 +73,7 @@ public: * @retval RET_BAD_STATUS Execute failure. */ static int FindTgService(const RawAddress &rawAddr, - void (*callback)(const BtAddr *btAddr, const uint32_t *handleArray, uint16_t handleNum, void *context)); + void (*callback)(const BtAddr *btAddr, const SdpService *serviceArray, uint16_t serviceNum, void *context)); private: uint32_t sdpHandle_; // The handle got from the SDP. diff --git a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.cpp b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.cpp index 2b586c0a8597070d66745ae95318f83af686e63e..ae861964af7c029a49a7cf7241c928aa1a88b236 100644 --- a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.cpp +++ b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.cpp @@ -211,7 +211,7 @@ int AvrcpCtService::EnableProfile(void) config->GetValue(SECTION_AVRCP_CT_SERVICE, PROPERTY_BROWSE_MTU, browseMtu); config->GetValue(SECTION_CLASSIC_ADAPTER, PROPERTY_AVRCP_TG_SERVICE, isTgEnabled); - profile_ = std::make_unique(features_, + profile_ = std::make_unique(features_ & AVRC_CT_SDP_ALL_SUPPORTED_FEATURES, AVRC_CT_DEFAULT_BLUETOOTH_SIG_COMPANY_ID, controlMtu, browseMtu, @@ -487,6 +487,29 @@ void AvrcpCtService::RejectActiveConnect(const RawAddress &rawAddr) const HILOGI("address: %{public}s", GET_ENCRYPT_AVRCP_ADDR(rawAddr)); } +// Parse AVRCP SDP Information +// supports browsing || supports advanced control +void AvrcpCtService::ParseSDPInformation( + const BtAddr *btAddr, const SdpService *serviceArray, uint16_t serviceNum) +{ + HILOGI("serviceNum(%{public}d)\n", serviceNum); + + uint16_t peerFeatures = 0; + uint16_t peerAvrcpVersion = 0; + + for (int i = 0; i < serviceNum; i++) { + HILOGI("uuid16: %{public}4x\n", serviceArray[i].classId->uuid16); + if (serviceArray[i].classId->uuid16 == AVRC_CT_AV_REMOTE_CONTROL_TARGET) { + peerAvrcpVersion = serviceArray[i].profileDescriptor->versionNumber; + HILOGI("peerAvrcpVersion: %{public}x\n", peerAvrcpVersion); + if (peerAvrcpVersion >= AVCT_REV_1_4) { + peerFeatures = *(uint16_t*)serviceArray[i].attribute[0].attributeValue; + HILOGI("peerFeatures: %{public}x\n", peerFeatures); + } + } + } +} + int AvrcpCtService::FindTgService(const RawAddress &rawAddr) const { HILOGI("address: %{public}s", GET_ENCRYPT_AVRCP_ADDR(rawAddr)); @@ -495,15 +518,16 @@ int AvrcpCtService::FindTgService(const RawAddress &rawAddr) const } void AvrcpCtService::FindTgServiceCallback( - const BtAddr *btAddr, const uint32_t *handleArray, uint16_t handleCount, void *context) + const BtAddr *btAddr, const SdpService *serviceArray, uint16_t serviceNum, void *context) { - HILOGI("handleCount: %{public}d", handleCount); + HILOGI("serviceNum: %{public}d", serviceNum); auto servManager = IProfileManager::GetInstance(); auto service = static_cast(servManager->GetProfileService(PROFILE_NAME_AVRCP_CT)); RawAddress rawAddr(RawAddress::ConvertToString(btAddr->addr)); if (service != nullptr) { - if (handleCount > 0) { + if (serviceNum > 0) { + ParseSDPInformation(btAddr, serviceArray, serviceNum); service->GetDispatcher()->PostTask(std::bind(&AvrcpCtService::AcceptActiveConnect, service, rawAddr)); } else { service->GetDispatcher()->PostTask(std::bind(&AvrcpCtService::RejectActiveConnect, service, rawAddr)); @@ -2211,7 +2235,9 @@ void AvrcpCtService::ChannelMessageCallback( { HILOGI("connectId: %{public}d, label: %{public}d, crType: %{public}d, chType: %{public}d", connectId, label, crType, chType); - + if (!crType) { + return; + } auto servManager = IProfileManager::GetInstance(); auto service = static_cast(servManager->GetProfileService(PROFILE_NAME_AVRCP_CT)); auto myPkt = PacketRefMalloc(pkt); diff --git a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.h b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.h index 3cf23b51d3897375d575fc225c79abb37929c721..f9898f0c125a0ef2d72a7ffc1417402279b294b3 100644 --- a/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.h +++ b/services/bluetooth/service/src/avrcp_ct/avrcp_ct_service.h @@ -610,7 +610,7 @@ private: /// The flag is used to indicate that the state of the AVRCP CT service. std::atomic_uint8_t state_ {AVRC_CT_SERVICE_STATE_DISABLED}; /// The features supported by the AVRCP CT service. - uint16_t features_ {AVRC_CT_FEATURE_INVALID_FEATURE}; + uint32_t features_ {AVRC_CT_FEATURE_INVALID_FEATURE}; /// The observer registered by the AVRCP CT framework. /// @see AvrcCtProfile::Observer @@ -770,13 +770,23 @@ private: /** * @brief The callback function that receives the search result return from the SDP. * - * @param[in] btAddr The address of the peer Bluetooth device. - * @param[in] handleArray The list of handle to a qualifying service. - * @param[in] handleCount The number of handle to a qualifying service. - * @param[in] context The context is used to send the event in the callback. + * @param[in] btAddr The address of the peer Bluetooth device. + * @param[in] serviceArray The list of serviceArray to a qualifying service. + * @param[in] serviceNum The number of serviceArray to a qualifying service. + * @param[in] context The context is used to send the event in the callback. */ static void FindTgServiceCallback( - const BtAddr *btAddr, const uint32_t *handleArray, uint16_t handleCount, void *context); + const BtAddr *btAddr, const SdpService *serviceArray, uint16_t serviceNum, void *context); + + // parse SDP_SERVICE_SEARCH_ATTR_RSP + /** + * @brief The parse function, which parse SDP search result. + * + * @param[in] btAddr The address of the peer Bluetooth device. + * @param[in] serviceArray The list of handle to a qualifying service. + * @param[in] serviceNum The number of handle to a qualifying service. + */ + static void ParseSDPInformation(const BtAddr *btAddr, const SdpService *serviceArray, uint16_t serviceNum); /****************************************************************** * BUTTON OPERATION *