Skip to content

Commit

Permalink
feat(ble): Add option to disable profile auto save
Browse files Browse the repository at this point in the history
Add Kconfig option to disable persisting the BLE profile index after
every change. This is useful if the user wants to have the same profile
connected at startup regardless of which profile was connected last.

Add `&bt BT_SAVE` command to manually persist the currently active BLE
profile, ensuring it is selected as the active profile on startup.
  • Loading branch information
huber-th committed Jun 7, 2024
1 parent 308d6bc commit 9dc7694
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 20 deletions.
7 changes: 7 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ config ZMK_BLE_PASSKEY_ENTRY
bool "Require passkey entry on the keyboard to complete pairing"
select RING_BUFFER

config ZMK_BLE_PERSIST_PROFILE_ON_CHANGE
bool "Persist the active BLE profile on change"
default y
help
Enables persisting the active BLE profile on change (after ZMK_SETTINGS_SAVE_DEBOUNCE ms),
ensuring it is active on startup.

config BT_SMP_ALLOW_UNAUTH_OVERWRITE
imply ZMK_BLE_PASSKEY_ENTRY

Expand Down
2 changes: 2 additions & 0 deletions app/include/dt-bindings/zmk/bt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define BT_SEL_CMD 3
#define BT_CLR_ALL_CMD 4
#define BT_DISC_CMD 5
#define BT_SAVE_CMD 6

/*
Note: Some future commands will include additional parameters, so we
Expand All @@ -22,3 +23,4 @@ defines these aliases up front.
#define BT_SEL BT_SEL_CMD
#define BT_CLR_ALL BT_CLR_ALL_CMD 0
#define BT_DISC BT_DISC_CMD
#define BT_SAVE BT_SAVE_CMD 0
1 change: 1 addition & 0 deletions app/include/zmk/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ int zmk_ble_prof_prev(void);
int zmk_ble_prof_select(uint8_t index);
void zmk_ble_clear_all_bonds(void);
int zmk_ble_prof_disconnect(uint8_t index);
void zmk_ble_save_profile(bool immediate);

int zmk_ble_active_profile_index(void);
int zmk_ble_profile_index(const bt_addr_le_t *addr);
Expand Down
3 changes: 3 additions & 0 deletions app/src/behaviors/behavior_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
return 0;
case BT_DISC_CMD:
return zmk_ble_prof_disconnect(binding->param2);
case BT_SAVE_CMD:
zmk_ble_save_profile(true);
return 0;
default:
LOG_ERR("Unknown BT command: %d", binding->param1);
}
Expand Down
13 changes: 8 additions & 5 deletions app/src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,16 +251,16 @@ int zmk_ble_profile_index(const bt_addr_le_t *addr) {
#if IS_ENABLED(CONFIG_SETTINGS)
static void ble_save_profile_work(struct k_work *work) {
settings_save_one("ble/active_profile", &active_profile, sizeof(active_profile));
LOG_DBG("Saved active profile %d.", active_profile);
}

static struct k_work_delayable ble_save_work;
#endif

static int ble_save_profile(void) {
void zmk_ble_save_profile(bool immediate) {
#if IS_ENABLED(CONFIG_SETTINGS)
return k_work_reschedule(&ble_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
#else
return 0;
int delay = immediate ? 0 : CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE;
k_work_reschedule(&ble_save_work, K_MSEC(delay));
#endif
}

Expand All @@ -275,7 +275,9 @@ int zmk_ble_prof_select(uint8_t index) {
}

active_profile = index;
ble_save_profile();
#if IS_ENABLED(CONFIG_ZMK_BLE_PERSIST_PROFILE_ON_CHANGE)
zmk_ble_save_profile(false);
#endif

update_advertising();

Expand Down Expand Up @@ -407,6 +409,7 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c
LOG_ERR("Failed to handle active profile from settings (err %d)", err);
return err;
}
LOG_DBG("Loaded active profile %d", active_profile);
}
#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
else if (settings_name_steq(name, "peripheral_addresses", &next) && next) {
Expand Down
19 changes: 11 additions & 8 deletions docs/docs/behaviors/bluetooth.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,21 @@ This will allow you to reference the actions defined in this header such as `BT_

Here is a table describing the command for each define:

| Define | Action |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BT_CLR` | Clear bond information between the keyboard and host for the selected profile. |
| `BT_CLR_ALL` | Clear bond information between the keyboard and host for all profiles. |
| `BT_NXT` | Switch to the next profile, cycling through to the first one when the end is reached. |
| `BT_PRV` | Switch to the previous profile, cycling through to the last one when the beginning is reached. |
| `BT_SEL` | Select the 0-indexed profile by number; must include a number as an argument in the keymap to work correctly, e.g. `BT_SEL 0`. |
| `BT_DISC` | Disconnect from the 0-indexed profile by number, if it's currently connected and inactive; must include a number as an argument in the keymap to work correctly, e.g. `BT_DISC 0`. |
| Define | Action |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BT_CLR` | Clear bond information between the keyboard and host for the selected profile. |
| `BT_CLR_ALL` | Clear bond information between the keyboard and host for all profiles. |
| `BT_NXT` | Switch to the next profile, cycling through to the first one when the end is reached. |
| `BT_PRV` | Switch to the previous profile, cycling through to the last one when the beginning is reached. |
| `BT_SEL` | Select the 0-indexed profile by number; must include a number as an argument in the keymap to work correctly, e.g. `BT_SEL 0`. |
| `BT_DISC` | Disconnect from the 0-indexed profile by number, if it's currently connected and inactive; must include a number as an argument in the keymap to work correctly, e.g. `BT_DISC 0`. |
| `BT_SAVE` | Saves the currently selected profile, ensuring it is active at startup. <br/><br/>Note: This is only useful if `ZMK_CONFIG_BLE_PERSIST_PROFILE_ON_CHANGE` is disabled. Per default the active profile will be persisted on change automatically. |

:::note[Selected profile persistence]
The profile that is selected by the `BT_SEL`/`BT_PRV`/`BT_NXT` actions will be saved to flash storage and hence persist across restarts and firmware flashes.
However it will only be saved after [`CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE`](../config/system.md#general) milliseconds in order to reduce potential wear on the flash memory.

[`CONFIG_ZMK_BLE_PERSIST_PROFILE_ON_CHANGE`](../config/bluetooth.md) can be used to disable automatic saving of the selected profile to flash storage. In this case `BT_SAVE` can be used to manually persist the currently selected profile to change the active profile at startup.
:::

## Bluetooth Behavior
Expand Down
15 changes: 8 additions & 7 deletions docs/docs/config/bluetooth.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ See [Configuration Overview](index.md) for instructions on how to change these s

## Kconfig

| Option | Type | Description | Default |
| -------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| `CONFIG_ZMK_BLE_EXPERIMENTAL_CONN` | bool | Enables a combination of settings that are planned to be default in future versions of ZMK to improve connection stability. This includes changes to timing on BLE pairing initiation, restores use of the updated/new LLCP implementation, and disables 2M PHY support. | n |
| `CONFIG_ZMK_BLE_EXPERIMENTAL_SEC` | bool | Enables a combination of settings that are planned to be officially supported in the future. This includes enabling BT Secure Connection passkey entry, and allows overwrite of keys from previously paired hosts. | n |
| `CONFIG_ZMK_BLE_EXPERIMENTAL_FEATURES` | bool | Aggregate config that enables both `CONFIG_ZMK_BLE_EXPERIMENTAL_CONN` and `CONFIG_ZMK_BLE_EXPERIMENTAL_SEC`. | n |
| `CONFIG_ZMK_BLE_PASSKEY_ENTRY` | bool | Enable passkey entry during pairing for enhanced security. (Note: After enabling this, you will need to re-pair all previously paired hosts.) | n |
| `CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION` | bool | Low level setting for GATT subscriptions. Set to `n` to work around an annoying Windows bug with battery notifications. | y |
| Option | Type | Description | Default |
| ------------------------------------------ | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| `CONFIG_ZMK_BLE_EXPERIMENTAL_CONN` | bool | Enables a combination of settings that are planned to be default in future versions of ZMK to improve connection stability. This includes changes to timing on BLE pairing initiation, restores use of the updated/new LLCP implementation, and disables 2M PHY support. | n |
| `CONFIG_ZMK_BLE_EXPERIMENTAL_SEC` | bool | Enables a combination of settings that are planned to be officially supported in the future. This includes enabling BT Secure Connection passkey entry, and allows overwrite of keys from previously paired hosts. | n |
| `CONFIG_ZMK_BLE_EXPERIMENTAL_FEATURES` | bool | Aggregate config that enables both `CONFIG_ZMK_BLE_EXPERIMENTAL_CONN` and `CONFIG_ZMK_BLE_EXPERIMENTAL_SEC`. | n |
| `CONFIG_ZMK_BLE_PASSKEY_ENTRY` | bool | Enable passkey entry during pairing for enhanced security. (Note: After enabling this, you will need to re-pair all previously paired hosts.) | n |
| `CONFIG_ZMK_BLE_PERSIST_PROFILE_ON_CHANGE` | bool | Enables the new profile to be saved upon selection, ensuring it is active at startup. (Note: The profile is only saved after a delay of `CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE` milliseconds, to minimize potential wear on the flash memory.) | y |
| `CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION` | bool | Low level setting for GATT subscriptions. Set to `n` to work around an annoying Windows bug with battery notifications. | y |

0 comments on commit 9dc7694

Please sign in to comment.