From e14f2a6a7f51e2ad8c554e24ceb7926d41ab80f1 Mon Sep 17 00:00:00 2001 From: Nate Karstens Date: Wed, 3 Jan 2024 01:00:12 -0600 Subject: [PATCH] Add WebUSB platform descriptor Adds a WebUSB platform descriptor to the BOS descriptor and a landing page pointing to https://code.pybricks.com. Signed-off-by: Nate Karstens --- lib/pbio/drv/usb/stm32_usbd/usbd_desc.c | 28 ++++++++++++++++++--- lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.c | 20 +++++++++++++++ lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.h | 4 +++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c b/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c index 58aa51e37..4d5c162b5 100644 --- a/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c +++ b/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c @@ -74,7 +74,7 @@ static const char software_version[] = PBIO_PROTOCOL_VERSION_STR; #define USB_DEV_CAP_TYPE_PLATFORM (5) #define USB_SIZ_STRING_SERIAL 0x1A -#define USB_SIZ_BOS_DESC_CONST (5 + 28) +#define USB_SIZ_BOS_DESC_CONST (5 + 28 + 24) #define USB_SIZ_UUID (128 / 8) #define USB_SIZ_PLATFORM_HDR (4 + USB_SIZ_UUID) #define USB_SIZ_HUB_NAME_MAX (16) @@ -118,7 +118,7 @@ __ALIGN_BEGIN static uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = USB_DESC_TYPE_BOS, /* bDescriptorType = BOS */ LOBYTE(USB_SIZ_BOS_DESC), /* wTotalLength */ HIBYTE(USB_SIZ_BOS_DESC), /* wTotalLength */ - 1, /* bNumDeviceCaps */ + 2, /* bNumDeviceCaps */ 28, /* bLength */ USB_DEVICE_CAPABITY_TYPE, /* bDescriptorType = Device Capability */ @@ -141,7 +141,29 @@ __ALIGN_BEGIN static uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = LOBYTE(USBD_SIZ_MS_OS_DSCRPTR_SET), /* wMSOSDescriptorSetTotalLength */ HIBYTE(USBD_SIZ_MS_OS_DSCRPTR_SET), /* wMSOSDescriptorSetTotalLength */ USBD_MS_VENDOR_CODE, /* bMS_VendorCode */ - 0x00 /* bAltEnumCode = Does not support alternate enumeration */ + 0x00, /* bAltEnumCode = Does not support alternate enumeration */ + + 24, /* bLength */ + USB_DEVICE_CAPABITY_TYPE, /* bDescriptorType = Device Capability */ + USB_DEV_CAP_TYPE_PLATFORM, /* bDevCapabilityType */ + 0x00, /* bReserved */ + + /* + * PlatformCapabilityUUID + * WebUSB Platform Capability descriptor + * 3408B638-09A9-47A0-8BFD-A0768815B665 + * RFC 4122 explains the correct byte ordering + */ + 0x38, 0xB6, 0x08, 0x34, /* 32-bit value */ + 0xA9, 0x09, /* 16-bit value */ + 0xA0, 0x47, /* 16-bit value */ + 0x8B, 0xFD, + 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65, + + LOBYTE(0x0100), /* bcdVersion */ + HIBYTE(0x0100), /* bcdVersion */ + USBD_WEBUSB_VENDOR_CODE, /* bVendorCode */ + USBD_WEBUSB_LANDING_PAGE_IDX /* iLandingPage */ }; static uint16_t USBD_BOSDesc_Len; diff --git a/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.c b/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.c index e7c896bad..fdbc4a32c 100644 --- a/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.c +++ b/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.c @@ -155,6 +155,18 @@ __ALIGN_BEGIN static uint8_t USBD_Pybricks_CfgDesc[USBD_PYBRICKS_CONFIG_DESC_SIZ 0x00 /* bInterval */ }; +__ALIGN_BEGIN static const uint8_t WebUSB_DescSet[20] __ALIGN_END = +{ + 20, /* bLength */ + 0x03, /* bDescriptorType = URL */ + 0x01, /* bScheme = https:// */ + + /* URL */ + 'c', 'o', 'd', 'e', '.', + 'p', 'y', 'b', 'r', 'i', 'c', 'k', 's', '.', + 'c', 'o', 'm' +}; + /** * @} */ @@ -248,6 +260,14 @@ static USBD_StatusTypeDef USBD_Pybricks_Setup(USBD_HandleTypeDef *pdev, MIN(sizeof(USBD_OSDescSet), req->wLength)); break; + case USBD_WEBUSB_VENDOR_CODE: + if ((req->wValue == USBD_WEBUSB_LANDING_PAGE_IDX) && (req->wIndex == 0x02)) { + (void)USBD_CtlSendData(pdev, + (uint8_t *)WebUSB_DescSet, + MIN(sizeof(WebUSB_DescSet), req->wLength)); + } + break; + default: USBD_CtlError(pdev, req); ret = USBD_FAIL; diff --git a/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.h b/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.h index 226f2b9b2..43af3b167 100644 --- a/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.h +++ b/lib/pbio/drv/usb/stm32_usbd/usbd_pybricks.h @@ -41,8 +41,12 @@ extern "C" { * @{ */ #define USBD_MS_VENDOR_CODE 0x01 +#define USBD_WEBUSB_VENDOR_CODE 0x02 + #define USBD_SIZ_MS_OS_DSCRPTR_SET (10 + 20 + 132) +#define USBD_WEBUSB_LANDING_PAGE_IDX 1 + #define USBD_PYBRICKS_CONFIG_DESC_SIZ (9 + 9 + 7 + 7) #define USBD_PYBRICKS_IN_EP 0x81U /* EP1 for data IN */