1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "a2dp_sdp.h"
17 
18 #include "log.h"
19 
20 namespace OHOS {
21 namespace bluetooth {
22 const int ATTR_NUMBER2 = 2;
23 const int ATTR_NUMBER1 = 1;
SetProfileRole(uint8_t role)24 void A2dpSdpManager::SetProfileRole(uint8_t role)
25 {
26     role_ = role;
27 }
28 
RegisterService()29 int A2dpSdpManager::RegisterService()
30 {
31     LOG_INFO("[A2dpSdpManager]%{public}s role[%u]\n", __func__, role_);
32     int rtnSts;
33     sdpHandle_ = SDP_CreateServiceRecord();
34 
35     /// Service Class ID List.
36     BtUuid classIdList[A2DP_SERVICE_CLASS_ID_LIST_NUMBER];
37     classIdList[0].type = BT_UUID_16;
38     if (role_ == A2DP_ROLE_SOURCE) {
39         classIdList[0].uuid16 = A2DP_SERVICE_CLASS_UUID;
40     } else {
41         classIdList[0].uuid16 = A2DP_SINK_SERVICE_CLASS_UUID;
42     }
43     rtnSts = SDP_AddServiceClassIdList(sdpHandle_, classIdList, A2DP_SERVICE_CLASS_ID_LIST_NUMBER);
44     if (rtnSts != BT_SUCCESS) {
45         LOG_WARN("[A2dpSdpManager]%{public}s SDP_AddServiceClassIdList[result:%{public}d]\n", __func__, rtnSts);
46         return rtnSts;
47     }
48 
49     /// Protocol Descriptor List.
50     SdpProtocolDescriptor dscList[A2DP_PROTOCOL_DESCRIPTOR_LIST_NUMBER];
51     dscList[0].parameter[0].type = SDP_TYPE_UINT_16;
52     dscList[0].parameter[0].value = A2DP_PROTOCOL_UUID_AVDTP;  // PSM= AVDTP
53     dscList[0].parameterNumber = 1;
54     dscList[0].protocolUuid.type = BT_UUID_16;
55     dscList[0].protocolUuid.uuid16 = A2DP_PROTOCOL_UUID_L2CAP;
56     dscList[ATTR_NUMBER1].parameter[0].type = SDP_TYPE_UINT_16;
57     dscList[ATTR_NUMBER1].parameter[0].value = A2DP_PROFILE_REV_1_3;  // Profile Version
58     dscList[ATTR_NUMBER1].parameterNumber = ATTR_NUMBER1;
59     dscList[ATTR_NUMBER1].protocolUuid.type = BT_UUID_16;
60     dscList[ATTR_NUMBER1].protocolUuid.uuid16 = A2DP_PROTOCOL_UUID_AVDTP;
61     rtnSts = SDP_AddProtocolDescriptorList(sdpHandle_, dscList, A2DP_PROTOCOL_DESCRIPTOR_LIST_NUMBER);
62     if (rtnSts != BT_SUCCESS) {
63         LOG_WARN("[A2dpSdpManager]%{public}s SDP_AddProtocolDescriptorList[result:%{public}d]\n", __func__, rtnSts);
64         return rtnSts;
65     }
66 
67     /// Bluetooth Profile Descriptor List.
68     SdpProfileDescriptor profileDsc;
69     profileDsc.versionNumber = A2DP_PROFILE_REV_1_3;
70     profileDsc.profileUuid.type = BT_UUID_16;
71     profileDsc.profileUuid.uuid16 = A2DP_PROFILE_UUID;
72     rtnSts =
73         SDP_AddBluetoothProfileDescriptorList(sdpHandle_, &profileDsc, A2DP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_NUMBER);
74     if (rtnSts != BT_SUCCESS) {
75         LOG_WARN("[A2dpSdpManager]%{public}s SDP_AddBluetoothProfileDescriptorList[result:%{public}d]\n",
76             __func__, rtnSts);
77         return rtnSts;
78     }
79 
80     /// Register target service.
81     rtnSts = SDP_RegisterServiceRecord(sdpHandle_);
82     if (rtnSts != BT_SUCCESS) {
83         LOG_WARN("[A2dpSdpManager]%{public}s SDP_RegisterServiceRecord[result:%{public}d]\n", __func__, rtnSts);
84     }
85     return rtnSts;
86 }
87 
UnregisterService(void) const88 int A2dpSdpManager::UnregisterService(void) const
89 {
90     LOG_INFO("[A2dpSdpManager]%{public}s\n", __func__);
91     int rtnSts;
92 
93     rtnSts = SDP_DestroyServiceRecord(sdpHandle_);
94     if (rtnSts != BT_SUCCESS) {
95         LOG_WARN("[A2dpSdpManager]%{public}s SDP_DestroyServiceRecord[result:%{public}d]\n", __func__, rtnSts);
96         return rtnSts;
97     }
98 
99     rtnSts = SDP_DeregisterServiceRecord(sdpHandle_);
100     if (rtnSts != BT_SUCCESS) {
101         LOG_WARN("[A2dpSdpManager]%{public}s SDP_DeregisterServiceRecord[result:%{public}d]\n", __func__, rtnSts);
102         return rtnSts;
103     }
104 
105     return rtnSts;
106 }
107 
FindSnkService(const BtAddr & addr,void * a2dpInstance,void (* callback)(const BtAddr * addr,const SdpService * serviceArray,uint16_t serviceNum,void * context)) const108 int A2dpSdpManager::FindSnkService(const BtAddr &addr, void *a2dpInstance,
109     void (*callback)(const BtAddr *addr, const SdpService *serviceArray, uint16_t serviceNum, void *context)) const
110 {
111     LOG_INFO("[A2dpSdpManager]%{public}s\n", __func__);
112     void *context = a2dpInstance;
113     BtUuid classid[A2DP_SERVICE_CLASS_ID_LIST_NUMBER];
114 
115     classid[0].type = BT_UUID_16;
116     if (role_ == A2DP_ROLE_SOURCE) {
117         classid[0].uuid16 = A2DP_SINK_SERVICE_CLASS_UUID;
118     } else {
119         classid[0].uuid16 = A2DP_SERVICE_CLASS_UUID;
120     }
121 
122     SdpUuid sdpUUid;
123     sdpUUid.uuidNum = A2DP_SERVICE_CLASS_ID_LIST_NUMBER;
124     sdpUUid.uuid = &classid[0];
125 
126     SdpAttributeIdList attributeIdList;
127     attributeIdList.type = SDP_TYPE_LIST;
128 
129     attributeIdList.attributeIdList.attributeIdNumber = A2DP_SDP_ATTRIBUTE_NUM;
130     attributeIdList.attributeIdList.attributeId[0] = SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
131     attributeIdList.attributeIdList.attributeId[ATTR_NUMBER1] = SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
132     attributeIdList.attributeIdList.attributeId[ATTR_NUMBER2] = SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
133 
134     return SDP_ServiceSearchAttribute(&addr, &sdpUUid, attributeIdList, context, callback);
135 }
136 }  // namespace bluetooth
137 }  // namespace OHOS
138