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