diff --git a/src/btstack_hid_parser.c b/src/btstack_hid_parser.c index 5cb4194a0..89f37d98c 100644 --- a/src/btstack_hid_parser.c +++ b/src/btstack_hid_parser.c @@ -439,7 +439,6 @@ int btstack_hid_get_report_size_for_id(int report_id, hid_report_type_t report_t 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 != HID_REPORT_TYPE_INPUT) break; @@ -468,4 +467,53 @@ int btstack_hid_get_report_size_for_id(int report_id, hid_report_type_t report_t hid_descriptor += item.item_size; } return (total_report_size + 7)/8; +} + +hid_report_id_status_t btstack_hid_id_valid(int report_id, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor){ + int current_report_id = 0; + while (hid_descriptor_len){ + hid_descriptor_item_t item; + 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; + // printf("current ID %d, searched ID %d\n", current_report_id, report_id); + if (current_report_id != report_id) break; + return HID_REPORT_ID_VALID; + default: + break; + } + break; + default: + break; + } + hid_descriptor_len -= item.item_size; + hid_descriptor += item.item_size; + } + if (current_report_id != 0) return HID_REPORT_ID_INVALID; + return HID_REPORT_ID_UNDECLARED; +} + +int btstack_hid_report_id_declared(uint16_t hid_descriptor_len, const uint8_t * hid_descriptor){ + while (hid_descriptor_len){ + hid_descriptor_item_t item; + btstack_hid_parse_descriptor_item(&item, hid_descriptor, hid_descriptor_len); + switch (item.item_type){ + case Global: + switch ((GlobalItemTag)item.item_tag){ + case ReportID: + return 1; + default: + break; + } + break; + default: + break; + } + hid_descriptor_len -= item.item_size; + hid_descriptor += item.item_size; + } + return 0; } \ No newline at end of file diff --git a/src/btstack_hid_parser.h b/src/btstack_hid_parser.h index ec31b5966..1a392083d 100644 --- a/src/btstack_hid_parser.h +++ b/src/btstack_hid_parser.h @@ -114,6 +114,12 @@ typedef enum { HID_REPORT_TYPE_FEATURE } hid_report_type_t; +typedef enum { + HID_REPORT_ID_UNDECLARED, + HID_REPORT_ID_VALID, + HID_REPORT_ID_INVALID +} hid_report_id_status_t; + typedef struct { // Descriptor @@ -199,6 +205,21 @@ void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8 * @param hid_descriptor */ int btstack_hid_get_report_size_for_id(int report_id, hid_report_type_t report_type, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor); + +/** + * @brief Parses descriptor and returns report size for given report ID and report type + * @param report_id + * @param hid_descriptor_len + * @param hid_descriptor + */ +hid_report_id_status_t btstack_hid_id_valid(int report_id, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor); + +/** + * @brief Parses descriptor and returns 1 if report ID found + * @param hid_descriptor_len + * @param hid_descriptor + */ +int btstack_hid_report_id_declared(uint16_t hid_descriptor_len, const uint8_t * hid_descriptor); /* API_END */ #if defined __cplusplus diff --git a/src/classic/hid_device.c b/src/classic/hid_device.c index 6a1eba185..9dec4c945 100644 --- a/src/classic/hid_device.c +++ b/src/classic/hid_device.c @@ -79,7 +79,6 @@ typedef struct hid_device { static hid_device_t _hid_device; static uint8_t hid_boot_protocol_mode_supported; -static uint8_t hid_report_ids_declared; static const uint8_t * hid_descriptor; static uint16_t hid_descriptor_len; @@ -383,7 +382,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * pack switch (device->protocol_mode){ case HID_PROTOCOL_MODE_BOOT: // printf("HID_PROTOCOL_MODE_BOOT \n"); - if (!hid_report_ids_declared || packet_size < 2){ + if (!btstack_hid_report_id_declared(hid_descriptor_len, hid_descriptor) || packet_size < 2){ device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER; break; } @@ -391,7 +390,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * pack break; case HID_PROTOCOL_MODE_REPORT: // printf("HID_PROTOCOL_MODE_REPORT, hid_report_ids_declared %d\n", hid_report_ids_declared); - if (!hid_report_ids_declared) break; + if (!btstack_hid_report_id_declared(hid_descriptor_len, hid_descriptor)) break; if (packet_size < 2){ device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER; @@ -410,7 +409,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * pack // l2cap_request_can_send_now_event(device->control_cid); hid_device_request_can_send_now_event(channel); break; - + case HID_MESSAGE_TYPE_SET_REPORT: device->state = HID_DEVICE_W2_SET_REPORT; device->max_packet_size = l2cap_max_mtu(); @@ -862,3 +861,18 @@ int hid_report_size_valid(uint16_t cid, int report_id, hid_report_type_t report_ } return 1; } + + +hid_report_id_status_t hid_report_id_status(uint16_t cid, uint16_t report_id){ + if (hid_device_in_boot_protocol_mode(cid)){ + switch (report_id){ + case HID_BOOT_MODE_KEYBOARD_ID: + case HID_BOOT_MODE_MOUSE_ID: + return HID_REPORT_ID_VALID; + default: + return HID_REPORT_ID_INVALID; + } + } else { + return btstack_hid_id_valid(report_id, hid_descriptor_len, hid_descriptor); + } +} \ No newline at end of file diff --git a/src/classic/hid_device.h b/src/classic/hid_device.h index 6f67a075f..1059794a0 100644 --- a/src/classic/hid_device.h +++ b/src/classic/hid_device.h @@ -90,12 +90,6 @@ typedef enum { HID_PROTOCOL_MODE_REPORT } hid_protocol_mode_t; -typedef enum { - HID_REPORT_ID_UNDECLARED, - HID_REPORT_ID_VALID, - HID_REPORT_ID_INVALID -} hid_report_id_status_t; - /** * @brief Create HID Device SDP service record. * @param service Empty buffer in which a new service record will be stored. @@ -197,6 +191,7 @@ int hid_device_in_boot_protocol_mode(uint16_t hid_cid); int hid_report_size_valid(uint16_t cid, int report_id, hid_report_type_t report_type, int report_size); +hid_report_id_status_t hid_report_id_status(uint16_t cid, uint16_t report_id); /* API_END */ /* Only needed for PTS Testing */ diff --git a/test/pts/hid_device_test.c b/test/pts/hid_device_test.c index 094358a13..d2fec2146 100644 --- a/test/pts/hid_device_test.c +++ b/test/pts/hid_device_test.c @@ -281,24 +281,6 @@ static int prepare_keyboard_report(hid_report_type_t report_type, int modifier, return pos; } -static hid_report_id_status_t hid_report_id_status(uint16_t cid, uint16_t report_id){ - if (hid_device_in_boot_protocol_mode(cid)){ - switch (report_id){ - case HID_BOOT_MODE_KEYBOARD_ID: - case HID_BOOT_MODE_MOUSE_ID: - return HID_REPORT_ID_VALID; - default: - return HID_REPORT_ID_INVALID; - } - } else { -#ifdef REPORT_ID_DECLARED - if (report_id != 1) return HID_REPORT_ID_INVALID; - return HID_REPORT_ID_VALID; -#endif - return HID_REPORT_ID_UNDECLARED; - } -} - static hid_handshake_param_type_t hid_get_report_callback(uint16_t cid, hid_report_type_t report_type, uint16_t report_id, uint8_t report_max_size, int * out_report_size, uint8_t * out_report){ UNUSED(cid); UNUSED(report_max_size); @@ -347,10 +329,6 @@ static hid_handshake_param_type_t hid_set_report_callback(uint16_t cid, hid_repo UNUSED(cid); UNUSED(report); int pos = 0; - - printf("set report, size %d\n", report_size); - printf_hexdump(report, report_size); - printf("\n"); int report_id = report[0]; hid_report_id_status_t report_id_status = hid_report_id_status(cid, report_id); @@ -365,7 +343,6 @@ static hid_handshake_param_type_t hid_set_report_callback(uint16_t cid, hid_repo report_id = 0; break; } - printf(" report_id %d \n", report_id); if (!hid_report_size_valid(cid, report_id, report_type, report_size-pos)){ printf("invalid report size\n");