1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdio.h>
8 #include "unity.h"
9 #include "test_utils.h"
10 #include "usb/usb_host.h"
11
12 /*
13 Tests that check the configuration descriptor parsing functions provided in usb_host.h work by parsing a fixed
14 configuration descriptor. The fixed configuration descriptor used in this test is provided below (both in textual and
15 byte format), and is of a UVC device. Thus the configuration descriptor has a good set of scenarios that can be tested
16 (such as multiple interfaces, alternate settings, class specific descriptors, default endpoint only interfaces etc).
17 */
18
19 /*
20 Configuration Descriptor:
21 bLength 9
22 bDescriptorType 2
23 wTotalLength 0x0185
24 bNumInterfaces 2
25 bConfigurationValue 1
26 iConfiguration 0
27 bmAttributes 0x80
28 (Bus Powered)
29 MaxPower 500mA
30 Interface Association:
31 bLength 8
32 bDescriptorType 11
33 bFirstInterface 0
34 bInterfaceCount 2
35 bFunctionClass 14 Video
36 bFunctionSubClass 3 Video Interface Collection
37 bFunctionProtocol 0
38 iFunction 5
39 Interface Descriptor:
40 bLength 9
41 bDescriptorType 4
42 bInterfaceNumber 0
43 bAlternateSetting 0
44 bNumEndpoints 1
45 bInterfaceClass 14 Video
46 bInterfaceSubClass 1 Video Control
47 bInterfaceProtocol 0
48 iInterface 5
49 VideoControl Interface Descriptor:
50 bLength 13
51 bDescriptorType 36
52 bDescriptorSubtype 1 (HEADER)
53 bcdUVC 1.00
54 wTotalLength 0x004f
55 dwClockFrequency 15.000000MHz
56 bInCollection 1
57 baInterfaceNr( 0) 1
58 VideoControl Interface Descriptor:
59 bLength 9
60 bDescriptorType 36
61 bDescriptorSubtype 3 (OUTPUT_TERMINAL)
62 bTerminalID 4
63 wTerminalType 0x0101 USB Streaming
64 bAssocTerminal 0
65 bSourceID 3
66 iTerminal 0
67 VideoControl Interface Descriptor:
68 bLength 28
69 bDescriptorType 36
70 bDescriptorSubtype 6 (EXTENSION_UNIT)
71 bUnitID 3
72 guidExtensionCode {4cf18db6-abd0-495c-9876-1fa3942ff9fa}
73 bNumControl 24
74 bNrPins 1
75 baSourceID( 0) 2
76 bControlSize 3
77 bmControls( 0) 0xff
78 bmControls( 1) 0xff
79 bmControls( 2) 0xff
80 iExtension 0
81 VideoControl Interface Descriptor:
82 bLength 18
83 bDescriptorType 36
84 bDescriptorSubtype 2 (INPUT_TERMINAL)
85 bTerminalID 1
86 wTerminalType 0x0201 Camera Sensor
87 bAssocTerminal 0
88 iTerminal 0
89 wObjectiveFocalLengthMin 0
90 wObjectiveFocalLengthMax 0
91 wOcularFocalLength 0
92 bControlSize 3
93 bmControls 0x0000000e
94 Auto-Exposure Mode
95 Auto-Exposure Priority
96 Exposure Time (Absolute)
97 VideoControl Interface Descriptor:
98 bLength 11
99 bDescriptorType 36
100 bDescriptorSubtype 5 (PROCESSING_UNIT)
101 Warning: Descriptor too short
102 bUnitID 2
103 bSourceID 1
104 wMaxMultiplier 0
105 bControlSize 2
106 bmControls 0x0000177f
107 Brightness
108 Contrast
109 Hue
110 Saturation
111 Sharpness
112 Gamma
113 White Balance Temperature
114 Backlight Compensation
115 Gain
116 Power Line Frequency
117 White Balance Temperature, Auto
118 iProcessing 0
119 bmVideoStandards 0x62
120 NTSC - 525/60
121 PAL - 525/60
122 Endpoint Descriptor:
123 bLength 7
124 bDescriptorType 5
125 bEndpointAddress 0x83 EP 3 IN
126 bmAttributes 3
127 Transfer Type Interrupt
128 Synch Type None
129 Usage Type Data
130 wMaxPacketSize 0x0010 1x 16 bytes
131 bInterval 6
132 Interface Descriptor:
133 bLength 9
134 bDescriptorType 4
135 bInterfaceNumber 1
136 bAlternateSetting 0
137 bNumEndpoints 0
138 bInterfaceClass 14 Video
139 bInterfaceSubClass 2 Video Streaming
140 bInterfaceProtocol 0
141 iInterface 0
142 VideoStreaming Interface Descriptor:
143 bLength 15
144 bDescriptorType 36
145 bDescriptorSubtype 1 (INPUT_HEADER)
146 bNumFormats 2
147 wTotalLength 0x00f7
148 bEndPointAddress 129
149 bmInfo 0
150 bTerminalLink 4
151 bStillCaptureMethod 0
152 bTriggerSupport 0
153 bTriggerUsage 0
154 bControlSize 1
155 bmaControls( 0) 0
156 bmaControls( 1) 0
157 VideoStreaming Interface Descriptor:
158 bLength 27
159 bDescriptorType 36
160 bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
161 bFormatIndex 1
162 bNumFrameDescriptors 2
163 guidFormat {85f6cc1d-0c9f-44f5-9ce0-97c7dd8c98ab}
164 bBitsPerPixel 16
165 bDefaultFrameIndex 1
166 bAspectRatioX 0
167 bAspectRatioY 0
168 bmInterlaceFlags 0x00
169 Interlaced stream or variable: No
170 Fields per frame: 2 fields
171 Field 1 first: No
172 Field pattern: Field 1 only
173 bCopyProtect 0
174 VideoStreaming Interface Descriptor:
175 bLength 30
176 bDescriptorType 36
177 bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
178 bFrameIndex 1
179 bmCapabilities 0x00
180 Still image unsupported
181 wWidth 480
182 wHeight 320
183 dwMinBitRate 12288000
184 dwMaxBitRate 12288000
185 dwMaxVideoFrameBufferSize 307200
186 dwDefaultFrameInterval 2000000
187 bFrameIntervalType 1
188 dwFrameInterval( 0) 2000000
189 VideoStreaming Interface Descriptor:
190 bLength 30
191 bDescriptorType 36
192 bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
193 bFrameIndex 2
194 bmCapabilities 0x00
195 Still image unsupported
196 wWidth 640
197 wHeight 480
198 dwMinBitRate 73728000
199 dwMaxBitRate 73728000
200 dwMaxVideoFrameBufferSize 614400
201 dwDefaultFrameInterval 666666
202 bFrameIntervalType 1
203 dwFrameInterval( 0) 666666
204 VideoStreaming Interface Descriptor:
205 bLength 11
206 bDescriptorType 36
207 bDescriptorSubtype 6 (FORMAT_MJPEG)
208 bFormatIndex 2
209 bNumFrameDescriptors 4
210 bFlags 0
211 Fixed-size samples: No
212 bDefaultFrameIndex 1
213 bAspectRatioX 0
214 bAspectRatioY 0
215 bmInterlaceFlags 0x00
216 Interlaced stream or variable: No
217 Fields per frame: 1 fields
218 Field 1 first: No
219 Field pattern: Field 1 only
220 bCopyProtect 0
221 VideoStreaming Interface Descriptor:
222 bLength 30
223 bDescriptorType 36
224 bDescriptorSubtype 7 (FRAME_MJPEG)
225 bFrameIndex 1
226 bmCapabilities 0x00
227 Still image unsupported
228 wWidth 640
229 wHeight 480
230 dwMinBitRate 36864000
231 dwMaxBitRate 36864000
232 dwMaxVideoFrameBufferSize 307789
233 dwDefaultFrameInterval 666666
234 bFrameIntervalType 1
235 dwFrameInterval( 0) 666666
236 VideoStreaming Interface Descriptor:
237 bLength 38
238 bDescriptorType 36
239 bDescriptorSubtype 7 (FRAME_MJPEG)
240 bFrameIndex 2
241 bmCapabilities 0x00
242 Still image unsupported
243 wWidth 480
244 wHeight 320
245 dwMinBitRate 6144000
246 dwMaxBitRate 18432000
247 dwMaxVideoFrameBufferSize 154189
248 dwDefaultFrameInterval 666666
249 bFrameIntervalType 3
250 dwFrameInterval( 0) 666666
251 dwFrameInterval( 1) 1000000
252 dwFrameInterval( 2) 2000000
253 VideoStreaming Interface Descriptor:
254 bLength 30
255 bDescriptorType 36
256 bDescriptorSubtype 7 (FRAME_MJPEG)
257 bFrameIndex 3
258 bmCapabilities 0x00
259 Still image unsupported
260 wWidth 352
261 wHeight 288
262 dwMinBitRate 12165120
263 dwMaxBitRate 12165120
264 dwMaxVideoFrameBufferSize 101965
265 dwDefaultFrameInterval 666666
266 bFrameIntervalType 1
267 dwFrameInterval( 0) 666666
268 VideoStreaming Interface Descriptor:
269 bLength 30
270 bDescriptorType 36
271 bDescriptorSubtype 7 (FRAME_MJPEG)
272 bFrameIndex 4
273 bmCapabilities 0x00
274 Still image unsupported
275 wWidth 320
276 wHeight 240
277 dwMinBitRate 9216000
278 dwMaxBitRate 9216000
279 dwMaxVideoFrameBufferSize 77389
280 dwDefaultFrameInterval 666666
281 bFrameIntervalType 1
282 dwFrameInterval( 0) 666666
283 VideoStreaming Interface Descriptor:
284 bLength 6
285 bDescriptorType 36
286 bDescriptorSubtype 13 (COLORFORMAT)
287 bColorPrimaries 1 (BT.709,sRGB)
288 bTransferCharacteristics 1 (BT.709)
289 bMatrixCoefficients 4 (SMPTE 170M (BT.601))
290 Interface Descriptor:
291 bLength 9
292 bDescriptorType 4
293 bInterfaceNumber 1
294 bAlternateSetting 1
295 bNumEndpoints 1
296 bInterfaceClass 14 Video
297 bInterfaceSubClass 2 Video Streaming
298 bInterfaceProtocol 0
299 iInterface 0
300 Endpoint Descriptor:
301 bLength 7
302 bDescriptorType 5
303 bEndpointAddress 0x81 EP 1 IN
304 bmAttributes 5
305 Transfer Type Isochronous
306 Synch Type Asynchronous
307 Usage Type Data
308 wMaxPacketSize 0x03bc 1x 956 bytes
309 bInterval 1
310 */
311
312 static uint8_t config_desc_bytes [] = {
313 0x09, 0x02, 0x85, 0x01, 0x02, 0x01, 0x00, 0x80, 0xFA, 0x08, 0x0B, 0x00, 0x02, 0x0E, 0x03, 0x00, 0x05, 0x09, 0x04,
314 0x00, 0x00, 0x01, 0x0E, 0x01, 0x00, 0x05, 0x0D, 0x24, 0x01, 0x00, 0x01, 0x4F, 0x00, 0xC0, 0xE1, 0xE4, 0x00, 0x01,
315 0x01, 0x09, 0x24, 0x03, 0x04, 0x01, 0x01, 0x00, 0x03, 0x00, 0x1C, 0x24, 0x06, 0x03, 0xB6, 0x8D, 0xF1, 0x4C, 0xD0,
316 0xAB, 0x5C, 0x49, 0x76, 0x98, 0xFA, 0xF9, 0x2F, 0x94, 0xA3, 0x1F, 0x18, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0xFF, 0x00,
317 0x12, 0x24, 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0B,
318 0x24, 0x05, 0x02, 0x01, 0x00, 0x00, 0x02, 0x7F, 0x17, 0x00, 0x07, 0x05, 0x83, 0x03, 0x10, 0x00, 0x06, 0x05, 0x25,
319 0x03, 0x80, 0x00, 0x09, 0x04, 0x01, 0x00, 0x00, 0x0E, 0x02, 0x00, 0x00, 0x0F, 0x24, 0x01, 0x02, 0xF7, 0x00, 0x81,
320 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1B, 0x24, 0x04, 0x01, 0x02, 0x1D, 0xCC, 0xF6, 0x85, 0x9F, 0x0C,
321 0xF5, 0x44, 0xE0, 0x9C, 0xAB, 0x98, 0x8C, 0xDD, 0xC7, 0x97, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x24, 0x05,
322 0x01, 0x00, 0xE0, 0x01, 0x40, 0x01, 0x00, 0x80, 0xBB, 0x00, 0x00, 0x80, 0xBB, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x80,
323 0x84, 0x1E, 0x00, 0x01, 0x80, 0x84, 0x1E, 0x00, 0x1E, 0x24, 0x05, 0x02, 0x00, 0x80, 0x02, 0xE0, 0x01, 0x00, 0x00,
324 0x65, 0x04, 0x00, 0x00, 0x65, 0x04, 0x00, 0x60, 0x09, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x01, 0x2A, 0x2C, 0x0A, 0x00,
325 0x0B, 0x24, 0x06, 0x02, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x24, 0x07, 0x01, 0x00, 0x80, 0x02, 0xE0,
326 0x01, 0x00, 0x80, 0x32, 0x02, 0x00, 0x80, 0x32, 0x02, 0x4D, 0xB2, 0x04, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x01, 0x2A,
327 0x2C, 0x0A, 0x00, 0x26, 0x24, 0x07, 0x02, 0x00, 0xE0, 0x01, 0x40, 0x01, 0x00, 0xC0, 0x5D, 0x00, 0x00, 0x40, 0x19,
328 0x01, 0x4D, 0x5A, 0x02, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x03, 0x2A, 0x2C, 0x0A, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x80,
329 0x84, 0x1E, 0x00, 0x1E, 0x24, 0x07, 0x03, 0x00, 0x60, 0x01, 0x20, 0x01, 0x00, 0xA0, 0xB9, 0x00, 0x00, 0xA0, 0xB9,
330 0x00, 0x4D, 0x8E, 0x01, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x01, 0x2A, 0x2C, 0x0A, 0x00, 0x1E, 0x24, 0x07, 0x04, 0x00,
331 0x40, 0x01, 0xF0, 0x00, 0x00, 0xA0, 0x8C, 0x00, 0x00, 0xA0, 0x8C, 0x00, 0x4D, 0x2E, 0x01, 0x00, 0x2A, 0x2C, 0x0A,
332 0x00, 0x01, 0x2A, 0x2C, 0x0A, 0x00, 0x06, 0x24, 0x0D, 0x01, 0x01, 0x04, 0x09, 0x04, 0x01, 0x01, 0x01, 0x0E, 0x02,
333 0x00, 0x00, 0x07, 0x05, 0x81, 0x05, 0xBC, 0x03, 0x01,
334 };
335 _Static_assert(sizeof(config_desc_bytes) == 0x0185, "Configuration Descriptor size does not match");
336
337 #define TEST_NUM_INTF_DESC 3 //Total number of interface descriptors (including alternate)
338
339 // --------------------- Sub-Test 1 ------------------------
340
341 /*
342 Test if we can walk the configuration descriptor to find each interface descriptor
343 */
test_walk_desc(const usb_config_desc_t * config_desc)344 static void test_walk_desc(const usb_config_desc_t *config_desc)
345 {
346 int offset = 0;
347 const usb_standard_desc_t *cur_desc = (usb_standard_desc_t *)config_desc;
348 for (int i = 0; i < TEST_NUM_INTF_DESC; i++) {
349 cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset);
350 TEST_ASSERT_NOT_EQUAL(NULL, cur_desc);
351 }
352 //Attempting to look for another interface descriptor should result in NULL
353 cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset);
354 TEST_ASSERT_EQUAL(NULL, cur_desc);
355 }
356
357 /*
358 Test if the count of number of alternate descriptors is correct
359 */
test_alt_intf_desc_count(const usb_config_desc_t * config_desc)360 static void test_alt_intf_desc_count(const usb_config_desc_t *config_desc)
361 {
362 //bInterface 0 has no alternate interfaces
363 TEST_ASSERT_EQUAL(0, usb_parse_interface_number_of_alternate(config_desc, 0));
364 //bInterface 1 has 1 alternate interface
365 TEST_ASSERT_EQUAL(1, usb_parse_interface_number_of_alternate(config_desc, 1));
366 //Non existent bInterface 2 should return -1
367 TEST_ASSERT_EQUAL(-1, usb_parse_interface_number_of_alternate(config_desc, 2));
368 }
369
test_parse_intf_and_ep(const usb_config_desc_t * config_desc)370 static void test_parse_intf_and_ep(const usb_config_desc_t *config_desc)
371 {
372 int offset_intf = 0;
373
374 //Get bInterfaceNumber 0 (index 0)
375 const usb_intf_desc_t *intf_desc = usb_parse_interface_descriptor(config_desc, 0, 0, &offset_intf);
376 TEST_ASSERT_NOT_EQUAL(NULL, intf_desc);
377 //Should only have one endpoint
378 int offset_ep = offset_intf;
379 const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
380 TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
381 TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress);
382 offset_ep = offset_intf;
383 ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep);
384 TEST_ASSERT_EQUAL(NULL, ep_desc);
385
386 //Get bInterfaceNumber 1 alternate setting 0
387 offset_intf = 0;
388 intf_desc = usb_parse_interface_descriptor(config_desc, 1, 0, &offset_intf);
389 TEST_ASSERT_NOT_EQUAL(NULL, intf_desc);
390 //Should have no endpoints
391 offset_ep = offset_intf;
392 ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
393 TEST_ASSERT_EQUAL(NULL, ep_desc);
394
395 //Get bInterfaceNumber 1 alternate setting 1
396 offset_intf = 0;
397 intf_desc = usb_parse_interface_descriptor(config_desc, 1, 1, &offset_intf);
398 TEST_ASSERT_NOT_EQUAL(NULL, intf_desc);
399 //Should only have one endpoint
400 offset_ep = offset_intf;
401 ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
402 TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
403 TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress);
404 offset_ep = offset_intf;
405 ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep);
406 TEST_ASSERT_EQUAL(NULL, ep_desc);
407 }
408
test_parse_ep_by_address(const usb_config_desc_t * config_desc)409 static void test_parse_ep_by_address(const usb_config_desc_t *config_desc)
410 {
411 int offset_ep = 0;
412 //Get bInterface 0 bAlternateSetting 0 EP 0x83
413 const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 0, 0, 0x83, &offset_ep);
414 TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
415 TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress);
416 //Getting same EP address under different interface should return NULL
417 offset_ep = 0;
418 ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x83, &offset_ep);
419 TEST_ASSERT_EQUAL(NULL, ep_desc);
420
421 //Get bInterface 1 bAlternateSetting 1 EP 0x81
422 offset_ep = 0;
423 ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 1, 0x81, &offset_ep);
424 TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
425 TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress);
426 //Getting same EP address under different interface should return NULL
427 offset_ep = 0;
428 ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x81, &offset_ep);
429 TEST_ASSERT_EQUAL(NULL, ep_desc);
430 }
431
432 TEST_CASE("Test USB Helpers descriptor parsing", "[usb_host][ignore]")
433 {
434 const usb_config_desc_t *config_desc = (const usb_config_desc_t *)config_desc_bytes;
435 test_walk_desc(config_desc);
436 test_alt_intf_desc_count(config_desc);
437 test_parse_intf_and_ep(config_desc);
438 test_parse_ep_by_address(config_desc);
439 }
440