samples: subsys: usb: webusb: Fix Win10 detection
This patch refactors the usage of MS OS 2.0 descriptors in the WebUSB sample. The function subset header was removed since it is not allowed for non-composite devices. Also, a new random GUID was added for automatic driver installation. Signed-off-by: Maximilian Deubel <maximilian.deubel@nordicsemi.no>
This commit is contained in:
parent
fbacedaef8
commit
860515a3ad
102
include/zephyr/usb/msos_desc.h
Normal file
102
include/zephyr/usb/msos_desc.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief MS OS 2.0 descriptor definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_USB_MSOS_DESC_H
|
||||
#define ZEPHYR_INCLUDE_USB_MSOS_DESC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum msosv2_descriptor_index {
|
||||
MS_OS_20_DESCRIPTOR_INDEX = 0x07,
|
||||
MS_OS_20_SET_ALT_ENUMERATION = 0x08,
|
||||
};
|
||||
|
||||
enum msosv2_descriptor_type {
|
||||
MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00,
|
||||
MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01,
|
||||
MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02,
|
||||
MS_OS_20_FEATURE_COMPATIBLE_ID = 0x03,
|
||||
MS_OS_20_FEATURE_REG_PROPERTY = 0x04,
|
||||
MS_OS_20_FEATURE_MIN_RESUME_TIME = 0x05,
|
||||
MS_OS_20_FEATURE_MODEL_ID = 0x06,
|
||||
MS_OS_20_FEATURE_CCGP_DEVICE = 0x07,
|
||||
MS_OS_20_FEATURE_VENDOR_REVISION = 0x08
|
||||
};
|
||||
|
||||
enum msosv2_property_data_type {
|
||||
MS_OS_20_PROPERTY_DATA_RESERVED = 0,
|
||||
MS_OS_20_PROPERTY_DATA_REG_SZ = 1,
|
||||
MS_OS_20_PROPERTY_DATA_REG_EXPAND_SZ = 2,
|
||||
MS_OS_20_PROPERTY_DATA_REG_BINARY = 3,
|
||||
MS_OS_20_PROPERTY_DATA_REG_DWORD_LITTLE_ENDIAN = 4,
|
||||
MS_OS_20_PROPERTY_DATA_REG_DWORD_BIG_ENDIAN = 5,
|
||||
MS_OS_20_PROPERTY_DATA_REG_LINK = 6,
|
||||
MS_OS_20_PROPERTY_DATA_REG_MULTI_SZ = 7
|
||||
};
|
||||
|
||||
/* Microsoft OS 2.0 descriptor set header */
|
||||
struct msosv2_descriptor_set_header {
|
||||
uint16_t wLength;
|
||||
uint16_t wDescriptorType;
|
||||
uint32_t dwWindowsVersion;
|
||||
uint16_t wTotalLength;
|
||||
} __packed;
|
||||
|
||||
/* Microsoft OS 2.0 configuration subset header
|
||||
* This header is for composite devices with multiple configurations.
|
||||
*/
|
||||
struct msosv2_configuration_subset_header {
|
||||
uint16_t wLength;
|
||||
uint16_t wDescriptorType;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t bReserved;
|
||||
uint16_t wTotalLength;
|
||||
} __packed;
|
||||
|
||||
/* Microsoft OS 2.0 function subset header
|
||||
* Note: This must be used if your device has multiple interfaces and cannot be used otherwise.
|
||||
*/
|
||||
struct msosv2_function_subset_header {
|
||||
uint16_t wLength;
|
||||
uint16_t wDescriptorType;
|
||||
uint8_t bFirstInterface;
|
||||
uint8_t bReserved;
|
||||
uint16_t wSubsetLength;
|
||||
} __packed;
|
||||
|
||||
/* Microsoft OS 2.0 compatible ID descriptor */
|
||||
struct msosv2_compatible_id {
|
||||
uint16_t wLength;
|
||||
uint16_t wDescriptorType;
|
||||
uint8_t CompatibleID[8];
|
||||
uint8_t SubCompatibleID[8];
|
||||
} __packed;
|
||||
|
||||
/* Microsoft OS 2.0 Registry property descriptor: DeviceInterfaceGUIDs */
|
||||
struct msosv2_guids_property {
|
||||
uint16_t wLength;
|
||||
uint16_t wDescriptorType;
|
||||
uint16_t wPropertyDataType;
|
||||
uint16_t wPropertyNameLength;
|
||||
uint8_t PropertyName[42];
|
||||
uint16_t wPropertyDataLength;
|
||||
uint8_t bPropertyData[80];
|
||||
} __packed;
|
||||
|
||||
/* DeviceInterfaceGUIDs */
|
||||
#define DEVICE_INTERFACE_GUIDS_PROPERTY_NAME \
|
||||
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, \
|
||||
'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, \
|
||||
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, \
|
||||
'D', 0x00, 's', 0x00, 0x00, 0x00
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_USB_MSOS_DESC_H */
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2019 Intel Corporation
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -20,33 +21,51 @@ LOG_MODULE_REGISTER(main);
|
|||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/usb/usb_device.h>
|
||||
#include <zephyr/usb/bos.h>
|
||||
#include <zephyr/usb/msos_desc.h>
|
||||
|
||||
#include "webusb.h"
|
||||
|
||||
/* Predefined response to control commands related to MS OS 2.0 descriptors */
|
||||
static const uint8_t msos2_descriptor[] = {
|
||||
/* MS OS 2.0 set header descriptor */
|
||||
0x0A, 0x00, /* Descriptor size (10 bytes) */
|
||||
0x00, 0x00, /* MS_OS_20_SET_HEADER_DESCRIPTOR */
|
||||
0x00, 0x00, 0x03, 0x06, /* Windows version (8.1) (0x06030000) */
|
||||
(0x0A + 0x14 + 0x08), 0x00, /* Length of the MS OS 2.0 descriptor set */
|
||||
/* random GUID {FA611CC3-7057-42EE-9D82-4919639562B3} */
|
||||
#define WEBUSB_DEVICE_INTERFACE_GUID \
|
||||
'{', 0x00, 'F', 0x00, 'A', 0x00, '6', 0x00, '1', 0x00, '1', 0x00, \
|
||||
'C', 0x00, 'C', 0x00, '3', 0x00, '-', 0x00, '7', 0x00, '0', 0x00, \
|
||||
'5', 0x00, '7', 0x00, '-', 0x00, '4', 0x00, '2', 0x00, 'E', 0x00, \
|
||||
'E', 0x00, '-', 0x00, '9', 0x00, 'D', 0x00, '8', 0x00, '2', 0x00, \
|
||||
'-', 0x00, '4', 0x00, '9', 0x00, '1', 0x00, '9', 0x00, '6', 0x00, \
|
||||
'3', 0x00, '9', 0x00, '5', 0x00, '6', 0x00, '2', 0x00, 'B', 0x00, \
|
||||
'3', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
/* MS OS 2.0 function subset ID descriptor
|
||||
* This means that the descriptors below will only apply to one
|
||||
* set of interfaces
|
||||
#define COMPATIBLE_ID_WINUSB \
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00
|
||||
|
||||
static struct msosv2_descriptor_t {
|
||||
struct msosv2_descriptor_set_header header;
|
||||
struct msosv2_compatible_id webusb_compatible_id;
|
||||
struct msosv2_guids_property webusb_guids_property;
|
||||
} __packed msosv2_descriptor = {
|
||||
/* Microsoft OS 2.0 descriptor set
|
||||
* This tells Windows what kind of device this is and to install the WinUSB driver.
|
||||
*/
|
||||
0x08, 0x00, /* Descriptor size (8 bytes) */
|
||||
0x02, 0x00, /* MS_OS_20_SUBSET_HEADER_FUNCTION */
|
||||
0x02, /* Index of first interface this subset applies to. */
|
||||
0x00, /* reserved */
|
||||
(0x08 + 0x14), 0x00, /* Length of the MS OS 2.0 descriptor subset */
|
||||
|
||||
/* MS OS 2.0 compatible ID descriptor */
|
||||
0x14, 0x00, /* Descriptor size */
|
||||
0x03, 0x00, /* MS_OS_20_FEATURE_COMPATIBLE_ID */
|
||||
/* 8-byte compatible ID string, then 8-byte sub-compatible ID string */
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.header = {
|
||||
.wLength = sizeof(struct msosv2_descriptor_set_header),
|
||||
.wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR,
|
||||
.dwWindowsVersion = 0x06030000,
|
||||
.wTotalLength = sizeof(struct msosv2_descriptor_t),
|
||||
},
|
||||
.webusb_compatible_id = {
|
||||
.wLength = sizeof(struct msosv2_compatible_id),
|
||||
.wDescriptorType = MS_OS_20_FEATURE_COMPATIBLE_ID,
|
||||
.CompatibleID = {COMPATIBLE_ID_WINUSB},
|
||||
},
|
||||
.webusb_guids_property = {
|
||||
.wLength = sizeof(struct msosv2_guids_property),
|
||||
.wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY,
|
||||
.wPropertyDataType = MS_OS_20_PROPERTY_DATA_REG_MULTI_SZ,
|
||||
.wPropertyNameLength = 42,
|
||||
.PropertyName = {DEVICE_INTERFACE_GUIDS_PROPERTY_NAME},
|
||||
.wPropertyDataLength = 80,
|
||||
.bPropertyData = {WEBUSB_DEVICE_INTERFACE_GUID},
|
||||
},
|
||||
};
|
||||
|
||||
USB_DEVICE_BOS_DESC_DEFINE_CAP struct usb_bos_webusb_desc {
|
||||
|
@ -113,7 +132,8 @@ USB_DEVICE_BOS_DESC_DEFINE_CAP struct usb_bos_msosv2_desc {
|
|||
/* Windows version (8.1) (0x06030000) */
|
||||
.dwWindowsVersion = sys_cpu_to_le32(0x06030000),
|
||||
.wMSOSDescriptorSetTotalLength =
|
||||
sys_cpu_to_le16(sizeof(msos2_descriptor)),
|
||||
sys_cpu_to_le16(sizeof(msosv2_descriptor)),
|
||||
/* Arbitrary code that is used as bRequest for vendor command */
|
||||
.bMS_VendorCode = 0x02,
|
||||
.bAltEnumCode = 0x00
|
||||
},
|
||||
|
@ -268,11 +288,11 @@ int vendor_handle_req(struct usb_setup_packet *pSetup,
|
|||
LOG_DBG("Get webusb_origin_url");
|
||||
|
||||
return 0;
|
||||
} else if (pSetup->bRequest == 0x02 && pSetup->wIndex == 0x07) {
|
||||
} else if (pSetup->bRequest == bos_cap_msosv2.cap.bMS_VendorCode &&
|
||||
pSetup->wIndex == MS_OS_20_DESCRIPTOR_INDEX) {
|
||||
/* Get MS OS 2.0 Descriptors request */
|
||||
/* 0x07 means "MS_OS_20_DESCRIPTOR_INDEX" */
|
||||
*data = (uint8_t *)(&msos2_descriptor);
|
||||
*len = sizeof(msos2_descriptor);
|
||||
*data = (uint8_t *)(&msosv2_descriptor);
|
||||
*len = sizeof(msosv2_descriptor);
|
||||
|
||||
LOG_DBG("Get MS OS Descriptors v2");
|
||||
|
||||
|
|
Loading…
Reference in a new issue