163bf37cdSMilanka Ringwald /* 263bf37cdSMilanka Ringwald * Copyright (C) 2020 BlueKitchen GmbH 363bf37cdSMilanka Ringwald * 463bf37cdSMilanka Ringwald * Redistribution and use in source and binary forms, with or without 563bf37cdSMilanka Ringwald * modification, are permitted provided that the following conditions 663bf37cdSMilanka Ringwald * are met: 763bf37cdSMilanka Ringwald * 863bf37cdSMilanka Ringwald * 1. Redistributions of source code must retain the above copyright 963bf37cdSMilanka Ringwald * notice, this list of conditions and the following disclaimer. 1063bf37cdSMilanka Ringwald * 2. Redistributions in binary form must reproduce the above copyright 1163bf37cdSMilanka Ringwald * notice, this list of conditions and the following disclaimer in the 1263bf37cdSMilanka Ringwald * documentation and/or other materials provided with the distribution. 1363bf37cdSMilanka Ringwald * 3. Neither the name of the copyright holders nor the names of 1463bf37cdSMilanka Ringwald * contributors may be used to endorse or promote products derived 1563bf37cdSMilanka Ringwald * from this software without specific prior written permission. 1663bf37cdSMilanka Ringwald * 4. Any redistribution, use, or modification is done solely for 1763bf37cdSMilanka Ringwald * personal benefit and not for any commercial purpose or for 1863bf37cdSMilanka Ringwald * monetary gain. 1963bf37cdSMilanka Ringwald * 2063bf37cdSMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 2163bf37cdSMilanka Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2263bf37cdSMilanka Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2363bf37cdSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 2463bf37cdSMilanka Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2563bf37cdSMilanka Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2663bf37cdSMilanka Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2763bf37cdSMilanka Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2863bf37cdSMilanka Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2963bf37cdSMilanka Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 3063bf37cdSMilanka Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3163bf37cdSMilanka Ringwald * SUCH DAMAGE. 3263bf37cdSMilanka Ringwald * 3363bf37cdSMilanka Ringwald * Please inquire about commercial licensing options at 3463bf37cdSMilanka Ringwald * [email protected] 3563bf37cdSMilanka Ringwald * 3663bf37cdSMilanka Ringwald */ 3763bf37cdSMilanka Ringwald 3863bf37cdSMilanka Ringwald #ifndef HID_HOST_H 3963bf37cdSMilanka Ringwald #define HID_HOST_H 4063bf37cdSMilanka Ringwald 4163bf37cdSMilanka Ringwald #include <stdint.h> 4263bf37cdSMilanka Ringwald #include "btstack_defines.h" 4363bf37cdSMilanka Ringwald #include "bluetooth.h" 4463bf37cdSMilanka Ringwald #include "btstack_hid_parser.h" 4563bf37cdSMilanka Ringwald #include "classic/hid.h" 4663bf37cdSMilanka Ringwald 4763bf37cdSMilanka Ringwald #if defined __cplusplus 4863bf37cdSMilanka Ringwald extern "C" { 4963bf37cdSMilanka Ringwald #endif 5063bf37cdSMilanka Ringwald 5101977ed1SMilanka Ringwald 52fd7ba7a6SMilanka Ringwald typedef enum { 53fd7ba7a6SMilanka Ringwald HID_HOST_IDLE, 54fd7ba7a6SMilanka Ringwald HID_HOST_W2_SEND_SDP_QUERY, 55fd7ba7a6SMilanka Ringwald HID_HOST_W4_SDP_QUERY_RESULT, 56fd7ba7a6SMilanka Ringwald 57fd7ba7a6SMilanka Ringwald HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED, 58fd7ba7a6SMilanka Ringwald HID_HOST_CONTROL_CONNECTION_ESTABLISHED, 59fd7ba7a6SMilanka Ringwald 60fd7ba7a6SMilanka Ringwald HID_HOST_W4_SET_BOOT_MODE, 6101977ed1SMilanka Ringwald HID_HOST_W4_INCOMING_INTERRUPT_CONNECTION, 62fd7ba7a6SMilanka Ringwald HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED, 635961e155SMilanka Ringwald HID_HOST_W4_PROTOCOL_MODE_VERIFIED, 64fd7ba7a6SMilanka Ringwald HID_HOST_CONNECTION_ESTABLISHED, 65fd7ba7a6SMilanka Ringwald 66fd7ba7a6SMilanka Ringwald HID_HOST_W2_SEND_GET_REPORT, 67fd7ba7a6SMilanka Ringwald HID_HOST_W4_GET_REPORT_RESPONSE, 68fd7ba7a6SMilanka Ringwald HID_HOST_W2_SEND_SET_REPORT, 69fd7ba7a6SMilanka Ringwald HID_HOST_W4_SET_REPORT_RESPONSE, 70fd7ba7a6SMilanka Ringwald HID_HOST_W2_SEND_GET_PROTOCOL, 71fd7ba7a6SMilanka Ringwald HID_HOST_W4_GET_PROTOCOL_RESPONSE, 7201977ed1SMilanka Ringwald 73fd7ba7a6SMilanka Ringwald HID_HOST_W2_SEND_REPORT, 74ab30106eSMilanka Ringwald HID_HOST_W4_SEND_REPORT_RESPONSE, 75ab30106eSMilanka Ringwald 76ab30106eSMilanka Ringwald HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED, 77ab30106eSMilanka Ringwald HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED 78fd7ba7a6SMilanka Ringwald } hid_host_state_t; 79fd7ba7a6SMilanka Ringwald 80fd7ba7a6SMilanka Ringwald typedef struct { 81ab30106eSMilanka Ringwald btstack_linked_item_t item; 82ab30106eSMilanka Ringwald 83fd7ba7a6SMilanka Ringwald uint16_t hid_cid; 84fd7ba7a6SMilanka Ringwald hci_con_handle_t con_handle; 85fd7ba7a6SMilanka Ringwald 86fd7ba7a6SMilanka Ringwald bd_addr_t remote_addr; 87fd7ba7a6SMilanka Ringwald 88fd7ba7a6SMilanka Ringwald uint16_t control_cid; 89fd7ba7a6SMilanka Ringwald uint16_t control_psm; 90fd7ba7a6SMilanka Ringwald uint16_t interrupt_cid; 91fd7ba7a6SMilanka Ringwald uint16_t interrupt_psm; 92fd7ba7a6SMilanka Ringwald 93fd7ba7a6SMilanka Ringwald hid_host_state_t state; 9401977ed1SMilanka Ringwald bool incoming; 95fd7ba7a6SMilanka Ringwald hid_protocol_mode_t protocol_mode; 96fd7ba7a6SMilanka Ringwald 9701977ed1SMilanka Ringwald bool set_protocol; 9801977ed1SMilanka Ringwald bool w4_set_protocol_response; 9901977ed1SMilanka Ringwald hid_protocol_mode_t requested_protocol_mode; 10001977ed1SMilanka Ringwald 101fd7ba7a6SMilanka Ringwald uint16_t hid_descriptor_offset; 102fd7ba7a6SMilanka Ringwald uint16_t hid_descriptor_len; 103fd7ba7a6SMilanka Ringwald uint16_t hid_descriptor_max_len; 104fd7ba7a6SMilanka Ringwald 105fd7ba7a6SMilanka Ringwald uint8_t user_request_can_send_now; 106fd7ba7a6SMilanka Ringwald 107fd7ba7a6SMilanka Ringwald // get report 108fd7ba7a6SMilanka Ringwald hid_report_type_t report_type; 109fd7ba7a6SMilanka Ringwald uint8_t report_id; 110fd7ba7a6SMilanka Ringwald 11159a2ea74SMilanka Ringwald // control message, bit mask: 11259a2ea74SMilanka Ringwald // SUSSPEND 1 11359a2ea74SMilanka Ringwald // EXIT_SUSSPEND 2 11459a2ea74SMilanka Ringwald // VIRTUAL_CABLE_UNPLUG 4 11559a2ea74SMilanka Ringwald uint8_t control_tasks; 11659a2ea74SMilanka Ringwald 117fd7ba7a6SMilanka Ringwald // set report 118a93a968fSMilanka Ringwald const uint8_t * report; 119fd7ba7a6SMilanka Ringwald uint16_t report_len; 120fd7ba7a6SMilanka Ringwald } hid_host_connection_t; 121fd7ba7a6SMilanka Ringwald 12263bf37cdSMilanka Ringwald /* API_START */ 123*5f0d88b0SMilanka Ringwald 12463bf37cdSMilanka Ringwald /** 12563bf37cdSMilanka Ringwald * @brief Set up HID Host 12663bf37cdSMilanka Ringwald * @param hid_descriptor_storage 12763bf37cdSMilanka Ringwald * @param hid_descriptor_storage_len 12863bf37cdSMilanka Ringwald */ 129fd7ba7a6SMilanka Ringwald void hid_host_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len); 13063bf37cdSMilanka Ringwald 13163bf37cdSMilanka Ringwald /** 132*5f0d88b0SMilanka Ringwald * @brief Register callback for the HID Host. 13363bf37cdSMilanka Ringwald * @param callback 13463bf37cdSMilanka Ringwald */ 13563bf37cdSMilanka Ringwald void hid_host_register_packet_handler(btstack_packet_handler_t callback); 13663bf37cdSMilanka Ringwald 13763bf37cdSMilanka Ringwald /* 138*5f0d88b0SMilanka Ringwald * @brief Create HID connection to HID Device and emit HID_SUBEVENT_CONNECTION_OPENED event with status code. 139*5f0d88b0SMilanka Ringwald * @note HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT will try ti set up REPORT mode, but fallback to BOOT mode if necessary. 140*5f0d88b0SMilanka Ringwald * @note Reports from HID Device are received via HID_SUBEVENT_REPORT. 141fd7ba7a6SMilanka Ringwald * @param remote_addr 142*5f0d88b0SMilanka Ringwald * @param protocol_mode see hid_protocol_mode_t in hid.h 14363bf37cdSMilanka Ringwald * @param hid_cid to use for other commands 144*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_COMMAND_DISALLOWED, BTSTACK_MEMORY_ALLOC_FAILED 14563bf37cdSMilanka Ringwald */ 146fd7ba7a6SMilanka Ringwald uint8_t hid_host_connect(bd_addr_t remote_addr, hid_protocol_mode_t protocol_mode, uint16_t * hid_cid); 14763bf37cdSMilanka Ringwald 148*5f0d88b0SMilanka Ringwald 149*5f0d88b0SMilanka Ringwald /* 150*5f0d88b0SMilanka Ringwald * @brief Accept incoming HID connection, this should be called upon receiving HID_SUBEVENT_INCOMING_CONNECTION event. 151*5f0d88b0SMilanka Ringwald * @param hid_cid 152*5f0d88b0SMilanka Ringwald * @param protocol_mode see hid_protocol_mode_t in hid.h 153*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 154*5f0d88b0SMilanka Ringwald */ 15501977ed1SMilanka Ringwald uint8_t hid_host_accept_connection(uint16_t hid_cid, hid_protocol_mode_t protocol_mode); 156*5f0d88b0SMilanka Ringwald 157*5f0d88b0SMilanka Ringwald /* 158*5f0d88b0SMilanka Ringwald * @brief Decline incoming HID connection, this should be called upon receiving HID_SUBEVENT_INCOMING_CONNECTION event. 159*5f0d88b0SMilanka Ringwald * @param hid_cid 160*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 161*5f0d88b0SMilanka Ringwald */ 16259a2ea74SMilanka Ringwald uint8_t hid_host_decline_connection(uint16_t hid_cid); 16359a2ea74SMilanka Ringwald 16463bf37cdSMilanka Ringwald /* 165*5f0d88b0SMilanka Ringwald * @brief Disconnect from HID Device and emit HID_SUBEVENT_CONNECTION_CLOSED event. 16663bf37cdSMilanka Ringwald * @param hid_cid 16763bf37cdSMilanka Ringwald */ 16863bf37cdSMilanka Ringwald void hid_host_disconnect(uint16_t hid_cid); 16963bf37cdSMilanka Ringwald 17059a2ea74SMilanka Ringwald // Control messages: 171*5f0d88b0SMilanka Ringwald 172*5f0d88b0SMilanka Ringwald /* 173*5f0d88b0SMilanka Ringwald * @brief Send SUSPEND control signal to connected HID Device. A Bluetooth HID Device which receives a SUSPEND control signal 174*5f0d88b0SMilanka Ringwald * may optionally disconnect from the Bluetooth HID Host. 175*5f0d88b0SMilanka Ringwald * @param hid_cid 176*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 177*5f0d88b0SMilanka Ringwald */ 17859a2ea74SMilanka Ringwald uint8_t hid_host_send_suspend(uint16_t hid_cid); 179*5f0d88b0SMilanka Ringwald 180*5f0d88b0SMilanka Ringwald /* 181*5f0d88b0SMilanka Ringwald * @brief Order connected HID Device to exit suspend mode. 182*5f0d88b0SMilanka Ringwald * The Bluetooth HID Device shall send a report to the Bluetooth HID Host. 183*5f0d88b0SMilanka Ringwald * @param hid_cid 184*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 185*5f0d88b0SMilanka Ringwald */ 18659a2ea74SMilanka Ringwald uint8_t hid_host_send_exit_suspend(uint16_t hid_cid); 187*5f0d88b0SMilanka Ringwald 188*5f0d88b0SMilanka Ringwald /* 189*5f0d88b0SMilanka Ringwald * @brief Unplug connected HID Device. 190*5f0d88b0SMilanka Ringwald * @note This is the only command that can be also received from HID Device. It will be indicated by receiving 191*5f0d88b0SMilanka Ringwald * HID_SUBEVENT_VIRTUAL_CABLE_UNPLUG event, as well as disconnecting HID Host from device. 192*5f0d88b0SMilanka Ringwald * @param hid_cid 193*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 194*5f0d88b0SMilanka Ringwald */ 19559a2ea74SMilanka Ringwald uint8_t hid_host_send_virtual_cable_unplug(uint16_t hid_cid); 19663bf37cdSMilanka Ringwald 197*5f0d88b0SMilanka Ringwald /* 198*5f0d88b0SMilanka Ringwald * @brief Set Protocol Mode on the Bluetooth HID Device and emit HID_SUBEVENT_SET_PROTOCOL_RESPONSE event with handshake_status, see hid_handshake_param_type_t 199*5f0d88b0SMilanka Ringwald * @param hid_cid 200*5f0d88b0SMilanka Ringwald * @param protocol_mode see hid_protocol_mode_t in hid.h 201*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 202*5f0d88b0SMilanka Ringwald */ 203fe493a7cSMilanka Ringwald uint8_t hid_host_send_set_protocol_mode(uint16_t hid_cid, hid_protocol_mode_t protocol_mode); 204*5f0d88b0SMilanka Ringwald 205*5f0d88b0SMilanka Ringwald /* 206*5f0d88b0SMilanka Ringwald * @brief Retrieve the Protocol Mode of the Bluetooth HID Device and emit HID_SUBEVENT_GET_PROTOCOL_RESPONSE with handshake_status, see hid_handshake_param_type_t 207*5f0d88b0SMilanka Ringwald * @param hid_cid 208*5f0d88b0SMilanka Ringwald * @param protocol_mode see hid_protocol_mode_t in hid.h 209*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 210*5f0d88b0SMilanka Ringwald */ 211fe493a7cSMilanka Ringwald uint8_t hid_host_send_get_protocol(uint16_t hid_cid); 212fe493a7cSMilanka Ringwald 213*5f0d88b0SMilanka Ringwald /* 214*5f0d88b0SMilanka Ringwald 215*5f0d88b0SMilanka Ringwald * @brief Send report to a Bluetooth HID Device and emit HID_SUBEVENT_SET_REPORT_RESPONSE with handshake_status, see hid_handshake_param_type_t. The Bluetooth HID Host shall send complete reports. 216*5f0d88b0SMilanka Ringwald * @param hid_cid 217*5f0d88b0SMilanka Ringwald * @param report_type see hid_report_type_t in hid.h 218*5f0d88b0SMilanka Ringwald * @param report_id 219*5f0d88b0SMilanka Ringwald * @param report 220*5f0d88b0SMilanka Ringwald * @param report_len 221*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 222*5f0d88b0SMilanka Ringwald */ 223fe493a7cSMilanka Ringwald uint8_t hid_host_send_set_report(uint16_t hid_cid, hid_report_type_t report_type, uint8_t report_id, const uint8_t * report, uint8_t report_len); 224*5f0d88b0SMilanka Ringwald 225*5f0d88b0SMilanka Ringwald /* 226*5f0d88b0SMilanka Ringwald * @brief Request a HID report from the Bluetooth HID Device and emit HID_SUBEVENT_GET_REPORT_RESPONSE event with with handshake_status, see hid_handshake_param_type_t. 227*5f0d88b0SMilanka Ringwald * Polling Bluetooth HID Devices using the GET_REPORT transfer is costly in terms of time and overhead, 228*5f0d88b0SMilanka Ringwald * and should be avoided whenever possible. The GET_REPORT transfer is typically only used by applications 229*5f0d88b0SMilanka Ringwald * to determine the initial state of a Bluetooth HID Device. If the state of a report changes frequently, 230*5f0d88b0SMilanka Ringwald * then the report should be reported over the more efficient Interrupt channel, see hid_host_send_report. 231*5f0d88b0SMilanka Ringwald * @param hid_cid 232*5f0d88b0SMilanka Ringwald * @param report_type see hid_report_type_t in hid.h 233*5f0d88b0SMilanka Ringwald * @param report_id 234*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 235*5f0d88b0SMilanka Ringwald */ 236fe493a7cSMilanka Ringwald uint8_t hid_host_send_get_report(uint16_t hid_cid, hid_report_type_t report_type, uint8_t report_id); 237fe493a7cSMilanka Ringwald 23863bf37cdSMilanka Ringwald /** 239*5f0d88b0SMilanka Ringwald * @brief Send HID output report on interrupt channel. 24063bf37cdSMilanka Ringwald * @param hid_cid 241*5f0d88b0SMilanka Ringwald * @param report_id 242*5f0d88b0SMilanka Ringwald * @param report 243*5f0d88b0SMilanka Ringwald * @param report_len 244*5f0d88b0SMilanka Ringwald * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED 24563bf37cdSMilanka Ringwald */ 246fe493a7cSMilanka Ringwald uint8_t hid_host_send_report(uint16_t hid_cid, uint8_t report_id, const uint8_t * report, uint8_t report_len); 24763bf37cdSMilanka Ringwald 248*5f0d88b0SMilanka Ringwald /* 249*5f0d88b0SMilanka Ringwald * @brief Get descriptor data 250*5f0d88b0SMilanka Ringwald * @param hid_cid 251*5f0d88b0SMilanka Ringwald * @result data 252*5f0d88b0SMilanka Ringwald */ 253a93a968fSMilanka Ringwald const uint8_t * hid_descriptor_storage_get_descriptor_data(uint16_t hid_cid); 254*5f0d88b0SMilanka Ringwald 255*5f0d88b0SMilanka Ringwald /* 256*5f0d88b0SMilanka Ringwald * @brief Get descriptor length 257*5f0d88b0SMilanka Ringwald * @param hid_cid 258*5f0d88b0SMilanka Ringwald * @result length 259*5f0d88b0SMilanka Ringwald */ 260a93a968fSMilanka Ringwald const uint16_t hid_descriptor_storage_get_descriptor_len(uint16_t hid_cid); 261*5f0d88b0SMilanka Ringwald 26263bf37cdSMilanka Ringwald /* API_END */ 26363bf37cdSMilanka Ringwald 26463bf37cdSMilanka Ringwald 26563bf37cdSMilanka Ringwald #if defined __cplusplus 26663bf37cdSMilanka Ringwald } 26763bf37cdSMilanka Ringwald #endif 26863bf37cdSMilanka Ringwald 26963bf37cdSMilanka Ringwald #endif 270