Skip to content

Commit 9151e95

Browse files
authored
Merge pull request #293 from rygwdn/hid-parsing
Track HID report offsets per report ID
2 parents f82e7dd + 6c92c11 commit 9151e95

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/hid_parser.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,39 @@ uint32_t get_descriptor_value(uint8_t const *report, int size) {
3333
}
3434
}
3535

36+
uint32_t *get_or_create_report_offset(parser_state_t *parser, uint8_t report_id) {
37+
for (int i = 0; i < parser->num_report_offsets; i++) {
38+
if (parser->report_offsets[i].report_id == report_id) {
39+
return &parser->report_offsets[i].offset_in_bits;
40+
}
41+
}
42+
43+
if (parser->num_report_offsets < MAX_REPORTS) {
44+
parser->report_offsets[parser->num_report_offsets].report_id = report_id;
45+
parser->report_offsets[parser->num_report_offsets].offset_in_bits = 0;
46+
return &parser->report_offsets[parser->num_report_offsets++].offset_in_bits;
47+
}
48+
49+
return NULL;
50+
}
51+
52+
uint32_t get_current_offset(parser_state_t *parser) {
53+
uint32_t *offset = get_or_create_report_offset(parser, parser->report_id);
54+
return offset ? *offset : 0;
55+
}
56+
3657
void update_usage(parser_state_t *parser, int i) {
3758
/* If we don't have as many usages as elements, the usage for the previous element applies */
3859
if (i > 0 && i >= parser->usage_count && i < HID_MAX_USAGES)
3960
*(parser->p_usage + i) = *(parser->p_usage + i - 1);
4061
}
4162

4263
void store_element(parser_state_t *parser, report_val_t *val, int i, uint32_t data, uint16_t size, hid_interface_t *iface) {
64+
uint32_t current_offset = get_current_offset(parser);
65+
4366
*val = (report_val_t){
44-
.offset = parser->offset_in_bits,
45-
.offset_idx = parser->offset_in_bits >> 3,
67+
.offset = current_offset,
68+
.offset_idx = current_offset >> 3,
4669
.size = size,
4770

4871
.usage_max = parser->locals[RI_LOCAL_USAGE_MAX].val,
@@ -62,8 +85,6 @@ void store_element(parser_state_t *parser, report_val_t *val, int i, uint32_t da
6285

6386
void handle_global_item(parser_state_t *parser, item_t *item) {
6487
if (item->hdr.tag == RI_GLOBAL_REPORT_ID) {
65-
/* Reset offset for a new page */
66-
parser->offset_in_bits = 0;
6788
parser->report_id = item->val;
6889
}
6990

@@ -98,6 +119,10 @@ void handle_main_input(parser_state_t *parser, item_t *item, hid_interface_t *if
98119
count = 1;
99120
}
100121

122+
uint32_t *current_offset = get_or_create_report_offset(parser, parser->report_id);
123+
if (!current_offset)
124+
return;
125+
101126
for (int i = 0; i < count; i++) {
102127
update_usage(parser, i);
103128
store_element(parser, &val, i, item->val, size, iface);
@@ -106,7 +131,7 @@ void handle_main_input(parser_state_t *parser, item_t *item, hid_interface_t *if
106131
extract_data(iface, &val);
107132

108133
/* Iterate <count> times and increase offset by <size> amount, moving by <count> x <size> bits */
109-
parser->offset_in_bits += size;
134+
*current_offset += size;
110135
}
111136

112137
/* Advance the usage array pointer by global report count and reset the count variable */
@@ -117,9 +142,6 @@ void handle_main_input(parser_state_t *parser, item_t *item, hid_interface_t *if
117142
}
118143

119144
void handle_main_item(parser_state_t *parser, item_t *item, hid_interface_t *iface) {
120-
if (IS_BLOCK_END)
121-
parser->offset_in_bits = 0;
122-
123145
switch (item->hdr.tag) {
124146
case RI_MAIN_COLLECTION:
125147
parser->collection.start++;

src/include/hid_parser.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ typedef struct {
3838
uint8_t end;
3939
} collection_t;
4040

41+
/* Maps a report ID to its current bit offset */
42+
typedef struct {
43+
uint8_t report_id;
44+
uint32_t offset_in_bits;
45+
} report_offset_map_t;
46+
4147
/* Header byte is unpacked to size/type/tag using this struct */
4248
typedef struct TU_ATTR_PACKED {
4349
uint8_t size : 2;
@@ -149,13 +155,15 @@ typedef struct {
149155
int report_id; /* Report ID of the current section we're parsing */
150156

151157
uint32_t usage_count;
152-
uint32_t offset_in_bits;
153158
uint16_t usages[HID_MAX_USAGES];
154159
uint16_t *p_usage;
155160
uint16_t global_usage;
156161

157162
collection_t collection;
158163

164+
report_offset_map_t report_offsets[MAX_REPORTS];
165+
uint8_t num_report_offsets;
166+
159167
/* as tag is 4 bits, there can be 16 different tags in global header type */
160168
item_t globals[16];
161169

0 commit comments

Comments
 (0)