Move HID ids to common HID code

The HID ids (accessory ids or UHID ids) were defined by the keyboard and
mouse implementations.

Instead, define them in the common HID part, and make that id part of
the sc_hid_event.

This prepares the introduction of gamepad support, which will handle
several gamepads (and ids) in the common HID gamepad code.
This commit is contained in:
Romain Vimont 2024-09-06 23:08:08 +02:00
parent ced31229c8
commit 9c5876cc15
11 changed files with 30 additions and 42 deletions

View File

@ -8,6 +8,7 @@
#define SC_HID_MAX_SIZE 8 #define SC_HID_MAX_SIZE 8
struct sc_hid_event { struct sc_hid_event {
uint16_t hid_id;
uint8_t data[SC_HID_MAX_SIZE]; uint8_t data[SC_HID_MAX_SIZE];
uint8_t size; uint8_t size;
}; };

View File

@ -200,6 +200,7 @@ const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN =
static void static void
sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) { sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
hid_event->hid_id = SC_HID_ID_KEYBOARD;
hid_event->size = SC_HID_KEYBOARD_EVENT_SIZE; hid_event->size = SC_HID_KEYBOARD_EVENT_SIZE;
uint8_t *data = hid_event->data; uint8_t *data = hid_event->data;

View File

@ -14,6 +14,8 @@
// 0x65 is Application, typically AT-101 Keyboard ends here. // 0x65 is Application, typically AT-101 Keyboard ends here.
#define SC_HID_KEYBOARD_KEYS 0x66 #define SC_HID_KEYBOARD_KEYS 0x66
#define SC_HID_ID_KEYBOARD 1
extern const uint8_t SC_HID_KEYBOARD_REPORT_DESC[]; extern const uint8_t SC_HID_KEYBOARD_REPORT_DESC[];
extern const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN; extern const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN;

View File

@ -126,6 +126,7 @@ const size_t SC_HID_MOUSE_REPORT_DESC_LEN =
static void static void
sc_hid_mouse_event_init(struct sc_hid_event *hid_event) { sc_hid_mouse_event_init(struct sc_hid_event *hid_event) {
hid_event->hid_id = SC_HID_ID_MOUSE;
hid_event->size = SC_HID_MOUSE_EVENT_SIZE; hid_event->size = SC_HID_MOUSE_EVENT_SIZE;
// Leave hid_event->data uninitialized, it will be fully initialized by // Leave hid_event->data uninitialized, it will be fully initialized by
// callers // callers

View File

@ -8,6 +8,8 @@
#include "hid/hid_event.h" #include "hid/hid_event.h"
#include "input_events.h" #include "input_events.h"
#define SC_HID_ID_MOUSE 2
extern const uint8_t SC_HID_MOUSE_REPORT_DESC[]; extern const uint8_t SC_HID_MOUSE_REPORT_DESC[];
extern const size_t SC_HID_MOUSE_REPORT_DESC_LEN; extern const size_t SC_HID_MOUSE_REPORT_DESC_LEN;

View File

@ -9,14 +9,12 @@
#define DOWNCAST_RECEIVER(UR) \ #define DOWNCAST_RECEIVER(UR) \
container_of(UR, struct sc_keyboard_uhid, uhid_receiver) container_of(UR, struct sc_keyboard_uhid, uhid_receiver)
#define UHID_KEYBOARD_ID 1
static void static void
sc_keyboard_uhid_send_input(struct sc_keyboard_uhid *kb, sc_keyboard_uhid_send_input(struct sc_keyboard_uhid *kb,
const struct sc_hid_event *event) { const struct sc_hid_event *event) {
struct sc_control_msg msg; struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT; msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT;
msg.uhid_input.id = UHID_KEYBOARD_ID; msg.uhid_input.id = event->hid_id;
assert(event->size <= SC_HID_MAX_SIZE); assert(event->size <= SC_HID_MAX_SIZE);
memcpy(msg.uhid_input.data, event->data, event->size); memcpy(msg.uhid_input.data, event->data, event->size);
@ -141,13 +139,13 @@ sc_keyboard_uhid_init(struct sc_keyboard_uhid *kb,
.process_output = sc_uhid_receiver_process_output, .process_output = sc_uhid_receiver_process_output,
}; };
kb->uhid_receiver.id = UHID_KEYBOARD_ID; kb->uhid_receiver.id = SC_HID_ID_KEYBOARD;
kb->uhid_receiver.ops = &uhid_receiver_ops; kb->uhid_receiver.ops = &uhid_receiver_ops;
sc_uhid_devices_add_receiver(uhid_devices, &kb->uhid_receiver); sc_uhid_devices_add_receiver(uhid_devices, &kb->uhid_receiver);
struct sc_control_msg msg; struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE; msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = UHID_KEYBOARD_ID; msg.uhid_create.id = SC_HID_ID_KEYBOARD;
msg.uhid_create.report_desc = SC_HID_KEYBOARD_REPORT_DESC; 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_size = SC_HID_KEYBOARD_REPORT_DESC_LEN;
if (!sc_controller_push_msg(controller, &msg)) { if (!sc_controller_push_msg(controller, &msg)) {

View File

@ -7,14 +7,12 @@
/** Downcast mouse processor to mouse_uhid */ /** Downcast mouse processor to mouse_uhid */
#define DOWNCAST(MP) container_of(MP, struct sc_mouse_uhid, mouse_processor) #define DOWNCAST(MP) container_of(MP, struct sc_mouse_uhid, mouse_processor)
#define UHID_MOUSE_ID 2
static void static void
sc_mouse_uhid_send_input(struct sc_mouse_uhid *mouse, sc_mouse_uhid_send_input(struct sc_mouse_uhid *mouse,
const struct sc_hid_event *event, const char *name) { const struct sc_hid_event *event, const char *name) {
struct sc_control_msg msg; struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT; msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT;
msg.uhid_input.id = UHID_MOUSE_ID; msg.uhid_input.id = event->hid_id;
assert(event->size <= SC_HID_MAX_SIZE); assert(event->size <= SC_HID_MAX_SIZE);
memcpy(msg.uhid_input.data, event->data, event->size); memcpy(msg.uhid_input.data, event->data, event->size);
@ -77,7 +75,7 @@ sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
struct sc_control_msg msg; struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE; msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = UHID_MOUSE_ID; msg.uhid_create.id = SC_HID_ID_MOUSE;
msg.uhid_create.report_desc = SC_HID_MOUSE_REPORT_DESC; 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_size = SC_HID_MOUSE_REPORT_DESC_LEN;
if (!sc_controller_push_msg(controller, &msg)) { if (!sc_controller_push_msg(controller, &msg)) {

View File

@ -1,6 +1,7 @@
#include "util/log.h" #include "util/log.h"
#include <assert.h> #include <assert.h>
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include "aoa_hid.h" #include "aoa_hid.h"
@ -18,14 +19,14 @@
#define SC_AOA_EVENT_QUEUE_MAX 64 #define SC_AOA_EVENT_QUEUE_MAX 64
static void static void
sc_hid_event_log(uint16_t accessory_id, const struct sc_hid_event *event) { sc_hid_event_log(const struct sc_hid_event *event) {
// HID Event: [00] FF FF FF FF... // HID Event: [00] FF FF FF FF...
assert(event->size); assert(event->size);
char *hex = sc_str_to_hex_string(event->data, event->size); char *hex = sc_str_to_hex_string(event->data, event->size);
if (!hex) { if (!hex) {
return; return;
} }
LOGV("HID Event: [%d] %s", accessory_id, hex); LOGV("HID Event: [%" PRIu16 "] %s", event->hid_id, hex);
free(hex); free(hex);
} }
@ -146,14 +147,13 @@ sc_aoa_setup_hid(struct sc_aoa *aoa, uint16_t accessory_id,
} }
static bool static bool
sc_aoa_send_hid_event(struct sc_aoa *aoa, uint16_t accessory_id, sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
const struct sc_hid_event *event) {
uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR; uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR;
uint8_t request = ACCESSORY_SEND_HID_EVENT; uint8_t request = ACCESSORY_SEND_HID_EVENT;
// <https://source.android.com/devices/accessories/aoa2.html#hid-support> // <https://source.android.com/devices/accessories/aoa2.html#hid-support>
// value (arg0): accessory assigned ID for the HID device // value (arg0): accessory assigned ID for the HID device
// index (arg1): 0 (unused) // index (arg1): 0 (unused)
uint16_t value = accessory_id; uint16_t value = event->hid_id;
uint16_t index = 0; uint16_t index = 0;
unsigned char *data = (uint8_t *) event->data; // discard const unsigned char *data = (uint8_t *) event->data; // discard const
uint16_t length = event->size; uint16_t length = event->size;
@ -194,11 +194,10 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id) {
bool bool
sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa, sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
uint16_t accessory_id,
const struct sc_hid_event *event, const struct sc_hid_event *event,
uint64_t ack_to_wait) { uint64_t ack_to_wait) {
if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) { if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) {
sc_hid_event_log(accessory_id, event); sc_hid_event_log(event);
} }
sc_mutex_lock(&aoa->mutex); sc_mutex_lock(&aoa->mutex);
@ -209,7 +208,6 @@ sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
struct sc_aoa_event *aoa_event = struct sc_aoa_event *aoa_event =
sc_vecdeque_push_hole_noresize(&aoa->queue); sc_vecdeque_push_hole_noresize(&aoa->queue);
aoa_event->hid = *event; aoa_event->hid = *event;
aoa_event->accessory_id = accessory_id;
aoa_event->ack_to_wait = ack_to_wait; aoa_event->ack_to_wait = ack_to_wait;
if (was_empty) { if (was_empty) {
@ -265,7 +263,7 @@ run_aoa_thread(void *data) {
} }
} }
bool ok = sc_aoa_send_hid_event(aoa, event.accessory_id, &event.hid); bool ok = sc_aoa_send_hid_event(aoa, &event.hid);
if (!ok) { if (!ok) {
LOGW("Could not send HID event to USB device"); LOGW("Could not send HID event to USB device");
} }

View File

@ -15,7 +15,6 @@
struct sc_aoa_event { struct sc_aoa_event {
struct sc_hid_event hid; struct sc_hid_event hid;
uint16_t accessory_id;
uint64_t ack_to_wait; uint64_t ack_to_wait;
}; };
@ -56,14 +55,12 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id);
bool bool
sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa, sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
uint16_t accessory_id,
const struct sc_hid_event *event, const struct sc_hid_event *event,
uint64_t ack_to_wait); uint64_t ack_to_wait);
static inline bool static inline bool
sc_aoa_push_hid_event(struct sc_aoa *aoa, uint16_t accessory_id, sc_aoa_push_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
const struct sc_hid_event *event) { return sc_aoa_push_hid_event_with_ack_to_wait(aoa, event,
return sc_aoa_push_hid_event_with_ack_to_wait(aoa, accessory_id, event,
SC_SEQUENCE_INVALID); SC_SEQUENCE_INVALID);
} }

View File

@ -8,8 +8,6 @@
/** Downcast key processor to keyboard_aoa */ /** Downcast key processor to keyboard_aoa */
#define DOWNCAST(KP) container_of(KP, struct sc_keyboard_aoa, key_processor) #define DOWNCAST(KP) container_of(KP, struct sc_keyboard_aoa, key_processor)
#define HID_KEYBOARD_ACCESSORY_ID 1
static bool static bool
push_mod_lock_state(struct sc_keyboard_aoa *kb, uint16_t mods_state) { push_mod_lock_state(struct sc_keyboard_aoa *kb, uint16_t mods_state) {
struct sc_hid_event hid_event; struct sc_hid_event hid_event;
@ -18,8 +16,7 @@ push_mod_lock_state(struct sc_keyboard_aoa *kb, uint16_t mods_state) {
return true; return true;
} }
if (!sc_aoa_push_hid_event(kb->aoa, HID_KEYBOARD_ACCESSORY_ID, if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
&hid_event)) {
LOGW("Could not request HID event (mod lock state)"); LOGW("Could not request HID event (mod lock state)");
return false; return false;
} }
@ -58,9 +55,7 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
// synchronization is acknowledged by the server, otherwise it could // synchronization is acknowledged by the server, otherwise it could
// paste the old clipboard content. // paste the old clipboard content.
if (!sc_aoa_push_hid_event_with_ack_to_wait(kb->aoa, if (!sc_aoa_push_hid_event_with_ack_to_wait(kb->aoa, &hid_event,
HID_KEYBOARD_ACCESSORY_ID,
&hid_event,
ack_to_wait)) { ack_to_wait)) {
LOGW("Could not request HID event (key)"); LOGW("Could not request HID event (key)");
} }
@ -71,7 +66,7 @@ bool
sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) { sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) {
kb->aoa = aoa; kb->aoa = aoa;
bool ok = sc_aoa_setup_hid(aoa, HID_KEYBOARD_ACCESSORY_ID, bool ok = sc_aoa_setup_hid(aoa, SC_HID_ID_KEYBOARD,
SC_HID_KEYBOARD_REPORT_DESC, SC_HID_KEYBOARD_REPORT_DESC,
SC_HID_KEYBOARD_REPORT_DESC_LEN); SC_HID_KEYBOARD_REPORT_DESC_LEN);
if (!ok) { if (!ok) {
@ -103,7 +98,7 @@ sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) {
void void
sc_keyboard_aoa_destroy(struct sc_keyboard_aoa *kb) { sc_keyboard_aoa_destroy(struct sc_keyboard_aoa *kb) {
// Unregister HID keyboard so the soft keyboard shows again on Android // Unregister HID keyboard so the soft keyboard shows again on Android
bool ok = sc_aoa_unregister_hid(kb->aoa, HID_KEYBOARD_ACCESSORY_ID); bool ok = sc_aoa_unregister_hid(kb->aoa, SC_HID_ID_KEYBOARD);
if (!ok) { if (!ok) {
LOGW("Could not unregister HID keyboard"); LOGW("Could not unregister HID keyboard");
} }

View File

@ -9,8 +9,6 @@
/** Downcast mouse processor to mouse_aoa */ /** Downcast mouse processor to mouse_aoa */
#define DOWNCAST(MP) container_of(MP, struct sc_mouse_aoa, mouse_processor) #define DOWNCAST(MP) container_of(MP, struct sc_mouse_aoa, mouse_processor)
#define HID_MOUSE_ACCESSORY_ID 2
static void static void
sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp, sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
const struct sc_mouse_motion_event *event) { const struct sc_mouse_motion_event *event) {
@ -19,8 +17,7 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
struct sc_hid_event hid_event; struct sc_hid_event hid_event;
sc_hid_mouse_event_from_motion(&hid_event, event); sc_hid_mouse_event_from_motion(&hid_event, event);
if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID, if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
&hid_event)) {
LOGW("Could not request HID event (mouse motion)"); LOGW("Could not request HID event (mouse motion)");
} }
} }
@ -33,8 +30,7 @@ sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
struct sc_hid_event hid_event; struct sc_hid_event hid_event;
sc_hid_mouse_event_from_click(&hid_event, event); sc_hid_mouse_event_from_click(&hid_event, event);
if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID, if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
&hid_event)) {
LOGW("Could not request HID event (mouse click)"); LOGW("Could not request HID event (mouse click)");
} }
} }
@ -47,8 +43,7 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
struct sc_hid_event hid_event; struct sc_hid_event hid_event;
sc_hid_mouse_event_from_scroll(&hid_event, event); sc_hid_mouse_event_from_scroll(&hid_event, event);
if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID, if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
&hid_event)) {
LOGW("Could not request HID event (mouse scroll)"); LOGW("Could not request HID event (mouse scroll)");
} }
} }
@ -57,7 +52,7 @@ bool
sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) { sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) {
mouse->aoa = aoa; mouse->aoa = aoa;
bool ok = sc_aoa_setup_hid(aoa, HID_MOUSE_ACCESSORY_ID, bool ok = sc_aoa_setup_hid(aoa, SC_HID_ID_MOUSE,
SC_HID_MOUSE_REPORT_DESC, SC_HID_MOUSE_REPORT_DESC,
SC_HID_MOUSE_REPORT_DESC_LEN); SC_HID_MOUSE_REPORT_DESC_LEN);
if (!ok) { if (!ok) {
@ -82,7 +77,7 @@ sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) {
void void
sc_mouse_aoa_destroy(struct sc_mouse_aoa *mouse) { sc_mouse_aoa_destroy(struct sc_mouse_aoa *mouse) {
bool ok = sc_aoa_unregister_hid(mouse->aoa, HID_MOUSE_ACCESSORY_ID); bool ok = sc_aoa_unregister_hid(mouse->aoa, SC_HID_ID_MOUSE);
if (!ok) { if (!ok) {
LOGW("Could not unregister HID mouse"); LOGW("Could not unregister HID mouse");
} }