feat(ble): add behavior to disconnect from BLE profile

Adds new functionality and a behavior to disconnect an active BLE connection.
The motivation for this is that for some devices like phones, the presence of an
active BLE connection results in the onscreen keyboard being selected.
This commit is contained in:
Chris Andreae 2023-11-21 05:00:10 +09:00 committed by GitHub
parent d7d9eed317
commit 0a4b1a6533
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 6 deletions

View File

@ -9,6 +9,7 @@
#define BT_PRV_CMD 2
#define BT_SEL_CMD 3
// #define BT_FULL_RESET_CMD 4
#define BT_DISC_CMD 5
/*
Note: Some future commands will include additional parameters, so we
@ -19,3 +20,4 @@ defines these aliases up front.
#define BT_NXT BT_NXT_CMD 0
#define BT_PRV BT_PRV_CMD 0
#define BT_SEL BT_SEL_CMD
#define BT_DISC BT_DISC_CMD

View File

@ -24,6 +24,7 @@ int zmk_ble_clear_bonds();
int zmk_ble_prof_next();
int zmk_ble_prof_prev();
int zmk_ble_prof_select(uint8_t index);
int zmk_ble_prof_disconnect(uint8_t index);
int zmk_ble_active_profile_index();
bt_addr_le_t *zmk_ble_active_profile_addr();

View File

@ -31,6 +31,8 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
return zmk_ble_prof_prev();
case BT_SEL_CMD:
return zmk_ble_prof_select(binding->param2);
case BT_DISC_CMD:
return zmk_ble_prof_disconnect(binding->param2);
default:
LOG_ERR("Unknown BT command: %d", binding->param1);
}

View File

@ -271,6 +271,27 @@ int zmk_ble_prof_prev() {
ZMK_BLE_PROFILE_COUNT);
};
int zmk_ble_prof_disconnect(uint8_t index) {
if (index >= ZMK_BLE_PROFILE_COUNT)
return -ERANGE;
bt_addr_le_t *addr = &profiles[index].peer;
struct bt_conn *conn;
int result;
if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
return -ENODEV;
} else if ((conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, addr)) == NULL) {
return -ENODEV;
}
result = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
LOG_DBG("Disconnected from profile %d: %d", index, result);
bt_conn_unref(conn);
return result;
}
bt_addr_le_t *zmk_ble_active_profile_addr() { return &profiles[active_profile].peer; }
char *zmk_ble_active_profile_name() { return profiles[active_profile].name; }

View File

@ -13,6 +13,13 @@ computer/laptop/keyboard should receive the keyboard input; many of the commands
When pairing to a host device ZMK saves bond information to the selected profile. It will not replace this when you initiate pairing with another device. To pair with a new device select an unused profile with `BT_SEL`, `BT_NXT` or `BT_PRV` bindings, or by clearing an existing profile using `BT_CLR`.
A ZMK device may show as "connected" on multiple hosts at the same time. This is working as intended, and only the host associated with the active profile will receive keystrokes.
An _inactive_ connected profile can be explicitly disconnected using the `BT_DISC` behavior. This can be helpful in
cases when host devices behave differently when a bluetooth keyboard is connected, for example by hiding their on-screen
keyboard. Note that at present the active bluetooth profile will immediately reconnect if disconnected. This is true
even if OUT_USB is selected. To remain disconnected, another bluetooth profile must be first selected using (e.g.)
`BT_SEL`.
:::
## Bluetooth Command Defines
@ -28,12 +35,14 @@ 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_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. Please note: this definition must include a number as an argument in the keymap to work correctly. eg. `BT_SEL 0` |
| Define | Action |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BT_CLR` | Clear bond information between the keyboard and host for the selected profile. |
| `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. Please note: this definition must include a number as an argument in the keymap to work correctly. eg. `BT_SEL 0` |
| `BT_DISC` | Disconnect from the 0-indexed profile by number, if it's currently connected and inactive. Please note: this definition must include a number as an |
| | argument in the keymap to work correctly. eg. `BT_DISC 0` |
:::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.