Skip to content

Commit

Permalink
Merge pull request #269 from joelspadin/endpoint-selection
Browse files Browse the repository at this point in the history
feat: only send HID reports to one endpoint
  • Loading branch information
petejohanson committed Oct 31, 2020
2 parents 3c958e6 + 821f054 commit 2d31e1d
Show file tree
Hide file tree
Showing 19 changed files with 451 additions and 41 deletions.
2 changes: 2 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ target_sources(app PRIVATE src/events/keycode_state_changed.c)
target_sources(app PRIVATE src/events/modifiers_state_changed.c)
target_sources(app PRIVATE src/events/sensor_event.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/ble_active_profile_changed.c)
target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c)
if (NOT CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
target_sources(app PRIVATE src/behaviors/behavior_key_press.c)
target_sources(app PRIVATE src/behaviors/behavior_reset.c)
target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c)
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_outputs.c)
target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_transparent.c)
target_sources(app PRIVATE src/behaviors/behavior_none.c)
Expand Down
1 change: 1 addition & 0 deletions app/dts/behaviors.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
#include <behaviors/rgb_underglow.dtsi>
#include <behaviors/bluetooth.dtsi>
#include <behaviors/ext_power.dtsi>
#include <behaviors/outputs.dtsi>
9 changes: 9 additions & 0 deletions app/dts/behaviors/outputs.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/ {
behaviors {
out: behavior_outputs {
compatible = "zmk,behavior-outputs";
label = "OUTPUTS";
#binding-cells = <1>;
};
};
};
10 changes: 10 additions & 0 deletions app/dts/bindings/behaviors/zmk,behavior-outputs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Copyright (c) 2020, The ZMK Contributors
# SPDX-License-Identifier: MIT
#

description: Output Selection Behavior

compatible: "zmk,behavior-outputs"

include: one_param.yaml
9 changes: 9 additions & 0 deletions app/include/dt-bindings/zmk/outputs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#define OUT_TOG 0
#define OUT_USB 1
#define OUT_BLE 2
1 change: 1 addition & 0 deletions app/include/zmk/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
8 changes: 8 additions & 0 deletions app/include/zmk/endpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@
#include <zmk/keys.h>
#include <zmk/hid.h>

enum zmk_endpoint {
ZMK_ENDPOINT_USB,
ZMK_ENDPOINT_BLE,
};

int zmk_endpoints_select(enum zmk_endpoint endpoint);
int zmk_endpoints_toggle();

int zmk_endpoints_send_report(u8_t usage_report);
20 changes: 20 additions & 0 deletions app/include/zmk/events/usb-conn-state-changed.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <zephyr.h>
#include <usb/usb_device.h>

#include <zmk/event-manager.h>
#include <zmk/usb.h>

struct usb_conn_state_changed {
struct zmk_event_header header;
enum zmk_usb_conn_state conn_state;
};

ZMK_EVENT_DECLARE(usb_conn_state_changed);
2 changes: 2 additions & 0 deletions app/include/zmk/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,11 @@ int zmk_hid_register_mods(zmk_mod_flags modifiers);
int zmk_hid_unregister_mods(zmk_mod_flags modifiers);
int zmk_hid_keypad_press(zmk_key key);
int zmk_hid_keypad_release(zmk_key key);
void zmk_hid_keypad_clear();

int zmk_hid_consumer_press(zmk_key key);
int zmk_hid_consumer_release(zmk_key key);
void zmk_hid_consumer_clear();

struct zmk_hid_keypad_report *zmk_hid_get_keypad_report();
struct zmk_hid_consumer_report *zmk_hid_get_consumer_report();
12 changes: 11 additions & 1 deletion app/include/zmk/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,18 @@
#include <zmk/keys.h>
#include <zmk/hid.h>

enum zmk_usb_conn_state {
ZMK_USB_CONN_NONE,
ZMK_USB_CONN_POWERED,
ZMK_USB_CONN_HID,
};

enum usb_dc_status_code zmk_usb_get_status();
enum zmk_usb_conn_state zmk_usb_get_conn_state();

static inline bool zmk_usb_is_powered() { return zmk_usb_get_conn_state() != ZMK_USB_CONN_NONE; }
static inline bool zmk_usb_is_hid_ready() { return zmk_usb_get_conn_state() == ZMK_USB_CONN_HID; }

#ifdef CONFIG_ZMK_USB
int zmk_usb_hid_send_report(u8_t *report, size_t len);
int zmk_usb_hid_send_report(const u8_t *report, size_t len);
#endif /* CONFIG_ZMK_USB */
44 changes: 44 additions & 0 deletions app/src/behaviors/behavior_outputs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#define DT_DRV_COMPAT zmk_behavior_outputs

#include <device.h>
#include <devicetree.h>
#include <drivers/behavior.h>

#include <dt-bindings/zmk/outputs.h>

#include <zmk/behavior.h>
#include <zmk/endpoints.h>

#include <logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
switch (binding->param1) {
case OUT_TOG:
return zmk_endpoints_toggle();
case OUT_USB:
return zmk_endpoints_select(ZMK_ENDPOINT_USB);
case OUT_BLE:
return zmk_endpoints_select(ZMK_ENDPOINT_BLE);
default:
LOG_ERR("Unknown output command: %d", binding->param1);
}

return -ENOTSUP;
}

static int behavior_out_init(struct device *dev) { return 0; }

static const struct behavior_driver_api behavior_outputs_driver_api = {
.binding_pressed = on_keymap_binding_pressed,
};

DEVICE_AND_API_INIT(behavior_out, DT_INST_LABEL(0), behavior_out_init, NULL, NULL, APPLICATION,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_outputs_driver_api);
26 changes: 23 additions & 3 deletions app/src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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)) {
Expand Down Expand Up @@ -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()) {
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
Expand Down Expand Up @@ -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));
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down

0 comments on commit 2d31e1d

Please sign in to comment.