1 /*
2 * Copyright (C) 2022 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 "hid_host_service.h"
19 #include "hid_host_sdp_client.h"
20 #include "interface_adapter_manager.h"
21
22 namespace OHOS {
23 namespace bluetooth {
HidHostSdpClient(std::string address)24 HidHostSdpClient::HidHostSdpClient(std::string address)
25 {
26 currentAddr_ = address;
27 GetConfigHidSdpInfo();
28 }
29
~HidHostSdpClient()30 HidHostSdpClient::~HidHostSdpClient()
31 {
32 }
33
SdpCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)34 void HidHostSdpClient::SdpCallback(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum, void *context)
35 {
36 int result = HID_HOST_SDP_FAILD;
37 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
38 if (context == nullptr) {
39 HidHostMessage event(HID_HOST_SDP_CMPL_EVT, result);
40 event.dev_ = address;
41 HidHostService::GetService()->PostEvent(event);
42 return;
43 }
44 HidHostSdpClient *sdpClient = static_cast<HidHostSdpClient *>(context);
45 sdpClient->SdpCallback_(addr, serviceAry, serviceNum);
46 }
47
SdpCallback_(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum)48 void HidHostSdpClient::SdpCallback_(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum)
49 {
50 LOG_DEBUG("[HIDH SDP]%{public}s()", __FUNCTION__);
51 int result = HID_HOST_SDP_FAILD;
52 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
53 if (serviceNum > 0) {
54 if (serviceAry[0].serviceName != nullptr) {
55 hidInf_.serviceName = serviceAry[0].serviceName;
56 } else {
57 hidInf_.serviceName = "";
58 }
59 if (serviceAry[0].serviceDescription != nullptr) {
60 hidInf_.serviceDescription = serviceAry[0].serviceDescription;
61 } else {
62 hidInf_.serviceDescription = "";
63 }
64 if (serviceAry[0].providerName != nullptr) {
65 hidInf_.providerName = serviceAry[0].providerName;
66 } else {
67 hidInf_.providerName = "";
68 }
69 if (!ParseHidDescInfo(serviceAry)) {
70 return;
71 }
72 for (uint16_t i = 0; i < serviceAry[0].attributeNumber; i++) {
73 SdpAttribute attribute = serviceAry[0].attribute[i];
74 if (attribute.attributeId == ATTR_ID_HID_COUNTRY_CODE &&
75 attribute.attributeValueLength == HID_HOST_ATTRIBUTE_LENGTH_UINT8) {
76 hidInf_.ctryCode = *static_cast<uint8_t*>(serviceAry[0].attribute[i].attributeValue);
77 } else {
78 LOG_ERROR("[HIDH SDP]%{public}s() attribute length is error!", __FUNCTION__);
79 }
80 }
81 result = HID_HOST_SDP_SUCCESS;
82 isSdpDone_ = true;
83 printHidSdpInfo();
84 SaveHidSdpInfo();
85 }
86 SendSdpComplete(result);
87 }
88
ParseHidDescInfo(const SdpService * serviceAry)89 bool HidHostSdpClient::ParseHidDescInfo(const SdpService *serviceAry)
90 {
91 int result = HID_HOST_SDP_FAILD;
92 for (uint16_t i = 0; i < serviceAry[0].sequenceAttributeNumber; i++) {
93 SdpSequenceAttribute attribute = serviceAry[0].sequenceAttribute[i];
94 uint8_t offset = CheckAttributeValueLengthAvalid(attribute);
95 if (offset != 0) {
96 uint8_t *attributeValue = attribute.attributeValue + offset;
97 uint8_t type = attributeValue[0] >> HID_SDP_DESCRIPTOR_SIZE_BIT;
98 uint8_t size = attributeValue[0] & SDP_SIZE_MASK;
99 uint16_t descLength = 0;
100 if ((type == SDP_DE_TYPE_STRING) && (size == SDP_DE_SIZE_VAR_8)) {
101 descLength = attributeValue[1];
102 offset = SDP_UINT8_LENGTH + 1;
103 } else if ((type == SDP_DE_TYPE_STRING) && (size == SDP_DE_SIZE_VAR_16)) {
104 offset = 1;
105 descLength = (attributeValue[offset] << ONE_BYTE_OFFSET) | attributeValue[offset + 1];
106 offset = SDP_UINT16_LENGTH + 1;
107 } else {
108 LOG_ERROR("[HIDH SDP]%{public}s() error type or size!", __FUNCTION__);
109 SendSdpComplete(result);
110 offset = 0;
111 return false;
112 }
113 if (descLength <= 0) {
114 LOG_ERROR("[HIDH SDP]%{public}s() length is 0!", __FUNCTION__);
115 SendSdpComplete(result);
116 offset = 0;
117 return false;
118 }
119 hidInf_.descInfo = std::make_unique<uint8_t[]>(descLength);
120 if (memcpy_s(hidInf_.descInfo.get(), descLength, attributeValue + offset, descLength) != EOK) {
121 LOG_ERROR("[HIDH SDP]%{public}s() memcpy error", __FUNCTION__);
122 SendSdpComplete(result);
123 return false;
124 }
125 hidInf_.descLength = descLength;
126 return true;
127 }
128 }
129 LOG_ERROR("[HIDH SDP]%{public}s() not find hid descriptor list!", __FUNCTION__);
130 SendSdpComplete(result);
131 return false;
132 }
133
CheckAttributeValueLengthAvalid(SdpSequenceAttribute attribute)134 uint8_t HidHostSdpClient::CheckAttributeValueLengthAvalid(SdpSequenceAttribute attribute)
135 {
136 int result = HID_HOST_SDP_FAILD;
137 uint8_t offset = 0;
138 if (attribute.attributeId == ATTR_ID_HID_DESCRIPTOR_LIST) {
139 if (attribute.attributeValueLength > DESCRIPTOR_LIST_SDP_HEAD_LENGTH) {
140 if ((attribute.attributeValue[0] & SDP_SIZE_MASK) == SDP_DE_SIZE_VAR_8) {
141 offset = DESCRIPTOR_LIST_SDP_OFFSET;
142 } else if ((attribute.attributeValue[0] & SDP_SIZE_MASK) == SDP_DE_SIZE_VAR_16) {
143 offset = DESCRIPTOR_LIST_SDP_OFFSET + 1;
144 } else {
145 LOG_ERROR("[HIDH SDP]%{public}s() first error size!", __FUNCTION__);
146 SendSdpComplete(result);
147 return offset;
148 }
149 } else {
150 LOG_ERROR("[HIDH SDP]%{public}s() attribute length is error!", __FUNCTION__);
151 SendSdpComplete(result);
152 return offset;
153 }
154 } else {
155 LOG_ERROR("[HIDH SDP]%{public}s() attribute id is invalid!", __FUNCTION__);
156 }
157 return offset;
158 }
159
SendSdpComplete(int result)160 void HidHostSdpClient::SendSdpComplete(int result)
161 {
162 HidHostMessage event(HID_HOST_SDP_CMPL_EVT, result);
163 event.dev_ = currentAddr_;
164 HidHostService::GetService()->PostEvent(event);
165 }
166
printHidSdpInfo()167 void HidHostSdpClient::printHidSdpInfo()
168 {
169 LOG_DEBUG("[HIDH SDP]%{public}s()", __FUNCTION__);
170 LOG_DEBUG("[HIDH SDP]supTimeout:0x%{public}x,MaxLatency:0x%{public}x,MinTout:0x%{public}x,hparsVer:0x%{public}x",
171 hidInf_.supTimeout, hidInf_.ssrMaxLatency, hidInf_.ssrMinTout, hidInf_.hparsVer);
172 LOG_DEBUG("[HIDH SDP]relNum:0x%{public}x,ctryCode:0x%{public}x,subClass:0x%{public}x,descLength:%{public}d",
173 hidInf_.relNum, hidInf_.ctryCode, hidInf_.subClass, hidInf_.descLength);
174 LOG_DEBUG("[HIDH SDP]serviceName:%{public}s,serviceDescription:%{public}s,providerName:%{public}s",
175 hidInf_.serviceName.c_str(), hidInf_.serviceDescription.c_str(), hidInf_.providerName.c_str());
176 }
177
SaveHidSdpInfo()178 void HidHostSdpClient::SaveHidSdpInfo()
179 {
180 LOG_DEBUG("[HIDH SDP]%{public}s() enter!", __FUNCTION__);
181 auto classicAdapter = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
182 if (classicAdapter) {
183 bool ret = classicAdapter->SetHidPnpInfo(currentAddr_, pnpInf_.vendorId, pnpInf_.productId, pnpInf_.version);
184 if (!ret) {
185 LOG_ERROR("[HIDH SDP]%{public}s() SetHidPnpInfo is error!", __FUNCTION__);
186 }
187
188 std::vector<uint8_t> descData = std::vector<uint8_t>(
189 hidInf_.descInfo.get(), hidInf_.descInfo.get() + hidInf_.descLength);
190 ret = classicAdapter->SetHidDescInfo(
191 currentAddr_, hidInf_.ctryCode, descData, hidInf_.descLength);
192 if (!ret) {
193 LOG_ERROR("[HIDH SDP]%{public}s() SetHidDescInfo is error!", __FUNCTION__);
194 }
195 }
196 }
197
GetConfigHidSdpInfo()198 void HidHostSdpClient::GetConfigHidSdpInfo()
199 {
200 auto classicAdapter = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
201 int vendorId = 0;
202 int productId = 0;
203 int version = 0;
204 int ctryCode = 0;
205 int descLength = 0;
206 std::vector<uint8_t> descData;
207 if (classicAdapter) {
208 classicAdapter->GetHidPnpInfo(currentAddr_, vendorId, productId, version);
209
210 classicAdapter->GetHidDescInfo(currentAddr_, ctryCode, descData, descLength);
211 if (!descData.empty() && descLength > 0) {
212 hidInf_.descInfo = std::make_unique<uint8_t[]>(descLength);
213 if (memcpy_s(hidInf_.descInfo.get(), descLength, &descData[0], descLength) != EOK) {
214 LOG_ERROR("[HIDH SDP]%{public}s() memcpy error", __FUNCTION__);
215 return;
216 }
217
218 pnpInf_.vendorId = vendorId;
219 pnpInf_.productId = productId;
220 pnpInf_.version = version;
221 hidInf_.ctryCode = ctryCode;
222 hidInf_.descLength = descLength;
223 isSdpDone_ = true;
224 }
225 }
226 LOG_DEBUG("[HIDH SDP]%{public}s() isSdpDone_:%{public}d end !", __FUNCTION__, isSdpDone_);
227 }
228
SdpPnpCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)229 void HidHostSdpClient::SdpPnpCallback(const BtAddr *addr, const SdpService *serviceAry,
230 uint16_t serviceNum, void *context)
231 {
232 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
233 int result = HID_HOST_SDP_FAILD;
234 if (context == nullptr) {
235 HidHostMessage event(HID_HOST_SDP_CMPL_EVT, result);
236 event.dev_ = address;
237 HidHostService::GetService()->PostEvent(event);
238 return;
239 }
240 HidHostSdpClient *sdpClient = static_cast<HidHostSdpClient *>(context);
241 sdpClient->SdpPnpCallback_(addr, serviceAry, serviceNum);
242 }
243
SdpPnpCallback_(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum)244 void HidHostSdpClient::SdpPnpCallback_(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum)
245 {
246 LOG_DEBUG("[HIDH SDP]%{public}s()", __FUNCTION__);
247 std::string address = RawAddress::ConvertToString(addr->addr).GetAddress();
248 int result = HID_HOST_SDP_FAILD;
249
250 if (serviceNum > 0) {
251 for (uint16_t i = 0; i < serviceAry[0].attributeNumber; i++) {
252 SdpAttribute attribute = serviceAry[0].attribute[i];
253 if (attribute.attributeId == SDP_ATTRIBUTE_VENDOR_ID &&
254 attribute.attributeValueLength == HID_HOST_ATTRIBUTE_LENGTH_UINT16) {
255 pnpInf_.vendorId = *static_cast<uint16_t*>(serviceAry[0].attribute[i].attributeValue);
256 LOG_DEBUG("[HIDH SDP]%{public}s():vendorId = 0x%{public}x", __FUNCTION__, pnpInf_.vendorId);
257 }
258
259 if (attribute.attributeId == SDP_ATTRIBUTE_PRODUCT_ID &&
260 attribute.attributeValueLength == HID_HOST_ATTRIBUTE_LENGTH_UINT16) {
261 pnpInf_.productId = *static_cast<uint16_t*>(serviceAry[0].attribute[i].attributeValue);
262 LOG_DEBUG("[HIDH SDP]%{public}s():productId = 0x%{public}x", __FUNCTION__, pnpInf_.productId);
263 }
264
265 if (attribute.attributeId == SDP_ATTRIBUTE_VERSION &&
266 attribute.attributeValueLength == HID_HOST_ATTRIBUTE_LENGTH_UINT16) {
267 pnpInf_.version = *static_cast<uint16_t*>(serviceAry[0].attribute[i].attributeValue);
268 LOG_DEBUG("[HIDH SDP]%{public}s():version = 0x%{public}x", __FUNCTION__, pnpInf_.version);
269 }
270 }
271 result = HID_HOST_SDP_SUCCESS;
272 isPnpSdpDone_ = true;
273 }
274 HidHostMessage event(HID_HOST_SDP_CMPL_EVT, result);
275 event.dev_ = currentAddr_;
276 HidHostService::GetService()->PostEvent(event);
277 }
278
DoDiscovery(const std::string & remoteAddr)279 int HidHostSdpClient::DoDiscovery(const std::string &remoteAddr)
280 {
281 if (isPnpSdpDone_) {
282 return DoHidDiscovery(remoteAddr);
283 }
284 return DoPnpDiscovery(remoteAddr);
285 }
286
DoPnpDiscovery(const std::string & remoteAddr)287 int HidHostSdpClient::DoPnpDiscovery(const std::string &remoteAddr)
288 {
289 BtAddr address;
290 address.type = BT_PUBLIC_DEVICE_ADDRESS;
291 RawAddress rawAddr(remoteAddr);
292 rawAddr.ConvertToUint8(address.addr);
293
294 BtUuid classid[HID_HOST_CLASSID_NUM];
295 classid[0].type = BT_UUID_16;
296 classid[0].uuid16 = HID_HOST_UUID_SERVCLASS_PNP;
297 SdpUuid sdpUUid;
298 sdpUUid.uuidNum = HID_HOST_CLASSID_NUM;
299 sdpUUid.uuid = &classid[0];
300
301 SdpAttributeIdList attributeIdList;
302 attributeIdList.type = SDP_TYPE_RANGE;
303 attributeIdList.attributeIdRange.start = 0x0000;
304 attributeIdList.attributeIdRange.end = 0xFFFF;
305
306 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, SdpPnpCallback);
307 if (ret != BT_SUCCESS) {
308 LOG_ERROR("[HIDH SDP]%{public}s():SDP_ServiceSearchAttribute failed!", __FUNCTION__);
309 }
310 currentAddr_ = remoteAddr;
311 return ret;
312 }
313
DoHidDiscovery(const std::string & remoteAddr)314 int HidHostSdpClient::DoHidDiscovery(const std::string &remoteAddr)
315 {
316 BtAddr address;
317 address.type = BT_PUBLIC_DEVICE_ADDRESS;
318 RawAddress rawAddr(remoteAddr);
319 rawAddr.ConvertToUint8(address.addr);
320
321 BtUuid classid[HID_HOST_CLASSID_NUM];
322 classid[0].type = BT_UUID_16;
323 classid[0].uuid16 = HID_HOST_UUID_SERVCLASS_HID;
324 SdpUuid sdpUUid;
325 sdpUUid.uuidNum = HID_HOST_CLASSID_NUM;
326 sdpUUid.uuid = &classid[0];
327
328 SdpAttributeIdList attributeIdList;
329 attributeIdList.type = SDP_TYPE_LIST;
330 int attributeIdNumber = 0;
331 attributeIdList.attributeIdList.attributeId[attributeIdNumber++] =
332 SDP_ATTRIBUTE_PRIMARY_LANGUAGE_BASE + SDP_ATTRIBUTE_PROVIDER_NAME;
333 attributeIdList.attributeIdList.attributeId[attributeIdNumber++] =
334 SDP_ATTRIBUTE_PRIMARY_LANGUAGE_BASE + SDP_ATTRIBUTE_SERVICE_NAME;
335 attributeIdList.attributeIdList.attributeId[attributeIdNumber++] =
336 SDP_ATTRIBUTE_PRIMARY_LANGUAGE_BASE + SDP_ATTRIBUTE_DESCRIPTOR;
337 attributeIdList.attributeIdList.attributeId[attributeIdNumber++] = ATTR_ID_HID_COUNTRY_CODE;
338 attributeIdList.attributeIdList.attributeId[attributeIdNumber++] = ATTR_ID_HID_DESCRIPTOR_LIST;
339 attributeIdList.attributeIdList.attributeIdNumber = attributeIdNumber;
340
341 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, SdpCallback);
342 if (ret != BT_SUCCESS) {
343 LOG_ERROR("[HIDH SDP]%{public}s():SDP_ServiceSearchAttribute failed!", __FUNCTION__);
344 }
345 return ret;
346 }
347
CheckIsSdpDone()348 bool HidHostSdpClient::CheckIsSdpDone()
349 {
350 return isSdpDone_;
351 }
352
GetRemoteSdpPnpInfo()353 PnpInformation& HidHostSdpClient::GetRemoteSdpPnpInfo()
354 {
355 return pnpInf_;
356 }
357
GetRemoteSdpHidInfo()358 HidInformation& HidHostSdpClient::GetRemoteSdpHidInfo()
359 {
360 return hidInf_;
361 }
362 } // namespace bluetooth
363 } // namespace OHOS
364