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 <cstring>
17
18 #include "adapter_config.h"
19 #include "hfp_hf_profile_event_sender.h"
20 #include "hfp_hf_sdp_client.h"
21 #include "raw_address.h"
22
23 namespace OHOS {
24 namespace bluetooth {
25 std::map<std::string, HfpHfRemoteSdpServiceArray> HfpHfSdpClient::g_remoteSdpServiceArrays;
26 std::recursive_mutex HfpHfSdpClient::g_hfpSdpMutex;
27 int agProfileState_ = -1;
28
~HfpHfSdpClient()29 HfpHfSdpClient::~HfpHfSdpClient()
30 {
31 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
32 auto it = g_remoteSdpServiceArrays.find(currentAddr_);
33 if (it != g_remoteSdpServiceArrays.end()) {
34 DeleteSdpServiceArray(it->second);
35 g_remoteSdpServiceArrays.erase(it);
36 }
37 }
38
SdpCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)39 void HfpHfSdpClient::SdpCallback(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum, void *context)
40 {
41 int msgWhat = HFP_HF_SDP_DISCOVERY_RESULT_FAIL;
42 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
43 if (serviceNum > 0) {
44 CopySdpServiceArray(address, serviceAry, serviceNum);
45 msgWhat = HFP_HF_SDP_DISCOVERY_RESULT_SUCCESS;
46 agProfileState_ = HFP_HF_HFAG_FOUND;
47 }
48 int hspState = 1;
49 AdapterConfig::GetInstance()->GetValue(HSP_HS_STATE_SECTION_NAME, HSP_HS_STATE_PROPERY_NAME, hspState);
50 if (hspState == HSP_HS_STATE_BOTH) {
51 HfpHfSdpClient *sdpClient = static_cast<HfpHfSdpClient *>(context);
52 HfpHfService::GetService()->GetDispatcher()->PostTask(
53 std::bind(&HfpHfSdpClient::DoHspAgDiscovery, sdpClient, address));
54 return;
55 }
56 HfpHfProfileEventSender::GetInstance().ProcessSdpDiscoveryResult(address, msgWhat);
57 }
58
DoDiscovery(const std::string & remoteAddr,int role)59 int HfpHfSdpClient::DoDiscovery(const std::string &remoteAddr, int role)
60 {
61 agProfileState_ = -1;
62 AdapterConfig::GetInstance()->GetValue(HSP_HS_STATE_SECTION_NAME, HSP_HS_STATE_PROPERY_NAME, hspState_);
63 if (hspState_ == HSP_HS_STATE_HSP) {
64 LOG_INFO("[HFP HF] start hsp ag dicovery");
65 return DoHspAgDiscovery(remoteAddr);
66 }
67
68 BtAddr address;
69 address.type = BT_PUBLIC_DEVICE_ADDRESS;
70 RawAddress rawAddr(remoteAddr);
71 rawAddr.ConvertToUint8(address.addr);
72
73 BtUuid classid[HFP_HF_CLIENT_CLASSID_NUM];
74 classid[0].type = BT_UUID_16;
75 classid[0].uuid16 = HFP_HF_UUID_SERVCLASS_HFP_AG;
76 SdpUuid sdpUUid;
77 sdpUUid.uuidNum = HFP_HF_CLIENT_CLASSID_NUM;
78 sdpUUid.uuid = &classid[0];
79
80 SdpAttributeIdList attributeIdList;
81 attributeIdList.type = SDP_TYPE_LIST;
82 if (HFP_HF_INITIATOR == role) {
83 attributeIdList.attributeIdList.attributeIdNumber = HFP_HF_CLIENT_INITIATOR_ATTR_NUM;
84 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
85 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
86 attributeIdList.attributeIdList.attributeId[PROTOCOL_DESCRIPTOR_LIST_INDEX] =
87 SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
88 attributeIdList.attributeIdList.attributeId[INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX] =
89 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
90 attributeIdList.attributeIdList.attributeId[INITIATOR_SUPPORTED_FEATURES_INDEX] =
91 HFP_HF_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
92 attributeIdList.attributeIdList.attributeId[INITIATOR_DATA_STORES_OR_NETWORK_INDEX] =
93 HFP_HF_SDP_ATTRIBUTE_DATA_STORES_OR_NETWORK;
94 } else {
95 attributeIdList.attributeIdList.attributeIdNumber = HFP_HF_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_HF_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
102 attributeIdList.attributeIdList.attributeId[ACCEPTER_DATA_STORES_OR_NETWORK_INDEX] =
103 HFP_HF_SDP_ATTRIBUTE_DATA_STORES_OR_NETWORK;
104 }
105
106 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, &HfpHfSdpClient::SdpCallback);
107 HFP_HF_RETURN_IF_FAIL(ret);
108 currentAddr_ = remoteAddr;
109 return ret;
110 }
111
SdpHspCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)112 void HfpHfSdpClient::SdpHspCallback(const BtAddr *addr, const SdpService *serviceAry,
113 uint16_t serviceNum, void *context)
114 {
115 int msgWhat = HFP_HF_SDP_DISCOVERY_RESULT_FAIL;
116 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
117 if (serviceNum > 0) {
118 CopySdpServiceArray(address, serviceAry, serviceNum);
119 msgWhat = HFP_HF_SDP_DISCOVERY_RESULT_SUCCESS;
120 if (agProfileState_ == HFP_HF_HFAG_FOUND) {
121 agProfileState_ = HFP_HF_HFAG_HSAG_FOUND;
122 } else {
123 agProfileState_ = HFP_HF_HSAG_FOUND;
124 }
125 }
126 if (agProfileState_ != -1) {
127 msgWhat = HFP_HF_SDP_DISCOVERY_RESULT_SUCCESS;
128 HfpHfProfileEventSender::GetInstance().ProcessSdpDiscoveryResult(address, msgWhat);
129 }
130 }
131
DoHspAgDiscovery(const std::string & remoteAddr)132 int HfpHfSdpClient::DoHspAgDiscovery(const std::string &remoteAddr)
133 {
134 BtAddr address;
135 address.type = BT_PUBLIC_DEVICE_ADDRESS;
136 RawAddress rawAddr(remoteAddr);
137 rawAddr.ConvertToUint8(address.addr);
138
139 BtUuid classid[HFP_HF_CLIENT_CLASSID_NUM];
140 classid[0].type = BT_UUID_16;
141 classid[0].uuid16 = HFP_HF_UUID_SERVCLASS_HSP_AG;
142 SdpUuid sdpUUid;
143 sdpUUid.uuidNum = HFP_HF_CLIENT_CLASSID_NUM;
144 sdpUUid.uuid = &classid[0];
145
146 SdpAttributeIdList attributeIdList;
147 attributeIdList.type = SDP_TYPE_LIST;
148 attributeIdList.attributeIdList.attributeIdNumber = HFP_HF_CLIENT_INITIATOR_ATTR_NUM;
149 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
150 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
151 attributeIdList.attributeIdList.attributeId[PROTOCOL_DESCRIPTOR_LIST_INDEX] =
152 SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
153 attributeIdList.attributeIdList.attributeId[INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX] =
154 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
155 attributeIdList.attributeIdList.attributeId[INITIATOR_SUPPORTED_FEATURES_INDEX] =
156 HFP_HF_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
157
158 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, &HfpHfSdpClient::SdpHspCallback);
159 HFP_HF_RETURN_IF_FAIL(ret);
160 currentAddr_ = remoteAddr;
161 return ret;
162 }
163
FindAttributes(const std::string & remoteAddr,int role)164 bool HfpHfSdpClient::FindAttributes(const std::string &remoteAddr, int role)
165 {
166 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
167 auto it = g_remoteSdpServiceArrays.find(remoteAddr);
168 if (it == g_remoteSdpServiceArrays.end()) {
169 LOG_ERROR("[HFP HF]%{public}s():Not found the attributes", __FUNCTION__);
170 return false;
171 }
172
173 HfpHfRemoteSdpInfo info;
174 uint16_t num = 0;
175 if (HFP_HF_INITIATOR == role) {
176 if (!LoopAllProtocolRfcomm(num, it->second, info.remoteServerChannelNumber)) {
177 LOG_ERROR("[HFP HF]%{public}s():Not found peer rfcomm scn", __FUNCTION__);
178 return false;
179 }
180 }
181
182 if (!FindProfileVersion(it->second.services[num].profileDescriptors, info.remoteVersion)) {
183 info.remoteVersion = HFP_HF_HFP_VERSION_1_1;
184 LOG_DEBUG("[HFP HF]%{public}s():Not found peer HFP version, using default version[1.1]", __FUNCTION__);
185 }
186
187 if (!FindProfileFeatures(it->second.services[num].attributes, info.remoteFeatures)) {
188 info.remoteFeatures = HFP_HF_AG_FEATURES_NONE;
189 LOG_DEBUG("[HFP HF]%{public}s():Not found peer HFP features, using default features", __FUNCTION__);
190 }
191 SelectProfileFeatures(info.remoteFeatures, info.remoteCodec);
192
193 if (!FindProfileNetwork(it->second.services[num].attributes, info.remoteNetwork)) {
194 info.remoteNetwork = HFP_HF_NETWORK_VALUE_NONE;
195 LOG_DEBUG("[HFP HF]%{public}s():Not found peer network", __FUNCTION__);
196 } else {
197 if (info.remoteNetwork == HFP_HF_NETWORK_VALUE_HAVE) {
198 info.remoteFeatures |= HFP_HF_AG_FEATURES_REJECT_CALL;
199 }
200 }
201
202 remoteSdpInfo_ = info;
203 DeleteSdpServiceArray(it->second);
204 g_remoteSdpServiceArrays.erase(it);
205 return true;
206 }
207
GetRemoteSdpInfo() const208 HfpHfRemoteSdpInfo HfpHfSdpClient::GetRemoteSdpInfo() const
209 {
210 return remoteSdpInfo_;
211 }
212
CopySdpServiceArray(const std::string & remoteAddr,const SdpService * serviceAry,uint16_t serviceNum)213 void HfpHfSdpClient::CopySdpServiceArray(
214 const std::string &remoteAddr, const SdpService *serviceAry, uint16_t serviceNum)
215 {
216 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
217 HfpHfRemoteSdpServiceArray array;
218 for (uint16_t n = 0; n < serviceNum; n++) {
219 HfpHfRemoteSdpService service;
220 for (uint16_t i = 0; i < serviceAry[n].descriptorNumber; i++) {
221 SdpProtocolDescriptor descriptor = serviceAry[n].descriptor[i];
222 service.descriptors.push_back(descriptor);
223 }
224 for (uint16_t j = 0; j < serviceAry[n].profileDescriptorNumber; j++) {
225 SdpProfileDescriptor profileDescriptor = serviceAry[n].profileDescriptor[j];
226 service.profileDescriptors.push_back(profileDescriptor);
227 }
228 for (uint16_t k = 0; k < serviceAry[n].attributeNumber; k++) {
229 HfpHfSdpAttribute attribute;
230 attribute.attributeId = serviceAry[n].attribute[k].attributeId;
231 attribute.type = serviceAry[n].attribute[k].type;
232 uint16_t length = serviceAry[n].attribute[k].attributeValueLength;
233 if (length == ATTRIBUTE_LENGTH_UINT16) {
234 attribute.attributeValue = *static_cast<uint16_t*>(serviceAry[n].attribute[k].attributeValue);
235 } else if (length == ATTRIBUTE_LENGTH_UINT8) {
236 attribute.attributeValue = *static_cast<uint8_t*>(serviceAry[n].attribute[k].attributeValue);
237 } else {
238 LOG_ERROR("[HFP HF]%{public}s():Error attribute(n[%hu] k[%hu]) length[%hu]",
239 __FUNCTION__, n, k, length);
240 }
241 service.attributes.push_back(attribute);
242 }
243 array.services.push_back(service);
244 }
245 g_remoteSdpServiceArrays.insert_or_assign(remoteAddr, array);
246 }
247
DeleteSdpServiceArray(HfpHfRemoteSdpServiceArray & array)248 void HfpHfSdpClient::DeleteSdpServiceArray(HfpHfRemoteSdpServiceArray &array)
249 {
250 if (array.services.capacity() == 0) {
251 return;
252 }
253
254 for (uint16_t n = 0; n < array.services.size(); n++) {
255 if (array.services[n].descriptors.capacity() != 0) {
256 std::vector<SdpProtocolDescriptor>().swap(array.services[n].descriptors);
257 }
258 if (array.services[n].profileDescriptors.capacity() != 0) {
259 std::vector<SdpProfileDescriptor>().swap(array.services[n].profileDescriptors);
260 }
261 if (array.services[n].attributes.capacity() != 0) {
262 std::vector<HfpHfSdpAttribute>().swap(array.services[n].attributes);
263 }
264 }
265 std::vector<HfpHfRemoteSdpService>().swap(array.services);
266 }
267
LoopAllProtocolRfcomm(uint16_t & loopNum,const HfpHfRemoteSdpServiceArray & array,uint8_t & scn) const268 bool HfpHfSdpClient::LoopAllProtocolRfcomm(uint16_t &loopNum,
269 const HfpHfRemoteSdpServiceArray &array,
270 uint8_t &scn) const
271 {
272 uint16_t serviceNum = array.services.size();
273 for (uint16_t num = 0; num < serviceNum; num++) {
274 loopNum = num;
275 if (FindProtocolRfcomm(array.services[loopNum].descriptors, scn)) {
276 break;
277 }
278 }
279
280 bool ret = false;
281 if (loopNum < serviceNum) {
282 ret = true;
283 }
284 return ret;
285 }
286
FindProtocolRfcomm(const std::vector<SdpProtocolDescriptor> & protocols,uint8_t & scn)287 bool HfpHfSdpClient::FindProtocolRfcomm(const std::vector<SdpProtocolDescriptor> &protocols, uint8_t &scn)
288 {
289 uint16_t num = 0;
290 while (num < protocols.size()) {
291 if ((protocols[num].protocolUuid.uuid16 == UUID_PROTOCOL_RFCOMM) &&
292 (protocols[num].parameter[0].type == SDP_TYPE_UINT_8)) {
293 scn = static_cast<uint8_t>(protocols[num].parameter[0].value);
294 LOG_DEBUG("[HFP HF]%{public}s():Found rfcomm scn is [%hhu]", __FUNCTION__, scn);
295 return true;
296 }
297 num++;
298 }
299 return false;
300 }
301
FindProfileVersion(const std::vector<SdpProfileDescriptor> & profiles,uint16_t & version)302 bool HfpHfSdpClient::FindProfileVersion(const std::vector<SdpProfileDescriptor> &profiles, uint16_t &version)
303 {
304 uint16_t num = 0;
305 while (num < profiles.size()) {
306 if (profiles[num].profileUuid.uuid16 == HFP_HF_UUID_SERVCLASS_HFP_AG) {
307 version = profiles[num].versionNumber;
308 LOG_DEBUG("[HFP HF]%{public}s():Found profile version is [%hu]", __FUNCTION__, version);
309 return true;
310 } else if (profiles[num].profileUuid.uuid16 == HFP_HF_UUID_SERVCLASS_HSP_AG) {
311 version = profiles[num].versionNumber;
312 LOG_DEBUG("[HSP HF]%{public}s():Found profile version is [%hu]", __FUNCTION__, version);
313 return true;
314 }
315 num++;
316 }
317 return false;
318 }
319
FindProfileFeatures(const std::vector<HfpHfSdpAttribute> & attributes,uint16_t & features)320 bool HfpHfSdpClient::FindProfileFeatures(const std::vector<HfpHfSdpAttribute> &attributes, uint16_t &features)
321 {
322 uint16_t num = 0;
323 while (num < attributes.size()) {
324 if (attributes[num].attributeId == HFP_HF_SDP_ATTRIBUTE_SUPPORTED_FEATURES) {
325 features = HFP_HF_AG_FEATURES_BRSF_MASK & attributes[num].attributeValue;
326 LOG_DEBUG("[HFP HF]%{public}s():Found profile features are [%hu]", __FUNCTION__, features);
327 return true;
328 }
329 num++;
330 }
331 return false;
332 }
333
FindProfileNetwork(const std::vector<HfpHfSdpAttribute> & attributes,uint8_t & network)334 bool HfpHfSdpClient::FindProfileNetwork(const std::vector<HfpHfSdpAttribute> &attributes, uint8_t &network)
335 {
336 uint16_t num = 0;
337 while (num < attributes.size()) {
338 if (attributes[num].attributeId == HFP_HF_SDP_ATTRIBUTE_DATA_STORES_OR_NETWORK) {
339 network = static_cast<uint8_t>(attributes[num].attributeValue);
340 LOG_DEBUG("[HFP HF]%{public}s():Found profile features are [%hhu]", __FUNCTION__, network);
341 return true;
342 }
343 num++;
344 }
345 return false;
346 }
347
SelectProfileFeatures(uint16_t & features,int & codec)348 void HfpHfSdpClient::SelectProfileFeatures(uint16_t &features, int &codec)
349 {
350 if (features & HFP_HF_AG_FEATURES_SUPPORT_WBS) {
351 codec = HFP_HF_CODEC_MSBC;
352 // SDP and BRSF WBS bit are different, correct it if set
353 features &= HFP_HF_AG_FEATURES_SUPPORT_WBS;
354 features |= HFP_HF_AG_FEATURES_CODEC_NEGOTIATION;
355 } else {
356 codec = HFP_HF_CODEC_CVSD;
357 }
358 }
359 } // namespace bluetooth
360 } // namespace OHOS