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