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