mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-18 05:42:49 +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
|
* 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 };
|
const int hid_item_sizes[] = { 0, 1, 2, 4 };
|
||||||
|
|
||||||
#ifdef HID_PARSER_PRETTY_PRINT
|
#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
|
// 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
|
// parse item header
|
||||||
if (hid_descriptor_len < 1) return;
|
if (hid_descriptor_len < 1) return;
|
||||||
uint16_t pos = 0;
|
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" {
|
extern "C" {
|
||||||
#endif
|
#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 {
|
typedef struct {
|
||||||
int32_t item_value;
|
int32_t item_value;
|
||||||
uint16_t item_size;
|
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);
|
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 */
|
/* API_END */
|
||||||
|
|
||||||
#if defined __cplusplus
|
#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_report1[] = { 0x01, 0x03, 0x02, 0x03 };
|
||||||
const uint8_t combo_report2[] = { 0x02, 0x01, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00 };
|
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){
|
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);
|
// 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));
|
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));
|
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[]){
|
int main (int argc, const char * argv[]){
|
||||||
// hci_dump_open("hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
|
// hci_dump_open("hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
|
||||||
return CommandLineTestRunner::RunAllTests(argc, argv);
|
return CommandLineTestRunner::RunAllTests(argc, argv);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user