mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-03 07:13:51 +00:00
btstack_hid_parser: add function that calculates report size for given report type and ID from report descriptor
This commit is contained in:
parent
6cdc2862f6
commit
fada717989
@ -54,50 +54,6 @@
|
||||
* btstack_hid_parser.c
|
||||
*/
|
||||
|
||||
|
||||
typedef enum {
|
||||
Main=0,
|
||||
Global,
|
||||
Local,
|
||||
Reserved
|
||||
} TagType;
|
||||
|
||||
typedef enum {
|
||||
Input=8,
|
||||
Output,
|
||||
Coll,
|
||||
Feature,
|
||||
EndColl
|
||||
} MainItemTag;
|
||||
|
||||
typedef enum {
|
||||
UsagePage,
|
||||
LogicalMinimum,
|
||||
LogicalMaximum,
|
||||
PhysicalMinimum,
|
||||
PhysicalMaximum,
|
||||
UnitExponent,
|
||||
Unit,
|
||||
ReportSize,
|
||||
ReportID,
|
||||
ReportCount,
|
||||
Push,
|
||||
Pop
|
||||
} GlobalItemTag;
|
||||
|
||||
typedef enum {
|
||||
Usage,
|
||||
UsageMinimum,
|
||||
UsageMaximum,
|
||||
DesignatorIndex,
|
||||
DesignatorMinimum,
|
||||
DesignatorMaximum,
|
||||
StringIndex,
|
||||
StringMinimum,
|
||||
StringMaximum,
|
||||
Delimiter
|
||||
} LocalItemTag;
|
||||
|
||||
const int hid_item_sizes[] = { 0, 1, 2, 4 };
|
||||
|
||||
#ifdef HID_PARSER_PRETTY_PRINT
|
||||
@ -193,7 +149,7 @@ static void hid_pretty_print_item(btstack_hid_parser_t * parser, hid_descriptor_
|
||||
}
|
||||
|
||||
// parse descriptor item and read up to 32-bit bit value
|
||||
static void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len){
|
||||
void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len){
|
||||
// parse item header
|
||||
if (hid_descriptor_len < 1) return;
|
||||
uint16_t pos = 0;
|
||||
@ -451,3 +407,65 @@ void btstack_hid_parser_get_field(btstack_hid_parser_t * parser, uint16_t * usag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int btstack_hid_get_report_size_for_id(int report_id, btstack_hid_report_type_t report_type, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor){
|
||||
int total_report_size = 0;
|
||||
int report_size = 0;
|
||||
int report_count = 0;
|
||||
int current_report_id = 0;
|
||||
|
||||
while (hid_descriptor_len){
|
||||
int valid_report_type = 0;
|
||||
hid_descriptor_item_t item;
|
||||
// printf("item: 0x%02x (%p)\n", *hid_descriptor, hid_descriptor);
|
||||
btstack_hid_parse_descriptor_item(&item, hid_descriptor, hid_descriptor_len);
|
||||
switch (item.item_type){
|
||||
case Global:
|
||||
switch ((GlobalItemTag)item.item_tag){
|
||||
case ReportID:
|
||||
current_report_id = item.item_value;
|
||||
break;
|
||||
case ReportCount:
|
||||
if (current_report_id != report_id) break;
|
||||
report_count = item.item_value;
|
||||
break;
|
||||
case ReportSize:
|
||||
if (current_report_id != report_id) break;
|
||||
report_size = item.item_value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Main:
|
||||
if (current_report_id != report_id) break;
|
||||
// printf("tag %d, report_type %d\n", item.item_tag, report_type);
|
||||
switch ((MainItemTag)item.item_tag){
|
||||
case Input:
|
||||
if (report_type != BTSTACK_HID_REPORT_TYPE_INPUT) break;
|
||||
valid_report_type = 1;
|
||||
break;
|
||||
case Output:
|
||||
if (report_type != BTSTACK_HID_REPORT_TYPE_OUTPUT) break;
|
||||
valid_report_type = 1;
|
||||
break;
|
||||
case Feature:
|
||||
if (report_type != BTSTACK_HID_REPORT_TYPE_FEATURE) break;
|
||||
valid_report_type = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!valid_report_type) break;
|
||||
total_report_size += report_count * report_size;
|
||||
report_size = 0;
|
||||
report_count = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hid_descriptor_len -= item.item_size;
|
||||
hid_descriptor += item.item_size;
|
||||
}
|
||||
return (total_report_size + 7)/8;
|
||||
}
|
@ -50,6 +50,49 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
Main=0,
|
||||
Global,
|
||||
Local,
|
||||
Reserved
|
||||
} TagType;
|
||||
|
||||
typedef enum {
|
||||
Input=8,
|
||||
Output,
|
||||
Coll,
|
||||
Feature,
|
||||
EndColl
|
||||
} MainItemTag;
|
||||
|
||||
typedef enum {
|
||||
UsagePage,
|
||||
LogicalMinimum,
|
||||
LogicalMaximum,
|
||||
PhysicalMinimum,
|
||||
PhysicalMaximum,
|
||||
UnitExponent,
|
||||
Unit,
|
||||
ReportSize,
|
||||
ReportID,
|
||||
ReportCount,
|
||||
Push,
|
||||
Pop
|
||||
} GlobalItemTag;
|
||||
|
||||
typedef enum {
|
||||
Usage,
|
||||
UsageMinimum,
|
||||
UsageMaximum,
|
||||
DesignatorIndex,
|
||||
DesignatorMinimum,
|
||||
DesignatorMaximum,
|
||||
StringIndex,
|
||||
StringMinimum,
|
||||
StringMaximum,
|
||||
Delimiter
|
||||
} LocalItemTag;
|
||||
|
||||
typedef struct {
|
||||
int32_t item_value;
|
||||
uint16_t item_size;
|
||||
@ -140,6 +183,22 @@ int btstack_hid_parser_has_more(btstack_hid_parser_t * parser);
|
||||
*/
|
||||
void btstack_hid_parser_get_field(btstack_hid_parser_t * parser, uint16_t * usage_page, uint16_t * usage, int32_t * value);
|
||||
|
||||
/**
|
||||
* @brief Parses descriptor item
|
||||
* @param item
|
||||
* @param hid_descriptor
|
||||
* @param hid_descriptor_len
|
||||
*/
|
||||
void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len);
|
||||
|
||||
/**
|
||||
* @brief Parses descriptor and returns report size for given report ID and report type
|
||||
* @param report_id
|
||||
* @param report_type
|
||||
* @param hid_descriptor_len
|
||||
* @param hid_descriptor
|
||||
*/
|
||||
int btstack_hid_get_report_size_for_id(int report_id, btstack_hid_report_type_t report_type, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor);
|
||||
/* API_END */
|
||||
|
||||
#if defined __cplusplus
|
||||
|
1
test/hid_parser/.gitignore
vendored
Normal file
1
test/hid_parser/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
hid_parser_test
|
@ -218,6 +218,8 @@ const uint8_t keyboard_report1[] = { 0x01, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0
|
||||
const uint8_t combo_report1[] = { 0x01, 0x03, 0x02, 0x03 };
|
||||
const uint8_t combo_report2[] = { 0x02, 0x01, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00 };
|
||||
|
||||
|
||||
|
||||
static void expect_field(btstack_hid_parser_t * parser, uint16_t expected_usage_page, uint16_t expected_usage, int32_t expected_value){
|
||||
// printf("expected - usage page %02x, usage %04x, value %02x (bit pos %u)\n", expected_usage_page, expected_usage, expected_value, parser->report_pos_in_bit);
|
||||
CHECK_EQUAL(1, btstack_hid_parser_has_more(parser));
|
||||
@ -326,6 +328,22 @@ TEST(HID, Combo2){
|
||||
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
|
||||
}
|
||||
|
||||
TEST(HID, GetReportSize){
|
||||
int report_size = 0;
|
||||
const uint8_t * hid_descriptor = combo_descriptor_with_report_ids;
|
||||
uint16_t hid_descriptor_len = sizeof(combo_descriptor_with_report_ids);
|
||||
// report_size = btstack_hid_get_report_size_for_id(1, BTSTACK_HID_REPORT_TYPE_INPUT, hid_descriptor_len, hid_descriptor);
|
||||
// CHECK_EQUAL(3, report_size);
|
||||
|
||||
hid_descriptor = hid_descriptor_keyboard_boot_mode;
|
||||
hid_descriptor_len = sizeof(hid_descriptor_keyboard_boot_mode);
|
||||
report_size = btstack_hid_get_report_size_for_id(0, BTSTACK_HID_REPORT_TYPE_OUTPUT, hid_descriptor_len, hid_descriptor);
|
||||
CHECK_EQUAL(1, report_size);
|
||||
report_size = btstack_hid_get_report_size_for_id(0, BTSTACK_HID_REPORT_TYPE_INPUT, hid_descriptor_len, hid_descriptor);
|
||||
CHECK_EQUAL(8, report_size);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, const char * argv[]){
|
||||
// hci_dump_open("hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
return CommandLineTestRunner::RunAllTests(argc, argv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user