1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 #include "usb_accessory_manager.h"
16
17 #include <iostream>
18 #include <functional>
19 #include <chrono>
20 #include <sstream>
21 #include <iomanip>
22 #include <hdf_base.h>
23
24 #include "common_event_data.h"
25 #include "common_event_manager.h"
26 #include "common_event_support.h"
27 #include "hisysevent.h"
28 #include "usb_errors.h"
29 #include "usb_srv_support.h"
30 #include "usbd_type.h"
31 #include "cJSON.h"
32 using namespace OHOS::AAFwk;
33 using namespace OHOS::EventFwk;
34 using namespace OHOS::HiviewDFX;
35 using namespace OHOS::HDI::Usb::V1_0;
36 using namespace OHOS::HDI::Usb::V1_1;
37
38 namespace OHOS {
39 namespace USB {
40 constexpr int32_t ACCESSORY_INFO_SIZE = 5;
41 constexpr uint32_t ACCESSORY_EXTRA_INDEX = 5;
42 constexpr uint32_t FUN_ACCESSORY = 1 << 11;
43 constexpr int32_t NUM_OF_SERAIL_BIT = 16;
44 constexpr uint32_t DELAY_ACC_INTERVAL = 10 * 1000;
45 constexpr uint32_t ANTI_SHAKE_INTERVAL = 1 * 1000;
46 constexpr int32_t ACCESSORY_IS_BUSY = -16;
47 const int INDEX_FIRST = 0;
48 const int INDEX_SECOND = 1;
49 const int INDEX_THIRD = 2;
50 const int INDEX_FORTH = 3;
51 const int INDEX_FIFTH = 4;
52 const uint32_t OFFSET2 = 2;
53 const uint32_t OFFSET4 = 4;
54 const uint32_t OFFSET6 = 6;
55 const std::string BASE_64_CHARS =
56 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
57 "abcdefghijklmnopqrstuvwxyz"
58 "0123456789+/";
59
60 // LCOV_EXCL_START
UsbAccessoryManager()61 UsbAccessoryManager::UsbAccessoryManager()
62 {
63 USB_HILOGI(MODULE_USB_SERVICE, "UsbAccessoryManager::Init start");
64 usbdImpl_ = OHOS::HDI::Usb::V1_1::IUsbInterface::Get();
65 if (usbdImpl_ == nullptr) {
66 USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::Get inteface failed");
67 }
68 uint32_t ret = antiShakeDelayTimer_.Setup();
69 if (ret != UEC_OK) {
70 USB_HILOGE(MODULE_USB_SERVICE, "set up antiShakeDelayTimer_ failed %{public}u", ret);
71 return;
72 }
73 ret = accDelayTimer_.Setup();
74 if (ret != UEC_OK) {
75 USB_HILOGE(MODULE_USB_SERVICE, "set up accDelayTimer_ failed %{public}u", ret);
76 return;
77 }
78 }
79
~UsbAccessoryManager()80 UsbAccessoryManager::~UsbAccessoryManager()
81 {
82 accDelayTimer_.Shutdown();
83 antiShakeDelayTimer_.Shutdown();
84 }
85
SetUsbd(const sptr<OHOS::HDI::Usb::V1_1::IUsbInterface> usbd)86 int32_t UsbAccessoryManager::SetUsbd(const sptr<OHOS::HDI::Usb::V1_1::IUsbInterface> usbd)
87 {
88 if (usbd == nullptr) {
89 USB_HILOGE(MODULE_USB_SERVICE, "UsbAccessoryManager usbd is nullptr");
90 return UEC_SERVICE_INVALID_VALUE;
91 }
92 usbdImpl_ = usbd;
93 return UEC_OK;
94 }
95
GetAccessoryList(const std::string & bundleName,std::vector<USBAccessory> & accessoryList)96 void UsbAccessoryManager::GetAccessoryList(const std::string &bundleName,
97 std::vector<USBAccessory> &accessoryList)
98 {
99 if (accStatus_ == ACC_START) {
100 USBAccessory access = this->accessory;
101 access.SetSerialNumber(bundleName + this->accessory.GetSerialNumber());
102 accessoryList.push_back(access);
103 }
104 return;
105 }
106
OpenAccessory(int32_t & fd)107 int32_t UsbAccessoryManager::OpenAccessory(int32_t &fd)
108 {
109 if (usbdImpl_ == nullptr) {
110 USB_HILOGE(MODULE_USB_INNERKIT, "UsbAccessoryManager usbdImpl_ is nullptr.");
111 return UEC_SERVICE_INVALID_VALUE;
112 }
113 int32_t ret = usbdImpl_->OpenAccessory(fd);
114 if (ret == UEC_OK) {
115 accFd_ = fd;
116 return ret;
117 } else if (ret == ACCESSORY_IS_BUSY) {
118 return UEC_SERVICE_ACCESSORY_REOPEN;
119 }
120 return UEC_SERVICE_ACCESSORY_OPEN_NATIVE_NODE_FAILED;
121 }
122
CloseAccessory(int32_t fd)123 int32_t UsbAccessoryManager::CloseAccessory(int32_t fd)
124 {
125 if (usbdImpl_ == nullptr) {
126 USB_HILOGE(MODULE_USB_INNERKIT, "UsbAccessoryManager usbdImpl_ is nullptr.");
127 return UEC_SERVICE_INVALID_VALUE;
128 }
129 int32_t ret = usbdImpl_->CloseAccessory(accFd_);
130 if (ret != UEC_OK) {
131 USB_HILOGE(MODULE_USB_INNERKIT, "%{public}s, close ret: %{public}d, fd: %{public}d.", __func__, ret, fd);
132 return ret;
133 }
134 accFd_ = 0;
135 return ret;
136 }
137
ProcessAccessoryStart(int32_t curFunc,int32_t curAccStatus)138 int32_t UsbAccessoryManager::ProcessAccessoryStart(int32_t curFunc, int32_t curAccStatus)
139 {
140 uint32_t curFuncUint = static_cast<uint32_t>(curFunc);
141 if ((curFuncUint & FUN_ACCESSORY) != 0 && accStatus_ != ACC_START) {
142 this->accStatus_ = ACC_START;
143 std::vector<std::string> accessorys;
144 usbdImpl_->GetAccessoryInfo(accessorys);
145 this->accessory.SetAccessory(accessorys);
146 std::string hashSerial = SerialValueHash(this->accessory.GetSerialNumber());
147 this->accessory.SetSerialNumber(hashSerial);
148 Want want;
149 want.SetAction(CommonEventSupport::COMMON_EVENT_USB_ACCESSORY_ATTACHED);
150 CommonEventData data(want);
151 data.SetData(this->accessory.GetJsonString().c_str());
152 CommonEventPublishInfo publishInfo;
153 USB_HILOGI(MODULE_SERVICE, "send accessory attached broadcast device:%{public}s",
154 this->accessory.GetJsonString().c_str());
155 return CommonEventManager::PublishCommonEvent(data, publishInfo);
156 } else if ((curFuncUint & FUN_ACCESSORY) == 0 && curAccStatus == ACC_CONFIGURING) {
157 int32_t ret = usbdImpl_->SetCurrentFunctions(FUN_ACCESSORY);
158 if (ret != UEC_OK) {
159 USB_HILOGE(MODULE_SERVICE, "curFunc %{public}d curAccStatus:%{public}u, set func ret: %{public}d",
160 curFuncUint, curAccStatus, ret);
161 return ret;
162 }
163 lastDeviceFunc_ = static_cast<int32_t>(curFuncUint);
164 auto task = [&]() {
165 this->accStatus_ = ACC_STOP;
166 int32_t ret = usbdImpl_ ->SetCurrentFunctions(this->lastDeviceFunc_);
167 if (ret != UEC_OK) {
168 USB_HILOGW(MODULE_SERVICE, "set old func: %{public}d ret: %{public}d", this->lastDeviceFunc_, ret);
169 }
170 return;
171 };
172 accDelayTimerId_ = accDelayTimer_.Register(task, DELAY_ACC_INTERVAL, true);
173 this->accStatus_ = ACC_CONFIGURING;
174 } else {
175 USB_HILOGD(MODULE_SERVICE, "curFunc %{public}u curAccStatus:%{public}d not necessary",
176 curFuncUint, curAccStatus);
177 }
178 return UEC_OK;
179 }
180
ProcessAccessoryStop(int32_t curFunc,int32_t curAccStatus)181 int32_t UsbAccessoryManager::ProcessAccessoryStop(int32_t curFunc, int32_t curAccStatus)
182 {
183 uint32_t curFuncUint = static_cast<uint32_t>(curFunc);
184 if ((curFuncUint & FUN_ACCESSORY) != 0 && accStatus_ == ACC_START) {
185 accStatus_ = ACC_STOP;
186 int32_t ret = usbdImpl_ ->SetCurrentFunctions(lastDeviceFunc_);
187 if (ret != UEC_OK) {
188 USB_HILOGW(MODULE_SERVICE, "setFunc %{public}d curAccStatus:%{public}d, set func ret: %{public}d",
189 lastDeviceFunc_, curAccStatus, ret);
190 }
191 curDeviceFunc_ = lastDeviceFunc_;
192 Want want;
193 want.SetAction(CommonEventSupport::COMMON_EVENT_USB_ACCESSORY_DETACHED);
194 CommonEventData data(want);
195 data.SetData(this->accessory.GetJsonString().c_str());
196 CommonEventPublishInfo publishInfo;
197 USB_HILOGI(MODULE_SERVICE, "send accessory detached broadcast device:%{public}s",
198 this->accessory.GetJsonString().c_str());
199 return CommonEventManager::PublishCommonEvent(data, publishInfo);
200 } else {
201 USB_HILOGD(MODULE_SERVICE, "curFunc %{public}u curAccStatus:%{public}d not necessary",
202 curFuncUint, curAccStatus);
203 }
204 return UEC_OK;
205 }
206
ProcessAccessorySend()207 int32_t UsbAccessoryManager::ProcessAccessorySend()
208 {
209 this->accStatus_ = ACC_SEND;
210 std::vector<std::string> accessorys;
211 usbdImpl_->GetAccessoryInfo(accessorys);
212 this->accessory.SetAccessory(accessorys);
213 std::string extraInfo;
214 if (accessorys.size() > ACCESSORY_INFO_SIZE &&
215 ACCESSORY_EXTRA_INDEX < accessorys.size() && !accessorys[ACCESSORY_EXTRA_INDEX].empty()) {
216 if (base64Map_.empty()) {
217 InitBase64Map();
218 }
219 std::string extraEcode = accessorys[ACCESSORY_EXTRA_INDEX];
220 USB_HILOGE(MODULE_USB_SERVICE, "extraEcode, length: %{public}zu, extraData: %{public}s",
221 extraEcode.length(), extraEcode.c_str());
222 std::vector<uint8_t> extraData = Base64Decode(extraEcode);
223 cJSON *root = cJSON_CreateArray();
224 for (uint8_t value : extraData) {
225 cJSON_AddItemToArray(root, cJSON_CreateNumber(value));
226 }
227 char *pExtraJson = cJSON_PrintUnformatted(root);
228 cJSON_Delete(root);
229 if (!pExtraJson) {
230 USB_HILOGE(MODULE_USB_SERVICE, "print json error.");
231 return UEC_SERVICE_INVALID_VALUE;
232 }
233 extraInfo = pExtraJson;
234 cJSON_free(pExtraJson);
235 pExtraJson = nullptr;
236 }
237
238 USBAccessory extraAcces;
239 extraAcces.SetDescription(extraInfo);
240 Want want;
241 want.SetAction(CommonEventSupport::COMMON_EVENT_USB_ACCESSORY_ATTACHED);
242 CommonEventData data(want);
243 data.SetData(extraAcces.GetJsonString().c_str());
244 CommonEventPublishInfo publishInfo;
245 USB_HILOGI(MODULE_SERVICE, "send accessory attached broadcast device:%{public}s",
246 extraAcces.GetJsonString().c_str());
247 CommonEventManager::PublishCommonEvent(data, publishInfo);
248 return UEC_OK;
249 }
250
HandleEvent(int32_t status,bool delayProcess)251 void UsbAccessoryManager::HandleEvent(int32_t status, bool delayProcess)
252 {
253 if (usbdImpl_ == nullptr) {
254 USB_HILOGE(MODULE_USB_SERVICE, "UsbAccessoryManager::usbd_ is nullptr");
255 return;
256 }
257 std::lock_guard<std::mutex> guard(mutexHandleEvent_);
258 eventStatus_ = status;
259 if (delayProcess) {
260 antiShakeDelayTimer_.Unregister(antiShakeDelayTimerId_);
261 }
262 if ((status == ACT_UPDEVICE || status == ACT_DOWNDEVICE) && delayProcess) {
263 auto task = [&]() {
264 this->HandleEvent(this->eventStatus_, false);
265 return;
266 };
267 antiShakeDelayTimerId_ = antiShakeDelayTimer_.Register(task, ANTI_SHAKE_INTERVAL, true);
268 return;
269 }
270 int32_t curAccStatus = ACC_NONE;
271 switch (status) {
272 case ACT_UPDEVICE: {
273 if (accStatus_ == ACC_CONFIGURING) {
274 curAccStatus = ACC_START;
275 }
276 break;
277 }
278 case ACT_ACCESSORYUP: {
279 curAccStatus = ACC_CONFIGURING;
280 break;
281 }
282 case ACT_DOWNDEVICE:
283 case ACT_ACCESSORYDOWN: {
284 curAccStatus = ACC_STOP;
285 break;
286 }
287 case ACT_ACCESSORYSEND: {
288 curAccStatus = ACC_SEND;
289 break;
290 }
291 default:
292 USB_HILOGE(MODULE_USB_SERVICE, "invalid status %{public}d", status);
293 }
294 ProcessHandle(curAccStatus);
295 }
296
ProcessHandle(int32_t curAccStatus)297 void UsbAccessoryManager::ProcessHandle(int32_t curAccStatus)
298 {
299 int32_t ret = UEC_INTERFACE_INVALID_VALUE;
300 if ((curAccStatus == ACC_CONFIGURING || curAccStatus == ACC_START)) {
301 accDelayTimer_.Unregister(accDelayTimerId_);
302
303 int32_t curFunc = 0;
304 ret = usbdImpl_->GetCurrentFunctions(curFunc);
305 if (ret != UEC_OK) {
306 USB_HILOGE(MODULE_USB_SERVICE, "GetCurrentFunctions ret: %{public}d", ret);
307 return;
308 }
309 this->curDeviceFunc_ = curFunc;
310 ret = ProcessAccessoryStart(curFunc, curAccStatus);
311 if (ret != UEC_OK) {
312 USB_HILOGE(MODULE_USB_SERVICE, "ProcessAccessoryStart ret: %{public}d", ret);
313 return;
314 }
315 } else if (curAccStatus == ACC_STOP && accStatus_ != ACC_CONFIGURING) {
316 ret = ProcessAccessoryStop(curDeviceFunc_, curAccStatus);
317 if (ret != UEC_OK) {
318 USB_HILOGE(MODULE_USB_SERVICE, "ProcessAccessoryStop ret: %{public}d", ret);
319 return;
320 }
321 } else if (curAccStatus == ACC_SEND) {
322 ProcessAccessorySend();
323 }
324 return;
325 }
326
SerialValueHash(const std::string & serialValue)327 std::string UsbAccessoryManager::SerialValueHash(const std::string&serialValue)
328 {
329 uint64_t timestamp = 0;
330 auto now = std::chrono::system_clock::now();
331 auto duration = now.time_since_epoch();
332 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
333 timestamp = static_cast<uint64_t>(millis);
334
335 std::hash<std::string> string_hash;
336 std::hash<uint64_t> int_hash;
337
338 uint32_t hashValue = (string_hash(serialValue) ^ (int_hash(timestamp) << 1));
339
340 std::stringstream ss;
341 ss << std::hex << std::setw(NUM_OF_SERAIL_BIT) << std::setfill('0') << hashValue;
342 return ss.str();
343 }
344
InitBase64Map()345 void UsbAccessoryManager::InitBase64Map()
346 {
347 for (size_t i = 0; i < BASE_64_CHARS.size(); ++i) {
348 base64Map_[BASE_64_CHARS[i]] = static_cast<int>(i);
349 }
350 }
351
IsBase64(unsigned char c)352 bool IsBase64(unsigned char c)
353 {
354 return (isalnum(c) || (c == '+') || (c == '/'));
355 }
356
Base64Decode(const std::string & basicString)357 std::vector<uint8_t> UsbAccessoryManager::Base64Decode(const std::string& basicString)
358 {
359 std::string decoded_data;
360 uint32_t i = 0;
361 int index = 0;
362 int len = static_cast<int>(basicString.size());
363 unsigned char charArray3[INDEX_FORTH];
364 unsigned char charArray4[INDEX_FIFTH];
365
366 while (len-- && (basicString[index] != '=') && IsBase64(basicString[index])) {
367 charArray4[i++] = basicString[index];
368 index++;
369 if (i == sizeof(charArray4)) {
370 for (i = 0; i < sizeof(charArray4); i++) {
371 charArray4[i] = BASE_64_CHARS.find(charArray4[i]);
372 }
373 charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) +
374 ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4);
375 charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) +
376 ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2);
377 charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH];
378 for (i = 0; i < sizeof(charArray3); i++) {
379 decoded_data += charArray3[i];
380 }
381 i = 0;
382 }
383 }
384
385 if (i) {
386 uint32_t j = 0;
387 for (j = i; j < sizeof(charArray4); j++) {
388 charArray4[j] = 0;
389 }
390 for (j = 0; j < sizeof(charArray4); j++) {
391 charArray4[j] = BASE_64_CHARS.find(charArray4[j]);
392 }
393 charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) +
394 ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4);
395 charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) +
396 ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2);
397 charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH];
398 for (j = 0; j < i - 1; j++) {
399 decoded_data += charArray3[j];
400 }
401 }
402
403 std::vector<uint8_t> ret;
404 for (char c : decoded_data) {
405 ret.push_back(static_cast<uint8_t>(c));
406 }
407
408 return ret;
409 }
410
compare(const std::string & s1,const std::string & s2)411 bool UsbAccessoryManager::compare(const std::string &s1, const std::string &s2)
412 {
413 if (s1.empty())
414 return (s2.empty());
415 return s1 == s2;
416 }
417
GetAccessorySerialNumber(const USBAccessory & access,const std::string & bundleName,std::string & serialValue)418 int32_t UsbAccessoryManager::GetAccessorySerialNumber(const USBAccessory &access,
419 const std::string &bundleName, std::string &serialValue)
420 {
421 USB_HILOGD(MODULE_USB_SERVICE, "%{public}s, bundleName: %{public}s, serial: %{public}s",
422 __func__, bundleName.c_str(), this->accessory.GetSerialNumber().c_str());
423 if (accStatus_ != ACC_START) {
424 USB_HILOGE(MODULE_USB_SERVICE, "invalid status %{public}d", accStatus_);
425 return UEC_SERVICE_ACCESSORY_NOT_MATCH;
426 } else if (compare(this->accessory.GetManufacturer(), access.GetManufacturer()) &&
427 (compare(this->accessory.GetProduct(), access.GetProduct())) &&
428 compare(this->accessory.GetDescription(), access.GetDescription()) &&
429 compare(this->accessory.GetManufacturer(), access.GetManufacturer()) &&
430 compare(this->accessory.GetVersion(), access.GetVersion()) &&
431 (compare(this->accessory.GetSerialNumber(), access.GetSerialNumber()) ||
432 compare(bundleName + this->accessory.GetSerialNumber(), access.GetSerialNumber()))) {
433 serialValue = access.GetManufacturer() + access.GetProduct() + access.GetVersion() + access.GetSerialNumber();
434 return UEC_OK;
435 }
436 return UEC_SERVICE_ACCESSORY_NOT_MATCH;
437 }
438 // LCOV_EXCL_STOP
439
440 } // USB
441 } // OHOS
442