• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "usb_descriptor_parser.h"
17 #include "hilog_wrapper.h"
18 #include "message_parcel.h"
19 #include "securec.h"
20 #include "usb_config.h"
21 #include "usb_endpoint.h"
22 #include "usb_errors.h"
23 #include "usb_interface.h"
24 #include "usbd_type.h"
25 
26 namespace OHOS {
27 namespace USB {
28 enum class DescriptorType {
29     DESCRIPTOR_TYPE_DEVICE = 1,
30     DESCRIPTOR_TYPE_CONFIG = 2,
31     DESCRIPTOR_TYPE_INTERFACE = 4,
32     DESCRIPTOR_TYPE_ENDPOINT = 5
33 };
34 
UsbDescriptorParser()35 UsbDescriptorParser::UsbDescriptorParser() {}
36 
~UsbDescriptorParser()37 UsbDescriptorParser::~UsbDescriptorParser() {}
38 
ParseDeviceDescriptor(const uint8_t * buffer,uint32_t length,UsbDevice & dev)39 int32_t UsbDescriptorParser::ParseDeviceDescriptor(const uint8_t *buffer, uint32_t length, UsbDevice &dev)
40 {
41     if (buffer == nullptr || length == 0) {
42         USB_HILOGE(MODULE_USB_SERVICE, "buffer is null");
43         return UEC_SERVICE_INVALID_VALUE;
44     }
45 
46     USB_HILOGI(MODULE_USB_SERVICE, "parse begin length=%{public}u", length);
47     uint32_t deviceDescriptorSize = sizeof(UsbdDeviceDescriptor);
48     if (length < deviceDescriptorSize) {
49         USB_HILOGE(MODULE_USB_SERVICE, "buffer size error");
50         return UEC_SERVICE_INVALID_VALUE;
51     }
52 
53     UsbdDeviceDescriptor deviceDescriptor = *(reinterpret_cast<const UsbdDeviceDescriptor *>(buffer));
54     if (deviceDescriptor.bLength != deviceDescriptorSize) {
55         USB_HILOGE(MODULE_USB_SERVICE, "UsbdDeviceDescriptor size error");
56         return UEC_SERVICE_INVALID_VALUE;
57     }
58 
59     dev.SetVendorId(deviceDescriptor.idVendor);
60     dev.SetProductId(deviceDescriptor.idProduct);
61     dev.SetClass(deviceDescriptor.bDeviceClass);
62     dev.SetSubclass(deviceDescriptor.bDeviceSubClass);
63     dev.SetDescConfigCount(deviceDescriptor.bNumConfigurations);
64 
65     dev.SetbMaxPacketSize0(deviceDescriptor.bMaxPacketSize0);
66     dev.SetbcdDevice(deviceDescriptor.bcdDevice);
67     dev.SetbcdUSB(deviceDescriptor.bcdUSB);
68     dev.SetiManufacturer(deviceDescriptor.iManufacturer);
69     dev.SetiProduct(deviceDescriptor.iProduct);
70     dev.SetiSerialNumber(deviceDescriptor.iSerialNumber);
71     return UEC_OK;
72 }
73 
ParseConfigDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,USBConfig & config)74 int32_t UsbDescriptorParser::ParseConfigDescriptor(
75     const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBConfig &config)
76 {
77     if (buffer == nullptr || length == 0) {
78         return UEC_SERVICE_INVALID_VALUE;
79     }
80 
81     USB_HILOGI(MODULE_USB_SERVICE, "parse begin length=%{public}u, cursor=%{public}u", length, cursor);
82     uint32_t configDescriptorSize = sizeof(UsbdConfigDescriptor);
83     if (length < configDescriptorSize) {
84         USB_HILOGE(MODULE_USB_SERVICE, "buffer size error");
85         return UEC_SERVICE_INVALID_VALUE;
86     }
87 
88     UsbdConfigDescriptor configDescriptor = *(reinterpret_cast<const UsbdConfigDescriptor *>(buffer));
89     cursor += configDescriptorSize;
90     if (configDescriptor.bLength != configDescriptorSize) {
91         USB_HILOGE(MODULE_USB_SERVICE, "UsbdDeviceDescriptor size error");
92         return UEC_SERVICE_INVALID_VALUE;
93     }
94 
95     config.SetId(configDescriptor.bConfigurationValue);
96     config.SetAttribute(configDescriptor.bmAttributes);
97     config.SetMaxPower(configDescriptor.bMaxPower);
98     config.SetiConfiguration(configDescriptor.iConfiguration);
99 
100     std::vector<UsbInterface> interfaces;
101     for (int32_t i = 0; (i < configDescriptor.bNumInterfaces) && (cursor < length); ++i) {
102         uint32_t interfaceCursor = 0;
103         UsbInterface interface;
104         ParseInterfaceDescriptor(
105             buffer + cursor + interfaceCursor, length - cursor - interfaceCursor, interfaceCursor, interface);
106         if (interface.GetEndpointCount() > 0) {
107             interfaces.push_back(interface);
108         } else {
109             // retry
110             --i;
111         }
112         cursor += interfaceCursor;
113     }
114     config.SetInterfaces(interfaces);
115     return UEC_OK;
116 }
117 
ParseInterfaceDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,UsbInterface & interface)118 int32_t UsbDescriptorParser::ParseInterfaceDescriptor(
119     const uint8_t *buffer, uint32_t length, uint32_t &cursor, UsbInterface &interface)
120 {
121     if (buffer == nullptr || length == 0) {
122         return UEC_SERVICE_INVALID_VALUE;
123     }
124 
125     uint32_t descriptorHeaderSize = sizeof(UsbdDescriptorHeader);
126     while (static_cast<uint32_t>(cursor) < length) {
127         if (descriptorHeaderSize >= length) {
128             USB_HILOGE(MODULE_USB_SERVICE, "length error");
129             return UEC_SERVICE_INVALID_VALUE;
130         }
131         UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
132         if (descriptorHeader.bLength > length) {
133             USB_HILOGE(MODULE_USB_SERVICE, "descriptor size error");
134             return UEC_SERVICE_INVALID_VALUE;
135         }
136         if (descriptorHeader.bDescriptorType == static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_INTERFACE)) {
137             break;
138         }
139         cursor += descriptorHeader.bLength;
140         USB_HILOGI(MODULE_USB_SERVICE, "type = %{public}d, length=%{public}d", descriptorHeader.bDescriptorType,
141             descriptorHeader.bLength);
142     }
143 
144     UsbdInterfaceDescriptor interfaceDescriptor = *(reinterpret_cast<const UsbdInterfaceDescriptor *>(buffer + cursor));
145     if (interfaceDescriptor.bLength != sizeof(UsbdInterfaceDescriptor)) {
146         USB_HILOGE(MODULE_USB_SERVICE, "UsbdInterfaceDescriptor size error");
147         return UEC_SERVICE_INVALID_VALUE;
148     }
149     cursor += interfaceDescriptor.bLength;
150 
151     interface.SetId(interfaceDescriptor.bInterfaceNumber);
152     interface.SetProtocol(interfaceDescriptor.bInterfaceProtocol);
153     interface.SetAlternateSetting(interfaceDescriptor.bAlternateSetting);
154     interface.SetClass(interfaceDescriptor.bInterfaceClass);
155     interface.SetSubClass(interfaceDescriptor.bInterfaceSubClass);
156     interface.SetiInterface(interfaceDescriptor.iInterface);
157 
158     std::vector<USBEndpoint> eps;
159     for (int32_t j = 0; j < interfaceDescriptor.bNumEndpoints; ++j) {
160         uint32_t epCursor = 0;
161         USBEndpoint ep;
162         ParseEndpointDescriptor(buffer + cursor + epCursor, length - cursor - epCursor, epCursor, ep);
163         ep.SetInterfaceId(interfaceDescriptor.bInterfaceNumber);
164         eps.push_back(ep);
165         cursor += epCursor;
166     }
167     interface.SetEndpoints(eps);
168     return UEC_OK;
169 }
170 
ParseEndpointDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,USBEndpoint & ep)171 int32_t UsbDescriptorParser::ParseEndpointDescriptor(
172     const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBEndpoint &ep)
173 {
174     USB_HILOGI(MODULE_USB_SERVICE, "parse begin, length=%{public}u, cursor=%{public}u", length, cursor);
175     if (buffer == nullptr || length == 0) {
176         return UEC_SERVICE_INVALID_VALUE;
177     }
178 
179     uint32_t descriptorHeaderSize = sizeof(UsbdDescriptorHeader);
180     while (static_cast<uint32_t>(cursor) < length) {
181         if (descriptorHeaderSize >= length) {
182             USB_HILOGE(MODULE_USB_SERVICE, "length error");
183             return UEC_SERVICE_INVALID_VALUE;
184         }
185         UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
186         if (descriptorHeader.bLength > length) {
187             USB_HILOGE(MODULE_USB_SERVICE, "descriptor size error");
188             return UEC_SERVICE_INVALID_VALUE;
189         }
190         if (descriptorHeader.bDescriptorType == static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_ENDPOINT)) {
191             break;
192         }
193         cursor += descriptorHeader.bLength;
194         USB_HILOGI(MODULE_USB_SERVICE, "error type = %{public}d, length=%{public}d", descriptorHeader.bDescriptorType,
195             descriptorHeader.bLength);
196     }
197 
198     UsbdEndpointDescriptor endpointDescriptor = *(reinterpret_cast<const UsbdEndpointDescriptor *>(buffer + cursor));
199     if (endpointDescriptor.bLength != sizeof(UsbdEndpointDescriptor)) {
200         USB_HILOGE(MODULE_USB_SERVICE, "Endpoint descriptor size error, length=%{public}d", endpointDescriptor.bLength);
201         return UEC_SERVICE_INVALID_VALUE;
202     }
203     cursor += endpointDescriptor.bLength;
204 
205     ep.SetAddr(endpointDescriptor.bEndpointAddress);
206     ep.SetAttr(endpointDescriptor.bmAttributes);
207     ep.SetInterval(endpointDescriptor.bInterval);
208     ep.SetMaxPacketSize(endpointDescriptor.wMaxPacketSize);
209     return UEC_OK;
210 }
211 } // namespace USB
212 } // namespace OHOS
213