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