test_usb_mock_classes.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*
  7. This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB
  8. Host stack.
  9. */
  10. #pragma once
  11. #include <stdint.h>
  12. #include <stdbool.h>
  13. #include "usb/usb_types_ch9.h"
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. // ---------------------------------------------------- MSC SCSI -------------------------------------------------------
  18. const char *MSC_CLIENT_TAG;
  19. /*
  20. Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should...
  21. - Be implement the Mass Storage class supporting BULK only transfers using SCSI commands
  22. - It's configuration 1 should have the following endpoints
  23. Device Descriptor:
  24. bLength 18
  25. bDescriptorType 1
  26. bcdUSB 2.00
  27. bDeviceClass 0
  28. bDeviceSubClass 0
  29. bDeviceProtocol 0
  30. bMaxPacketSize0 64
  31. idVendor 0x125f
  32. idProduct 0xc08a
  33. bcdDevice 1.00
  34. iManufacturer 1
  35. iProduct 2
  36. iSerial 3
  37. bNumConfigurations 1
  38. Configuration Descriptor:
  39. bLength 9
  40. bDescriptorType 2
  41. wTotalLength 0x0020
  42. bNumInterfaces 1
  43. bConfigurationValue 1
  44. iConfiguration 0
  45. bmAttributes 0x80
  46. (Bus Powered)
  47. MaxPower 480mA
  48. Interface Descriptor:
  49. bLength 9
  50. bDescriptorType 4
  51. bInterfaceNumber 0
  52. bAlternateSetting 0
  53. bNumEndpoints 2
  54. bInterfaceClass 8 Mass Storage
  55. bInterfaceSubClass 6 SCSI
  56. bInterfaceProtocol 80 Bulk-Only
  57. iInterface 0
  58. Endpoint Descriptor:
  59. bLength 7
  60. bDescriptorType 5
  61. bEndpointAddress 0x01 EP 1 OUT
  62. bmAttributes 2
  63. Transfer Type Bulk
  64. Synch Type None
  65. Usage Type Data
  66. wMaxPacketSize 0x0040 1x 64 bytes
  67. bInterval 1
  68. Endpoint Descriptor:
  69. bLength 7
  70. bDescriptorType 5
  71. bEndpointAddress 0x82 EP 2 IN
  72. bmAttributes 2
  73. Transfer Type Bulk
  74. Synch Type None
  75. Usage Type Data
  76. wMaxPacketSize 0x0040 1x 64 bytes
  77. bInterval 1
  78. If you're using a flash driver with different endpoints, modify the endpoint descriptors below.
  79. */
  80. static const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc = {
  81. .bLength = sizeof(usb_ep_desc_t),
  82. .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
  83. .bEndpointAddress = 0x01, //EP 1 OUT
  84. .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
  85. .wMaxPacketSize = 64, //MPS of 64 bytes
  86. .bInterval = 1,
  87. };
  88. static const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc = {
  89. .bLength = sizeof(usb_ep_desc_t),
  90. .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
  91. .bEndpointAddress = 0x82, //EP 2 IN
  92. .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
  93. .wMaxPacketSize = 64, //MPS of 64 bytes
  94. .bInterval = 1,
  95. };
  96. #define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x125F
  97. #define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0xc08A
  98. #define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64
  99. #define MOCK_MSC_SCSI_SECTOR_SIZE 512
  100. #define MOCK_MSC_SCSI_LUN 0
  101. #define MOCK_MSC_SCSI_INTF_NUMBER 0
  102. #define MOCK_MSC_SCSI_INTF_ALT_SETTING 0
  103. #define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x01
  104. #define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x82
  105. #define MOCK_MSC_SCSI_BULK_EP_MPS 64
  106. #define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \
  107. (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \
  108. (setup_pkt_ptr)->bRequest = 0xFF; \
  109. (setup_pkt_ptr)->wValue = 0; \
  110. (setup_pkt_ptr)->wIndex = (intf_num); \
  111. (setup_pkt_ptr)->wLength = 0; \
  112. })
  113. typedef struct __attribute__((packed)) {
  114. uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
  115. uint8_t flags;
  116. uint8_t lba_3;
  117. uint8_t lba_2;
  118. uint8_t lba_1;
  119. uint8_t lba_0;
  120. uint8_t group;
  121. uint8_t len_1;
  122. uint8_t len_0;
  123. uint8_t control;
  124. } mock_scsi_cmd10_t;
  125. typedef struct __attribute__((packed)) {
  126. uint32_t dCBWSignature;
  127. uint32_t dCBWTag;
  128. uint32_t dCBWDataTransferLength;
  129. uint8_t bmCBWFlags;
  130. uint8_t bCBWLUN;
  131. uint8_t bCBWCBLength;
  132. mock_scsi_cmd10_t CBWCB;
  133. uint8_t padding[6];
  134. } mock_msc_bulk_cbw_t;
  135. // USB Bulk Transfer Command Status Wrapper data
  136. typedef struct __attribute__((packed)) {
  137. uint32_t dCSWSignature;
  138. uint32_t dCSWTag;
  139. uint32_t dCSWDataResidue;
  140. uint8_t bCSWStatus;
  141. } mock_msc_bulk_csw_t;
  142. /**
  143. * @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command
  144. *
  145. * @param cbw CBW structure
  146. * @param is_read Is a read command
  147. * @param offset Block offset
  148. * @param num_sectors Number of sectors to read
  149. * @param tag Tag (this is simply echoed back
  150. */
  151. void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag);
  152. /**
  153. * @brief Check that returned Command Status Wrapper (CSW) is valid
  154. *
  155. * @param csw CSW structure
  156. * @param tag_expect Expected tag
  157. * @return true CSW is valid
  158. * @return false CSW is not valid
  159. */
  160. bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect);
  161. // ---------------------------------------------------- HID Mouse ------------------------------------------------------
  162. /*
  163. Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should...
  164. - Be implement the HID with standard report format used by mice
  165. - It's configuration 1 should have the following endpoint
  166. Device Descriptor:
  167. bLength 18
  168. bDescriptorType 1
  169. bcdUSB 2.00
  170. bDeviceClass 0
  171. bDeviceSubClass 0
  172. bDeviceProtocol 0
  173. bMaxPacketSize0 8
  174. idVendor 0x413c Dell Computer Corp.
  175. idProduct 0x301a
  176. bcdDevice 1.00
  177. iManufacturer 1
  178. iProduct 2
  179. iSerial 0
  180. bNumConfigurations 1
  181. Configuration Descriptor:
  182. bLength 9
  183. bDescriptorType 2
  184. wTotalLength 0x0022
  185. bNumInterfaces 1
  186. bConfigurationValue 1
  187. iConfiguration 0
  188. bmAttributes 0xa0
  189. (Bus Powered)
  190. Remote Wakeup
  191. MaxPower 100mA
  192. Interface Descriptor:
  193. bLength 9
  194. bDescriptorType 4
  195. bInterfaceNumber 0
  196. bAlternateSetting 0
  197. bNumEndpoints 1
  198. bInterfaceClass 3 Human Interface Device
  199. bInterfaceSubClass 1 Boot Interface Subclass
  200. bInterfaceProtocol 2 Mouse
  201. iInterface 0
  202. HID Device Descriptor:
  203. bLength 9
  204. bDescriptorType 33
  205. bcdHID 1.11
  206. bCountryCode 0 Not supported
  207. bNumDescriptors 1
  208. bDescriptorType 34 Report
  209. wDescriptorLength 46
  210. Report Descriptors:
  211. ** UNAVAILABLE **
  212. Endpoint Descriptor:
  213. bLength 7
  214. bDescriptorType 5
  215. bEndpointAddress 0x81 EP 1 IN
  216. bmAttributes 3
  217. Transfer Type Interrupt
  218. Synch Type None
  219. Usage Type Data
  220. wMaxPacketSize 0x0004 1x 4 bytes
  221. bInterval 10
  222. If you're using another mice with different endpoints, modify the endpoint descriptor below
  223. */
  224. static const usb_ep_desc_t mock_hid_mouse_in_ep_desc = {
  225. .bLength = sizeof(usb_ep_desc_t),
  226. .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
  227. .bEndpointAddress = 0x81, //EP 1 IN
  228. .bmAttributes = USB_BM_ATTRIBUTES_XFER_INT,
  229. .wMaxPacketSize = 4, //MPS of 4 bytes
  230. .bInterval = 10, //Interval of 10ms
  231. };
  232. #define MOCK_HID_MOUSE_DEV_ID_VENDOR 0x413C
  233. #define MOCK_HID_MOUSE_DEV_ID_PRODUCT 0x301A
  234. #define MOCK_HID_MOUSE_DEV_DFLT_EP_MPS 8
  235. #define MOCK_HID_MOUSE_INTF_NUMBER 0
  236. #define MOCK_HID_MOUSE_INTF_ALT_SETTING 0
  237. #define MOCK_HID_MOUSE_INTR_IN_EP_ADDR 0x81
  238. #define MOCK_HID_MOUSE_INTR_IN_MPS 0x04
  239. typedef union {
  240. struct {
  241. uint32_t left_button: 1;
  242. uint32_t right_button: 1;
  243. uint32_t middle_button: 1;
  244. uint32_t reserved5: 5;
  245. uint8_t x_movement;
  246. uint8_t y_movement;
  247. } __attribute__((packed));
  248. uint8_t val[3];
  249. } mock_hid_mouse_report_t;
  250. _Static_assert(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect");
  251. void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter);
  252. // ---------------------------------------------------- Mock ISOC ------------------------------------------------------
  253. /*
  254. Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for
  255. ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below:
  256. */
  257. #define MOCK_ISOC_EP_NUM 2
  258. #define MOCK_ISOC_EP_MPS 512
  259. static const usb_ep_desc_t mock_isoc_out_ep_desc = {
  260. .bLength = sizeof(usb_ep_desc_t),
  261. .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
  262. .bEndpointAddress = MOCK_ISOC_EP_NUM,
  263. .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC,
  264. .wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes
  265. .bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
  266. };
  267. #ifdef __cplusplus
  268. }
  269. #endif