• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "string"
17 #include "securec.h"
18 #include "hilog_wrapper.h"
19 #include "edm_errors.h"
20 #include "usb_dev_subscriber.h"
21 namespace OHOS {
22 namespace ExternalDeviceManager {
23 using namespace std;
24 constexpr uint32_t MAX_DEV_ID_SIZE = 100;
25 constexpr uint32_t ACT_DEVUP       = 0;
26 constexpr uint32_t ACT_DEVDOWN     = 1;
27 constexpr uint32_t SHIFT_16        = 16;
28 constexpr uint32_t USB_DEV_DESC_SIZE = 0x12;
29 struct UsbDevDescLite {
30     uint8_t bLength;
31     uint8_t bDescriptorType;
32     uint16_t bcdUSB;
33     uint8_t bDeviceClass;
34     uint8_t bDeviceSubClass;
35     uint8_t bDeviceProtocol;
36     uint8_t bMaxPacketSize0;
37     uint16_t idVendor;
38     uint16_t idProduct;
39 } __attribute__((packed));
40 
ToDeviceDesc(const UsbDev & usbDev,const UsbDevDescLite & desc)41 static string ToDeviceDesc(const UsbDev& usbDev, const UsbDevDescLite& desc)
42 {
43     char buffer[MAX_DEV_ID_SIZE];
44     auto ret = sprintf_s(buffer, sizeof(buffer), "USB&BUS_%02X&DEV_%02X&PID_%04X&VID_%04X&CLASS_%02X",\
45         usbDev.busNum, usbDev.devAddr, desc.idProduct, desc.idVendor, desc.bDeviceClass);
46     if (ret < 0) {
47         EDM_LOGE(MODULE_BUS_USB,  "ToDeivceDesc sprintf_s error. ret = %{public}d", ret);
48         return string();
49     }
50     return string(buffer);
51 }
52 
ToBusDeivceId(const UsbDev & usbDev)53 static uint32_t ToBusDeivceId(const UsbDev& usbDev)
54 {
55     uint32_t devId = (usbDev.busNum << SHIFT_16) + usbDev.devAddr;
56     return devId;
57 }
58 
59 
Init(shared_ptr<IDevChangeCallback> callback,sptr<IUsbInterface> iusb)60 void UsbDevSubscriber::Init(shared_ptr<IDevChangeCallback> callback, sptr<IUsbInterface> iusb)
61 {
62     this->iusb_ = iusb;
63     this->callback_ = callback;
64 };
65 
OnDeviceConnect(const UsbDev & usbDev)66 int32_t UsbDevSubscriber::OnDeviceConnect(const UsbDev &usbDev)
67 {
68     int32_t ret = 0;
69     if (this->iusb_ == nullptr) {
70         return EDM_ERR_INVALID_OBJECT;
71     }
72     vector<uint8_t> descData;
73     ret = this->iusb_->GetDeviceDescriptor(usbDev, descData);
74     if (ret != 0) {
75         EDM_LOGE(MODULE_BUS_USB,  "GetDeviceDescriptor fail, ret = %{public}d\n", ret);
76         return EDM_ERR_IO;
77     }
78     uint8_t *buffer = descData.data();
79     uint32_t length = descData.size();
80     if (length == 0) {
81         EDM_LOGE(MODULE_BUS_USB,  "GetRawDescriptor failed len=%{public}d busNum:%{public}d devAddr:%{public}d",\
82             length, usbDev.busNum, usbDev.devAddr);
83         return EDM_ERR_USB_ERR;
84     }
85     UsbDevDescLite deviceDescriptor = *(reinterpret_cast<const UsbDevDescLite *>(buffer));
86     if (deviceDescriptor.bLength != USB_DEV_DESC_SIZE) {
87         EDM_LOGE(MODULE_BUS_USB,  "UsbdDeviceDescriptor size error");
88         return EDM_ERR_USB_ERR;
89     }
90     string desc = ToDeviceDesc(usbDev, deviceDescriptor);
91     uint32_t busDevId = ToBusDeivceId(usbDev);
92     auto usbDevInfo = make_shared<UsbDeviceInfo>(busDevId, desc);
93 
94     usbDevInfo->bcdUSB_ = deviceDescriptor.bcdUSB;
95     usbDevInfo->idProduct_ = deviceDescriptor.idProduct;
96     usbDevInfo->idVendor_ = deviceDescriptor.idVendor;
97     usbDevInfo->deviceClass_ = deviceDescriptor.bDeviceClass;
98 
99     this->deviceInfos_[busDevId] = usbDevInfo;
100     if (this->callback_ != nullptr) {
101         this->callback_->OnDeviceAdd(usbDevInfo);
102     }
103     EDM_LOGD(MODULE_BUS_USB,  "OnDeviceConnect:");
104     EDM_LOGD(MODULE_BUS_USB,  "%{public}s", desc.c_str());
105     return EDM_OK;
106 };
107 
OnDeviceDisconnect(const UsbDev & usbDev)108 int32_t UsbDevSubscriber::OnDeviceDisconnect(const UsbDev &usbDev)
109 {
110     uint32_t busDevId = ToBusDeivceId(usbDev);
111     if (this->callback_ != nullptr) {
112         auto deviceInfo = this->deviceInfos_[busDevId];
113         if (deviceInfo != nullptr) {
114             this->callback_->OnDeviceRemove(deviceInfo);
115         } else {
116             EDM_LOGW(MODULE_BUS_USB,  "no dev in map, busDevId=%{public}08X \n", busDevId);
117         }
118     }
119     this->deviceInfos_.erase(busDevId);
120     return 0;
121 }
122 
DeviceEvent(const USBDeviceInfo & usbDevInfo)123 int32_t UsbDevSubscriber::DeviceEvent(const USBDeviceInfo &usbDevInfo)
124 {
125     UsbDev usbDev = {usbDevInfo.busNum, usbDevInfo.devNum};
126     int32_t ret = 0;
127     if (usbDevInfo.status == ACT_DEVUP) {
128         ret = this->OnDeviceConnect(usbDev);
129     } else if (usbDevInfo.status == ACT_DEVDOWN) {
130         ret = this->OnDeviceDisconnect(usbDev);
131     } else {
132         EDM_LOGW(MODULE_BUS_USB,  "status not support, %{public}d \n", usbDevInfo.status);
133     }
134     EDM_LOGD(MODULE_BUS_USB,  "ret = %{public}d, %{public}s", ret, this->ToString().c_str());
135     return ret;
136 }
137 
PortChangedEvent(const PortInfo & usbDevInfo)138 int32_t UsbDevSubscriber::PortChangedEvent(const PortInfo &usbDevInfo)
139 {
140     return 0;
141 }
142 
ToString(void)143 string UsbDevSubscriber::ToString(void)
144 {
145     string str = "DeviceInfos: Device count:" + to_string(this->deviceInfos_.size()) + "\n";
146     int i = 0;
147     for (auto it = this->deviceInfos_.begin(); it != deviceInfos_.end(); it++) {
148         str += "[" +to_string(i++) + "]" + to_string(it->first) + "\n";
149     }
150     return str;
151 }
152 }
153 }