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 1/3] 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) {

From 2852fe315ca804d68a99396cf1ceb5dd20e552cb Mon Sep 17 00:00:00 2001
From: ReFil <31960031+ReFil@users.noreply.github.com>
Date: Tue, 18 Jun 2024 18:31:42 +0100
Subject: [PATCH 2/3] Address review comments

---
 app/Kconfig           |  2 +-
 app/include/zmk/ble.h |  2 +-
 app/src/ble.c         | 13 +++++++++----
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/app/Kconfig b/app/Kconfig
index 7857ba7b..6a285a15 100644
--- a/app/Kconfig
+++ b/app/Kconfig
@@ -147,7 +147,7 @@ menuconfig ZMK_BLE
     select BT_SMP_APP_PAIRING_ACCEPT
     select BT_PERIPHERAL
     select BT_DIS
-    select BT_DEVICE_NAME_DYNAMIC
+    imply 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 f03f09ca..17cb38ed 100644
--- a/app/include/zmk/ble.h
+++ b/app/include/zmk/ble.h
@@ -36,7 +36,7 @@ char *zmk_ble_active_profile_name(void);
 
 int zmk_ble_unpair_all(void);
 
-void zmk_ble_set_device_name(char *name);
+int 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);
diff --git a/app/src/ble.c b/app/src/ble.c
index 34590532..b3cf6c79 100644
--- a/app/src/ble.c
+++ b/app/src/ble.c
@@ -319,19 +319,24 @@ 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) {
+int zmk_ble_set_device_name(char *name) {
     // Copy new name to advertising parameters
-    bt_set_name(name);
+    int err = bt_set_name(name);
     LOG_DBG("New device name: %s", name);
+    if (err) {
+        LOG_ERR("Failed to set new device name (err %d)", err);
+        return err;
+    }
     if (advertising_status == ZMK_ADV_CONN) {
         // Stop current advertising so it can restart with new name
-        int err = bt_le_adv_stop();
+        err = bt_le_adv_stop();
         advertising_status = ZMK_ADV_NONE;
         if (err) {
             LOG_ERR("Failed to stop advertising (err %d)", err);
+            return err;
         }
     }
-    update_advertising();
+    return update_advertising();
 }
 
 #if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)

From 64e89b09ea7b858f8f55d6ba58f1886da11673d1 Mon Sep 17 00:00:00 2001
From: ReFil <31960031+ReFil@users.noreply.github.com>
Date: Tue, 18 Jun 2024 19:07:27 +0100
Subject: [PATCH 3/3] Move name to AD and restrict length

---
 app/src/ble.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/app/src/ble.c b/app/src/ble.c
index b3cf6c79..90f45db3 100644
--- a/app/src/ble.c
+++ b/app/src/ble.c
@@ -56,7 +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_LE_ADV_OPT_USE_NAME,   \
+    BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME | BT_LE_ADV_OPT_USE_NAME |  \
+                        BT_LE_ADV_OPT_FORCE_NAME_IN_AD,                                            \
                     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];
@@ -65,7 +66,7 @@ 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 <= 27, "ERROR: BLE device name is too long. Max length: 27");
+BUILD_ASSERT(DEVICE_NAME_LEN <= 16, "ERROR: BLE device name is too long. Max length: 16");
 
 static struct bt_data zmk_ble_ad[] = {
     BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, 0xC1, 0x03),