xref: /btstack/src/btstack_hid_parser.h (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
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
23*2fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald  * GMBH 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 
38fe5a6c4eSMilanka Ringwald /**
39fe5a6c4eSMilanka Ringwald  * @title HID Parser
4012ccb71bSMatthias Ringwald  *
41fe5a6c4eSMilanka Ringwald  * Single-pass HID Report Parser: HID Report is directly parsed without preprocessing HID Descriptor to minimize memory.
42fe5a6c4eSMilanka Ringwald  *
4312ccb71bSMatthias Ringwald  */
4412ccb71bSMatthias Ringwald 
4580e33422SMatthias Ringwald #ifndef BTSTACK_HID_PARSER_H
4680e33422SMatthias Ringwald #define BTSTACK_HID_PARSER_H
4712ccb71bSMatthias Ringwald 
4812ccb71bSMatthias Ringwald #include <stdint.h>
493cbedd43SMatthias Ringwald #include "btstack_hid.h"
5012ccb71bSMatthias Ringwald 
5112ccb71bSMatthias Ringwald #if defined __cplusplus
5212ccb71bSMatthias Ringwald extern "C" {
5312ccb71bSMatthias Ringwald #endif
5412ccb71bSMatthias Ringwald 
55fada7179SMilanka Ringwald typedef enum {
56fada7179SMilanka Ringwald     Main=0,
57fada7179SMilanka Ringwald     Global,
58fada7179SMilanka Ringwald     Local,
59fada7179SMilanka Ringwald     Reserved
60fada7179SMilanka Ringwald } TagType;
61fada7179SMilanka Ringwald 
62fada7179SMilanka Ringwald typedef enum {
63fada7179SMilanka Ringwald     Input=8,
64fada7179SMilanka Ringwald     Output,
65fada7179SMilanka Ringwald     Coll,
66fada7179SMilanka Ringwald     Feature,
67fada7179SMilanka Ringwald     EndColl
68fada7179SMilanka Ringwald } MainItemTag;
69fada7179SMilanka Ringwald 
70fada7179SMilanka Ringwald typedef enum {
71fada7179SMilanka Ringwald     UsagePage,
72fada7179SMilanka Ringwald     LogicalMinimum,
73fada7179SMilanka Ringwald     LogicalMaximum,
74fada7179SMilanka Ringwald     PhysicalMinimum,
75fada7179SMilanka Ringwald     PhysicalMaximum,
76fada7179SMilanka Ringwald     UnitExponent,
77fada7179SMilanka Ringwald     Unit,
78fada7179SMilanka Ringwald     ReportSize,
79fada7179SMilanka Ringwald     ReportID,
80fada7179SMilanka Ringwald     ReportCount,
81fada7179SMilanka Ringwald     Push,
82fada7179SMilanka Ringwald     Pop
83fada7179SMilanka Ringwald } GlobalItemTag;
84fada7179SMilanka Ringwald 
85fada7179SMilanka Ringwald typedef enum {
86fada7179SMilanka Ringwald     Usage,
87fada7179SMilanka Ringwald     UsageMinimum,
88fada7179SMilanka Ringwald     UsageMaximum,
89fada7179SMilanka Ringwald     DesignatorIndex,
90fada7179SMilanka Ringwald     DesignatorMinimum,
91fada7179SMilanka Ringwald     DesignatorMaximum,
92fada7179SMilanka Ringwald     StringIndex,
93fada7179SMilanka Ringwald     StringMinimum,
94fada7179SMilanka Ringwald     StringMaximum,
95fada7179SMilanka Ringwald     Delimiter
96fada7179SMilanka Ringwald } LocalItemTag;
97fada7179SMilanka Ringwald 
9812ccb71bSMatthias Ringwald typedef struct  {
9912ccb71bSMatthias Ringwald     int32_t  item_value;
10012ccb71bSMatthias Ringwald     uint16_t item_size;
10112ccb71bSMatthias Ringwald     uint8_t  item_type;
10212ccb71bSMatthias Ringwald     uint8_t  item_tag;
10312ccb71bSMatthias Ringwald     uint8_t  data_size;
10412ccb71bSMatthias Ringwald } hid_descriptor_item_t;
10512ccb71bSMatthias Ringwald 
10612ccb71bSMatthias Ringwald typedef enum {
10712ccb71bSMatthias Ringwald     BTSTACK_HID_PARSER_SCAN_FOR_REPORT_ITEM,
10812ccb71bSMatthias Ringwald     BTSTACK_HID_PARSER_USAGES_AVAILABLE,
10912ccb71bSMatthias Ringwald     BTSTACK_HID_PARSER_COMPLETE,
11012ccb71bSMatthias Ringwald } btstack_hid_parser_state_t;
11112ccb71bSMatthias Ringwald 
112dbcaefc7SMilanka Ringwald 
11312ccb71bSMatthias Ringwald typedef struct {
11412ccb71bSMatthias Ringwald 
11512ccb71bSMatthias Ringwald     // Descriptor
11612ccb71bSMatthias Ringwald     const uint8_t * descriptor;
11712ccb71bSMatthias Ringwald     uint16_t        descriptor_len;
11812ccb71bSMatthias Ringwald 
11912ccb71bSMatthias Ringwald     // Report
120662cddc2SMilanka Ringwald     hid_report_type_t report_type;
12112ccb71bSMatthias Ringwald     const uint8_t * report;
12212ccb71bSMatthias Ringwald     uint16_t        report_len;
12312ccb71bSMatthias Ringwald 
12412ccb71bSMatthias Ringwald     // State
12512ccb71bSMatthias Ringwald     btstack_hid_parser_state_t state;
12612ccb71bSMatthias Ringwald 
12712ccb71bSMatthias Ringwald     hid_descriptor_item_t descriptor_item;
12812ccb71bSMatthias Ringwald 
12912ccb71bSMatthias Ringwald     uint16_t        descriptor_pos;
13012ccb71bSMatthias Ringwald     uint16_t        report_pos_in_bit;
13112ccb71bSMatthias Ringwald 
13212ccb71bSMatthias Ringwald     // usage pos and usage_page after last main item, used to find next usage
13312ccb71bSMatthias Ringwald     uint16_t        usage_pos;
13412ccb71bSMatthias Ringwald     uint16_t        usage_page;
13512ccb71bSMatthias Ringwald 
13612ccb71bSMatthias Ringwald     // usage generator
13712ccb71bSMatthias Ringwald     uint32_t        usage_minimum;
13812ccb71bSMatthias Ringwald     uint32_t        usage_maximum;
13912ccb71bSMatthias Ringwald     uint16_t        available_usages;
14012ccb71bSMatthias Ringwald     uint8_t         required_usages;
14112ccb71bSMatthias Ringwald     uint8_t         active_record;
14212ccb71bSMatthias Ringwald     uint8_t         have_usage_min;
14312ccb71bSMatthias Ringwald     uint8_t         have_usage_max;
14412ccb71bSMatthias Ringwald 
14512ccb71bSMatthias Ringwald     // global
14612ccb71bSMatthias Ringwald     int32_t         global_logical_minimum;
14712ccb71bSMatthias Ringwald     int32_t         global_logical_maximum;
14812ccb71bSMatthias Ringwald     uint16_t        global_usage_page;
14912ccb71bSMatthias Ringwald     uint8_t         global_report_size;
15012ccb71bSMatthias Ringwald     uint8_t         global_report_count;
15112ccb71bSMatthias Ringwald     uint8_t         global_report_id;
15212ccb71bSMatthias Ringwald } btstack_hid_parser_t;
15312ccb71bSMatthias Ringwald 
15412ccb71bSMatthias Ringwald /* API_START */
15512ccb71bSMatthias Ringwald 
15612ccb71bSMatthias Ringwald /**
15712ccb71bSMatthias Ringwald  * @brief Initialize HID Parser.
15812ccb71bSMatthias Ringwald  * @param parser state
15912ccb71bSMatthias Ringwald  * @param hid_descriptor
16012ccb71bSMatthias Ringwald  * @param hid_descriptor_len
16112ccb71bSMatthias Ringwald  * @param hid_report_type
16212ccb71bSMatthias Ringwald  * @param hid_report
16312ccb71bSMatthias Ringwald  * @param hid_report_len
16412ccb71bSMatthias Ringwald  */
165662cddc2SMilanka 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);
16612ccb71bSMatthias Ringwald 
16712ccb71bSMatthias Ringwald /**
16812ccb71bSMatthias Ringwald  * @brief Checks if more fields are available
16912ccb71bSMatthias Ringwald  * @param parser
17012ccb71bSMatthias Ringwald  */
17112ccb71bSMatthias Ringwald int  btstack_hid_parser_has_more(btstack_hid_parser_t * parser);
17212ccb71bSMatthias Ringwald 
17312ccb71bSMatthias Ringwald /**
17412ccb71bSMatthias Ringwald  * @brief Get next field
17512ccb71bSMatthias Ringwald  * @param parser
17612ccb71bSMatthias Ringwald  * @param usage_page
17712ccb71bSMatthias Ringwald  * @param usage
17812ccb71bSMatthias Ringwald  * @param value provided in HID report
17912ccb71bSMatthias Ringwald  */
18012ccb71bSMatthias Ringwald void btstack_hid_parser_get_field(btstack_hid_parser_t * parser, uint16_t * usage_page, uint16_t * usage, int32_t * value);
18112ccb71bSMatthias Ringwald 
182fada7179SMilanka Ringwald /**
183fada7179SMilanka Ringwald  * @brief Parses descriptor item
184fada7179SMilanka Ringwald  * @param item
185fada7179SMilanka Ringwald  * @param hid_descriptor
186fada7179SMilanka Ringwald  * @param hid_descriptor_len
187fada7179SMilanka Ringwald  */
188fada7179SMilanka Ringwald void btstack_hid_parse_descriptor_item(hid_descriptor_item_t * item, const uint8_t * hid_descriptor, uint16_t hid_descriptor_len);
189fada7179SMilanka Ringwald 
190fada7179SMilanka Ringwald /**
191fada7179SMilanka Ringwald  * @brief Parses descriptor and returns report size for given report ID and report type
192fada7179SMilanka Ringwald  * @param report_id
193fada7179SMilanka Ringwald  * @param report_type
194fada7179SMilanka Ringwald  * @param hid_descriptor_len
195fada7179SMilanka Ringwald  * @param hid_descriptor
196fada7179SMilanka Ringwald  */
197662cddc2SMilanka 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);
198dbcaefc7SMilanka Ringwald 
199dbcaefc7SMilanka Ringwald /**
200dbcaefc7SMilanka Ringwald  * @brief Parses descriptor and returns report size for given report ID and report type
201dbcaefc7SMilanka Ringwald  * @param report_id
202dbcaefc7SMilanka Ringwald  * @param hid_descriptor_len
203dbcaefc7SMilanka Ringwald  * @param hid_descriptor
204dbcaefc7SMilanka Ringwald  */
205dbcaefc7SMilanka Ringwald hid_report_id_status_t btstack_hid_id_valid(int report_id, uint16_t hid_descriptor_len, const uint8_t * hid_descriptor);
206dbcaefc7SMilanka Ringwald 
207dbcaefc7SMilanka Ringwald /**
208dbcaefc7SMilanka Ringwald  * @brief Parses descriptor and returns 1 if report ID found
209dbcaefc7SMilanka Ringwald  * @param hid_descriptor_len
210dbcaefc7SMilanka Ringwald  * @param hid_descriptor
211dbcaefc7SMilanka Ringwald  */
212dbcaefc7SMilanka Ringwald int btstack_hid_report_id_declared(uint16_t hid_descriptor_len, const uint8_t * hid_descriptor);
21312ccb71bSMatthias Ringwald /* API_END */
21412ccb71bSMatthias Ringwald 
21512ccb71bSMatthias Ringwald #if defined __cplusplus
21612ccb71bSMatthias Ringwald }
21712ccb71bSMatthias Ringwald #endif
21812ccb71bSMatthias Ringwald 
21980e33422SMatthias Ringwald #endif // BTSTACK_HID_PARSER_H
220