1 /*
2  * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * SPDX-FileContributor: Blake Felt
7  */
8 
9 #ifndef __ESP_HIDH_API_H__
10 #define __ESP_HIDH_API_H__
11 
12 #include "esp_bt_defs.h"
13 #include "esp_err.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /// maximum size of HID Device report descriptor
20 #define BTHH_MAX_DSC_LEN 884
21 
22 /**
23  * @brief HID host connection state
24  */
25 typedef enum {
26     ESP_HIDH_CONN_STATE_CONNECTED = 0,           /*!< connected state */
27     ESP_HIDH_CONN_STATE_CONNECTING,              /*!< connecting state */
28     ESP_HIDH_CONN_STATE_DISCONNECTED,            /*!< disconnected state */
29     ESP_HIDH_CONN_STATE_DISCONNECTING,           /*!< disconnecting state */
30     ESP_HIDH_CONN_STATE_UNKNOWN                  /*!< unknown state (initial state) */
31 } esp_hidh_connection_state_t;
32 
33 /**
34  * @brief HID handshake error code and vendor-defined result code
35  */
36 typedef enum {
37     ESP_HIDH_OK,                /*!< successful */
38     ESP_HIDH_HS_HID_NOT_READY,  /*!< handshake error: device not ready */
39     ESP_HIDH_HS_INVALID_RPT_ID, /*!< handshake error: invalid report ID */
40     ESP_HIDH_HS_TRANS_NOT_SPT,  /*!< handshake error: HID device does not support the request */
41     ESP_HIDH_HS_INVALID_PARAM,  /*!< handshake error: parameter value does not meet the expected criteria of called function or API */
42     ESP_HIDH_HS_ERROR,          /*!< handshake error: HID device could not identify the error condition */
43     ESP_HIDH_ERR,               /*!< general ESP HID Host error */
44     ESP_HIDH_ERR_SDP,           /*!< SDP error */
45     ESP_HIDH_ERR_PROTO,         /*!< SET_PROTOCOL error, only used in ESP_HIDH_OPEN_EVT callback */
46     ESP_HIDH_ERR_DB_FULL,       /*!< device database full, used in ESP_HIDH_OPEN_EVT/ESP_HIDH_ADD_DEV_EVT */
47     ESP_HIDH_ERR_TOD_UNSPT,     /*!< type of device not supported */
48     ESP_HIDH_ERR_NO_RES,        /*!< out of system resources */
49     ESP_HIDH_ERR_AUTH_FAILED,   /*!< authentication fail */
50     ESP_HIDH_ERR_HDL,           /*!< connection handle error */
51     ESP_HIDH_ERR_SEC,           /*!< encryption error */
52     ESP_HIDH_BUSY,              /*!< vendor-defined: temporarily can not handle this request */
53     ESP_HIDH_NO_DATA,           /*!< vendor-defined: no data. */
54     ESP_HIDH_NEED_INIT,         /*!< vendor-defined: HIDH module shall initialize first */
55     ESP_HIDH_NEED_DEINIT,       /*!< vendor-defined: HIDH module shall de-deinitialize first */
56     ESP_HIDH_NO_CONNECTION,     /*!< vendor-defined: connection may have been closed */
57 } esp_hidh_status_t;
58 
59 /**
60  * @brief HID host protocol modes
61  */
62 typedef enum {
63     ESP_HIDH_BOOT_MODE = 0x00,       /*!< boot protocol mode */
64     ESP_HIDH_REPORT_MODE = 0x01,     /*!< report protocol mode */
65     ESP_HIDH_UNSUPPORTED_MODE = 0xff /*!< unsupported protocol mode */
66 } esp_hidh_protocol_mode_t;
67 
68 /**
69  * @brief HID host report types
70  */
71 typedef enum {
72     ESP_HIDH_REPORT_TYPE_OTHER = 0, /*!< unsupported report type */
73     ESP_HIDH_REPORT_TYPE_INPUT,     /*!< input report type */
74     ESP_HIDH_REPORT_TYPE_OUTPUT,    /*!< output report type */
75     ESP_HIDH_REPORT_TYPE_FEATURE,   /*!< feature report type */
76 } esp_hidh_report_type_t;
77 
78 /**
79  * @brief HID host callback function events
80  */
81 typedef enum {
82     ESP_HIDH_INIT_EVT = 0,  /*!< when HID host is initialized, the event comes */
83     ESP_HIDH_DEINIT_EVT,    /*!< when HID host is deinitialized, the event comes */
84     ESP_HIDH_OPEN_EVT,      /*!< when HID host connection opened, the event comes */
85     ESP_HIDH_CLOSE_EVT,     /*!< when HID host connection closed, the event comes */
86     ESP_HIDH_GET_RPT_EVT,   /*!< when Get_Report command is called, the event comes */
87     ESP_HIDH_SET_RPT_EVT,   /*!< when Set_Report command is called, the event comes */
88     ESP_HIDH_GET_PROTO_EVT, /*!< when Get_Protocol command is called, the event comes */
89     ESP_HIDH_SET_PROTO_EVT, /*!< when Set_Protocol command is called, the event comes */
90     ESP_HIDH_GET_IDLE_EVT,  /*!< when Get_Idle command is called, the event comes */
91     ESP_HIDH_SET_IDLE_EVT,  /*!< when Set_Idle command is called, the event comes */
92     ESP_HIDH_GET_DSCP_EVT,  /*!< when HIDH is initialized, the event comes */
93     ESP_HIDH_ADD_DEV_EVT,   /*!< when a device is added, the event comes */
94     ESP_HIDH_RMV_DEV_EVT,   /*!< when a device is removed, the event comes */
95     ESP_HIDH_VC_UNPLUG_EVT, /*!< when virtually unplugged, the event comes */
96     ESP_HIDH_DATA_EVT,      /*!< when send data on interrupt channel, the event comes */
97     ESP_HIDH_DATA_IND_EVT,  /*!< when receive data on interrupt channel, the event comes */
98     ESP_HIDH_SET_INFO_EVT   /*!< when set the HID device descriptor, the event comes */
99 } esp_hidh_cb_event_t;
100 
101 /**
102  * @brief HID device information from HID Device Service Record and Device ID Service Record
103  */
104 typedef enum {
105     ESP_HIDH_DEV_ATTR_VIRTUAL_CABLE = 0x0001,           /*!< whether Virtual Cables is supported */
106     ESP_HIDH_DEV_ATTR_NORMALLY_CONNECTABLE = 0x0002,    /*!< whether device is in Page Scan mode when there is no active connection */
107     ESP_HIDH_DEV_ATTR_RECONNECT_INITIATE = 0x0004,      /*!< whether the HID device inititates the reconnection process */
108 } esp_hidh_dev_attr_t;
109 
110 /**
111  * @brief application ID(non-zero) for each type of device
112  */
113 typedef enum {
114     ESP_HIDH_APP_ID_MOUSE = 1,                /*!< pointing device */
115     ESP_HIDH_APP_ID_KEYBOARD = 2,             /*!< keyboard */
116     ESP_HIDH_APP_ID_REMOTE_CONTROL = 3,       /*!< remote control */
117     ESP_HIDH_APP_ID_JOYSTICK = 5,             /*!< joystick */
118     ESP_HIDH_APP_ID_GAMEPAD = 6,              /*!< gamepad*/
119 } esp_hidh_dev_app_id_t;
120 
121 /**
122  * @brief HID device information from HID Device Service Record and Device ID Service Record
123  */
124 typedef struct {
125     int attr_mask;                            /*!< device attribute bit mask, refer to esp_hidh_dev_attr_t */
126     uint8_t sub_class;                        /*!< HID device subclass */
127     uint8_t app_id;                           /*!< application ID, refer to esp_hidh_dev_app_id_t */
128     int vendor_id;                            /*!< Device ID information: vendor ID */
129     int product_id;                           /*!< Device ID information: product ID */
130     int version;                              /*!< Device ID information: version */
131     uint8_t ctry_code;                        /*!< SDP attrbutes of HID devices: HID country code (https://www.usb.org/sites/default/files/hid1_11.pdf) */
132     int dl_len;                               /*!< SDP attrbutes of HID devices: HID device descriptor length */
133     uint8_t dsc_list[BTHH_MAX_DSC_LEN];       /*!< SDP attrbutes of HID devices: HID device descriptor definition */
134 } esp_hidh_hid_info_t;
135 
136 /**
137  * @brief HID host callback parameters union
138  */
139 typedef union {
140     /**
141      * @brief ESP_HIDH_INIT_EVT
142      */
143     struct hidh_init_evt_param {
144         esp_hidh_status_t status; /*!< status */
145     } init;                       /*!< HIDH callback param of ESP_HIDH_INIT_EVT */
146 
147     /**
148      * @brief ESP_HIDH_DEINIT_EVT
149      */
150     struct hidh_uninit_evt_param {
151         esp_hidh_status_t status; /*!< status */
152     } deinit;                     /*!< HIDH callback param of ESP_HIDH_DEINIT_EVT */
153 
154     /**
155      * @brief ESP_HIDH_OPEN_EVT
156      */
157     struct hidh_open_evt_param {
158         esp_hidh_status_t status;                /*!< operation status         */
159         esp_hidh_connection_state_t conn_status; /*!< connection status        */
160         bool is_orig;                            /*!< indicate if host intiate the connection        */
161         uint8_t handle;                          /*!< device handle            */
162         esp_bd_addr_t bd_addr;                   /*!< device address           */
163     } open;                                      /*!< HIDH callback param of ESP_HIDH_OPEN_EVT */
164 
165     /**
166      * @brief ESP_HIDH_CLOSE_EVT
167      */
168     struct hidh_close_evt_param {
169         esp_hidh_status_t status;                /*!< operation status         */
170         uint8_t reason;                          /*!< lower layer failed reason(ref hiddefs.h)       */
171         esp_hidh_connection_state_t conn_status; /*!< connection status        */
172         uint8_t handle;                          /*!< device handle            */
173     } close;                                     /*!< HIDH callback param of ESP_HIDH_CLOSE_EVT */
174 
175     /**
176      * @brief ESP_HIDH_VC_UNPLUG_EVT
177      */
178     struct hidh_unplug_evt_param {
179         esp_hidh_status_t status;                /*!< operation status         */
180         esp_hidh_connection_state_t conn_status; /*!< connection status        */
181         uint8_t handle;                          /*!< device handle            */
182     } unplug;                                    /*!< HIDH callback param of ESP_HIDH_VC_UNPLUG_EVT */
183 
184     /**
185      * @brief ESP_HIDH_GET_PROTO_EVT
186      */
187     struct hidh_get_proto_evt_param {
188         esp_hidh_status_t status;            /*!< operation status         */
189         uint8_t handle;                      /*!< device handle            */
190         esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode            */
191     } get_proto;                             /*!< HIDH callback param of ESP_HIDH_GET_PROTO_EVT */
192 
193     /**
194      * @brief ESP_HIDH_SET_PROTO_EVT
195      */
196     struct hidh_set_proto_evt_param {
197         esp_hidh_status_t status; /*!< operation status         */
198         uint8_t handle;           /*!< device handle            */
199     } set_proto;                  /*!< HIDH callback param of ESP_HIDH_SET_PROTO_EVT */
200 
201     /**
202      * @brief ESP_HIDH_GET_RPT_EVT
203      */
204     struct hidh_get_rpt_evt_param {
205         esp_hidh_status_t status; /*!< operation status         */
206         uint8_t handle;           /*!< device handle            */
207         uint16_t len;             /*!< data length              */
208         uint8_t *data;            /*!< data pointer             */
209     } get_rpt;                    /*!< HIDH callback param of ESP_HIDH_GET_RPT_EVT */
210 
211     /**
212      * @brief ESP_HIDH_SET_RPT_EVT
213      */
214     struct hidh_set_rpt_evt_param {
215         esp_hidh_status_t status; /*!< operation status         */
216         uint8_t handle;           /*!< device handle            */
217     } set_rpt;                    /*!< HIDH callback param of ESP_HIDH_SET_RPT_EVT */
218 
219     /**
220      * @brief ESP_HIDH_DATA_EVT
221      */
222     struct hidh_send_data_evt_param {
223         esp_hidh_status_t status; /*!< operation status         */
224         uint8_t handle;           /*!< device handle            */
225         uint8_t reason;           /*!< lower layer failed reason(ref hiddefs.h)       */
226     } send_data;                  /*!< HIDH callback param of ESP_HIDH_DATA_EVT */
227 
228     /**
229      * @brief ESP_HIDH_GET_IDLE_EVT
230      */
231     struct hidh_get_idle_evt_param {
232         esp_hidh_status_t status; /*!< operation status         */
233         uint8_t handle;           /*!< device handle            */
234         uint8_t idle_rate;        /*!< idle rate                */
235     } get_idle;                   /*!< HIDH callback param of ESP_HIDH_GET_IDLE_EVT */
236 
237     /**
238      * @brief ESP_HIDH_SET_IDLE_EVT
239      */
240     struct hidh_set_idle_evt_param {
241         esp_hidh_status_t status; /*!< operation status         */
242         uint8_t handle;           /*!< device handle            */
243     } set_idle;                   /*!< HIDH callback param of ESP_HIDH_SET_IDLE_EVT */
244 
245     /**
246      * @brief ESP_HIDH_DATA_IND_EVT
247      */
248     struct hidh_data_ind_evt_param {
249         esp_hidh_status_t status;            /*!< operation status         */
250         uint8_t handle;                      /*!< device handle            */
251         esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode            */
252         uint16_t len;                        /*!< data length              */
253         uint8_t *data;                       /*!< data pointer             */
254     } data_ind;                              /*!< HIDH callback param of ESP_HIDH_DATA_IND_EVT */
255 
256     /**
257      * @brief ESP_HIDH_ADD_DEV_EVT
258      */
259     struct hidh_add_dev_evt_param {
260         esp_hidh_status_t status; /*!< operation status         */
261         uint8_t handle;           /*!< device handle            */
262         esp_bd_addr_t bd_addr;    /*!< device address           */
263     } add_dev;                    /*!< HIDH callback param of ESP_HIDH_ADD_DEV_EVT */
264 
265     /**
266      * @brief ESP_HIDH_RMV_DEV_EVT
267      */
268     struct hidh_rmv_dev_evt_param {
269         esp_hidh_status_t status; /*!< operation status         */
270         uint8_t handle;           /*!< device handle            */
271         esp_bd_addr_t bd_addr;    /*!< device address           */
272     } rmv_dev;                    /*!< HIDH callback param of ESP_HIDH_RMV_DEV_EVT */
273 
274     /**
275      * @brief ESP_HIDH_GET_DSCP_EVT
276      */
277     struct hidh_get_dscp_evt_param {
278         esp_hidh_status_t status; /*!< operation status         */
279         uint8_t handle;           /*!< device handle            */
280         bool added;               /*!< Indicate if added        */
281         uint16_t vendor_id;       /*!< Vendor ID */
282         uint16_t product_id;      /*!< Product ID */
283         uint16_t version;         /*!< Version */
284         uint16_t ssr_max_latency; /*!< SSR max latency in slots */
285         uint16_t ssr_min_tout;    /*!< SSR min timeout in slots */
286         uint8_t ctry_code;        /*!< Country Code */
287         uint16_t dl_len;          /*!< Device descriptor length */
288         uint8_t *dsc_list;        /*!< Device descriptor pointer */
289     } dscp;                       /*!< HIDH callback param of ESP_HIDH_GET_DSCP_EVT */
290 
291     /**
292      * @brief ESP_HIDH_SET_INFO_EVT
293      */
294     struct hidh_set_info_evt_param {
295         esp_hidh_status_t status; /*!< operation status         */
296         uint8_t handle;           /*!< device handle            */
297         esp_bd_addr_t bd_addr;    /*!< device address           */
298     } set_info;                   /*!< HIDH callback param of ESP_HIDH_SET_INFO_EVT */
299 } esp_hidh_cb_param_t;
300 
301 /**
302  * @brief       HID host callback function type
303  * @param       event:      Event type
304  * @param       param:      Point to callback parameter, currently is union type
305  */
306 typedef void (*esp_hh_cb_t)(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param);
307 
308 /**
309  * @brief       This function is called to init callbacks with HID host module.
310  *
311  * @param[in]   callback:   pointer to the init callback function.
312  *
313  * @return
314  *              - ESP_OK: success
315  *              - other: failed
316  */
317 esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t callback);
318 
319 /**
320  * @brief       This function initializes HID host. This function should be called after esp_bluedroid_enable() and
321  *              esp_bluedroid_init() success, and should be called after esp_bt_hid_host_register_callback().
322  *              When the operation is complete the callback function will be called with ESP_HIDH_INIT_EVT.
323  *
324  * @return
325  *              - ESP_OK: success
326  *              - other: failed
327  */
328 esp_err_t esp_bt_hid_host_init(void);
329 
330 /**
331  * @brief       Closes the interface. This function should be called after esp_bluedroid_enable() and
332  *              esp_bluedroid_init() success, and should be called after esp_bt_hid_host_init().
333  *              When the operation is complete the callback function will be called with ESP_HIDH_DEINIT_EVT.
334  *
335  * @return      - ESP_OK: success
336  *              - other: failed
337  */
338 esp_err_t esp_bt_hid_host_deinit(void);
339 
340 /**
341  * @brief       Connect to HID device. When the operation is complete the callback
342  *              function will be called with ESP_HIDH_OPEN_EVT.
343  *
344  * @param[in]   bd_addr:  Remote device bluetooth device address.
345  *
346  * @return      - ESP_OK: success
347  *              - other: failed
348  */
349 esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr);
350 
351 /**
352  * @brief       Disconnect from HID device. When the operation is complete the callback
353  *              function will be called with ESP_HIDH_CLOSE_EVT.
354  *
355  * @param[in]   bd_addr:  Remote device bluetooth device address.
356  *
357  * @return      - ESP_OK: success
358  *              - other: failed
359  */
360 esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr);
361 
362 /**
363  * @brief       Virtual UnPlug (VUP) the specified HID device. When the operation is complete the callback
364  *              function will be called with ESP_HIDH_VC_UNPLUG_EVT.
365  *
366  * @param[in]   bd_addr:  Remote device bluetooth device address.
367  *
368  * @return      - ESP_OK: success
369  *              - other: failed
370  */
371 esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr);
372 
373 /**
374  * @brief       Set the HID device descriptor for the specified HID device. When the operation is complete the callback
375  *              function will be called with ESP_HIDH_SET_INFO_EVT.
376  *
377  * @param[in]   bd_addr:  Remote device bluetooth device address.
378  * @param[in]   hid_info:  HID device descriptor structure.
379  *
380  * @return      - ESP_OK: success
381  *              - other: failed
382  */
383 esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info);
384 
385 /**
386  * @brief       Get the HID proto mode. When the operation is complete the callback
387  *              function will be called with ESP_HIDH_GET_PROTO_EVT.
388  *
389  * @param[in]   bd_addr:  Remote device bluetooth device address.
390  *
391  * @return
392  *              - ESP_OK: success
393  *              - other: failed
394  */
395 esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr);
396 
397 /**
398  * @brief       Set the HID proto mode. When the operation is complete the callback
399  *              function will be called with ESP_HIDH_SET_PROTO_EVT.
400  *
401  * @param[in]   bd_addr:  Remote device bluetooth device address.
402  * @param[in]   protocol_mode:  Protocol mode type.
403  *
404  * @return
405  *              - ESP_OK: success
406  *              - other: failed
407  */
408 esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode);
409 
410 /**
411  * @brief       Get the HID Idle Time. When the operation is complete the callback
412  *              function will be called with ESP_HIDH_GET_IDLE_EVT.
413  *
414  * @param[in]   bd_addr:  Remote device bluetooth device address.
415  *
416  * @return
417  *              - ESP_OK: success
418  *              - other: failed
419  */
420 esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr);
421 
422 /**
423  * @brief       Set the HID Idle Time. When the operation is complete the callback
424  *              function will be called with ESP_HIDH_SET_IDLE_EVT.
425  *
426  * @param[in]   bd_addr:  Remote device bluetooth device address.
427  * @param[in]   idle_time:  Idle time rate
428  *
429  * @return    - ESP_OK: success
430  *            - other: failed
431  */
432 esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time);
433 
434 /**
435  * @brief       Send a GET_REPORT to HID device. When the operation is complete the callback
436  *              function will be called with ESP_HIDH_GET_RPT_EVT.
437  *
438  * @param[in]   bd_addr:  Remote device bluetooth device address.
439  * @param[in]   report_type:  Report type
440  * @param[in]   report_id:  Report id
441  * @param[in]   buffer_size:  Buffer size
442  *
443  * @return      - ESP_OK: success
444  *              - other: failed
445  */
446 esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id,
447                                      int buffer_size);
448 
449 /**
450  * @brief       Send a SET_REPORT to HID device. When the operation is complete the callback
451  *              function will be called with ESP_HIDH_SET_RPT_EVT.
452  *
453  * @param[in]   bd_addr:  Remote device bluetooth device address.
454  * @param[in]   report_type:  Report type
455  * @param[in]   report:  Report data pointer
456  * @param[in]   len:  Report data length
457  *
458  * @return      - ESP_OK: success
459  *              - other: failed
460  */
461 esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report,
462                                      size_t len);
463 
464 /**
465  * @brief       Send data to HID device. When the operation is complete the callback
466  *              function will be called with ESP_HIDH_DATA_EVT.
467  *
468  * @param[in]   bd_addr:  Remote device bluetooth device address.
469  * @param[in]   data:  Data pointer
470  * @param[in]   len:  Data length
471  *
472  * @return      - ESP_OK: success
473  *              - other: failed
474  */
475 esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len);
476 
477 #ifdef __cplusplus
478 }
479 #endif
480 
481 #endif
482