diff --git a/app/include/zmk/ble.h b/app/include/zmk/ble.h index 1cf71a77..56980c69 100644 --- a/app/include/zmk/ble.h +++ b/app/include/zmk/ble.h @@ -15,6 +15,7 @@ int zmk_ble_prof_prev(); int zmk_ble_prof_select(u8_t index); bt_addr_le_t *zmk_ble_active_profile_addr(); +bool zmk_ble_active_profile_is_connected(); char *zmk_ble_active_profile_name(); int zmk_ble_unpair_all(); diff --git a/app/src/ble.c b/app/src/ble.c index 9090582c..a79f7237 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -94,6 +94,12 @@ static void raise_profile_changed_event() { ZMK_EVENT_RAISE(ev); } +static void raise_profile_changed_event_callback(struct k_work *work) { + raise_profile_changed_event(); +} + +K_WORK_DEFINE(raise_profile_changed_event_work, raise_profile_changed_event_callback); + static bool active_profile_is_open() { return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY); } @@ -111,7 +117,7 @@ void set_profile_address(u8_t index, const bt_addr_le_t *addr) { raise_profile_changed_event(); } -bool active_profile_is_connected() { +bool zmk_ble_active_profile_is_connected() { struct bt_conn *conn; bt_addr_le_t *addr = zmk_ble_active_profile_addr(); if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) { @@ -163,9 +169,9 @@ int update_advertising() { struct bt_conn *conn; enum advertising_type desired_adv = ZMK_ADV_NONE; - if (active_profile_is_open() || !active_profile_is_connected()) { + if (active_profile_is_open() || !zmk_ble_active_profile_is_connected()) { desired_adv = ZMK_ADV_CONN; - } else if (!active_profile_is_connected()) { + } else if (!zmk_ble_active_profile_is_connected()) { desired_adv = ZMK_ADV_CONN; // Need to fix directed advertising for privacy centrals. See // https://github.com/zephyrproject-rtos/zephyr/pull/14984 char @@ -327,6 +333,10 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c struct settings_handler profiles_handler = {.name = "ble", .h_set = ble_profiles_handle_set}; #endif /* IS_ENABLED(CONFIG_SETTINGS) */ +static bool is_conn_active_profile(const struct bt_conn *conn) { + return bt_addr_le_cmp(bt_conn_get_dst(conn), &profiles[active_profile].peer) == 0; +} + static void connected(struct bt_conn *conn, u8_t err) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); @@ -352,6 +362,11 @@ static void connected(struct bt_conn *conn, u8_t err) { } update_advertising(); + + if (is_conn_active_profile(conn)) { + LOG_DBG("Active profile connected"); + raise_profile_changed_event(); + } } static void disconnected(struct bt_conn *conn, u8_t reason) { @@ -364,6 +379,11 @@ static void disconnected(struct bt_conn *conn, u8_t reason) { // We need to do this in a work callback, otherwise the advertising update will still see the // connection for a profile as active, and not start advertising yet. k_work_submit(&update_advertising_work); + + if (is_conn_active_profile(conn)) { + LOG_DBG("Active profile disconnected"); + k_work_submit(&raise_profile_changed_event_work); + } } static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { diff --git a/app/src/endpoints.c b/app/src/endpoints.c index 3acaba64..56204a47 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -4,11 +4,13 @@ * SPDX-License-Identifier: MIT */ +#include #include #include #include #include #include +#include #include #include @@ -19,8 +21,9 @@ enum endpoint { ENDPOINT_BLE, }; -static enum endpoint current_endpoint = - COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ENDPOINT_BLE), (ENDPOINT_USB)); +#define DEFAULT_ENDPOINT COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ENDPOINT_BLE), (ENDPOINT_USB)) + +static enum endpoint current_endpoint = DEFAULT_ENDPOINT; static int send_keypad_report() { struct zmk_hid_keypad_report *keypad_report = zmk_hid_get_keypad_report(); @@ -115,15 +118,22 @@ static bool is_ble_ready() { static enum endpoint get_selected_endpoint() { if (is_ble_ready()) { if (is_usb_ready()) { - LOG_DBG("Both endpoints ready. Selecting USB"); + LOG_DBG("Both endpoints are ready."); // TODO: add user setting to control this return ENDPOINT_USB; } + LOG_DBG("Only BLE is ready."); return ENDPOINT_BLE; } - return ENDPOINT_USB; + if (is_usb_ready()) { + LOG_DBG("Only USB is ready."); + return ENDPOINT_USB; + } + + LOG_DBG("No endpoints are ready."); + return DEFAULT_ENDPOINT; } static void disconnect_current_endpoint() { @@ -149,7 +159,9 @@ static int endpoint_listener(const struct zmk_event_header *eh) { } ZMK_LISTENER(endpoint_listener, endpoint_listener); -#if IS_ENABLED(CONFIG_USB) +#if IS_ENABLED(CONFIG_ZMK_USB) ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed); #endif -// TODO: add BLE state subscription \ No newline at end of file +#if IS_ENABLED(CONFIG_ZMK_BLE) +ZMK_SUBSCRIPTION(endpoint_listener, ble_active_profile_changed); +#endif \ No newline at end of file