summaryrefslogtreecommitdiff
path: root/app/src/endpoints.c
diff options
context:
space:
mode:
authorJoel Spadin <joelspadin@gmail.com>2020-10-11 17:03:21 -0500
committerJoel Spadin <joelspadin@gmail.com>2020-10-28 18:15:05 -0500
commit1d369ffa73ae63af821d012b1c2ab4a07a5dc9c7 (patch)
tree409067d51461b939cccbc4381d7185921444a545 /app/src/endpoints.c
parentdfb69d8727e01cb9ee855ac2d1cb7a6da1d6aa85 (diff)
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.
Diffstat (limited to 'app/src/endpoints.c')
-rw-r--r--app/src/endpoints.c140
1 files changed, 112 insertions, 28 deletions
diff --git a/app/src/endpoints.c b/app/src/endpoints.c
index 79d294e..4f56aa5 100644
--- a/app/src/endpoints.c
+++ b/app/src/endpoints.c
@@ -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);
-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");
+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);
}
-#endif /* CONFIG_ZMK_USB */
+ return err;
+ }
+#endif /* IS_ENABLED(CONFIG_ZMK_USB) */
-#ifdef CONFIG_ZMK_BLE
- err = zmk_hog_send_keypad_report(&keypad_report->body);
+#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);
}
-#endif /* CONFIG_ZMK_BLE */
+ return err;
+ }
+#endif /* IS_ENABLED(CONFIG_ZMK_BLE) */
- break;
- 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");
+ 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);
}
-#endif /* CONFIG_ZMK_USB */
+ return err;
+ }
+#endif /* IS_ENABLED(CONFIG_ZMK_USB) */
-#ifdef CONFIG_ZMK_BLE
- err = zmk_hog_send_consumer_report(&consumer_report->body);
+#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);
}
-#endif /* CONFIG_ZMK_BLE */
+ 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) {
- break;
+ LOG_DBG("usage page 0x%02X", usage_page);
+ switch (usage_page) {
+ case USAGE_KEYPAD:
+ return send_keypad_report();
+ case USAGE_CONSUMER:
+ 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 \ No newline at end of file