test_usb_mock_classes.h 10 KB

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