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         curFunc = static_cast<int32_t>(curFuncUint);
143         this->accStatus_ = ACC_START;
144         std::vector<std::string> accessorys;
145         usbdImpl_->GetAccessoryInfo(accessorys);
146         this->accessory.SetAccessory(accessorys);
147         std::string hashSerial = SerialValueHash(this->accessory.GetSerialNumber());
148         this->accessory.SetSerialNumber(hashSerial);
149         Want want;
150         want.SetAction(CommonEventSupport::COMMON_EVENT_USB_ACCESSORY_ATTACHED);
151         CommonEventData data(want);
152         data.SetData(this->accessory.GetJsonString().c_str());
153         CommonEventPublishInfo publishInfo;
154         USB_HILOGI(MODULE_SERVICE, "send accessory attached broadcast device:%{public}s",
155             this->accessory.GetJsonString().c_str());
156         return CommonEventManager::PublishCommonEvent(data, publishInfo);
157     } else if ((curFuncUint & FUN_ACCESSORY) == 0 && curAccStatus == ACC_CONFIGURING) {
158         curFunc = static_cast<int32_t>(curFuncUint);
159         int32_t ret = usbdImpl_->SetCurrentFunctions(FUN_ACCESSORY);
160         if (ret != UEC_OK) {
161             USB_HILOGE(MODULE_SERVICE, "curFunc %{public}d curAccStatus:%{public}u, set func ret: %{public}d",
162                 curFuncUint, curAccStatus, ret);
163             return ret;
164         }
165         lastDeviceFunc_ = static_cast<uint32_t>(curFuncUint);
166         auto task = [&]() {
167             this->accStatus_ = ACC_STOP;
168             int32_t ret = usbdImpl_ ->SetCurrentFunctions(this->lastDeviceFunc_);
169             if (ret != UEC_OK) {
170                 USB_HILOGW(MODULE_SERVICE, "set old func: %{public}d ret: %{public}d", this->lastDeviceFunc_, ret);
171             }
172             return;
173         };
174         accDelayTimerId_ = accDelayTimer_.Register(task, DELAY_ACC_INTERVAL, true);
175         this->accStatus_ = ACC_CONFIGURING;
176     } else {
177         USB_HILOGD(MODULE_SERVICE, "curFunc %{public}u curAccStatus:%{public}d not necessary",
178             curFuncUint, curAccStatus);
179     }
180     return UEC_OK;
181 }
182 
ProcessAccessoryStop(int32_t curFunc,int32_t curAccStatus)183 int32_t UsbAccessoryManager::ProcessAccessoryStop(int32_t curFunc, int32_t curAccStatus)
184 {
185     uint32_t curFuncUint = static_cast<uint32_t>(curFunc);
186     if ((curFuncUint & FUN_ACCESSORY) != 0 && accStatus_ == ACC_START) {
187         accStatus_ = ACC_STOP;
188         int32_t ret = usbdImpl_ ->SetCurrentFunctions(lastDeviceFunc_);
189         if (ret != UEC_OK) {
190             USB_HILOGW(MODULE_SERVICE, "setFunc %{public}d curAccStatus:%{public}d, set func ret: %{public}d",
191                 lastDeviceFunc_, curAccStatus, ret);
192         }
193         curDeviceFunc_ = lastDeviceFunc_;
194         Want want;
195         want.SetAction(CommonEventSupport::COMMON_EVENT_USB_ACCESSORY_DETACHED);
196         CommonEventData data(want);
197         data.SetData(this->accessory.GetJsonString().c_str());
198         CommonEventPublishInfo publishInfo;
199         USB_HILOGI(MODULE_SERVICE, "send accessory detached broadcast device:%{public}s",
200             this->accessory.GetJsonString().c_str());
201         return CommonEventManager::PublishCommonEvent(data, publishInfo);
202     } else {
203         USB_HILOGD(MODULE_SERVICE, "curFunc %{public}u curAccStatus:%{public}d not necessary",
204             curFuncUint, curAccStatus);
205     }
206     return UEC_OK;
207 }
208 
ProcessAccessorySend()209 int32_t UsbAccessoryManager::ProcessAccessorySend()
210 {
211     this->accStatus_ = ACC_SEND;
212     std::vector<std::string> accessorys;
213     usbdImpl_->GetAccessoryInfo(accessorys);
214     this->accessory.SetAccessory(accessorys);
215     std::string extraInfo;
216     if (accessorys.size() > ACCESSORY_INFO_SIZE &&
217         ACCESSORY_EXTRA_INDEX < accessorys.size() && !accessorys[ACCESSORY_EXTRA_INDEX].empty()) {
218         if (base64Map_.empty()) {
219             InitBase64Map();
220         }
221         std::string extraEcode = accessorys[ACCESSORY_EXTRA_INDEX];
222         USB_HILOGE(MODULE_USB_SERVICE, "extraEcode, length: %{public}zu, extraData: %{public}s",
223             extraEcode.length(), extraEcode.c_str());
224         std::vector<uint8_t> extraData = Base64Decode(extraEcode);
225         cJSON *root = cJSON_CreateArray();
226         for (uint8_t value : extraData) {
227             cJSON_AddItemToArray(root, cJSON_CreateNumber(value));
228         }
229         char *pExtraJson = cJSON_PrintUnformatted(root);
230         cJSON_Delete(root);
231         if (!pExtraJson) {
232             USB_HILOGE(MODULE_USB_SERVICE, "print json error.");
233             return UEC_SERVICE_INVALID_VALUE;
234         }
235         extraInfo = pExtraJson;
236         cJSON_free(pExtraJson);
237         pExtraJson = nullptr;
238     }
239 
240     USBAccessory extraAcces;
241     extraAcces.SetDescription(extraInfo);
242     Want want;
243     want.SetAction(CommonEventSupport::COMMON_EVENT_USB_ACCESSORY_ATTACHED);
244     CommonEventData data(want);
245     data.SetData(extraAcces.GetJsonString().c_str());
246     CommonEventPublishInfo publishInfo;
247     USB_HILOGI(MODULE_SERVICE, "send accessory attached broadcast device:%{public}s",
248         extraAcces.GetJsonString().c_str());
249     CommonEventManager::PublishCommonEvent(data, publishInfo);
250     return UEC_OK;
251 }
252 
HandleEvent(int32_t status,bool delayProcess)253 void UsbAccessoryManager::HandleEvent(int32_t status, bool delayProcess)
254 {
255     if (usbdImpl_ == nullptr) {
256         USB_HILOGE(MODULE_USB_SERVICE, "UsbAccessoryManager::usbd_ is nullptr");
257         return;
258     }
259     std::lock_guard<std::mutex> guard(mutexHandleEvent_);
260     eventStatus_ = status;
261     if (delayProcess) {
262         antiShakeDelayTimer_.Unregister(antiShakeDelayTimerId_);
263     }
264     if ((status == ACT_UPDEVICE || status == ACT_DOWNDEVICE) && delayProcess) {
265         auto task = [&]() {
266             this->HandleEvent(this->eventStatus_, false);
267             return;
268         };
269         antiShakeDelayTimerId_ = antiShakeDelayTimer_.Register(task, ANTI_SHAKE_INTERVAL, true);
270         return;
271     }
272     int32_t curAccStatus = ACC_NONE;
273     switch (status) {
274         case ACT_UPDEVICE: {
275             if (accStatus_ == ACC_CONFIGURING) {
276                 curAccStatus = ACC_START;
277             }
278             break;
279         }
280         case ACT_ACCESSORYUP: {
281             curAccStatus = ACC_CONFIGURING;
282             break;
283         }
284         case ACT_DOWNDEVICE:
285         case ACT_ACCESSORYDOWN: {
286             curAccStatus = ACC_STOP;
287             break;
288         }
289         case ACT_ACCESSORYSEND: {
290             curAccStatus = ACC_SEND;
291             break;
292         }
293         default:
294             USB_HILOGE(MODULE_USB_SERVICE, "invalid status %{public}d", status);
295     }
296     ProcessHandle(curAccStatus);
297 }
298 
ProcessHandle(int32_t curAccStatus)299 void UsbAccessoryManager::ProcessHandle(int32_t curAccStatus)
300 {
301     int32_t ret = UEC_INTERFACE_INVALID_VALUE;
302     if ((curAccStatus == ACC_CONFIGURING || curAccStatus == ACC_START)) {
303         accDelayTimer_.Unregister(accDelayTimerId_);
304 
305         int32_t curFunc = 0;
306         ret = usbdImpl_->GetCurrentFunctions(curFunc);
307         if (ret != UEC_OK) {
308             USB_HILOGE(MODULE_USB_SERVICE, "GetCurrentFunctions ret: %{public}d", ret);
309             return;
310         }
311         this->curDeviceFunc_ = curFunc;
312         ret = ProcessAccessoryStart(curFunc, curAccStatus);
313         if (ret != UEC_OK) {
314             USB_HILOGE(MODULE_USB_SERVICE, "ProcessAccessoryStart ret: %{public}d", ret);
315             return;
316         }
317     } else if (curAccStatus == ACC_STOP && accStatus_ != ACC_CONFIGURING) {
318         ret = ProcessAccessoryStop(curDeviceFunc_, curAccStatus);
319         if (ret != UEC_OK) {
320             USB_HILOGE(MODULE_USB_SERVICE, "ProcessAccessoryStop ret: %{public}d", ret);
321             return;
322         }
323     } else if (curAccStatus == ACC_SEND) {
324         ProcessAccessorySend();
325     }
326     return;
327 }
328 
SerialValueHash(const std::string & serialValue)329 std::string UsbAccessoryManager::SerialValueHash(const std::string&serialValue)
330 {
331     uint64_t timestamp = 0;
332     auto now = std::chrono::system_clock::now();
333     auto duration = now.time_since_epoch();
334     auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
335     timestamp = static_cast<uint64_t>(millis);
336 
337     std::hash<std::string> string_hash;
338     std::hash<uint64_t> int_hash;
339 
340     uint32_t hashValue = (string_hash(serialValue) ^ (int_hash(timestamp) << 1));
341 
342     std::stringstream ss;
343     ss << std::hex << std::setw(NUM_OF_SERAIL_BIT) << std::setfill('0') << hashValue;
344     return ss.str();
345 }
346 
InitBase64Map()347 void UsbAccessoryManager::InitBase64Map()
348 {
349     for (size_t i = 0; i < BASE_64_CHARS.size(); ++i) {
350         base64Map_[BASE_64_CHARS[i]] = static_cast<int>(i);
351     }
352 }
353 
IsBase64(unsigned char c)354 bool IsBase64(unsigned char c)
355 {
356     return (isalnum(c) || (c == '+') || (c == '/'));
357 }
358 
Base64Decode(const std::string & basicString)359 std::vector<uint8_t> UsbAccessoryManager::Base64Decode(const std::string& basicString)
360 {
361     std::string decoded_data;
362     uint32_t i = 0;
363     int index = 0;
364     int len = static_cast<int>(basicString.size());
365     unsigned char charArray3[INDEX_FORTH];
366     unsigned char charArray4[INDEX_FIFTH];
367 
368     while (len-- && (basicString[index] != '=') && IsBase64(basicString[index])) {
369         charArray4[i++] = basicString[index];
370         index++;
371         if (i == sizeof(charArray4)) {
372             for (i = 0; i < sizeof(charArray4); i++) {
373                 charArray4[i] = BASE_64_CHARS.find(charArray4[i]);
374             }
375             charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) +
376                 ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4);
377             charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) +
378                 ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2);
379             charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH];
380             for (i = 0; i < sizeof(charArray3); i++) {
381                 decoded_data += charArray3[i];
382             }
383             i = 0;
384         }
385     }
386 
387     if (i) {
388         uint32_t j = 0;
389         for (j = i; j < sizeof(charArray4); j++) {
390             charArray4[j] = 0;
391         }
392         for (j = 0; j < sizeof(charArray4); j++) {
393             charArray4[j] = BASE_64_CHARS.find(charArray4[j]);
394         }
395         charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) +
396             ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4);
397         charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) +
398             ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2);
399         charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH];
400         for (j = 0; j < i - 1; j++) {
401             decoded_data += charArray3[j];
402         }
403     }
404 
405     std::vector<uint8_t> ret;
406     for (char c : decoded_data) {
407         ret.push_back(static_cast<uint8_t>(c));
408     }
409 
410     return ret;
411 }
412 
compare(const std::string & s1,const std::string & s2)413 bool UsbAccessoryManager::compare(const std::string &s1, const std::string &s2)
414 {
415     if (s1.empty())
416         return (s2.empty());
417     return s1 == s2;
418 }
419 
GetAccessorySerialNumber(const USBAccessory & access,const std::string & bundleName,std::string & serialValue)420 int32_t UsbAccessoryManager::GetAccessorySerialNumber(const USBAccessory &access,
421     const std::string &bundleName, std::string &serialValue)
422 {
423     USB_HILOGD(MODULE_USB_SERVICE, "%{public}s, bundleName: %{public}s, serial: %{public}s",
424         __func__, bundleName.c_str(), this->accessory.GetSerialNumber().c_str());
425     if (accStatus_ != ACC_START) {
426         USB_HILOGE(MODULE_USB_SERVICE, "invalid status %{public}d", accStatus_);
427         return UEC_SERVICE_ACCESSORY_NOT_MATCH;
428     } else if (compare(this->accessory.GetManufacturer(), access.GetManufacturer()) &&
429         (compare(this->accessory.GetProduct(), access.GetProduct())) &&
430         compare(this->accessory.GetDescription(), access.GetDescription()) &&
431         compare(this->accessory.GetManufacturer(), access.GetManufacturer()) &&
432         compare(this->accessory.GetVersion(), access.GetVersion()) &&
433         (compare(this->accessory.GetSerialNumber(), access.GetSerialNumber()) ||
434         compare(bundleName + this->accessory.GetSerialNumber(), access.GetSerialNumber()))) {
435         serialValue = access.GetManufacturer() + access.GetProduct() + access.GetVersion() + access.GetSerialNumber();
436         return UEC_OK;
437     }
438     return UEC_SERVICE_ACCESSORY_NOT_MATCH;
439 }
440 // LCOV_EXCL_STOP
441 
442 } // USB
443 } // OHOS
444