• 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 SHIFT_32        = 32;
29 constexpr uint32_t USB_DEV_DESC_SIZE = 0x12;
30 struct UsbDevDescLite {
31     uint8_t bLength;
32     uint8_t bDescriptorType;
33     uint16_t bcdUSB;
34     uint8_t bDeviceClass;
35     uint8_t bDeviceSubClass;
36     uint8_t bDeviceProtocol;
37     uint8_t bMaxPacketSize0;
38     uint16_t idVendor;
39     uint16_t idProduct;
40 } __attribute__((packed));
41 
ToDeviceDesc(const UsbDev & usbDev,const UsbDevDescLite & desc)42 static string ToDeviceDesc(const UsbDev& usbDev, const UsbDevDescLite& desc)
43 {
44     char buffer[MAX_DEV_ID_SIZE];
45     auto ret = sprintf_s(buffer, sizeof(buffer), "USB&BUS_%02X&DEV_%02X&PID_%04X&VID_%04X&CLASS_%02X",\
46         usbDev.busNum, usbDev.devAddr, desc.idProduct, desc.idVendor, desc.bDeviceClass);
47     if (ret < 0) {
48         EDM_LOGE(MODULE_BUS_USB,  "ToDeivceDesc sprintf_s error. ret = %{public}d", ret);
49         return string();
50     }
51     return string(buffer);
52 }
53 
ToBusDeivceId(const UsbDev & usbDev)54 static uint32_t ToBusDeivceId(const UsbDev& usbDev)
55 {
56     uint32_t devId = (usbDev.busNum << SHIFT_16) + usbDev.devAddr;
57     return devId;
58 }
59 
ToDdkDeviceId(const UsbDev & usbDev)60 static uint64_t ToDdkDeviceId(const UsbDev& usbDev)
61 {
62     return ((uint64_t)usbDev.busNum << SHIFT_32) + usbDev.devAddr;
63 }
64 
65 
Init(shared_ptr<IDevChangeCallback> callback,sptr<IUsbInterface> iusb,sptr<IUsbDdk> iUsbDdk)66 void UsbDevSubscriber::Init(shared_ptr<IDevChangeCallback> callback, sptr<IUsbInterface> iusb, sptr<IUsbDdk> iUsbDdk)
67 {
68     this->iusb_ = iusb;
69     this->callback_ = callback;
70     this->iUsbDdk_ = iUsbDdk;
71 };
72 
GetInterfaceDescriptor(const UsbDev & usbDev,std::vector<UsbInterfaceDescriptor> & interfaceList)73 int32_t UsbDevSubscriber::GetInterfaceDescriptor(const UsbDev &usbDev,
74     std::vector<UsbInterfaceDescriptor> &interfaceList)
75 {
76     int32_t ret = EDM_NOK;
77     if (this->iusb_ == nullptr || this->iUsbDdk_ == nullptr) {
78         return EDM_ERR_INVALID_OBJECT;
79     }
80     uint8_t configIndex;
81     ret = this->iusb_->GetConfig(usbDev, configIndex);
82     if (ret != EDM_OK) {
83         EDM_LOGE(MODULE_BUS_USB,  "GetConfig fail, ret = %{public}d", ret);
84         return ret;
85     }
86 
87     uint64_t ddkDeviceId = ToDdkDeviceId(usbDev);
88     std::vector<uint8_t> descriptor;
89     ret = this->iUsbDdk_->GetConfigDescriptor(ddkDeviceId, configIndex, descriptor);
90     if (ret != EDM_OK) {
91         EDM_LOGE(MODULE_BUS_USB, "GetConfigDescriptor fail, ret = %{public}d", ret);
92         return ret;
93     }
94     UsbDdkConfigDescriptor *config = nullptr;
95     ret = ParseUsbConfigDescriptor(descriptor, &config);
96     if (ret != EDM_OK || config == nullptr) {
97         FreeUsbConfigDescriptor(config);
98         EDM_LOGE(MODULE_BUS_USB, "ParseUsbConfigDescriptor fail, ret = %{public}d", ret);
99         return ret;
100     }
101     if (config->interface == nullptr) {
102         FreeUsbConfigDescriptor(config);
103         EDM_LOGE(MODULE_BUS_USB,  "UsbDdkInterface is null");
104         return EDM_ERR_INVALID_OBJECT;
105     }
106     for (uint8_t i = 0; i < config->configDescriptor.bNumInterfaces; i++) {
107         UsbDdkInterfaceDescriptor *interfaceDesc = config->interface[i].altsetting;
108         if (interfaceDesc == nullptr) {
109             FreeUsbConfigDescriptor(config);
110             EDM_LOGE(MODULE_BUS_USB,  "UsbDdkInterfaceDescriptor is null");
111             return EDM_ERR_INVALID_OBJECT;
112         }
113         interfaceList.push_back(interfaceDesc->interfaceDescriptor);
114     }
115     FreeUsbConfigDescriptor(config);
116     return EDM_OK;
117 }
118 
OnDeviceConnect(const UsbDev & usbDev)119 int32_t UsbDevSubscriber::OnDeviceConnect(const UsbDev &usbDev)
120 {
121     EDM_LOGD(MODULE_BUS_USB,  "OnDeviceConnect enter");
122     int32_t ret = 0;
123     if (this->iusb_ == nullptr) {
124         return EDM_ERR_INVALID_OBJECT;
125     }
126     vector<uint8_t> descData;
127     ret = this->iusb_->GetDeviceDescriptor(usbDev, descData);
128     if (ret != 0) {
129         EDM_LOGE(MODULE_BUS_USB,  "GetDeviceDescriptor fail, ret = %{public}d\n", ret);
130         return EDM_ERR_IO;
131     }
132     uint8_t *buffer = descData.data();
133     uint32_t length = descData.size();
134     if (length == 0) {
135         EDM_LOGE(MODULE_BUS_USB,  "GetRawDescriptor failed len=%{public}d busNum:%{public}d devAddr:%{public}d",\
136             length, usbDev.busNum, usbDev.devAddr);
137         return EDM_ERR_USB_ERR;
138     }
139     UsbDevDescLite deviceDescriptor = *(reinterpret_cast<const UsbDevDescLite *>(buffer));
140     if (deviceDescriptor.bLength != USB_DEV_DESC_SIZE) {
141         EDM_LOGE(MODULE_BUS_USB,  "UsbdDeviceDescriptor size error");
142         return EDM_ERR_USB_ERR;
143     }
144     string desc = ToDeviceDesc(usbDev, deviceDescriptor);
145     uint32_t busDevId = ToBusDeivceId(usbDev);
146     auto usbDevInfo = make_shared<UsbDeviceInfo>(busDevId, desc);
147 
148     usbDevInfo->bcdUSB_ = deviceDescriptor.bcdUSB;
149     usbDevInfo->idProduct_ = deviceDescriptor.idProduct;
150     usbDevInfo->idVendor_ = deviceDescriptor.idVendor;
151     usbDevInfo->deviceClass_ = deviceDescriptor.bDeviceClass;
152 
153     ret = GetInterfaceDescriptor(usbDev, usbDevInfo->interfaceDescList_);
154     if (ret != EDM_OK) {
155         EDM_LOGE(MODULE_BUS_USB,  "GetInterfaceDescriptor fail, ret = %{public}d", ret);
156         return ret;
157     }
158 
159     this->deviceInfos_[busDevId] = usbDevInfo;
160     if (this->callback_ != nullptr) {
161         this->callback_->OnDeviceAdd(usbDevInfo);
162     }
163     EDM_LOGD(MODULE_BUS_USB,  "OnDeviceConnect:");
164     EDM_LOGD(MODULE_BUS_USB,  "%{public}s", desc.c_str());
165     return EDM_OK;
166 };
167 
OnDeviceDisconnect(const UsbDev & usbDev)168 int32_t UsbDevSubscriber::OnDeviceDisconnect(const UsbDev &usbDev)
169 {
170     EDM_LOGD(MODULE_BUS_USB,  "OnDeviceDisconnect enter");
171     uint32_t busDevId = ToBusDeivceId(usbDev);
172     if (this->callback_ != nullptr) {
173         auto deviceInfo = this->deviceInfos_[busDevId];
174         if (deviceInfo != nullptr) {
175             this->callback_->OnDeviceRemove(deviceInfo);
176         } else {
177             EDM_LOGW(MODULE_BUS_USB,  "no dev in map, busDevId=%{public}08X \n", busDevId);
178         }
179     }
180     this->deviceInfos_.erase(busDevId);
181     return 0;
182 }
183 
DeviceEvent(const USBDeviceInfo & usbDevInfo)184 int32_t UsbDevSubscriber::DeviceEvent(const USBDeviceInfo &usbDevInfo)
185 {
186     EDM_LOGD(MODULE_BUS_USB,  "DeviceEvent enter");
187     UsbDev usbDev = {usbDevInfo.busNum, usbDevInfo.devNum};
188     int32_t ret = 0;
189     if (usbDevInfo.status == ACT_DEVUP) {
190         ret = this->OnDeviceConnect(usbDev);
191     } else if (usbDevInfo.status == ACT_DEVDOWN) {
192         ret = this->OnDeviceDisconnect(usbDev);
193     } else {
194         EDM_LOGW(MODULE_BUS_USB,  "status not support, %{public}d \n", usbDevInfo.status);
195     }
196     EDM_LOGD(MODULE_BUS_USB,  "ret = %{public}d, %{public}s", ret, this->ToString().c_str());
197     return ret;
198 }
199 
PortChangedEvent(const PortInfo & usbDevInfo)200 int32_t UsbDevSubscriber::PortChangedEvent(const PortInfo &usbDevInfo)
201 {
202     return 0;
203 }
204 
ToString(void)205 string UsbDevSubscriber::ToString(void)
206 {
207     string str = "DeviceInfos: Device count:" + to_string(this->deviceInfos_.size()) + "\n";
208     int i = 0;
209     for (auto it = this->deviceInfos_.begin(); it != deviceInfos_.end(); it++) {
210         str += "[" +to_string(i++) + "]" + to_string(it->first) + "\n";
211     }
212     return str;
213 }
214 }
215 }