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