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