Skip to content

Commit 72d3412

Browse files
committed
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
1 parent e7883fe commit 72d3412

File tree

5 files changed

+106
-1
lines changed

5 files changed

+106
-1
lines changed

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

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,19 @@
4343
******************************************************************************
4444
*/
4545
/* Includes ------------------------------------------------------------------*/
46+
#include <string.h>
47+
4648
#include "usbd_core.h"
4749
#include "usbd_conf.h"
4850
#include "usbd_pybricks.h"
4951

52+
#include "pbio/protocol.h"
53+
#include "pbio/version.h"
54+
#include "pbsys/app.h"
55+
#include "pbsys/program_load.h"
56+
#include "pbdrvconfig.h"
57+
#include "sys/config.h"
58+
5059
/* Private typedef -----------------------------------------------------------*/
5160
/* Private define ------------------------------------------------------------*/
5261
#define USBD_VID 0x0483
@@ -57,12 +66,21 @@
5766
#define USBD_CONFIGURATION_FS_STRING "Pybricks Config"
5867
#define USBD_INTERFACE_FS_STRING "Pybricks Interface"
5968

69+
static const char firmware_version[] = PBIO_VERSION_STR;
70+
static const char software_version[] = PBIO_PROTOCOL_VERSION_STR;
71+
6072
#define DEVICE_ID1 (0x1FFF7A10)
6173
#define DEVICE_ID2 (0x1FFF7A14)
6274
#define DEVICE_ID3 (0x1FFF7A18)
6375

6476
#define USB_SIZ_STRING_SERIAL 0x1A
65-
#define USB_SIZ_BOS_DESC 33
77+
#define USB_SIZ_BOS_DESC_CONST (5 + 28)
78+
#define USB_SIZ_UUID (128 / 8)
79+
#define USB_SIZ_PLATFORM_HDR (4 + USB_SIZ_UUID)
80+
#define USB_SIZ_BOS_DESC (USB_SIZ_BOS_DESC_CONST + \
81+
USB_SIZ_PLATFORM_HDR + sizeof(firmware_version) + \
82+
USB_SIZ_PLATFORM_HDR + sizeof(software_version) + \
83+
USB_SIZ_PLATFORM_HDR + PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE)
6684

6785
/* USB Standard Device Descriptor */
6886
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
@@ -378,6 +396,54 @@ static uint8_t *USBD_Pybricks_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *l
378396
/* Prevent unused argument(s) compilation warning */
379397
UNUSED(speed);
380398

399+
static uint8_t created = 0;
400+
uint8_t *ptr;
401+
402+
/* Generate BOS Descriptor on first attempt */
403+
if (!created) {
404+
created = 1;
405+
ptr = &USBD_BOSDesc[USB_SIZ_BOS_DESC_CONST];
406+
407+
/* Add firmware version */
408+
*ptr++ = USB_SIZ_PLATFORM_HDR + sizeof(firmware_version);
409+
*ptr++ = USB_DEVICE_CAPABITY_TYPE;
410+
*ptr++ = 0x05;
411+
*ptr++ = 0x00;
412+
413+
pbio_uuid128_le_copy(ptr, pbio_gatt_firmware_version_char_uuid_128);
414+
ptr += USB_SIZ_UUID;
415+
416+
memcpy(ptr, firmware_version, sizeof(firmware_version));
417+
ptr += sizeof(firmware_version);
418+
419+
/* Add software (protocol) version */
420+
*ptr++ = USB_SIZ_PLATFORM_HDR + sizeof(software_version);
421+
*ptr++ = USB_DEVICE_CAPABITY_TYPE;
422+
*ptr++ = 0x05;
423+
*ptr++ = 0x00;
424+
425+
pbio_uuid128_le_copy(ptr, pbio_gatt_software_version_char_uuid_128);
426+
ptr += USB_SIZ_UUID;
427+
428+
memcpy(ptr, software_version, sizeof(software_version));
429+
ptr += sizeof(software_version);
430+
431+
/* Add hub capabilities */
432+
*ptr++ = USB_SIZ_PLATFORM_HDR + PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE;
433+
*ptr++ = USB_DEVICE_CAPABITY_TYPE;
434+
*ptr++ = 0x05;
435+
*ptr++ = 0x00;
436+
437+
pbio_uuid128_le_copy(ptr, pbio_pybricks_hub_capabilities_char_uuid);
438+
ptr += USB_SIZ_UUID;
439+
440+
pbio_pybricks_hub_capabilities(ptr, 0, PBSYS_APP_HUB_FEATURE_FLAGS, PBSYS_PROGRAM_LOAD_MAX_PROGRAM_SIZE);
441+
ptr += PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE;
442+
443+
/* Update bNumDeviceCaps field in BOS Descriptor */
444+
USBD_BOSDesc[4] += 3;
445+
}
446+
381447
*length = sizeof(USBD_BOSDesc);
382448
return (uint8_t *)USBD_BOSDesc;
383449
}

lib/pbio/include/pbio/protocol.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ extern const uint8_t pbio_pybricks_hub_capabilities_char_uuid[];
301301

302302
extern const uint16_t pbio_gatt_device_info_service_uuid;
303303
extern const uint16_t pbio_gatt_firmware_version_char_uuid;
304+
extern const uint8_t pbio_gatt_firmware_version_char_uuid_128[];
304305
extern const uint16_t pbio_gatt_software_version_char_uuid;
306+
extern const uint8_t pbio_gatt_software_version_char_uuid_128[];
305307
extern const uint16_t pbio_gatt_pnp_id_char_uuid;
306308

307309
extern const uint8_t pbio_lwp3_hub_service_uuid[];

lib/pbio/include/pbio/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ void pbio_set_uint32_be(uint8_t *buf, uint32_t value) {
118118
buf[3] = value;
119119
}
120120

121+
void pbio_uuid128_le_copy(uint8_t *dst, const uint8_t *src);
121122
bool pbio_uuid128_reverse_compare(const uint8_t *uuid1, const uint8_t *uuid2);
122123
void pbio_uuid128_reverse_copy(uint8_t *dst, const uint8_t *src);
123124

lib/pbio/src/protocol/pybricks.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,17 @@ const uint16_t pbio_gatt_device_info_service_uuid = 0x180A;
8787

8888
/** Bluetooth Firmware Version Characteristic UUID. */
8989
const uint16_t pbio_gatt_firmware_version_char_uuid = 0x2A26;
90+
const uint8_t pbio_gatt_firmware_version_char_uuid_128[] = {
91+
0x00, 0x00, 0x2A, 0x26, 0x00, 0x00, 0x10, 0x00,
92+
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
93+
};
9094

9195
/** Bluetooth Software Version Characteristic UUID (Pybricks protocol version). */
9296
const uint16_t pbio_gatt_software_version_char_uuid = 0x2A28;
97+
const uint8_t pbio_gatt_software_version_char_uuid_128[] = {
98+
0x00, 0x00, 0x2A, 0x28, 0x00, 0x00, 0x10, 0x00,
99+
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
100+
};
93101

94102
/** Bluetooth PnP ID Characteristic UUID. */
95103
const uint16_t pbio_gatt_pnp_id_char_uuid = 0x2A50;

lib/pbio/src/util.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,34 @@
33

44
#include <stdbool.h>
55
#include <stdint.h>
6+
#include <string.h>
7+
8+
/**
9+
* Copies a 128-bit UUID from @p src to a buffer @p dst,
10+
* which is a buffer used by a little endian medium.
11+
*
12+
* According to RFC 4122, the UUID is grouped into the following:
13+
* 1) One 32-bit
14+
* 2) Two 16-bit
15+
* 3) Eight 8-bit
16+
*
17+
* @param [in] dst The destination array.
18+
* @param [in] src The UUID to reverse and copy.
19+
*/
20+
void pbio_uuid128_le_copy(uint8_t *dst, const uint8_t *src) {
21+
dst[0] = src[3];
22+
dst[1] = src[2];
23+
dst[2] = src[1];
24+
dst[3] = src[0];
25+
26+
dst[4] = src[5];
27+
dst[5] = src[4];
28+
29+
dst[6] = src[7];
30+
dst[7] = src[6];
31+
32+
memcpy(&dst[8], &src[8], 8);
33+
}
634

735
/**
836
* Compares two 128-bit UUIDs with opposite byte ordering for equality.

0 commit comments

Comments
 (0)