1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * SPDX-FileContributor: Blake Felt 7 */ 8 9 #ifndef __ESP_HIDD_API_H__ 10 #define __ESP_HIDD_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 /// subclass of hid device 20 #define ESP_HID_CLASS_UNKNOWN (0x00<<2) /*!< unknown HID device subclass */ 21 #define ESP_HID_CLASS_JOS (0x01<<2) /*!< joystick */ 22 #define ESP_HID_CLASS_GPD (0x02<<2) /*!< game pad */ 23 #define ESP_HID_CLASS_RMC (0x03<<2) /*!< remote control */ 24 #define ESP_HID_CLASS_SED (0x04<<2) /*!< sensing device */ 25 #define ESP_HID_CLASS_DGT (0x05<<2) /*!< digitizer tablet */ 26 #define ESP_HID_CLASS_CDR (0x06<<2) /*!< card reader */ 27 #define ESP_HID_CLASS_KBD (0x10<<2) /*!< keyboard */ 28 #define ESP_HID_CLASS_MIC (0x20<<2) /*!< pointing device */ 29 #define ESP_HID_CLASS_COM (0x30<<2) /*!< combo keyboard/pointing */ 30 31 /** 32 * @brief HIDD handshake result code 33 */ 34 typedef enum { 35 ESP_HID_PAR_HANDSHAKE_RSP_SUCCESS = 0, /*!< successful */ 36 ESP_HID_PAR_HANDSHAKE_RSP_NOT_READY = 1, /*!< not ready, device is too busy to accept data */ 37 ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID = 2, /*!< invalid report ID */ 38 ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ = 3, /*!< device does not support the request */ 39 ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM = 4, /*!< parameter value is out of range or inappropriate */ 40 ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN = 14, /*!< device could not identify the error condition */ 41 ESP_HID_PAR_HANDSHAKE_RSP_ERR_FATAL = 15, /*!< restart is essential to resume functionality */ 42 } esp_hidd_handshake_error_t; 43 44 /** 45 * @brief HIDD report types 46 */ 47 typedef enum { 48 ESP_HIDD_REPORT_TYPE_OTHER = 0, /*!< unknown report type */ 49 ESP_HIDD_REPORT_TYPE_INPUT, /*!< input report */ 50 ESP_HIDD_REPORT_TYPE_OUTPUT, /*!< output report */ 51 ESP_HIDD_REPORT_TYPE_FEATURE, /*!< feature report */ 52 ESP_HIDD_REPORT_TYPE_INTRDATA, /*!< special value for reports to be sent on interrupt channel, INPUT is assumed */ 53 } esp_hidd_report_type_t; 54 55 /** 56 * @brief HIDD connection state 57 */ 58 typedef enum { 59 ESP_HIDD_CONN_STATE_CONNECTED, /*!< HID connection established */ 60 ESP_HIDD_CONN_STATE_CONNECTING, /*!< connection to remote Bluetooth device */ 61 ESP_HIDD_CONN_STATE_DISCONNECTED, /*!< connection released */ 62 ESP_HIDD_CONN_STATE_DISCONNECTING, /*!< disconnecting to remote Bluetooth device*/ 63 ESP_HIDD_CONN_STATE_UNKNOWN, /*!< unknown connection state */ 64 } esp_hidd_connection_state_t; 65 66 /** 67 * @brief HID device protocol modes 68 */ 69 typedef enum { 70 ESP_HIDD_REPORT_MODE = 0x00, /*!< Report Protocol Mode */ 71 ESP_HIDD_BOOT_MODE = 0x01, /*!< Boot Protocol Mode */ 72 ESP_HIDD_UNSUPPORTED_MODE = 0xff, /*!< unsupported */ 73 } esp_hidd_protocol_mode_t; 74 75 /** 76 * @brief HID Boot Protocol report IDs 77 */ 78 typedef enum { 79 ESP_HIDD_BOOT_REPORT_ID_KEYBOARD = 1, /*!< report ID of Boot Protocol keyboard report */ 80 ESP_HIDD_BOOT_REPORT_ID_MOUSE = 2, /*!< report ID of Boot Protocol mouse report */ 81 } esp_hidd_boot_report_id_t; 82 83 /** 84 * @brief HID Boot Protocol report size including report ID 85 */ 86 enum { 87 ESP_HIDD_BOOT_REPORT_SIZE_KEYBOARD = 9, /*!< report size of Boot Protocol keyboard report */ 88 ESP_HIDD_BOOT_REPORT_SIZE_MOUSE = 4, /*!< report size of Boot Protocol mouse report */ 89 }; 90 91 /** 92 * @brief HID device characteristics for SDP server 93 */ 94 typedef struct { 95 const char *name; /*!< service name */ 96 const char *description; /*!< service description */ 97 const char *provider; /*!< provider name */ 98 uint8_t subclass; /*!< HID device subclass */ 99 uint8_t *desc_list; /*!< HID descriptor list */ 100 int desc_list_len; /*!< size in bytes of HID descriptor list */ 101 } esp_hidd_app_param_t; 102 103 /** 104 * @brief HIDD Quality of Service parameters negotiated over L2CAP 105 */ 106 typedef struct { 107 uint8_t service_type; /*!< the level of service, 0 indicates no traffic */ 108 uint32_t token_rate; /*!< token rate in bytes per second, 0 indicates "don't care" */ 109 uint32_t token_bucket_size; /*!< limit on the burstness of the application data */ 110 uint32_t peak_bandwidth; /*!< bytes per second, value 0 indicates "don't care" */ 111 uint32_t access_latency; /*!< maximum acceptable delay in microseconds */ 112 uint32_t delay_variation; /*!< the difference in microseconds between the max and min delay */ 113 } esp_hidd_qos_param_t; 114 115 /** 116 * @brief HID device callback function events 117 */ 118 typedef enum { 119 ESP_HIDD_INIT_EVT = 0, /*!< When HID device is initialized, the event comes */ 120 ESP_HIDD_DEINIT_EVT, /*!< When HID device is deinitialized, the event comes */ 121 ESP_HIDD_REGISTER_APP_EVT, /*!< When HID device application registered, the event comes */ 122 ESP_HIDD_UNREGISTER_APP_EVT, /*!< When HID device application unregistered, the event comes */ 123 ESP_HIDD_OPEN_EVT, /*!< When HID device connection to host opened, the event comes */ 124 ESP_HIDD_CLOSE_EVT, /*!< When HID device connection to host closed, the event comes */ 125 ESP_HIDD_SEND_REPORT_EVT, /*!< When HID device send report to lower layer, the event comes */ 126 ESP_HIDD_REPORT_ERR_EVT, /*!< When HID device report handshanke error to lower layer, the event comes */ 127 ESP_HIDD_GET_REPORT_EVT, /*!< When HID device receives GET_REPORT request from host, the event comes */ 128 ESP_HIDD_SET_REPORT_EVT, /*!< When HID device receives SET_REPORT request from host, the event comes */ 129 ESP_HIDD_SET_PROTOCOL_EVT, /*!< When HID device receives SET_PROTOCOL request from host, the event comes */ 130 ESP_HIDD_INTR_DATA_EVT, /*!< When HID device receives DATA from host on intr, the event comes */ 131 ESP_HIDD_VC_UNPLUG_EVT, /*!< When HID device initiates Virtual Cable Unplug, the event comes */ 132 ESP_HIDD_API_ERR_EVT /*!< When HID device has API error, the event comes */ 133 } esp_hidd_cb_event_t; 134 135 typedef enum { 136 ESP_HIDD_SUCCESS, 137 ESP_HIDD_ERROR, /*!< general ESP HD error */ 138 ESP_HIDD_NO_RES, /*!< out of system resources */ 139 ESP_HIDD_BUSY, /*!< Temporarily can not handle this request. */ 140 ESP_HIDD_NO_DATA, /*!< No data. */ 141 ESP_HIDD_NEED_INIT, /*!< HIDD module shall init first */ 142 ESP_HIDD_NEED_DEINIT, /*!< HIDD module shall deinit first */ 143 ESP_HIDD_NEED_REG, /*!< HIDD module shall register first */ 144 ESP_HIDD_NEED_DEREG, /*!< HIDD module shall deregister first */ 145 ESP_HIDD_NO_CONNECTION, /*!< connection may have been closed */ 146 } esp_hidd_status_t; 147 148 /** 149 * @brief HID device callback parameters union 150 */ 151 typedef union { 152 /** 153 * @brief ESP_HIDD_INIT_EVT 154 */ 155 struct hidd_init_evt_param { 156 esp_hidd_status_t status; /*!< operation status */ 157 } init; /*!< HIDD callback param of ESP_HIDD_INIT_EVT */ 158 159 /** 160 * @brief ESP_HIDD_DEINIT_EVT 161 */ 162 struct hidd_deinit_evt_param { 163 esp_hidd_status_t status; /*!< operation status */ 164 } deinit; /*!< HIDD callback param of ESP_HIDD_DEINIT_EVT */ 165 166 /** 167 * @brief ESP_HIDD_REGISTER_APP_EVT 168 */ 169 struct hidd_register_app_evt_param { 170 esp_hidd_status_t status; /*!< operation status */ 171 bool in_use; /*!< indicate whether use virtual cable plug host address */ 172 esp_bd_addr_t bd_addr; /*!< host address */ 173 } register_app; /*!< HIDD callback param of ESP_HIDD_REGISTER_APP_EVT */ 174 175 /** 176 * @brief ESP_HIDD_UNREGISTER_APP_EVT 177 */ 178 struct hidd_unregister_app_evt_param { 179 esp_hidd_status_t status; /*!< operation status */ 180 } unregister_app; /*!< HIDD callback param of ESP_HIDD_UNREGISTER_APP_EVT */ 181 182 /** 183 * @brief ESP_HIDD_OPEN_EVT 184 */ 185 struct hidd_open_evt_param { 186 esp_hidd_status_t status; /*!< operation status */ 187 esp_hidd_connection_state_t conn_status; /*!< connection status */ 188 esp_bd_addr_t bd_addr; /*!< host address */ 189 } open; /*!< HIDD callback param of ESP_HIDD_OPEN_EVT */ 190 191 /** 192 * @brief ESP_HIDD_CLOSE_EVT 193 */ 194 struct hidd_close_evt_param { 195 esp_hidd_status_t status; /*!< operation status */ 196 esp_hidd_connection_state_t conn_status; /*!< connection status */ 197 } close; /*!< HIDD callback param of ESP_HIDD_CLOSE_EVT */ 198 199 /** 200 * @brief ESP_HIDD_SEND_REPORT_EVT 201 */ 202 struct hidd_send_report_evt_param { 203 esp_hidd_status_t status; /*!< operation status */ 204 uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */ 205 esp_hidd_report_type_t report_type; /*!< report type */ 206 uint8_t report_id; /*!< report id */ 207 } send_report; /*!< HIDD callback param of ESP_HIDD_SEND_REPORT_EVT */ 208 209 /** 210 * @brief ESP_HIDD_REPORT_ERR_EVT 211 */ 212 struct hidd_report_err_evt_param { 213 esp_hidd_status_t status; /*!< operation status */ 214 uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */ 215 } report_err; /*!< HIDD callback param of ESP_HIDD_REPORT_ERR_EVT */ 216 217 /** 218 * @brief ESP_HIDD_GET_REPORT_EVT 219 */ 220 struct hidd_get_report_evt_param { 221 esp_hidd_report_type_t report_type; /*!< report type */ 222 uint8_t report_id; /*!< report id */ 223 uint16_t buffer_size; /*!< buffer size */ 224 } get_report; /*!< HIDD callback param of ESP_HIDD_GET_REPORT_EVT */ 225 226 /** 227 * @brief ESP_HIDD_SET_REPORT_EVT 228 */ 229 struct hidd_set_report_evt_param { 230 esp_hidd_report_type_t report_type; /*!< report type */ 231 uint8_t report_id; /*!< report id */ 232 uint16_t len; /*!< set_report data length */ 233 uint8_t *data; /*!< set_report data pointer */ 234 } set_report; /*!< HIDD callback param of ESP_HIDD_SET_REPORT_EVT */ 235 236 /** 237 * @brief ESP_HIDD_SET_PROTOCOL_EVT 238 */ 239 struct hidd_set_protocol_evt_param { 240 esp_hidd_protocol_mode_t protocol_mode; /*!< protocol mode */ 241 } set_protocol; /*!< HIDD callback param of ESP_HIDD_SET_PROTOCOL_EVT */ 242 243 /** 244 * @brief ESP_HIDD_INTR_DATA_EVT 245 */ 246 struct hidd_intr_data_evt_param { 247 uint8_t report_id; /*!< interrupt channel report id */ 248 uint16_t len; /*!< interrupt channel report data length */ 249 uint8_t *data; /*!< interrupt channel report data pointer */ 250 } intr_data; /*!< HIDD callback param of ESP_HIDD_INTR_DATA_EVT */ 251 252 /** 253 * @brief ESP_HIDD_VC_UNPLUG_EVT 254 */ 255 struct hidd_vc_unplug_param { 256 esp_hidd_status_t status; /*!< operation status */ 257 esp_hidd_connection_state_t conn_status; /*!< connection status */ 258 } vc_unplug; /*!< HIDD callback param of ESP_HIDD_VC_UNPLUG_EVT */ 259 } esp_hidd_cb_param_t; 260 261 /** 262 * @brief HID device callback function type. 263 * @param event: Event type 264 * @param param: Point to callback parameter, currently is union type 265 */ 266 typedef void (*esp_hd_cb_t)(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param); 267 268 /** 269 * @brief This function is called to init callbacks with HID device module. 270 * 271 * @param[in] callback: pointer to the init callback function. 272 * 273 * @return 274 * - ESP_OK: success 275 * - other: failed 276 */ 277 esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t callback); 278 279 /** 280 * @brief Initializes HIDD interface. This function should be called after esp_bluedroid_init() and 281 * esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_register_callback. 282 * When the operation is complete, the callback function will be called with ESP_HIDD_INIT_EVT. 283 * 284 * @return 285 * - ESP_OK: success 286 * - other: failed 287 */ 288 esp_err_t esp_bt_hid_device_init(void); 289 290 /** 291 * @brief De-initializes HIDD interface. This function should be called after esp_bluedroid_init() and 292 * esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_init(). When the 293 * operation is complete, the callback function will be called with ESP_HIDD_DEINIT_EVT. 294 * 295 * @return 296 * - ESP_OK: success 297 * - other: failed 298 */ 299 esp_err_t esp_bt_hid_device_deinit(void); 300 301 /** 302 * @brief Registers HIDD parameters with SDP and sets l2cap Quality of Service. This function should be 303 * called after esp_bluedroid_init() and esp_bluedroid_enable() success, and should be called after 304 * esp_bt_hid_device_init(). When the operation is complete, the callback function will be called 305 * with ESP_HIDD_REGISTER_APP_EVT. 306 * 307 * @param[in] app_param: HIDD parameters 308 * @param[in] in_qos: incoming QoS parameters 309 * @param[in] out_qos: outgoing QoS parameters 310 * 311 * @return 312 * - ESP_OK: success 313 * - other: failed 314 */ 315 esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t *app_param, esp_hidd_qos_param_t *in_qos, 316 esp_hidd_qos_param_t *out_qos); 317 318 /** 319 * @brief Removes HIDD parameters from SDP and resets l2cap Quality of Service. This function should be 320 * called after esp_bluedroid_init() and esp_bluedroid_enable() success, and should be called after 321 * esp_bt_hid_device_init(). When the operation is complete, the callback function will be called 322 * with ESP_HIDD_UNREGISTER_APP_EVT. 323 * 324 * @return 325 * - ESP_OK: success 326 * - other: failed 327 */ 328 esp_err_t esp_bt_hid_device_unregister_app(void); 329 330 /** 331 * @brief Connects to the peer HID Host with virtual cable. This function should be called after 332 * esp_bluedroid_init() and esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_init(). 333 * When the operation is complete, the callback function will be called with ESP_HIDD_OPEN_EVT. 334 * 335 * @param[in] bd_addr: Remote host bluetooth device address. 336 * 337 * @return 338 * - ESP_OK: success 339 * - other: failed 340 */ 341 esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr); 342 343 /** 344 * @brief Disconnects from the currently connected HID Host. This function should be called after 345 * esp_bluedroid_init() and esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_init(). 346 * When the operation is complete, the callback function will be called with ESP_HIDD_CLOSE_EVT. 347 * 348 * @note The disconnect operation will not remove the virtually cabled device. If the connect request from the 349 * different HID Host, it will reject the request. 350 * 351 * @return 352 * - ESP_OK: success 353 * - other: failed 354 */ 355 esp_err_t esp_bt_hid_device_disconnect(void); 356 357 /** 358 * @brief Sends HID report to the currently connected HID Host. This function should be called after 359 * esp_bluedroid_init() and esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_init(). 360 * When the operation is complete, the callback function will be called with ESP_HIDD_SEND_REPORT_EVT. 361 * 362 * @param[in] type: type of report 363 * @param[in] id: report id as defined by descriptor 364 * @param[in] len: length of report 365 * @param[in] data: report data 366 * 367 * @return 368 * - ESP_OK: success 369 * - other: failed 370 */ 371 esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t *data); 372 373 /** 374 * @brief Sends HID Handshake with error info for invalid set_report to the currently connected HID Host. 375 * This function should be called after esp_bluedroid_init() and esp_bluedroid_enable() success, and 376 * should be called after esp_bt_hid_device_init(). When the operation is complete, the callback 377 * function will be called with ESP_HIDD_REPORT_ERR_EVT. 378 * 379 * @param[in] error: type of error 380 * 381 * @return 382 * - ESP_OK: success 383 * - other: failed 384 */ 385 esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error); 386 387 /** 388 * @brief Remove the virtually cabled device. This function should be called after esp_bluedroid_init() 389 * and esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_init(). When the 390 * operation is complete, the callback function will be called with ESP_HIDD_VC_UNPLUG_EVT. 391 * 392 * @note If the connection exists, then HID Device will send a `VIRTUAL_CABLE_UNPLUG` control command to 393 * the peer HID Host, and the connection will be destroyed. If the connection does not exist, then HID 394 * Device will only unplug on it's single side. Once the unplug operation is success, the related 395 * pairing and bonding information will be removed, then the HID Device can accept connection request 396 * from the different HID Host, 397 * 398 * @return - ESP_OK: success 399 * - other: failed 400 */ 401 esp_err_t esp_bt_hid_device_virtual_cable_unplug(void); 402 403 #ifdef __cplusplus 404 } 405 #endif 406 407 #endif 408