1 /* 2 * Copyright (C) 2017 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 /* 39 * btstack_hid_parser.h 40 * 41 * Single-pass HID Report Parser: HID Report is directly parsed without preprocessing HID Descriptor to minimize memory 42 */ 43 44 #ifndef __BTSTACK_HID_PARSER_H 45 #define __BTSTACK_HID_PARSER_H 46 47 #include <stdint.h> 48 49 #if defined __cplusplus 50 extern "C" { 51 #endif 52 53 typedef enum { 54 Main=0, 55 Global, 56 Local, 57 Reserved 58 } TagType; 59 60 typedef enum { 61 Input=8, 62 Output, 63 Coll, 64 Feature, 65 EndColl 66 } MainItemTag; 67 68 typedef enum { 69 UsagePage, 70 LogicalMinimum, 71 LogicalMaximum, 72 PhysicalMinimum, 73 PhysicalMaximum, 74 UnitExponent, 75 Unit, 76 ReportSize, 77 ReportID, 78 ReportCount, 79 Push, 80 Pop 81 } GlobalItemTag; 82 83 typedef enum { 84 Usage, 85 UsageMinimum, 86 UsageMaximum, 87 DesignatorIndex, 88 DesignatorMinimum, 89 DesignatorMaximum, 90 StringIndex, 91 StringMinimum, 92 StringMaximum, 93 Delimiter 94 } LocalItemTag; 95 96 typedef struct { 97 int32_t item_value; 98 uint16_t item_size; 99 uint8_t item_type; 100 uint8_t item_tag; 101 uint8_t data_size; 102 } hid_descriptor_item_t; 103 104 typedef enum { 105 BTSTACK_HID_PARSER_SCAN_FOR_REPORT_ITEM, 106 BTSTACK_HID_PARSER_USAGES_AVAILABLE, 107 BTSTACK_HID_PARSER_COMPLETE, 108 } btstack_hid_parser_state_t; 109 110 typedef enum { 111 HID_REPORT_TYPE_RESERVED = 0, 112 HID_REPORT_TYPE_INPUT, 113 HID_REPORT_TYPE_OUTPUT, 114 HID_REPORT_TYPE_FEATURE 115 } hid_report_type_t; 116 117 typedef struct { 118 119 // Descriptor 120 const uint8_t * descriptor; 121 uint16_t descriptor_len; 122 123 // Report 124 hid_report_type_t report_type; 125 const uint8_t * report; 126 uint16_t report_len; 127 128 // State 129 btstack_hid_parser_state_t state; 130 131 hid_descriptor_item_t descriptor_item; 132 133 uint16_t descriptor_pos; 134 uint16_t report_pos_in_bit; 135 136 // usage pos and usage_page after last main item, used to find next usage 137 uint16_t usage_pos; 138 uint16_t usage_page; 139 140 // usage generator 141 uint32_t usage_minimum; 142 uint32_t usage_maximum; 143 uint16_t available_usages; 144 uint8_t required_usages; 145 uint8_t active_record; 146 uint8_t have_usage_min; 147 uint8_t have_usage_max; 148 149 // global 150 int32_t global_logical_minimum; 151 int32_t global_logical_maximum; 152 uint16_t global_usage_page; 153 uint8_t global_report_size; 154 uint8_t global_report_count; 155 uint8_t global_report_id; 156 } btstack_hid_parser_t; 157 158 /* API_START */ 159 160 /** 161 * @brief Initialize HID Parser. 162 * @param parser state 163 * @param hid_descriptor 164 * @param hid_descriptor_len 165 * @param hid_report_type 166 * @param hid_report 167 * @param hid_report_len 168 */ 169 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); 170 171 /** 172 * @brief Checks if more fields are available 173 * @param parser 174 */ 175 int btstack_hid_parser_has_more(btstack_hid_parser_t * parser); 176 177 /** 178 * @brief Get next field 179 * @param parser 180 * @param usage_page 181 * @param usage 182 * @param value provided in HID report 183 */ 184 void btstack_hid_parser_get_field(btstack_hid_parser_t * parser, uint16_t * usage_page, uint16_t * usage, int32_t * value); 185 186 /** 187 * @brief Parses descriptor item 188 * @param item 189 * @param hid_descriptor 190 * @param hid_descriptor_len 191 */ 192 void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len); 193 194 /** 195 * @brief Parses descriptor and returns report size for given report ID and report type 196 * @param report_id 197 * @param report_type 198 * @param hid_descriptor_len 199 * @param hid_descriptor 200 */ 201 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); 202 /* API_END */ 203 204 #if defined __cplusplus 205 } 206 #endif 207 208 #endif // __BTSTACK_HID_PARSER_H 209