| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <stdio.h>
- #include "unity.h"
- #include "usb/usb_host.h"
- /*
- Tests that check the configuration descriptor parsing functions provided in usb_host.h work by parsing a fixed
- configuration descriptor. The fixed configuration descriptor used in this test is provided below (both in textual and
- byte format), and is of a UVC device. Thus the configuration descriptor has a good set of scenarios that can be tested
- (such as multiple interfaces, alternate settings, class specific descriptors, default endpoint only interfaces etc).
- */
- /*
- Configuration Descriptor:
- bLength 9
- bDescriptorType 2
- wTotalLength 0x0185
- bNumInterfaces 2
- bConfigurationValue 1
- iConfiguration 0
- bmAttributes 0x80
- (Bus Powered)
- MaxPower 500mA
- Interface Association:
- bLength 8
- bDescriptorType 11
- bFirstInterface 0
- bInterfaceCount 2
- bFunctionClass 14 Video
- bFunctionSubClass 3 Video Interface Collection
- bFunctionProtocol 0
- iFunction 5
- Interface Descriptor:
- bLength 9
- bDescriptorType 4
- bInterfaceNumber 0
- bAlternateSetting 0
- bNumEndpoints 1
- bInterfaceClass 14 Video
- bInterfaceSubClass 1 Video Control
- bInterfaceProtocol 0
- iInterface 5
- VideoControl Interface Descriptor:
- bLength 13
- bDescriptorType 36
- bDescriptorSubtype 1 (HEADER)
- bcdUVC 1.00
- wTotalLength 0x004f
- dwClockFrequency 15.000000MHz
- bInCollection 1
- baInterfaceNr( 0) 1
- VideoControl Interface Descriptor:
- bLength 9
- bDescriptorType 36
- bDescriptorSubtype 3 (OUTPUT_TERMINAL)
- bTerminalID 4
- wTerminalType 0x0101 USB Streaming
- bAssocTerminal 0
- bSourceID 3
- iTerminal 0
- VideoControl Interface Descriptor:
- bLength 28
- bDescriptorType 36
- bDescriptorSubtype 6 (EXTENSION_UNIT)
- bUnitID 3
- guidExtensionCode {4cf18db6-abd0-495c-9876-1fa3942ff9fa}
- bNumControl 24
- bNrPins 1
- baSourceID( 0) 2
- bControlSize 3
- bmControls( 0) 0xff
- bmControls( 1) 0xff
- bmControls( 2) 0xff
- iExtension 0
- VideoControl Interface Descriptor:
- bLength 18
- bDescriptorType 36
- bDescriptorSubtype 2 (INPUT_TERMINAL)
- bTerminalID 1
- wTerminalType 0x0201 Camera Sensor
- bAssocTerminal 0
- iTerminal 0
- wObjectiveFocalLengthMin 0
- wObjectiveFocalLengthMax 0
- wOcularFocalLength 0
- bControlSize 3
- bmControls 0x0000000e
- Auto-Exposure Mode
- Auto-Exposure Priority
- Exposure Time (Absolute)
- VideoControl Interface Descriptor:
- bLength 11
- bDescriptorType 36
- bDescriptorSubtype 5 (PROCESSING_UNIT)
- Warning: Descriptor too short
- bUnitID 2
- bSourceID 1
- wMaxMultiplier 0
- bControlSize 2
- bmControls 0x0000177f
- Brightness
- Contrast
- Hue
- Saturation
- Sharpness
- Gamma
- White Balance Temperature
- Backlight Compensation
- Gain
- Power Line Frequency
- White Balance Temperature, Auto
- iProcessing 0
- bmVideoStandards 0x62
- NTSC - 525/60
- PAL - 525/60
- Endpoint Descriptor:
- bLength 7
- bDescriptorType 5
- bEndpointAddress 0x83 EP 3 IN
- bmAttributes 3
- Transfer Type Interrupt
- Synch Type None
- Usage Type Data
- wMaxPacketSize 0x0010 1x 16 bytes
- bInterval 6
- Interface Descriptor:
- bLength 9
- bDescriptorType 4
- bInterfaceNumber 1
- bAlternateSetting 0
- bNumEndpoints 0
- bInterfaceClass 14 Video
- bInterfaceSubClass 2 Video Streaming
- bInterfaceProtocol 0
- iInterface 0
- VideoStreaming Interface Descriptor:
- bLength 15
- bDescriptorType 36
- bDescriptorSubtype 1 (INPUT_HEADER)
- bNumFormats 2
- wTotalLength 0x00f7
- bEndPointAddress 129
- bmInfo 0
- bTerminalLink 4
- bStillCaptureMethod 0
- bTriggerSupport 0
- bTriggerUsage 0
- bControlSize 1
- bmaControls( 0) 0
- bmaControls( 1) 0
- VideoStreaming Interface Descriptor:
- bLength 27
- bDescriptorType 36
- bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
- bFormatIndex 1
- bNumFrameDescriptors 2
- guidFormat {85f6cc1d-0c9f-44f5-9ce0-97c7dd8c98ab}
- bBitsPerPixel 16
- bDefaultFrameIndex 1
- bAspectRatioX 0
- bAspectRatioY 0
- bmInterlaceFlags 0x00
- Interlaced stream or variable: No
- Fields per frame: 2 fields
- Field 1 first: No
- Field pattern: Field 1 only
- bCopyProtect 0
- VideoStreaming Interface Descriptor:
- bLength 30
- bDescriptorType 36
- bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
- bFrameIndex 1
- bmCapabilities 0x00
- Still image unsupported
- wWidth 480
- wHeight 320
- dwMinBitRate 12288000
- dwMaxBitRate 12288000
- dwMaxVideoFrameBufferSize 307200
- dwDefaultFrameInterval 2000000
- bFrameIntervalType 1
- dwFrameInterval( 0) 2000000
- VideoStreaming Interface Descriptor:
- bLength 30
- bDescriptorType 36
- bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
- bFrameIndex 2
- bmCapabilities 0x00
- Still image unsupported
- wWidth 640
- wHeight 480
- dwMinBitRate 73728000
- dwMaxBitRate 73728000
- dwMaxVideoFrameBufferSize 614400
- dwDefaultFrameInterval 666666
- bFrameIntervalType 1
- dwFrameInterval( 0) 666666
- VideoStreaming Interface Descriptor:
- bLength 11
- bDescriptorType 36
- bDescriptorSubtype 6 (FORMAT_MJPEG)
- bFormatIndex 2
- bNumFrameDescriptors 4
- bFlags 0
- Fixed-size samples: No
- bDefaultFrameIndex 1
- bAspectRatioX 0
- bAspectRatioY 0
- bmInterlaceFlags 0x00
- Interlaced stream or variable: No
- Fields per frame: 1 fields
- Field 1 first: No
- Field pattern: Field 1 only
- bCopyProtect 0
- VideoStreaming Interface Descriptor:
- bLength 30
- bDescriptorType 36
- bDescriptorSubtype 7 (FRAME_MJPEG)
- bFrameIndex 1
- bmCapabilities 0x00
- Still image unsupported
- wWidth 640
- wHeight 480
- dwMinBitRate 36864000
- dwMaxBitRate 36864000
- dwMaxVideoFrameBufferSize 307789
- dwDefaultFrameInterval 666666
- bFrameIntervalType 1
- dwFrameInterval( 0) 666666
- VideoStreaming Interface Descriptor:
- bLength 38
- bDescriptorType 36
- bDescriptorSubtype 7 (FRAME_MJPEG)
- bFrameIndex 2
- bmCapabilities 0x00
- Still image unsupported
- wWidth 480
- wHeight 320
- dwMinBitRate 6144000
- dwMaxBitRate 18432000
- dwMaxVideoFrameBufferSize 154189
- dwDefaultFrameInterval 666666
- bFrameIntervalType 3
- dwFrameInterval( 0) 666666
- dwFrameInterval( 1) 1000000
- dwFrameInterval( 2) 2000000
- VideoStreaming Interface Descriptor:
- bLength 30
- bDescriptorType 36
- bDescriptorSubtype 7 (FRAME_MJPEG)
- bFrameIndex 3
- bmCapabilities 0x00
- Still image unsupported
- wWidth 352
- wHeight 288
- dwMinBitRate 12165120
- dwMaxBitRate 12165120
- dwMaxVideoFrameBufferSize 101965
- dwDefaultFrameInterval 666666
- bFrameIntervalType 1
- dwFrameInterval( 0) 666666
- VideoStreaming Interface Descriptor:
- bLength 30
- bDescriptorType 36
- bDescriptorSubtype 7 (FRAME_MJPEG)
- bFrameIndex 4
- bmCapabilities 0x00
- Still image unsupported
- wWidth 320
- wHeight 240
- dwMinBitRate 9216000
- dwMaxBitRate 9216000
- dwMaxVideoFrameBufferSize 77389
- dwDefaultFrameInterval 666666
- bFrameIntervalType 1
- dwFrameInterval( 0) 666666
- VideoStreaming Interface Descriptor:
- bLength 6
- bDescriptorType 36
- bDescriptorSubtype 13 (COLORFORMAT)
- bColorPrimaries 1 (BT.709,sRGB)
- bTransferCharacteristics 1 (BT.709)
- bMatrixCoefficients 4 (SMPTE 170M (BT.601))
- Interface Descriptor:
- bLength 9
- bDescriptorType 4
- bInterfaceNumber 1
- bAlternateSetting 1
- bNumEndpoints 1
- bInterfaceClass 14 Video
- bInterfaceSubClass 2 Video Streaming
- bInterfaceProtocol 0
- iInterface 0
- Endpoint Descriptor:
- bLength 7
- bDescriptorType 5
- bEndpointAddress 0x81 EP 1 IN
- bmAttributes 5
- Transfer Type Isochronous
- Synch Type Asynchronous
- Usage Type Data
- wMaxPacketSize 0x03bc 1x 956 bytes
- bInterval 1
- */
- static uint8_t config_desc_bytes [] = {
- 0x09, 0x02, 0x85, 0x01, 0x02, 0x01, 0x00, 0x80, 0xFA, 0x08, 0x0B, 0x00, 0x02, 0x0E, 0x03, 0x00, 0x05, 0x09, 0x04,
- 0x00, 0x00, 0x01, 0x0E, 0x01, 0x00, 0x05, 0x0D, 0x24, 0x01, 0x00, 0x01, 0x4F, 0x00, 0xC0, 0xE1, 0xE4, 0x00, 0x01,
- 0x01, 0x09, 0x24, 0x03, 0x04, 0x01, 0x01, 0x00, 0x03, 0x00, 0x1C, 0x24, 0x06, 0x03, 0xB6, 0x8D, 0xF1, 0x4C, 0xD0,
- 0xAB, 0x5C, 0x49, 0x76, 0x98, 0xFA, 0xF9, 0x2F, 0x94, 0xA3, 0x1F, 0x18, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0xFF, 0x00,
- 0x12, 0x24, 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0B,
- 0x24, 0x05, 0x02, 0x01, 0x00, 0x00, 0x02, 0x7F, 0x17, 0x00, 0x07, 0x05, 0x83, 0x03, 0x10, 0x00, 0x06, 0x05, 0x25,
- 0x03, 0x80, 0x00, 0x09, 0x04, 0x01, 0x00, 0x00, 0x0E, 0x02, 0x00, 0x00, 0x0F, 0x24, 0x01, 0x02, 0xF7, 0x00, 0x81,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1B, 0x24, 0x04, 0x01, 0x02, 0x1D, 0xCC, 0xF6, 0x85, 0x9F, 0x0C,
- 0xF5, 0x44, 0xE0, 0x9C, 0xAB, 0x98, 0x8C, 0xDD, 0xC7, 0x97, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x24, 0x05,
- 0x01, 0x00, 0xE0, 0x01, 0x40, 0x01, 0x00, 0x80, 0xBB, 0x00, 0x00, 0x80, 0xBB, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x80,
- 0x84, 0x1E, 0x00, 0x01, 0x80, 0x84, 0x1E, 0x00, 0x1E, 0x24, 0x05, 0x02, 0x00, 0x80, 0x02, 0xE0, 0x01, 0x00, 0x00,
- 0x65, 0x04, 0x00, 0x00, 0x65, 0x04, 0x00, 0x60, 0x09, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x01, 0x2A, 0x2C, 0x0A, 0x00,
- 0x0B, 0x24, 0x06, 0x02, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x24, 0x07, 0x01, 0x00, 0x80, 0x02, 0xE0,
- 0x01, 0x00, 0x80, 0x32, 0x02, 0x00, 0x80, 0x32, 0x02, 0x4D, 0xB2, 0x04, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x01, 0x2A,
- 0x2C, 0x0A, 0x00, 0x26, 0x24, 0x07, 0x02, 0x00, 0xE0, 0x01, 0x40, 0x01, 0x00, 0xC0, 0x5D, 0x00, 0x00, 0x40, 0x19,
- 0x01, 0x4D, 0x5A, 0x02, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x03, 0x2A, 0x2C, 0x0A, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x80,
- 0x84, 0x1E, 0x00, 0x1E, 0x24, 0x07, 0x03, 0x00, 0x60, 0x01, 0x20, 0x01, 0x00, 0xA0, 0xB9, 0x00, 0x00, 0xA0, 0xB9,
- 0x00, 0x4D, 0x8E, 0x01, 0x00, 0x2A, 0x2C, 0x0A, 0x00, 0x01, 0x2A, 0x2C, 0x0A, 0x00, 0x1E, 0x24, 0x07, 0x04, 0x00,
- 0x40, 0x01, 0xF0, 0x00, 0x00, 0xA0, 0x8C, 0x00, 0x00, 0xA0, 0x8C, 0x00, 0x4D, 0x2E, 0x01, 0x00, 0x2A, 0x2C, 0x0A,
- 0x00, 0x01, 0x2A, 0x2C, 0x0A, 0x00, 0x06, 0x24, 0x0D, 0x01, 0x01, 0x04, 0x09, 0x04, 0x01, 0x01, 0x01, 0x0E, 0x02,
- 0x00, 0x00, 0x07, 0x05, 0x81, 0x05, 0xBC, 0x03, 0x01,
- };
- _Static_assert(sizeof(config_desc_bytes) == 0x0185, "Configuration Descriptor size does not match");
- #define TEST_NUM_INTF_DESC 3 //Total number of interface descriptors (including alternate)
- // --------------------- Sub-Test 1 ------------------------
- /*
- Test if we can walk the configuration descriptor to find each interface descriptor
- */
- static void test_walk_desc(const usb_config_desc_t *config_desc)
- {
- int offset = 0;
- const usb_standard_desc_t *cur_desc = (usb_standard_desc_t *)config_desc;
- for (int i = 0; i < TEST_NUM_INTF_DESC; i++) {
- cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset);
- TEST_ASSERT_NOT_NULL(cur_desc);
- }
- //Attempting to look for another interface descriptor should result in NULL
- cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset);
- TEST_ASSERT_NULL(cur_desc);
- }
- /*
- Test if the count of number of alternate descriptors is correct
- */
- static void test_alt_intf_desc_count(const usb_config_desc_t *config_desc)
- {
- //bInterface 0 has no alternate interfaces
- TEST_ASSERT_EQUAL(0, usb_parse_interface_number_of_alternate(config_desc, 0));
- //bInterface 1 has 1 alternate interface
- TEST_ASSERT_EQUAL(1, usb_parse_interface_number_of_alternate(config_desc, 1));
- //Non existent bInterface 2 should return -1
- TEST_ASSERT_EQUAL(-1, usb_parse_interface_number_of_alternate(config_desc, 2));
- }
- static void test_parse_intf_and_ep(const usb_config_desc_t *config_desc)
- {
- int offset_intf = 0;
- //Get bInterfaceNumber 0 (index 0)
- const usb_intf_desc_t *intf_desc = usb_parse_interface_descriptor(config_desc, 0, 0, &offset_intf);
- TEST_ASSERT_NOT_NULL(intf_desc);
- //Should only have one endpoint
- int offset_ep = offset_intf;
- const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
- TEST_ASSERT_NOT_NULL(ep_desc);
- TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress);
- offset_ep = offset_intf;
- ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep);
- TEST_ASSERT_NULL(ep_desc);
- //Get bInterfaceNumber 1 alternate setting 0
- offset_intf = 0;
- intf_desc = usb_parse_interface_descriptor(config_desc, 1, 0, &offset_intf);
- TEST_ASSERT_NOT_NULL(intf_desc);
- //Should have no endpoints
- offset_ep = offset_intf;
- ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
- TEST_ASSERT_NULL(ep_desc);
- //Get bInterfaceNumber 1 alternate setting 1
- offset_intf = 0;
- intf_desc = usb_parse_interface_descriptor(config_desc, 1, 1, &offset_intf);
- TEST_ASSERT_NOT_NULL(intf_desc);
- //Should only have one endpoint
- offset_ep = offset_intf;
- ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
- TEST_ASSERT_NOT_NULL(ep_desc);
- TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress);
- offset_ep = offset_intf;
- ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep);
- TEST_ASSERT_NULL(ep_desc);
- }
- static void test_parse_ep_by_address(const usb_config_desc_t *config_desc)
- {
- int offset_ep = 0;
- //Get bInterface 0 bAlternateSetting 0 EP 0x83
- const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 0, 0, 0x83, &offset_ep);
- TEST_ASSERT_NOT_NULL(ep_desc);
- TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress);
- //Getting same EP address under different interface should return NULL
- offset_ep = 0;
- ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x83, &offset_ep);
- TEST_ASSERT_NULL(ep_desc);
- //Get bInterface 1 bAlternateSetting 1 EP 0x81
- offset_ep = 0;
- ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 1, 0x81, &offset_ep);
- TEST_ASSERT_NOT_NULL(ep_desc);
- TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress);
- //Getting same EP address under different interface should return NULL
- offset_ep = 0;
- ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x81, &offset_ep);
- TEST_ASSERT_NULL(ep_desc);
- }
- TEST_CASE("Test USB Helpers descriptor parsing", "[helpers][full_speed]")
- {
- const usb_config_desc_t *config_desc = (const usb_config_desc_t *)config_desc_bytes;
- test_walk_desc(config_desc);
- test_alt_intf_desc_count(config_desc);
- test_parse_intf_and_ep(config_desc);
- test_parse_ep_by_address(config_desc);
- }
|