From c1724f65bfae94ff8db4ad424c170c3cfc2af32f Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 31 May 2018 16:26:58 +0300 Subject: [PATCH] usb: bos: Add USB BOS descriptors API Add API for USB BOS Descriptors. Signed-off-by: Andrei Emeltchenko --- include/usb/bos.h | 57 ++++++++++++++++++++++++++++++++ include/usb/usb_common.h | 21 ------------ subsys/usb/CMakeLists.txt | 6 ++++ subsys/usb/Kconfig | 5 +++ subsys/usb/bos.c | 68 +++++++++++++++++++++++++++++++++++++++ subsys/usb/usb_device.c | 6 ++++ 6 files changed, 142 insertions(+), 21 deletions(-) create mode 100644 include/usb/bos.h create mode 100644 subsys/usb/bos.c diff --git a/include/usb/bos.h b/include/usb/bos.h new file mode 100644 index 00000000000..bd296177a11 --- /dev/null +++ b/include/usb/bos.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_USB_DEVICE_BOS) +#define USB_DEVICE_BOS_DESC_DEFINE_HDR \ + static __in_section(usb, bos_desc_area, 0) __used +#define USB_DEVICE_BOS_DESC_DEFINE_CAP \ + static __in_section(usb, bos_desc_area, 1) __used + +/* BOS descriptor type */ +#define DESCRIPTOR_TYPE_BOS 0x0F + +#define USB_BOS_CAPABILITY_PLATFORM 0x05 + +/* BOS Capability Descriptor */ +struct usb_bos_platform_descriptor { + u8_t bLength; + u8_t bDescriptorType; + u8_t bDevCapabilityType; + u8_t bReserved; + u8_t PlatformCapabilityUUID[16]; +} __packed; + +/* BOS Descriptor */ +struct usb_bos_descriptor { + u8_t bLength; + u8_t bDescriptorType; + u16_t wTotalLength; + u8_t bNumDeviceCaps; +} __packed; + +/* BOS Capability webusb */ +struct usb_bos_capability_webusb { + u16_t bcdVersion; + u8_t bVendorCode; + u8_t iLandingPage; +} __packed; + +/* BOS Capability MS OS Descriptors version 2 */ +struct usb_bos_capability_msos { + u32_t dwWindowsVersion; + u16_t wMSOSDescriptorSetTotalLength; + u8_t bMS_VendorCode; + u8_t bAltEnumCode; +} __packed; + +size_t usb_bos_get_length(void); +void usb_bos_fix_total_length(void); +void usb_bos_register_cap(struct usb_bos_platform_descriptor *hdr); +const void *usb_bos_get_header(void); +int usb_handle_bos(struct usb_setup_packet *setup, s32_t *len, u8_t **data); +#else +#define usb_handle_bos(x, y, z) -ENOTSUP +#endif diff --git a/include/usb/usb_common.h b/include/usb/usb_common.h index de9f58fb2d7..8e80444ece5 100644 --- a/include/usb/usb_common.h +++ b/include/usb/usb_common.h @@ -198,25 +198,4 @@ struct usb_ep_descriptor { u8_t bInterval; } __packed; -/** Binary Device Object Store (BOS) */ - -#define USB_BOS_CAPABILITY_PLATFORM 0x05 - -/** BOS Capability Descriptor */ -struct usb_bos_platform_descriptor { - u8_t bLength; - u8_t bDescriptorType; - u8_t bDevCapabilityType; - u8_t bReserved; - u8_t PlatformCapabilityUUID[16]; -} __packed; - -/** BOS Descriptor */ -struct usb_bos_descriptor { - u8_t bLength; - u8_t bDescriptorType; - u16_t wTotalLength; - u8_t bNumDeviceCaps; -} __packed; - #endif /* USB_COMMON_H_ */ diff --git a/subsys/usb/CMakeLists.txt b/subsys/usb/CMakeLists.txt index b9227fe70de..05d5eb3c3e3 100644 --- a/subsys/usb/CMakeLists.txt +++ b/subsys/usb/CMakeLists.txt @@ -7,6 +7,12 @@ if(CONFIG_USB_DEVICE_STACK) add_subdirectory(class) endif() +if(CONFIG_USB_DEVICE_BOS) + zephyr_sources( + bos.c + ) +endif() + if(CONFIG_USB_DEVICE_VID EQUAL 0x2FE3) message(WARNING "CONFIG_USB_DEVICE_VID has default value 0x2FE3. diff --git a/subsys/usb/Kconfig b/subsys/usb/Kconfig index d5baa257032..b2936359180 100644 --- a/subsys/usb/Kconfig +++ b/subsys/usb/Kconfig @@ -86,6 +86,11 @@ config USB_COMPOSITE_BUFFER_SIZE default 64 default 256 if USB_DEVICE_NETWORK_RNDIS +config USB_DEVICE_BOS + bool + prompt "Enable USB Binary Device Object Store (BOS)" + default n + source "subsys/usb/class/Kconfig" endif # USB_DEVICE_STACK diff --git a/subsys/usb/bos.c b/subsys/usb/bos.c new file mode 100644 index 00000000000..5403b218f27 --- /dev/null +++ b/subsys/usb/bos.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define SYS_LOG_LEVEL CONFIG_SYS_LOG_USB_DEVICE_LEVEL +#define SYS_LOG_DOMAIN "usb/bos" +#include + +#include + +#include +#include + +#include + +extern const u8_t __usb_bos_desc_start[]; +extern const u8_t __usb_bos_desc_end[]; + +USB_DEVICE_BOS_DESC_DEFINE_HDR struct usb_bos_descriptor hdr = { + .bLength = sizeof(struct usb_bos_descriptor), + .bDescriptorType = USB_BINARY_OBJECT_STORE_DESC, + .wTotalLength = 0, /* should be corrected with register */ + .bNumDeviceCaps = 0, /* should be set with register */ +}; + +size_t usb_bos_get_length(void) +{ + return __usb_bos_desc_end - __usb_bos_desc_start; +} + +const void *usb_bos_get_header(void) +{ + return __usb_bos_desc_start; +} + +void usb_bos_fix_total_length(void) +{ + struct usb_bos_descriptor *hdr = (void *)__usb_bos_desc_start; + + hdr->wTotalLength = usb_bos_get_length(); +} + +void usb_bos_register_cap(struct usb_bos_platform_descriptor *desc) +{ + struct usb_bos_descriptor *hdr = (void *)__usb_bos_desc_start; + + /* Has effect only on first register */ + hdr->wTotalLength = usb_bos_get_length(); + + hdr->bNumDeviceCaps += 1; +} + +int usb_handle_bos(struct usb_setup_packet *setup, + s32_t *len, u8_t **data) +{ + SYS_LOG_DBG("wValue 0x%x", setup->wValue); + + if (GET_DESC_TYPE(setup->wValue) == DESCRIPTOR_TYPE_BOS) { + *data = (u8_t *)usb_bos_get_header(); + *len = usb_bos_get_length(); + + return 0; + } + + return -ENOTSUP; +} diff --git a/subsys/usb/usb_device.c b/subsys/usb/usb_device.c index 33def4abd2f..3196f05d41c 100644 --- a/subsys/usb/usb_device.c +++ b/subsys/usb/usb_device.c @@ -74,6 +74,8 @@ #define SYS_LOG_NO_NEWLINE #include +#include + #define MAX_DESC_HANDLERS 4 /** Device, interface, endpoint, other */ /* general descriptor field offsets */ @@ -782,6 +784,10 @@ static int usb_handle_standard_request(struct usb_setup_packet *setup, { int rc = 0; + if (!usb_handle_bos(setup, len, data_buf)) { + return 0; + } + /* try the custom request handler first */ if (usb_dev.custom_req_handler && !usb_dev.custom_req_handler(setup, len, data_buf)) {