btstack/test/hid_parser/hid_parser_test.c

333 lines
15 KiB
C

// *****************************************************************************
//
// HID Parser Test
//
// *****************************************************************************
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CppUTest/TestHarness.h"
#include "CppUTest/CommandLineTestRunner.h"
#include "btstack_hid_parser.h"
const uint8_t mouse_descriptor_without_report_id[] = {
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x02, /* Usage (Mouse), */
0xA1, 0x01, /* Collection (Application), */
0x09, 0x01, /* Usage (Pointer), */
0xA0, /* Collection (Physical), */
0x05, 0x09, /* Usage Page (Button), */
0x19, 0x01, /* Usage Minimum (01h), */
0x29, 0x03, /* Usage Maximum (03h), */
0x14, /* Logical Minimum (0), */
0x25, 0x01, /* Logical Maximum (1), */
0x75, 0x01, /* Report Size (1), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x02, /* Input (Variable), */
0x75, 0x05, /* Report Size (5), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x01, /* Input (Constant), */
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x30, /* Usage (X), */
0x09, 0x31, /* Usage (Y), */
0x15, 0x81, /* Logical Minimum (-127), */
0x25, 0x7F, /* Logical Maximum (127), */
0x75, 0x08, /* Report Size (8), */
0x95, 0x02, /* Report Count (2), */
0x81, 0x06, /* Input (Variable, Relative), */
0xC0, /* End Collection, */
0xC0 /* End Collection */
};
const uint8_t mouse_descriptor_with_report_id[] = {
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x02, /* Usage (Mouse), */
0xA1, 0x01, /* Collection (Application), */
0x85, 0x01, // Report ID 1
0x09, 0x01, /* Usage (Pointer), */
0xA0, /* Collection (Physical), */
0x05, 0x09, /* Usage Page (Button), */
0x19, 0x01, /* Usage Minimum (01h), */
0x29, 0x03, /* Usage Maximum (03h), */
0x14, /* Logical Minimum (0), */
0x25, 0x01, /* Logical Maximum (1), */
0x75, 0x01, /* Report Size (1), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x02, /* Input (Variable), */
0x75, 0x05, /* Report Size (5), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x01, /* Input (Constant), */
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x30, /* Usage (X), */
0x09, 0x31, /* Usage (Y), */
0x15, 0x81, /* Logical Minimum (-127), */
0x25, 0x7F, /* Logical Maximum (127), */
0x75, 0x08, /* Report Size (8), */
0x95, 0x02, /* Report Count (2), */
0x81, 0x06, /* Input (Variable, Relative), */
0xC0, /* End Collection, */
0xC0 /* End Collection */
};
// from USB HID Specification 1.1, Appendix B.1
const uint8_t hid_descriptor_keyboard_boot_mode[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
// Modifier byte
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x05, 0x07, // Usage Page (Key codes)
0x19, 0xe0, // Usage Minimum (Keyboard LeftControl)
0x29, 0xe7, // Usage Maxium (Keyboard Right GUI)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
// Reserved byte
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x03, // Input (Constant, Variable, Absolute)
// LED report + padding
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maxium (Kana)
0x91, 0x02, // Output (Data, Variable, Absolute)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Constant, Variable, Absolute)
// Keycodes
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0xff, // Logical Maximum (1)
0x05, 0x07, // Usage Page (Key codes)
0x19, 0x00, // Usage Minimum (Reserved (no event indicated))
0x29, 0xff, // Usage Maxium (Reserved)
0x81, 0x00, // Input (Data, Array)
0xc0, // End collection
};
const uint8_t combo_descriptor_with_report_ids[] = {
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x02, /* Usage (Mouse), */
0xA1, 0x01, /* Collection (Application), */
0x85, 0x01, // Report ID 1
0x09, 0x01, /* Usage (Pointer), */
0xA0, /* Collection (Physical), */
0x05, 0x09, /* Usage Page (Button), */
0x19, 0x01, /* Usage Minimum (01h), */
0x29, 0x03, /* Usage Maximum (03h), */
0x14, /* Logical Minimum (0), */
0x25, 0x01, /* Logical Maximum (1), */
0x75, 0x01, /* Report Size (1), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x02, /* Input (Variable), */
0x75, 0x05, /* Report Size (5), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x01, /* Input (Constant), */
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x30, /* Usage (X), */
0x09, 0x31, /* Usage (Y), */
0x15, 0x81, /* Logical Minimum (-127), */
0x25, 0x7F, /* Logical Maximum (127), */
0x75, 0x08, /* Report Size (8), */
0x95, 0x02, /* Report Count (2), */
0x81, 0x06, /* Input (Variable, Relative), */
0xC0, /* End Collection, */
0xC0, /* End Collection */
0xa1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID 2
// Modifier byte
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x05, 0x07, // Usage Page (Key codes)
0x19, 0xe0, // Usage Minimum (Keyboard LeftControl)
0x29, 0xe7, // Usage Maxium (Keyboard Right GUI)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
// Reserved byte
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x03, // Input (Constant, Variable, Absolute)
// LED report + padding
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maxium (Kana)
0x91, 0x02, // Output (Data, Variable, Absolute)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Constant, Variable, Absolute)
// Keycodes
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0xff, // Logical Maximum (1)
0x05, 0x07, // Usage Page (Key codes)
0x19, 0x00, // Usage Minimum (Reserved (no event indicated))
0x29, 0xff, // Usage Maxium (Reserved)
0x81, 0x00, // Input (Data, Array)
0xc0, // En
};
const uint8_t mouse_report_without_id_positive_xy[] = { 0x03, 0x02, 0x03 };
const uint8_t mouse_report_without_id_negative_xy[] = { 0x03, 0xFE, 0xFD };
const uint8_t mouse_report_with_id_1[] = { 0x01, 0x03, 0x02, 0x03 };
const uint8_t keyboard_report1[] = { 0x01, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00 };
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));
uint16_t usage_page;
uint16_t usage;
int32_t value;
btstack_hid_parser_get_field(parser, &usage_page, &usage, &value);
CHECK_EQUAL(expected_usage_page, usage_page);
CHECK_EQUAL(expected_usage, usage);
CHECK_EQUAL(expected_value, value);
}
// test
TEST_GROUP(HID){
void setup(void){
}
};
TEST(HID, MouseWithoutReportID){
static btstack_hid_parser_t hid_parser;
btstack_hid_parser_init(&hid_parser, mouse_descriptor_without_report_id, sizeof(mouse_descriptor_without_report_id), BTSTACK_HID_REPORT_TYPE_INPUT, mouse_report_without_id_positive_xy, sizeof(mouse_report_without_id_positive_xy));
expect_field(&hid_parser, 9, 1, 1);
expect_field(&hid_parser, 9, 2, 1);
expect_field(&hid_parser, 9, 3, 0);
expect_field(&hid_parser, 1, 0x30, 2);
expect_field(&hid_parser, 1, 0x31, 3);
CHECK_EQUAL(24, hid_parser.report_pos_in_bit);
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
}
TEST(HID, MouseWithoutReportIDSigned){
static btstack_hid_parser_t hid_parser;
btstack_hid_parser_init(&hid_parser, mouse_descriptor_without_report_id, sizeof(mouse_descriptor_without_report_id), BTSTACK_HID_REPORT_TYPE_INPUT, mouse_report_without_id_negative_xy, sizeof(mouse_report_without_id_negative_xy));
expect_field(&hid_parser, 9, 1, 1);
expect_field(&hid_parser, 9, 2, 1);
expect_field(&hid_parser, 9, 3, 0);
expect_field(&hid_parser, 1, 0x30, -2);
expect_field(&hid_parser, 1, 0x31, -3);
CHECK_EQUAL(24, hid_parser.report_pos_in_bit);
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
}
TEST(HID, MouseWithReportID){
static btstack_hid_parser_t hid_parser;
btstack_hid_parser_init(&hid_parser, mouse_descriptor_with_report_id, sizeof(mouse_descriptor_with_report_id), BTSTACK_HID_REPORT_TYPE_INPUT, mouse_report_with_id_1, sizeof(mouse_report_with_id_1));
expect_field(&hid_parser, 9, 1, 1);
expect_field(&hid_parser, 9, 2, 1);
expect_field(&hid_parser, 9, 3, 0);
expect_field(&hid_parser, 1, 0x30, 2);
expect_field(&hid_parser, 1, 0x31, 3);
CHECK_EQUAL(32, hid_parser.report_pos_in_bit);
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
}
TEST(HID, BootKeyboard){
static btstack_hid_parser_t hid_parser;
btstack_hid_parser_init(&hid_parser, hid_descriptor_keyboard_boot_mode, sizeof(hid_descriptor_keyboard_boot_mode), BTSTACK_HID_REPORT_TYPE_INPUT, keyboard_report1, sizeof(keyboard_report1));
expect_field(&hid_parser, 7, 0xe0, 1);
expect_field(&hid_parser, 7, 0xe1, 0);
expect_field(&hid_parser, 7, 0xe2, 0);
expect_field(&hid_parser, 7, 0xe3, 0);
expect_field(&hid_parser, 7, 0xe4, 0);
expect_field(&hid_parser, 7, 0xe5, 0);
expect_field(&hid_parser, 7, 0xe6, 0);
expect_field(&hid_parser, 7, 0xe7, 0);
expect_field(&hid_parser, 7, 0x04, 1);
expect_field(&hid_parser, 7, 0x05, 1);
expect_field(&hid_parser, 7, 0x06, 1);
expect_field(&hid_parser, 7, 0x00, 1);
expect_field(&hid_parser, 7, 0x00, 1);
expect_field(&hid_parser, 7, 0x00, 1);
CHECK_EQUAL(64, hid_parser.report_pos_in_bit);
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
}
TEST(HID, Combo1){
static btstack_hid_parser_t hid_parser;
btstack_hid_parser_init(&hid_parser, combo_descriptor_with_report_ids, sizeof(combo_descriptor_with_report_ids), BTSTACK_HID_REPORT_TYPE_INPUT, combo_report1, sizeof(combo_report1));
expect_field(&hid_parser, 9, 1, 1);
expect_field(&hid_parser, 9, 2, 1);
expect_field(&hid_parser, 9, 3, 0);
expect_field(&hid_parser, 1, 0x30, 2);
expect_field(&hid_parser, 1, 0x31, 3);
CHECK_EQUAL(32, hid_parser.report_pos_in_bit);
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
}
TEST(HID, Combo2){
static btstack_hid_parser_t hid_parser;
btstack_hid_parser_init(&hid_parser, combo_descriptor_with_report_ids, sizeof(combo_descriptor_with_report_ids), BTSTACK_HID_REPORT_TYPE_INPUT, combo_report2, sizeof(combo_report2));
expect_field(&hid_parser, 7, 0xe0, 1);
expect_field(&hid_parser, 7, 0xe1, 0);
expect_field(&hid_parser, 7, 0xe2, 0);
expect_field(&hid_parser, 7, 0xe3, 0);
expect_field(&hid_parser, 7, 0xe4, 0);
expect_field(&hid_parser, 7, 0xe5, 0);
expect_field(&hid_parser, 7, 0xe6, 0);
expect_field(&hid_parser, 7, 0xe7, 0);
expect_field(&hid_parser, 7, 0x04, 1);
expect_field(&hid_parser, 7, 0x05, 1);
expect_field(&hid_parser, 7, 0x06, 1);
expect_field(&hid_parser, 7, 0x00, 1);
expect_field(&hid_parser, 7, 0x00, 1);
expect_field(&hid_parser, 7, 0x00, 1);
CHECK_EQUAL(72, hid_parser.report_pos_in_bit);
CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
}
int main (int argc, const char * argv[]){
// hci_dump_open("hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
return CommandLineTestRunner::RunAllTests(argc, argv);
}