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