fix(bluetooth): Passkey pairing improvements.

* Capture the last 6 entered digits, and then require pressing
   Enter/Return to submit the entered digits. This matches the
   messaging shown on hosts regarding how to complete pairing.
* Fix the wording on the Kconfig menu item to accurately describe
  the feature.
This commit is contained in:
Peter Johanson 2023-06-03 02:53:20 +00:00 committed by Pete Johanson
parent ace11e327f
commit 19d883cdfe
3 changed files with 34 additions and 23 deletions

View file

@ -160,8 +160,9 @@ config BT_DEVICE_APPEARANCE
default 961 default 961
config ZMK_BLE_PASSKEY_ENTRY 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 default n
select RING_BUFFER
config BT_PERIPHERAL_PREF_MIN_INT config BT_PERIPHERAL_PREF_MIN_INT
default 6 default 6

View file

@ -13,6 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include <zephyr/settings/settings.h> #include <zephyr/settings/settings.h>
#include <zephyr/sys/ring_buffer.h>
#include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h> #include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/hci.h> #include <zephyr/bluetooth/hci.h>
@ -42,8 +43,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#define PASSKEY_DIGITS 6 #define PASSKEY_DIGITS 6
static struct bt_conn *auth_passkey_entry_conn; static struct bt_conn *auth_passkey_entry_conn;
static uint8_t passkey_entries[PASSKEY_DIGITS] = {}; RING_BUF_DECLARE(passkey_entries, PASSKEY_DIGITS);
static uint8_t passkey_digit = 0;
#endif /* IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) */ #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)); bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_DBG("Passkey entry requested for %s", 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); 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; auth_passkey_entry_conn = NULL;
} }
passkey_digit = 0; ring_buf_reset(&passkey_entries);
#endif #endif
LOG_DBG("Pairing cancelled: %s", addr); 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) #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, 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) { if (key < one || key > zero) {
return false; return false;
} }
@ -634,7 +634,23 @@ static int zmk_ble_handle_key_user(struct zmk_keycode_state_changed *event) {
return ZMK_EV_EVENT_HANDLED; 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, if (!(zmk_ble_numeric_usage_to_value(key, HID_USAGE_KEY_KEYBOARD_1_AND_EXCLAMATION,
HID_USAGE_KEY_KEYBOARD_0_AND_RIGHT_PARENTHESIS, &val) || HID_USAGE_KEY_KEYBOARD_0_AND_RIGHT_PARENTHESIS, &val) ||
zmk_ble_numeric_usage_to_value(key, HID_USAGE_KEY_KEYPAD_1_AND_END, 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; return ZMK_EV_EVENT_BUBBLE;
} }
passkey_entries[passkey_digit++] = val; if (ring_buf_space_get(&passkey_entries) <= 0) {
LOG_DBG("value entered: %d, digits collected so far: %d", val, passkey_digit); uint8_t discard_val;
ring_buf_get(&passkey_entries, &discard_val, 1);
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;
} }
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; return ZMK_EV_EVENT_HANDLED;
} }

View file

@ -9,6 +9,7 @@ See [Configuration Overview](index.md) for instructions on how to change these s
## Kconfig ## Kconfig
| Option | Type | Description | Default | | 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 | | `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 |