diff options
Diffstat (limited to 'app/src')
-rw-r--r-- | app/src/ble.c | 18 | ||||
-rw-r--r-- | app/src/ble_unpair_combo.c | 80 | ||||
-rw-r--r-- | app/src/usb_hid.c | 36 |
3 files changed, 127 insertions, 7 deletions
diff --git a/app/src/ble.c b/app/src/ble.c index 71bbccd..0e96d16 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -28,6 +28,16 @@ static struct bt_conn *auth_passkey_entry_conn; static u8_t passkey_entries[6] = {0, 0, 0, 0, 0, 0}; static u8_t passkey_digit = 0; +#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) +#define ZMK_ADV_PARAMS BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \ + BT_LE_ADV_OPT_USE_NAME | \ + BT_LE_ADV_OPT_ONE_TIME, \ + BT_GAP_ADV_FAST_INT_MIN_2, \ + BT_GAP_ADV_FAST_INT_MAX_2, NULL) +#else +#define ZMK_ADV_PARAMS BT_LE_ADV_CONN_NAME +#endif + static void connected(struct bt_conn *conn, u8_t err) { char addr[BT_ADDR_LE_STR_LEN]; @@ -159,7 +169,7 @@ static void zmk_ble_ready(int err) return; } - err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); + err = bt_le_adv_start(ZMK_ADV_PARAMS, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); if (err) { LOG_ERR("Advertising failed to start (err %d)", err); @@ -190,6 +200,12 @@ static int zmk_ble_init(struct device *_arg) return 0; } +int zmk_ble_unpair_all() +{ + LOG_DBG(""); + return bt_unpair(BT_ID_DEFAULT, NULL); +}; + bool zmk_ble_handle_key_user(struct zmk_key_event *key_event) { zmk_key key = key_event->key; diff --git a/app/src/ble_unpair_combo.c b/app/src/ble_unpair_combo.c new file mode 100644 index 0000000..a33a8e2 --- /dev/null +++ b/app/src/ble_unpair_combo.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 Peter Johanson + * + * SPDX-License-Identifier: MIT + */ + +#include <device.h> +#include <init.h> + +#include <logging/log.h> + +#define DT_DRV_COMPAT zmk_bt_unpair_combo + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include <zmk/ble.h> +#include <zmk/event-manager.h> +#include <zmk/events/position-state-changed.h> + + +static u8_t combo_state; + +const u32_t key_positions[] = DT_INST_PROP(0, key_positions); +#define KP_LEN DT_INST_PROP_LEN(0, key_positions) + +int index_for_key_position(u32_t kp) +{ + for (int i = 0; i < KP_LEN; i++) { + if (key_positions[i] == kp) { + return i; + } + } + + return -1; +} + +int unpair_combo_listener(const struct zmk_event_header *eh) +{ + if (is_position_state_changed(eh)) { + const struct position_state_changed *psc = cast_position_state_changed(eh); + + int kp_index = index_for_key_position(psc->position); + if (kp_index < 0) { + return 0; + } + + WRITE_BIT(combo_state, kp_index, psc->state); + } + + return 0; +}; + +void unpair_combo_work_handler(struct k_work *work) +{ + for (int i = 0; i < KP_LEN; i++) { + if (!(combo_state & BIT(i))) { + LOG_DBG("Key position %d not held, skipping unpair combo", key_positions[i]); + return; + } + } + + zmk_ble_unpair_all(); +}; + +struct k_delayed_work unpair_combo_work; + +int zmk_ble_unpair_combo_init(struct device *_unused) +{ + k_delayed_work_init(&unpair_combo_work, unpair_combo_work_handler); + k_delayed_work_submit(&unpair_combo_work, K_SECONDS(2)); + + return 0; +}; + +ZMK_LISTENER(zmk_ble_unpair_combo, unpair_combo_listener); +ZMK_SUBSCRIPTION(zmk_ble_unpair_combo, position_state_changed); + +SYS_INIT(zmk_ble_unpair_combo_init, + APPLICATION, + CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/usb_hid.c b/app/src/usb_hid.c index 4c6dd4b..784fc25 100644 --- a/app/src/usb_hid.c +++ b/app/src/usb_hid.c @@ -11,18 +11,42 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -static enum usb_dc_status_code usb_status; +static enum usb_dc_status_code usb_status = USB_DC_UNKNOWN; static struct device *hid_dev; +static K_SEM_DEFINE(hid_sem, 1, 1); + +static void in_ready_cb(void) +{ + k_sem_give(&hid_sem); +} + +static const struct hid_ops ops = +{ + .int_in_ready = in_ready_cb, +}; + int zmk_usb_hid_send_report(const u8_t *report, size_t len) { - if (usb_status == USB_DC_SUSPEND) - { + switch(usb_status) { + case USB_DC_SUSPEND: return usb_wakeup_request(); + case USB_DC_ERROR: + case USB_DC_RESET: + case USB_DC_DISCONNECTED: + case USB_DC_UNKNOWN: + return -ENODEV; + default: + k_sem_take(&hid_sem, K_MSEC(30)); + int err = hid_int_ep_write(hid_dev, report, len, NULL); + + if (err) { + k_sem_give(&hid_sem); + } + + return err; } - - return hid_int_ep_write(hid_dev, report, len, NULL); } void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) @@ -43,7 +67,7 @@ static int zmk_usb_hid_init(struct device *_arg) usb_hid_register_device(hid_dev, zmk_hid_report_desc, sizeof(zmk_hid_report_desc), - NULL); + &ops); usb_hid_init(hid_dev); |