1/****************************************************************************** 2 * 3 * Copyright (C) 2005-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * This file contains the HID host action functions. 22 * 23 ******************************************************************************/ 24 25#include "bt_target.h" 26 27#if (BTA_HH_INCLUDED == TRUE) 28 29#include <string.h> 30 31#include "bta_hh_co.h" 32#include "bta_hh_int.h" 33#include "bta_sys.h" 34#include "btm_api.h" 35#include "l2c_api.h" 36#include "osi/include/osi.h" 37#include "utl.h" 38 39/***************************************************************************** 40 * Constants 41 ****************************************************************************/ 42 43/***************************************************************************** 44 * Local Function prototypes 45 ****************************************************************************/ 46static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr, 47 uint8_t event, uint32_t data, BT_HDR* pdata); 48static tBTA_HH_STATUS bta_hh_get_trans_status(uint32_t result); 49 50#if (BTA_HH_DEBUG == TRUE) 51static const char* bta_hh_get_w4_event(uint16_t event); 52static const char* bta_hh_hid_event_name(uint16_t event); 53#endif 54 55/***************************************************************************** 56 * Action Functions 57 ****************************************************************************/ 58/******************************************************************************* 59 * 60 * Function bta_hh_api_enable 61 * 62 * Description Perform necessary operations to enable HID host. 63 * 64 * 65 * Returns void 66 * 67 ******************************************************************************/ 68void bta_hh_api_enable(tBTA_HH_DATA* p_data) { 69 tBTA_HH_STATUS status = BTA_HH_ERR; 70 uint8_t xx; 71 72 /* initialize BTE HID */ 73 HID_HostInit(); 74 75 memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB)); 76 77 HID_HostSetSecurityLevel("", p_data->api_enable.sec_mask); 78 79 /* Register with L2CAP */ 80 if (HID_HostRegister(bta_hh_cback) == HID_SUCCESS) { 81 /* store parameters */ 82 bta_hh_cb.p_cback = p_data->api_enable.p_cback; 83 84 status = BTA_HH_OK; 85 /* initialize device CB */ 86 for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) { 87 bta_hh_cb.kdev[xx].state = BTA_HH_IDLE_ST; 88 bta_hh_cb.kdev[xx].hid_handle = BTA_HH_INVALID_HANDLE; 89 bta_hh_cb.kdev[xx].index = xx; 90 } 91 92 /* initialize control block map */ 93 for (xx = 0; xx < BTA_HH_MAX_KNOWN; xx++) 94 bta_hh_cb.cb_index[xx] = BTA_HH_IDX_INVALID; 95 } 96 97#if (BTA_HH_LE_INCLUDED == TRUE) 98 if (status == BTA_HH_OK) { 99 bta_hh_le_enable(); 100 } else 101#endif 102 /* signal BTA call back event */ 103 (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, (tBTA_HH*)&status); 104} 105/******************************************************************************* 106 * 107 * Function bta_hh_api_disable 108 * 109 * Description Perform necessary operations to disable HID host. 110 * 111 * 112 * Returns void 113 * 114 ******************************************************************************/ 115void bta_hh_api_disable(void) { 116 uint8_t xx; 117 118 /* service is not enabled */ 119 if (bta_hh_cb.p_cback == NULL) return; 120 121 /* no live connection, signal DISC_CMPL_EVT directly */ 122 if (!bta_hh_cb.cnt_num) { 123 bta_hh_disc_cmpl(); 124 } else /* otherwise, disconnect all live connections */ 125 { 126 bta_hh_cb.w4_disable = true; 127 128 for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) { 129 /* send API_CLOSE event to every connected device */ 130 if (bta_hh_cb.kdev[xx].state == BTA_HH_CONN_ST) { 131 /* disconnect all connected devices */ 132 bta_hh_sm_execute(&bta_hh_cb.kdev[xx], BTA_HH_API_CLOSE_EVT, NULL); 133 } 134 } 135 } 136 137 return; 138} 139 140/******************************************************************************* 141 * 142 * Function bta_hh_disc_cmpl 143 * 144 * Description All connections have been closed, disable service. 145 * 146 * 147 * Returns void 148 * 149 ******************************************************************************/ 150void bta_hh_disc_cmpl(void) { 151#if (BTA_HH_LE_INCLUDED == TRUE) 152 HID_HostDeregister(); 153 bta_hh_le_deregister(); 154#else 155 tBTA_HH_STATUS status = BTA_HH_OK; 156 157 /* Deregister with lower layer */ 158 if (HID_HostDeregister() != HID_SUCCESS) status = BTA_HH_ERR; 159 160 bta_hh_cleanup_disable(status); 161#endif 162} 163 164/******************************************************************************* 165 * 166 * Function bta_hh_sdp_cback 167 * 168 * Description SDP callback function. 169 * 170 * Returns void 171 * 172 ******************************************************************************/ 173static void bta_hh_sdp_cback(uint16_t result, uint16_t attr_mask, 174 tHID_DEV_SDP_INFO* sdp_rec) { 175 tBTA_HH_DEV_CB* p_cb = bta_hh_cb.p_cur; 176 uint8_t hdl = 0; 177 tBTA_HH_STATUS status = BTA_HH_ERR_SDP; 178 179 /* make sure sdp succeeded and hh has not been disabled */ 180 if ((result == SDP_SUCCESS) && (p_cb != NULL)) { 181 /* security is required for the connection, add attr_mask bit*/ 182 if (p_cb->sec_mask) attr_mask |= HID_SEC_REQUIRED; 183 184#if (BTA_HH_DEBUG == TRUE) 185 APPL_TRACE_EVENT("%s: p_cb: %d result 0x%02x, attr_mask 0x%02x, handle %x", 186 __func__, p_cb, result, attr_mask, p_cb->hid_handle); 187#endif 188 189 /* check to see type of device is supported , and should not been added 190 * before */ 191 if (bta_hh_tod_spt(p_cb, sdp_rec->sub_class)) { 192 /* if not added before */ 193 if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { 194 /* add device/update attr_mask information */ 195 if (HID_HostAddDev(p_cb->addr, attr_mask, &hdl) == HID_SUCCESS) { 196 status = BTA_HH_OK; 197 /* update cb_index[] map */ 198 bta_hh_cb.cb_index[hdl] = p_cb->index; 199 } else { 200 p_cb->app_id = 0; 201 } 202 } else { 203 hdl = p_cb->hid_handle; 204 } 205 /* else : incoming connection after SDP should update the SDP information 206 * as well */ 207 208 if (p_cb->app_id != 0) { 209 /* update cb information with attr_mask, dscp_info etc. */ 210 bta_hh_add_device_to_list(p_cb, hdl, attr_mask, &sdp_rec->dscp_info, 211 sdp_rec->sub_class, sdp_rec->ssr_max_latency, 212 sdp_rec->ssr_min_tout, p_cb->app_id); 213 214 p_cb->dscp_info.ctry_code = sdp_rec->ctry_code; 215 216 status = BTA_HH_OK; 217 } 218 219 } else /* type of device is not supported */ 220 status = BTA_HH_ERR_TOD_UNSPT; 221 } 222 223 /* free disc_db when SDP is completed */ 224 osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); 225 226 /* send SDP_CMPL_EVT into state machine */ 227 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status); 228 229 return; 230} 231/******************************************************************************* 232 * 233 * Function bta_hh_di_sdp_cback 234 * 235 * Description SDP DI callback function. 236 * 237 * Returns void 238 * 239 ******************************************************************************/ 240static void bta_hh_di_sdp_cback(uint16_t result) { 241 tBTA_HH_DEV_CB* p_cb = bta_hh_cb.p_cur; 242 tBTA_HH_STATUS status = BTA_HH_ERR_SDP; 243 tSDP_DI_GET_RECORD di_rec; 244 tHID_STATUS ret; 245#if (BTA_HH_DEBUG == TRUE) 246 APPL_TRACE_EVENT("%s: p_cb: %d result 0x%02x", __func__, p_cb, result); 247#endif 248 249 /* if DI record does not exist on remote device, vendor_id in 250 * tBTA_HH_DEV_DSCP_INFO will be set to 0xffff and we will allow the 251 * connection to go through. Spec mandates that DI record be set, but many 252 * HID devices do not set this. So for IOP purposes, we allow the connection 253 * to go through and update the DI record to invalid DI entry. 254 */ 255 if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) && 256 (p_cb != NULL)) { 257 if (result == SDP_SUCCESS && 258 SDP_GetNumDiRecords(bta_hh_cb.p_disc_db) != 0) { 259 /* always update information with primary DI record */ 260 if (SDP_GetDiRecord(1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS) { 261 bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, 262 di_rec.rec.version, 0); 263 } 264 265 } else /* no DI recrod available */ 266 { 267 bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0); 268 } 269 270 ret = HID_HostGetSDPRecord(p_cb->addr, bta_hh_cb.p_disc_db, 271 p_bta_hh_cfg->sdp_db_size, bta_hh_sdp_cback); 272 if (ret == HID_SUCCESS) { 273 status = BTA_HH_OK; 274 } else { 275#if (BTA_HH_DEBUG == TRUE) 276 APPL_TRACE_DEBUG("%s: HID_HostGetSDPRecord failed: Status 0x%2x", 277 __func__, ret); 278#endif 279 } 280 } 281 282 if (status != BTA_HH_OK) { 283 osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); 284 /* send SDP_CMPL_EVT into state machine */ 285 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status); 286 } 287 return; 288} 289 290/******************************************************************************* 291 * 292 * Function bta_hh_start_sdp 293 * 294 * Description Start SDP service search, and obtain necessary SDP records. 295 * Only one SDP service search request is allowed at the same 296 * time. For every BTA_HhOpen API call, do SDP first unless SDP 297 * has been done previously. 298 * 299 * Returns void 300 * 301 ******************************************************************************/ 302void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 303 tBTA_HH_STATUS status = BTA_HH_ERR_SDP; 304 uint8_t hdl; 305 306 p_cb->sec_mask = p_data->api_conn.sec_mask; 307 p_cb->mode = p_data->api_conn.mode; 308 bta_hh_cb.p_cur = p_cb; 309 310#if (BTA_HH_LE_INCLUDED == TRUE) 311 if (bta_hh_is_le_device(p_cb, p_data->api_conn.bd_addr)) { 312 bta_hh_le_open_conn(p_cb, p_data->api_conn.bd_addr); 313 return; 314 } 315#endif 316 317 /* if previously virtually cabled device, skip SDP */ 318 if (p_cb->app_id) { 319 status = BTA_HH_OK; 320#if (BTA_HH_DEBUG == TRUE) 321 APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__); 322#endif 323 if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { 324 if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) { 325 /* update device CB with newly register device handle */ 326 bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, 327 p_cb->sub_class, 328 p_cb->dscp_info.ssr_max_latency, 329 p_cb->dscp_info.ssr_min_tout, p_cb->app_id); 330 /* update cb_index[] map */ 331 bta_hh_cb.cb_index[hdl] = p_cb->index; 332 } else 333 status = BTA_HH_ERR_NO_RES; 334 } 335 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status); 336 337 return; 338 } 339 /* GetSDPRecord. at one time only one SDP precedure can be active */ 340 else if (!bta_hh_cb.p_disc_db) { 341 bta_hh_cb.p_disc_db = 342 (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size); 343 bta_hh_cb.p_cur = p_cb; 344 /* do DI discovery first */ 345 if (SDP_DiDiscover(p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db, 346 p_bta_hh_cfg->sdp_db_size, 347 bta_hh_di_sdp_cback) != SDP_SUCCESS) { 348#if (BTA_HH_DEBUG == TRUE) 349 APPL_TRACE_DEBUG("%s: SDP_DiDiscover failed: Status 0x%2X", __func__, 350 status); 351#endif 352 status = BTA_HH_ERR_SDP; 353 osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); 354 } else { 355 status = BTA_HH_OK; 356 } 357 } else if (bta_hh_cb.p_disc_db) { 358 /* It is possible that there is incoming/outgoing collision case. DUT 359 * initiated 360 * HID connection at same time remote has connected L2CAP for HID control, 361 * so SDP would be in progress, when this flow reaches here. Just do nothing 362 * when the code reaches here, and ongoing SDP completion or failure will 363 * handle this case. 364 */ 365 APPL_TRACE_DEBUG("%s: ignoring as SDP already in progress", __func__); 366 return; 367 } 368 369 if (status != BTA_HH_OK) 370 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status); 371 372 return; 373} 374/******************************************************************************* 375 * 376 * Function bta_hh_sdp_cmpl 377 * 378 * Description When SDP completes, initiate a connection or report an error 379 * depending on the SDP result. 380 * 381 * 382 * Returns void 383 * 384 ******************************************************************************/ 385void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 386 tBTA_HH_CONN conn_dat; 387 tBTA_HH_STATUS status = p_data->status; 388 389#if (BTA_HH_DEBUG == TRUE) 390 APPL_TRACE_DEBUG("%s: status 0x%2X", __func__, p_data->status); 391#endif 392 393 /* initialize call back data */ 394 memset((void*)&conn_dat, 0, sizeof(tBTA_HH_CONN)); 395 conn_dat.handle = p_cb->hid_handle; 396 conn_dat.bda = p_cb->addr; 397 398 /* if SDP compl success */ 399 if (status == BTA_HH_OK) { 400 /* not incoming connection doing SDP, initiate a HID connection */ 401 if (!p_cb->incoming_conn) { 402 tHID_STATUS ret; 403 /* set security level */ 404 HID_HostSetSecurityLevel("", p_cb->sec_mask); 405 406 /* open HID connection */ 407 ret = HID_HostOpenDev(p_cb->hid_handle); 408 APPL_TRACE_DEBUG("%s: HID_HostOpenDev returned=%d", __func__, ret); 409 if (ret == HID_SUCCESS || ret == HID_ERR_ALREADY_CONN) { 410 status = BTA_HH_OK; 411 } else if (ret == HID_ERR_CONN_IN_PROCESS) { 412 /* Connection already in progress, return from here, SDP 413 * will be performed after connection is completed. 414 */ 415 APPL_TRACE_DEBUG("%s: connection already in progress", __func__); 416 return; 417 } else { 418#if (BTA_HH_DEBUG == TRUE) 419 APPL_TRACE_DEBUG("%s: HID_HostOpenDev failed: Status 0x%2X", __func__, 420 ret); 421#endif 422 /* open fail, remove device from management device list */ 423 HID_HostRemoveDev(p_cb->hid_handle); 424 status = BTA_HH_ERR; 425 } 426 } else /* incoming connection SDP finish */ 427 { 428 bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL); 429 } 430 } 431 432 if (status != BTA_HH_OK) { 433 /* Check if this was incoming connection request from an unknown device 434 * and connection failed due to missing HID Device SDP UUID 435 * In above condition, disconnect the link as well as remove the 436 * device from list of HID devices 437 */ 438 if ((status == BTA_HH_ERR_SDP) && (p_cb->incoming_conn) && 439 (p_cb->app_id == 0)) { 440 APPL_TRACE_DEBUG("%s: SDP failed for incoming conn :hndl %d", __func__, 441 p_cb->incoming_hid_handle); 442 HID_HostRemoveDev(p_cb->incoming_hid_handle); 443 } 444 conn_dat.status = status; 445 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat); 446 447 /* move state machine W4_CONN ->IDLE */ 448 bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL); 449 450 /* if this is an outgoing connection to an unknown device, clean up cb */ 451 if (p_cb->app_id == 0 && !p_cb->incoming_conn) { 452 /* clean up device control block */ 453 bta_hh_clean_up_kdev(p_cb); 454 } 455#if (BTA_HH_DEBUG == TRUE) 456 bta_hh_trace_dev_db(); 457#endif 458 } 459 return; 460} 461 462/******************************************************************************* 463 * 464 * Function bta_hh_api_disc_act 465 * 466 * Description HID Host initiate a disconnection. 467 * 468 * 469 * Returns void 470 * 471 ******************************************************************************/ 472void bta_hh_api_disc_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 473 tBTA_HH_CBDATA disc_dat; 474 tHID_STATUS status; 475 476#if (BTA_HH_LE_INCLUDED == TRUE) 477 if (p_cb->is_le_device) 478 bta_hh_le_api_disc_act(p_cb); 479 else 480#endif 481 { 482 /* found an active connection */ 483 disc_dat.handle = 484 p_data ? (uint8_t)p_data->hdr.layer_specific : p_cb->hid_handle; 485 disc_dat.status = BTA_HH_ERR; 486 487 status = HID_HostCloseDev(disc_dat.handle); 488 489 if (status) (*bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, (tBTA_HH*)&disc_dat); 490 } 491 492 return; 493} 494/******************************************************************************* 495 * 496 * Function bta_hh_open_cmpl_act 497 * 498 * Description HID host connection completed 499 * 500 * 501 * Returns void 502 * 503 ******************************************************************************/ 504void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 505 tBTA_HH_CONN conn; 506 uint8_t dev_handle = 507 p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle; 508 509 memset((void*)&conn, 0, sizeof(tBTA_HH_CONN)); 510 conn.handle = dev_handle; 511 conn.bda = p_cb->addr; 512 513 /* increase connection number */ 514 bta_hh_cb.cnt_num++; 515 516 /* initialize device driver */ 517 bta_hh_co_open(p_cb->hid_handle, p_cb->sub_class, p_cb->attr_mask, 518 p_cb->app_id); 519 520#if (BTA_HH_LE_INCLUDED == TRUE) 521 conn.status = p_cb->status; 522 conn.le_hid = p_cb->is_le_device; 523 conn.scps_supported = p_cb->scps_supported; 524 525 if (!p_cb->is_le_device) 526#endif 527 { 528 /* inform role manager */ 529 bta_sys_conn_open(BTA_ID_HH, p_cb->app_id, p_cb->addr); 530 } 531 /* set protocol mode when not default report mode */ 532 if (p_cb->mode != BTA_HH_PROTO_RPT_MODE 533#if (BTA_HH_LE_INCLUDED == TRUE) 534 && !p_cb->is_le_device 535#endif 536 ) { 537 if ((HID_HostWriteDev(dev_handle, HID_TRANS_SET_PROTOCOL, 538 HID_PAR_PROTOCOL_BOOT_MODE, 0, 0, NULL)) != 539 HID_SUCCESS) { 540 /* HID connection is up, while SET_PROTO fail */ 541 conn.status = BTA_HH_ERR_PROTO; 542 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn); 543 } else { 544 conn.status = BTA_HH_OK; 545 p_cb->w4_evt = BTA_HH_OPEN_EVT; 546 } 547 } else 548 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn); 549 550 p_cb->incoming_conn = false; 551 p_cb->incoming_hid_handle = BTA_HH_INVALID_HANDLE; 552} 553/******************************************************************************* 554 * 555 * Function bta_hh_open_act 556 * 557 * Description HID host receive HID_OPEN_EVT . 558 * 559 * 560 * Returns void 561 * 562 ******************************************************************************/ 563void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 564 tBTA_HH_API_CONN conn_data; 565 566 uint8_t dev_handle = 567 p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle; 568 569#if (BTA_HH_DEBUG == TRUE) 570 APPL_TRACE_EVENT("%s: Device[%d] connected", __func__, dev_handle); 571#endif 572 573 /* SDP has been done */ 574 if (p_cb->app_id != 0) { 575 bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data); 576 } else 577 /* app_id == 0 indicates an incoming conenction request arrives without SDP 578 * performed, do it first 579 */ 580 { 581 p_cb->incoming_conn = true; 582 /* store the handle here in case sdp fails - need to disconnect */ 583 p_cb->incoming_hid_handle = dev_handle; 584 585 memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN)); 586 conn_data.bd_addr = p_cb->addr; 587 bta_hh_start_sdp(p_cb, (tBTA_HH_DATA*)&conn_data); 588 } 589 590 return; 591} 592 593/******************************************************************************* 594 * 595 * Function bta_hh_data_act 596 * 597 * Description HID Host process a data report 598 * 599 * 600 * Returns void 601 * 602 ******************************************************************************/ 603void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 604 BT_HDR* pdata = p_data->hid_cback.p_data; 605 uint8_t* p_rpt = (uint8_t*)(pdata + 1) + pdata->offset; 606 607 bta_hh_co_data((uint8_t)p_data->hid_cback.hdr.layer_specific, p_rpt, 608 pdata->len, p_cb->mode, p_cb->sub_class, 609 p_cb->dscp_info.ctry_code, p_cb->addr, p_cb->app_id); 610 611 osi_free_and_reset((void**)&pdata); 612} 613 614/******************************************************************************* 615 * 616 * Function bta_hh_handsk_act 617 * 618 * Description HID Host process a handshake acknoledgement. 619 * 620 * 621 * Returns void 622 * 623 ******************************************************************************/ 624void bta_hh_handsk_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 625 tBTA_HH_CBDATA cback_data; 626 tBTA_HH_HSDATA hs_data; 627 tBTA_HH_CONN conn; 628 629#if (BTA_HH_DEBUG == TRUE) 630 APPL_TRACE_DEBUG("HANDSHAKE received for: event = %s data= %d", 631 bta_hh_get_w4_event(p_cb->w4_evt), p_data->hid_cback.data); 632#endif 633 634 memset(&hs_data, 0, sizeof(tBTA_HH_HSDATA)); 635 memset(&cback_data, 0, sizeof(tBTA_HH_CBDATA)); 636 637 switch (p_cb->w4_evt) { 638 /* GET_ transsaction, handshake indicate unsupported request */ 639 case BTA_HH_GET_PROTO_EVT: 640 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_UNKNOWN; 641 /* fall through */ 642 case BTA_HH_GET_RPT_EVT: 643 case BTA_HH_GET_IDLE_EVT: 644 hs_data.handle = p_cb->hid_handle; 645 /* if handshake gives an OK code for these transaction, fill in UNSUPT */ 646 hs_data.status = bta_hh_get_trans_status(p_data->hid_cback.data); 647 if (hs_data.status == BTA_HH_OK) hs_data.status = BTA_HH_HS_TRANS_NOT_SPT; 648 649 (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&hs_data); 650 p_cb->w4_evt = 0; 651 break; 652 653 /* acknoledgement from HID device for SET_ transaction */ 654 case BTA_HH_SET_RPT_EVT: 655 case BTA_HH_SET_PROTO_EVT: 656 case BTA_HH_SET_IDLE_EVT: 657 cback_data.handle = p_cb->hid_handle; 658 cback_data.status = bta_hh_get_trans_status(p_data->hid_cback.data); 659 (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&cback_data); 660 p_cb->w4_evt = 0; 661 break; 662 663 /* SET_PROTOCOL when open connection */ 664 case BTA_HH_OPEN_EVT: 665 conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK; 666 conn.handle = p_cb->hid_handle; 667 conn.bda = p_cb->addr; 668 (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&conn); 669#if (BTA_HH_DEBUG == TRUE) 670 bta_hh_trace_dev_db(); 671#endif 672 p_cb->w4_evt = 0; 673 break; 674 675 default: 676 /* unknow transaction handshake response */ 677 APPL_TRACE_DEBUG("unknown transaction type"); 678 break; 679 } 680 681 /* transaction achknoledgement received, inform PM for mode change */ 682 bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); 683 return; 684} 685/******************************************************************************* 686 * 687 * Function bta_hh_ctrl_dat_act 688 * 689 * Description HID Host process a data report from control channel. 690 * 691 * 692 * Returns void 693 * 694 ******************************************************************************/ 695void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 696 BT_HDR* pdata = p_data->hid_cback.p_data; 697 uint8_t* data = (uint8_t*)(pdata + 1) + pdata->offset; 698 tBTA_HH_HSDATA hs_data; 699 700#if (BTA_HH_DEBUG == TRUE) 701 APPL_TRACE_DEBUG("Ctrl DATA received w4: event[%s]", 702 bta_hh_get_w4_event(p_cb->w4_evt)); 703#endif 704 hs_data.status = BTA_HH_OK; 705 hs_data.handle = p_cb->hid_handle; 706 707 switch (p_cb->w4_evt) { 708 case BTA_HH_GET_IDLE_EVT: 709 hs_data.rsp_data.idle_rate = *data; 710 break; 711 case BTA_HH_GET_RPT_EVT: 712 hs_data.rsp_data.p_rpt_data = pdata; 713 break; 714 case BTA_HH_GET_PROTO_EVT: 715 /* match up BTE/BTA report/boot mode def*/ 716 hs_data.rsp_data.proto_mode = ((*data) == HID_PAR_PROTOCOL_REPORT) 717 ? BTA_HH_PROTO_RPT_MODE 718 : BTA_HH_PROTO_BOOT_MODE; 719#if (BTA_HH_DEBUG == TRUE) 720 APPL_TRACE_DEBUG("GET_PROTOCOL Mode = [%s]", 721 (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) 722 ? "Report" 723 : "Boot"); 724#endif 725 break; 726 /* should not expect control DATA for SET_ transaction */ 727 case BTA_HH_SET_PROTO_EVT: 728 /* fall through */ 729 case BTA_HH_SET_RPT_EVT: 730 /* fall through */ 731 case BTA_HH_SET_IDLE_EVT: 732 /* fall through */ 733 default: 734#if (BTA_HH_DEBUG == TRUE) 735 APPL_TRACE_DEBUG("invalid transaction type for DATA payload: 4_evt[%s]", 736 bta_hh_get_w4_event(p_cb->w4_evt)); 737#endif 738 break; 739 } 740 741 /* inform PM for mode change */ 742 bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr); 743 bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); 744 745 (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&hs_data); 746 747 p_cb->w4_evt = 0; 748 osi_free_and_reset((void**)&pdata); 749} 750 751/******************************************************************************* 752 * 753 * Function bta_hh_open_failure 754 * 755 * Description report HID open failure when at wait for connection state 756 * and receive device close event. 757 * 758 * 759 * Returns void 760 * 761 ******************************************************************************/ 762void bta_hh_open_failure(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 763 tBTA_HH_CONN conn_dat; 764 uint32_t reason = p_data->hid_cback.data; /* Reason for closing (32-bit) */ 765 766 memset(&conn_dat, 0, sizeof(tBTA_HH_CONN)); 767 conn_dat.handle = p_cb->hid_handle; 768 conn_dat.status = 769 (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR; 770 conn_dat.bda = p_cb->addr; 771 HID_HostCloseDev(p_cb->hid_handle); 772 773 /* Report OPEN fail event */ 774 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat); 775 776#if (BTA_HH_DEBUG == TRUE) 777 bta_hh_trace_dev_db(); 778#endif 779 /* clean up control block, but retain SDP info and device handle */ 780 p_cb->vp = false; 781 p_cb->w4_evt = 0; 782 783 /* if no connection is active and HH disable is signaled, disable service */ 784 if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) { 785 bta_hh_disc_cmpl(); 786 } 787 788 /* Error in opening hid connection, reset flags */ 789 p_cb->incoming_conn = false; 790 p_cb->incoming_hid_handle = BTA_HH_INVALID_HANDLE; 791} 792 793/******************************************************************************* 794 * 795 * Function bta_hh_close_act 796 * 797 * Description HID Host process a close event 798 * 799 * 800 * Returns void 801 * 802 ******************************************************************************/ 803void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 804 tBTA_HH_CONN conn_dat; 805 tBTA_HH_CBDATA disc_dat = {BTA_HH_OK, 0}; 806 uint32_t reason = p_data->hid_cback.data; /* Reason for closing (32-bit) */ 807 808 /* if HID_HDEV_EVT_VC_UNPLUG was received, report BTA_HH_VC_UNPLUG_EVT */ 809 uint16_t event = p_cb->vp ? BTA_HH_VC_UNPLUG_EVT : BTA_HH_CLOSE_EVT; 810 811 disc_dat.handle = p_cb->hid_handle; 812 disc_dat.status = p_data->hid_cback.data; 813 814 /* Check reason for closing */ 815 if ((reason & (HID_L2CAP_CONN_FAIL | 816 HID_L2CAP_REQ_FAIL)) || /* Failure to initialize connection 817 (page timeout or l2cap error) */ 818 (reason == 819 HID_ERR_AUTH_FAILED) || /* Authenication error (while initiating) */ 820 (reason == HID_ERR_L2CAP_FAILED)) /* Failure creating l2cap connection */ 821 { 822 /* Failure in opening connection */ 823 conn_dat.handle = p_cb->hid_handle; 824 conn_dat.status = 825 (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR; 826 conn_dat.bda = p_cb->addr; 827 HID_HostCloseDev(p_cb->hid_handle); 828 829 /* Report OPEN fail event */ 830 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat); 831 832#if (BTA_HH_DEBUG == TRUE) 833 bta_hh_trace_dev_db(); 834#endif 835 return; 836 } 837 /* otherwise report CLOSE/VC_UNPLUG event */ 838 else { 839 /* finaliza device driver */ 840 bta_hh_co_close(p_cb->hid_handle, p_cb->app_id); 841 /* inform role manager */ 842 bta_sys_conn_close(BTA_ID_HH, p_cb->app_id, p_cb->addr); 843 /* update total conn number */ 844 bta_hh_cb.cnt_num--; 845 846 if (disc_dat.status) disc_dat.status = BTA_HH_ERR; 847 848 (*bta_hh_cb.p_cback)(event, (tBTA_HH*)&disc_dat); 849 850 /* if virtually unplug, remove device */ 851 if (p_cb->vp) { 852 HID_HostRemoveDev(p_cb->hid_handle); 853 bta_hh_clean_up_kdev(p_cb); 854 } 855 856#if (BTA_HH_DEBUG == TRUE) 857 bta_hh_trace_dev_db(); 858#endif 859 } 860 861 /* clean up control block, but retain SDP info and device handle */ 862 p_cb->vp = false; 863 p_cb->w4_evt = 0; 864 865 /* if no connection is active and HH disable is signaled, disable service */ 866 if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) { 867 bta_hh_disc_cmpl(); 868 } 869 870 return; 871} 872 873/******************************************************************************* 874 * 875 * Function bta_hh_get_dscp_act 876 * 877 * Description Get device report descriptor 878 * 879 * 880 * Returns void 881 * 882 ******************************************************************************/ 883void bta_hh_get_dscp_act(tBTA_HH_DEV_CB* p_cb, 884 UNUSED_ATTR tBTA_HH_DATA* p_data) { 885#if (BTA_HH_LE_INCLUDED == TRUE) 886 if (p_cb->is_le_device) { 887 bta_hh_le_get_dscp_act(p_cb); 888 } else 889#endif 890 (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH*)&p_cb->dscp_info); 891} 892 893/******************************************************************************* 894 * 895 * Function bta_hh_maint_dev_act 896 * 897 * Description HID Host maintain device list. 898 * 899 * 900 * Returns void 901 * 902 ******************************************************************************/ 903void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 904 tBTA_HH_MAINT_DEV* p_dev_info = &p_data->api_maintdev; 905 tBTA_HH_DEV_INFO dev_info; 906 uint8_t dev_handle; 907 908 dev_info.status = BTA_HH_ERR; 909 dev_info.handle = BTA_HH_INVALID_HANDLE; 910 911 switch (p_dev_info->sub_event) { 912 case BTA_HH_ADD_DEV_EVT: /* add a device */ 913 dev_info.bda = p_dev_info->bda; 914 /* initialize callback data */ 915 if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { 916#if (BTA_HH_LE_INCLUDED == TRUE) 917 if (bta_hh_is_le_device(p_cb, p_data->api_conn.bd_addr)) { 918 dev_info.handle = bta_hh_le_add_device(p_cb, p_dev_info); 919 dev_info.status = BTA_HH_OK; 920 } else 921#endif 922 923 if (HID_HostAddDev(p_dev_info->bda, p_dev_info->attr_mask, 924 &dev_handle) == HID_SUCCESS) { 925 dev_info.handle = dev_handle; 926 dev_info.status = BTA_HH_OK; 927 928#if (BTA_HH_LE_INCLUDED == TRUE) 929 /* update DI information */ 930 bta_hh_update_di_info(p_cb, p_dev_info->dscp_info.vendor_id, 931 p_dev_info->dscp_info.product_id, 932 p_dev_info->dscp_info.version, 933 p_dev_info->dscp_info.flag); 934#else 935 bta_hh_update_di_info(p_cb, p_dev_info->dscp_info.vendor_id, 936 p_dev_info->dscp_info.product_id, 937 p_dev_info->dscp_info.version, 0); 938 939#endif 940 /* add to BTA device list */ 941 bta_hh_add_device_to_list( 942 p_cb, dev_handle, p_dev_info->attr_mask, 943 &p_dev_info->dscp_info.descriptor, p_dev_info->sub_class, 944 p_dev_info->dscp_info.ssr_max_latency, 945 p_dev_info->dscp_info.ssr_min_tout, p_dev_info->app_id); 946 /* update cb_index[] map */ 947 bta_hh_cb.cb_index[dev_handle] = p_cb->index; 948 } 949 } else /* device already been added */ 950 { 951 dev_info.handle = p_cb->hid_handle; 952 dev_info.status = BTA_HH_OK; 953 } 954#if (BTA_HH_DEBUG == TRUE) 955 bta_hh_trace_dev_db(); 956#endif 957 958 break; 959 case BTA_HH_RMV_DEV_EVT: /* remove device */ 960 dev_info.handle = (uint8_t)p_dev_info->hdr.layer_specific; 961 dev_info.bda = p_cb->addr; 962 963#if (BTA_HH_LE_INCLUDED == TRUE) 964 if (p_cb->is_le_device) { 965 bta_hh_le_remove_dev_bg_conn(p_cb); 966 bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL); 967 bta_hh_clean_up_kdev(p_cb); 968 } else 969#endif 970 { 971 if (HID_HostRemoveDev(dev_info.handle) == HID_SUCCESS) { 972 dev_info.status = BTA_HH_OK; 973 974 /* remove from known device list in BTA */ 975 bta_hh_clean_up_kdev(p_cb); 976 } 977 } 978 break; 979 980 default: 981 APPL_TRACE_DEBUG("invalid command"); 982 break; 983 } 984 985 (*bta_hh_cb.p_cback)(p_dev_info->sub_event, (tBTA_HH*)&dev_info); 986} 987/******************************************************************************* 988 * 989 * Function bta_hh_write_dev_act 990 * 991 * Description Write device action. can be SET/GET/DATA transaction. 992 * 993 * Returns void 994 * 995 ******************************************************************************/ 996void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 997 tBTA_HH_CBDATA cbdata = {BTA_HH_OK, 0}; 998 uint16_t event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) + 999 BTA_HH_FST_TRANS_CB_EVT; 1000 1001#if (BTA_HH_LE_INCLUDED == TRUE) 1002 if (p_cb->is_le_device) 1003 bta_hh_le_write_dev_act(p_cb, p_data); 1004 else 1005#endif 1006 { 1007 1008 cbdata.handle = p_cb->hid_handle; 1009 1010 /* match up BTE/BTA report/boot mode def */ 1011 if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL) { 1012 p_data->api_sndcmd.param = 1013 (p_data->api_sndcmd.param == BTA_HH_PROTO_RPT_MODE) 1014 ? HID_PAR_PROTOCOL_REPORT 1015 : HID_PAR_PROTOCOL_BOOT_MODE; 1016 } 1017 1018 if (HID_HostWriteDev(p_cb->hid_handle, p_data->api_sndcmd.t_type, 1019 p_data->api_sndcmd.param, p_data->api_sndcmd.data, 1020 p_data->api_sndcmd.rpt_id, 1021 p_data->api_sndcmd.p_data) != HID_SUCCESS) { 1022 APPL_TRACE_ERROR("HID_HostWriteDev Error "); 1023 cbdata.status = BTA_HH_ERR; 1024 1025 if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL && 1026 p_data->api_sndcmd.t_type != HID_TRANS_DATA) 1027 (*bta_hh_cb.p_cback)(event, (tBTA_HH*)&cbdata); 1028 else if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) 1029 (*bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, (tBTA_HH*)&cbdata); 1030 } else { 1031 switch (p_data->api_sndcmd.t_type) { 1032 case HID_TRANS_SET_PROTOCOL: 1033 /* fall through */ 1034 case HID_TRANS_GET_REPORT: 1035 /* fall through */ 1036 case HID_TRANS_SET_REPORT: 1037 /* fall through */ 1038 case HID_TRANS_GET_PROTOCOL: 1039 /* fall through */ 1040 case HID_TRANS_GET_IDLE: 1041 /* fall through */ 1042 case HID_TRANS_SET_IDLE: /* set w4_handsk event name for callback 1043 function use */ 1044 p_cb->w4_evt = event; 1045 break; 1046 case HID_TRANS_DATA: /* output report */ 1047 /* fall through */ 1048 case HID_TRANS_CONTROL: 1049 /* no handshake event will be generated */ 1050 /* if VC_UNPLUG is issued, set flag */ 1051 if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) 1052 p_cb->vp = true; 1053 1054 break; 1055 /* currently not expected */ 1056 case HID_TRANS_DATAC: 1057 default: 1058 APPL_TRACE_DEBUG("%s: cmd type = %d", __func__, 1059 p_data->api_sndcmd.t_type); 1060 break; 1061 } 1062 1063 /* if not control type transaction, notify PM for energy control */ 1064 if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) { 1065 /* inform PM for mode change */ 1066 bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr); 1067 bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); 1068 } else if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND) { 1069 bta_sys_sco_close(BTA_ID_HH, p_cb->app_id, p_cb->addr); 1070 } else if (p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND) { 1071 bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr); 1072 } 1073 } 1074 } 1075 return; 1076} 1077 1078/***************************************************************************** 1079 * Static Function 1080 ****************************************************************************/ 1081/******************************************************************************* 1082 * 1083 * Function bta_hh_cback 1084 * 1085 * Description BTA HH callback function. 1086 * 1087 * 1088 * Returns void 1089 * 1090 ******************************************************************************/ 1091static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr, 1092 uint8_t event, uint32_t data, BT_HDR* pdata) { 1093 uint16_t sm_event = BTA_HH_INVALID_EVT; 1094 uint8_t xx = 0; 1095 1096#if (BTA_HH_DEBUG == TRUE) 1097 APPL_TRACE_DEBUG("%s::HID_event [%s]", __func__, 1098 bta_hh_hid_event_name(event)); 1099#endif 1100 1101 switch (event) { 1102 case HID_HDEV_EVT_OPEN: 1103 sm_event = BTA_HH_INT_OPEN_EVT; 1104 break; 1105 case HID_HDEV_EVT_CLOSE: 1106 sm_event = BTA_HH_INT_CLOSE_EVT; 1107 break; 1108 case HID_HDEV_EVT_INTR_DATA: 1109 sm_event = BTA_HH_INT_DATA_EVT; 1110 break; 1111 case HID_HDEV_EVT_HANDSHAKE: 1112 sm_event = BTA_HH_INT_HANDSK_EVT; 1113 break; 1114 case HID_HDEV_EVT_CTRL_DATA: 1115 sm_event = BTA_HH_INT_CTRL_DATA; 1116 break; 1117 case HID_HDEV_EVT_RETRYING: 1118 break; 1119 case HID_HDEV_EVT_INTR_DATC: 1120 case HID_HDEV_EVT_CTRL_DATC: 1121 /* Unhandled events: Free buffer for DATAC */ 1122 osi_free_and_reset((void**)&pdata); 1123 break; 1124 case HID_HDEV_EVT_VC_UNPLUG: 1125 for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) { 1126 if (bta_hh_cb.kdev[xx].hid_handle == dev_handle) { 1127 bta_hh_cb.kdev[xx].vp = true; 1128 break; 1129 } 1130 } 1131 break; 1132 } 1133 1134 if (sm_event != BTA_HH_INVALID_EVT) { 1135 tBTA_HH_CBACK_DATA* p_buf = (tBTA_HH_CBACK_DATA*)osi_malloc( 1136 sizeof(tBTA_HH_CBACK_DATA) + sizeof(BT_HDR)); 1137 p_buf->hdr.event = sm_event; 1138 p_buf->hdr.layer_specific = (uint16_t)dev_handle; 1139 p_buf->data = data; 1140 p_buf->addr = addr; 1141 p_buf->p_data = pdata; 1142 1143 bta_sys_sendmsg(p_buf); 1144 } 1145} 1146 1147/******************************************************************************* 1148 * 1149 * Function bta_hh_get_trans_status 1150 * 1151 * Description translate a handshake result code into BTA HH 1152 * status code 1153 * 1154 ******************************************************************************/ 1155static tBTA_HH_STATUS bta_hh_get_trans_status(uint32_t result) { 1156 switch (result) { 1157 case HID_PAR_HANDSHAKE_RSP_SUCCESS: /* (0) */ 1158 return BTA_HH_OK; 1159 case HID_PAR_HANDSHAKE_RSP_NOT_READY: /* (1) */ 1160 case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID: /* (2) */ 1161 case HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ: /* (3) */ 1162 case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM: /* (4) */ 1163 return (tBTA_HH_STATUS)result; 1164 case HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN: /* (14) */ 1165 case HID_PAR_HANDSHAKE_RSP_ERR_FATAL: /* (15) */ 1166 default: 1167 return BTA_HH_HS_ERROR; 1168 break; 1169 } 1170} 1171/***************************************************************************** 1172 * Debug Functions 1173 ****************************************************************************/ 1174 1175#if (BTA_HH_DEBUG == TRUE) 1176static const char* bta_hh_get_w4_event(uint16_t event) { 1177 switch (event) { 1178 case BTA_HH_GET_RPT_EVT: 1179 return "BTA_HH_GET_RPT_EVT"; 1180 case BTA_HH_SET_RPT_EVT: 1181 return "BTA_HH_SET_RPT_EVT"; 1182 case BTA_HH_GET_PROTO_EVT: 1183 return "BTA_HH_GET_PROTO_EVT"; 1184 case BTA_HH_SET_PROTO_EVT: 1185 return "BTA_HH_SET_PROTO_EVT"; 1186 case BTA_HH_GET_IDLE_EVT: 1187 return "BTA_HH_GET_IDLE_EVT"; 1188 case BTA_HH_SET_IDLE_EVT: 1189 return "BTA_HH_SET_IDLE_EVT"; 1190 case BTA_HH_OPEN_EVT: 1191 return "BTA_HH_OPEN_EVT"; 1192 default: 1193 return "Unknown event"; 1194 } 1195} 1196 1197static const char* bta_hh_hid_event_name(uint16_t event) { 1198 switch (event) { 1199 case HID_HDEV_EVT_OPEN: 1200 return "HID_HDEV_EVT_OPEN"; 1201 case HID_HDEV_EVT_CLOSE: 1202 return "HID_HDEV_EVT_CLOSE"; 1203 case HID_HDEV_EVT_RETRYING: 1204 return "HID_HDEV_EVT_RETRYING"; 1205 case HID_HDEV_EVT_INTR_DATA: 1206 return "HID_HDEV_EVT_INTR_DATA"; 1207 case HID_HDEV_EVT_INTR_DATC: 1208 return "HID_HDEV_EVT_INTR_DATC"; 1209 case HID_HDEV_EVT_CTRL_DATA: 1210 return "HID_HDEV_EVT_CTRL_DATA"; 1211 case HID_HDEV_EVT_CTRL_DATC: 1212 return "HID_HDEV_EVT_CTRL_DATC"; 1213 case HID_HDEV_EVT_HANDSHAKE: 1214 return "HID_HDEV_EVT_HANDSHAKE"; 1215 case HID_HDEV_EVT_VC_UNPLUG: 1216 return "HID_HDEV_EVT_VC_UNPLUG"; 1217 default: 1218 return "Unknown HID event"; 1219 } 1220} 1221#endif 1222#endif /* BTA_HH_INCLUDED */ 1223