test_usb_helpers.c 20 KB

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