Skip to content

Commit

Permalink
Include the serial number in the Bluetooth device name
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisandreae committed Jul 1, 2024
1 parent 7ebd1f5 commit 3f110c5
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 11 deletions.
10 changes: 10 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ config ZMK_BLE_MOUSE_REPORT_QUEUE_SIZE
config ZMK_BLE_CLEAR_BONDS_ON_START
bool "Configuration that clears all bond information from the keyboard on startup."

config ZMK_BLE_DEVICE_NAME_APPEND_SN
bool "Append the device serial number to the Bluetooth device name"
default n
select BT_DEVICE_NAME_DYNAMIC

config ZMK_BLE_DEVICE_NAME_SN_CHARS
int "Number of hexadecimal digits of serial number to append to the BT device name"
default 6
depends on ZMK_BLE_DEVICE_NAME_APPEND_SN

# HID GATT notifications sent this way are *not* picked up by Linux, and possibly others.
config BT_GATT_NOTIFY_MULTIPLE
default n
Expand Down
2 changes: 2 additions & 0 deletions app/boards/arm/glove80/glove80_lh_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ CONFIG_USB_DEVICE_VID=0x16c0
CONFIG_USB_DEVICE_MANUFACTURER="MoErgo"
CONFIG_USB_DEVICE_SN="moergo.com:GLV80-0123456789ABCDEF"

CONFIG_BT_DEVICE_NAME="Glove80"

CONFIG_BT_DIS_PNP_PID=0x27db
CONFIG_BT_DIS_PNP_VID=0x16c0
CONFIG_BT_DIS_MANUF="MoErgo"
Expand Down
31 changes: 20 additions & 11 deletions app/boards/arm/glove80/usb_serial_number.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
LOG_MODULE_DECLARE(usb_descriptor);

int base16_encode(const uint8_t *data, int length, uint8_t *result, int bufSize);
void fill_serial_number(char *buf, int length);

/**
* nrf52840 hwinfo returns a 64-bit hardware id. Glove80 uses this as a
* serial number, encoded as base16 into the last 16 characters of the
* CONFIG_USB_DEVICE_SN template. If insufficient template space is
* available, instead return the static serial number string.
*/
uint8_t *usb_update_sn_string_descriptor(void) {
/*
* nrf52840 hwinfo returns a 64-bit hardware id. Glove80 uses this as a
* serial number, encoded as base16 into the last 16 characters of the
* CONFIG_USB_DEVICE_SN template. If insufficient template space is
* available, instead return the static serial number string.
*/
const uint8_t template_len = sizeof(CONFIG_USB_DEVICE_SN);
const uint8_t sn_len = 16;

Expand All @@ -33,17 +34,25 @@ uint8_t *usb_update_sn_string_descriptor(void) {
static uint8_t serial[sizeof(CONFIG_USB_DEVICE_SN)];
strncpy(serial, CONFIG_USB_DEVICE_SN, template_len);

const uint8_t offset = template_len - sn_len - 1;
fill_serial_number(serial + offset, sn_len);
serial[template_len - 1] = '\0';

return serial;
}

/**
* Writes the first `length` bytes of the device serial number into buf
*/
void fill_serial_number(char *buf, int length) {
uint8_t hwid[8];
memset(hwid, 0, sizeof(hwid));
uint8_t hwlen = hwinfo_get_device_id(hwid, sizeof(hwid));

if (hwlen > 0) {
const uint8_t offset = template_len - sn_len - 1;
LOG_HEXDUMP_DBG(&hwid, sn_len, "Serial Number");
base16_encode(hwid, hwlen, serial + offset, sn_len + 1);
LOG_HEXDUMP_DBG(&hwid, 16, "Serial Number");
base16_encode(hwid, hwlen, buf, length);
}

return serial;
}

int base16_encode(const uint8_t *data, int length, uint8_t *result, int bufSize) {
Expand Down
32 changes: 32 additions & 0 deletions app/src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,32 @@ enum advertising_type {
static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT];
static uint8_t active_profile;

#if IS_ENABLED(CONFIG_ZMK_BLE_DEVICE_NAME_APPEND_SN)

static char bt_device_name[sizeof(CONFIG_BT_DEVICE_NAME) + CONFIG_ZMK_BLE_DEVICE_NAME_SN_CHARS + 1];

void fill_serial_number(char *buf, int length);

// configure the BT device name by appending a serial number prefix to
// CONFIG_BT_DEVICE_NAME
void init_bt_device_name(void) {
strncpy(bt_device_name, CONFIG_BT_DEVICE_NAME, sizeof(bt_device_name));
bt_device_name[sizeof(CONFIG_BT_DEVICE_NAME) - 1] = ' ';
fill_serial_number(&bt_device_name[sizeof(CONFIG_BT_DEVICE_NAME)],
CONFIG_ZMK_BLE_DEVICE_NAME_SN_CHARS);
bt_device_name[sizeof(bt_device_name) - 1] = '\0';
}

#define DEVICE_NAME bt_device_name
#define DEVICE_NAME_LEN (sizeof(bt_device_name) - 1)

#else

#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

#endif

BUILD_ASSERT(DEVICE_NAME_LEN <= 16, "ERROR: BLE device name is too long. Max length: 16");

static const struct bt_data zmk_ble_ad[] = {
Expand Down Expand Up @@ -662,6 +685,10 @@ static void zmk_ble_ready(int err) {
}

static int zmk_ble_init(void) {
#if IS_ENABLED(CONFIG_ZMK_BLE_DEVICE_NAME_APPEND_SN)
init_bt_device_name();
#endif

int err = bt_enable(NULL);

if (err) {
Expand All @@ -682,7 +709,12 @@ static int zmk_ble_init(void) {

settings_load_subtree("ble");
settings_load_subtree("bt");
#endif

#if IS_ENABLED(CONFIG_ZMK_BLE_DEVICE_NAME_APPEND_SN)
if (strcmp(bt_get_name(), bt_device_name) != 0) {
bt_set_name(bt_device_name);
}
#endif

#if IS_ENABLED(CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START)
Expand Down

0 comments on commit 3f110c5

Please sign in to comment.