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