Skip to content

Commit

Permalink
Fix incorrect multiple-count report field sizing
Browse files Browse the repository at this point in the history
- Add `HIDInputReportItem::get_total_size()`, the item's size times
its count
- Use `HIDInputReportItem::get_total_size()` to calculate the correct
item offset in `HIDInputReport::push_back`

Offsets for `HIDInputReportItem` instances within a report are
calculated using the size of the field, but the message will contain
N fields of the given size. As a result, multiple-count fields give
every following `HIDInputReportItem` an incorrect offset when parsing
HID reports. In addition, the report's calculated total size is
incorrect, which would cause issues with any code that might rely on its
size in the future.

Introducing a member to provide the correct total size allows correct
calculation of a report's size.
  • Loading branch information
trianglPixl committed Nov 24, 2024
1 parent 1742617 commit b56008a
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
7 changes: 6 additions & 1 deletion components/ble_client_hid/hid_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ namespace esphome
void HIDInputReport::push_back(HIDInputReportItem *item)
{
this->items.push_back(item);
this->report_size += item->report_size;
this->report_size += item->get_total_size();
}

std::vector<HIDReportItemValue> HIDReportMap::parse(uint8_t *hid_report_data)
Expand Down Expand Up @@ -370,6 +370,11 @@ namespace esphome
return report_values;
}

size_t HIDInputReportItem::get_total_size()
{
return this->report_size * this->report_count;
}

int32_t HIDInputReportItem::parse_input_report_item(uint8_t *report_data, uint16_t bit_offset, uint16_t report_size, HIDLogicalRange logical_range)
{
int32_t value = 0;
Expand Down
1 change: 1 addition & 0 deletions components/ble_client_hid/hid_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ namespace esphome
{
delete usage_collection;
};
size_t get_total_size();
virtual std::vector<HIDReportItemValue> parse(uint8_t *hid_report_data) = 0;
static int32_t parse_input_report_item(uint8_t *report_data, uint16_t bit_offset, uint16_t report_size, HIDLogicalRange logical_range);
const uint8_t report_size; // in bits
Expand Down

0 comments on commit b56008a

Please sign in to comment.