• 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 namespace OHOS {
27 namespace USB {
28 enum class DescriptorType {
29     DESCRIPTOR_TYPE_DEVICE = 1,
30     DESCRIPTOR_TYPE_CONFIG = 2,
31     DESCRIPTOR_TYPE_INTERFACE = 4,
32     DESCRIPTOR_TYPE_ENDPOINT = 5
33 };
34 
UsbDescriptorParser()35 UsbDescriptorParser::UsbDescriptorParser() {}
36 
~UsbDescriptorParser()37 UsbDescriptorParser::~UsbDescriptorParser() {}
38 
ParseDeviceDescriptor(const uint8_t * buffer,uint32_t length,UsbDevice & dev)39 int32_t UsbDescriptorParser::ParseDeviceDescriptor(const uint8_t *buffer, uint32_t length, UsbDevice &dev)
40 {
41     if (buffer == nullptr || length == 0) {
42         USB_HILOGE(MODULE_USB_SERVICE, "buffer is null");
43         return UEC_SERVICE_INVALID_VALUE;
44     }
45 
46     USB_HILOGI(MODULE_USB_SERVICE, "parse begin length=%{public}u", length);
47     uint32_t deviceDescriptorSize = sizeof(UsbdDeviceDescriptor);
48     if (length < deviceDescriptorSize) {
49         USB_HILOGE(MODULE_USB_SERVICE, "buffer size error");
50         return UEC_SERVICE_INVALID_VALUE;
51     }
52 
53     UsbdDeviceDescriptor deviceDescriptor = *(reinterpret_cast<const UsbdDeviceDescriptor *>(buffer));
54     if (deviceDescriptor.bLength != deviceDescriptorSize) {
55         USB_HILOGE(MODULE_USB_SERVICE, "UsbdDeviceDescriptor size error");
56         return UEC_SERVICE_INVALID_VALUE;
57     }
58 
59     dev.SetVendorId(deviceDescriptor.idVendor);
60     dev.SetProductId(deviceDescriptor.idProduct);
61     dev.SetClass(deviceDescriptor.bDeviceClass);
62     dev.SetSubclass(deviceDescriptor.bDeviceSubClass);
63     dev.SetDescConfigCount(deviceDescriptor.bNumConfigurations);
64 
65     dev.SetbMaxPacketSize0(deviceDescriptor.bMaxPacketSize0);
66     dev.SetbcdDevice(deviceDescriptor.bcdDevice);
67     dev.SetbcdUSB(deviceDescriptor.bcdUSB);
68     dev.SetiManufacturer(deviceDescriptor.iManufacturer);
69     dev.SetiProduct(deviceDescriptor.iProduct);
70     dev.SetiSerialNumber(deviceDescriptor.iSerialNumber);
71     return UEC_OK;
72 }
73 
ParseConfigDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,USBConfig & config)74 int32_t UsbDescriptorParser::ParseConfigDescriptor(
75     const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBConfig &config)
76 {
77     if (buffer == nullptr || length == 0) {
78         return UEC_SERVICE_INVALID_VALUE;
79     }
80 
81     USB_HILOGI(MODULE_USB_SERVICE, "parse begin length=%{public}u, cursor=%{public}u", length, cursor);
82     uint32_t configDescriptorSize = sizeof(UsbdConfigDescriptor);
83     if (length < configDescriptorSize) {
84         USB_HILOGE(MODULE_USB_SERVICE, "buffer size error");
85         return UEC_SERVICE_INVALID_VALUE;
86     }
87 
88     UsbdConfigDescriptor configDescriptor = *(reinterpret_cast<const UsbdConfigDescriptor *>(buffer));
89     cursor += configDescriptorSize;
90     if (configDescriptor.bLength != configDescriptorSize) {
91         USB_HILOGE(MODULE_USB_SERVICE, "UsbdDeviceDescriptor size error");
92         return UEC_SERVICE_INVALID_VALUE;
93     }
94 
95     config.SetId(configDescriptor.bConfigurationValue);
96     config.SetAttribute(configDescriptor.bmAttributes);
97     config.SetMaxPower(configDescriptor.bMaxPower);
98     config.SetiConfiguration(configDescriptor.iConfiguration);
99 
100     std::vector<UsbInterface> interfaces;
101     for (int32_t i = 0; (i < configDescriptor.bNumInterfaces) && (cursor < length); ++i) {
102         uint32_t interfaceCursor = 0;
103         UsbInterface interface;
104         ParseInterfaceDescriptor(
105             buffer + cursor + interfaceCursor, length - cursor - interfaceCursor, interfaceCursor, interface);
106         bool isRepeat = false;
107         auto iter = interfaces.begin();
108         while (iter != interfaces.end()) {
109             if (iter->GetId() == interface.GetId()) {
110                 isRepeat = true;
111                 break;
112             }
113             iter++;
114         }
115         if (interface.GetEndpointCount() >= 0 && !isRepeat) {
116             interfaces.push_back(interface);
117         } else {
118             // retry
119             if (interface.GetEndpointCount() > 0 && iter != interfaces.end()) {
120                 USB_HILOGE(MODULE_USB_SERVICE, "get repeat interface id info, and has endpoints");
121                 *iter = interface;
122             }
123             --i;
124         }
125         cursor += interfaceCursor;
126     }
127     config.SetInterfaces(interfaces);
128     return UEC_OK;
129 }
130 
ParseInterfaceDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,UsbInterface & interface)131 int32_t UsbDescriptorParser::ParseInterfaceDescriptor(
132     const uint8_t *buffer, uint32_t length, uint32_t &cursor, UsbInterface &interface)
133 {
134     if (buffer == nullptr || length == 0) {
135         return UEC_SERVICE_INVALID_VALUE;
136     }
137 
138     uint32_t descriptorHeaderSize = sizeof(UsbdDescriptorHeader);
139     while (static_cast<uint32_t>(cursor) < length) {
140         if (descriptorHeaderSize >= length) {
141             USB_HILOGE(MODULE_USB_SERVICE, "length error");
142             return UEC_SERVICE_INVALID_VALUE;
143         }
144         UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
145         if (descriptorHeader.bLength > length) {
146             USB_HILOGE(MODULE_USB_SERVICE, "descriptor size error");
147             return UEC_SERVICE_INVALID_VALUE;
148         }
149         if (descriptorHeader.bDescriptorType == static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_INTERFACE)) {
150             break;
151         }
152         cursor += descriptorHeader.bLength;
153         USB_HILOGI(MODULE_USB_SERVICE, "type = %{public}d, length=%{public}d", descriptorHeader.bDescriptorType,
154             descriptorHeader.bLength);
155     }
156 
157     UsbdInterfaceDescriptor interfaceDescriptor = *(reinterpret_cast<const UsbdInterfaceDescriptor *>(buffer + cursor));
158     if (interfaceDescriptor.bLength != sizeof(UsbdInterfaceDescriptor)) {
159         USB_HILOGE(MODULE_USB_SERVICE, "UsbdInterfaceDescriptor size error");
160         return UEC_SERVICE_INVALID_VALUE;
161     }
162     cursor += interfaceDescriptor.bLength;
163 
164     interface.SetId(interfaceDescriptor.bInterfaceNumber);
165     interface.SetProtocol(interfaceDescriptor.bInterfaceProtocol);
166     interface.SetAlternateSetting(interfaceDescriptor.bAlternateSetting);
167     interface.SetClass(interfaceDescriptor.bInterfaceClass);
168     interface.SetSubClass(interfaceDescriptor.bInterfaceSubClass);
169     interface.SetiInterface(interfaceDescriptor.iInterface);
170 
171     std::vector<USBEndpoint> eps;
172     for (int32_t j = 0; j < interfaceDescriptor.bNumEndpoints; ++j) {
173         uint32_t epCursor = 0;
174         USBEndpoint ep;
175         ParseEndpointDescriptor(buffer + cursor + epCursor, length - cursor - epCursor, epCursor, ep);
176         ep.SetInterfaceId(interfaceDescriptor.bInterfaceNumber);
177         eps.push_back(ep);
178         cursor += epCursor;
179     }
180     interface.SetEndpoints(eps);
181     USB_HILOGE(MODULE_USB_SERVICE, "interface to string : %{public}s", interface.ToString().c_str());
182     return UEC_OK;
183 }
184 
ParseEndpointDescriptor(const uint8_t * buffer,uint32_t length,uint32_t & cursor,USBEndpoint & ep)185 int32_t UsbDescriptorParser::ParseEndpointDescriptor(
186     const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBEndpoint &ep)
187 {
188     USB_HILOGI(MODULE_USB_SERVICE, "parse begin, length=%{public}u, cursor=%{public}u", length, cursor);
189     if (buffer == nullptr || length == 0) {
190         return UEC_SERVICE_INVALID_VALUE;
191     }
192 
193     uint32_t descriptorHeaderSize = sizeof(UsbdDescriptorHeader);
194     while (static_cast<uint32_t>(cursor) < length) {
195         if (descriptorHeaderSize >= length) {
196             USB_HILOGE(MODULE_USB_SERVICE, "length error");
197             return UEC_SERVICE_INVALID_VALUE;
198         }
199         UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast<const UsbdDescriptorHeader *>(buffer + cursor));
200         if (descriptorHeader.bLength > length) {
201             USB_HILOGE(MODULE_USB_SERVICE, "descriptor size error");
202             return UEC_SERVICE_INVALID_VALUE;
203         }
204         if (descriptorHeader.bDescriptorType == static_cast<uint8_t>(DescriptorType::DESCRIPTOR_TYPE_ENDPOINT)) {
205             break;
206         }
207         cursor += descriptorHeader.bLength;
208         USB_HILOGI(MODULE_USB_SERVICE, "error type = %{public}d, length=%{public}d", descriptorHeader.bDescriptorType,
209             descriptorHeader.bLength);
210     }
211 
212     UsbdEndpointDescriptor endpointDescriptor = *(reinterpret_cast<const UsbdEndpointDescriptor *>(buffer + cursor));
213     if (endpointDescriptor.bLength != sizeof(UsbdEndpointDescriptor)) {
214         USB_HILOGE(MODULE_USB_SERVICE, "Endpoint descriptor size error, length=%{public}d", endpointDescriptor.bLength);
215         return UEC_SERVICE_INVALID_VALUE;
216     }
217     cursor += endpointDescriptor.bLength;
218 
219     ep.SetAddr(endpointDescriptor.bEndpointAddress);
220     ep.SetAttr(endpointDescriptor.bmAttributes);
221     ep.SetInterval(endpointDescriptor.bInterval);
222     ep.SetMaxPacketSize(endpointDescriptor.wMaxPacketSize);
223     return UEC_OK;
224 }
225 } // namespace USB
226 } // namespace OHOS
227