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_WEBUSB_DESCRIPTOR_H
9 #define ZEPHYR_INCLUDE_WEBUSB_DESCRIPTOR_H
10
11 /*
12 * WebUSB platform capability and WebUSB URL descriptor.
13 * See https://wicg.github.io/webusb for reference.
14 */
15
16 #define WEBUSB_REQ_GET_URL 0x02U
17 #define WEBUSB_DESC_TYPE_URL 0x03U
18 #define WEBUSB_URL_PREFIX_HTTP 0x00U
19 #define WEBUSB_URL_PREFIX_HTTPS 0x01U
20
21 #define SAMPLE_WEBUSB_VENDOR_CODE 0x01U
22 #define SAMPLE_WEBUSB_LANDING_PAGE 0x01U
23
24 struct usb_bos_webusb_desc {
25 struct usb_bos_platform_descriptor platform;
26 struct usb_bos_capability_webusb cap;
27 } __packed;
28
29 static const struct usb_bos_webusb_desc bos_cap_webusb = {
30 /* WebUSB Platform Capability Descriptor:
31 * https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
32 */
33 .platform = {
34 .bLength = sizeof(struct usb_bos_platform_descriptor)
35 + sizeof(struct usb_bos_capability_webusb),
36 .bDescriptorType = USB_DESC_DEVICE_CAPABILITY,
37 .bDevCapabilityType = USB_BOS_CAPABILITY_PLATFORM,
38 .bReserved = 0,
39 /* WebUSB Platform Capability UUID
40 * 3408b638-09a9-47a0-8bfd-a0768815b665
41 */
42 .PlatformCapabilityUUID = {
43 0x38, 0xB6, 0x08, 0x34,
44 0xA9, 0x09,
45 0xA0, 0x47,
46 0x8B, 0xFD,
47 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
48 },
49 },
50 .cap = {
51 .bcdVersion = sys_cpu_to_le16(0x0100),
52 .bVendorCode = SAMPLE_WEBUSB_VENDOR_CODE,
53 .iLandingPage = SAMPLE_WEBUSB_LANDING_PAGE
54 }
55 };
56
57 /* WebUSB URL Descriptor, see https://wicg.github.io/webusb/#webusb-descriptors */
58 static const uint8_t webusb_origin_url[] = {
59 /* bLength, bDescriptorType, bScheme, UTF-8 encoded URL */
60 0x11, WEBUSB_DESC_TYPE_URL, WEBUSB_URL_PREFIX_HTTP,
61 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', ':', '8', '0', '0', '0'
62 };
63
webusb_to_host_cb(const struct usbd_context * const ctx,const struct usb_setup_packet * const setup,struct net_buf * const buf)64 static int webusb_to_host_cb(const struct usbd_context *const ctx,
65 const struct usb_setup_packet *const setup,
66 struct net_buf *const buf)
67 {
68 LOG_INF("Vendor callback to host");
69
70 if (setup->wIndex == WEBUSB_REQ_GET_URL) {
71 uint8_t index = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
72
73 if (index != SAMPLE_WEBUSB_LANDING_PAGE) {
74 return -ENOTSUP;
75 }
76
77 LOG_INF("Get URL request, index %u", index);
78 net_buf_add_mem(buf, &webusb_origin_url,
79 MIN(net_buf_tailroom(buf), sizeof(webusb_origin_url)));
80
81 return 0;
82 }
83
84 return -ENOTSUP;
85 }
86
87 USBD_DESC_BOS_VREQ_DEFINE(bos_vreq_webusb, sizeof(bos_cap_webusb), &bos_cap_webusb,
88 SAMPLE_WEBUSB_VENDOR_CODE, webusb_to_host_cb, NULL);
89
90 #endif /* ZEPHYR_INCLUDE_WEBUSB_DESCRIPTOR_H */
91