Browse Source

feat(endpoints): update on BLE profile change

Added zmk_ble_active_profile_is_connected() to allow code outside ble.c to check
the status of the active profile, and changed the ble_active_profile_changed
event to also notify when the active profile connects or disconnects.

Changed endpoint selection to to also update when the active profile changes,
connects, or disconnects.
xmkb
Joel Spadin 4 years ago
parent
commit
b538e60532
  1. 1
      app/include/zmk/ble.h
  2. 26
      app/src/ble.c
  3. 24
      app/src/endpoints.c

1
app/include/zmk/ble.h

@ -15,6 +15,7 @@ int zmk_ble_prof_prev();
int zmk_ble_prof_select(u8_t index); int zmk_ble_prof_select(u8_t index);
bt_addr_le_t *zmk_ble_active_profile_addr(); bt_addr_le_t *zmk_ble_active_profile_addr();
bool zmk_ble_active_profile_is_connected();
char *zmk_ble_active_profile_name(); char *zmk_ble_active_profile_name();
int zmk_ble_unpair_all(); int zmk_ble_unpair_all();

26
app/src/ble.c

@ -94,6 +94,12 @@ static void raise_profile_changed_event() {
ZMK_EVENT_RAISE(ev); 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() { static bool active_profile_is_open() {
return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY); 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(); raise_profile_changed_event();
} }
bool active_profile_is_connected() { bool zmk_ble_active_profile_is_connected() {
struct bt_conn *conn; struct bt_conn *conn;
bt_addr_le_t *addr = zmk_ble_active_profile_addr(); bt_addr_le_t *addr = zmk_ble_active_profile_addr();
if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) { if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
@ -163,9 +169,9 @@ int update_advertising() {
struct bt_conn *conn; struct bt_conn *conn;
enum advertising_type desired_adv = ZMK_ADV_NONE; 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; desired_adv = ZMK_ADV_CONN;
} else if (!active_profile_is_connected()) { } else if (!zmk_ble_active_profile_is_connected()) {
desired_adv = ZMK_ADV_CONN; desired_adv = ZMK_ADV_CONN;
// Need to fix directed advertising for privacy centrals. See // Need to fix directed advertising for privacy centrals. See
// https://github.com/zephyrproject-rtos/zephyr/pull/14984 char // 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}; struct settings_handler profiles_handler = {.name = "ble", .h_set = ble_profiles_handle_set};
#endif /* IS_ENABLED(CONFIG_SETTINGS) */ #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) { static void connected(struct bt_conn *conn, u8_t err) {
char addr[BT_ADDR_LE_STR_LEN]; char addr[BT_ADDR_LE_STR_LEN];
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));
@ -352,6 +362,11 @@ static void connected(struct bt_conn *conn, u8_t err) {
} }
update_advertising(); 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) { 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 // 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. // connection for a profile as active, and not start advertising yet.
k_work_submit(&update_advertising_work); 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) { static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) {

24
app/src/endpoints.c

@ -4,11 +4,13 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <zmk/ble.h>
#include <zmk/endpoints.h> #include <zmk/endpoints.h>
#include <zmk/hid.h> #include <zmk/hid.h>
#include <zmk/usb.h> #include <zmk/usb.h>
#include <zmk/hog.h> #include <zmk/hog.h>
#include <zmk/event-manager.h> #include <zmk/event-manager.h>
#include <zmk/events/ble-active-profile-changed.h>
#include <zmk/events/usb-conn-state-changed.h> #include <zmk/events/usb-conn-state-changed.h>
#include <logging/log.h> #include <logging/log.h>
@ -19,8 +21,9 @@ enum endpoint {
ENDPOINT_BLE, ENDPOINT_BLE,
}; };
static enum endpoint current_endpoint = #define DEFAULT_ENDPOINT COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ENDPOINT_BLE), (ENDPOINT_USB))
COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ENDPOINT_BLE), (ENDPOINT_USB));
static enum endpoint current_endpoint = DEFAULT_ENDPOINT;
static int send_keypad_report() { static int send_keypad_report() {
struct zmk_hid_keypad_report *keypad_report = zmk_hid_get_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() { static enum endpoint get_selected_endpoint() {
if (is_ble_ready()) { if (is_ble_ready()) {
if (is_usb_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 // TODO: add user setting to control this
return ENDPOINT_USB; return ENDPOINT_USB;
} }
LOG_DBG("Only BLE is ready.");
return ENDPOINT_BLE; 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() { 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); 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); ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed);
#endif #endif
// TODO: add BLE state subscription #if IS_ENABLED(CONFIG_ZMK_BLE)
ZMK_SUBSCRIPTION(endpoint_listener, ble_active_profile_changed);
#endif
Loading…
Cancel
Save