forked from kofal.net/zmk
feat: only send HID reports to one endpoint
Added some utility functions and an event for tracking the state of the USB connection. Updated endpoints.c to select a single endpoint to send HID reports to based on the status of the USB and BLE connections. Partially fixes #206. Future commits will add a user setting to control which endpoint is used if both USB and BLE are ready.
This commit is contained in:
@@ -8,54 +8,138 @@
|
||||
#include <zmk/hid.h>
|
||||
#include <zmk/usb.h>
|
||||
#include <zmk/hog.h>
|
||||
#include <zmk/event-manager.h>
|
||||
#include <zmk/events/usb-conn-state-changed.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
enum endpoint {
|
||||
ENDPOINT_USB,
|
||||
ENDPOINT_BLE,
|
||||
};
|
||||
|
||||
static enum endpoint current_endpoint =
|
||||
COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ENDPOINT_BLE), (ENDPOINT_USB));
|
||||
|
||||
static int send_keypad_report() {
|
||||
struct zmk_hid_keypad_report *keypad_report = zmk_hid_get_keypad_report();
|
||||
|
||||
switch (current_endpoint) {
|
||||
#if IS_ENABLED(CONFIG_ZMK_USB)
|
||||
case ENDPOINT_USB: {
|
||||
int err = zmk_usb_hid_send_report((u8_t *)keypad_report, sizeof(*keypad_report));
|
||||
if (err) {
|
||||
LOG_ERR("FAILED TO SEND OVER USB: %d", err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_ZMK_USB) */
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BLE)
|
||||
case ENDPOINT_BLE: {
|
||||
int err = zmk_hog_send_keypad_report(&keypad_report->body);
|
||||
if (err) {
|
||||
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_ZMK_BLE) */
|
||||
|
||||
default:
|
||||
LOG_ERR("Unsupported endpoint %d", current_endpoint);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
static int send_consumer_report() {
|
||||
struct zmk_hid_consumer_report *consumer_report = zmk_hid_get_consumer_report();
|
||||
|
||||
switch (current_endpoint) {
|
||||
#if IS_ENABLED(CONFIG_ZMK_USB)
|
||||
case ENDPOINT_USB: {
|
||||
int err = zmk_usb_hid_send_report((u8_t *)consumer_report, sizeof(*consumer_report));
|
||||
if (err) {
|
||||
LOG_ERR("FAILED TO SEND OVER USB: %d", err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_ZMK_USB) */
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BLE)
|
||||
case ENDPOINT_BLE: {
|
||||
int err = zmk_hog_send_consumer_report(&consumer_report->body);
|
||||
if (err) {
|
||||
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_ZMK_BLE) */
|
||||
|
||||
default:
|
||||
LOG_ERR("Unsupported endpoint %d", current_endpoint);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
int zmk_endpoints_send_report(u8_t usage_page) {
|
||||
int err;
|
||||
struct zmk_hid_keypad_report *keypad_report;
|
||||
struct zmk_hid_consumer_report *consumer_report;
|
||||
|
||||
LOG_DBG("usage page 0x%02X", usage_page);
|
||||
switch (usage_page) {
|
||||
case USAGE_KEYPAD:
|
||||
keypad_report = zmk_hid_get_keypad_report();
|
||||
#ifdef CONFIG_ZMK_USB
|
||||
if (zmk_usb_hid_send_report((u8_t *)keypad_report, sizeof(struct zmk_hid_keypad_report)) !=
|
||||
0) {
|
||||
LOG_DBG("USB Send Failed");
|
||||
}
|
||||
#endif /* CONFIG_ZMK_USB */
|
||||
|
||||
#ifdef CONFIG_ZMK_BLE
|
||||
err = zmk_hog_send_keypad_report(&keypad_report->body);
|
||||
if (err) {
|
||||
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
||||
}
|
||||
#endif /* CONFIG_ZMK_BLE */
|
||||
|
||||
break;
|
||||
return send_keypad_report();
|
||||
case USAGE_CONSUMER:
|
||||
consumer_report = zmk_hid_get_consumer_report();
|
||||
#ifdef CONFIG_ZMK_USB
|
||||
if (zmk_usb_hid_send_report((u8_t *)consumer_report,
|
||||
sizeof(struct zmk_hid_consumer_report)) != 0) {
|
||||
LOG_DBG("USB Send Failed");
|
||||
}
|
||||
#endif /* CONFIG_ZMK_USB */
|
||||
|
||||
#ifdef CONFIG_ZMK_BLE
|
||||
err = zmk_hog_send_consumer_report(&consumer_report->body);
|
||||
if (err) {
|
||||
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
||||
}
|
||||
#endif /* CONFIG_ZMK_BLE */
|
||||
|
||||
break;
|
||||
return send_consumer_report();
|
||||
default:
|
||||
LOG_ERR("Unsupported usage page %d", usage_page);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_usb_ready() {
|
||||
#if IS_ENABLED(CONFIG_ZMK_USB)
|
||||
return zmk_usb_is_hid_ready();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool is_ble_ready() {
|
||||
#if IS_ENABLED(CONFIG_ZMK_BLE)
|
||||
return zmk_ble_active_profile_is_connected();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static enum endpoint get_selected_endpoint() {
|
||||
if (is_ble_ready()) {
|
||||
if (is_usb_ready()) {
|
||||
LOG_DBG("Both endpoints ready. Selecting USB");
|
||||
// TODO: add user setting to control this
|
||||
return ENDPOINT_USB;
|
||||
}
|
||||
|
||||
return ENDPOINT_BLE;
|
||||
}
|
||||
|
||||
return ENDPOINT_USB;
|
||||
}
|
||||
|
||||
static int endpoint_listener(const struct zmk_event_header *eh) {
|
||||
enum endpoint new_endpoint = get_selected_endpoint();
|
||||
|
||||
if (new_endpoint != current_endpoint) {
|
||||
// TODO: send null report on previous endpoint
|
||||
current_endpoint = new_endpoint;
|
||||
LOG_INF("Endpoint changed: %d", current_endpoint);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZMK_LISTENER(endpoint_listener, endpoint_listener);
|
||||
#if IS_ENABLED(CONFIG_USB)
|
||||
ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed);
|
||||
#endif
|
||||
// TODO: add BLE state subscription
|
||||
Reference in New Issue
Block a user