diff --git a/app/include/dt-bindings/zmk/bt.h b/app/include/dt-bindings/zmk/bt.h index 8ca10606..215f8559 100644 --- a/app/include/dt-bindings/zmk/bt.h +++ b/app/include/dt-bindings/zmk/bt.h @@ -9,6 +9,7 @@ #define BT_PRV_CMD 2 #define BT_SEL_CMD 3 // #define BT_FULL_RESET_CMD 4 +#define BT_DISCONNECT_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_DISCONNECT BT_DISCONNECT_CMD diff --git a/app/include/zmk/ble.h b/app/include/zmk/ble.h index 435fde49..92fd595f 100644 --- a/app/include/zmk/ble.h +++ b/app/include/zmk/ble.h @@ -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(); diff --git a/app/src/behaviors/behavior_bt.c b/app/src/behaviors/behavior_bt.c index 6d44b5f5..319014b4 100644 --- a/app/src/behaviors/behavior_bt.c +++ b/app/src/behaviors/behavior_bt.c @@ -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_DISCONNECT_CMD: + return zmk_ble_prof_disconnect(binding->param2); default: LOG_ERR("Unknown BT command: %d", binding->param1); } diff --git a/app/src/ble.c b/app/src/ble.c index 483bc9d7..1d7f6e86 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -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 -1; + } else if ((conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, addr)) == NULL) { + return -1; + } + + 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; }