From 994c3ddd2b0392fb0f25aa449f3be6930aeb2a3e Mon Sep 17 00:00:00 2001 From: Nate Karstens Date: Wed, 22 Nov 2023 23:00:00 -0600 Subject: [PATCH] Add versions and capabilities to BOS descriptor Adds versions and capabilities to the BOS Descriptor by appending dynamically-generated platform descriptors that use the same UUIDs that are used with BLE and contain the following values: * Firmware version * Software (protocol) version * Hub capabilities --- lib/pbio/drv/usb/stm32_usbd/usbd_desc.c | 71 ++++++++++++++++++++++++- lib/pbio/include/pbio/protocol.h | 2 + lib/pbio/src/protocol/pybricks.c | 8 +++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c b/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c index 6323e381d..8c79159ba 100644 --- a/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c +++ b/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c @@ -43,10 +43,19 @@ ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ +#include + #include "usbd_core.h" #include "usbd_conf.h" #include "usbd_pybricks.h" +#include "pbio/protocol.h" +#include "pbio/version.h" +#include "pbsys/app.h" +#include "pbsys/program_load.h" +#include "pbdrvconfig.h" +#include "sys/config.h" + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define USBD_VID 0x0483 @@ -57,12 +66,21 @@ #define USBD_CONFIGURATION_FS_STRING "Pybricks Config" #define USBD_INTERFACE_FS_STRING "Pybricks Interface" +static const char firmware_version[] = PBIO_VERSION_STR; +static const char software_version[] = PBIO_PROTOCOL_VERSION_STR; + #define DEVICE_ID1 (0x1FFF7A10) #define DEVICE_ID2 (0x1FFF7A14) #define DEVICE_ID3 (0x1FFF7A18) #define USB_SIZ_STRING_SERIAL 0x1A -#define USB_SIZ_BOS_DESC 33 +#define USB_SIZ_BOS_DESC_CONST (5 + 28) +#define USB_SIZ_UUID (128 / 8) +#define USB_SIZ_PLATFORM_HDR (4 + USB_SIZ_UUID) +#define USB_SIZ_BOS_DESC (USB_SIZ_BOS_DESC_CONST + \ + USB_SIZ_PLATFORM_HDR + sizeof(firmware_version) + \ + USB_SIZ_PLATFORM_HDR + sizeof(software_version) + \ + USB_SIZ_PLATFORM_HDR + PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE) /* USB Standard Device Descriptor */ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { @@ -378,6 +396,57 @@ static uint8_t *USBD_Pybricks_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *l /* Prevent unused argument(s) compilation warning */ UNUSED(speed); + static uint8_t created = 0; + uint8_t *ptr; + + /* Generate BOS Descriptor on first attempt */ + if (!created) { + created = 1; + ptr = &USBD_BOSDesc[USB_SIZ_BOS_DESC_CONST]; + + /* Add firmware version */ + *ptr++ = USB_SIZ_PLATFORM_HDR + sizeof(firmware_version); + *ptr++ = USB_DEVICE_CAPABITY_TYPE; + *ptr++ = 0x05; + *ptr++ = 0x00; + + pbio_uuid128_le_copy(ptr, pbio_gatt_firmware_version_char_uuid_128); + ptr += USB_SIZ_UUID; + + memcpy(ptr, firmware_version, sizeof(firmware_version)); + ptr += sizeof(firmware_version); + + /* Add software (protocol) version */ + *ptr++ = USB_SIZ_PLATFORM_HDR + sizeof(software_version); + *ptr++ = USB_DEVICE_CAPABITY_TYPE; + *ptr++ = 0x05; + *ptr++ = 0x00; + + pbio_uuid128_le_copy(ptr, pbio_gatt_software_version_char_uuid_128); + ptr += USB_SIZ_UUID; + + memcpy(ptr, software_version, sizeof(software_version)); + ptr += sizeof(software_version); + + /* Add hub capabilities */ + *ptr++ = USB_SIZ_PLATFORM_HDR + PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE; + *ptr++ = USB_DEVICE_CAPABITY_TYPE; + *ptr++ = 0x05; + *ptr++ = 0x00; + + pbio_uuid128_le_copy(ptr, pbio_pybricks_hub_capabilities_char_uuid); + ptr += USB_SIZ_UUID; + + pbio_pybricks_hub_capabilities(ptr, + USBD_PYBRICKS_MAX_PACKET_SIZE - USB_SIZ_UUID, + PBSYS_APP_HUB_FEATURE_FLAGS, + PBSYS_PROGRAM_LOAD_MAX_PROGRAM_SIZE); + ptr += PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE; + + /* Update bNumDeviceCaps field in BOS Descriptor */ + USBD_BOSDesc[4] += 3; + } + *length = sizeof(USBD_BOSDesc); return (uint8_t *)USBD_BOSDesc; } diff --git a/lib/pbio/include/pbio/protocol.h b/lib/pbio/include/pbio/protocol.h index 48e65685f..801bf14b9 100644 --- a/lib/pbio/include/pbio/protocol.h +++ b/lib/pbio/include/pbio/protocol.h @@ -301,7 +301,9 @@ extern const uint8_t pbio_pybricks_hub_capabilities_char_uuid[]; extern const uint16_t pbio_gatt_device_info_service_uuid; extern const uint16_t pbio_gatt_firmware_version_char_uuid; +extern const uint8_t pbio_gatt_firmware_version_char_uuid_128[]; extern const uint16_t pbio_gatt_software_version_char_uuid; +extern const uint8_t pbio_gatt_software_version_char_uuid_128[]; extern const uint16_t pbio_gatt_pnp_id_char_uuid; extern const uint8_t pbio_lwp3_hub_service_uuid[]; diff --git a/lib/pbio/src/protocol/pybricks.c b/lib/pbio/src/protocol/pybricks.c index 6bf2ec9e4..e23055281 100644 --- a/lib/pbio/src/protocol/pybricks.c +++ b/lib/pbio/src/protocol/pybricks.c @@ -87,9 +87,17 @@ const uint16_t pbio_gatt_device_info_service_uuid = 0x180A; /** Bluetooth Firmware Version Characteristic UUID. */ const uint16_t pbio_gatt_firmware_version_char_uuid = 0x2A26; +const uint8_t pbio_gatt_firmware_version_char_uuid_128[] = { + 0x00, 0x00, 0x2A, 0x26, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, +}; /** Bluetooth Software Version Characteristic UUID (Pybricks protocol version). */ const uint16_t pbio_gatt_software_version_char_uuid = 0x2A28; +const uint8_t pbio_gatt_software_version_char_uuid_128[] = { + 0x00, 0x00, 0x2A, 0x28, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, +}; /** Bluetooth PnP ID Characteristic UUID. */ const uint16_t pbio_gatt_pnp_id_char_uuid = 0x2A50;