Browse Source

fix(ble): Restore BLE SC passkey entry for pairing.

* Handle capturing numeric inputs while pairing and sending
  final passkey once six digits entered.
xmkb
Peter Johanson 3 years ago committed by Pete Johanson
parent
commit
ed48d1ae89
  1. 3
      app/include/zmk/ble.h
  2. 95
      app/src/ble.c

3
app/include/zmk/ble.h

@ -21,8 +21,7 @@ bool zmk_ble_active_profile_is_connected(); @@ -21,8 +21,7 @@ bool zmk_ble_active_profile_is_connected();
char *zmk_ble_active_profile_name();
int zmk_ble_unpair_all();
bool zmk_ble_handle_key_user(struct zmk_key_event *key_event);
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
void zmk_ble_set_peripheral_addr(bt_addr_le_t *addr);
#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) */
#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) */

95
app/src/ble.c

@ -36,10 +36,24 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -36,10 +36,24 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/event_manager.h>
#include <zmk/events/ble_active_profile_changed.h>
#define IS_HOST_PERIPHERAL \
(!IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL))
#define IS_SPLIT_PERIPHERAL \
(IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL))
#define DO_PASSKEY_ENTRY (IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) && !IS_SPLIT_PERIPHERAL)
#if DO_PASSKEY_ENTRY
#include <zmk/events/keycode_state_changed.h>
#define PASSKEY_DIGITS 6
static struct bt_conn *auth_passkey_entry_conn;
static uint8_t passkey_entries[6] = {0, 0, 0, 0, 0, 0};
static uint8_t passkey_entries[PASSKEY_DIGITS] = {};
static uint8_t passkey_digit = 0;
#endif
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
#define PROFILE_COUNT (CONFIG_BT_MAX_PAIRED - 1)
#else
@ -66,11 +80,6 @@ static uint8_t active_profile; @@ -66,11 +80,6 @@ static uint8_t active_profile;
BUILD_ASSERT(DEVICE_NAME_LEN <= 16, "ERROR: BLE device name is too long. Max length: 16");
#define IS_HOST_PERIPHERAL \
(!IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL))
#define IS_SPLIT_PERIPHERAL \
(IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL))
static const struct bt_data zmk_ble_ad[] = {
#if IS_HOST_PERIPHERAL
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
@ -456,7 +465,7 @@ static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) { @@ -456,7 +465,7 @@ static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) {
}
*/
#ifdef CONFIG_ZMK_BLE_PASSKEY_ENTRY
#if DO_PASSKEY_ENTRY
static void auth_passkey_entry(struct bt_conn *conn) {
char addr[BT_ADDR_LE_STR_LEN];
@ -464,6 +473,7 @@ static void auth_passkey_entry(struct bt_conn *conn) { @@ -464,6 +473,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", log_strdup(addr));
passkey_digit = 0;
auth_passkey_entry_conn = bt_conn_ref(conn);
}
@ -474,12 +484,14 @@ static void auth_cancel(struct bt_conn *conn) { @@ -474,12 +484,14 @@ static void auth_cancel(struct bt_conn *conn) {
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
#if DO_PASSKEY_ENTRY
if (auth_passkey_entry_conn) {
bt_conn_unref(auth_passkey_entry_conn);
auth_passkey_entry_conn = NULL;
}
passkey_digit = 0;
#endif
LOG_DBG("Pairing cancelled: %s", log_strdup(addr));
}
@ -532,7 +544,7 @@ static struct bt_conn_auth_cb zmk_ble_auth_cb_display = { @@ -532,7 +544,7 @@ static struct bt_conn_auth_cb zmk_ble_auth_cb_display = {
.pairing_complete = auth_pairing_complete,
// .passkey_display = auth_passkey_display,
#ifdef CONFIG_ZMK_BLE_PASSKEY_ENTRY
#if DO_PASSKEY_ENTRY
.passkey_entry = auth_passkey_entry,
#endif
.cancel = auth_cancel,
@ -612,32 +624,79 @@ int zmk_ble_unpair_all() { @@ -612,32 +624,79 @@ int zmk_ble_unpair_all() {
return resp;
};
bool zmk_ble_handle_key_user(struct zmk_key_event *key_event) {
zmk_key_t key = key_event->key;
#if DO_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) {
if (key < one || key > zero) {
return false;
}
*value = (key == zero) ? 0 : (key - one + 1);
return true;
}
static int zmk_ble_handle_key_user(struct zmk_keycode_state_changed *event) {
zmk_key_t key = event->keycode;
LOG_DBG("key %d", key);
if (!auth_passkey_entry_conn) {
return true;
LOG_DBG("No connection for passkey entry");
return ZMK_EV_EVENT_BUBBLE;
}
if (!event->state) {
LOG_DBG("Key released, ignoring");
return ZMK_EV_EVENT_BUBBLE;
}
if (key < NUMBER_1 || key > NUMBER_0) {
return true;
if (key == HID_USAGE_KEY_KEYBOARD_ESCAPE) {
bt_conn_auth_cancel(auth_passkey_entry_conn);
return ZMK_EV_EVENT_HANDLED;
}
uint32_t val = (key == NUMBER_0) ? 0 : (key - NUMBER_1 + 1);
uint32_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,
HID_USAGE_KEY_KEYPAD_0_AND_INSERT, &val))) {
LOG_DBG("Key not a number, ignoring");
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 == 6) {
if (passkey_digit == PASSKEY_DIGITS) {
uint32_t passkey = 0;
for (int i = 5; i >= 0; i--) {
passkey = (passkey * 10) + val;
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;
}
return false;
return ZMK_EV_EVENT_HANDLED;
}
static int zmk_ble_listener(const zmk_event_t *eh) {
struct zmk_keycode_state_changed *kc_state;
kc_state = as_zmk_keycode_state_changed(eh);
if (kc_state != NULL) {
return zmk_ble_handle_key_user(kc_state);
}
return 0;
}
ZMK_LISTENER(zmk_ble, zmk_ble_listener);
ZMK_SUBSCRIPTION(zmk_ble, zmk_keycode_state_changed);
#endif /* DO_PASSKEY_ENTRY */
SYS_INIT(zmk_ble_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY);

Loading…
Cancel
Save