test_usb_mock_msc.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2022 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 "esp_assert.h"
  14. #include "usb/usb_types_ch9.h"
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. // ---------------------------------------------------- MSC SCSI -------------------------------------------------------
  19. extern const char *MSC_CLIENT_TAG;
  20. /*
  21. Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should...
  22. - Be implement the Mass Storage class supporting BULK only transfers using SCSI commands
  23. - It's configuration 1 should have the following endpoints
  24. ------------------ Configuration Descriptor -------------------
  25. bLength : 0x09 (9 bytes)
  26. bDescriptorType : 0x02 (Configuration Descriptor)
  27. wTotalLength : 0x0020 (32 bytes)
  28. bNumInterfaces : 0x01 (1 Interface)
  29. bConfigurationValue : 0x01 (Configuration 1)
  30. iConfiguration : 0x00 (No String Descriptor)
  31. bmAttributes : 0x80
  32. D7: Reserved, set 1 : 0x01
  33. D6: Self Powered : 0x00 (no)
  34. D5: Remote Wakeup : 0x00 (no)
  35. D4..0: Reserved, set 0 : 0x00
  36. MaxPower : 0x70 (224 mA)
  37. Data (HexDump) : 09 02 20 00 01 01 00 80 70 09 04 00 00 02 08 06
  38. 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00
  39. ---------------- Interface Descriptor -----------------
  40. bLength : 0x09 (9 bytes)
  41. bDescriptorType : 0x04 (Interface Descriptor)
  42. bInterfaceNumber : 0x00
  43. bAlternateSetting : 0x00
  44. bNumEndpoints : 0x02 (2 Endpoints)
  45. bInterfaceClass : 0x08 (Mass Storage)
  46. bInterfaceSubClass : 0x06 (SCSI transparent command set)
  47. bInterfaceProtocol : 0x50 (Bulk-Only Transport)
  48. iInterface : 0x00 (No String Descriptor)
  49. Data (HexDump) : 09 04 00 00 02 08 06 50 00
  50. ----------------- Endpoint Descriptor -----------------
  51. bLength : 0x07 (7 bytes)
  52. bDescriptorType : 0x05 (Endpoint Descriptor)
  53. bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
  54. bmAttributes : 0x02 (TransferType=Bulk)
  55. wMaxPacketSize : 0x0040 (max 64 bytes)
  56. bInterval : 0x00 (never NAKs)
  57. Data (HexDump) : 07 05 81 02 40 00 00
  58. ----------------- Endpoint Descriptor -----------------
  59. bLength : 0x07 (7 bytes)
  60. bDescriptorType : 0x05 (Endpoint Descriptor)
  61. bEndpointAddress : 0x02 (Direction=OUT EndpointID=2)
  62. bmAttributes : 0x02 (TransferType=Bulk)
  63. wMaxPacketSize : 0x0040 (max 64 bytes)
  64. bInterval : 0x00 (never NAKs)
  65. Data (HexDump) : 07 05 02 02 40 00 00
  66. If you're using a flash driver with different endpoints, modify the endpoint descriptors below.
  67. */
  68. //Constant descriptors
  69. extern const usb_device_desc_t mock_msc_scsi_dev_desc;
  70. extern uint8_t mock_msc_scsi_config_desc[255];
  71. extern uint16_t mock_msc_scsi_str_desc_manu[128];
  72. extern uint16_t mock_msc_scsi_str_desc_prod[128];
  73. extern uint16_t mock_msc_scsi_str_desc_ser_num[128];
  74. extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc;
  75. extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
  76. #define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x0781 // Western Digital, Sandisk
  77. #define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0x5595
  78. #define MOCK_MSC_SCSI_DEV_VERSION 0x0100 //1.00
  79. #define MOCK_MSC_SCSI_USB_VERSION 0x0210 //2.10
  80. #define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64
  81. #define MOCK_MSC_SCSI_SECTOR_SIZE 512
  82. #define MOCK_MSC_SCSI_LUN 0
  83. #define MOCK_MSC_SCSI_INTF_NUMBER 0
  84. #define MOCK_MSC_SCSI_INTF_ALT_SETTING 0
  85. #define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x02
  86. #define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x81
  87. #define MOCK_MSC_SCSI_BULK_EP_MPS 64
  88. #define MOCK_MSC_SCSI_STRING_1 (" USB")
  89. #define MOCK_MSC_SCSI_STRING_2 (" SanDisk 3.2Gen1")
  90. #define MOCK_MSC_SCSI_STRING_3 ("0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4") // This string is NOT checked by the enum test
  91. #define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \
  92. (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \
  93. (setup_pkt_ptr)->bRequest = 0xFF; \
  94. (setup_pkt_ptr)->wValue = 0; \
  95. (setup_pkt_ptr)->wIndex = (intf_num); \
  96. (setup_pkt_ptr)->wLength = 0; \
  97. })
  98. typedef struct __attribute__((packed)) {
  99. uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
  100. uint8_t flags;
  101. uint8_t lba_3;
  102. uint8_t lba_2;
  103. uint8_t lba_1;
  104. uint8_t lba_0;
  105. uint8_t group;
  106. uint8_t len_1;
  107. uint8_t len_0;
  108. uint8_t control;
  109. } mock_scsi_cmd10_t;
  110. typedef struct __attribute__((packed)) {
  111. uint32_t dCBWSignature;
  112. uint32_t dCBWTag;
  113. uint32_t dCBWDataTransferLength;
  114. uint8_t bmCBWFlags;
  115. uint8_t bCBWLUN;
  116. uint8_t bCBWCBLength;
  117. mock_scsi_cmd10_t CBWCB;
  118. uint8_t padding[6];
  119. } mock_msc_bulk_cbw_t;
  120. // USB Bulk Transfer Command Status Wrapper data
  121. typedef struct __attribute__((packed)) {
  122. uint32_t dCSWSignature;
  123. uint32_t dCSWTag;
  124. uint32_t dCSWDataResidue;
  125. uint8_t bCSWStatus;
  126. } mock_msc_bulk_csw_t;
  127. /**
  128. * @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command
  129. *
  130. * @param cbw CBW structure
  131. * @param is_read Is a read command
  132. * @param offset Block offset
  133. * @param num_sectors Number of sectors to read
  134. * @param tag Tag (this is simply echoed back
  135. */
  136. void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag);
  137. /**
  138. * @brief Check that returned Command Status Wrapper (CSW) is valid
  139. *
  140. * @param csw CSW structure
  141. * @param tag_expect Expected tag
  142. * @return true CSW is valid
  143. * @return false CSW is not valid
  144. */
  145. bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect);
  146. /**
  147. * @brief Construct configuration and string descriptors
  148. */
  149. void mock_msc_scsi_init_reference_descriptors(void);
  150. // ---------------------------------------------------- Mock ISOC ------------------------------------------------------
  151. /*
  152. Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for
  153. ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below:
  154. */
  155. #define MOCK_ISOC_EP_NUM 2
  156. #define MOCK_ISOC_EP_MPS 512
  157. static const usb_ep_desc_t mock_isoc_out_ep_desc = {
  158. .bLength = sizeof(usb_ep_desc_t),
  159. .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
  160. .bEndpointAddress = MOCK_ISOC_EP_NUM,
  161. .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC,
  162. .wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes
  163. .bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
  164. };
  165. #ifdef __cplusplus
  166. }
  167. #endif