From f7dee8238deb1bb67f2109a32a1af090b584a4dd Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:33:43 +0100 Subject: [PATCH] feat(ble): Set device name at runtime This allows for the device name to be set at runtime, possible uses for this include a custom display screen that lets you type it in using the keycode state event, future configuration in zmk studio, or altering it per profile as per #1169 --- app/Kconfig | 1 + app/include/zmk/ble.h | 2 ++ app/src/ble.c | 24 +++++++++++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 5aedd9d9..7857ba7b 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -147,6 +147,7 @@ menuconfig ZMK_BLE select BT_SMP_APP_PAIRING_ACCEPT select BT_PERIPHERAL select BT_DIS + select BT_DEVICE_NAME_DYNAMIC imply BT_SETTINGS if !ARCH_POSIX imply SETTINGS if !ARCH_POSIX imply ZMK_BATTERY_REPORTING if !ARCH_POSIX diff --git a/app/include/zmk/ble.h b/app/include/zmk/ble.h index 773323c1..f03f09ca 100644 --- a/app/include/zmk/ble.h +++ b/app/include/zmk/ble.h @@ -36,6 +36,8 @@ char *zmk_ble_active_profile_name(void); int zmk_ble_unpair_all(void); +void zmk_ble_set_device_name(char *name); + #if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) int zmk_ble_put_peripheral_addr(const bt_addr_le_t *addr); #endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) */ diff --git a/app/src/ble.c b/app/src/ble.c index 7e1ae7d4..34590532 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -56,8 +56,8 @@ enum advertising_type { #define CURR_ADV(adv) (adv << 4) #define ZMK_ADV_CONN_NAME \ - BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME, BT_GAP_ADV_FAST_INT_MIN_2, \ - BT_GAP_ADV_FAST_INT_MAX_2, NULL) + BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME | BT_LE_ADV_OPT_USE_NAME, \ + BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL) static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT]; static uint8_t active_profile; @@ -65,10 +65,9 @@ static uint8_t active_profile; #define DEVICE_NAME CONFIG_BT_DEVICE_NAME #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) -BUILD_ASSERT(DEVICE_NAME_LEN <= 16, "ERROR: BLE device name is too long. Max length: 16"); +BUILD_ASSERT(DEVICE_NAME_LEN <= 27, "ERROR: BLE device name is too long. Max length: 27"); -static const struct bt_data zmk_ble_ad[] = { - BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +static struct bt_data zmk_ble_ad[] = { BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, 0xC1, 0x03), BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID16_SOME, 0x12, 0x18, /* HID Service */ @@ -320,6 +319,21 @@ bt_addr_le_t *zmk_ble_active_profile_addr(void) { return &profiles[active_profil char *zmk_ble_active_profile_name(void) { return profiles[active_profile].name; } +void zmk_ble_set_device_name(char *name) { + // Copy new name to advertising parameters + bt_set_name(name); + LOG_DBG("New device name: %s", name); + if (advertising_status == ZMK_ADV_CONN) { + // Stop current advertising so it can restart with new name + int err = bt_le_adv_stop(); + advertising_status = ZMK_ADV_NONE; + if (err) { + LOG_ERR("Failed to stop advertising (err %d)", err); + } + } + update_advertising(); +} + #if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) int zmk_ble_put_peripheral_addr(const bt_addr_le_t *addr) {