Skip to content

Commit 51d0831

Browse files
nkarstensdlech
authored andcommitted
pbdrv/usb: Add additional info to BOS descriptor.
Add additional information 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: * Device Name * Firmware version * Software (protocol) version * Hub capabilities Signed-off-by: Nate Karstens <[email protected]>
1 parent 28d1cb4 commit 51d0831

File tree

3 files changed

+130
-2
lines changed

3 files changed

+130
-2
lines changed

lib/pbio/drv/usb/stm32_usbd/usbd_desc.c

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,15 @@
4343
******************************************************************************
4444
*/
4545
/* Includes ------------------------------------------------------------------*/
46+
#include <string.h>
4647

4748
#include <lego_usb.h>
4849

50+
#include <pbdrv/bluetooth.h>
4951
#include <pbdrv/config.h>
5052
#include <pbio/protocol.h>
53+
#include <pbio/version.h>
54+
#include <pbsys/storage.h>
5155

5256
#include "usbd_core.h"
5357
#include "usbd_conf.h"
@@ -59,14 +63,25 @@
5963
#define USBD_CONFIGURATION_FS_STRING "Pybricks Config"
6064
#define USBD_INTERFACE_FS_STRING "Pybricks Interface"
6165

66+
static const char firmware_version[] = PBIO_VERSION_STR;
67+
static const char software_version[] = PBIO_PROTOCOL_VERSION_STR;
68+
6269
#define DEVICE_ID1 (0x1FFF7A10)
6370
#define DEVICE_ID2 (0x1FFF7A14)
6471
#define DEVICE_ID3 (0x1FFF7A18)
6572

6673
#define USB_DEV_CAP_TYPE_PLATFORM (5)
6774

6875
#define USB_SIZ_STRING_SERIAL 0x1A
69-
#define USB_SIZ_BOS_DESC 33
76+
#define USB_SIZ_BOS_DESC_CONST (5 + 28)
77+
#define USB_SIZ_UUID (128 / 8)
78+
#define USB_SIZ_PLATFORM_HDR (4 + USB_SIZ_UUID)
79+
#define USB_SIZ_HUB_NAME_MAX (16)
80+
#define USB_SIZ_BOS_DESC (USB_SIZ_BOS_DESC_CONST + \
81+
USB_SIZ_PLATFORM_HDR + USB_SIZ_HUB_NAME_MAX + \
82+
USB_SIZ_PLATFORM_HDR + sizeof(firmware_version) - 1 + \
83+
USB_SIZ_PLATFORM_HDR + sizeof(software_version) - 1 + \
84+
USB_SIZ_PLATFORM_HDR + PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE)
7085

7186
/* USB Standard Device Descriptor */
7287
__ALIGN_BEGIN static
@@ -128,6 +143,8 @@ __ALIGN_BEGIN static uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
128143
0x00 /* bAltEnumCode = Does not support alternate enumeration */
129144
};
130145

146+
static uint16_t USBD_BOSDesc_Len;
147+
131148
__ALIGN_BEGIN const uint8_t USBD_OSDescSet[USBD_SIZ_MS_OS_DSCRPTR_SET] __ALIGN_END =
132149
{
133150
0x0A, 0x00, /* wLength = 10 */
@@ -275,6 +292,38 @@ static void Get_SerialNum(void) {
275292
}
276293
}
277294

295+
/**
296+
* @brief Add the short BLE UUID to the buffer in little-endian format.
297+
* @param dst The destination buffer
298+
* @param dst The short BLE UUID to add
299+
* @retval None
300+
*/
301+
static void add_ble_short_uuid_le(uint8_t *dst, uint16_t short_uuid) {
302+
/* 32-bit */
303+
dst[0] = LOBYTE(short_uuid);
304+
dst[1] = HIBYTE(short_uuid);
305+
dst[2] = 0x00;
306+
dst[3] = 0x00;
307+
308+
/* 16-bit */
309+
dst[4] = 0x00;
310+
dst[5] = 0x00;
311+
312+
/* 16-bit */
313+
dst[6] = 0x00;
314+
dst[7] = 0x10;
315+
316+
/* 8-byte buffer */
317+
dst[8] = 0x80;
318+
dst[9] = 0x00;
319+
dst[10] = 0x00;
320+
dst[11] = 0x80;
321+
dst[12] = 0x5F;
322+
dst[13] = 0x9B;
323+
dst[14] = 0x34;
324+
dst[15] = 0xFB;
325+
}
326+
278327
/**
279328
* @brief Returns the device descriptor.
280329
* @param speed: Current device speed
@@ -372,7 +421,7 @@ static uint8_t *USBD_Pybricks_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *l
372421
/* Prevent unused argument(s) compilation warning */
373422
UNUSED(speed);
374423

375-
*length = sizeof(USBD_BOSDesc);
424+
*length = USBD_BOSDesc_Len;
376425
return (uint8_t *)USBD_BOSDesc;
377426
}
378427

@@ -400,4 +449,79 @@ void USBD_Pybricks_Desc_Init(void) {
400449
USBD_DeviceDesc[11] = HIBYTE(PBDRV_CONFIG_USB_PID_1);
401450
}
402451
#endif
452+
453+
const char *str;
454+
size_t len;
455+
456+
uint8_t *ptr = &USBD_BOSDesc[USB_SIZ_BOS_DESC_CONST];
457+
458+
/* Add device name */
459+
str = pbdrv_bluetooth_get_hub_name();
460+
len = MIN(strlen(str), USB_SIZ_HUB_NAME_MAX);
461+
462+
*ptr++ = USB_SIZ_PLATFORM_HDR + len; // bLength
463+
*ptr++ = USB_DEVICE_CAPABITY_TYPE; // bDescriptorType
464+
*ptr++ = USB_DEV_CAP_TYPE_PLATFORM; // bDevCapabilityType
465+
*ptr++ = 0x00; // bReserved
466+
467+
// PlatformCapabilityUUID
468+
add_ble_short_uuid_le(ptr, pbio_gatt_device_name_char_uuid);
469+
ptr += USB_SIZ_UUID;
470+
471+
// CapabilityData: Device Name
472+
memcpy(ptr, str, len);
473+
ptr += len;
474+
475+
/* Add firmware version */
476+
*ptr++ = USB_SIZ_PLATFORM_HDR + sizeof(firmware_version) - 1; // bLength
477+
*ptr++ = USB_DEVICE_CAPABITY_TYPE; // bDescriptorType
478+
*ptr++ = USB_DEV_CAP_TYPE_PLATFORM; // bDevCapabilityType
479+
*ptr++ = 0x00; // bReserved
480+
481+
// PlatformCapabilityUUID
482+
add_ble_short_uuid_le(ptr, pbio_gatt_firmware_version_char_uuid);
483+
ptr += USB_SIZ_UUID;
484+
485+
// CapabilityData: Firmware Version
486+
memcpy(ptr, firmware_version, sizeof(firmware_version) - 1);
487+
ptr += sizeof(firmware_version) - 1;
488+
489+
/* Add software (protocol) version */
490+
*ptr++ = USB_SIZ_PLATFORM_HDR + sizeof(software_version) - 1; // bLength
491+
*ptr++ = USB_DEVICE_CAPABITY_TYPE; // bDescriptorType
492+
*ptr++ = USB_DEV_CAP_TYPE_PLATFORM; // bDevCapabilityType
493+
*ptr++ = 0x00; // bReserved
494+
495+
// PlatformCapabilityUUID
496+
add_ble_short_uuid_le(ptr, pbio_gatt_software_version_char_uuid);
497+
ptr += USB_SIZ_UUID;
498+
499+
// CapabilityData: Software Version
500+
memcpy(ptr, software_version, sizeof(software_version) - 1);
501+
ptr += sizeof(software_version) - 1;
502+
503+
/* Add hub capabilities */
504+
*ptr++ = USB_SIZ_PLATFORM_HDR + PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE; // bLength
505+
*ptr++ = USB_DEVICE_CAPABITY_TYPE; // bDescriptorType
506+
*ptr++ = USB_DEV_CAP_TYPE_PLATFORM; // bDevCapabilityType
507+
*ptr++ = 0x00; // bReserved
508+
509+
// PlatformCapabilityUUID
510+
pbio_uuid128_le_copy(ptr, pbio_pybricks_hub_capabilities_char_uuid);
511+
ptr += USB_SIZ_UUID;
512+
513+
// CapabilityData: Hub Capabilities
514+
pbio_pybricks_hub_capabilities(ptr,
515+
USBD_PYBRICKS_MAX_PACKET_SIZE - 1,
516+
PBSYS_CONFIG_APP_FEATURE_FLAGS,
517+
pbsys_storage_get_maximum_program_size());
518+
ptr += PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE;
519+
520+
/* Update wTotalLength field in BOS Descriptor */
521+
USBD_BOSDesc_Len = ptr - USBD_BOSDesc;
522+
USBD_BOSDesc[2] = LOBYTE(USBD_BOSDesc_Len);
523+
USBD_BOSDesc[3] = HIBYTE(USBD_BOSDesc_Len);
524+
525+
/* Update bNumDeviceCaps field in BOS Descriptor */
526+
USBD_BOSDesc[4] += 4;
403527
}

lib/pbio/include/pbio/protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ extern const uint8_t pbio_pybricks_command_event_char_uuid[];
403403
extern const uint8_t pbio_pybricks_hub_capabilities_char_uuid[];
404404

405405
extern const uint16_t pbio_gatt_device_info_service_uuid;
406+
extern const uint16_t pbio_gatt_device_name_char_uuid;
406407
extern const uint16_t pbio_gatt_firmware_version_char_uuid;
407408
extern const uint16_t pbio_gatt_software_version_char_uuid;
408409
extern const uint16_t pbio_gatt_pnp_id_char_uuid;

lib/pbio/src/protocol/pybricks.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ const uint8_t pbio_pybricks_hub_capabilities_char_uuid[] = {
8989
/** Bluetooth Device Information Service UUID. */
9090
const uint16_t pbio_gatt_device_info_service_uuid = 0x180A;
9191

92+
/** Bluetooth Device Name Characteristic UUID. */
93+
const uint16_t pbio_gatt_device_name_char_uuid = 0x2A00;
94+
9295
/** Bluetooth Firmware Version Characteristic UUID. */
9396
const uint16_t pbio_gatt_firmware_version_char_uuid = 0x2A26;
9497

0 commit comments

Comments
 (0)