Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: only send HID reports to one endpoint #269

Merged
merged 7 commits into from
Oct 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -165,9 +165,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