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