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