From f2d62031561b4d1660c2c5bb3910e7a723d317f7 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 25 Jan 2024 20:32:37 +0100 Subject: [PATCH] Extract HID events struct An event contained several fields: - the accessory id - the HID event data - a field ack_to_wait specific to the AOA implementation. Extract the HID event part to prepare the factorization of HID event creation. PR #4473 --- app/src/hid/hid_event.h | 15 +++++++++++++++ app/src/usb/aoa_hid.c | 34 ++++++++++++++++++++++------------ app/src/usb/aoa_hid.h | 22 ++++++++++++++++------ app/src/usb/hid_keyboard.c | 21 ++++++++++----------- app/src/usb/hid_mouse.c | 11 ++++++----- 5 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 app/src/hid/hid_event.h diff --git a/app/src/hid/hid_event.h b/app/src/hid/hid_event.h new file mode 100644 index 00000000..e17f8569 --- /dev/null +++ b/app/src/hid/hid_event.h @@ -0,0 +1,15 @@ +#ifndef SC_HID_EVENT_H +#define SC_HID_EVENT_H + +#include "common.h" + +#include + +#define SC_HID_MAX_SIZE 8 + +struct sc_hid_event { + uint8_t data[SC_HID_MAX_SIZE]; + uint8_t size; +}; + +#endif diff --git a/app/src/usb/aoa_hid.c b/app/src/usb/aoa_hid.c index 5db7ab94..d6b418a0 100644 --- a/app/src/usb/aoa_hid.c +++ b/app/src/usb/aoa_hid.c @@ -14,10 +14,10 @@ #define DEFAULT_TIMEOUT 1000 -#define SC_HID_EVENT_QUEUE_MAX 64 +#define SC_AOA_EVENT_QUEUE_MAX 64 static void -sc_hid_event_log(const struct sc_hid_event *event) { +sc_hid_event_log(uint16_t accessory_id, const struct sc_hid_event *event) { // HID Event: [00] FF FF FF FF... assert(event->size); unsigned buffer_size = event->size * 3 + 1; @@ -29,7 +29,7 @@ sc_hid_event_log(const struct sc_hid_event *event) { for (unsigned i = 0; i < event->size; ++i) { snprintf(buffer + i * 3, 4, " %02x", event->data[i]); } - LOGV("HID Event: [%d]%s", event->accessory_id, buffer); + LOGV("HID Event: [%d]%s", accessory_id, buffer); free(buffer); } @@ -38,7 +38,7 @@ sc_aoa_init(struct sc_aoa *aoa, struct sc_usb *usb, struct sc_acksync *acksync) { sc_vecdeque_init(&aoa->queue); - if (!sc_vecdeque_reserve(&aoa->queue, SC_HID_EVENT_QUEUE_MAX)) { + if (!sc_vecdeque_reserve(&aoa->queue, SC_AOA_EVENT_QUEUE_MAX)) { return false; } @@ -150,13 +150,14 @@ sc_aoa_setup_hid(struct sc_aoa *aoa, uint16_t accessory_id, } static bool -sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) { +sc_aoa_send_hid_event(struct sc_aoa *aoa, uint16_t accessory_id, + const struct sc_hid_event *event) { uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR; uint8_t request = ACCESSORY_SEND_HID_EVENT; // // value (arg0): accessory assigned ID for the HID device // index (arg1): 0 (unused) - uint16_t value = event->accessory_id; + uint16_t value = accessory_id; uint16_t index = 0; unsigned char *data = (uint8_t *) event->data; // discard const uint16_t length = event->size; @@ -173,7 +174,7 @@ sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) { } bool -sc_aoa_unregister_hid(struct sc_aoa *aoa, const uint16_t accessory_id) { +sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id) { uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR; uint8_t request = ACCESSORY_UNREGISTER_HID; // @@ -196,16 +197,25 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, const uint16_t accessory_id) { } bool -sc_aoa_push_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) { +sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa, + uint16_t accessory_id, + const struct sc_hid_event *event, + uint64_t ack_to_wait) { if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) { - sc_hid_event_log(event); + sc_hid_event_log(accessory_id, event); } sc_mutex_lock(&aoa->mutex); bool full = sc_vecdeque_is_full(&aoa->queue); if (!full) { bool was_empty = sc_vecdeque_is_empty(&aoa->queue); - sc_vecdeque_push_noresize(&aoa->queue, *event); + + struct sc_aoa_event *aoa_event = + sc_vecdeque_push_hole_noresize(&aoa->queue); + aoa_event->hid = *event; + aoa_event->accessory_id = accessory_id; + aoa_event->ack_to_wait = ack_to_wait; + if (was_empty) { sc_cond_signal(&aoa->event_cond); } @@ -233,7 +243,7 @@ run_aoa_thread(void *data) { } assert(!sc_vecdeque_is_empty(&aoa->queue)); - struct sc_hid_event event = sc_vecdeque_pop(&aoa->queue); + struct sc_aoa_event event = sc_vecdeque_pop(&aoa->queue); uint64_t ack_to_wait = event.ack_to_wait; sc_mutex_unlock(&aoa->mutex); @@ -259,7 +269,7 @@ run_aoa_thread(void *data) { } } - bool ok = sc_aoa_send_hid_event(aoa, &event); + bool ok = sc_aoa_send_hid_event(aoa, event.accessory_id, &event.hid); if (!ok) { LOGW("Could not send HID event to USB device"); } diff --git a/app/src/usb/aoa_hid.h b/app/src/usb/aoa_hid.h index 2cbd1a23..33a1f136 100644 --- a/app/src/usb/aoa_hid.h +++ b/app/src/usb/aoa_hid.h @@ -6,6 +6,7 @@ #include +#include "hid/hid_event.h" #include "usb.h" #include "util/acksync.h" #include "util/thread.h" @@ -14,14 +15,13 @@ #define SC_HID_MAX_SIZE 8 -struct sc_hid_event { +struct sc_aoa_event { + struct sc_hid_event hid; uint16_t accessory_id; - uint8_t data[SC_HID_MAX_SIZE]; - uint8_t size; uint64_t ack_to_wait; }; -struct sc_hid_event_queue SC_VECDEQUE(struct sc_hid_event); +struct sc_aoa_event_queue SC_VECDEQUE(struct sc_aoa_event); struct sc_aoa { struct sc_usb *usb; @@ -29,7 +29,7 @@ struct sc_aoa { sc_mutex mutex; sc_cond event_cond; bool stopped; - struct sc_hid_event_queue queue; + struct sc_aoa_event_queue queue; struct sc_acksync *acksync; }; @@ -57,6 +57,16 @@ bool sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id); bool -sc_aoa_push_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event); +sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa, + uint16_t accessory_id, + const struct sc_hid_event *event, + uint64_t ack_to_wait); + +static inline bool +sc_aoa_push_hid_event(struct sc_aoa *aoa, uint16_t accessory_id, + const struct sc_hid_event *event) { + return sc_aoa_push_hid_event_with_ack_to_wait(aoa, accessory_id, event, + SC_SEQUENCE_INVALID); +} #endif diff --git a/app/src/usb/hid_keyboard.c b/app/src/usb/hid_keyboard.c index dcf56313..9b87a27a 100644 --- a/app/src/usb/hid_keyboard.c +++ b/app/src/usb/hid_keyboard.c @@ -233,9 +233,7 @@ sdl_keymod_to_hid_modifiers(uint16_t mod) { static void sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) { - hid_event->accessory_id = HID_KEYBOARD_ACCESSORY_ID; hid_event->size = HID_KEYBOARD_EVENT_SIZE; - hid_event->ack_to_wait = SC_SEQUENCE_INVALID; uint8_t *data = hid_event->data; @@ -329,7 +327,8 @@ push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t mods_state) { ++i; } - if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) { + if (!sc_aoa_push_hid_event(kb->aoa, HID_KEYBOARD_ACCESSORY_ID, + &hid_event)) { LOGW("Could not request HID event (mod lock state)"); return false; } @@ -362,15 +361,15 @@ sc_key_processor_process_key(struct sc_key_processor *kp, } } - if (ack_to_wait) { - // Ctrl+v is pressed, so clipboard synchronization has been - // requested. Wait until clipboard synchronization is acknowledged - // by the server, otherwise it could paste the old clipboard - // content. - hid_event.ack_to_wait = ack_to_wait; - } + // If ack_to_wait is != SC_SEQUENCE_INVALID, then Ctrl+v is pressed, so + // clipboard synchronization has been requested. Wait until clipboard + // synchronization is acknowledged by the server, otherwise it could + // paste the old clipboard content. - if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) { + if (!sc_aoa_push_hid_event_with_ack_to_wait(kb->aoa, + HID_KEYBOARD_ACCESSORY_ID, + &hid_event, + ack_to_wait)) { LOGW("Could not request HID event (key)"); } } diff --git a/app/src/usb/hid_mouse.c b/app/src/usb/hid_mouse.c index a47534c1..de961265 100644 --- a/app/src/usb/hid_mouse.c +++ b/app/src/usb/hid_mouse.c @@ -133,9 +133,7 @@ static const unsigned char mouse_report_desc[] = { static void sc_hid_mouse_event_init(struct sc_hid_event *hid_event) { - hid_event->accessory_id = HID_MOUSE_ACCESSORY_ID; hid_event->size = HID_MOUSE_EVENT_SIZE; - hid_event->ack_to_wait = SC_SEQUENCE_INVALID; // Leave hid_event->data uninitialized, it will be fully initialized by // callers } @@ -175,7 +173,8 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp, data[2] = CLAMP(event->yrel, -127, 127); data[3] = 0; // wheel coordinates only used for scrolling - if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) { + if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID, + &hid_event)) { LOGW("Could not request HID event (mouse motion)"); } } @@ -194,7 +193,8 @@ sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp, data[2] = 0; // no y motion data[3] = 0; // wheel coordinates only used for scrolling - if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) { + if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID, + &hid_event)) { LOGW("Could not request HID event (mouse click)"); } } @@ -216,7 +216,8 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp, data[3] = CLAMP(event->vscroll, -127, 127); // Horizontal scrolling ignored - if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) { + if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID, + &hid_event)) { LOGW("Could not request HID event (mouse scroll)"); } }