• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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