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 return;
55 }
56 HfpAgProfileEventSender::GetInstance().ProcessSdpDiscoveryResult(address, msgWhat);
57 }
58
DoDiscovery(const std::string & remoteAddr,int role)59 int HfpAgSdpClient::DoDiscovery(const std::string &remoteAddr, int role)
60 {
61 hfProfileState_ = -1;
62 int ret = 0;
63
64 AdapterConfig::GetInstance()->GetValue(HSP_AG_STATE_SECTION_NAME, HSP_AG_STATE_PROPERY_NAME, hspState_);
65 if (hspState_ != HSP_AG_STATE_HSP) {
66 ret = DoHfpDiscovery(remoteAddr, role);
67 LOG_INFO("[HFP AG] start hfp dicovery :%{public}d", ret);
68 }
69 if (hspState_ != HSP_AG_STATE_NONE) {
70 ret = DoHspHsDiscovery(remoteAddr);
71 LOG_INFO("[HFP AG] start hsp hs dicovery :%{public}d", ret);
72 }
73 return ret;
74 }
75
SdpHspHsCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)76 void HfpAgSdpClient::SdpHspHsCallback(const BtAddr *addr, const SdpService *serviceAry,
77 uint16_t serviceNum, void *context)
78 {
79 int msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_FAIL;
80 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
81 if (serviceNum > 0) {
82 CopySdpServiceArray(address, serviceAry, serviceNum);
83 msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_SUCCESS;
84 if (hfProfileState_ == HFP_AG_HF_FOUND) {
85 hfProfileState_ = HFP_AG_HF_HS_FOUND;
86 } else {
87 hfProfileState_ = HFP_AG_HS_FOUND;
88 }
89 }
90 if (hfProfileState_ != -1) {
91 msgWhat = HFP_AG_SDP_DISCOVERY_RESULT_SUCCESS;
92 }
93 HfpAgProfileEventSender::GetInstance().ProcessSdpDiscoveryResult(address, msgWhat);
94 }
95
DoHfpDiscovery(const std::string & remoteAddr,int role)96 int HfpAgSdpClient::DoHfpDiscovery(const std::string &remoteAddr, int role)
97 {
98 BtAddr address;
99 address.type = BT_PUBLIC_DEVICE_ADDRESS;
100 RawAddress rawAddr(remoteAddr);
101 rawAddr.ConvertToUint8(address.addr);
102
103 BtUuid classid[HFP_AG_CLIENT_CLASSID_NUM];
104 classid[0].type = BT_UUID_16;
105 classid[0].uuid16 = HFP_AG_UUID_SERVCLASS_HFP_HF;
106 SdpUuid sdpUUid;
107 sdpUUid.uuidNum = HFP_AG_CLIENT_CLASSID_NUM;
108 sdpUUid.uuid = &classid[0];
109
110 SdpAttributeIdList attributeIdList;
111 attributeIdList.type = SDP_TYPE_LIST;
112 if (role == HFP_AG_INITIATOR) {
113 attributeIdList.attributeIdList.attributeIdNumber = HFP_AG_CLIENT_INITIATOR_ATTR_NUM;
114 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
115 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
116 attributeIdList.attributeIdList.attributeId[PROTOCOL_DESCRIPTOR_LIST_INDEX] =
117 SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
118 attributeIdList.attributeIdList.attributeId[INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX] =
119 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
120 attributeIdList.attributeIdList.attributeId[INITIATOR_SUPPORTED_FEATURES_INDEX] =
121 HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
122 } else {
123 attributeIdList.attributeIdList.attributeIdNumber = HFP_AG_CLIENT_ACCEPTOR_ATTR_NUM;
124 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
125 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
126 attributeIdList.attributeIdList.attributeId[ACCEPTER_PROFILE_DESCRIPTOR_LIST_INDEX] =
127 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
128 attributeIdList.attributeIdList.attributeId[ACCEPTER_SUPPORTED_FEATURES_INDEX] =
129 HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
130 }
131
132 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, &HfpAgSdpClient::SdpCallback);
133 HFP_AG_RETURN_IF_FAIL(ret);
134 currentAddr_ = remoteAddr;
135 return ret;
136 }
137
DoHspHsDiscovery(const std::string & remoteAddr)138 int HfpAgSdpClient::DoHspHsDiscovery(const std::string &remoteAddr)
139 {
140 BtAddr address;
141 address.type = BT_PUBLIC_DEVICE_ADDRESS;
142 RawAddress rawAddr(remoteAddr);
143 rawAddr.ConvertToUint8(address.addr);
144
145 BtUuid classid[HFP_AG_CLIENT_CLASSID_NUM];
146 classid[0].type = BT_UUID_16;
147 classid[0].uuid16 = HSP_HS_UUID_SERVCLASS;
148 SdpUuid sdpUUid;
149 sdpUUid.uuidNum = HFP_AG_CLIENT_CLASSID_NUM;
150 sdpUUid.uuid = &classid[0];
151
152 SdpAttributeIdList attributeIdList;
153 attributeIdList.type = SDP_TYPE_LIST;
154 attributeIdList.attributeIdList.attributeIdNumber = HFP_AG_CLIENT_INITIATOR_ATTR_NUM;
155 attributeIdList.attributeIdList.attributeId[SERVICE_CLASS_ID_LIST_INDEX] =
156 SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
157 attributeIdList.attributeIdList.attributeId[PROTOCOL_DESCRIPTOR_LIST_INDEX] =
158 SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
159 attributeIdList.attributeIdList.attributeId[INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX] =
160 SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
161 attributeIdList.attributeIdList.attributeId[INITIATOR_SUPPORTED_FEATURES_INDEX] =
162 HSP_AG_SDP_ATTRIBUTE_REMOTE_AUDIO_VOLUME_CONTROL;
163
164 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, &HfpAgSdpClient::SdpHspHsCallback);
165 currentAddr_ = remoteAddr;
166 return ret;
167 }
168
FindAttributes(const std::string & remoteAddr,int role)169 bool HfpAgSdpClient::FindAttributes(const std::string &remoteAddr, int role)
170 {
171 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
172 auto it = g_remoteSdpServiceArrays.find(remoteAddr);
173 if (it == g_remoteSdpServiceArrays.end()) {
174 LOG_ERROR("[HFP AG]%{public}s():Not found the attributes", __FUNCTION__);
175 return false;
176 }
177
178 HfpAgRemoteSdpInfo info;
179 uint16_t num = 0;
180 if (HFP_AG_INITIATOR == role) {
181 if (!LoopAllProtocolRfcomm(num, it->second, info.remoteServerChannelNumber)) {
182 LOG_ERROR("[HFP AG]%{public}s():Not found peer rfcomm scn", __FUNCTION__);
183 return false;
184 }
185 }
186
187 if (!FindProfileVersion(it->second.services[num].profileDescriptors, info.remoteVersion)) {
188 info.remoteVersion = HFP_AG_HFP_VERSION_1_1;
189 LOG_INFO("[HFP AG]%{public}s():Not found peer HFP version, using default version[1.1]", __FUNCTION__);
190 }
191
192 if (!FindProfileFeatures(it->second.services[num].attributes, info.remoteFeatures)) {
193 info.remoteFeatures = HFP_AG_HF_FEATURES_NONE;
194 LOG_INFO("[HFP AG]%{public}s():Not found peer HFP features, using default features", __FUNCTION__);
195 }
196 if (info.remoteFeatures & HFP_AG_HF_FEATURES_SUPPORT_WBS) {
197 info.remoteCodec = HFP_AG_CODEC_MSBC;
198 } else {
199 info.remoteCodec = HFP_AG_CODEC_CVSD;
200 }
201
202 remoteSdpInfo_ = info;
203 DeleteSdpServiceArray(it->second);
204 g_remoteSdpServiceArrays.erase(it);
205 return true;
206 }
207
GetRemoteSdpInfo() const208 HfpAgRemoteSdpInfo HfpAgSdpClient::GetRemoteSdpInfo() const
209 {
210 return remoteSdpInfo_;
211 }
212
CopySdpServiceArray(const std::string & remoteAddr,const SdpService * serviceAry,uint16_t serviceNum)213 void HfpAgSdpClient::CopySdpServiceArray(
214 const std::string &remoteAddr, const SdpService *serviceAry, uint16_t serviceNum)
215 {
216 std::lock_guard<std::recursive_mutex> lk(g_hfpSdpMutex);
217 HfpAgRemoteSdpServiceArray array;
218 for (uint16_t n = 0; n < serviceNum; n++) {
219 HfpAgRemoteSdpService 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 HfpAgSdpAttribute 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 AG]%{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(HfpAgRemoteSdpServiceArray & array)248 void HfpAgSdpClient::DeleteSdpServiceArray(HfpAgRemoteSdpServiceArray &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<HfpAgSdpAttribute>().swap(array.services[n].attributes);
263 }
264 }
265 std::vector<HfpAgRemoteSdpService>().swap(array.services);
266 }
267
LoopAllProtocolRfcomm(uint16_t & loopNum,const HfpAgRemoteSdpServiceArray & array,uint8_t & scn) const268 bool HfpAgSdpClient::LoopAllProtocolRfcomm(uint16_t &loopNum,
269 const HfpAgRemoteSdpServiceArray &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 HfpAgSdpClient::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_INFO("[HFP AG]%{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 HfpAgSdpClient::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_AG_UUID_SERVCLASS_HFP_HF) {
307 version = profiles[num].versionNumber;
308 LOG_DEBUG("[HFP AG]%{public}s():Found profile version is [%hu]", __FUNCTION__, version);
309 return true;
310 } else if (profiles[num].profileUuid.uuid16 == HSP_HS_UUID_SERVCLASS) {
311 version = profiles[num].versionNumber;
312 LOG_DEBUG("[HSP AG]%{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<HfpAgSdpAttribute> & attributes,uint16_t & features)320 bool HfpAgSdpClient::FindProfileFeatures(const std::vector<HfpAgSdpAttribute> &attributes, uint16_t &features)
321 {
322 uint16_t num = 0;
323 while (num < attributes.size()) {
324 if (attributes[num].attributeId == HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES) {
325 features = HFP_AG_HF_FEATURES_BRSF_MASK & attributes[num].attributeValue;
326 LOG_INFO("[HFP AG]%{public}s():Found profile features are [%hu]", __FUNCTION__, features);
327 return true;
328 }
329 num++;
330 }
331 return false;
332 }
333 } // namespace bluetooth
334 } // namespace OHOS
335