Skip to content

Commit

Permalink
-Add reconstruction logic of const padding bytes at the end of a repo…
Browse files Browse the repository at this point in the history
…rt for devices which don't use ReportIDs

-Enhanced padding logic to distinguish between byte and bit padding.
-Add a new test case for Razer Cobra mouse `1532_00A3_0002_0001` which has a completly con feature report of 90 bytes.
-Modified expected report descriptor reference file `045E_02FF_0005_0001_expected.rpt_desc` to include additional padding bytes.
  • Loading branch information
JoergAtGithub committed Oct 27, 2024
1 parent 750bf20 commit 7dd822a
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 6 deletions.
54 changes: 49 additions & 5 deletions windows/hidapi_descriptor_reconstruct.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,10 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha
}
}

BOOLEAN devicehasReportIDs = FALSE;
struct rd_main_item_node *list = main_item_list; // List root;
// Windows pp_data are per top-level collection, therefore top level coll end is unique
struct rd_main_item_node* node_before_top_level_coll_end = NULL;

while (list->next != NULL)
{
Expand All @@ -552,12 +555,20 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha
struct rd_main_item_node *list_node = rd_search_main_item_list_for_bit_position(last_bit_position[list->MainItemType][list->ReportID], list->MainItemType, list->ReportID, &last_report_item_lookup[list->MainItemType][list->ReportID]);
rd_insert_main_item_node(last_bit_position[list->MainItemType][list->ReportID] + 1, list->FirstBit - 1, rd_item_node_padding, -1, 0, list->MainItemType, list->ReportID, &list_node);
}
if (list->ReportID != 0) {
devicehasReportIDs = TRUE;
}
last_bit_position[list->MainItemType][list->ReportID] = list->LastBit;
last_report_item_lookup[list->MainItemType][list->ReportID] = list;
}
}
if (list->next->MainItemType == rd_collection_end) {
// Store the node before the collection end - the last occurence is the end of the top level collection
node_before_top_level_coll_end = list;
}
list = list->next;
}

// Add 8 bit padding at each report end
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
Expand All @@ -566,10 +577,31 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha
if (padding < 8) {
// Insert padding item after item referenced in last_report_item_lookup
rd_insert_main_item_node(last_bit_position[rt_idx][reportid_idx] + 1, last_bit_position[rt_idx][reportid_idx] + padding, rd_item_node_padding, -1, 0, (rd_main_items) rt_idx, (unsigned char) reportid_idx, &last_report_item_lookup[rt_idx][reportid_idx]);
if (last_report_item_lookup[rt_idx][reportid_idx] == node_before_top_level_coll_end) {
// If this padding item is at the end of the top level collection, update node_before_top_level_coll_end
node_before_top_level_coll_end = last_report_item_lookup[rt_idx][reportid_idx]->next;
}
last_bit_position[rt_idx][reportid_idx] += padding;
}
}
}
}

// Add full byte padding at the end of the report descriptor (only reconstructable, for devices without Report IDs)
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
if (!devicehasReportIDs && pp_data->caps_info[rt_idx].NumberOfCaps > 0 && pp_data->caps_info[rt_idx].ReportByteLength > 0) {
// ReportID 0 means this device uses not Report IDs
// => Maximum one report per type possible, so we can take the size from the buffer size for the report type
const unsigned char reportId = 0;
// ReportByteLength is the report length in bytes plus the one byte for the optional ReportID
int padding = (pp_data->caps_info[rt_idx].ReportByteLength - 1) * 8 - (last_bit_position[rt_idx][reportId] + 1);

if (padding > 0) {
// Insert padding item after item referenced in last_report_item_lookup
rd_insert_main_item_node(last_bit_position[rt_idx][reportId] + 1, last_bit_position[rt_idx][reportId] + padding, rd_item_node_padding, -1, 0, (rd_main_items)rt_idx, reportId, &node_before_top_level_coll_end);
}
}
}
}


Expand Down Expand Up @@ -652,13 +684,25 @@ int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned cha
else if (main_item_list->TypeOfNode == rd_item_node_padding) {
// Padding
// The preparsed data doesn't contain any information about padding. Therefore all undefined gaps
// in the reports are filled with the same style of constant padding.
// in the reports are filled with the same style of constant bit or byte padding.

if ((main_item_list->LastBit - main_item_list->FirstBit + 1) % 8 == 0) {
// Padding in full bytes

// Write "Report Size" with number of padding bits
rd_write_short_item(rd_global_report_size, (main_item_list->LastBit - main_item_list->FirstBit + 1), &rpt_desc);
// Write "Report Size" for padding bytes is 8
rd_write_short_item(rd_global_report_size, 8, &rpt_desc);

// Write "Report Count" for padding always as 1
rd_write_short_item(rd_global_report_count, 1, &rpt_desc);
// Write "Report Count" with number of padding bytes
rd_write_short_item(rd_global_report_count, (main_item_list->LastBit - main_item_list->FirstBit + 1) / 8, &rpt_desc);
} else {
// Padding in bits

// Write "Report Size" with number of padding bits
rd_write_short_item(rd_global_report_size, (main_item_list->LastBit - main_item_list->FirstBit + 1), &rpt_desc);

// Write "Report Count" for padding bits is 1
rd_write_short_item(rd_global_report_count, 1, &rpt_desc);
}

if (rt_idx == HidP_Input) {
// Write "Input" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
Expand Down
1 change: 1 addition & 0 deletions windows/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ set(HID_DESCRIPTOR_RECONSTRUCT_TEST_CASES
047F_C056_0003_FFA0
047F_C056_0005_000B
045E_02FF_0005_0001
1532_00A3_0002_0001
)

set(CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION "3.22")
Expand Down
2 changes: 1 addition & 1 deletion windows/test/data/045E_02FF_0005_0001_expected.rpt_desc
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
0x00, 0x81, 0x02, 0x05, 0x01, 0x09, 0x39, 0x15, 0x01, 0x25,
0x08, 0x35, 0x00, 0x46, 0x3B, 0x10, 0x65, 0x0E, 0x75, 0x04,
0x95, 0x01, 0x81, 0x42, 0x75, 0x04, 0x95, 0x01, 0x81, 0x03,
0xC0,
0x75, 0x08, 0x95, 0x02, 0x81, 0x03, 0xC0,
Loading

0 comments on commit 7dd822a

Please sign in to comment.