112ccb71bSMatthias Ringwald /* 212ccb71bSMatthias Ringwald * Copyright (C) 2017 BlueKitchen GmbH 312ccb71bSMatthias Ringwald * 412ccb71bSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 512ccb71bSMatthias Ringwald * modification, are permitted provided that the following conditions 612ccb71bSMatthias Ringwald * are met: 712ccb71bSMatthias Ringwald * 812ccb71bSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 912ccb71bSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 1012ccb71bSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 1112ccb71bSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 1212ccb71bSMatthias Ringwald * documentation and/or other materials provided with the distribution. 1312ccb71bSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 1412ccb71bSMatthias Ringwald * contributors may be used to endorse or promote products derived 1512ccb71bSMatthias Ringwald * from this software without specific prior written permission. 1612ccb71bSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 1712ccb71bSMatthias Ringwald * personal benefit and not for any commercial purpose or for 1812ccb71bSMatthias Ringwald * monetary gain. 1912ccb71bSMatthias Ringwald * 2012ccb71bSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 2112ccb71bSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2212ccb71bSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2312ccb71bSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 2412ccb71bSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2512ccb71bSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2612ccb71bSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2712ccb71bSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2812ccb71bSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2912ccb71bSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 3012ccb71bSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3112ccb71bSMatthias Ringwald * SUCH DAMAGE. 3212ccb71bSMatthias Ringwald * 3312ccb71bSMatthias Ringwald * Please inquire about commercial licensing options at 3412ccb71bSMatthias Ringwald * [email protected] 3512ccb71bSMatthias Ringwald * 3612ccb71bSMatthias Ringwald */ 3712ccb71bSMatthias Ringwald 3812ccb71bSMatthias Ringwald /* 3912ccb71bSMatthias Ringwald * btstack_hid_parser.h 4012ccb71bSMatthias Ringwald * 4112ccb71bSMatthias Ringwald * Single-pass HID Report Parser: HID Report is directly parsed without preprocessing HID Descriptor to minimize memory 4212ccb71bSMatthias Ringwald */ 4312ccb71bSMatthias Ringwald 44*80e33422SMatthias Ringwald #ifndef BTSTACK_HID_PARSER_H 45*80e33422SMatthias Ringwald #define BTSTACK_HID_PARSER_H 4612ccb71bSMatthias Ringwald 4712ccb71bSMatthias Ringwald #include <stdint.h> 4812ccb71bSMatthias Ringwald 4912ccb71bSMatthias Ringwald #if defined __cplusplus 5012ccb71bSMatthias Ringwald extern "C" { 5112ccb71bSMatthias Ringwald #endif 5212ccb71bSMatthias Ringwald 53fada7179SMilanka Ringwald typedef enum { 54fada7179SMilanka Ringwald Main=0, 55fada7179SMilanka Ringwald Global, 56fada7179SMilanka Ringwald Local, 57fada7179SMilanka Ringwald Reserved 58fada7179SMilanka Ringwald } TagType; 59fada7179SMilanka Ringwald 60fada7179SMilanka Ringwald typedef enum { 61fada7179SMilanka Ringwald Input=8, 62fada7179SMilanka Ringwald Output, 63fada7179SMilanka Ringwald Coll, 64fada7179SMilanka Ringwald Feature, 65fada7179SMilanka Ringwald EndColl 66fada7179SMilanka Ringwald } MainItemTag; 67fada7179SMilanka Ringwald 68fada7179SMilanka Ringwald typedef enum { 69fada7179SMilanka Ringwald UsagePage, 70fada7179SMilanka Ringwald LogicalMinimum, 71fada7179SMilanka Ringwald LogicalMaximum, 72fada7179SMilanka Ringwald PhysicalMinimum, 73fada7179SMilanka Ringwald PhysicalMaximum, 74fada7179SMilanka Ringwald UnitExponent, 75fada7179SMilanka Ringwald Unit, 76fada7179SMilanka Ringwald ReportSize, 77fada7179SMilanka Ringwald ReportID, 78fada7179SMilanka Ringwald ReportCount, 79fada7179SMilanka Ringwald Push, 80fada7179SMilanka Ringwald Pop 81fada7179SMilanka Ringwald } GlobalItemTag; 82fada7179SMilanka Ringwald 83fada7179SMilanka Ringwald typedef enum { 84fada7179SMilanka Ringwald Usage, 85fada7179SMilanka Ringwald UsageMinimum, 86fada7179SMilanka Ringwald UsageMaximum, 87fada7179SMilanka Ringwald DesignatorIndex, 88fada7179SMilanka Ringwald DesignatorMinimum, 89fada7179SMilanka Ringwald DesignatorMaximum, 90fada7179SMilanka Ringwald StringIndex, 91fada7179SMilanka Ringwald StringMinimum, 92fada7179SMilanka Ringwald StringMaximum, 93fada7179SMilanka Ringwald Delimiter 94fada7179SMilanka Ringwald } LocalItemTag; 95fada7179SMilanka Ringwald 9612ccb71bSMatthias Ringwald typedef struct { 9712ccb71bSMatthias Ringwald int32_t item_value; 9812ccb71bSMatthias Ringwald uint16_t item_size; 9912ccb71bSMatthias Ringwald uint8_t item_type; 10012ccb71bSMatthias Ringwald uint8_t item_tag; 10112ccb71bSMatthias Ringwald uint8_t data_size; 10212ccb71bSMatthias Ringwald } hid_descriptor_item_t; 10312ccb71bSMatthias Ringwald 10412ccb71bSMatthias Ringwald typedef enum { 10512ccb71bSMatthias Ringwald BTSTACK_HID_PARSER_SCAN_FOR_REPORT_ITEM, 10612ccb71bSMatthias Ringwald BTSTACK_HID_PARSER_USAGES_AVAILABLE, 10712ccb71bSMatthias Ringwald BTSTACK_HID_PARSER_COMPLETE, 10812ccb71bSMatthias Ringwald } btstack_hid_parser_state_t; 10912ccb71bSMatthias Ringwald 110662cddc2SMilanka Ringwald typedef enum { 111662cddc2SMilanka Ringwald HID_REPORT_TYPE_RESERVED = 0, 112662cddc2SMilanka Ringwald HID_REPORT_TYPE_INPUT, 113662cddc2SMilanka Ringwald HID_REPORT_TYPE_OUTPUT, 114662cddc2SMilanka Ringwald HID_REPORT_TYPE_FEATURE 115662cddc2SMilanka Ringwald } hid_report_type_t; 116662cddc2SMilanka Ringwald 117dbcaefc7SMilanka Ringwald typedef enum { 118dbcaefc7SMilanka Ringwald HID_REPORT_ID_UNDECLARED, 119dbcaefc7SMilanka Ringwald HID_REPORT_ID_VALID, 120dbcaefc7SMilanka Ringwald HID_REPORT_ID_INVALID 121dbcaefc7SMilanka Ringwald } hid_report_id_status_t; 122dbcaefc7SMilanka Ringwald 12312ccb71bSMatthias Ringwald typedef struct { 12412ccb71bSMatthias Ringwald 12512ccb71bSMatthias Ringwald // Descriptor 12612ccb71bSMatthias Ringwald const uint8_t * descriptor; 12712ccb71bSMatthias Ringwald uint16_t descriptor_len; 12812ccb71bSMatthias Ringwald 12912ccb71bSMatthias Ringwald // Report 130662cddc2SMilanka Ringwald hid_report_type_t report_type; 13112ccb71bSMatthias Ringwald const uint8_t * report; 13212ccb71bSMatthias Ringwald uint16_t report_len; 13312ccb71bSMatthias Ringwald 13412ccb71bSMatthias Ringwald // State 13512ccb71bSMatthias Ringwald btstack_hid_parser_state_t state; 13612ccb71bSMatthias Ringwald 13712ccb71bSMatthias Ringwald hid_descriptor_item_t descriptor_item; 13812ccb71bSMatthias Ringwald 13912ccb71bSMatthias Ringwald uint16_t descriptor_pos; 14012ccb71bSMatthias Ringwald uint16_t report_pos_in_bit; 14112ccb71bSMatthias Ringwald 14212ccb71bSMatthias Ringwald // usage pos and usage_page after last main item, used to find next usage 14312ccb71bSMatthias Ringwald uint16_t usage_pos; 14412ccb71bSMatthias Ringwald uint16_t usage_page; 14512ccb71bSMatthias Ringwald 14612ccb71bSMatthias Ringwald // usage generator 14712ccb71bSMatthias Ringwald uint32_t usage_minimum; 14812ccb71bSMatthias Ringwald uint32_t usage_maximum; 14912ccb71bSMatthias Ringwald uint16_t available_usages; 15012ccb71bSMatthias Ringwald uint8_t required_usages; 15112ccb71bSMatthias Ringwald uint8_t active_record; 15212ccb71bSMatthias Ringwald uint8_t have_usage_min; 15312ccb71bSMatthias Ringwald uint8_t have_usage_max; 15412ccb71bSMatthias Ringwald 15512ccb71bSMatthias Ringwald // global 15612ccb71bSMatthias Ringwald int32_t global_logical_minimum; 15712ccb71bSMatthias Ringwald int32_t global_logical_maximum; 15812ccb71bSMatthias Ringwald uint16_t global_usage_page; 15912ccb71bSMatthias Ringwald uint8_t global_report_size; 16012ccb71bSMatthias Ringwald uint8_t global_report_count; 16112ccb71bSMatthias Ringwald uint8_t global_report_id; 16212ccb71bSMatthias Ringwald } btstack_hid_parser_t; 16312ccb71bSMatthias Ringwald 16412ccb71bSMatthias Ringwald /* API_START */ 16512ccb71bSMatthias Ringwald 16612ccb71bSMatthias Ringwald /** 16712ccb71bSMatthias Ringwald * @brief Initialize HID Parser. 16812ccb71bSMatthias Ringwald * @param parser state 16912ccb71bSMatthias Ringwald * @param hid_descriptor 17012ccb71bSMatthias Ringwald * @param hid_descriptor_len 17112ccb71bSMatthias Ringwald * @param hid_report_type 17212ccb71bSMatthias Ringwald * @param hid_report 17312ccb71bSMatthias Ringwald * @param hid_report_len 17412ccb71bSMatthias Ringwald */ 175662cddc2SMilanka Ringwald void btstack_hid_parser_init(btstack_hid_parser_t * parser, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len, hid_report_type_t hid_report_type, const uint8_t * hid_report, uint16_t hid_report_len); 17612ccb71bSMatthias Ringwald 17712ccb71bSMatthias Ringwald /** 17812ccb71bSMatthias Ringwald * @brief Checks if more fields are available 17912ccb71bSMatthias Ringwald * @param parser 18012ccb71bSMatthias Ringwald */ 18112ccb71bSMatthias Ringwald int btstack_hid_parser_has_more(btstack_hid_parser_t * parser); 18212ccb71bSMatthias Ringwald 18312ccb71bSMatthias Ringwald /** 18412ccb71bSMatthias Ringwald * @brief Get next field 18512ccb71bSMatthias Ringwald * @param parser 18612ccb71bSMatthias Ringwald * @param usage_page 18712ccb71bSMatthias Ringwald * @param usage 18812ccb71bSMatthias Ringwald * @param value provided in HID report 18912ccb71bSMatthias Ringwald */ 19012ccb71bSMatthias Ringwald void btstack_hid_parser_get_field(btstack_hid_parser_t * parser, uint16_t * usage_page, uint16_t * usage, int32_t * value); 19112ccb71bSMatthias Ringwald 192fada7179SMilanka Ringwald /** 193fada7179SMilanka Ringwald * @brief Parses descriptor item 194fada7179SMilanka Ringwald * @param item 195fada7179SMilanka Ringwald * @param hid_descriptor 196fada7179SMilanka Ringwald * @param hid_descriptor_len 197fada7179SMilanka Ringwald */ 198fada7179SMilanka Ringwald void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len); 199fada7179SMilanka Ringwald 200fada7179SMilanka Ringwald /** 201fada7179SMilanka Ringwald * @brief Parses descriptor and returns report size for given report ID and report type 202fada7179SMilanka Ringwald * @param report_id 203fada7179SMilanka Ringwald * @param report_type 204fada7179SMilanka Ringwald * @param hid_descriptor_len 205fada7179SMilanka Ringwald * @param hid_descriptor 206fada7179SMilanka Ringwald */ 207662cddc2SMilanka Ringwald 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); 208dbcaefc7SMilanka Ringwald 209dbcaefc7SMilanka Ringwald /** 210dbcaefc7SMilanka Ringwald * @brief Parses descriptor and returns report size for given report ID and report type 211dbcaefc7SMilanka Ringwald * @param report_id 212dbcaefc7SMilanka Ringwald * @param hid_descriptor_len 213dbcaefc7SMilanka Ringwald * @param hid_descriptor 214dbcaefc7SMilanka Ringwald */ 215dbcaefc7SMilanka Ringwald hid_report_id_status_t btstack_hid_id_valid(int report_id, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor); 216dbcaefc7SMilanka Ringwald 217dbcaefc7SMilanka Ringwald /** 218dbcaefc7SMilanka Ringwald * @brief Parses descriptor and returns 1 if report ID found 219dbcaefc7SMilanka Ringwald * @param hid_descriptor_len 220dbcaefc7SMilanka Ringwald * @param hid_descriptor 221dbcaefc7SMilanka Ringwald */ 222dbcaefc7SMilanka Ringwald int btstack_hid_report_id_declared(uint16_t hid_descriptor_len, const uint8_t * hid_descriptor); 22312ccb71bSMatthias Ringwald /* API_END */ 22412ccb71bSMatthias Ringwald 22512ccb71bSMatthias Ringwald #if defined __cplusplus 22612ccb71bSMatthias Ringwald } 22712ccb71bSMatthias Ringwald #endif 22812ccb71bSMatthias Ringwald 229*80e33422SMatthias Ringwald #endif // BTSTACK_HID_PARSER_H 230