From 996aa32068a7b0a7e62ce640c422ede7e3a2c0ac Mon Sep 17 00:00:00 2001 From: Jacek Fedorynski Date: Tue, 28 May 2024 23:07:11 +0200 Subject: [PATCH] Sanitize outgoing reports This adds the option for an emulated device type to sanitize input reports ensuring values are valid before the report is sent out. Currently used to clamp Stadia stick axes to 1-255. --- firmware/src/our_descriptor.cc | 16 ++++++++++++++++ firmware/src/our_descriptor.h | 2 ++ firmware/src/remapper.cc | 3 +++ 3 files changed, 21 insertions(+) diff --git a/firmware/src/our_descriptor.cc b/firmware/src/our_descriptor.cc index 2551ce9..edbac8f 100644 --- a/firmware/src/our_descriptor.cc +++ b/firmware/src/our_descriptor.cc @@ -548,6 +548,21 @@ int32_t ps4_stadia_default_value(uint32_t usage) { } } +void stadia_sanitize_report(uint8_t report_id, uint8_t* buffer, uint16_t len) { + if (buffer[3] == 0) { + buffer[3] = 1; + } + if (buffer[4] == 0) { + buffer[4] = 1; + } + if (buffer[5] == 0) { + buffer[5] = 1; + } + if (buffer[6] == 0) { + buffer[6] = 1; + } +} + const our_descriptor_def_t our_descriptors[] = { { .idx = 0, @@ -599,6 +614,7 @@ const our_descriptor_def_t our_descriptors[] = { .handle_received_report = do_handle_received_report, .clear_report = stadia_clear_report, .default_value = ps4_stadia_default_value, + .sanitize_report = stadia_sanitize_report, }, }; diff --git a/firmware/src/our_descriptor.h b/firmware/src/our_descriptor.h index 2e4350f..6207800 100644 --- a/firmware/src/our_descriptor.h +++ b/firmware/src/our_descriptor.h @@ -25,6 +25,7 @@ typedef void (*handle_get_report_response_t)(uint16_t interface, uint8_t report_ typedef void (*handle_set_report_complete_t)(uint16_t interface, uint8_t report_id); typedef void (*clear_report_t)(uint8_t* report, uint8_t report_id, uint16_t len); typedef int32_t (*default_value_t)(uint32_t usage); +typedef void (*sanitize_report_t)(uint8_t report_id, uint8_t* buffer, uint16_t len); struct our_descriptor_def_t { uint8_t idx; @@ -42,6 +43,7 @@ struct our_descriptor_def_t { handle_set_report_complete_t handle_set_report_complete = nullptr; clear_report_t clear_report = nullptr; default_value_t default_value = nullptr; + sanitize_report_t sanitize_report = nullptr; }; extern const our_descriptor_def_t our_descriptors[]; diff --git a/firmware/src/remapper.cc b/firmware/src/remapper.cc index 4e9d917..850c993 100644 --- a/firmware/src/remapper.cc +++ b/firmware/src/remapper.cc @@ -1139,6 +1139,9 @@ void process_mapping(bool auto_repeat) { for (unsigned int i = 0; i < report_ids.size(); i++) { // XXX what order should we go in? maybe keyboard first so that mappings to ctrl-left click work as expected? uint8_t report_id = report_ids[i]; + if (our_descriptor->sanitize_report != nullptr) { + our_descriptor->sanitize_report(report_id, reports[report_id], report_sizes[report_id]); + } if (needs_to_be_sent(report_id)) { if (or_items == OR_BUFSIZE) { printf("overflow!\n");