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