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 static constexpr uint8_t NORMAL_ENDPOINT_DESCRIPTOR = 7;
27 static constexpr uint8_t AUDIO_ENDPOINT_DESCRIPTOR = 9;
28 namespace OHOS {
29 namespace USB {
30 enum class DescriptorType {
31 DESCRIPTOR_TYPE_DEVICE = 1,
32 DESCRIPTOR_TYPE_CONFIG = 2,
33 DESCRIPTOR_TYPE_INTERFACE = 4,
34 DESCRIPTOR_TYPE_ENDPOINT = 5
35 };
36
UsbDescriptorParser()37 UsbDescriptorParser::UsbDescriptorParser() {}
38
~UsbDescriptorParser()39 UsbDescriptorParser::~UsbDescriptorParser() {}
40
ParseDeviceDescriptor(const uint8_t * buffer,uint32_t length,UsbDevice & dev)41 int32_t UsbDescriptorParser::ParseDeviceDescriptor(const uint8_t *buffer, uint32_t length, UsbDevice &dev)
42 {
43 if (buffer == nullptr || length == 0) {
44 USB_HILOGE(MODULE_USB_SERVICE, "buffer is null or length is zero");
45 return UEC_SERVICE_INVALID_VALUE;
46 }
47
48 USB_HILOGD(MODULE_USB_SERVICE, "parse begin length=%{public}u", length);
49 uint32_t deviceDescriptorSize = sizeof(UsbdDeviceDescriptor);
50 if (length < deviceDescriptorSize) {
51 USB_HILOGE(MODULE_USB_SERVICE, "buffer size error");
52 return UEC_SERVICE_INVALID_VALUE;
53 }
54
55 UsbdDeviceDescriptor deviceDescriptor = *(reinterpret_cast<const UsbdDeviceDescriptor *>(buffer));
56 if (deviceDescriptor.bLength != deviceDescriptorSize) {
57 USB_HILOGE(MODULE_USB_SERVICE, "UsbdDeviceDescriptor size error");
58 return UEC_SERVICE_INVALID_VALUE;
59 }
60
61 dev.SetVendorId(deviceDescriptor.idVendor);
62 dev.SetProductId(deviceDescriptor.idProduct);
63 dev.SetClass(deviceDescriptor.bDeviceClass);
64 dev.SetSubclass(deviceDescriptor.bDeviceSubClass);
65 dev.SetProtocol(deviceDescriptor.bDeviceProtocol);
66 dev.SetDescConfigCount(deviceDescriptor.bNumConfigurations);
67
68 dev.SetbMaxPacketSize0(deviceDescriptor.bMaxPacketSize0);
69 dev.SetbcdDevice(deviceDescriptor.bcdDevice);
70 dev.SetbcdUSB(deviceDescriptor.bcdUSB);
71 dev.SetiManufacturer(deviceDescriptor.iManufacturer);
72 dev.SetiProduct(deviceDescriptor.iProduct);
73 dev.SetiSerialNumber(deviceDescriptor.iSerialNumber);
74 return UEC_OK;
75 }
76
AddConfig(std::vector<USBConfig> & configs,const UsbdConfigDescriptor * configDescriptor)77 static int32_t AddConfig(std::vector<USBConfig> &configs, const UsbdConfigDescriptor *configDescriptor)
78 {
79 if (configDescriptor == nullptr) {
80 USB_HILOGE(MODULE_USB_SERVICE, "configDescriptor is nullptr");
81 return UEC_SERVICE_INVALID_VALUE;
82 }
83
84 USBConfig config;
85 config.SetId(configDescriptor->bConfigurationValue);
86 config.SetAttribute(configDescriptor->bmAttributes);
87 config.SetMaxPower(configDescriptor->bMaxPower);
88 config.SetiConfiguration(configDescriptor->iConfiguration);
89 configs.emplace_back(config);
90 USB_HILOGD(MODULE_USB_SERVICE, "add config, interfaces=%{public}u", configDescriptor->bNumInterfaces);
91 return UEC_OK;
92 }
93
AddInterface(std::vector<USBConfig> & configs,const UsbdInterfaceDescriptor * interfaceDescriptor)94 static int32_t AddInterface(std::vector<USBConfig> &configs, const UsbdInterfaceDescriptor *interfaceDescriptor)
95 {
96 if (interfaceDescriptor == nullptr) {
97 USB_HILOGE(MODULE_USB_SERVICE, "interfaceDescriptor is nullptr");
98 return UEC_SERVICE_INVALID_VALUE;
99 }
100 if (configs.empty()) {
101 USB_HILOGE(MODULE_USB_SERVICE, "config descriptor not found");
102 return UEC_SERVICE_INVALID_VALUE;
103 }
104
105 UsbInterface interface;
106 interface.SetId(interfaceDescriptor->bInterfaceNumber);
107 interface.SetProtocol(interfaceDescriptor->bInterfaceProtocol);
108 interface.SetAlternateSetting(interfaceDescriptor->bAlternateSetting);
109 interface.SetClass(interfaceDescriptor->bInterfaceClass);
110 interface.SetSubClass(interfaceDescriptor->bInterfaceSubClass);
111 interface.SetiInterface(interfaceDescriptor->iInterface);
112 configs.back().GetInterfaces().emplace_back(interface);
113 USB_HILOGD(MODULE_USB_SERVICE, "add interface, endpoints=%{public}u", interfaceDescriptor->bNumEndpoints);
114 return UEC_OK;
115 }
116
AddEndpoint(std::vector<USBConfig> & configs,const UsbdEndpointDescriptor * endpointDescriptor)117 static int32_t AddEndpoint(std::vector<USBConfig> &configs, const UsbdEndpointDescriptor *endpointDescriptor)
118 {
119 if (endpointDescriptor == nullptr) {
120 USB_HILOGE(MODULE_USB_SERVICE, "endpointDescriptor is nullptr");
121 return UEC_SERVICE_INVALID_VALUE;
122 }
123 if (configs.empty() || configs.back().GetInterfaces().empty()) {
124 USB_HILOGE(MODULE_USB_SERVICE, "interface descriptor not found");
125 return UEC_SERVICE_INVALID_VALUE;
126 }
127
128 USBEndpoint endpoint;
129 endpoint.SetAddr(endpointDescriptor->bEndpointAddress);
130 endpoint.SetAttr(endpointDescriptor->bmAttributes);
131 endpoint.SetInterval(endpointDescriptor->bInterval);
132 endpoint.SetMaxPacketSize(endpointDescriptor->wMaxPacketSize);
133 endpoint.SetInterfaceId(configs.back().GetInterfaces().back().GetId());
134 configs.back().GetInterfaces().back().GetEndpoints().emplace_back(endpoint);
135 USB_HILOGD(MODULE_USB_SERVICE, "add endpoint, address=%{public}u", endpointDescriptor->bEndpointAddress);
136 return UEC_OK;
137 }
138
ParseConfigDescriptors(std::vector<uint8_t> & descriptor,uint32_t offset,std::vector<USBConfig> & configs)139 int32_t UsbDescriptorParser::ParseConfigDescriptors(std::vector<uint8_t> &descriptor, uint32_t offset,
140 std::vector<USBConfig> &configs)
141 {
142 uint8_t *buffer = descriptor.data();
143 uint32_t length = descriptor.size();
144 uint32_t cursor = offset;
145 int32_t ret = UEC_OK;
146
147 while (cursor < length) {
148 if ((length - cursor) < sizeof(UsbdDescriptorHeader)) {
149 USB_HILOGW(MODULE_USB_SERVICE, "invalid desc data, length=%{public}u, cursor=%{public}u", length, cursor);
150 break;
151 }
152 UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
153 if (descriptorHeader.bLength > (length - cursor)) {
154 USB_HILOGW(MODULE_USB_SERVICE, "invalid data length, length=%{public}u, cursor=%{public}u", length, cursor);
155 break;
156 }
157 switch (descriptorHeader.bDescriptorType) {
158 case static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_CONFIG):
159 if (descriptorHeader.bLength != sizeof(UsbdConfigDescriptor)) {
160 USB_HILOGE(MODULE_USB_SERVICE, "invalid config, length=%{public}u", descriptorHeader.bLength);
161 return UEC_SERVICE_INVALID_VALUE;
162 }
163 ret = AddConfig(configs, reinterpret_cast<const UsbdConfigDescriptor *>(buffer + cursor));
164 break;
165 case static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_INTERFACE):
166 if (descriptorHeader.bLength != sizeof(UsbdInterfaceDescriptor)) {
167 USB_HILOGE(MODULE_USB_SERVICE, "invalid interface, length=%{public}u", descriptorHeader.bLength);
168 return UEC_SERVICE_INVALID_VALUE;
169 }
170 ret = AddInterface(configs, reinterpret_cast<const UsbdInterfaceDescriptor *>(buffer + cursor));
171 break;
172 case static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_ENDPOINT):
173 if (descriptorHeader.bLength != NORMAL_ENDPOINT_DESCRIPTOR
174 && descriptorHeader.bLength != AUDIO_ENDPOINT_DESCRIPTOR) {
175 USB_HILOGE(MODULE_USB_SERVICE, "invalid endpoint, length=%{public}u", descriptorHeader.bLength);
176 return UEC_SERVICE_INVALID_VALUE;
177 }
178 ret = AddEndpoint(configs, reinterpret_cast<const UsbdEndpointDescriptor *>(buffer + cursor));
179 break;
180 default:
181 USB_HILOGW(MODULE_USB_SERVICE, "unrecognized type=%{public}d", descriptorHeader.bDescriptorType);
182 break;
183 }
184 if (ret != UEC_OK) {
185 return ret;
186 }
187 cursor += descriptorHeader.bLength;
188 }
189 return ret;
190 }
191
ParseConfigDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,USBConfig & config)192 int32_t UsbDescriptorParser::ParseConfigDescriptor(
193 const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBConfig &config)
194 {
195 if (buffer == nullptr || length == 0) {
196 return UEC_SERVICE_INVALID_VALUE;
197 }
198
199 USB_HILOGD(MODULE_USB_SERVICE, "parse begin length=%{public}u, cursor=%{public}u", length, cursor);
200 uint32_t configDescriptorSize = sizeof(UsbdConfigDescriptor);
201 UsbdConfigDescriptor configDescriptor = *(reinterpret_cast<const UsbdConfigDescriptor *>(buffer));
202 if (length < configDescriptorSize || configDescriptor.bLength != configDescriptorSize) {
203 USB_HILOGE(MODULE_USB_SERVICE, "size error length=%{public}u, configDescriptor.bLength=%{public}d",
204 length, configDescriptor.bLength);
205 return UEC_SERVICE_INVALID_VALUE;
206 }
207 cursor += configDescriptorSize;
208
209 config.SetId(configDescriptor.bConfigurationValue);
210 config.SetAttribute(configDescriptor.bmAttributes);
211 config.SetMaxPower(configDescriptor.bMaxPower);
212 config.SetiConfiguration(configDescriptor.iConfiguration);
213
214 std::vector<UsbInterface> interfaces;
215 for (int32_t i = 0; (i < configDescriptor.bNumInterfaces) && (cursor < length); ++i) {
216 uint32_t interfaceCursor = 0;
217 UsbInterface interface;
218 int32_t ret = ParseInterfaceDescriptor(
219 buffer + cursor + interfaceCursor, length - cursor - interfaceCursor, interfaceCursor, interface);
220 if (ret != UEC_OK) {
221 USB_HILOGE(MODULE_USB_SERVICE, "ParseInterfaceDescriptor failed, ret=%{public}d", ret);
222 return UEC_SERVICE_INVALID_VALUE;
223 }
224 bool isRepeat = false;
225 auto iter = interfaces.begin();
226 while (iter != interfaces.end()) {
227 if (iter->GetId() == interface.GetId()) {
228 isRepeat = true;
229 break;
230 }
231 iter++;
232 }
233 if (interface.GetEndpointCount() >= 0 && !isRepeat) {
234 interfaces.push_back(interface);
235 } else {
236 // retry
237 if (interface.GetEndpointCount() > 0 && iter != interfaces.end()) {
238 USB_HILOGE(MODULE_USB_SERVICE, "get repeat interface id info, and has endpoints");
239 *iter = interface;
240 }
241 --i;
242 }
243 cursor += interfaceCursor;
244 }
245 config.SetInterfaces(interfaces);
246 return UEC_OK;
247 }
248
ParseInterfaceDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,UsbInterface & interface)249 int32_t UsbDescriptorParser::ParseInterfaceDescriptor(
250 const uint8_t *buffer, uint32_t length, uint32_t &cursor, UsbInterface &interface)
251 {
252 if (buffer == nullptr || length == 0) {
253 return UEC_SERVICE_INVALID_VALUE;
254 }
255
256 uint32_t descriptorHeaderSize = sizeof(UsbdDescriptorHeader);
257 while (cursor < length) {
258 if (descriptorHeaderSize >= length - cursor) {
259 USB_HILOGE(MODULE_USB_SERVICE, "length error");
260 return UEC_SERVICE_INVALID_VALUE;
261 }
262 UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
263 if (descriptorHeader.bLength >= descriptorHeaderSize) {
264 USB_HILOGE(MODULE_USB_SERVICE, "descriptor size error");
265 return UEC_SERVICE_INVALID_VALUE;
266 }
267 if (descriptorHeader.bDescriptorType == static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_INTERFACE)) {
268 break;
269 }
270 cursor += descriptorHeader.bLength;
271 USB_HILOGD(MODULE_USB_SERVICE, "type = %{public}d, length=%{public}d", descriptorHeader.bDescriptorType,
272 descriptorHeader.bLength);
273 }
274
275 if (length - cursor < sizeof(UsbdInterfaceDescriptor)) {
276 return UEC_SERVICE_INVALID_VALUE;
277 }
278 UsbdInterfaceDescriptor interfaceDescriptor = *(reinterpret_cast<const UsbdInterfaceDescriptor *>(buffer + cursor));
279 if (interfaceDescriptor.bLength != sizeof(UsbdInterfaceDescriptor)) {
280 USB_HILOGE(MODULE_USB_SERVICE, "UsbdInterfaceDescriptor size error");
281 return UEC_SERVICE_INVALID_VALUE;
282 }
283 cursor += interfaceDescriptor.bLength;
284
285 interface.SetId(interfaceDescriptor.bInterfaceNumber);
286 interface.SetProtocol(interfaceDescriptor.bInterfaceProtocol);
287 interface.SetAlternateSetting(interfaceDescriptor.bAlternateSetting);
288 interface.SetClass(interfaceDescriptor.bInterfaceClass);
289 interface.SetSubClass(interfaceDescriptor.bInterfaceSubClass);
290 interface.SetiInterface(interfaceDescriptor.iInterface);
291
292 std::vector<USBEndpoint> eps;
293 for (int32_t j = 0; j < interfaceDescriptor.bNumEndpoints; ++j) {
294 uint32_t epCursor = 0;
295 USBEndpoint ep;
296 ParseEndpointDescriptor(buffer + cursor + epCursor, length - cursor - epCursor, epCursor, ep);
297 ep.SetInterfaceId(interfaceDescriptor.bInterfaceNumber);
298 eps.push_back(ep);
299 cursor += epCursor;
300 }
301 interface.SetEndpoints(eps);
302 USB_HILOGD(MODULE_USB_SERVICE, "interface to string : %{public}s", interface.ToString().c_str());
303 return UEC_OK;
304 }
305
ParseEndpointDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,USBEndpoint & ep)306 int32_t UsbDescriptorParser::ParseEndpointDescriptor(
307 const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBEndpoint &ep)
308 {
309 USB_HILOGD(MODULE_USB_SERVICE, "parse begin, length=%{public}u, cursor=%{public}u", length, cursor);
310 if (buffer == nullptr || length == 0) {
311 return UEC_SERVICE_INVALID_VALUE;
312 }
313
314 uint32_t descriptorHeaderSize = sizeof(UsbdDescriptorHeader);
315 while (cursor < length) {
316 if (descriptorHeaderSize >= length - cursor) {
317 USB_HILOGE(MODULE_USB_SERVICE, "length error");
318 return UEC_SERVICE_INVALID_VALUE;
319 }
320 UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
321 if (descriptorHeader.bLength >= descriptorHeaderSize) {
322 USB_HILOGE(MODULE_USB_SERVICE, "descriptor size error");
323 return UEC_SERVICE_INVALID_VALUE;
324 }
325 if (descriptorHeader.bDescriptorType == static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_ENDPOINT)) {
326 break;
327 }
328 cursor += descriptorHeader.bLength;
329 USB_HILOGD(MODULE_USB_SERVICE, "error type = %{public}d, length=%{public}d", descriptorHeader.bDescriptorType,
330 descriptorHeader.bLength);
331 }
332
333 if (length - cursor < sizeof(UsbdInterfaceDescriptor)) {
334 USB_HILOGE(MODULE_USB_SERVICE, "insufficient length to parse interface descriptor");
335 return UEC_SERVICE_INVALID_VALUE;
336 }
337 UsbdEndpointDescriptor endpointDescriptor = *(reinterpret_cast<const UsbdEndpointDescriptor *>(buffer + cursor));
338 if (endpointDescriptor.bLength != NORMAL_ENDPOINT_DESCRIPTOR &&
339 endpointDescriptor.bLength != AUDIO_ENDPOINT_DESCRIPTOR) {
340 USB_HILOGE(MODULE_USB_SERVICE, "Endpoint descriptor size error, length=%{public}d", endpointDescriptor.bLength);
341 return UEC_SERVICE_INVALID_VALUE;
342 }
343 cursor += endpointDescriptor.bLength;
344
345 ep.SetAddr(endpointDescriptor.bEndpointAddress);
346 ep.SetAttr(endpointDescriptor.bmAttributes);
347 ep.SetInterval(endpointDescriptor.bInterval);
348 ep.SetMaxPacketSize(endpointDescriptor.wMaxPacketSize);
349 return UEC_OK;
350 }
351 } // namespace USB
352 } // namespace OHOS
353