From 6f0c9eba9bb030cc8e4e6bc4c14ae2c9dd730348 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 6 Sep 2024 23:08:08 +0200 Subject: [PATCH] Introduce hid_open and hid_close events This allows to handle HID open/close reports at the same place as HID input reports (in the HID layer). This will be especially useful to manage HID gamepads, to avoid implementing one part in the HID layer and another part in the gamepad processor implementation. PR #5270 --- app/src/hid/hid_event.h | 10 ++++++++++ app/src/hid/hid_keyboard.c | 15 +++++++++++---- app/src/hid/hid_keyboard.h | 9 ++++++--- app/src/hid/hid_mouse.c | 15 +++++++++++---- app/src/hid/hid_mouse.h | 7 +++++-- app/src/uhid/keyboard_uhid.c | 8 ++++++-- app/src/uhid/mouse_uhid.c | 8 ++++++-- app/src/usb/aoa_hid.c | 31 +++++++++++++++---------------- app/src/usb/aoa_hid.h | 11 ++++------- app/src/usb/keyboard_aoa.c | 12 ++++++++---- app/src/usb/mouse_aoa.c | 12 ++++++++---- 11 files changed, 90 insertions(+), 48 deletions(-) diff --git a/app/src/hid/hid_event.h b/app/src/hid/hid_event.h index 9f9432e6..9171004e 100644 --- a/app/src/hid/hid_event.h +++ b/app/src/hid/hid_event.h @@ -13,4 +13,14 @@ struct sc_hid_input { uint8_t size; }; +struct sc_hid_open { + uint16_t hid_id; + const uint8_t *report_desc; // pointer to static memory + size_t report_desc_size; +}; + +struct sc_hid_close { + uint16_t hid_id; +}; + #endif diff --git a/app/src/hid/hid_keyboard.c b/app/src/hid/hid_keyboard.c index 9ab444f6..64dffe80 100644 --- a/app/src/hid/hid_keyboard.c +++ b/app/src/hid/hid_keyboard.c @@ -47,7 +47,7 @@ * * (change vid:pid' to your device's vendor ID and product ID). */ -const uint8_t SC_HID_KEYBOARD_REPORT_DESC[] = { +static const uint8_t SC_HID_KEYBOARD_REPORT_DESC[] = { // Usage Page (Generic Desktop) 0x05, 0x01, // Usage (Keyboard) @@ -121,9 +121,6 @@ const uint8_t SC_HID_KEYBOARD_REPORT_DESC[] = { 0xC0 }; -const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN = - sizeof(SC_HID_KEYBOARD_REPORT_DESC); - /** * A keyboard HID input report is 8 bytes long: * @@ -332,3 +329,13 @@ sc_hid_keyboard_generate_input_from_mods(struct sc_hid_input *hid_input, return true; } + +void sc_hid_keyboard_generate_open(struct sc_hid_open *hid_open) { + hid_open->hid_id = SC_HID_ID_KEYBOARD; + hid_open->report_desc = SC_HID_KEYBOARD_REPORT_DESC; + hid_open->report_desc_size = sizeof(SC_HID_KEYBOARD_REPORT_DESC); +} + +void sc_hid_keyboard_generate_close(struct sc_hid_close *hid_close) { + hid_close->hid_id = SC_HID_ID_KEYBOARD; +} diff --git a/app/src/hid/hid_keyboard.h b/app/src/hid/hid_keyboard.h index 01495cc2..cde1ac52 100644 --- a/app/src/hid/hid_keyboard.h +++ b/app/src/hid/hid_keyboard.h @@ -16,9 +16,6 @@ #define SC_HID_ID_KEYBOARD 1 -extern const uint8_t SC_HID_KEYBOARD_REPORT_DESC[]; -extern const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN; - /** * HID keyboard events are sequence-based, every time keyboard state changes * it sends an array of currently pressed keys, the host is responsible for @@ -38,6 +35,12 @@ struct sc_hid_keyboard { void sc_hid_keyboard_init(struct sc_hid_keyboard *hid); +void +sc_hid_keyboard_generate_open(struct sc_hid_open *hid_open); + +void +sc_hid_keyboard_generate_close(struct sc_hid_close *hid_close); + bool sc_hid_keyboard_generate_input_from_key(struct sc_hid_keyboard *hid, struct sc_hid_input *hid_input, diff --git a/app/src/hid/hid_mouse.c b/app/src/hid/hid_mouse.c index e26c248b..d1aae83a 100644 --- a/app/src/hid/hid_mouse.c +++ b/app/src/hid/hid_mouse.c @@ -14,7 +14,7 @@ * * ยง4 Generic Desktop Page (0x01) (p26) */ -const uint8_t SC_HID_MOUSE_REPORT_DESC[] = { +static const uint8_t SC_HID_MOUSE_REPORT_DESC[] = { // Usage Page (Generic Desktop) 0x05, 0x01, // Usage (Mouse) @@ -80,9 +80,6 @@ const uint8_t SC_HID_MOUSE_REPORT_DESC[] = { 0xC0, }; -const size_t SC_HID_MOUSE_REPORT_DESC_LEN = - sizeof(SC_HID_MOUSE_REPORT_DESC); - /** * A mouse HID input report is 4 bytes long: * @@ -190,3 +187,13 @@ sc_hid_mouse_generate_input_from_scroll(struct sc_hid_input *hid_input, data[3] = CLAMP(event->vscroll, -127, 127); // Horizontal scrolling ignored } + +void sc_hid_mouse_generate_open(struct sc_hid_open *hid_open) { + hid_open->hid_id = SC_HID_ID_MOUSE; + hid_open->report_desc = SC_HID_MOUSE_REPORT_DESC; + hid_open->report_desc_size = sizeof(SC_HID_MOUSE_REPORT_DESC); +} + +void sc_hid_mouse_generate_close(struct sc_hid_close *hid_close) { + hid_close->hid_id = SC_HID_ID_MOUSE; +} diff --git a/app/src/hid/hid_mouse.h b/app/src/hid/hid_mouse.h index 3b647fb3..a9a54718 100644 --- a/app/src/hid/hid_mouse.h +++ b/app/src/hid/hid_mouse.h @@ -10,8 +10,11 @@ #define SC_HID_ID_MOUSE 2 -extern const uint8_t SC_HID_MOUSE_REPORT_DESC[]; -extern const size_t SC_HID_MOUSE_REPORT_DESC_LEN; +void +sc_hid_mouse_generate_open(struct sc_hid_open *hid_open); + +void +sc_hid_mouse_generate_close(struct sc_hid_close *hid_close); void sc_hid_mouse_generate_input_from_motion(struct sc_hid_input *hid_input, diff --git a/app/src/uhid/keyboard_uhid.c b/app/src/uhid/keyboard_uhid.c index c91f9539..e7a0e33a 100644 --- a/app/src/uhid/keyboard_uhid.c +++ b/app/src/uhid/keyboard_uhid.c @@ -145,11 +145,15 @@ sc_keyboard_uhid_init(struct sc_keyboard_uhid *kb, kb->uhid_receiver.ops = &uhid_receiver_ops; sc_uhid_devices_add_receiver(uhid_devices, &kb->uhid_receiver); + struct sc_hid_open hid_open; + sc_hid_keyboard_generate_open(&hid_open); + assert(hid_open.hid_id == SC_HID_ID_KEYBOARD); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE; msg.uhid_create.id = SC_HID_ID_KEYBOARD; - msg.uhid_create.report_desc = SC_HID_KEYBOARD_REPORT_DESC; - msg.uhid_create.report_desc_size = SC_HID_KEYBOARD_REPORT_DESC_LEN; + msg.uhid_create.report_desc = hid_open.report_desc; + msg.uhid_create.report_desc_size = hid_open.report_desc_size; if (!sc_controller_push_msg(controller, &msg)) { LOGE("Could not send UHID_CREATE message (keyboard)"); return false; diff --git a/app/src/uhid/mouse_uhid.c b/app/src/uhid/mouse_uhid.c index e1daa9e5..c379f3ad 100644 --- a/app/src/uhid/mouse_uhid.c +++ b/app/src/uhid/mouse_uhid.c @@ -74,11 +74,15 @@ sc_mouse_uhid_init(struct sc_mouse_uhid *mouse, mouse->mouse_processor.relative_mode = true; + struct sc_hid_open hid_open; + sc_hid_mouse_generate_open(&hid_open); + assert(hid_open.hid_id == SC_HID_ID_MOUSE); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE; msg.uhid_create.id = SC_HID_ID_MOUSE; - msg.uhid_create.report_desc = SC_HID_MOUSE_REPORT_DESC; - msg.uhid_create.report_desc_size = SC_HID_MOUSE_REPORT_DESC_LEN; + msg.uhid_create.report_desc = hid_open.report_desc; + msg.uhid_create.report_desc_size = hid_open.report_desc_size; if (!sc_controller_push_msg(controller, &msg)) { LOGE("Could not send UHID_CREATE message (mouse)"); return false; diff --git a/app/src/usb/aoa_hid.c b/app/src/usb/aoa_hid.c index f9bcf8e5..c44c80f6 100644 --- a/app/src/usb/aoa_hid.c +++ b/app/src/usb/aoa_hid.c @@ -230,8 +230,7 @@ sc_aoa_push_input_with_ack_to_wait(struct sc_aoa *aoa, } bool -sc_aoa_push_open(struct sc_aoa *aoa, uint16_t accessory_id, - const uint8_t *report_desc, uint16_t report_desc_size) { +sc_aoa_push_open(struct sc_aoa *aoa, const struct sc_hid_open *hid_open) { // TODO log verbose sc_mutex_lock(&aoa->mutex); @@ -247,9 +246,7 @@ sc_aoa_push_open(struct sc_aoa *aoa, uint16_t accessory_id, } aoa_event->type = SC_AOA_EVENT_TYPE_OPEN; - aoa_event->open.hid_id = accessory_id; - aoa_event->open.report_desc = report_desc; - aoa_event->open.report_desc_size = report_desc_size; + aoa_event->open.hid = *hid_open; if (was_empty) { sc_cond_signal(&aoa->event_cond); @@ -261,7 +258,7 @@ sc_aoa_push_open(struct sc_aoa *aoa, uint16_t accessory_id, } bool -sc_aoa_push_close(struct sc_aoa *aoa, uint16_t accessory_id) { +sc_aoa_push_close(struct sc_aoa *aoa, const struct sc_hid_close *hid_close) { // TODO log verbose sc_mutex_lock(&aoa->mutex); @@ -277,7 +274,7 @@ sc_aoa_push_close(struct sc_aoa *aoa, uint16_t accessory_id) { } aoa_event->type = SC_AOA_EVENT_TYPE_CLOSE; - aoa_event->close.hid_id = accessory_id; + aoa_event->close.hid = *hid_close; if (was_empty) { sc_cond_signal(&aoa->event_cond); @@ -316,29 +313,31 @@ sc_aoa_process_event(struct sc_aoa *aoa, struct sc_aoa_event *event) { } } - bool ok = sc_aoa_send_hid_event(aoa, &event->input.hid); + struct sc_hid_input *hid_input = &event->input.hid; + bool ok = sc_aoa_send_hid_event(aoa, hid_input); if (!ok) { LOGW("Could not send HID event to USB device: %" PRIu16, - event->input.hid.hid_id); + hid_input->hid_id); } break; } case SC_AOA_EVENT_TYPE_OPEN: { - bool ok = sc_aoa_setup_hid(aoa, event->open.hid_id, - event->open.report_desc, - event->open.report_desc_size); + struct sc_hid_open *hid_open = &event->open.hid; + bool ok = sc_aoa_setup_hid(aoa, hid_open->hid_id, + hid_open->report_desc, + hid_open->report_desc_size); if (!ok) { - LOGW("Could not open AOA device: %" PRIu16, event->open.hid_id); + LOGW("Could not open AOA device: %" PRIu16, hid_open->hid_id); } break; } case SC_AOA_EVENT_TYPE_CLOSE: { - bool ok = sc_aoa_unregister_hid(aoa, event->close.hid_id); + struct sc_hid_close *hid_close = &event->close.hid; + bool ok = sc_aoa_unregister_hid(aoa, hid_close->hid_id); if (!ok) { - LOGW("Could not close AOA device: %" PRIu16, - event->close.hid_id); + LOGW("Could not close AOA device: %" PRIu16, hid_close->hid_id); } break; diff --git a/app/src/usb/aoa_hid.h b/app/src/usb/aoa_hid.h index 63a9f4de..010b3742 100644 --- a/app/src/usb/aoa_hid.h +++ b/app/src/usb/aoa_hid.h @@ -23,12 +23,10 @@ struct sc_aoa_event { enum sc_aoa_event_type type; union { struct { - uint16_t hid_id; - const uint8_t *report_desc; // pointer to static memory - uint16_t report_desc_size; + struct sc_hid_open hid; } open; struct { - uint16_t hid_id; + struct sc_hid_close hid; } close; struct { struct sc_hid_input hid; @@ -75,11 +73,10 @@ sc_aoa_join(struct sc_aoa *aoa); // report_desc must be a pointer to static memory, accessed at any time from // another thread bool -sc_aoa_push_open(struct sc_aoa *aoa, uint16_t accessory_id, - const uint8_t *report_desc, uint16_t report_desc_size); +sc_aoa_push_open(struct sc_aoa *aoa, const struct sc_hid_open *hid_open); bool -sc_aoa_push_close(struct sc_aoa *aoa, uint16_t accessory_id); +sc_aoa_push_close(struct sc_aoa *aoa, const struct sc_hid_close *hid_close); bool sc_aoa_push_input_with_ack_to_wait(struct sc_aoa *aoa, diff --git a/app/src/usb/keyboard_aoa.c b/app/src/usb/keyboard_aoa.c index 33924dbf..6c4aaed7 100644 --- a/app/src/usb/keyboard_aoa.c +++ b/app/src/usb/keyboard_aoa.c @@ -66,9 +66,10 @@ bool sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) { kb->aoa = aoa; - bool ok = sc_aoa_push_open(aoa, SC_HID_ID_KEYBOARD, - SC_HID_KEYBOARD_REPORT_DESC, - SC_HID_KEYBOARD_REPORT_DESC_LEN); + struct sc_hid_open hid_open; + sc_hid_keyboard_generate_open(&hid_open); + + bool ok = sc_aoa_push_open(aoa, &hid_open); if (!ok) { LOGW("Could not push AOA keyboard open request"); return false; @@ -97,7 +98,10 @@ sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) { void sc_keyboard_aoa_destroy(struct sc_keyboard_aoa *kb) { - bool ok = sc_aoa_push_close(kb->aoa, SC_HID_ID_KEYBOARD); + struct sc_hid_close hid_close; + sc_hid_keyboard_generate_close(&hid_close); + + bool ok = sc_aoa_push_close(kb->aoa, &hid_close); if (!ok) { LOGW("Could not push AOA keyboard close request"); } diff --git a/app/src/usb/mouse_aoa.c b/app/src/usb/mouse_aoa.c index 03d28610..3c4e3693 100644 --- a/app/src/usb/mouse_aoa.c +++ b/app/src/usb/mouse_aoa.c @@ -52,9 +52,10 @@ bool sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) { mouse->aoa = aoa; - bool ok = sc_aoa_push_open(aoa, SC_HID_ID_MOUSE, - SC_HID_MOUSE_REPORT_DESC, - SC_HID_MOUSE_REPORT_DESC_LEN); + struct sc_hid_open hid_open; + sc_hid_mouse_generate_open(&hid_open); + + bool ok = sc_aoa_push_open(aoa, &hid_open); if (!ok) { LOGW("Could not push AOA mouse open request"); return false; @@ -77,7 +78,10 @@ sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) { void sc_mouse_aoa_destroy(struct sc_mouse_aoa *mouse) { - bool ok = sc_aoa_push_close(mouse->aoa, SC_HID_ID_MOUSE); + struct sc_hid_close hid_close; + sc_hid_mouse_generate_close(&hid_close); + + bool ok = sc_aoa_push_close(mouse->aoa, &hid_close); if (!ok) { LOGW("Could not push AOA mouse close request"); }