Skip to content

Commit

Permalink
Fix for interface number in user defined quirks
Browse files Browse the repository at this point in the history
It turns out that the thing that we called interface is not the
interface number as it appears in the USB descriptors and instead it's
an internal tinyusb index, which meant that user defined quirks only
worked correctly on the first connected device because then the
numbers matched.

This makes the actual interface number available to the apply_quirks()
function.
  • Loading branch information
jfedor2 committed Apr 19, 2024
1 parent 3aaccb1 commit 12377c0
Show file tree
Hide file tree
Showing 13 changed files with 27 additions and 17 deletions.
2 changes: 1 addition & 1 deletion firmware-bluetooth/src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ int main() {

while (!k_msgq_get(&descriptor_q, &incoming_descriptor, K_NO_WAIT)) {
LOG_HEXDUMP_DBG(incoming_descriptor.data, incoming_descriptor.size, "incoming_descriptor");
parse_descriptor(1, 1, incoming_descriptor.data, incoming_descriptor.size, incoming_descriptor.conn_idx << 8);
parse_descriptor(1, 1, incoming_descriptor.data, incoming_descriptor.size, incoming_descriptor.conn_idx << 8, 0);
}

if (config_updated) {
Expand Down
4 changes: 2 additions & 2 deletions firmware/src/descriptor_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void assign_interface_index(uint16_t interface) {
interface_index_in_use |= 1 << i;
}

void parse_descriptor(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface) {
void parse_descriptor(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t itf_num) {
my_mutex_enter(MutexId::THEIR_USAGES);
auto their_report_sizes_map = parse_descriptor(
their_usages[interface],
Expand All @@ -77,7 +77,7 @@ void parse_descriptor(uint16_t vendor_id, uint16_t product_id, const uint8_t* re
has_report_id_theirs[interface],
report_descriptor,
len);
apply_quirks(vendor_id, product_id, their_usages[interface], report_descriptor, len, interface & 0xFF);
apply_quirks(vendor_id, product_id, their_usages[interface], report_descriptor, len, itf_num);
assign_interface_index(interface);

for (auto const& [report_id, size] : their_report_sizes_map[ReportType::OUTPUT]) {
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/descriptor_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ std::unordered_map<ReportType, std::unordered_map<uint8_t, uint16_t>> parse_desc
extern "C" {
#endif

void parse_descriptor(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface);
void parse_descriptor(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t itf_num);
void clear_descriptor_data(uint8_t dev_addr);

#ifdef __cplusplus
Expand Down
1 change: 1 addition & 0 deletions firmware/src/dual.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct __attribute__((packed)) device_connected_t {
uint8_t dev_addr;
uint8_t interface;
uint8_t hub_port;
uint8_t itf_num;
uint8_t report_descriptor[0];
};

Expand Down
4 changes: 2 additions & 2 deletions firmware/src/quirks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ const uint8_t spacemouse_pro_descriptor[] = {
0xC0, // End Collection
};

void apply_quirks(uint16_t vendor_id, uint16_t product_id, std::unordered_map<uint8_t, std::unordered_map<uint32_t, usage_def_t>>& usage_map, const uint8_t* report_descriptor, int len, uint8_t interface) {
void apply_quirks(uint16_t vendor_id, uint16_t product_id, std::unordered_map<uint8_t, std::unordered_map<uint32_t, usage_def_t>>& usage_map, const uint8_t* report_descriptor, int len, uint8_t itf_num) {
// Button Fn1 is described as a constant (padding) in the descriptor.
// We add it as button 6.
if (vendor_id == VENDOR_ID_ELECOM &&
Expand Down Expand Up @@ -753,7 +753,7 @@ void apply_quirks(uint16_t vendor_id, uint16_t product_id, std::unordered_map<ui
my_mutex_enter(MutexId::QUIRKS);
for (uint16_t i = 0; i < quirks.size(); i++) {
quirk_t* quirk = &quirks[i];
if (((quirk->vendor_id == vendor_id) && (quirk->product_id == product_id) && (quirk->interface == interface)) ||
if (((quirk->vendor_id == vendor_id) && (quirk->product_id == product_id) && (quirk->interface == itf_num)) ||
((quirk->vendor_id == 0) && (quirk->product_id == 0))) {
uint8_t quirk_size = quirk->size_flags & QUIRK_SIZE_MASK;
if (quirk_size != 0) {
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
#include <unordered_map>
#include "types.h"

void apply_quirks(uint16_t vendor_id, uint16_t product_id, std::unordered_map<uint8_t, std::unordered_map<uint32_t, usage_def_t>>& usage_map, const uint8_t* report_descriptor, int len, uint8_t interface);
void apply_quirks(uint16_t vendor_id, uint16_t product_id, std::unordered_map<uint8_t, std::unordered_map<uint32_t, usage_def_t>>& usage_map, const uint8_t* report_descriptor, int len, uint8_t itf_num);

#endif
2 changes: 1 addition & 1 deletion firmware/src/remapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void handle_set_report0(uint8_t report_id, const uint8_t* buffer, uint16_t reqle
void handle_get_report_response(uint16_t interface, uint8_t report_id, uint8_t* report, uint16_t len);
void handle_set_report_complete(uint16_t interface, uint8_t report_id);

void descriptor_received_callback(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t hub_port);
void descriptor_received_callback(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t hub_port, uint8_t itf_num);
void report_received_callback(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
void umount_callback(uint8_t dev_addr, uint8_t instance);

Expand Down
2 changes: 1 addition & 1 deletion firmware/src/remapper_dual_a.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bool serial_callback(const uint8_t* data, uint16_t len) {
switch ((DualCommand) data[0]) {
case DualCommand::DEVICE_CONNECTED: {
device_connected_t* msg = (device_connected_t*) data;
parse_descriptor(msg->vid, msg->pid, msg->report_descriptor, len - sizeof(device_connected_t), (uint16_t) (msg->dev_addr << 8) | msg->interface);
parse_descriptor(msg->vid, msg->pid, msg->report_descriptor, len - sizeof(device_connected_t), (uint16_t) (msg->dev_addr << 8) | msg->interface, msg->itf_num);
device_connected_callback((uint16_t) (msg->dev_addr << 8) | msg->interface, msg->vid, msg->pid, msg->hub_port);
break;
}
Expand Down
9 changes: 7 additions & 2 deletions firmware/src/remapper_dual_b.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,15 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
tuh_hid_receive_report(dev_addr, instance);
}

void descriptor_received_callback(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t hub_port) {
void descriptor_received_callback(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t hub_port, uint8_t itf_num) {
device_connected_t* msg = (device_connected_t*) buffer;
msg->command = DualCommand::DEVICE_CONNECTED;
msg->vid = vendor_id;
msg->pid = product_id;
msg->dev_addr = (interface >> 8) & 0xFF;
msg->interface = interface & 0xFF;
msg->hub_port = hub_port;
msg->itf_num = itf_num;
memcpy(msg->report_descriptor, report_descriptor, len);
serial_write((uint8_t*) msg, len + sizeof(device_connected_t));
}
Expand All @@ -114,7 +115,11 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
uint16_t pid;
tuh_vid_pid_get(dev_addr, &vid, &pid);

descriptor_received_callback(vid, pid, desc_report, desc_len, (uint16_t) (dev_addr << 8) | instance, hub_port);
tuh_itf_info_t itf_info;
tuh_hid_itf_get_info(dev_addr, instance, &itf_info);
uint8_t itf_num = itf_info.desc.bInterfaceNumber;

descriptor_received_callback(vid, pid, desc_report, desc_len, (uint16_t) (dev_addr << 8) | instance, hub_port, itf_num);
tuh_hid_receive_report(dev_addr, instance);
}

Expand Down
2 changes: 1 addition & 1 deletion firmware/src/remapper_serial.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void extra_init() {
uart_set_translate_crlf(SERIAL_MOUSE_UART, false);
uart_set_format(SERIAL_MOUSE_UART, 7, 1, UART_PARITY_NONE);

parse_descriptor(FAKE_VID, FAKE_PID, fake_descriptor, sizeof(fake_descriptor), FAKE_INTERFACE);
parse_descriptor(FAKE_VID, FAKE_PID, fake_descriptor, sizeof(fake_descriptor), FAKE_INTERFACE, 0);
}

uint32_t get_gpio_valid_pins_mask() {
Expand Down
10 changes: 7 additions & 3 deletions firmware/src/remapper_single.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ void interval_override_updated() {
void flash_b_side() {
}

void descriptor_received_callback(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t hub_port) {
parse_descriptor(vendor_id, product_id, report_descriptor, len, interface);
void descriptor_received_callback(uint16_t vendor_id, uint16_t product_id, const uint8_t* report_descriptor, int len, uint16_t interface, uint8_t hub_port, uint8_t itf_num) {
parse_descriptor(vendor_id, product_id, report_descriptor, len, interface, itf_num);
}

void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) {
Expand All @@ -61,7 +61,11 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
uint16_t pid;
tuh_vid_pid_get(dev_addr, &vid, &pid);

descriptor_received_callback(vid, pid, desc_report, desc_len, (uint16_t) (dev_addr << 8) | instance, hub_port);
tuh_itf_info_t itf_info;
tuh_hid_itf_get_info(dev_addr, instance, &itf_info);
uint8_t itf_num = itf_info.desc.bInterfaceNumber;

descriptor_received_callback(vid, pid, desc_report, desc_len, (uint16_t) (dev_addr << 8) | instance, hub_port, itf_num);

device_connected_callback((uint16_t) (dev_addr << 8) | instance, vid, pid, hub_port);

Expand Down
2 changes: 1 addition & 1 deletion firmware/src/xbox.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ static void process_setup(struct xdev_t* xdev) {
uint8_t hub_addr;
uint8_t hub_port;
tuh_get_hub_addr_port(xdev->dev_addr, &hub_addr, &hub_port);
descriptor_received_callback(0, 0, xbox_one_descriptor, sizeof(xbox_one_descriptor), (uint16_t) (xdev->dev_addr << 8) | xdev->itf_num, hub_port);
descriptor_received_callback(0, 0, xbox_one_descriptor, sizeof(xbox_one_descriptor), (uint16_t) (xdev->dev_addr << 8) | xdev->itf_num, hub_port, xdev->itf_num);
usbh_driver_set_config_complete(xdev->dev_addr, xdev->itf_num);
break;
}
Expand Down

0 comments on commit 12377c0

Please sign in to comment.