• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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