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 #include "usb_config_desc_parser.h"
16
17 #include "edm_errors.h"
18 #include "hilog_wrapper.h"
19 #include "securec.h"
20 #include "usb_ddk_types.h"
21
22 namespace OHOS {
23 namespace ExternalDeviceManager {
24 struct UsbDescriptorHeader {
25 uint8_t bLength;
26 uint8_t bDescriptorType;
27 } __attribute__((packed));
28
29 enum UsbDdkDescriptorType {
30 USB_DDK_CONFIG_DESCRIPTOR_TYPE,
31 USB_DDK_INTERFACE_DESCRIPTOR_TYPE,
32 USB_DDK_ENDPOINT_DESCRIPTOR_TYPE,
33 USB_DDK_AUDIO_ENDPOINT_DESCRIPTOR_TYPE,
34 };
35
36 constexpr int32_t USB_MAXENDPOINTS = 32;
37 constexpr int32_t USB_MAXALTSETTING = 128;
38 constexpr int32_t DESC_HEADER_LENGTH = 2;
39 constexpr int32_t USB_MAXINTERFACES = 32;
40 constexpr int32_t USB_DDK_DT_CONFIG_SIZE = 0x09;
41 constexpr int32_t USB_DDK_DT_INTERFACE_SIZE = 0x09;
42 constexpr int32_t USB_DDK_DT_ENDPOINT_SIZE = 0x07;
43 constexpr int32_t USB_DDK_DT_CONFIG = 0x02;
44 constexpr int32_t USB_DDK_DT_INTERFACE = 0x04;
45 constexpr int32_t USB_DDK_DT_ENDPOINT = 0x05;
46
Le16ToHost(uint16_t number)47 static uint16_t Le16ToHost(uint16_t number)
48 {
49 uint8_t *addr = reinterpret_cast<uint8_t *>(&number);
50 uint16_t result = static_cast<uint16_t>(addr[1] << 8) | addr[0];
51 return result;
52 }
53
GetDescriptorLength(UsbDdkDescriptorType descriptorType)54 static int32_t GetDescriptorLength(UsbDdkDescriptorType descriptorType)
55 {
56 switch (descriptorType) {
57 case USB_DDK_CONFIG_DESCRIPTOR_TYPE:
58 return USB_DDK_DT_CONFIG_SIZE;
59 case USB_DDK_INTERFACE_DESCRIPTOR_TYPE:
60 return USB_DDK_DT_INTERFACE_SIZE;
61 case USB_DDK_ENDPOINT_DESCRIPTOR_TYPE:
62 return USB_DDK_DT_ENDPOINT_SIZE;
63 default:
64 EDM_LOGE(MODULE_USB_DDK, "invalid descriptorType:%{public}d", descriptorType);
65 }
66 return INT32_MAX;
67 }
68
ParseDescriptor(UsbDdkDescriptorType descriptorType,uint8_t * dest,uint32_t destLen,const uint8_t * source,int32_t sourceLen)69 static int32_t ParseDescriptor(
70 UsbDdkDescriptorType descriptorType, uint8_t *dest, uint32_t destLen, const uint8_t *source, int32_t sourceLen)
71 {
72 if (source == nullptr || dest == nullptr) {
73 EDM_LOGE(
74 MODULE_USB_DDK, "invalid param, source:%{public}d, dest:%{public}d", source == nullptr, dest == nullptr);
75 return USB_DDK_FAILED;
76 }
77
78 int32_t descriptorLen = GetDescriptorLength(descriptorType);
79 if (descriptorLen == INT32_MAX) {
80 return USB_DDK_FAILED;
81 }
82
83 if (sourceLen < descriptorLen) {
84 EDM_LOGE(MODULE_USB_DDK, "invalid sourceLen:%{public}u, descriptorType:%{public}d", sourceLen, descriptorType);
85 return USB_DDK_FAILED;
86 }
87
88 int32_t ret = memcpy_s(dest, destLen, source, descriptorLen);
89 if (ret != EOK) {
90 EDM_LOGE(MODULE_USB_DDK, "memcpy_s failed, ret = %{public}d", ret);
91 return USB_DDK_MEMORY_ERROR;
92 }
93
94 switch (descriptorType) {
95 case USB_DDK_CONFIG_DESCRIPTOR_TYPE: {
96 struct UsbConfigDescriptor *desc = reinterpret_cast<struct UsbConfigDescriptor *>(dest);
97 desc->wTotalLength = Le16ToHost(desc->wTotalLength);
98 break;
99 }
100 case USB_DDK_INTERFACE_DESCRIPTOR_TYPE:
101 break;
102 case USB_DDK_ENDPOINT_DESCRIPTOR_TYPE: {
103 UsbEndpointDescriptor *desc = reinterpret_cast<UsbEndpointDescriptor *>(dest);
104 desc->wMaxPacketSize = Le16ToHost(desc->wMaxPacketSize);
105 break;
106 }
107 default:
108 EDM_LOGE(MODULE_USB_DDK, "invalid descriptorType:%{public}d", descriptorType);
109 return USB_DDK_FAILED;
110 }
111 return EDM_OK;
112 }
113
FindNextDescriptor(const uint8_t * buffer,int32_t size)114 static int32_t FindNextDescriptor(const uint8_t *buffer, int32_t size)
115 {
116 const uint8_t *buffer0 = buffer;
117
118 while (size >= static_cast<int32_t>(sizeof(UsbDescriptorHeader))) {
119 auto header = reinterpret_cast<const UsbDescriptorHeader *>(buffer);
120 if (header->bDescriptorType == USB_DDK_DT_INTERFACE || header->bDescriptorType == USB_DDK_DT_ENDPOINT) {
121 break;
122 }
123 buffer += header->bLength;
124 size -= header->bLength;
125 }
126
127 return buffer - buffer0;
128 }
129
FillExtraDescriptor(const unsigned char ** extra,uint32_t * extraLength,const uint8_t * buffer,int32_t bufferLen)130 static int32_t FillExtraDescriptor(
131 const unsigned char **extra, uint32_t *extraLength, const uint8_t *buffer, int32_t bufferLen)
132 {
133 if (bufferLen == 0) {
134 EDM_LOGE(MODULE_USB_DDK, "invalid param");
135 return USB_DDK_FAILED;
136 }
137
138 uint32_t extraLenTmp = *extraLength + static_cast<uint32_t>(bufferLen);
139 unsigned char *extraTmp = new unsigned char[extraLenTmp];
140 if (extraTmp == nullptr) {
141 EDM_LOGE(MODULE_USB_DDK, "new failed");
142 return USB_DDK_MEMORY_ERROR;
143 }
144 (void)memset_s(static_cast<void *>(extraTmp), extraLenTmp, 0, extraLenTmp);
145
146 if (*extra != nullptr && *extraLength != 0) {
147 if (memcpy_s(extraTmp, extraLenTmp, *extra, *extraLength) != EOK) {
148 EDM_LOGE(MODULE_USB_DDK, "copy extra failed");
149 delete[] extraTmp;
150 return USB_DDK_MEMORY_ERROR;
151 }
152 }
153
154 if (memcpy_s(extraTmp + *extraLength, extraLenTmp - *extraLength, buffer, bufferLen) != EOK) {
155 EDM_LOGE(MODULE_USB_DDK, "copy buffer failed");
156 delete[] extraTmp;
157 return USB_DDK_MEMORY_ERROR;
158 }
159
160 if (*extra != nullptr) {
161 delete[] (*extra);
162 }
163 *extra = extraTmp;
164 *extraLength = extraLenTmp;
165
166 return EDM_OK;
167 }
168
ParseEndpoint(UsbDdkEndpointDescriptor * endPoint,const uint8_t * buffer,int32_t size)169 static int32_t ParseEndpoint(UsbDdkEndpointDescriptor *endPoint, const uint8_t *buffer, int32_t size)
170 {
171 const uint8_t *buffer0 = buffer;
172 int32_t len;
173 int32_t ret;
174
175 if (size < DESC_HEADER_LENGTH) {
176 EDM_LOGE(MODULE_USB_DDK, "size = %{public}d is short endPoint descriptor", size);
177 return USB_DDK_FAILED;
178 }
179
180 auto header = reinterpret_cast<const UsbDescriptorHeader *>(buffer);
181 if ((header->bDescriptorType != USB_DDK_DT_ENDPOINT) || (header->bLength > size)) {
182 EDM_LOGE(MODULE_USB_DDK, "unexpected descriptor, type = 0x%{public}x, length = %{public}hhu",
183 header->bDescriptorType, header->bLength);
184 return buffer - buffer0;
185 } else if (header->bLength < USB_DDK_DT_ENDPOINT_SIZE) {
186 EDM_LOGE(MODULE_USB_DDK, "invalid endpoint length = %{public}hhu", header->bLength);
187 return USB_DDK_FAILED;
188 }
189
190 ParseDescriptor(USB_DDK_ENDPOINT_DESCRIPTOR_TYPE, reinterpret_cast<uint8_t *>(endPoint),
191 sizeof(UsbEndpointDescriptor), buffer, size);
192
193 buffer += header->bLength;
194 size -= header->bLength;
195
196 len = FindNextDescriptor(buffer, size);
197 if (!len) {
198 return buffer - buffer0;
199 }
200 ret = FillExtraDescriptor(&endPoint->extra, &endPoint->extraLength, buffer, len);
201 if (ret != EDM_OK) {
202 EDM_LOGE(MODULE_USB_DDK, "FillExtraDescriptor failed");
203 return ret;
204 }
205 return buffer + len - buffer0;
206 }
207
RawParseDescriptor(int32_t size,const uint8_t * buffer,UsbDdkDescriptorType bDescriptorType,UsbDdkInterfaceDescriptor & ddkIntfDesc)208 static int32_t RawParseDescriptor(
209 int32_t size, const uint8_t *buffer, UsbDdkDescriptorType bDescriptorType, UsbDdkInterfaceDescriptor &ddkIntfDesc)
210 {
211 int32_t ret =
212 ParseDescriptor(bDescriptorType, (uint8_t *)&ddkIntfDesc, sizeof(UsbInterfaceDescriptor), buffer, size);
213 if (ret != EDM_OK) {
214 EDM_LOGE(MODULE_USB_DDK, "ParseDescriptor failed");
215 return ret;
216 }
217 if ((ddkIntfDesc.interfaceDescriptor.bDescriptorType != USB_DDK_DT_INTERFACE) ||
218 (ddkIntfDesc.interfaceDescriptor.bLength > size)) {
219 EDM_LOGE(MODULE_USB_DDK, "unexpected descriptor: type = 0x%{public}x, size = %{public}d",
220 ddkIntfDesc.interfaceDescriptor.bDescriptorType, size);
221 ret = USB_DDK_INVALID_PARAMETER;
222 } else if ((ddkIntfDesc.interfaceDescriptor.bLength < USB_DDK_DT_INTERFACE_SIZE) ||
223 (ddkIntfDesc.interfaceDescriptor.bNumEndpoints > USB_MAXENDPOINTS)) {
224 EDM_LOGE(MODULE_USB_DDK, "invalid descriptor: length = %{public}u, numEndpoints = %{public}u",
225 ddkIntfDesc.interfaceDescriptor.bLength, ddkIntfDesc.interfaceDescriptor.bNumEndpoints);
226 ret = USB_DDK_INVALID_OPERATION;
227 }
228
229 return ret;
230 }
231
ParseInterfaceEndpoint(UsbDdkInterfaceDescriptor & ddkIntfDesc,const uint8_t ** buffer,int32_t * size)232 static int32_t ParseInterfaceEndpoint(UsbDdkInterfaceDescriptor &ddkIntfDesc, const uint8_t **buffer, int32_t *size)
233 {
234 UsbDdkEndpointDescriptor *endPoint = nullptr;
235 int32_t ret = EDM_OK;
236
237 if (ddkIntfDesc.interfaceDescriptor.bNumEndpoints > 0) {
238 endPoint = new UsbDdkEndpointDescriptor[ddkIntfDesc.interfaceDescriptor.bNumEndpoints];
239 if (endPoint == nullptr) {
240 ret = USB_DDK_MEMORY_ERROR;
241 return ret;
242 }
243 auto len = ddkIntfDesc.interfaceDescriptor.bNumEndpoints * sizeof(UsbDdkEndpointDescriptor);
244 (void)memset_s(static_cast<void *>(endPoint), len, 0, len);
245
246 ddkIntfDesc.endPoint = endPoint;
247 for (uint8_t i = 0; i < ddkIntfDesc.interfaceDescriptor.bNumEndpoints; i++) {
248 ret = ParseEndpoint(endPoint + i, *buffer, *size);
249 if (ret == 0) {
250 ddkIntfDesc.interfaceDescriptor.bNumEndpoints = i;
251 break;
252 } else if (ret < 0) {
253 return ret;
254 }
255
256 *buffer += ret;
257 *size -= ret;
258 }
259 }
260 return ret;
261 }
262
GetInterfaceNumberDes(const UsbDescriptorHeader * header,std::vector<uint8_t> & interfaceNums,std::vector<uint8_t> & alternateSetting)263 static void GetInterfaceNumberDes(
264 const UsbDescriptorHeader *header, std::vector<uint8_t> &interfaceNums, std::vector<uint8_t> &alternateSetting)
265 {
266 auto desc = reinterpret_cast<const UsbInterfaceDescriptor *>(header);
267 if (desc->bLength < USB_DDK_DT_INTERFACE_SIZE) {
268 EDM_LOGW(MODULE_USB_DDK, "invalid interface descriptor length %{public}d, skipping", desc->bLength);
269 return;
270 }
271
272 uint8_t intfNum = desc->bInterfaceNumber;
273 size_t currentSize = interfaceNums.size();
274 size_t i;
275 for (i = 0; i < currentSize; ++i) {
276 if (interfaceNums[i] == intfNum) {
277 break;
278 }
279 }
280 if (i < currentSize) {
281 if (alternateSetting[i] < USB_MAXALTSETTING) {
282 ++(alternateSetting[i]);
283 }
284 } else if (currentSize < USB_MAXINTERFACES) {
285 interfaceNums.emplace_back(intfNum);
286 alternateSetting.emplace_back(1);
287 }
288 }
289
290 // return number of interfaces
291 // intf contains all interface numbers
292 // alts contains the number of alternate settings on the corresponding interface
GetInterfaceNumber(const uint8_t * buffer,int32_t size,std::vector<uint8_t> & interfaceNums,std::vector<uint8_t> & alternateSetting)293 static void GetInterfaceNumber(
294 const uint8_t *buffer, int32_t size, std::vector<uint8_t> &interfaceNums, std::vector<uint8_t> &alternateSetting)
295 {
296 const UsbDescriptorHeader *header = nullptr;
297 const uint8_t *buffer2;
298 int32_t size2;
299
300 for ((buffer2 = buffer, size2 = size); size2 > 0; (buffer2 += header->bLength, size2 -= header->bLength)) {
301 if (size2 < static_cast<int32_t>(sizeof(UsbDescriptorHeader))) {
302 EDM_LOGW(MODULE_USB_DDK, "descriptor has %{public}d excess bytes", size2);
303 break;
304 }
305 header = reinterpret_cast<const UsbDescriptorHeader *>(buffer2);
306 if ((header->bLength > size2) || (header->bLength < sizeof(UsbDescriptorHeader))) {
307 EDM_LOGW(MODULE_USB_DDK, "invalid descriptor length %{public}hhu, skipping remainder", header->bLength);
308 break;
309 }
310
311 if (header->bDescriptorType == USB_DDK_DT_INTERFACE) {
312 GetInterfaceNumberDes(header, interfaceNums, alternateSetting);
313 }
314 }
315 }
316
ParseInterface(UsbDdkInterface & usbInterface,const uint8_t * buffer,int32_t size)317 static int32_t ParseInterface(UsbDdkInterface &usbInterface, const uint8_t *buffer, int32_t size)
318 {
319 const uint8_t *buffer0 = buffer;
320 int32_t interfaceNumber = -1; // initial value of interfaceNumber is -1
321 const UsbInterfaceDescriptor *ifDesc = nullptr;
322
323 if (usbInterface.numAltsetting > USB_MAXALTSETTING) {
324 EDM_LOGE(MODULE_USB_DDK, "usbInterface is null or numAltsetting is invalid");
325 return USB_DDK_FAILED;
326 }
327
328 while (size >= USB_DDK_DT_INTERFACE_SIZE) {
329 UsbDdkInterfaceDescriptor &ddkIntfDesc = usbInterface.altsetting[usbInterface.numAltsetting];
330 int32_t ret = RawParseDescriptor(size, buffer, USB_DDK_INTERFACE_DESCRIPTOR_TYPE, ddkIntfDesc);
331 if (ret == USB_DDK_INVALID_PARAMETER) {
332 return buffer - buffer0;
333 } else if (ret == USB_DDK_INVALID_OPERATION) {
334 EDM_LOGE(MODULE_USB_DDK, "RawParseDescriptor failed");
335 return ret;
336 }
337
338 usbInterface.numAltsetting++;
339 ddkIntfDesc.extra = nullptr;
340 ddkIntfDesc.extraLength = 0;
341 ddkIntfDesc.endPoint = nullptr;
342 if (interfaceNumber == -1) {
343 interfaceNumber = ddkIntfDesc.interfaceDescriptor.bInterfaceNumber;
344 }
345
346 buffer += ddkIntfDesc.interfaceDescriptor.bLength;
347 size -= ddkIntfDesc.interfaceDescriptor.bLength;
348 int32_t len = FindNextDescriptor(buffer, size);
349 if (len != 0) {
350 if (FillExtraDescriptor(&ddkIntfDesc.extra, &ddkIntfDesc.extraLength, buffer, len) != EDM_OK) {
351 EDM_LOGE(MODULE_USB_DDK, "FillExtraDescriptor failed");
352 return USB_DDK_INVALID_PARAMETER;
353 }
354 buffer += len;
355 size -= len;
356 }
357
358 ret = ParseInterfaceEndpoint(ddkIntfDesc, &buffer, &size);
359 if (ret < EDM_OK) {
360 EDM_LOGE(MODULE_USB_DDK, "ParseInterfaceEndpoint, ret less than zero");
361 return ret;
362 }
363
364 ifDesc = reinterpret_cast<const UsbInterfaceDescriptor *>(buffer);
365 bool tempFlag = (size < USB_DDK_DT_INTERFACE_SIZE) || (ifDesc->bDescriptorType != USB_DDK_DT_INTERFACE) ||
366 (ifDesc->bInterfaceNumber != interfaceNumber);
367 if (tempFlag == true) {
368 return buffer - buffer0;
369 }
370 }
371
372 return buffer - buffer0;
373 }
374
ClearEndpoint(UsbDdkEndpointDescriptor * endPoint)375 static void ClearEndpoint(UsbDdkEndpointDescriptor *endPoint)
376 {
377 if ((endPoint != nullptr) && (endPoint->extra != nullptr)) {
378 delete[] (endPoint->extra);
379 endPoint->extra = nullptr;
380 }
381 }
382
ClearInterface(UsbDdkInterface & usbInterface)383 static void ClearInterface(UsbDdkInterface &usbInterface)
384 {
385 uint8_t i;
386 uint8_t j;
387
388 if (usbInterface.numAltsetting > USB_MAXALTSETTING) {
389 EDM_LOGE(MODULE_USB_DDK, "numAltsetting = %{public}hhu is error", usbInterface.numAltsetting);
390 return;
391 }
392
393 for (i = 0; i < usbInterface.numAltsetting; i++) {
394 auto infPtr = reinterpret_cast<UsbDdkInterfaceDescriptor *>(usbInterface.altsetting + i);
395 if (infPtr == nullptr) {
396 EDM_LOGE(MODULE_USB_DDK, "altsetting is null");
397 continue;
398 }
399
400 if (infPtr->extra != nullptr) {
401 delete[] (infPtr->extra);
402 infPtr->extra = nullptr;
403 }
404
405 if (infPtr->endPoint != nullptr) {
406 for (j = 0; j < infPtr->interfaceDescriptor.bNumEndpoints; j++) {
407 ClearEndpoint(reinterpret_cast<UsbDdkEndpointDescriptor *>(infPtr->endPoint + j));
408 }
409
410 delete[] (infPtr->endPoint);
411 infPtr->endPoint = nullptr;
412 }
413 }
414
415 delete[] usbInterface.altsetting;
416 }
417
RawClearConfiguration(UsbDdkConfigDescriptor & config)418 void RawClearConfiguration(UsbDdkConfigDescriptor &config)
419 {
420 uint8_t i;
421 if (config.interface != nullptr) {
422 for (i = 0; i < config.configDescriptor.bNumInterfaces; i++) {
423 ClearInterface(config.interface[i]);
424 }
425 }
426
427 if (config.interface != nullptr) {
428 delete[] config.interface;
429 config.interface = nullptr;
430 }
431
432 if (config.extra != nullptr) {
433 delete[] (config.extra);
434 config.extra = nullptr;
435 }
436 }
437
ParseConfigurationDes(UsbDdkConfigDescriptor & config,const uint8_t * buffer,int32_t size,std::vector<uint8_t> & interfaceNums)438 static int32_t ParseConfigurationDes(
439 UsbDdkConfigDescriptor &config, const uint8_t *buffer, int32_t size, std::vector<uint8_t> &interfaceNums)
440 {
441 int32_t ret;
442 while (size >= static_cast<int32_t>(sizeof(UsbDescriptorHeader))) {
443 int32_t len = FindNextDescriptor(buffer, size);
444 if (len != 0) {
445 ret = FillExtraDescriptor(&config.extra, &config.extraLength, buffer, len);
446 if (ret != EDM_OK) {
447 EDM_LOGE(MODULE_USB_DDK, "FillExtraDescriptor failed");
448 return ret;
449 }
450 buffer += len;
451 size -= len;
452 }
453
454 if (size <= static_cast<int32_t>(sizeof(UsbDescriptorHeader))) {
455 break;
456 }
457 auto ifDesc = reinterpret_cast<const UsbInterfaceDescriptor *>(buffer);
458 if (config.configDescriptor.bNumInterfaces >= USB_MAXINTERFACES) {
459 EDM_LOGE(MODULE_USB_DDK, "%{public}d: bNumInterfaces overlong.", config.configDescriptor.bNumInterfaces);
460 return USB_DDK_INVALID_PARAMETER;
461 }
462 uint8_t i = 0;
463 for (; i < config.configDescriptor.bNumInterfaces; ++i) {
464 if (interfaceNums[i] == ifDesc->bInterfaceNumber) {
465 break;
466 }
467 }
468 if (i == config.configDescriptor.bNumInterfaces) {
469 EDM_LOGE(MODULE_USB_DDK, "%{public}u: bInterfaceNumber not found.", ifDesc->bInterfaceNumber);
470 return USB_DDK_INVALID_PARAMETER;
471 }
472 ret = ParseInterface(config.interface[i], buffer, size);
473 if (ret < 0) {
474 EDM_LOGE(MODULE_USB_DDK, "%{public}u: Parse interface failed.", ifDesc->bInterfaceNumber);
475 return ret;
476 }
477
478 buffer += ret;
479 size -= ret;
480 }
481
482 return size;
483 }
484
485 // On error, return errcode, negative number
486 // On success, return 0, means all buffer are resolved into the config; return positive number, means buffer size that
487 // is not resolved
ParseConfiguration(UsbDdkConfigDescriptor & config,const uint8_t * buffer,int32_t size)488 static int32_t ParseConfiguration(UsbDdkConfigDescriptor &config, const uint8_t *buffer, int32_t size)
489 {
490 if (size < USB_DDK_DT_CONFIG_SIZE) {
491 EDM_LOGE(MODULE_USB_DDK, "size = %{public}u is short, or config is null!", size);
492 return USB_DDK_INVALID_OPERATION;
493 }
494
495 ParseDescriptor(
496 USB_DDK_CONFIG_DESCRIPTOR_TYPE, (uint8_t *)&config, sizeof(struct UsbConfigDescriptor), buffer, size);
497 if ((config.configDescriptor.bDescriptorType != USB_DDK_DT_CONFIG) ||
498 (config.configDescriptor.bLength < USB_DDK_DT_CONFIG_SIZE) ||
499 (config.configDescriptor.bLength > (uint8_t)size) ||
500 (config.configDescriptor.bNumInterfaces > USB_MAXINTERFACES)) {
501 EDM_LOGE(MODULE_USB_DDK, "invalid descriptor: type = 0x%{public}x, length = %{public}u",
502 config.configDescriptor.bDescriptorType, config.configDescriptor.bLength);
503 return USB_DDK_INVALID_OPERATION;
504 }
505
506 std::vector<uint8_t> interfaceNums;
507 std::vector<uint8_t> alternateSetting;
508 GetInterfaceNumber(buffer, size, interfaceNums, alternateSetting);
509
510 size_t intfNum = interfaceNums.size();
511 if (intfNum == 0 || intfNum > USB_MAXALTSETTING) {
512 EDM_LOGE(MODULE_USB_DDK, "interface num is zero");
513 return USB_DDK_INVALID_OPERATION;
514 }
515
516 config.configDescriptor.bNumInterfaces = (uint8_t)intfNum;
517 config.interface = new UsbDdkInterface[intfNum];
518 if (config.interface == nullptr) {
519 EDM_LOGE(MODULE_USB_DDK, "new UsbDdkInterface failed");
520 return USB_DDK_MEMORY_ERROR;
521 }
522 (void)memset_s(
523 static_cast<void *>(config.interface), sizeof(UsbDdkInterface) * intfNum, 0, sizeof(UsbDdkInterface) * intfNum);
524
525 for (size_t i = 0; i < intfNum; ++i) {
526 uint8_t j = alternateSetting[i];
527 if (j > USB_MAXALTSETTING) {
528 EDM_LOGE(MODULE_USB_DDK, "too many alternate settings: %{public}hhu", j);
529 alternateSetting[i] = USB_MAXALTSETTING;
530 j = USB_MAXALTSETTING;
531 }
532 config.interface[i].altsetting = new UsbDdkInterfaceDescriptor[j];
533 if (config.interface[i].altsetting == nullptr) {
534 EDM_LOGE(MODULE_USB_DDK, "new UsbDdkInterfaceDescriptor failed");
535 return USB_DDK_MEMORY_ERROR;
536 }
537 (void)memset_s(static_cast<void *>(config.interface[i].altsetting), sizeof(UsbDdkInterfaceDescriptor) * j, 0,
538 sizeof(UsbDdkInterfaceDescriptor) * j);
539 }
540
541 buffer += config.configDescriptor.bLength;
542 size -= config.configDescriptor.bLength;
543
544 return ParseConfigurationDes(config, buffer, size, interfaceNums);
545 }
546
ParseUsbConfigDescriptor(const std::vector<uint8_t> & configBuffer,UsbDdkConfigDescriptor ** const config)547 int32_t ParseUsbConfigDescriptor(const std::vector<uint8_t> &configBuffer, UsbDdkConfigDescriptor ** const config)
548 {
549 UsbDdkConfigDescriptor *tmpConfig = new UsbDdkConfigDescriptor();
550 if (tmpConfig == nullptr) {
551 EDM_LOGE(MODULE_USB_DDK, "new failed");
552 return USB_DDK_MEMORY_ERROR;
553 }
554 (void)memset_s(static_cast<void *>(tmpConfig), sizeof(UsbDdkConfigDescriptor), 0, sizeof(UsbDdkConfigDescriptor));
555
556 int32_t ret = ParseConfiguration(*tmpConfig, configBuffer.data(), configBuffer.size());
557 if (ret < 0) {
558 EDM_LOGE(MODULE_USB_DDK, "ParseConfiguration failed with error = %{public}d", ret);
559 FreeUsbConfigDescriptor(tmpConfig);
560 tmpConfig = nullptr;
561 return ret;
562 } else if (ret > 0) {
563 EDM_LOGW(MODULE_USB_DDK, "still %{public}d bytes of descriptor data left", ret);
564 }
565
566 *config = tmpConfig;
567 return ret;
568 }
569
FreeUsbConfigDescriptor(UsbDdkConfigDescriptor * const config)570 void FreeUsbConfigDescriptor(UsbDdkConfigDescriptor * const config)
571 {
572 if (config == nullptr) {
573 EDM_LOGE(MODULE_USB_DDK, "config is nullptr");
574 return;
575 }
576
577 RawClearConfiguration(*config);
578 delete config;
579 }
580 } // namespace ExternalDeviceManager
581 } // namespace OHOS