From af3c301ea5152ea4926e005159f4daa894b5df53 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2019 00:34:25 +0700 Subject: [PATCH] added BOS MS OS 2.0 descriptor to webusb example, it work with windows --- examples/device/webusb_serial/src/main.c | 15 +++ .../webusb_serial/src/usb_descriptors.c | 108 ++++++++++++------ .../webusb_serial/src/usb_descriptors.h | 3 + src/common/tusb_types.h | 14 +++ src/device/usbd.h | 25 +++- 5 files changed, 124 insertions(+), 41 deletions(-) diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 4990fe24..d81cf058 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -153,6 +153,19 @@ bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const // Get landing page url return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength); + case VENDOR_REQUEST_MICROSOFT: + if ( request->wIndex == 7 ) + { + // Get Microsoft OS 2.0 compatible descriptor + uint16_t total_len; + memcpy(&total_len, desc_ms_os_20+8, 2); + + return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len); + }else + { + return false; + } + case 0x22: // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to // connect and disconnect. @@ -175,6 +188,8 @@ bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const // stall unknown request return false; } + + return true; } // Invoked when DATA Stage of VENDOR's request is complete diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index 1ae8a61f..a61c62c9 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -70,38 +70,6 @@ uint8_t const * tud_descriptor_device_cb(void) return (uint8_t const *) &desc_device; } -//--------------------------------------------------------------------+ -// BOS Descriptor -//--------------------------------------------------------------------+ - -/* Microsoft OS 2.0 registry property descriptor -Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx -device should create DeviceInterfaceGUIDs. It can be done by driver and -in case of real PnP solution device should expose MS "Microsoft OS 2.0 -registry property descriptor". Such descriptor can insert any record -into Windows registry per device/configuration/interface. In our case it -will insert "DeviceInterfaceGUIDs" multistring property. - -GUID is freshly generated and should be OK to use. -*/ - -#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN) - -// BOS Descriptor is required for webUSB -uint8_t const desc_bos[] = -{ - // total length, number of device caps - TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), - - // Vendor Code, iLandingPage - TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1) -}; - -uint8_t const * tud_descriptor_bos_cb(void) -{ - return desc_bos; -} - //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ @@ -146,6 +114,77 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) return desc_configuration; } +//--------------------------------------------------------------------+ +// BOS Descriptor +//--------------------------------------------------------------------+ + +/* Microsoft OS 2.0 registry property descriptor +Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx +device should create DeviceInterfaceGUIDs. It can be done by driver and +in case of real PnP solution device should expose MS "Microsoft OS 2.0 +registry property descriptor". Such descriptor can insert any record +into Windows registry per device/configuration/interface. In our case it +will insert "DeviceInterfaceGUIDs" multistring property. + +GUID is freshly generated and should be OK to use. + +https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ +(Section Microsoft OS compatibility descriptors) +*/ + +#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) + +#define MS_OS_20_DESC_LEN 0xB2 + +// BOS Descriptor is required for webUSB +uint8_t const desc_bos[] = +{ + // total length, number of device caps + TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2), + + // Vendor Code, iLandingPage + TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1), + + // Microsoft OS 2.0 descriptor + TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT) +}; + +uint8_t const * tud_descriptor_bos_cb(void) +{ + return desc_bos; +} + + +uint8_t const desc_ms_os_20[] = +{ + // Set header: length, type, windows version, total length + U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), + + // Configuration subset header: length, type, configuration index, reserved, configuration total length + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A), + + // Function Subset header: length, type, first interface, reserved, subset length + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_VENDOR, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08), + + // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID + U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible + + // MS OS 2.0 Registry property descriptor: length, type + U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), + U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 + '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, + U16_TO_U8S_LE(0x0050), // wPropertyDataLength + //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”. + '{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00, + '0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, + '8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00, + '8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); + //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ @@ -196,8 +235,3 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) return _desc_str; } - -//--------------------------------------------------------------------+ -// WebUSB URL Descriptor -//--------------------------------------------------------------------+ - diff --git a/examples/device/webusb_serial/src/usb_descriptors.h b/examples/device/webusb_serial/src/usb_descriptors.h index d05843c3..19f1ff3f 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.h +++ b/examples/device/webusb_serial/src/usb_descriptors.h @@ -28,6 +28,9 @@ enum { VENDOR_REQUEST_WEBUSB = 1, + VENDOR_REQUEST_MICROSOFT = 2 }; +extern uint8_t const desc_ms_os_20[]; + #endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 2776eaa8..8358d7e6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -227,6 +227,20 @@ enum INTERFACE_INVALID_NUMBER = 0xff }; + +enum +{ + 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_COMPATBLE_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 +}microsoft_os_20_type_t; + //--------------------------------------------------------------------+ // USB Descriptors //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index 525fced8..6e781f18 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -104,11 +104,11 @@ TU_ATTR_WEAK void tud_resume_cb(void); TU_ATTR_WEAK bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request); TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request); + //--------------------------------------------------------------------+ -// Descriptor Templates +// Binary Device Object Store (BOS) Descriptor Templates //--------------------------------------------------------------------+ -//------------- Binary Device Object Store (BOS) -------------// #define TUD_BOS_DESC_LEN 5 // total length, number of device caps @@ -119,10 +119,10 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re #define TUD_BOS_PLATFORM_DESCRIPTOR(...) \ 4+TU_ARGS_NUM(__VA_ARGS__), TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_PLATFORM, 0x00, __VA_ARGS__ -//------------- WebUSB BOS -------------// +//------------- WebUSB BOS Platform -------------// // Descriptor Length -#define TUD_BOS_WEBUSB_DESC_LEN 24 +#define TUD_BOS_WEBUSB_DESC_LEN 24 // Vendor Code, iLandingPage #define TUD_BOS_WEBUSB_DESCRIPTOR(_vendor_code, _ipage) \ @@ -132,6 +132,23 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re 0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, \ 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65 +//------------- Microsoft OS 2.0 Platform -------------// + +#define TUD_BOS_MICROSOFT_OS_DESC_LEN 28 + +// Total Length of descriptor set, vendor code +#define TUD_BOS_MS_OS_20_DESCRIPTOR(_desc_set_len, _vendor_code) \ + TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_MS_OS_20_UUID, U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(_desc_set_len), _vendor_code, 0) + +#define TUD_BOS_MS_OS_20_UUID \ + 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, \ + 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F + + +//--------------------------------------------------------------------+ +// Configuration & Interface Descriptor Templates +//--------------------------------------------------------------------+ + //------------- Configuration -------------// #define TUD_CONFIG_DESC_LEN (9)