1 /*
2 * Copyright (c) 2016-2019 Intel Corporation
3 * Copyright (c) 2023-2024 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #ifndef ZEPHYR_INCLUDE_MSOSV2_DESCRIPTOR_H
9 #define ZEPHYR_INCLUDE_MSOSV2_DESCRIPTOR_H
10
11 /*
12 * Microsoft OS 2.0 platform capability and Microsoft OS 2.0 descriptor set.
13 * See Microsoft OS 2.0 Descriptors Specification for reference.
14 */
15
16 #define SAMPLE_MSOS2_VENDOR_CODE 0x02U
17 /* Windows version (10)*/
18 #define SAMPLE_MSOS2_OS_VERSION 0x0A000000UL
19
20 /* random GUID {FA611CC3-7057-42EE-9D82-4919639562B3} */
21 #define WEBUSB_DEVICE_INTERFACE_GUID \
22 '{', 0x00, 'F', 0x00, 'A', 0x00, '6', 0x00, '1', 0x00, '1', 0x00, \
23 'C', 0x00, 'C', 0x00, '3', 0x00, '-', 0x00, '7', 0x00, '0', 0x00, \
24 '5', 0x00, '7', 0x00, '-', 0x00, '4', 0x00, '2', 0x00, 'E', 0x00, \
25 'E', 0x00, '-', 0x00, '9', 0x00, 'D', 0x00, '8', 0x00, '2', 0x00, \
26 '-', 0x00, '4', 0x00, '9', 0x00, '1', 0x00, '9', 0x00, '6', 0x00, \
27 '3', 0x00, '9', 0x00, '5', 0x00, '6', 0x00, '2', 0x00, 'B', 0x00, \
28 '3', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
29
30 #define CDC_ACM_DESCRIPTOR_LENGTH 160
31
32 struct msosv2_descriptor {
33 struct msosv2_descriptor_set_header header;
34 #if defined(CONFIG_USBD_CDC_ACM_CLASS)
35 /*
36 * The composition of this descriptor is specific to the WebUSB example
37 * in its default configuration. If you use it for your application or
38 * change the configuration, you may need to modify this descriptor for
39 * your USB device. The following only covers the case where the CDC
40 * ACM implementation is enabled, and there is only one CDC ACM UART
41 * instance, and the CDC ACM communication interface is the first in
42 * the configuration.
43 */
44 struct msosv2_function_subset_header subset_header;
45 #endif
46 struct msosv2_compatible_id compatible_id;
47 struct msosv2_guids_property guids_property;
48 } __packed;
49
50 static struct msosv2_descriptor msosv2_desc = {
51 .header = {
52 .wLength = sizeof(struct msosv2_descriptor_set_header),
53 .wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR,
54 .dwWindowsVersion = sys_cpu_to_le32(SAMPLE_MSOS2_OS_VERSION),
55 .wTotalLength = sizeof(msosv2_desc),
56 },
57 #if defined(CONFIG_USBD_CDC_ACM_CLASS)
58 .subset_header = {
59 .wLength = sizeof(struct msosv2_function_subset_header),
60 .wDescriptorType = MS_OS_20_SUBSET_HEADER_FUNCTION,
61 .bFirstInterface = 0,
62 .wSubsetLength = CDC_ACM_DESCRIPTOR_LENGTH,
63 },
64 #endif
65 .compatible_id = {
66 .wLength = sizeof(struct msosv2_compatible_id),
67 .wDescriptorType = MS_OS_20_FEATURE_COMPATIBLE_ID,
68 .CompatibleID = {'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00},
69 },
70 .guids_property = {
71 .wLength = sizeof(struct msosv2_guids_property),
72 .wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY,
73 .wPropertyDataType = MS_OS_20_PROPERTY_DATA_REG_MULTI_SZ,
74 .wPropertyNameLength = 42,
75 .PropertyName = {DEVICE_INTERFACE_GUIDS_PROPERTY_NAME},
76 .wPropertyDataLength = 80,
77 .bPropertyData = {WEBUSB_DEVICE_INTERFACE_GUID},
78 },
79 };
80
81 struct bos_msosv2_descriptor {
82 struct usb_bos_platform_descriptor platform;
83 struct usb_bos_capability_msos cap;
84 } __packed;
85
86 struct bos_msosv2_descriptor bos_msosv2_desc = {
87 /*
88 * Microsoft OS 2.0 Platform Capability Descriptor,
89 * see Microsoft OS 2.0 Descriptors Specification
90 */
91 .platform = {
92 .bLength = sizeof(struct usb_bos_platform_descriptor)
93 + sizeof(struct usb_bos_capability_msos),
94 .bDescriptorType = USB_DESC_DEVICE_CAPABILITY,
95 .bDevCapabilityType = USB_BOS_CAPABILITY_PLATFORM,
96 .bReserved = 0,
97 /* Microsoft OS 2.0 descriptor platform capability UUID
98 * D8DD60DF-4589-4CC7-9CD2-659D9E648A9F
99 */
100 .PlatformCapabilityUUID = {
101 0xDF, 0x60, 0xDD, 0xD8,
102 0x89, 0x45,
103 0xC7, 0x4C,
104 0x9C, 0xD2,
105 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
106 },
107 },
108 .cap = {
109 .dwWindowsVersion = sys_cpu_to_le32(SAMPLE_MSOS2_OS_VERSION),
110 .wMSOSDescriptorSetTotalLength = sys_cpu_to_le16(sizeof(msosv2_desc)),
111 .bMS_VendorCode = SAMPLE_MSOS2_VENDOR_CODE,
112 .bAltEnumCode = 0x00
113 },
114 };
115
msosv2_to_host_cb(const struct usbd_context * const ctx,const struct usb_setup_packet * const setup,struct net_buf * const buf)116 static int msosv2_to_host_cb(const struct usbd_context *const ctx,
117 const struct usb_setup_packet *const setup,
118 struct net_buf *const buf)
119 {
120 LOG_INF("Vendor callback to host");
121
122 if (setup->bRequest == SAMPLE_MSOS2_VENDOR_CODE &&
123 setup->wIndex == MS_OS_20_DESCRIPTOR_INDEX) {
124 LOG_INF("Get MS OS 2.0 Descriptor Set");
125
126 net_buf_add_mem(buf, &msosv2_desc,
127 MIN(net_buf_tailroom(buf), sizeof(msosv2_desc)));
128
129 return 0;
130 }
131
132 return -ENOTSUP;
133 }
134
135 USBD_DESC_BOS_VREQ_DEFINE(bos_vreq_msosv2, sizeof(bos_msosv2_desc), &bos_msosv2_desc,
136 SAMPLE_MSOS2_VENDOR_CODE, msosv2_to_host_cb, NULL);
137
138 #endif /* ZEPHYR_INCLUDE_MSOSV2_DESCRIPTOR_H */
139