From 8fa6c6a564d7287229742321c4c2deeb140c5b4f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 5 Oct 2023 16:58:39 +0800 Subject: [PATCH] Add Microsoft OS 2.0 capability descrciptor Doesn't work yet, on Windows, because Windows will make a special control request if it sees this. On Linux lsusb shows it like this: ``` Binary Object Store Descriptor: bLength 5 bDescriptorType 15 wTotalLength 0x0048 bNumDeviceCaps 2 USB 2.0 Extension Device Capability: bLength 7 bDescriptorType 16 bDevCapabilityType 2 bmAttributes 0x00000000 (Missing must-be-set LPM bit!) Platform Device Capability: bLength 28 bDescriptorType 16 bDevCapabilityType 5 bReserved 0 PlatformCapabilityUUID {d8dd60df-4589-4cc7-9cd2-659d9e648a9f} CapabilityData[0] 0x00 CapabilityData[1] 0x00 CapabilityData[2] 0x03 CapabilityData[3] 0x06 CapabilityData[4] 0x48 CapabilityData[5] 0x00 CapabilityData[6] 0x01 CapabilityData[7] 0x00 ``` Signed-off-by: Daniel Schaefer --- tmk_core/protocol/usb_descriptor.c | 29 +++++++++++++++++++++-- tmk_core/protocol/usb_descriptor.h | 37 +++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 668ff8601c..50136d1cdc 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -492,8 +492,9 @@ const USB_Descriptor_Bos_t PROGMEM BosDescriptor = { .Type = DTYPE_Bos }, // 3 Bytes (=> 5 Bytes) - .TotalLength = 0x000C, - .NumDeviceCaps = 0x01, + // Value must be header + each cap + .TotalLength = 0x0048, + .NumDeviceCaps = 0x02, .Usb20ExtensionDevCap = { // 2 Bytes (=> 7 Bytes) @@ -505,6 +506,30 @@ const USB_Descriptor_Bos_t PROGMEM BosDescriptor = { .DevCapabilityType = 2, .Bytes = {0x00, 0x00, 0x00, 0x00}, }, + + .MsosCap = { + // 2 Bytes (=> 7 Bytes) + .Header = { + .Size = sizeof(USB_Descriptor_Capability_Msos_t), + .Type = 16, + }, + // 5 Bytes (=> 12 Bytes / 0x0C Bytes) + .DevCapabilityType = 5, + .Reserved = 0, + // Microsoft OS 2.0 {D8DD60DF-4589-4CC7-9CD2-659D9E648A9F} + .PlatformCapabilityId = { + 0xDF, 0x60, 0xDD, 0xD8, + 0x89, 0x45, 0xC7, 0x4C, + 0x9C, 0xD2, 0x65, 0x9D, + 0x9E, 0x64, 0x8A, 0x9F + }, + .Set = {{ + .WindowsVersion = {0x00, 0x00, 0x03, 0x06}, // Windows Blue + .TotalLength = 0x0048, + .VendorCode = 0x01, // Microsoft + .AltEnumCode = 0, + }}, + }, }; #ifndef USB_MAX_POWER_CONSUMPTION diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h index 68862f5fd7..ddc2774e2d 100644 --- a/tmk_core/protocol/usb_descriptor.h +++ b/tmk_core/protocol/usb_descriptor.h @@ -319,6 +319,9 @@ enum USB_DescriptorTypes_tmk_t DTYPE_Bos = 0x0F, /**< Indicates that the descriptor is a binary object store descriptor. */ DTYPE_DeviceCapability = 0x10, /**< Indicates that the descriptor is a device capability descriptor. */ }; + + +// Generic device capability descriptor typedef struct { USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ @@ -328,16 +331,47 @@ typedef struct uint8_t Bytes[]; /**< Capability-specific format */ } ATTR_PACKED USB_Descriptor_Capability_t; + +// USB 2.0 Extended device capability descriptor typedef struct { USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ uint8_t DevCapabilityType; /**< TODO */ - uint8_t Bytes[4]; /**< Capability-specific format + uint8_t Bytes[4]; /**< Capability-specific format */ } ATTR_PACKED USB_Descriptor_Capability_Usb20Ext_t; + +// Microsoft OS 2.0 Platform Capability Descriptor Set +typedef struct +{ + uint8_t WindowsVersion[4]; /**< TODO + */ + uint16_t TotalLength; /**< Total Length of the descriptor set + */ + uint8_t VendorCode; /**< 0x01 for Microsoft + */ + uint8_t AltEnumCode; /**< 0 by default. non-zero if device supports non-default USB descriptors + */ +} ATTR_PACKED USB_Descriptor_Capability_Msos_Set_t; + +// Microsoft OS 2.0 Platform Capability Descriptor Header +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint8_t DevCapabilityType; /**< 0x05 + */ + uint8_t Reserved; /**< Reserved, set as 0 + */ + uint8_t PlatformCapabilityId[16]; /**< GUID: D8DD60DF-4589-4CC7-9CD2-659D9E648A9F + */ + USB_Descriptor_Capability_Msos_Set_t Set[1]; /**< Descriptor Set. Can have multiple in theory. + */ +} ATTR_PACKED USB_Descriptor_Capability_Msos_t; + /** \brief Standard USB BOS Descriptor (LUFA naming conventions). * * Type define for a standard BOS Descriptor. This structure uses LUFA-specific element names @@ -354,6 +388,7 @@ typedef struct uint8_t NumDeviceCaps; /**< The number of separate device capability descriptors in the BOS. */ USB_Descriptor_Capability_Usb20Ext_t Usb20ExtensionDevCap; + USB_Descriptor_Capability_Msos_t MsosCap; } ATTR_PACKED USB_Descriptor_Bos_t; /** \brief Standard USB BOS Descriptor (USB-IF naming conventions).