• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef USB_DEF_H
7 #define USB_DEF_H
8 
9 /* Useful define */
10 #define USB_1_1 0x0110
11 #define USB_2_0 0x0200
12 /* Set USB version to 2.1 so that the host will request the BOS descriptor */
13 #define USB_2_1 0x0210
14 #define USB_3_0 0x0300
15 #define USB_3_1 0x0310
16 #define USB_3_2 0x0320
17 
18 /* Device speeds */
19 #define USB_SPEED_UNKNOWN    0 /* Transfer rate not yet set */
20 #define USB_SPEED_LOW        1 /* USB 1.1 */
21 #define USB_SPEED_FULL       2 /* USB 1.1 */
22 #define USB_SPEED_HIGH       3 /* USB 2.0 */
23 #define USB_SPEED_WIRELESS   4 /* Wireless USB 2.5 */
24 #define USB_SPEED_SUPER      5 /* USB 3.0 */
25 #define USB_SPEED_SUPER_PLUS 6 /* USB 3.1 */
26 
27 /* Maximum number of devices per controller */
28 #define USB_MAX_DEVICES (127)
29 
30 /* Default USB control EP, always 0 and 0x80 */
31 #define USB_CONTROL_OUT_EP0 0
32 #define USB_CONTROL_IN_EP0  0x80
33 
34 /**< maximum packet size (MPS) for EP 0 */
35 #define USB_CTRL_EP_MPS 64
36 
37 /* USB PID Types */
38 #define USB_PID_OUT   (0x01) /* Tokens */
39 #define USB_PID_IN    (0x09)
40 #define USB_PID_SOF   (0x05)
41 #define USB_PID_SETUP (0x0d)
42 
43 #define USB_PID_DATA0 (0x03) /* Data */
44 #define USB_PID_DATA1 (0x0b)
45 #define USB_PID_DATA2 (0x07)
46 #define USB_PID_MDATA (0x0f)
47 
48 #define USB_PID_ACK   (0x02) /* Handshake */
49 #define USB_PID_NAK   (0x0a)
50 #define USB_PID_STALL (0x0e)
51 #define USB_PID_NYET  (0x06)
52 
53 #define USB_PID_PRE      (0x0c) /* Special */
54 #define USB_PID_ERR      (0x0c)
55 #define USB_PID_SPLIT    (0x08)
56 #define USB_PID_PING     (0x04)
57 #define USB_PID_RESERVED (0x00)
58 
59 #define USB_REQUEST_DIR_SHIFT 7U                            /* Bits 7: Request dir */
60 #define USB_REQUEST_DIR_OUT   (0U << USB_REQUEST_DIR_SHIFT) /* Bit 7=0: Host-to-device */
61 #define USB_REQUEST_DIR_IN    (1U << USB_REQUEST_DIR_SHIFT) /* Bit 7=1: Device-to-host */
62 #define USB_REQUEST_DIR_MASK  (1U << USB_REQUEST_DIR_SHIFT) /* Bit 7=1: Direction bit */
63 
64 #define USB_REQUEST_TYPE_SHIFT 5U /* Bits 5:6: Request type */
65 #define USB_REQUEST_STANDARD   (0U << USB_REQUEST_TYPE_SHIFT)
66 #define USB_REQUEST_CLASS      (1U << USB_REQUEST_TYPE_SHIFT)
67 #define USB_REQUEST_VENDOR     (2U << USB_REQUEST_TYPE_SHIFT)
68 #define USB_REQUEST_RESERVED   (3U << USB_REQUEST_TYPE_SHIFT)
69 #define USB_REQUEST_TYPE_MASK  (3U << USB_REQUEST_TYPE_SHIFT)
70 
71 #define USB_REQUEST_RECIPIENT_SHIFT     0U /* Bits 0:4: Recipient */
72 #define USB_REQUEST_RECIPIENT_DEVICE    (0U << USB_REQUEST_RECIPIENT_SHIFT)
73 #define USB_REQUEST_RECIPIENT_INTERFACE (1U << USB_REQUEST_RECIPIENT_SHIFT)
74 #define USB_REQUEST_RECIPIENT_ENDPOINT  (2U << USB_REQUEST_RECIPIENT_SHIFT)
75 #define USB_REQUEST_RECIPIENT_OTHER     (3U << USB_REQUEST_RECIPIENT_SHIFT)
76 #define USB_REQUEST_RECIPIENT_MASK      (3U << USB_REQUEST_RECIPIENT_SHIFT)
77 
78 /* USB Standard Request Codes */
79 #define USB_REQUEST_GET_STATUS          0x00
80 #define USB_REQUEST_CLEAR_FEATURE       0x01
81 #define USB_REQUEST_SET_FEATURE         0x03
82 #define USB_REQUEST_SET_ADDRESS         0x05
83 #define USB_REQUEST_GET_DESCRIPTOR      0x06
84 #define USB_REQUEST_SET_DESCRIPTOR      0x07
85 #define USB_REQUEST_GET_CONFIGURATION   0x08
86 #define USB_REQUEST_SET_CONFIGURATION   0x09
87 #define USB_REQUEST_GET_INTERFACE       0x0A
88 #define USB_REQUEST_SET_INTERFACE       0x0B
89 #define USB_REQUEST_SYNCH_FRAME         0x0C
90 #define USB_REQUEST_SET_ENCRYPTION      0x0D
91 #define USB_REQUEST_GET_ENCRYPTION      0x0E
92 #define USB_REQUEST_RPIPE_ABORT         0x0E
93 #define USB_REQUEST_SET_HANDSHAKE       0x0F
94 #define USB_REQUEST_RPIPE_RESET         0x0F
95 #define USB_REQUEST_GET_HANDSHAKE       0x10
96 #define USB_REQUEST_SET_CONNECTION      0x11
97 #define USB_REQUEST_SET_SECURITY_DATA   0x12
98 #define USB_REQUEST_GET_SECURITY_DATA   0x13
99 #define USB_REQUEST_SET_WUSB_DATA       0x14
100 #define USB_REQUEST_LOOPBACK_DATA_WRITE 0x15
101 #define USB_REQUEST_LOOPBACK_DATA_READ  0x16
102 #define USB_REQUEST_SET_INTERFACE_DS    0x17
103 
104 /* USB Standard Feature selectors */
105 #define USB_FEATURE_ENDPOINT_HALT  0
106 #define USB_FEATURE_SELF_POWERED   0
107 #define USB_FEATURE_REMOTE_WAKEUP  1
108 #define USB_FEATURE_TEST_MODE      2
109 #define USB_FEATURE_BATTERY        2
110 #define USB_FEATURE_BHNPENABLE     3
111 #define USB_FEATURE_WUSBDEVICE     3
112 #define USB_FEATURE_AHNPSUPPORT    4
113 #define USB_FEATURE_AALTHNPSUPPORT 5
114 #define USB_FEATURE_DEBUGMODE      6
115 
116 /* USB GET_STATUS Bit Values */
117 #define USB_GETSTATUS_ENDPOINT_HALT 0x01
118 #define USB_GETSTATUS_SELF_POWERED  0x01
119 #define USB_GETSTATUS_REMOTE_WAKEUP 0x02
120 
121 /* USB Descriptor Types */
122 #define USB_DESCRIPTOR_TYPE_DEVICE                0x01U
123 #define USB_DESCRIPTOR_TYPE_CONFIGURATION         0x02U
124 #define USB_DESCRIPTOR_TYPE_STRING                0x03U
125 #define USB_DESCRIPTOR_TYPE_INTERFACE             0x04U
126 #define USB_DESCRIPTOR_TYPE_ENDPOINT              0x05U
127 #define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER      0x06U
128 #define USB_DESCRIPTOR_TYPE_OTHER_SPEED           0x07U
129 #define USB_DESCRIPTOR_TYPE_INTERFACE_POWER       0x08U
130 #define USB_DESCRIPTOR_TYPE_OTG                   0x09U
131 #define USB_DESCRIPTOR_TYPE_DEBUG                 0x0AU
132 #define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0BU
133 #define USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE   0x0FU
134 #define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY     0x10U
135 #define USB_DESCRIPTOR_TYPE_WIRELESS_ENDPOINTCOMP 0x11U
136 
137 /* Class Specific Descriptor */
138 #define USB_CS_DESCRIPTOR_TYPE_DEVICE        0x21U
139 #define USB_CS_DESCRIPTOR_TYPE_CONFIGURATION 0x22U
140 #define USB_CS_DESCRIPTOR_TYPE_STRING        0x23U
141 #define USB_CS_DESCRIPTOR_TYPE_INTERFACE     0x24U
142 #define USB_CS_DESCRIPTOR_TYPE_ENDPOINT      0x25U
143 
144 #define USB_DESCRIPTOR_TYPE_SUPERSPEED_ENDPOINT_COMPANION     0x30U
145 #define USB_DESCRIPTOR_TYPE_SUPERSPEED_ISO_ENDPOINT_COMPANION 0x31U
146 
147 /* USB Device Classes */
148 #define USB_DEVICE_CLASS_RESERVED      0x00
149 #define USB_DEVICE_CLASS_AUDIO         0x01
150 #define USB_DEVICE_CLASS_CDC           0x02
151 #define USB_DEVICE_CLASS_HID           0x03
152 #define USB_DEVICE_CLASS_MONITOR       0x04
153 #define USB_DEVICE_CLASS_PHYSICAL      0x05
154 #define USB_DEVICE_CLASS_IMAGE         0x06
155 #define USB_DEVICE_CLASS_PRINTER       0x07
156 #define USB_DEVICE_CLASS_MASS_STORAGE  0x08
157 #define USB_DEVICE_CLASS_HUB           0x09
158 #define USB_DEVICE_CLASS_CDC_DATA      0x0a
159 #define USB_DEVICE_CLASS_SMART_CARD    0x0b
160 #define USB_DEVICE_CLASS_SECURITY      0x0d
161 #define USB_DEVICE_CLASS_VIDEO         0x0e
162 #define USB_DEVICE_CLASS_HEALTHCARE    0x0f
163 #define USB_DEVICE_CLASS_DIAG_DEVICE   0xdc
164 #define USB_DEVICE_CLASS_WIRELESS      0xe0
165 #define USB_DEVICE_CLASS_MISC          0xef
166 #define USB_DEVICE_CLASS_APP_SPECIFIC  0xfe
167 #define USB_DEVICE_CLASS_VEND_SPECIFIC 0xff
168 
169 /* usb string index define */
170 #define USB_STRING_LANGID_INDEX    0x00
171 #define USB_STRING_MFC_INDEX       0x01
172 #define USB_STRING_PRODUCT_INDEX   0x02
173 #define USB_STRING_SERIAL_INDEX    0x03
174 #define USB_STRING_CONFIG_INDEX    0x04
175 #define USB_STRING_INTERFACE_INDEX 0x05
176 #define USB_STRING_OS_INDEX        0x06
177 #define USB_STRING_MAX             USB_STRING_OS_INDEX
178 /*
179  * Devices supporting Microsoft OS Descriptors store special string
180  * descriptor at fixed index (0xEE). It is read when a new device is
181  * attached to a computer for the first time.
182  */
183 #define USB_OSDESC_STRING_DESC_INDEX 0xEE
184 
185 /* bmAttributes in Configuration Descriptor */
186 #define USB_CONFIG_REMOTE_WAKEUP 0x20
187 #define USB_CONFIG_POWERED_MASK  0x40
188 #define USB_CONFIG_BUS_POWERED   0x80
189 #define USB_CONFIG_SELF_POWERED  0xC0
190 
191 /* bMaxPower in Configuration Descriptor */
192 #define USB_CONFIG_POWER_MA(mA) ((mA) / 2)
193 
194 /* bEndpointAddress in Endpoint Descriptor */
195 #define USB_ENDPOINT_DIRECTION_MASK 0x80
196 #define USB_ENDPOINT_OUT(addr)      ((addr) | 0x00)
197 #define USB_ENDPOINT_IN(addr)       ((addr) | 0x80)
198 
199 /**
200  * USB endpoint direction and number.
201  */
202 #define USB_EP_DIR_MASK 0x80U
203 #define USB_EP_DIR_IN   0x80U
204 #define USB_EP_DIR_OUT  0x00U
205 
206 /** Get endpoint index (number) from endpoint address */
207 #define USB_EP_GET_IDX(ep) ((ep) & ~USB_EP_DIR_MASK)
208 /** Get direction from endpoint address */
209 #define USB_EP_GET_DIR(ep) ((ep)&USB_EP_DIR_MASK)
210 /** Get endpoint address from endpoint index and direction */
211 #define USB_EP_GET_ADDR(idx, dir) ((idx) | ((dir)&USB_EP_DIR_MASK))
212 /** True if the endpoint is an IN endpoint */
213 #define USB_EP_DIR_IS_IN(ep) (USB_EP_GET_DIR(ep) == USB_EP_DIR_IN)
214 /** True if the endpoint is an OUT endpoint */
215 #define USB_EP_DIR_IS_OUT(ep) (USB_EP_GET_DIR(ep) == USB_EP_DIR_OUT)
216 
217 /* bmAttributes in Endpoint Descriptor */
218 #define USB_ENDPOINT_TYPE_SHIFT       0
219 #define USB_ENDPOINT_TYPE_CONTROL     (0 << USB_ENDPOINT_TYPE_SHIFT)
220 #define USB_ENDPOINT_TYPE_ISOCHRONOUS (1 << USB_ENDPOINT_TYPE_SHIFT)
221 #define USB_ENDPOINT_TYPE_BULK        (2 << USB_ENDPOINT_TYPE_SHIFT)
222 #define USB_ENDPOINT_TYPE_INTERRUPT   (3 << USB_ENDPOINT_TYPE_SHIFT)
223 #define USB_ENDPOINT_TYPE_MASK        (3 << USB_ENDPOINT_TYPE_SHIFT)
224 
225 #define USB_ENDPOINT_SYNC_SHIFT              2
226 #define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION (0 << USB_ENDPOINT_SYNC_SHIFT)
227 #define USB_ENDPOINT_SYNC_ASYNCHRONOUS       (1 << USB_ENDPOINT_SYNC_SHIFT)
228 #define USB_ENDPOINT_SYNC_ADAPTIVE           (2 << USB_ENDPOINT_SYNC_SHIFT)
229 #define USB_ENDPOINT_SYNC_SYNCHRONOUS        (3 << USB_ENDPOINT_SYNC_SHIFT)
230 #define USB_ENDPOINT_SYNC_MASK               (3 << USB_ENDPOINT_SYNC_SHIFT)
231 
232 #define USB_ENDPOINT_USAGE_SHIFT             4
233 #define USB_ENDPOINT_USAGE_DATA              (0 << USB_ENDPOINT_USAGE_SHIFT)
234 #define USB_ENDPOINT_USAGE_FEEDBACK          (1 << USB_ENDPOINT_USAGE_SHIFT)
235 #define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK (2 << USB_ENDPOINT_USAGE_SHIFT)
236 #define USB_ENDPOINT_USAGE_MASK              (3 << USB_ENDPOINT_USAGE_SHIFT)
237 
238 #define USB_ENDPOINT_MAX_ADJUSTABLE (1 << 7)
239 
240 /* wMaxPacketSize in Endpoint Descriptor */
241 #define USB_MAXPACKETSIZE_SHIFT                        0
242 #define USB_MAXPACKETSIZE_MASK                         (0x7ff << USB_MAXPACKETSIZE_SHIFT)
243 #define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT 11
244 #define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_NONE  (0 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
245 #define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_ONE   (1 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
246 #define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_TWO   (2 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
247 #define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK  (3 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
248 
249 /* bDevCapabilityType in Device Capability Descriptor */
250 #define USB_DEVICE_CAPABILITY_WIRELESS_USB                1
251 #define USB_DEVICE_CAPABILITY_USB_2_0_EXTENSION           2
252 #define USB_DEVICE_CAPABILITY_SUPERSPEED_USB              3
253 #define USB_DEVICE_CAPABILITY_CONTAINER_ID                4
254 #define USB_DEVICE_CAPABILITY_PLATFORM                    5
255 #define USB_DEVICE_CAPABILITY_POWER_DELIVERY_CAPABILITY   6
256 #define USB_DEVICE_CAPABILITY_BATTERY_INFO_CAPABILITY     7
257 #define USB_DEVICE_CAPABILITY_PD_CONSUMER_PORT_CAPABILITY 8
258 #define USB_DEVICE_CAPABILITY_PD_PROVIDER_PORT_CAPABILITY 9
259 #define USB_DEVICE_CAPABILITY_SUPERSPEED_PLUS             10
260 #define USB_DEVICE_CAPABILITY_PRECISION_TIME_MEASUREMENT  11
261 #define USB_DEVICE_CAPABILITY_WIRELESS_USB_EXT            12
262 
263 #define USB_BOS_CAPABILITY_EXTENSION 0x02
264 #define USB_BOS_CAPABILITY_PLATFORM  0x05
265 
266 /* OTG SET FEATURE Constants */
267 #define USB_OTG_FEATURE_B_HNP_ENABLE      3 /* Enable B device to perform HNP */
268 #define USB_OTG_FEATURE_A_HNP_SUPPORT     4 /* A device supports HNP */
269 #define USB_OTG_FEATURE_A_ALT_HNP_SUPPORT 5 /* Another port on the A device supports HNP */
270 
271 /* WinUSB Microsoft OS 2.0 descriptor request codes */
272 #define WINUSB_REQUEST_GET_DESCRIPTOR_SET 0x07
273 #define WINUSB_REQUEST_SET_ALT_ENUM       0x08
274 
275 /* WinUSB Microsoft OS 2.0 descriptor sizes */
276 #define WINUSB_DESCRIPTOR_SET_HEADER_SIZE  10
277 #define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
278 #define WINUSB_FEATURE_COMPATIBLE_ID_SIZE  20
279 
280 /* WinUSB Microsoft OS 2.0 Descriptor Types */
281 #define WINUSB_SET_HEADER_DESCRIPTOR_TYPE       0x00
282 #define WINUSB_SUBSET_HEADER_CONFIGURATION_TYPE 0x01
283 #define WINUSB_SUBSET_HEADER_FUNCTION_TYPE      0x02
284 #define WINUSB_FEATURE_COMPATIBLE_ID_TYPE       0x03
285 #define WINUSB_FEATURE_REG_PROPERTY_TYPE        0x04
286 #define WINUSB_FEATURE_MIN_RESUME_TIME_TYPE     0x05
287 #define WINUSB_FEATURE_MODEL_ID_TYPE            0x06
288 #define WINUSB_FEATURE_CCGP_DEVICE_TYPE         0x07
289 
290 #define WINUSB_PROP_DATA_TYPE_REG_SZ       0x01
291 #define WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ 0x07
292 
293 /* WebUSB Descriptor Types */
294 #define WEBUSB_DESCRIPTOR_SET_HEADER_TYPE       0x00
295 #define WEBUSB_CONFIGURATION_SUBSET_HEADER_TYPE 0x01
296 #define WEBUSB_FUNCTION_SUBSET_HEADER_TYPE      0x02
297 #define WEBUSB_URL_TYPE                         0x03
298 
299 /* WebUSB Request Codes */
300 #define WEBUSB_REQUEST_GET_URL 0x02
301 
302 /* bScheme in URL descriptor */
303 #define WEBUSB_URL_SCHEME_HTTP  0x00
304 #define WEBUSB_URL_SCHEME_HTTPS 0x01
305 
306 /* WebUSB Descriptor sizes */
307 #define WEBUSB_DESCRIPTOR_SET_HEADER_SIZE       5
308 #define WEBUSB_CONFIGURATION_SUBSET_HEADER_SIZE 4
309 #define WEBUSB_FUNCTION_SUBSET_HEADER_SIZE      3
310 
311 /* Setup packet definition used to read raw data from USB line */
312 struct usb_setup_packet {
313     /** Request type. Bits 0:4 determine recipient, see
314 	 * \ref usb_request_recipient. Bits 5:6 determine type, see
315 	 * \ref usb_request_type. Bit 7 determines data transfer direction, see
316 	 * \ref usb_endpoint_direction.
317 	 */
318     uint8_t bmRequestType;
319 
320     /** Request. If the type bits of bmRequestType are equal to
321 	 * \ref usb_request_type::LIBUSB_REQUEST_TYPE_STANDARD
322 	 * "USB_REQUEST_TYPE_STANDARD" then this field refers to
323 	 * \ref usb_standard_request. For other cases, use of this field is
324 	 * application-specific. */
325     uint8_t bRequest;
326 
327     /** Value. Varies according to request */
328     uint16_t wValue;
329 
330     /** Index. Varies according to request, typically used to pass an index
331 	 * or offset */
332     uint16_t wIndex;
333 
334     /** Number of bytes to transfer */
335     uint16_t wLength;
336 } __PACKED;
337 
338 #define USB_SIZEOF_SETUP_PACKET 8
339 
340 /** Standard Device Descriptor */
341 struct usb_device_descriptor {
342     uint8_t bLength;            /* Descriptor size in bytes = 18 */
343     uint8_t bDescriptorType;    /* DEVICE descriptor type = 1 */
344     uint16_t bcdUSB;            /* USB spec in BCD, e.g. 0x0200 */
345     uint8_t bDeviceClass;       /* Class code, if 0 see interface */
346     uint8_t bDeviceSubClass;    /* Sub-Class code, 0 if class = 0 */
347     uint8_t bDeviceProtocol;    /* Protocol, if 0 see interface */
348     uint8_t bMaxPacketSize0;    /* Endpoint 0 max. size */
349     uint16_t idVendor;          /* Vendor ID per USB-IF */
350     uint16_t idProduct;         /* Product ID per manufacturer */
351     uint16_t bcdDevice;         /* Device release # in BCD */
352     uint8_t iManufacturer;      /* Index to manufacturer string */
353     uint8_t iProduct;           /* Index to product string */
354     uint8_t iSerialNumber;      /* Index to serial number string */
355     uint8_t bNumConfigurations; /* Number of possible configurations */
356 } __PACKED;
357 
358 #define USB_SIZEOF_DEVICE_DESC 18
359 
360 /** Standard Configuration Descriptor */
361 struct usb_configuration_descriptor {
362     uint8_t bLength;             /* Descriptor size in bytes = 9 */
363     uint8_t bDescriptorType;     /* CONFIGURATION type = 2 or 7 */
364     uint16_t wTotalLength;       /* Length of concatenated descriptors */
365     uint8_t bNumInterfaces;      /* Number of interfaces, this config. */
366     uint8_t bConfigurationValue; /* Value to set this config. */
367     uint8_t iConfiguration;      /* Index to configuration string */
368     uint8_t bmAttributes;        /* Config. characteristics */
369     uint8_t bMaxPower;           /* Max.power from bus, 2mA units */
370 } __PACKED;
371 
372 #define USB_SIZEOF_CONFIG_DESC 9
373 
374 /** Standard Interface Descriptor */
375 struct usb_interface_descriptor {
376     uint8_t bLength;            /* Descriptor size in bytes = 9 */
377     uint8_t bDescriptorType;    /* INTERFACE descriptor type = 4 */
378     uint8_t bInterfaceNumber;   /* Interface no.*/
379     uint8_t bAlternateSetting;  /* Value to select this IF */
380     uint8_t bNumEndpoints;      /* Number of endpoints excluding 0 */
381     uint8_t bInterfaceClass;    /* Class code, 0xFF = vendor */
382     uint8_t bInterfaceSubClass; /* Sub-Class code, 0 if class = 0 */
383     uint8_t bInterfaceProtocol; /* Protocol, 0xFF = vendor */
384     uint8_t iInterface;         /* Index to interface string */
385 } __PACKED;
386 
387 #define USB_SIZEOF_INTERFACE_DESC 9
388 
389 /** Standard Endpoint Descriptor */
390 struct usb_endpoint_descriptor {
391     uint8_t bLength;          /* Descriptor size in bytes = 7 */
392     uint8_t bDescriptorType;  /* ENDPOINT descriptor type = 5 */
393     uint8_t bEndpointAddress; /* Endpoint # 0 - 15 | IN/OUT */
394     uint8_t bmAttributes;     /* Transfer type */
395     uint16_t wMaxPacketSize;  /* Bits 10:0 = max. packet size */
396     uint8_t bInterval;        /* Polling interval in (micro) frames */
397 } __PACKED;
398 
399 #define USB_SIZEOF_ENDPOINT_DESC 7
400 
401 /** Unicode (UTF16LE) String Descriptor */
402 struct usb_string_descriptor {
403     uint8_t bLength;
404     uint8_t bDescriptorType;
405     uint16_t bString;
406 } __PACKED;
407 
408 #define USB_SIZEOF_STRING_LANGID_DESC 4
409 
410 /* USB Interface Association Descriptor */
411 struct usb_interface_association_descriptor {
412     uint8_t bLength;
413     uint8_t bDescriptorType;
414     uint8_t bFirstInterface;
415     uint8_t bInterfaceCount;
416     uint8_t bFunctionClass;
417     uint8_t bFunctionSubClass;
418     uint8_t bFunctionProtocol;
419     uint8_t iFunction;
420 } __PACKED;
421 
422 #define USB_SIZEOF_IAD_DESC 8
423 
424 /** USB device_qualifier descriptor */
425 struct usb_device_qualifier_descriptor {
426     uint8_t bLength;            /* Descriptor size in bytes = 10 */
427     uint8_t bDescriptorType;    /* DEVICE QUALIFIER type = 6 */
428     uint16_t bcdUSB;            /* USB spec in BCD, e.g. 0x0200 */
429     uint8_t bDeviceClass;       /* Class code, if 0 see interface */
430     uint8_t bDeviceSubClass;    /* Sub-Class code, 0 if class = 0 */
431     uint8_t bDeviceProtocol;    /* Protocol, if 0 see interface */
432     uint8_t bMaxPacketSize;     /* Endpoint 0 max. size */
433     uint8_t bNumConfigurations; /* Number of possible configurations */
434     uint8_t bReserved;          /* Reserved = 0 */
435 } __PACKED;
436 
437 #define USB_SIZEOF_DEVICE_QUALIFIER_DESC 10
438 
439 /* Microsoft OS function descriptor.
440  * This can be used to request a specific driver (such as WINUSB) to be
441  * loaded on Windows. Unlike other descriptors, it is requested by a special
442  * request USB_REQ_GETMSFTOSDESCRIPTOR.
443  * More details:
444  *       https://msdn.microsoft.com/en-us/windows/hardware/gg463179
445  * And excellent explanation:
446  *       https://github.com/pbatard/libwdi/wiki/WCID-Devices
447  *
448  * The device will have exactly one "Extended Compat ID Feature Descriptor",
449  * which may contain multiple "Function Descriptors" associated with
450  * different interfaces.
451  */
452 
453 /* MS OS 1.0 string descriptor */
454 struct usb_msosv1_string_descriptor {
455     uint8_t bLength;
456     uint8_t bDescriptorType;
457     uint8_t bString[14];
458     uint8_t bMS_VendorCode; /* Vendor Code, used for a control request */
459     uint8_t bPad;           /* Padding byte for VendorCode look as UTF16 */
460 } __PACKED;
461 
462 /* MS OS 1.0 Header descriptor */
463 struct usb_msosv1_compat_id_header_descriptor {
464     uint32_t dwLength;
465     uint16_t bcdVersion;
466     uint16_t wIndex;
467     uint8_t bCount;
468     uint8_t reserved[7];
469 } __PACKED;
470 
471 /* MS OS 1.0 Function descriptor */
472 struct usb_msosv1_comp_id_function_descriptor {
473     uint8_t bFirstInterfaceNumber;
474     uint8_t reserved1;
475     uint8_t compatibleID[8];
476     uint8_t subCompatibleID[8];
477     uint8_t reserved2[6];
478 } __PACKED;
479 
480 #define usb_msosv1_comp_id_create(x)                                         \
481     struct usb_msosv1_comp_id {                                              \
482         struct usb_msosv1_compat_id_header_descriptor compat_id_header;      \
483         struct usb_msosv1_comp_id_function_descriptor compat_id_function[x]; \
484     };
485 
486 struct usb_msosv1_descriptor {
487     const uint8_t *string;
488     uint8_t vendor_code;
489     const uint8_t *compat_id;
490     const uint8_t **comp_id_property;
491 };
492 
493 /* MS OS 2.0 Header descriptor */
494 struct usb_msosv2_header_descriptor {
495     uint32_t dwLength;
496     uint16_t bcdVersion;
497     uint16_t wIndex;
498     uint8_t bCount;
499 } __PACKED;
500 
501 /*Microsoft OS 2.0 set header descriptor*/
502 struct usb_msosv2_set_header_descriptor {
503     uint16_t wLength;
504     uint16_t wDescriptorType;
505     uint32_t dwWindowsVersion;
506     uint16_t wDescriptorSetTotalLength;
507 } __PACKED;
508 
509 /* Microsoft OS 2.0 compatibleID descriptor*/
510 struct usb_msosv2_comp_id_descriptor {
511     uint16_t wLength;
512     uint16_t wDescriptorType;
513     uint8_t compatibleID[8];
514     uint8_t subCompatibleID[8];
515 } __PACKED;
516 
517 /* MS OS 2.0 property descriptor */
518 struct usb_msosv2_property_descriptor {
519     uint16_t wLength;
520     uint16_t wDescriptorType;
521     uint32_t dwPropertyDataType;
522     uint16_t wPropertyNameLength;
523     const char *bPropertyName;
524     uint32_t dwPropertyDataLength;
525     const char *bPropertyData;
526 };
527 
528 /* Microsoft OS 2.0 subset function descriptor  */
529 struct usb_msosv2_subset_function_descriptor {
530     uint16_t wLength;
531     uint16_t wDescriptorType;
532     uint8_t bFirstInterface;
533     uint8_t bReserved;
534     uint16_t wSubsetLength;
535 } __PACKED;
536 
537 struct usb_msosv2_descriptor {
538     uint8_t *compat_id;
539     uint16_t compat_id_len;
540     uint8_t vendor_code;
541 };
542 
543 /* BOS header Descriptor */
544 struct usb_bos_header_descriptor {
545     uint8_t bLength;
546     uint8_t bDescriptorType;
547     uint16_t wTotalLength;
548     uint8_t bNumDeviceCaps;
549 } __PACKED;
550 
551 /* BOS Capability platform Descriptor */
552 struct usb_bos_capability_platform_descriptor {
553     uint8_t bLength;
554     uint8_t bDescriptorType;
555     uint8_t bDevCapabilityType;
556     uint8_t bReserved;
557     uint8_t PlatformCapabilityUUID[16];
558 } __PACKED;
559 
560 /* BOS Capability MS OS Descriptors version 2 */
561 struct usb_bos_capability_msosv2_descriptor {
562     uint32_t dwWindowsVersion;
563     uint16_t wMSOSDescriptorSetTotalLength;
564     uint8_t bVendorCode;
565     uint8_t bAltEnumCode;
566 } __PACKED;
567 
568 /* BOS Capability webusb */
569 struct usb_bos_capability_webusb_descriptor {
570     uint16_t bcdVersion;
571     uint8_t bVendorCode;
572     uint8_t iLandingPage;
573 } __PACKED;
574 
575 /* BOS Capability extension Descriptor*/
576 struct usb_bos_capability_extension_descriptor {
577     uint8_t bLength;
578     uint8_t bDescriptorType;
579     uint8_t bDevCapabilityType;
580     uint32_t bmAttributes;
581 } __PACKED;
582 
583 /* Microsoft OS 2.0 Platform Capability Descriptor
584 * See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/
585 * microsoft-defined-usb-descriptors
586 * Adapted from the source:
587 * https://github.com/sowbug/weblight/blob/master/firmware/webusb.c
588 * (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c
589 */
590 struct usb_bos_capability_platform_msosv2_descriptor {
591     struct usb_bos_capability_platform_descriptor platform_msos;
592     struct usb_bos_capability_msosv2_descriptor data_msosv2;
593 } __PACKED;
594 
595 /* WebUSB Platform Capability Descriptor:
596 * https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
597 */
598 struct usb_bos_capability_platform_webusb_descriptor {
599     struct usb_bos_capability_platform_descriptor platform_webusb;
600     struct usb_bos_capability_webusb_descriptor data_webusb;
601 } __PACKED;
602 
603 struct usb_webusb_url_descriptor {
604     uint8_t bLength;
605     uint8_t bDescriptorType;
606     uint8_t bScheme;
607     char URL[];
608 } __PACKED;
609 
610 struct usb_webusb_url_ex_descriptor {
611     uint8_t vendor_code;
612     uint8_t *string;
613     uint32_t string_len;
614 } __PACKED;
615 
616 struct usb_bos_descriptor {
617     uint8_t *string;
618     uint32_t string_len;
619 };
620 
621 /* USB Device Capability Descriptor */
622 struct usb_device_capability_descriptor {
623     uint8_t bLength;
624     uint8_t bDescriptorType;
625     uint8_t bDevCapabilityType;
626 } __PACKED;
627 
628 /** USB descriptor header */
629 struct usb_desc_header {
630     uint8_t bLength;         /**< descriptor length */
631     uint8_t bDescriptorType; /**< descriptor type */
632 };
633 // clang-format off
634 #define USB_DEVICE_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct, bcdDevice, bNumConfigurations) \
635     0x12,                       /* bLength */                                                                                              \
636     USB_DESCRIPTOR_TYPE_DEVICE, /* bDescriptorType */                                                                                      \
637     WBVAL(bcdUSB),              /* bcdUSB */                                                                                               \
638     bDeviceClass,               /* bDeviceClass */                                                                                         \
639     bDeviceSubClass,            /* bDeviceSubClass */                                                                                      \
640     bDeviceProtocol,            /* bDeviceProtocol */                                                                                      \
641     0x40,                       /* bMaxPacketSize */                                                                                       \
642     WBVAL(idVendor),            /* idVendor */                                                                                             \
643     WBVAL(idProduct),           /* idProduct */                                                                                            \
644     WBVAL(bcdDevice),           /* bcdDevice */                                                                                            \
645     USB_STRING_MFC_INDEX,       /* iManufacturer */                                                                                        \
646     USB_STRING_PRODUCT_INDEX,   /* iProduct */                                                                                             \
647     USB_STRING_SERIAL_INDEX,    /* iSerial */                                                                                              \
648     bNumConfigurations          /* bNumConfigurations */
649 
650 #define USB_CONFIG_DESCRIPTOR_INIT(wTotalLength, bNumInterfaces, bConfigurationValue, bmAttributes, bMaxPower) \
651     0x09,                              /* bLength */                                                       \
652     USB_DESCRIPTOR_TYPE_CONFIGURATION, /* bDescriptorType */                                               \
653     WBVAL(wTotalLength),               /* wTotalLength */                                                  \
654     bNumInterfaces,                    /* bNumInterfaces */                                                \
655     bConfigurationValue,               /* bConfigurationValue */                                           \
656     0x00,                              /* iConfiguration */                                                \
657     bmAttributes,                      /* bmAttributes */                                                  \
658     USB_CONFIG_POWER_MA(bMaxPower)     /* bMaxPower */
659 
660 #define USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bNumEndpoints,                  \
661                                       bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol, iInterface) \
662     0x09,                          /* bLength */                                                       \
663     USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */                                               \
664     bInterfaceNumber,              /* bInterfaceNumber */                                              \
665     bAlternateSetting,             /* bAlternateSetting */                                             \
666     bNumEndpoints,                 /* bNumEndpoints */                                                 \
667     bInterfaceClass,               /* bInterfaceClass */                                               \
668     bInterfaceSubClass,            /* bInterfaceSubClass */                                            \
669     bInterfaceProtocol,            /* bInterfaceProtocol */                                            \
670     iInterface                     /* iInterface */
671 
672 #define USB_ENDPOINT_DESCRIPTOR_INIT(bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \
673     0x07,                         /* bLength */                                             \
674     USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */                                     \
675     bEndpointAddress,             /* bEndpointAddress */                                    \
676     bmAttributes,                 /* bmAttributes */                                        \
677     WBVAL(wMaxPacketSize),        /* wMaxPacketSize */                                      \
678     bInterval                     /* bInterval */
679 
680 #define USB_IAD_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \
681     0x08,                                      /* bLength */                                             \
682     USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */                                     \
683     bFirstInterface,                           /* bFirstInterface */                                     \
684     bInterfaceCount,                           /* bInterfaceCount */                                     \
685     bFunctionClass,                            /* bFunctionClass */                                      \
686     bFunctionSubClass,                         /* bFunctionSubClass */                                   \
687     bFunctionProtocol,                         /* bFunctionProtocol */                                   \
688     0x00                                       /* iFunction */
689 
690 #define USB_LANGID_INIT(id)                           \
691     0x04,                           /* bLength */     \
692     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \
693     WBVAL(id)                   /* wLangID0 */
694 // clang-format on
695 
696 #endif /* USB_DEF_H */
697