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 "hfp_ag_sdp_client.h"
17
18 #include <cstring>
19
20 #include "adapter_config.h"
21 #include "hfp_ag_profile_event_sender.h"
22 #include "raw_address.h"
23
24 #include "hfp_ag_service.h"
25
26 namespace OHOS {
27 namespace bluetooth {
28 std::map<std::string, HfpAgRemoteSdpServiceArray> HfpAgSdpClient::g_remoteSdpServiceArrays;
29 std::recursive_mutex HfpAgSdpClient::g_hfpSdpMutex;
30 int hfProfileState_ = -1;
31
~HfpAgSdpClient()32 HfpAgSdpClient::~HfpAgSdpClient()
33 {
34 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
35 auto it = g_remoteSdpServiceArrays.find(currentAddr_);
36 if (it != g_remoteSdpServiceArrays.end()) {
37 DeleteSdpServiceArray(it->second);
38 g_remoteSdpServiceArrays.erase(it);
39 }
40 }
41
SdpCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)42 void HfpAgSdpClient::SdpCallback(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum, void *context)
43 {
44 int msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_FAIL;
45 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
46 if (serviceNum > 0) {
47 CopySdpServiceArray(address, serviceAry, serviceNum);
48 msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_SUCCESS;
49 hfProfileState_ = HFP_AG_HF_FOUND;
50 }
51 int hspState = 1;
52 AdapterConfig::GetInstance()->GetValue(HSP_AG_STATE_SECTION_NAME, HSP_AG_STATE_PROPERY_NAME, hspState);
53 if (hspState == HSP_AG_STATE_BOTH) {
54 HfpAgSdpClient *sdpClient = static_cast<HfpAgSdpClient *>(context);
55 HfpAgService::GetService()->GetDispatcher()->PostTask(
56 std::bind(&HfpAgSdpClient::DoHspHsDiscovery, sdpClient, address));
57 return;
58 }
59 HfpAgProfileEventSender::GetInstance().ProcessSdpDiscoveryResult(address, msgWhat);
60 }
61
DoDiscovery(const std::string & remoteAddr,int role)62 int HfpAgSdpClient::DoDiscovery(const std::string &remoteAddr, int role)
63 {
64 hfProfileState_ = -1;
65 AdapterConfig::GetInstance()->GetValue(HSP_AG_STATE_SECTION_NAME, HSP_AG_STATE_PROPERY_NAME, hspState_);
66 if (hspState_ == HSP_AG_STATE_HSP) {
67 LOG_INFO("[HFP AG] start hsp hs dicovery");
68 return DoHspHsDiscovery(remoteAddr);
69 }
70 BtAddr address;
71 address.type = BT_PUBLIC_DEVICE_ADDRESS;
72 RawAddress rawAddr(remoteAddr);
73 rawAddr.ConvertToUint8(address.addr);
74
75 BtUuid classid[HFP_AG_CLIENT_CLASSID_NUM];
76 classid[0].type = BT_UUID_16;
77 classid[0].uuid16 = HFP_AG_UUID_SERVCLASS_HFP_HF;
78 SdpUuid sdpUUid;
79 sdpUUid.uuidNum = HFP_AG_CLIENT_CLASSID_NUM;
80 sdpUUid.uuid = &classid[0];
81
82 SdpAttributeIdList attributeIdList;
83 attributeIdList.type = SDP_TYPE_LIST;
84 if (HFP_AG_INITIATOR == role) {
85 attributeIdList.attributeIdList.attributeIdNumber = HFP_AG_CLIENT_INITIATOR_ATTR_NUM;
86 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
87 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
88 attributeIdList.attributeIdList.attributeId[PROTOCOL_DESCRIPTOR_LIST_INDEX] =
89 SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
90 attributeIdList.attributeIdList.attributeId[INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX] =
91 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
92 attributeIdList.attributeIdList.attributeId[INITIATOR_SUPPORTED_FEATURES_INDEX] =
93 HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
94 } else {
95 attributeIdList.attributeIdList.attributeIdNumber = HFP_AG_CLIENT_ACCEPTOR_ATTR_NUM;
96 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
97 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
98 attributeIdList.attributeIdList.attributeId[ACCEPTER_PROFILE_DESCRIPTOR_LIST_INDEX] =
99 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
100 attributeIdList.attributeIdList.attributeId[ACCEPTER_SUPPORTED_FEATURES_INDEX] =
101 HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
102 }
103
104 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, &HfpAgSdpClient::SdpCallback);
105 HFP_AG_RETURN_IF_FAIL(ret);
106 currentAddr_ = remoteAddr;
107 return ret;
108 }
109
SdpHspHsCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)110 void HfpAgSdpClient::SdpHspHsCallback(const BtAddr *addr, const SdpService *serviceAry,
111 uint16_t serviceNum, void *context)
112 {
113 int msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_FAIL;
114 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
115 if (serviceNum > 0) {
116 CopySdpServiceArray(address, serviceAry, serviceNum);
117 msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_SUCCESS;
118 if (hfProfileState_ == HFP_AG_HF_FOUND) {
119 hfProfileState_ = HFP_AG_HF_HS_FOUND;
120 } else {
121 hfProfileState_ = HFP_AG_HS_FOUND;
122 }
123 }
124 if (hfProfileState_ != -1) {
125 msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_SUCCESS;
126 HfpAgProfileEventSender::GetInstance().ProcessSdpDiscoveryResult(address, msgWhat);
127 }
128 }
129
DoHspHsDiscovery(const std::string & remoteAddr)130 int HfpAgSdpClient::DoHspHsDiscovery(const std::string &remoteAddr)
131 {
132 BtAddr address;
133 address.type = BT_PUBLIC_DEVICE_ADDRESS;
134 RawAddress rawAddr(remoteAddr);
135 rawAddr.ConvertToUint8(address.addr);
136
137 BtUuid classid[HFP_AG_CLIENT_CLASSID_NUM];
138 classid[0].type = BT_UUID_16;
139 classid[0].uuid16 = HSP_HS_UUID_SERVCLASS;
140 SdpUuid sdpUUid;
141 sdpUUid.uuidNum = HFP_AG_CLIENT_CLASSID_NUM;
142 sdpUUid.uuid = &classid[0];
143
144 SdpAttributeIdList attributeIdList;
145 attributeIdList.type = SDP_TYPE_LIST;
146 attributeIdList.attributeIdList.attributeIdNumber = HFP_AG_CLIENT_INITIATOR_ATTR_NUM;
147 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
148 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
149 attributeIdList.attributeIdList.attributeId[PROTOCOL_DESCRIPTOR_LIST_INDEX] =
150 SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
151 attributeIdList.attributeIdList.attributeId[INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX] =
152 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
153 attributeIdList.attributeIdList.attributeId[INITIATOR_SUPPORTED_FEATURES_INDEX] =
154 HSP_AG_SDP_ATTRIBUTE_REMOTE_AUDIO_VOLUME_CONTROL;
155
156 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, &HfpAgSdpClient::SdpHspHsCallback);
157 currentAddr_ = remoteAddr;
158 return ret;
159 }
160
FindAttributes(const std::string & remoteAddr,int role)161 bool HfpAgSdpClient::FindAttributes(const std::string &remoteAddr, int role)
162 {
163 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
164 auto it = g_remoteSdpServiceArrays.find(remoteAddr);
165 if (it == g_remoteSdpServiceArrays.end()) {
166 LOG_ERROR("[HFP AG]%{public}s():Not found the attributes", __FUNCTION__);
167 return false;
168 }
169
170 HfpAgRemoteSdpInfo info;
171 uint16_t num = 0;
172 if (HFP_AG_INITIATOR == role) {
173 if (!LoopAllProtocolRfcomm(num, it->second, info.remoteServerChannelNumber)) {
174 LOG_ERROR("[HFP AG]%{public}s():Not found peer rfcomm scn", __FUNCTION__);
175 return false;
176 }
177 }
178
179 if (!FindProfileVersion(it->second.services[num].profileDescriptors, info.remoteVersion)) {
180 info.remoteVersion = HFP_AG_HFP_VERSION_1_1;
181 LOG_INFO("[HFP AG]%{public}s():Not found peer HFP version, using default version[1.1]", __FUNCTION__);
182 }
183
184 if (!FindProfileFeatures(it->second.services[num].attributes, info.remoteFeatures)) {
185 info.remoteFeatures = HFP_AG_HF_FEATURES_NONE;
186 LOG_INFO("[HFP AG]%{public}s():Not found peer HFP features, using default features", __FUNCTION__);
187 }
188 if (info.remoteFeatures & HFP_AG_HF_FEATURES_SUPPORT_WBS) {
189 info.remoteCodec = HFP_AG_CODEC_MSBC;
190 } else {
191 info.remoteCodec = HFP_AG_CODEC_CVSD;
192 }
193
194 remoteSdpInfo_ = info;
195 DeleteSdpServiceArray(it->second);
196 g_remoteSdpServiceArrays.erase(it);
197 return true;
198 }
199
GetRemoteSdpInfo() const200 HfpAgRemoteSdpInfo HfpAgSdpClient::GetRemoteSdpInfo() const
201 {
202 return remoteSdpInfo_;
203 }
204
CopySdpServiceArray(const std::string & remoteAddr,const SdpService * serviceAry,uint16_t serviceNum)205 void HfpAgSdpClient::CopySdpServiceArray(
206 const std::string &remoteAddr, const SdpService *serviceAry, uint16_t serviceNum)
207 {
208 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
209 HfpAgRemoteSdpServiceArray array;
210 for (uint16_t n = 0; n < serviceNum; n++) {
211 HfpAgRemoteSdpService service;
212 for (uint16_t i = 0; i < serviceAry[n].descriptorNumber; i++) {
213 SdpProtocolDescriptor descriptor = serviceAry[n].descriptor[i];
214 service.descriptors.push_back(descriptor);
215 }
216 for (uint16_t j = 0; j < serviceAry[n].profileDescriptorNumber; j++) {
217 SdpProfileDescriptor profileDescriptor = serviceAry[n].profileDescriptor[j];
218 service.profileDescriptors.push_back(profileDescriptor);
219 }
220 for (uint16_t k = 0; k < serviceAry[n].attributeNumber; k++) {
221 HfpAgSdpAttribute attribute;
222 attribute.attributeId = serviceAry[n].attribute[k].attributeId;
223 attribute.type = serviceAry[n].attribute[k].type;
224 uint16_t length = serviceAry[n].attribute[k].attributeValueLength;
225 if (length == ATTRIBUTE_LENGTH_UINT16) {
226 attribute.attributeValue = *static_cast<uint16_t*>(serviceAry[n].attribute[k].attributeValue);
227 } else if (length == ATTRIBUTE_LENGTH_UINT8) {
228 attribute.attributeValue = *static_cast<uint8_t*>(serviceAry[n].attribute[k].attributeValue);
229 } else {
230 LOG_ERROR("[HFP AG]%{public}s():Error attribute(n[%hu] k[%hu]) length[%hu]",
231 __FUNCTION__, n, k, length);
232 }
233 service.attributes.push_back(attribute);
234 }
235 array.services.push_back(service);
236 }
237 g_remoteSdpServiceArrays.insert_or_assign(remoteAddr, array);
238 }
239
DeleteSdpServiceArray(HfpAgRemoteSdpServiceArray & array)240 void HfpAgSdpClient::DeleteSdpServiceArray(HfpAgRemoteSdpServiceArray &array)
241 {
242 if (array.services.capacity() == 0) {
243 return;
244 }
245
246 for (uint16_t n = 0; n < array.services.size(); n++) {
247 if (array.services[n].descriptors.capacity() != 0) {
248 std::vector<SdpProtocolDescriptor>().swap(array.services[n].descriptors);
249 }
250 if (array.services[n].profileDescriptors.capacity() != 0) {
251 std::vector<SdpProfileDescriptor>().swap(array.services[n].profileDescriptors);
252 }
253 if (array.services[n].attributes.capacity() != 0) {
254 std::vector<HfpAgSdpAttribute>().swap(array.services[n].attributes);
255 }
256 }
257 std::vector<HfpAgRemoteSdpService>().swap(array.services);
258 }
259
LoopAllProtocolRfcomm(uint16_t & loopNum,const HfpAgRemoteSdpServiceArray & array,uint8_t & scn) const260 bool HfpAgSdpClient::LoopAllProtocolRfcomm(uint16_t &loopNum,
261 const HfpAgRemoteSdpServiceArray &array,
262 uint8_t &scn) const
263 {
264 uint16_t serviceNum = array.services.size();
265 for (uint16_t num = 0; num < serviceNum; num++) {
266 loopNum = num;
267 if (FindProtocolRfcomm(array.services[loopNum].descriptors, scn)) {
268 break;
269 }
270 }
271
272 bool ret = false;
273 if (loopNum < serviceNum) {
274 ret = true;
275 }
276 return ret;
277 }
278
FindProtocolRfcomm(const std::vector<SdpProtocolDescriptor> & protocols,uint8_t & scn)279 bool HfpAgSdpClient::FindProtocolRfcomm(const std::vector<SdpProtocolDescriptor> &protocols, uint8_t &scn)
280 {
281 uint16_t num = 0;
282 while (num < protocols.size()) {
283 if ((protocols[num].protocolUuid.uuid16 == UUID_PROTOCOL_RFCOMM) &&
284 (protocols[num].parameter[0].type == SDP_TYPE_UINT_8)) {
285 scn = static_cast<uint8_t>(protocols[num].parameter[0].value);
286 LOG_INFO("[HFP AG]%{public}s():Found rfcomm scn is [%hhu]", __FUNCTION__, scn);
287 return true;
288 }
289 num++;
290 }
291 return false;
292 }
293
FindProfileVersion(const std::vector<SdpProfileDescriptor> & profiles,uint16_t & version)294 bool HfpAgSdpClient::FindProfileVersion(const std::vector<SdpProfileDescriptor> &profiles, uint16_t &version)
295 {
296 uint16_t num = 0;
297 while (num < profiles.size()) {
298 if (profiles[num].profileUuid.uuid16 == HFP_AG_UUID_SERVCLASS_HFP_HF) {
299 version = profiles[num].versionNumber;
300 LOG_DEBUG("[HFP AG]%{public}s():Found profile version is [%hu]", __FUNCTION__, version);
301 return true;
302 } else if (profiles[num].profileUuid.uuid16 == HSP_HS_UUID_SERVCLASS) {
303 version = profiles[num].versionNumber;
304 LOG_DEBUG("[HSP AG]%{public}s():Found profile version is [%hu]", __FUNCTION__, version);
305 return true;
306 }
307 num++;
308 }
309 return false;
310 }
311
FindProfileFeatures(const std::vector<HfpAgSdpAttribute> & attributes,uint16_t & features)312 bool HfpAgSdpClient::FindProfileFeatures(const std::vector<HfpAgSdpAttribute> &attributes, uint16_t &features)
313 {
314 uint16_t num = 0;
315 while (num < attributes.size()) {
316 if (attributes[num].attributeId == HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES) {
317 features = HFP_AG_HF_FEATURES_BRSF_MASK & attributes[num].attributeValue;
318 LOG_INFO("[HFP AG]%{public}s():Found profile features are [%hu]", __FUNCTION__, features);
319 return true;
320 }
321 num++;
322 }
323 return false;
324 }
325 } // namespace bluetooth
326 } // namespace OHOS