1 /****************************************************************************** 2 * 3 * Copyright (C) 2016 The Android Open Source Project 4 * Copyright (C) 2009-2012 Broadcom Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 ******************************************************************************/ 19 20 /************************************************************************************ 21 * 22 * Filename: btif_hd.c 23 * 24 * Description: HID Device Profile Bluetooth Interface 25 * 26 * 27 ***********************************************************************************/ 28 #include <errno.h> 29 #include <hardware/bluetooth.h> 30 #include <hardware/bt_hd.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #define LOG_TAG "BTIF_HD" 36 37 #include "bta_api.h" 38 #include "bta_hd_api.h" 39 #include "bta_hh_api.h" 40 41 #include "btif_common.h" 42 #include "btif_hd.h" 43 #include "btif_storage.h" 44 #include "btif_util.h" 45 46 #define BTIF_HD_APP_NAME_LEN 50 47 #define BTIF_HD_APP_DESCRIPTION_LEN 50 48 #define BTIF_HD_APP_PROVIDER_LEN 50 49 #define BTIF_HD_APP_DESCRIPTOR_LEN 2048 50 51 #define COD_HID_KEYBOARD 0x0540 52 #define COD_HID_POINTING 0x0580 53 #define COD_HID_COMBO 0x05C0 54 #define COD_HID_MAJOR 0x0500 55 56 extern bool bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr); 57 extern bool check_cod_hid(const bt_bdaddr_t* remote_bdaddr); 58 extern void btif_hh_service_registration(bool enable); 59 60 /* HD request events */ 61 typedef enum { BTIF_HD_DUMMY_REQ_EVT = 0 } btif_hd_req_evt_t; 62 63 btif_hd_cb_t btif_hd_cb; 64 65 static bthd_callbacks_t* bt_hd_callbacks = NULL; 66 static tBTA_HD_APP_INFO app_info; 67 static tBTA_HD_QOS_INFO in_qos; 68 static tBTA_HD_QOS_INFO out_qos; 69 70 static void intr_data_copy_cb(uint16_t event, char* p_dst, char* p_src) { 71 tBTA_HD_INTR_DATA* p_dst_data = (tBTA_HD_INTR_DATA*)p_dst; 72 tBTA_HD_INTR_DATA* p_src_data = (tBTA_HD_INTR_DATA*)p_src; 73 uint8_t* p_data; 74 75 if (!p_src) return; 76 77 if (event != BTA_HD_INTR_DATA_EVT) return; 78 79 memcpy(p_dst, p_src, sizeof(tBTA_HD_INTR_DATA)); 80 81 p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HD_INTR_DATA); 82 83 memcpy(p_data, p_src_data->p_data, p_src_data->len); 84 85 p_dst_data->p_data = p_data; 86 } 87 88 static void set_report_copy_cb(uint16_t event, char* p_dst, char* p_src) { 89 tBTA_HD_SET_REPORT* p_dst_data = (tBTA_HD_SET_REPORT*)p_dst; 90 tBTA_HD_SET_REPORT* p_src_data = (tBTA_HD_SET_REPORT*)p_src; 91 uint8_t* p_data; 92 93 if (!p_src) return; 94 95 if (event != BTA_HD_SET_REPORT_EVT) return; 96 97 memcpy(p_dst, p_src, sizeof(tBTA_HD_SET_REPORT)); 98 99 p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HD_SET_REPORT); 100 101 memcpy(p_data, p_src_data->p_data, p_src_data->len); 102 103 p_dst_data->p_data = p_data; 104 } 105 106 static void btif_hd_free_buf() { 107 if (app_info.descriptor.dsc_list) osi_free(app_info.descriptor.dsc_list); 108 if (app_info.p_description) osi_free(app_info.p_description); 109 if (app_info.p_name) osi_free(app_info.p_name); 110 if (app_info.p_provider) osi_free(app_info.p_provider); 111 app_info.descriptor.dsc_list = NULL; 112 app_info.p_description = NULL; 113 app_info.p_name = NULL; 114 app_info.p_provider = NULL; 115 } 116 117 /******************************************************************************* 118 * 119 * Function btif_hd_remove_device 120 * 121 * Description Removes plugged device 122 * 123 * Returns void 124 * 125 ******************************************************************************/ 126 void btif_hd_remove_device(bt_bdaddr_t bd_addr) { 127 BTA_HdRemoveDevice((uint8_t*)&bd_addr); 128 btif_storage_remove_hidd(&bd_addr); 129 } 130 131 /******************************************************************************* 132 * 133 * Function btif_hd_upstreams_evt 134 * 135 * Description Executes events in btif context 136 * 137 * Returns void 138 * 139 ******************************************************************************/ 140 static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { 141 tBTA_HD* p_data = (tBTA_HD*)p_param; 142 143 BTIF_TRACE_API("%s: event=%s", __func__, dump_hd_event(event)); 144 145 switch (event) { 146 case BTA_HD_ENABLE_EVT: 147 BTIF_TRACE_DEBUG("%s: status=%d", __func__, p_data->status); 148 if (p_data->status == BTA_HD_OK) { 149 btif_storage_load_hidd(); 150 btif_hd_cb.status = BTIF_HD_ENABLED; 151 /* Register the app if not yet registered */ 152 if (!btif_hd_cb.app_registered) { 153 BTA_HdRegisterApp(&app_info, &in_qos, &out_qos); 154 btif_hd_free_buf(); 155 } 156 } else { 157 btif_hd_cb.status = BTIF_HD_DISABLED; 158 BTIF_TRACE_WARNING("Failed to enable BT-HD, status=%d", p_data->status); 159 } 160 break; 161 162 case BTA_HD_DISABLE_EVT: 163 BTIF_TRACE_DEBUG("%s: status=%d", __func__, p_data->status); 164 btif_hd_cb.status = BTIF_HD_DISABLED; 165 if (btif_hd_cb.service_dereg_active) { 166 BTIF_TRACE_WARNING("registering hid host now"); 167 btif_hh_service_registration(TRUE); 168 btif_hd_cb.service_dereg_active = FALSE; 169 } 170 btif_hd_free_buf(); 171 if (p_data->status == BTA_HD_OK) 172 memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); 173 else 174 BTIF_TRACE_WARNING("Failed to disable BT-HD, status=%d", 175 p_data->status); 176 break; 177 178 case BTA_HD_REGISTER_APP_EVT: { 179 bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->reg_status.bda; 180 181 if (!p_data->reg_status.in_use) { 182 addr = NULL; 183 } 184 185 btif_hd_cb.app_registered = TRUE; 186 HAL_CBACK(bt_hd_callbacks, application_state_cb, addr, 187 BTHD_APP_STATE_REGISTERED); 188 } break; 189 190 case BTA_HD_UNREGISTER_APP_EVT: 191 btif_hd_cb.app_registered = FALSE; 192 HAL_CBACK(bt_hd_callbacks, application_state_cb, NULL, 193 BTHD_APP_STATE_NOT_REGISTERED); 194 if (btif_hd_cb.service_dereg_active) { 195 BTIF_TRACE_WARNING("disabling hid device service now"); 196 btif_hd_free_buf(); 197 BTA_HdDisable(); 198 } 199 break; 200 201 case BTA_HD_OPEN_EVT: { 202 bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->conn.bda; 203 BTIF_TRACE_WARNING( 204 "BTA_HD_OPEN_EVT, address (%02x:%02x:%02x:%02x:%02x:%02x)", 205 addr->address[0], addr->address[1], addr->address[2], 206 addr->address[3], addr->address[4], addr->address[5]); 207 /* Check if the connection is from hid host and not hid device */ 208 if (check_cod_hid(addr)) { 209 /* Incoming connection from hid device, reject it */ 210 BTIF_TRACE_WARNING("remote device is not hid host, disconnecting"); 211 btif_hd_cb.forced_disc = TRUE; 212 BTA_HdDisconnect(); 213 break; 214 } 215 btif_storage_set_hidd((bt_bdaddr_t*)&p_data->conn.bda); 216 217 HAL_CBACK(bt_hd_callbacks, connection_state_cb, 218 (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_CONNECTED); 219 } break; 220 221 case BTA_HD_CLOSE_EVT: 222 if (btif_hd_cb.forced_disc) { 223 bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->conn.bda; 224 BTIF_TRACE_WARNING("remote device was forcefully disconnected"); 225 btif_hd_remove_device(*addr); 226 btif_hd_cb.forced_disc = FALSE; 227 break; 228 } 229 HAL_CBACK(bt_hd_callbacks, connection_state_cb, 230 (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); 231 break; 232 233 case BTA_HD_GET_REPORT_EVT: 234 HAL_CBACK(bt_hd_callbacks, get_report_cb, p_data->get_report.report_type, 235 p_data->get_report.report_id, p_data->get_report.buffer_size); 236 break; 237 238 case BTA_HD_SET_REPORT_EVT: 239 HAL_CBACK(bt_hd_callbacks, set_report_cb, p_data->set_report.report_type, 240 p_data->set_report.report_id, p_data->set_report.len, 241 p_data->set_report.p_data); 242 break; 243 244 case BTA_HD_SET_PROTOCOL_EVT: 245 HAL_CBACK(bt_hd_callbacks, set_protocol_cb, p_data->set_protocol); 246 break; 247 248 case BTA_HD_INTR_DATA_EVT: 249 HAL_CBACK(bt_hd_callbacks, intr_data_cb, p_data->intr_data.report_id, 250 p_data->intr_data.len, p_data->intr_data.p_data); 251 break; 252 253 case BTA_HD_VC_UNPLUG_EVT: 254 HAL_CBACK(bt_hd_callbacks, connection_state_cb, 255 (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); 256 if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) { 257 BTIF_TRACE_DEBUG("%s: Removing bonding as only HID profile connected", 258 __func__); 259 BTA_DmRemoveDevice((uint8_t*)&p_data->conn.bda); 260 } else { 261 bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)&p_data->conn.bda; 262 BTIF_TRACE_DEBUG( 263 "%s: Only removing HID data as some other profiles " 264 "connected", 265 __func__); 266 btif_hd_remove_device(*bd_addr); 267 } 268 HAL_CBACK(bt_hd_callbacks, vc_unplug_cb); 269 break; 270 271 case BTA_HD_CONN_STATE_EVT: 272 HAL_CBACK(bt_hd_callbacks, connection_state_cb, 273 (bt_bdaddr_t*)&p_data->conn.bda, 274 (bthd_connection_state_t)p_data->conn.status); 275 break; 276 277 default: 278 BTIF_TRACE_WARNING("%s: unknown event (%d)", __func__, event); 279 break; 280 } 281 } 282 283 /******************************************************************************* 284 * 285 * Function bte_hd_evt 286 * 287 * Description Switches context from BTE to BTIF for all BT-HD events 288 * 289 * Returns void 290 * 291 ******************************************************************************/ 292 293 static void bte_hd_evt(tBTA_HD_EVT event, tBTA_HD* p_data) { 294 bt_status_t status; 295 int param_len = 0; 296 tBTIF_COPY_CBACK* p_copy_cback = NULL; 297 298 BTIF_TRACE_API("%s event=%d", __func__, event); 299 300 switch (event) { 301 case BTA_HD_ENABLE_EVT: 302 case BTA_HD_DISABLE_EVT: 303 case BTA_HD_UNREGISTER_APP_EVT: 304 param_len = sizeof(tBTA_HD_STATUS); 305 break; 306 307 case BTA_HD_REGISTER_APP_EVT: 308 param_len = sizeof(tBTA_HD_REG_STATUS); 309 break; 310 311 case BTA_HD_OPEN_EVT: 312 case BTA_HD_CLOSE_EVT: 313 case BTA_HD_VC_UNPLUG_EVT: 314 case BTA_HD_CONN_STATE_EVT: 315 param_len = sizeof(tBTA_HD_CONN); 316 break; 317 318 case BTA_HD_GET_REPORT_EVT: 319 param_len += sizeof(tBTA_HD_GET_REPORT); 320 break; 321 322 case BTA_HD_SET_REPORT_EVT: 323 param_len = sizeof(tBTA_HD_SET_REPORT) + p_data->set_report.len; 324 p_copy_cback = set_report_copy_cb; 325 break; 326 327 case BTA_HD_SET_PROTOCOL_EVT: 328 param_len += sizeof(p_data->set_protocol); 329 break; 330 331 case BTA_HD_INTR_DATA_EVT: 332 param_len = sizeof(tBTA_HD_INTR_DATA) + p_data->intr_data.len; 333 p_copy_cback = intr_data_copy_cb; 334 break; 335 } 336 337 status = btif_transfer_context(btif_hd_upstreams_evt, (uint16_t)event, 338 (char*)p_data, param_len, p_copy_cback); 339 340 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 341 } 342 343 /******************************************************************************* 344 * 345 * Function init 346 * 347 * Description Initializes BT-HD interface 348 * 349 * Returns BT_STATUS_SUCCESS 350 * 351 ******************************************************************************/ 352 static bt_status_t init(bthd_callbacks_t* callbacks) { 353 BTIF_TRACE_API("%s", __func__); 354 355 bt_hd_callbacks = callbacks; 356 memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); 357 358 btif_enable_service(BTA_HIDD_SERVICE_ID); 359 360 return BT_STATUS_SUCCESS; 361 } 362 363 /******************************************************************************* 364 * 365 * Function cleanup 366 * 367 * Description Cleans up BT-HD interface 368 * 369 * Returns none 370 * 371 ******************************************************************************/ 372 static void cleanup(void) { 373 BTIF_TRACE_API("hd:%s", __func__); 374 375 if (bt_hd_callbacks) { 376 /* update flag, not to enable hid host service now as BT is switching off */ 377 btif_hd_cb.service_dereg_active = FALSE; 378 btif_disable_service(BTA_HIDD_SERVICE_ID); 379 bt_hd_callbacks = NULL; 380 } 381 } 382 383 /******************************************************************************* 384 * 385 * Function register_app 386 * 387 * Description Registers HID Device application 388 * 389 * Returns bt_status_t 390 * 391 ******************************************************************************/ 392 static bt_status_t register_app(bthd_app_param_t* p_app_param, 393 bthd_qos_param_t* p_in_qos, 394 bthd_qos_param_t* p_out_qos) { 395 BTIF_TRACE_API("%s", __func__); 396 397 if (btif_hd_cb.app_registered) { 398 BTIF_TRACE_WARNING("%s: application already registered", __func__); 399 return BT_STATUS_BUSY; 400 } 401 402 app_info.p_name = (char*)osi_malloc(BTIF_HD_APP_NAME_LEN); 403 memcpy(app_info.p_name, p_app_param->name, BTIF_HD_APP_NAME_LEN); 404 app_info.p_description = (char*)osi_malloc(BTIF_HD_APP_DESCRIPTION_LEN); 405 memcpy(app_info.p_description, p_app_param->description, 406 BTIF_HD_APP_DESCRIPTION_LEN); 407 app_info.p_provider = (char*)osi_malloc(BTIF_HD_APP_PROVIDER_LEN); 408 memcpy(app_info.p_provider, p_app_param->provider, BTIF_HD_APP_PROVIDER_LEN); 409 app_info.subclass = p_app_param->subclass; 410 app_info.descriptor.dl_len = p_app_param->desc_list_len; 411 app_info.descriptor.dsc_list = 412 (uint8_t*)osi_malloc(app_info.descriptor.dl_len); 413 memcpy(app_info.descriptor.dsc_list, p_app_param->desc_list, 414 p_app_param->desc_list_len); 415 416 in_qos.service_type = p_in_qos->service_type; 417 in_qos.token_rate = p_in_qos->token_rate; 418 in_qos.token_bucket_size = p_in_qos->token_bucket_size; 419 in_qos.peak_bandwidth = p_in_qos->peak_bandwidth; 420 in_qos.access_latency = p_in_qos->access_latency; 421 in_qos.delay_variation = p_in_qos->delay_variation; 422 423 out_qos.service_type = p_out_qos->service_type; 424 out_qos.token_rate = p_out_qos->token_rate; 425 out_qos.token_bucket_size = p_out_qos->token_bucket_size; 426 out_qos.peak_bandwidth = p_out_qos->peak_bandwidth; 427 out_qos.access_latency = p_out_qos->access_latency; 428 out_qos.delay_variation = p_out_qos->delay_variation; 429 430 /* register HID Device with L2CAP and unregister HID Host with L2CAP */ 431 /* Disable HH */ 432 btif_hh_service_registration(FALSE); 433 434 return BT_STATUS_SUCCESS; 435 } 436 437 /******************************************************************************* 438 * 439 * Function unregister_app 440 * 441 * Description Unregisters HID Device application 442 * 443 * Returns bt_status_t 444 * 445 ******************************************************************************/ 446 static bt_status_t unregister_app(void) { 447 BTIF_TRACE_API("%s", __func__); 448 449 if (!btif_hd_cb.app_registered) { 450 BTIF_TRACE_WARNING("%s: application not yet registered", __func__); 451 return BT_STATUS_NOT_READY; 452 } 453 454 if (btif_hd_cb.status != BTIF_HD_ENABLED) { 455 BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, 456 btif_hd_cb.status); 457 return BT_STATUS_NOT_READY; 458 } 459 460 if (btif_hd_cb.service_dereg_active) { 461 BTIF_TRACE_WARNING("%s: BT-HD deregistering in progress", __func__); 462 return BT_STATUS_BUSY; 463 } 464 465 btif_hd_cb.service_dereg_active = TRUE; 466 BTA_HdUnregisterApp(); 467 468 return BT_STATUS_SUCCESS; 469 } 470 471 /******************************************************************************* 472 * 473 * Function connect 474 * 475 * Description Connects to host 476 * 477 * Returns bt_status_t 478 * 479 ******************************************************************************/ 480 static bt_status_t connect(bt_bdaddr_t* bd_addr) { 481 BTIF_TRACE_API("%s", __func__); 482 483 if (!btif_hd_cb.app_registered) { 484 BTIF_TRACE_WARNING("%s: application not yet registered", __func__); 485 return BT_STATUS_NOT_READY; 486 } 487 488 if (btif_hd_cb.status != BTIF_HD_ENABLED) { 489 BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, 490 btif_hd_cb.status); 491 return BT_STATUS_NOT_READY; 492 } 493 494 BTA_HdConnect(bd_addr->address); 495 496 return BT_STATUS_SUCCESS; 497 } 498 499 /******************************************************************************* 500 * 501 * Function disconnect 502 * 503 * Description Disconnects from host 504 * 505 * Returns bt_status_t 506 * 507 ******************************************************************************/ 508 static bt_status_t disconnect(void) { 509 BTIF_TRACE_API("%s", __func__); 510 511 if (!btif_hd_cb.app_registered) { 512 BTIF_TRACE_WARNING("%s: application not yet registered", __func__); 513 return BT_STATUS_NOT_READY; 514 } 515 516 if (btif_hd_cb.status != BTIF_HD_ENABLED) { 517 BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, 518 btif_hd_cb.status); 519 return BT_STATUS_NOT_READY; 520 } 521 522 BTA_HdDisconnect(); 523 524 return BT_STATUS_SUCCESS; 525 } 526 527 /******************************************************************************* 528 * 529 * Function send_report 530 * 531 * Description Sends Reports to hid host 532 * 533 * Returns bt_status_t 534 * 535 ******************************************************************************/ 536 static bt_status_t send_report(bthd_report_type_t type, uint8_t id, 537 uint16_t len, uint8_t* p_data) { 538 tBTA_HD_REPORT report; 539 540 APPL_TRACE_VERBOSE("%s: type=%d id=%d len=%d", __func__, type, id, len); 541 542 if (!btif_hd_cb.app_registered) { 543 BTIF_TRACE_WARNING("%s: application not yet registered", __func__); 544 return BT_STATUS_NOT_READY; 545 } 546 547 if (btif_hd_cb.status != BTIF_HD_ENABLED) { 548 BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, 549 btif_hd_cb.status); 550 return BT_STATUS_NOT_READY; 551 } 552 553 if (type == BTHD_REPORT_TYPE_INTRDATA) { 554 report.type = BTHD_REPORT_TYPE_INPUT; 555 report.use_intr = TRUE; 556 } else { 557 report.type = (type & 0x03); 558 report.use_intr = FALSE; 559 } 560 561 report.id = id; 562 report.len = len; 563 report.p_data = p_data; 564 565 BTA_HdSendReport(&report); 566 567 return BT_STATUS_SUCCESS; 568 } 569 570 /******************************************************************************* 571 * 572 * Function report_error 573 * 574 * Description Sends HANDSHAKE with error info for invalid SET_REPORT 575 * 576 * Returns bt_status_t 577 * 578 ******************************************************************************/ 579 static bt_status_t report_error(uint8_t error) { 580 BTIF_TRACE_API("%s", __func__); 581 582 if (!btif_hd_cb.app_registered) { 583 BTIF_TRACE_WARNING("%s: application not yet registered", __func__); 584 return BT_STATUS_NOT_READY; 585 } 586 587 if (btif_hd_cb.status != BTIF_HD_ENABLED) { 588 BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, 589 btif_hd_cb.status); 590 return BT_STATUS_NOT_READY; 591 } 592 593 BTA_HdReportError(error); 594 595 return BT_STATUS_SUCCESS; 596 } 597 598 /******************************************************************************* 599 * 600 * Function virtual_cable_unplug 601 * 602 * Description Sends Virtual Cable Unplug to host 603 * 604 * Returns bt_status_t 605 * 606 ******************************************************************************/ 607 static bt_status_t virtual_cable_unplug(void) { 608 BTIF_TRACE_API("%s", __func__); 609 610 if (!btif_hd_cb.app_registered) { 611 BTIF_TRACE_WARNING("%s: application not yet registered", __func__); 612 return BT_STATUS_NOT_READY; 613 } 614 615 if (btif_hd_cb.status != BTIF_HD_ENABLED) { 616 BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, 617 btif_hd_cb.status); 618 return BT_STATUS_NOT_READY; 619 } 620 621 BTA_HdVirtualCableUnplug(); 622 623 return BT_STATUS_SUCCESS; 624 } 625 626 static const bthd_interface_t bthdInterface = { 627 sizeof(bthdInterface), 628 init, 629 cleanup, 630 register_app, 631 unregister_app, 632 connect, 633 disconnect, 634 send_report, 635 report_error, 636 virtual_cable_unplug, 637 }; 638 639 /******************************************************************************* 640 * 641 * Function btif_hd_execute_service 642 * 643 * Description Enabled/disables BT-HD service 644 * 645 * Returns BT_STATUS_SUCCESS 646 * 647 ******************************************************************************/ 648 bt_status_t btif_hd_execute_service(bool b_enable) { 649 BTIF_TRACE_API("%s: b_enable=%d", __func__, b_enable); 650 651 if (!b_enable) BTA_HdDisable(); 652 653 return BT_STATUS_SUCCESS; 654 } 655 656 /******************************************************************************* 657 * 658 * Function btif_hd_get_interface 659 * 660 * Description Gets BT-HD interface 661 * 662 * Returns bthd_interface_t 663 * 664 ******************************************************************************/ 665 const bthd_interface_t* btif_hd_get_interface() { 666 BTIF_TRACE_API("%s", __func__); 667 return &bthdInterface; 668 } 669 670 /******************************************************************************* 671 * 672 * Function btif_hd_service_registration 673 * 674 * Description Registers hid device service 675 * 676 * Returns none 677 * 678 ******************************************************************************/ 679 void btif_hd_service_registration() { 680 BTIF_TRACE_API("%s", __func__); 681 /* enable HD */ 682 if (bt_hd_callbacks != NULL) { 683 BTA_HdEnable(bte_hd_evt); 684 } 685 } 686