diff --git a/app/Kconfig b/app/Kconfig index d1b6682f..1537bd61 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -160,8 +160,9 @@ config BT_DEVICE_APPEARANCE default 961 config ZMK_BLE_PASSKEY_ENTRY - bool "Experimental: Requiring typing passkey from host to pair BLE connection" + bool "Require passkey entry on the keyboard to complete pairing" default n + select RING_BUFFER config BT_PERIPHERAL_PREF_MIN_INT default 6 diff --git a/app/src/ble.c b/app/src/ble.c index c7bdc401..383a727d 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -42,8 +43,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define PASSKEY_DIGITS 6 static struct bt_conn *auth_passkey_entry_conn; -static uint8_t passkey_entries[PASSKEY_DIGITS] = {}; -static uint8_t passkey_digit = 0; +RING_BUF_DECLARE(passkey_entries, PASSKEY_DIGITS); #endif /* IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) */ @@ -469,7 +469,7 @@ static void auth_passkey_entry(struct bt_conn *conn) { bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_DBG("Passkey entry requested for %s", addr); - passkey_digit = 0; + ring_buf_reset(&passkey_entries); auth_passkey_entry_conn = bt_conn_ref(conn); } @@ -486,7 +486,7 @@ static void auth_cancel(struct bt_conn *conn) { auth_passkey_entry_conn = NULL; } - passkey_digit = 0; + ring_buf_reset(&passkey_entries); #endif LOG_DBG("Pairing cancelled: %s", addr); @@ -605,7 +605,7 @@ static int zmk_ble_init(const struct device *_arg) { #if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) static bool zmk_ble_numeric_usage_to_value(const zmk_key_t key, const zmk_key_t one, - const zmk_key_t zero, uint32_t *value) { + const zmk_key_t zero, uint8_t *value) { if (key < one || key > zero) { return false; } @@ -634,7 +634,23 @@ static int zmk_ble_handle_key_user(struct zmk_keycode_state_changed *event) { return ZMK_EV_EVENT_HANDLED; } - uint32_t val; + if (key == HID_USAGE_KEY_KEYBOARD_RETURN || key == HID_USAGE_KEY_KEYBOARD_RETURN_ENTER) { + uint8_t digits[PASSKEY_DIGITS]; + uint32_t count = ring_buf_get(&passkey_entries, digits, PASSKEY_DIGITS); + + uint32_t passkey = 0; + for (int i = 0; i < count; i++) { + passkey = (passkey * 10) + digits[i]; + } + + LOG_DBG("Final passkey: %d", passkey); + bt_conn_auth_passkey_entry(auth_passkey_entry_conn, passkey); + bt_conn_unref(auth_passkey_entry_conn); + auth_passkey_entry_conn = NULL; + return ZMK_EV_EVENT_HANDLED; + } + + uint8_t val; if (!(zmk_ble_numeric_usage_to_value(key, HID_USAGE_KEY_KEYBOARD_1_AND_EXCLAMATION, HID_USAGE_KEY_KEYBOARD_0_AND_RIGHT_PARENTHESIS, &val) || zmk_ble_numeric_usage_to_value(key, HID_USAGE_KEY_KEYPAD_1_AND_END, @@ -643,20 +659,13 @@ static int zmk_ble_handle_key_user(struct zmk_keycode_state_changed *event) { return ZMK_EV_EVENT_BUBBLE; } - passkey_entries[passkey_digit++] = val; - LOG_DBG("value entered: %d, digits collected so far: %d", val, passkey_digit); - - if (passkey_digit == PASSKEY_DIGITS) { - uint32_t passkey = 0; - for (int i = 0; i < PASSKEY_DIGITS; i++) { - passkey = (passkey * 10) + passkey_entries[i]; - } - - LOG_DBG("Final passkey: %d", passkey); - bt_conn_auth_passkey_entry(auth_passkey_entry_conn, passkey); - bt_conn_unref(auth_passkey_entry_conn); - auth_passkey_entry_conn = NULL; + if (ring_buf_space_get(&passkey_entries) <= 0) { + uint8_t discard_val; + ring_buf_get(&passkey_entries, &discard_val, 1); } + ring_buf_put(&passkey_entries, &val, 1); + LOG_DBG("value entered: %d, digits collected so far: %d", val, + ring_buf_size_get(&passkey_entries)); return ZMK_EV_EVENT_HANDLED; } diff --git a/docs/docs/config/bluetooth.md b/docs/docs/config/bluetooth.md index 420dd5c3..d2ddefdd 100644 --- a/docs/docs/config/bluetooth.md +++ b/docs/docs/config/bluetooth.md @@ -9,6 +9,7 @@ See [Configuration Overview](index.md) for instructions on how to change these s ## Kconfig -| Option | Type | Description | Default | -| ------------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------- | ------- | -| `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_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 |