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