1/****************************************************************************** 2 * 3 * Copyright (C) 2009-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 * Filename: btif_hh.c 22 * 23 * Description: HID Host Profile Bluetooth Interface 24 * 25 * 26 ***********************************************************************************/ 27 28#define LOG_TAG "bt_btif_hh" 29 30#include "btif_hh.h" 31 32#include <assert.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <errno.h> 36#include <string.h> 37#include <unistd.h> 38 39#include "bta_api.h" 40#include "btif_common.h" 41#include "btif_storage.h" 42#include "btif_util.h" 43#include "bt_common.h" 44#include "l2c_api.h" 45#include "osi/include/log.h" 46 47#define BTIF_HH_APP_ID_MI 0x01 48#define BTIF_HH_APP_ID_KB 0x02 49 50#define COD_HID_KEYBOARD 0x0540 51#define COD_HID_POINTING 0x0580 52#define COD_HID_COMBO 0x05C0 53 54#define KEYSTATE_FILEPATH "/data/misc/bluedroid/bt_hh_ks" //keep this in sync with HID host jni 55 56#define HID_REPORT_CAPSLOCK 0x39 57#define HID_REPORT_NUMLOCK 0x53 58#define HID_REPORT_SCROLLLOCK 0x47 59 60//For Apple Magic Mouse 61#define MAGICMOUSE_VENDOR_ID 0x05ac 62#define MAGICMOUSE_PRODUCT_ID 0x030d 63 64#define LOGITECH_KB_MX5500_VENDOR_ID 0x046D 65#define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B 66 67extern fixed_queue_t *btu_general_alarm_queue; 68extern const int BT_UID; 69extern const int BT_GID; 70static int btif_hh_keylockstates=0; //The current key state of each key 71 72#define BTIF_HH_ID_1 0 73#define BTIF_HH_DEV_DISCONNECTED 3 74 75#define BTIF_TIMEOUT_VUP_MS (3 * 1000) 76 77#ifndef BTUI_HH_SECURITY 78#define BTUI_HH_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT) 79#endif 80 81#ifndef BTUI_HH_MOUSE_SECURITY 82#define BTUI_HH_MOUSE_SECURITY (BTA_SEC_NONE) 83#endif 84 85/* HH request events */ 86typedef enum 87{ 88 BTIF_HH_CONNECT_REQ_EVT = 0, 89 BTIF_HH_DISCONNECT_REQ_EVT, 90 BTIF_HH_VUP_REQ_EVT 91} btif_hh_req_evt_t; 92 93/************************************************************************************ 94** Constants & Macros 95************************************************************************************/ 96#define BTIF_HH_SERVICES (BTA_HID_SERVICE_MASK) 97 98/************************************************************************************ 99** Local type definitions 100************************************************************************************/ 101 102typedef struct hid_kb_list 103{ 104 UINT16 product_id; 105 UINT16 version_id; 106 char* kb_name; 107} tHID_KB_LIST; 108 109/************************************************************************************ 110** Static variables 111************************************************************************************/ 112btif_hh_cb_t btif_hh_cb; 113 114static bthh_callbacks_t *bt_hh_callbacks = NULL; 115 116/* List of HID keyboards for which the NUMLOCK state needs to be 117 * turned ON by default. Add devices to this list to apply the 118 * NUMLOCK state toggle on fpr first connect.*/ 119static tHID_KB_LIST hid_kb_numlock_on_list[] = 120{ 121 {LOGITECH_KB_MX5500_PRODUCT_ID, 122 LOGITECH_KB_MX5500_VENDOR_ID, 123 "Logitech MX5500 Keyboard"} 124}; 125 126#define CHECK_BTHH_INIT() if (bt_hh_callbacks == NULL)\ 127 {\ 128 BTIF_TRACE_WARNING("BTHH: %s: BTHH not initialized", __FUNCTION__);\ 129 return BT_STATUS_NOT_READY;\ 130 }\ 131 else\ 132 {\ 133 BTIF_TRACE_EVENT("BTHH: %s", __FUNCTION__);\ 134 } 135 136/************************************************************************************ 137** Static functions 138************************************************************************************/ 139 140/************************************************************************************ 141** Externs 142************************************************************************************/ 143extern void bta_hh_co_destroy(int fd); 144extern void bta_hh_co_write(int fd, UINT8* rpt, UINT16 len); 145extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr); 146extern void bta_hh_co_send_hid_info(btif_hh_device_t *p_dev, char *dev_name, UINT16 vendor_id, 147 UINT16 product_id, UINT16 version, UINT8 ctry_code, 148 int dscp_len, UINT8 *p_dscp); 149extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod); 150extern void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr); 151extern BOOLEAN check_cod_hid(const bt_bdaddr_t *remote_bdaddr); 152extern int scru_ascii_2_hex(char *p_ascii, int len, UINT8 *p_hex); 153extern void btif_dm_hh_open_failed(bt_bdaddr_t *bdaddr); 154 155/***************************************************************************** 156** Local Function prototypes 157*****************************************************************************/ 158static void set_keylockstate(int keymask, BOOLEAN isSet); 159static void toggle_os_keylockstates(int fd, int changedkeystates); 160static void sync_lockstate_on_connect(btif_hh_device_t *p_dev); 161//static void hh_update_keyboard_lockstates(btif_hh_device_t *p_dev); 162void btif_hh_timer_timeout(void *data); 163 164/************************************************************************************ 165** Functions 166************************************************************************************/ 167 168static int get_keylockstates() 169{ 170 return btif_hh_keylockstates; 171} 172 173static void set_keylockstate(int keymask, BOOLEAN isSet) 174{ 175 if(isSet) 176 btif_hh_keylockstates |= keymask; 177} 178 179/******************************************************************************* 180** 181** Function toggle_os_keylockstates 182** 183** Description Function to toggle the keyboard lock states managed by the linux. 184** This function is used in by two call paths 185** (1) if the lock state change occurred from an onscreen keyboard, 186** this function is called to update the lock state maintained 187 for the HID keyboard(s) 188** (2) if a HID keyboard is disconnected and reconnected, 189** this function is called to update the lock state maintained 190 for the HID keyboard(s) 191** Returns void 192*******************************************************************************/ 193 194static void toggle_os_keylockstates(int fd, int changedlockstates) 195{ 196 BTIF_TRACE_EVENT("%s: fd = %d, changedlockstates = 0x%x", 197 __FUNCTION__, fd, changedlockstates); 198 UINT8 hidreport[9]; 199 int reportIndex; 200 memset(hidreport,0,9); 201 hidreport[0]=1; 202 reportIndex=4; 203 204 if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) { 205 BTIF_TRACE_DEBUG("%s Setting CAPSLOCK", __FUNCTION__); 206 hidreport[reportIndex++] = (UINT8)HID_REPORT_CAPSLOCK; 207 } 208 209 if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK) { 210 BTIF_TRACE_DEBUG("%s Setting NUMLOCK", __FUNCTION__); 211 hidreport[reportIndex++] = (UINT8)HID_REPORT_NUMLOCK; 212 } 213 214 if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) { 215 BTIF_TRACE_DEBUG("%s Setting SCROLLLOCK", __FUNCTION__); 216 hidreport[reportIndex++] = (UINT8) HID_REPORT_SCROLLLOCK; 217 } 218 219 BTIF_TRACE_DEBUG("Writing hidreport #1 to os: "\ 220 "%s: %x %x %x", __FUNCTION__, 221 hidreport[0], hidreport[1], hidreport[2]); 222 BTIF_TRACE_DEBUG("%s: %x %x %x", __FUNCTION__, 223 hidreport[3], hidreport[4], hidreport[5]); 224 BTIF_TRACE_DEBUG("%s: %x %x %x", __FUNCTION__, 225 hidreport[6], hidreport[7], hidreport[8]); 226 bta_hh_co_write(fd , hidreport, sizeof(hidreport)); 227 usleep(200000); 228 memset(hidreport,0,9); 229 hidreport[0]=1; 230 BTIF_TRACE_DEBUG("Writing hidreport #2 to os: "\ 231 "%s: %x %x %x", __FUNCTION__, 232 hidreport[0], hidreport[1], hidreport[2]); 233 BTIF_TRACE_DEBUG("%s: %x %x %x", __FUNCTION__, 234 hidreport[3], hidreport[4], hidreport[5]); 235 BTIF_TRACE_DEBUG("%s: %x %x %x ", __FUNCTION__, 236 hidreport[6], hidreport[7], hidreport[8]); 237 bta_hh_co_write(fd , hidreport, sizeof(hidreport)); 238} 239 240/******************************************************************************* 241** 242** Function create_pbuf 243** 244** Description Helper function to create p_buf for send_data or set_report 245** 246*******************************************************************************/ 247static BT_HDR *create_pbuf(UINT16 len, UINT8 *data) 248{ 249 BT_HDR* p_buf = osi_malloc(len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR)); 250 UINT8* pbuf_data; 251 252 p_buf->len = len; 253 p_buf->offset = BTA_HH_MIN_OFFSET; 254 255 pbuf_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 256 memcpy(pbuf_data, data, len); 257 258 return p_buf; 259} 260 261/******************************************************************************* 262** 263** Function update_keyboard_lockstates 264** 265** Description Sends a report to the keyboard to set the lock states of keys 266** 267*******************************************************************************/ 268static void update_keyboard_lockstates(btif_hh_device_t *p_dev) 269{ 270 UINT8 len = 2; /* reportid + 1 byte report*/ 271 BD_ADDR* bda; 272 BT_HDR* p_buf; 273 UINT8 data[] = {0x01, /* report id */ 274 btif_hh_keylockstates}; /* keystate */ 275 276 /* Set report for other keyboards */ 277 BTIF_TRACE_EVENT("%s: setting report on dev_handle %d to 0x%x", 278 __FUNCTION__, p_dev->dev_handle, btif_hh_keylockstates); 279 280 /* Get SetReport buffer */ 281 p_buf = create_pbuf(len, data); 282 if (p_buf != NULL) { 283 p_buf->layer_specific = BTA_HH_RPTT_OUTPUT; 284 bda = (BD_ADDR*) (&p_dev->bd_addr); 285 BTA_HhSendData(p_dev->dev_handle, *bda, p_buf); 286 } 287} 288 289/******************************************************************************* 290** 291** Function sync_lockstate_on_connect 292** 293** Description Function to update the keyboard lock states managed by the OS 294** when a HID keyboard is connected or disconnected and reconnected 295** Returns void 296*******************************************************************************/ 297static void sync_lockstate_on_connect(btif_hh_device_t *p_dev) 298{ 299 int keylockstates; 300 301 BTIF_TRACE_EVENT("%s: Syncing keyboard lock states after "\ 302 "reconnect...",__FUNCTION__); 303 /*If the device is connected, update keyboard state */ 304 update_keyboard_lockstates(p_dev); 305 306 /*Check if the lockstate of caps,scroll,num is set. 307 If so, send a report to the kernel 308 so the lockstate is in sync */ 309 keylockstates = get_keylockstates(); 310 if (keylockstates) 311 { 312 BTIF_TRACE_DEBUG("%s: Sending hid report to kernel "\ 313 "indicating lock key state 0x%x",__FUNCTION__, 314 keylockstates); 315 usleep(200000); 316 toggle_os_keylockstates(p_dev->fd, keylockstates); 317 } 318 else 319 { 320 BTIF_TRACE_DEBUG("%s: NOT sending hid report to kernel "\ 321 "indicating lock key state 0x%x",__FUNCTION__, 322 keylockstates); 323 } 324} 325 326/******************************************************************************* 327** 328** Function btif_hh_find_connected_dev_by_handle 329** 330** Description Return the connected device pointer of the specified device handle 331** 332** Returns Device entry pointer in the device table 333*******************************************************************************/ 334btif_hh_device_t *btif_hh_find_connected_dev_by_handle(UINT8 handle) 335{ 336 UINT32 i; 337 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 338 if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED && 339 btif_hh_cb.devices[i].dev_handle == handle) 340 { 341 return &btif_hh_cb.devices[i]; 342 } 343 } 344 return NULL; 345} 346 347/******************************************************************************* 348** 349** Function btif_hh_find_dev_by_bda 350** 351** Description Return the device pointer of the specified bt_bdaddr_t. 352** 353** Returns Device entry pointer in the device table 354*******************************************************************************/ 355static btif_hh_device_t *btif_hh_find_dev_by_bda(bt_bdaddr_t *bd_addr) 356{ 357 UINT32 i; 358 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 359 if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN && 360 memcmp(&(btif_hh_cb.devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0) 361 { 362 return &btif_hh_cb.devices[i]; 363 } 364 } 365 return NULL; 366} 367 368/******************************************************************************* 369** 370** Function btif_hh_find_connected_dev_by_bda 371** 372** Description Return the connected device pointer of the specified bt_bdaddr_t. 373** 374** Returns Device entry pointer in the device table 375*******************************************************************************/ 376static btif_hh_device_t *btif_hh_find_connected_dev_by_bda(bt_bdaddr_t *bd_addr) 377{ 378 UINT32 i; 379 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 380 if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED && 381 memcmp(&(btif_hh_cb.devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0) 382 { 383 return &btif_hh_cb.devices[i]; 384 } 385 } 386 return NULL; 387} 388 389/******************************************************************************* 390** 391** Function btif_hh_stop_vup_timer 392** 393** Description stop vitual unplug timer 394** 395** Returns void 396*******************************************************************************/ 397void btif_hh_stop_vup_timer(bt_bdaddr_t *bd_addr) 398{ 399 btif_hh_device_t *p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 400 401 if (p_dev != NULL) { 402 BTIF_TRACE_DEBUG("stop VUP timer"); 403 alarm_free(p_dev->vup_timer); 404 p_dev->vup_timer = NULL; 405 } 406} 407/******************************************************************************* 408** 409** Function btif_hh_start_vup_timer 410** 411** Description start virtual unplug timer 412** 413** Returns void 414*******************************************************************************/ 415void btif_hh_start_vup_timer(bt_bdaddr_t *bd_addr) 416{ 417 BTIF_TRACE_DEBUG("%s", __func__); 418 419 btif_hh_device_t *p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 420 assert(p_dev != NULL); 421 422 alarm_free(p_dev->vup_timer); 423 p_dev->vup_timer = alarm_new("btif_hh.vup_timer"); 424 alarm_set_on_queue(p_dev->vup_timer, BTIF_TIMEOUT_VUP_MS, 425 btif_hh_timer_timeout, p_dev, 426 btu_general_alarm_queue); 427} 428 429/******************************************************************************* 430** 431** Function btif_hh_add_added_dev 432** 433** Description Add a new device to the added device list. 434** 435** Returns TRUE if add successfully, otherwise FALSE. 436*******************************************************************************/ 437BOOLEAN btif_hh_add_added_dev(bt_bdaddr_t bda, tBTA_HH_ATTR_MASK attr_mask) 438{ 439 int i; 440 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { 441 if (memcmp(&(btif_hh_cb.added_devices[i].bd_addr), &bda, BD_ADDR_LEN) == 0) { 442 BTIF_TRACE_WARNING(" Device %02X:%02X:%02X:%02X:%02X:%02X already added", 443 bda.address[0], bda.address[1], bda.address[2], bda.address[3], bda.address[4], bda.address[5]); 444 return FALSE; 445 } 446 } 447 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { 448 if (btif_hh_cb.added_devices[i].bd_addr.address[0] == 0 && 449 btif_hh_cb.added_devices[i].bd_addr.address[1] == 0 && 450 btif_hh_cb.added_devices[i].bd_addr.address[2] == 0 && 451 btif_hh_cb.added_devices[i].bd_addr.address[3] == 0 && 452 btif_hh_cb.added_devices[i].bd_addr.address[4] == 0 && 453 btif_hh_cb.added_devices[i].bd_addr.address[5] == 0) 454 { 455 BTIF_TRACE_WARNING(" Added device %02X:%02X:%02X:%02X:%02X:%02X", 456 bda.address[0], bda.address[1], bda.address[2], bda.address[3], bda.address[4], bda.address[5]); 457 memcpy(&(btif_hh_cb.added_devices[i].bd_addr), &bda, BD_ADDR_LEN); 458 btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE; 459 btif_hh_cb.added_devices[i].attr_mask = attr_mask; 460 return TRUE; 461 } 462 } 463 464 BTIF_TRACE_WARNING("%s: Error, out of space to add device",__FUNCTION__); 465 return FALSE; 466} 467 468/******************************************************************************* 469 ** 470 ** Function btif_hh_remove_device 471 ** 472 ** Description Remove an added device from the stack. 473 ** 474 ** Returns void 475 *******************************************************************************/ 476void btif_hh_remove_device(bt_bdaddr_t bd_addr) 477{ 478 int i; 479 btif_hh_device_t *p_dev; 480 btif_hh_added_device_t *p_added_dev; 481 482 LOG_INFO(LOG_TAG, "%s: bda = %02x:%02x:%02x:%02x:%02x:%02x", __FUNCTION__, 483 bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); 484 485 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { 486 p_added_dev = &btif_hh_cb.added_devices[i]; 487 if (memcmp(&(p_added_dev->bd_addr),&bd_addr, 6) == 0) { 488 BTA_HhRemoveDev(p_added_dev->dev_handle); 489 btif_storage_remove_hid_info(&(p_added_dev->bd_addr)); 490 memset(&(p_added_dev->bd_addr), 0, 6); 491 p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE; 492 break; 493 } 494 } 495 496 p_dev = btif_hh_find_dev_by_bda(&bd_addr); 497 if (p_dev == NULL) { 498 BTIF_TRACE_WARNING(" Oops, can't find device [%02x:%02x:%02x:%02x:%02x:%02x]", 499 bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); 500 return; 501 } 502 503 /* need to notify up-layer device is disconnected to avoid state out of sync with up-layer */ 504 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), BTHH_CONN_STATE_DISCONNECTED); 505 506 p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN; 507 p_dev->dev_handle = BTA_HH_INVALID_HANDLE; 508 p_dev->ready_for_data = FALSE; 509 510 if (btif_hh_cb.device_num > 0) { 511 btif_hh_cb.device_num--; 512 } 513 else { 514 BTIF_TRACE_WARNING("%s: device_num = 0", __FUNCTION__); 515 } 516 517 p_dev->hh_keep_polling = 0; 518 p_dev->hh_poll_thread_id = -1; 519 BTIF_TRACE_DEBUG("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); 520 if (p_dev->fd >= 0) { 521 bta_hh_co_destroy(p_dev->fd); 522 p_dev->fd = -1; 523 } 524} 525 526BOOLEAN btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest , tBTA_HH_DEV_DSCP_INFO* src) 527{ 528 dest->descriptor.dl_len = 0; 529 if (src->descriptor.dl_len > 0) { 530 dest->descriptor.dsc_list = (UINT8 *)osi_malloc(src->descriptor.dl_len); 531 } 532 memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list, src->descriptor.dl_len); 533 dest->descriptor.dl_len = src->descriptor.dl_len; 534 dest->vendor_id = src->vendor_id; 535 dest->product_id = src->product_id; 536 dest->version = src->version; 537 dest->ctry_code = src->ctry_code; 538 dest->ssr_max_latency = src->ssr_max_latency; 539 dest->ssr_min_tout = src->ssr_min_tout; 540 return TRUE; 541} 542 543/******************************************************************************* 544** 545** Function btif_hh_virtual_unplug 546** 547** Description Virtual unplug initiated from the BTIF thread context 548** Special handling for HID mouse- 549** 550** Returns void 551** 552*******************************************************************************/ 553 554bt_status_t btif_hh_virtual_unplug(bt_bdaddr_t *bd_addr) 555{ 556 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 557 btif_hh_device_t *p_dev; 558 char bd_str[18]; 559 sprintf(bd_str, "%02X:%02X:%02X:%02X:%02X:%02X", 560 bd_addr->address[0], bd_addr->address[1], bd_addr->address[2], bd_addr->address[3], 561 bd_addr->address[4], bd_addr->address[5]); 562 p_dev = btif_hh_find_dev_by_bda(bd_addr); 563 if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) 564 && (p_dev->attr_mask & HID_VIRTUAL_CABLE)) 565 { 566 BTIF_TRACE_DEBUG("%s Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __FUNCTION__); 567 /* start the timer */ 568 btif_hh_start_vup_timer(bd_addr); 569 p_dev->local_vup = TRUE; 570 BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG); 571 return BT_STATUS_SUCCESS; 572 } 573 else 574 { 575 BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __FUNCTION__, bd_str); 576 return BT_STATUS_FAIL; 577 } 578} 579 580/******************************************************************************* 581** 582** Function btif_hh_connect 583** 584** Description connection initiated from the BTIF thread context 585** 586** Returns int status 587** 588*******************************************************************************/ 589 590bt_status_t btif_hh_connect(bt_bdaddr_t *bd_addr) 591{ 592 btif_hh_device_t *dev; 593 btif_hh_added_device_t *added_dev = NULL; 594 char bda_str[20]; 595 int i; 596 BD_ADDR *bda = (BD_ADDR*)bd_addr; 597 CHECK_BTHH_INIT(); 598 dev = btif_hh_find_dev_by_bda(bd_addr); 599 BTIF_TRACE_DEBUG("Connect _hh"); 600 sprintf(bda_str, "%02X:%02X:%02X:%02X:%02X:%02X", 601 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 602 if (dev == NULL && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) { 603 // No space for more HID device now. 604 BTIF_TRACE_WARNING("%s: Error, exceeded the maximum supported HID device number %d", 605 __FUNCTION__, BTIF_HH_MAX_HID); 606 return BT_STATUS_FAIL; 607 } 608 609 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { 610 if (memcmp(&(btif_hh_cb.added_devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0) { 611 added_dev = &btif_hh_cb.added_devices[i]; 612 BTIF_TRACE_WARNING("%s: Device %s already added, attr_mask = 0x%x", 613 __FUNCTION__, bda_str, added_dev->attr_mask); 614 } 615 } 616 617 if (added_dev != NULL) { 618 if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) { 619 // No space for more HID device now. 620 BTIF_TRACE_ERROR("%s: Error, device %s added but addition failed", __FUNCTION__, bda_str); 621 memset(&(added_dev->bd_addr), 0, 6); 622 added_dev->dev_handle = BTA_HH_INVALID_HANDLE; 623 return BT_STATUS_FAIL; 624 } 625 } 626 627 /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways sending this 628 request from host, for subsequent user initiated connection. If the remote is not in 629 pagescan mode, we will do 2 retries to connect before giving up */ 630 tBTA_SEC sec_mask = BTUI_HH_SECURITY; 631 btif_hh_cb.status = BTIF_HH_DEV_CONNECTING; 632 BTA_HhOpen(*bda, BTA_HH_PROTO_RPT_MODE, sec_mask); 633 634 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, BTHH_CONN_STATE_CONNECTING); 635 return BT_STATUS_SUCCESS; 636} 637 638/******************************************************************************* 639** 640** Function btif_hh_disconnect 641** 642** Description disconnection initiated from the BTIF thread context 643** 644** Returns void 645** 646*******************************************************************************/ 647 648void btif_hh_disconnect(bt_bdaddr_t *bd_addr) 649{ 650 btif_hh_device_t *p_dev; 651 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 652 if (p_dev != NULL) 653 { 654 BTA_HhClose(p_dev->dev_handle); 655 } 656 else 657 BTIF_TRACE_DEBUG("%s-- Error: device not connected:",__FUNCTION__); 658} 659 660/******************************************************************************* 661** 662** Function btif_btif_hh_setreport 663** 664** Description setreport initiated from the BTIF thread context 665** 666** Returns void 667** 668*******************************************************************************/ 669void btif_hh_setreport(btif_hh_device_t *p_dev, bthh_report_type_t r_type, UINT16 size, 670 UINT8* report) 671{ 672 BT_HDR* p_buf = create_pbuf(size, report); 673 if (p_buf == NULL) { 674 APPL_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, size = %d", __FUNCTION__, size); 675 return; 676 } 677 BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf); 678} 679 680/***************************************************************************** 681** Section name (Group of functions) 682*****************************************************************************/ 683 684/***************************************************************************** 685** 686** btif hh api functions (no context switch) 687** 688*****************************************************************************/ 689 690/******************************************************************************* 691** 692** Function btif_hh_upstreams_evt 693** 694** Description Executes HH UPSTREAMS events in btif context 695** 696** Returns void 697** 698*******************************************************************************/ 699static void btif_hh_upstreams_evt(UINT16 event, char* p_param) 700{ 701 tBTA_HH *p_data = (tBTA_HH *)p_param; 702 btif_hh_device_t *p_dev = NULL; 703 int i; 704 int len, tmplen; 705 706 BTIF_TRACE_DEBUG("%s: event=%s", __FUNCTION__, dump_hh_event(event)); 707 708 switch (event) 709 { 710 case BTA_HH_ENABLE_EVT: 711 BTIF_TRACE_DEBUG("%s: BTA_HH_ENABLE_EVT: status =%d",__FUNCTION__, p_data->status); 712 if (p_data->status == BTA_HH_OK) { 713 btif_hh_cb.status = BTIF_HH_ENABLED; 714 BTIF_TRACE_DEBUG("%s--Loading added devices",__FUNCTION__); 715 /* Add hid descriptors for already bonded hid devices*/ 716 btif_storage_load_bonded_hid_info(); 717 } 718 else { 719 btif_hh_cb.status = BTIF_HH_DISABLED; 720 BTIF_TRACE_WARNING("BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d", p_data->status); 721 } 722 break; 723 724 case BTA_HH_DISABLE_EVT: 725 btif_hh_cb.status = BTIF_HH_DISABLED; 726 if (p_data->status == BTA_HH_OK) { 727 int i; 728 // Clear the control block 729 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 730 alarm_free(btif_hh_cb.devices[i].vup_timer); 731 } 732 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb)); 733 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 734 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN; 735 } 736 } 737 else 738 BTIF_TRACE_WARNING("BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d", p_data->status); 739 break; 740 741 case BTA_HH_OPEN_EVT: 742 BTIF_TRACE_WARNING("%s: BTA_HH_OPN_EVT: handle=%d, status =%d",__FUNCTION__, p_data->conn.handle, p_data->conn.status); 743 if (p_data->conn.status == BTA_HH_OK) { 744 p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle); 745 if (p_dev == NULL) { 746 BTIF_TRACE_WARNING("BTA_HH_OPEN_EVT: Error, cannot find device with handle %d", p_data->conn.handle); 747 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 748 // The connect request must come from device side and exceeded the connected 749 // HID device number. 750 BTA_HhClose(p_data->conn.handle); 751 HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED); 752 } 753 else if (p_dev->fd < 0) { 754 BTIF_TRACE_WARNING("BTA_HH_OPEN_EVT: Error, failed to find the uhid driver..."); 755 memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN); 756 //remove the connection and then try again to reconnect from the mouse side to recover 757 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 758 BTA_HhClose(p_data->conn.handle); 759 } 760 else { 761 BTIF_TRACE_WARNING("BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle ... %d",p_data->conn.handle); 762 memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN); 763 btif_hh_cb.status = BTIF_HH_DEV_CONNECTED; 764 // Send set_idle if the peer_device is a keyboard 765 if (check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_KEYBOARD )|| 766 check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_COMBO)) 767 BTA_HhSetIdle(p_data->conn.handle, 0); 768 btif_hh_cb.p_curr_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle); 769 BTA_HhGetDscpInfo(p_data->conn.handle); 770 p_dev->dev_status = BTHH_CONN_STATE_CONNECTED; 771 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); 772 } 773 } 774 else { 775 bt_bdaddr_t *bdaddr = (bt_bdaddr_t*)p_data->conn.bda; 776 btif_dm_hh_open_failed(bdaddr); 777 p_dev = btif_hh_find_dev_by_bda(bdaddr); 778 if (p_dev != NULL) { 779 btif_hh_stop_vup_timer(&(p_dev->bd_addr)); 780 if (p_dev->fd >= 0) { 781 bta_hh_co_destroy(p_dev->fd); 782 p_dev->fd = -1; 783 } 784 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; 785 } 786 HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED); 787 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 788 } 789 break; 790 791 case BTA_HH_CLOSE_EVT: 792 BTIF_TRACE_DEBUG("BTA_HH_CLOSE_EVT: status = %d, handle = %d", 793 p_data->dev_status.status, p_data->dev_status.handle); 794 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 795 if (p_dev != NULL) { 796 BTIF_TRACE_DEBUG("%s: uhid fd=%d local_vup=%d", __func__, p_dev->fd, p_dev->local_vup); 797 btif_hh_stop_vup_timer(&(p_dev->bd_addr)); 798 /* If this is a locally initiated VUP, remove the bond as ACL got 799 * disconnected while VUP being processed. 800 */ 801 if (p_dev->local_vup) 802 { 803 p_dev->local_vup = FALSE; 804 BTA_DmRemoveDevice((UINT8 *)p_dev->bd_addr.address); 805 } 806 807 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 808 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; 809 810 if (p_dev->fd >= 0) { 811 bta_hh_co_destroy(p_dev->fd); 812 p_dev->fd = -1; 813 } 814 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); 815 } 816 else { 817 BTIF_TRACE_WARNING("Error: cannot find device with handle %d", p_data->dev_status.handle); 818 } 819 break; 820 821 case BTA_HH_GET_RPT_EVT: { 822 BT_HDR *hdr = p_data->hs_data.rsp_data.p_rpt_data; 823 UINT8 *data = NULL; 824 UINT16 len = 0; 825 826 BTIF_TRACE_DEBUG("BTA_HH_GET_RPT_EVT: status = %d, handle = %d", 827 p_data->hs_data.status, p_data->hs_data.handle); 828 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle); 829 if (p_dev) { 830 /* p_rpt_data is NULL in HANDSHAKE response case */ 831 if (hdr) { 832 data = (UINT8 *)(hdr + 1) + hdr->offset; 833 len = hdr->len; 834 HAL_CBACK(bt_hh_callbacks, get_report_cb, 835 (bt_bdaddr_t*) &(p_dev->bd_addr), 836 (bthh_status_t) p_data->hs_data.status, data, len); 837 } else { 838 HAL_CBACK(bt_hh_callbacks, handshake_cb, 839 (bt_bdaddr_t*) &(p_dev->bd_addr), 840 (bthh_status_t) p_data->hs_data.status); 841 } 842 } else { 843 BTIF_TRACE_WARNING("Error: cannot find device with handle %d", p_data->hs_data.handle); 844 } 845 break; 846 } 847 848 case BTA_HH_SET_RPT_EVT: 849 BTIF_TRACE_DEBUG("BTA_HH_SET_RPT_EVT: status = %d, handle = %d", 850 p_data->dev_status.status, p_data->dev_status.handle); 851 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 852 if (p_dev != NULL) { 853 HAL_CBACK(bt_hh_callbacks, handshake_cb, 854 (bt_bdaddr_t*) &(p_dev->bd_addr), 855 (bthh_status_t) p_data->hs_data.status); 856 } 857 break; 858 859 case BTA_HH_GET_PROTO_EVT: 860 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 861 BTIF_TRACE_WARNING("BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s", 862 p_data->hs_data.status, p_data->hs_data.handle, 863 p_data->hs_data.rsp_data.proto_mode, 864 (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) ? "Report Mode" : 865 (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE) ? "Boot Mode" : "Unsupported"); 866 if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) { 867 HAL_CBACK(bt_hh_callbacks, protocol_mode_cb, 868 (bt_bdaddr_t*) &(p_dev->bd_addr), 869 (bthh_status_t)p_data->hs_data.status, 870 (bthh_protocol_mode_t) p_data->hs_data.rsp_data.proto_mode); 871 } else { 872 HAL_CBACK(bt_hh_callbacks, handshake_cb, 873 (bt_bdaddr_t*) &(p_dev->bd_addr), 874 (bthh_status_t)p_data->hs_data.status); 875 } 876 break; 877 878 case BTA_HH_SET_PROTO_EVT: 879 BTIF_TRACE_DEBUG("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d", 880 p_data->dev_status.status, p_data->dev_status.handle); 881 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 882 if (p_dev) { 883 HAL_CBACK(bt_hh_callbacks, handshake_cb, 884 (bt_bdaddr_t*)&(p_dev->bd_addr), 885 (bthh_status_t)p_data->hs_data.status); 886 } 887 break; 888 889 case BTA_HH_GET_IDLE_EVT: 890 BTIF_TRACE_DEBUG("BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d", 891 p_data->hs_data.handle, p_data->hs_data.status, 892 p_data->hs_data.rsp_data.idle_rate); 893 break; 894 895 case BTA_HH_SET_IDLE_EVT: 896 BTIF_TRACE_DEBUG("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d", 897 p_data->dev_status.status, p_data->dev_status.handle); 898 break; 899 900 case BTA_HH_GET_DSCP_EVT: 901 len = p_data->dscp_info.descriptor.dl_len; 902 BTIF_TRACE_DEBUG("BTA_HH_GET_DSCP_EVT: len = %d", len); 903 p_dev = btif_hh_cb.p_curr_dev; 904 if (p_dev == NULL) { 905 BTIF_TRACE_ERROR("BTA_HH_GET_DSCP_EVT: No HID device is currently connected"); 906 return; 907 } 908 if (p_dev->fd < 0) { 909 LOG_ERROR(LOG_TAG, "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver..."); 910 return; 911 } 912 { 913 char *cached_name = NULL; 914 bt_bdname_t bdname; 915 bt_property_t prop_name; 916 BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME, 917 sizeof(bt_bdname_t), &bdname); 918 if (btif_storage_get_remote_device_property( 919 &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS) 920 { 921 cached_name = (char *)bdname.name; 922 } 923 else 924 { 925 cached_name = "Bluetooth HID"; 926 } 927 928 BTIF_TRACE_WARNING("%s: name = %s", __FUNCTION__, cached_name); 929 bta_hh_co_send_hid_info(p_dev, cached_name, 930 p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, 931 p_data->dscp_info.version, p_data->dscp_info.ctry_code, 932 len, p_data->dscp_info.descriptor.dsc_list); 933 if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) { 934 BD_ADDR bda; 935 bdcpy(bda, p_dev->bd_addr.address); 936 tBTA_HH_DEV_DSCP_INFO dscp_info; 937 bt_status_t ret; 938 bdcpy(bda, p_dev->bd_addr.address); 939 btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info); 940 BTIF_TRACE_DEBUG("BTA_HH_GET_DSCP_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x", 941 p_dev->bd_addr.address[0], p_dev->bd_addr.address[1], 942 p_dev->bd_addr.address[2],p_dev->bd_addr.address[3], 943 p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]); 944 BTA_HhAddDev(bda, p_dev->attr_mask,p_dev->sub_class,p_dev->app_id, dscp_info); 945 // write hid info to nvram 946 ret = btif_storage_add_hid_device_info(&(p_dev->bd_addr), p_dev->attr_mask,p_dev->sub_class,p_dev->app_id, 947 p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, 948 p_data->dscp_info.version, p_data->dscp_info.ctry_code, 949 p_data->dscp_info.ssr_max_latency, p_data->dscp_info.ssr_min_tout, 950 len, p_data->dscp_info.descriptor.dsc_list); 951 952 ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret); 953 BTIF_TRACE_WARNING("BTA_HH_GET_DSCP_EVT: Called add device"); 954 955 //Free buffer created for dscp_info; 956 if (dscp_info.descriptor.dl_len >0 && dscp_info.descriptor.dsc_list != NULL) 957 { 958 osi_free_and_reset((void **)&dscp_info.descriptor.dsc_list); 959 dscp_info.descriptor.dl_len = 0; 960 } 961 } 962 else { 963 //Device already added. 964 BTIF_TRACE_WARNING("%s: Device already added ",__FUNCTION__); 965 } 966 /*Sync HID Keyboard lockstates */ 967 tmplen = sizeof(hid_kb_numlock_on_list) 968 / sizeof(tHID_KB_LIST); 969 for(i = 0; i< tmplen; i++) 970 { 971 if(p_data->dscp_info.vendor_id 972 == hid_kb_numlock_on_list[i].version_id && 973 p_data->dscp_info.product_id 974 == hid_kb_numlock_on_list[i].product_id) 975 { 976 BTIF_TRACE_DEBUG("%s() idx[%d] Enabling "\ 977 "NUMLOCK for device :: %s", __FUNCTION__, 978 i, hid_kb_numlock_on_list[i].kb_name); 979 /* Enable NUMLOCK by default so that numeric 980 keys work from first keyboard connect */ 981 set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, 982 TRUE); 983 sync_lockstate_on_connect(p_dev); 984 /* End Sync HID Keyboard lockstates */ 985 break; 986 } 987 } 988 } 989 break; 990 991 case BTA_HH_ADD_DEV_EVT: 992 BTIF_TRACE_WARNING("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",p_data->dev_info.status, p_data->dev_info.handle); 993 int i; 994 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { 995 if (memcmp(btif_hh_cb.added_devices[i].bd_addr.address, p_data->dev_info.bda, 6) == 0) { 996 if (p_data->dev_info.status == BTA_HH_OK) { 997 btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle; 998 } 999 else { 1000 memset(btif_hh_cb.added_devices[i].bd_addr.address, 0, 6); 1001 btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE; 1002 } 1003 break; 1004 } 1005 } 1006 break; 1007 case BTA_HH_RMV_DEV_EVT: 1008 BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d", 1009 p_data->dev_info.status, p_data->dev_info.handle); 1010 BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x", 1011 p_data->dev_info.bda[0], p_data->dev_info.bda[1], p_data->dev_info.bda[2], 1012 p_data->dev_info.bda[3], p_data->dev_info.bda[4], p_data->dev_info.bda[5]); 1013 break; 1014 1015 case BTA_HH_VC_UNPLUG_EVT: 1016 BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d", 1017 p_data->dev_status.status, p_data->dev_status.handle); 1018 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 1019 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 1020 if (p_dev != NULL) { 1021 BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x", 1022 p_dev->bd_addr.address[0], p_dev->bd_addr.address[1], 1023 p_dev->bd_addr.address[2],p_dev->bd_addr.address[3], 1024 p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]); 1025 /* Stop the VUP timer */ 1026 btif_hh_stop_vup_timer(&(p_dev->bd_addr)); 1027 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; 1028 BTIF_TRACE_DEBUG("%s---Sending connection state change", __FUNCTION__); 1029 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); 1030 BTIF_TRACE_DEBUG("%s---Removing HID bond", __FUNCTION__); 1031 /* If it is locally initiated VUP or remote device has its major COD as 1032 Peripheral removed the bond.*/ 1033 if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) 1034 { 1035 p_dev->local_vup = FALSE; 1036 BTA_DmRemoveDevice((UINT8 *)p_dev->bd_addr.address); 1037 } 1038 else 1039 btif_hh_remove_device(p_dev->bd_addr); 1040 HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb,&(p_dev->bd_addr), 1041 p_data->dev_status.status); 1042 } 1043 break; 1044 1045 case BTA_HH_API_ERR_EVT : 1046 LOG_INFO(LOG_TAG, "BTA_HH API_ERR"); 1047 break; 1048 1049 default: 1050 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event); 1051 break; 1052 } 1053} 1054 1055/******************************************************************************* 1056** 1057** Function bte_hh_evt 1058** 1059** Description Switches context from BTE to BTIF for all HH events 1060** 1061** Returns void 1062** 1063*******************************************************************************/ 1064 1065static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH *p_data) 1066{ 1067 bt_status_t status; 1068 int param_len = 0; 1069 1070 if (BTA_HH_ENABLE_EVT == event) 1071 param_len = sizeof(tBTA_HH_STATUS); 1072 else if (BTA_HH_OPEN_EVT == event) 1073 param_len = sizeof(tBTA_HH_CONN); 1074 else if (BTA_HH_DISABLE_EVT == event) 1075 param_len = sizeof(tBTA_HH_STATUS); 1076 else if (BTA_HH_CLOSE_EVT == event) 1077 param_len = sizeof(tBTA_HH_CBDATA); 1078 else if (BTA_HH_GET_DSCP_EVT == event) 1079 param_len = sizeof(tBTA_HH_DEV_DSCP_INFO); 1080 else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event)|| (BTA_HH_GET_IDLE_EVT == event)) 1081 param_len = sizeof(tBTA_HH_HSDATA); 1082 else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) || (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event)) 1083 param_len = sizeof(tBTA_HH_CBDATA); 1084 else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event) ) 1085 param_len = sizeof(tBTA_HH_DEV_INFO); 1086 else if (BTA_HH_API_ERR_EVT == event) 1087 param_len = 0; 1088 /* switch context to btif task context (copy full union size for convenience) */ 1089 status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL); 1090 1091 /* catch any failed context transfers */ 1092 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 1093} 1094 1095/******************************************************************************* 1096** 1097** Function btif_hh_handle_evt 1098** 1099** Description Switches context for immediate callback 1100** 1101** Returns void 1102** 1103*******************************************************************************/ 1104 1105static void btif_hh_handle_evt(UINT16 event, char *p_param) 1106{ 1107 bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)p_param; 1108 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event); 1109 int ret; 1110 switch(event) 1111 { 1112 case BTIF_HH_CONNECT_REQ_EVT: 1113 { 1114 ret = btif_hh_connect(bd_addr); 1115 if(ret == BT_STATUS_SUCCESS) 1116 { 1117 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_CONNECTING); 1118 } 1119 else 1120 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_DISCONNECTED); 1121 } 1122 break; 1123 1124 case BTIF_HH_DISCONNECT_REQ_EVT: 1125 { 1126 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event); 1127 btif_hh_disconnect(bd_addr); 1128 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_DISCONNECTING); 1129 } 1130 break; 1131 1132 case BTIF_HH_VUP_REQ_EVT: 1133 { 1134 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event); 1135 ret = btif_hh_virtual_unplug(bd_addr); 1136 } 1137 break; 1138 1139 default: 1140 { 1141 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event); 1142 } 1143 break; 1144 } 1145} 1146 1147/******************************************************************************* 1148** 1149** Function btif_hh_timer_timeout 1150** 1151** Description Process timer timeout 1152** 1153** Returns void 1154*******************************************************************************/ 1155void btif_hh_timer_timeout(void *data) 1156{ 1157 btif_hh_device_t *p_dev = (btif_hh_device_t *)data; 1158 tBTA_HH_EVT event = BTA_HH_VC_UNPLUG_EVT; 1159 tBTA_HH p_data; 1160 int param_len = sizeof(tBTA_HH_CBDATA); 1161 1162 BTIF_TRACE_DEBUG("%s", __func__); 1163 if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) 1164 return; 1165 1166 memset(&p_data, 0, sizeof(tBTA_HH)); 1167 p_data.dev_status.status = BTHH_ERR; 1168 p_data.dev_status.handle = p_dev->dev_handle; 1169 1170 /* switch context to btif task context */ 1171 btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, 1172 (char *)&p_data, param_len, NULL); 1173} 1174 1175/******************************************************************************* 1176** 1177** Function btif_hh_init 1178** 1179** Description initializes the hh interface 1180** 1181** Returns bt_status_t 1182** 1183*******************************************************************************/ 1184static bt_status_t init( bthh_callbacks_t* callbacks ) 1185{ 1186 UINT32 i; 1187 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1188 1189 bt_hh_callbacks = callbacks; 1190 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb)); 1191 for (i = 0; i < BTIF_HH_MAX_HID; i++){ 1192 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN; 1193 } 1194 /* Invoke the enable service API to the core to set the appropriate service_id */ 1195 btif_enable_service(BTA_HID_SERVICE_ID); 1196 return BT_STATUS_SUCCESS; 1197} 1198 1199/******************************************************************************* 1200** 1201** Function connect 1202** 1203** Description connect to hid device 1204** 1205** Returns bt_status_t 1206** 1207*******************************************************************************/ 1208static bt_status_t connect( bt_bdaddr_t *bd_addr) 1209{ 1210 if(btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) 1211 { 1212 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT, 1213 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1214 return BT_STATUS_SUCCESS; 1215 } 1216 else 1217 return BT_STATUS_BUSY; 1218} 1219 1220/******************************************************************************* 1221** 1222** Function disconnect 1223** 1224** Description disconnect from hid device 1225** 1226** Returns bt_status_t 1227** 1228*******************************************************************************/ 1229static bt_status_t disconnect( bt_bdaddr_t *bd_addr ) 1230{ 1231 CHECK_BTHH_INIT(); 1232 btif_hh_device_t *p_dev; 1233 1234 if (btif_hh_cb.status == BTIF_HH_DISABLED) 1235 { 1236 BTIF_TRACE_WARNING("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1237 return BT_STATUS_FAIL; 1238 } 1239 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1240 if (p_dev != NULL) 1241 { 1242 return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT, 1243 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1244 } 1245 else 1246 { 1247 BTIF_TRACE_WARNING("%s: Error, device not opened.", __FUNCTION__); 1248 return BT_STATUS_FAIL; 1249 } 1250} 1251 1252/******************************************************************************* 1253** 1254** Function virtual_unplug 1255** 1256** Description Virtual UnPlug (VUP) the specified HID device. 1257** 1258** Returns bt_status_t 1259** 1260*******************************************************************************/ 1261static bt_status_t virtual_unplug (bt_bdaddr_t *bd_addr) 1262{ 1263 CHECK_BTHH_INIT(); 1264 btif_hh_device_t *p_dev; 1265 char bd_str[18]; 1266 sprintf(bd_str, "%02X:%02X:%02X:%02X:%02X:%02X", 1267 bd_addr->address[0], bd_addr->address[1], bd_addr->address[2], bd_addr->address[3], 1268 bd_addr->address[4], bd_addr->address[5]); 1269 if (btif_hh_cb.status == BTIF_HH_DISABLED) 1270 { 1271 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1272 return BT_STATUS_FAIL; 1273 } 1274 p_dev = btif_hh_find_dev_by_bda(bd_addr); 1275 if (!p_dev) 1276 { 1277 BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __FUNCTION__, bd_str); 1278 return BT_STATUS_FAIL; 1279 } 1280 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, 1281 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1282 return BT_STATUS_SUCCESS; 1283} 1284 1285/******************************************************************************* 1286** 1287** Function set_info 1288** 1289** Description Set the HID device descriptor for the specified HID device. 1290** 1291** Returns bt_status_t 1292** 1293*******************************************************************************/ 1294static bt_status_t set_info (bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info ) 1295{ 1296 CHECK_BTHH_INIT(); 1297 tBTA_HH_DEV_DSCP_INFO dscp_info; 1298 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1299 1300 BTIF_TRACE_DEBUG("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1301 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1302 BTIF_TRACE_DEBUG("%s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, " 1303 "product_id = 0x%04x, version= 0x%04x", 1304 __FUNCTION__, hid_info.sub_class, 1305 hid_info.app_id, hid_info.vendor_id, hid_info.product_id, 1306 hid_info.version); 1307 1308 if (btif_hh_cb.status == BTIF_HH_DISABLED) 1309 { 1310 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1311 return BT_STATUS_FAIL; 1312 } 1313 1314 dscp_info.vendor_id = hid_info.vendor_id; 1315 dscp_info.product_id = hid_info.product_id; 1316 dscp_info.version = hid_info.version; 1317 dscp_info.ctry_code = hid_info.ctry_code; 1318 1319 dscp_info.descriptor.dl_len = hid_info.dl_len; 1320 dscp_info.descriptor.dsc_list = (UINT8 *)osi_malloc(dscp_info.descriptor.dl_len); 1321 memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len); 1322 1323 if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) 1324 { 1325 BTA_HhAddDev(*bda, hid_info.attr_mask, hid_info.sub_class, 1326 hid_info.app_id, dscp_info); 1327 } 1328 1329 osi_free_and_reset((void **)&dscp_info.descriptor.dsc_list); 1330 1331 return BT_STATUS_SUCCESS; 1332} 1333 1334/******************************************************************************* 1335** 1336** Function get_protocol 1337** 1338** Description Get the HID proto mode. 1339** 1340** Returns bt_status_t 1341** 1342*******************************************************************************/ 1343static bt_status_t get_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode) 1344{ 1345 CHECK_BTHH_INIT(); 1346 btif_hh_device_t *p_dev; 1347 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1348 UNUSED(protocolMode); 1349 1350 BTIF_TRACE_DEBUG(" addr = %02X:%02X:%02X:%02X:%02X:%02X", 1351 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1352 1353 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1354 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1355 return BT_STATUS_FAIL; 1356 } 1357 1358 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1359 if (p_dev != NULL) { 1360 1361 BTA_HhGetProtoMode(p_dev->dev_handle); 1362 } 1363 else { 1364 return BT_STATUS_FAIL; 1365 } 1366 return BT_STATUS_SUCCESS; 1367} 1368 1369/******************************************************************************* 1370** 1371** Function set_protocol 1372** 1373** Description Set the HID proto mode. 1374** 1375** Returns bt_status_t 1376** 1377*******************************************************************************/ 1378static bt_status_t set_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode) 1379{ 1380 CHECK_BTHH_INIT(); 1381 btif_hh_device_t *p_dev; 1382 UINT8 proto_mode = protocolMode; 1383 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1384 1385 BTIF_TRACE_DEBUG("%s:proto_mode = %d", __FUNCTION__,protocolMode); 1386 1387 BTIF_TRACE_DEBUG("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1388 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1389 1390 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1391 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1392 return BT_STATUS_FAIL; 1393 } 1394 1395 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1396 if (p_dev == NULL) { 1397 BTIF_TRACE_WARNING(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1398 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1399 return BT_STATUS_FAIL; 1400 } 1401 else if (protocolMode != BTA_HH_PROTO_RPT_MODE && protocolMode != BTA_HH_PROTO_BOOT_MODE) { 1402 BTIF_TRACE_WARNING("%s: Error, device proto_mode = %d.", __func__, proto_mode); 1403 return BT_STATUS_FAIL; 1404 } 1405 else { 1406 BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode); 1407 } 1408 1409 return BT_STATUS_SUCCESS; 1410} 1411 1412/******************************************************************************* 1413** 1414** Function get_report 1415** 1416** Description Send a GET_REPORT to HID device. 1417** 1418** Returns bt_status_t 1419** 1420*******************************************************************************/ 1421static bt_status_t get_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, uint8_t reportId, int bufferSize) 1422{ 1423 CHECK_BTHH_INIT(); 1424 btif_hh_device_t *p_dev; 1425 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1426 1427 BTIF_TRACE_DEBUG("%s: r_type = %d, rpt_id = %d, buf_size = %d", __func__, 1428 reportType, reportId, bufferSize); 1429 1430 BTIF_TRACE_DEBUG("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1431 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1432 1433 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1434 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1435 return BT_STATUS_FAIL; 1436 } 1437 1438 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1439 if (p_dev == NULL) { 1440 BTIF_TRACE_ERROR("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", __func__, 1441 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1442 return BT_STATUS_FAIL; 1443 } 1444 else if ( ((int) reportType) <= BTA_HH_RPTT_RESRV || ((int) reportType) > BTA_HH_RPTT_FEATURE) { 1445 BTIF_TRACE_ERROR(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1446 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1447 return BT_STATUS_FAIL; 1448 } 1449 else { 1450 BTA_HhGetReport(p_dev->dev_handle, reportType, 1451 reportId, bufferSize); 1452 } 1453 1454 return BT_STATUS_SUCCESS; 1455} 1456 1457/******************************************************************************* 1458** 1459** Function set_report 1460** 1461** Description Send a SET_REPORT to HID device. 1462** 1463** Returns bt_status_t 1464** 1465*******************************************************************************/ 1466static bt_status_t set_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, char* report) 1467{ 1468 CHECK_BTHH_INIT(); 1469 btif_hh_device_t *p_dev; 1470 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1471 1472 BTIF_TRACE_DEBUG("%s:reportType = %d", __FUNCTION__,reportType); 1473 1474 BTIF_TRACE_DEBUG("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1475 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1476 1477 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1478 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1479 return BT_STATUS_FAIL; 1480 } 1481 1482 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1483 if (p_dev == NULL) { 1484 BTIF_TRACE_ERROR("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", __func__, 1485 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1486 return BT_STATUS_FAIL; 1487 } 1488 else if ( ( (int) reportType) <= BTA_HH_RPTT_RESRV || ( (int) reportType) > BTA_HH_RPTT_FEATURE) { 1489 BTIF_TRACE_ERROR(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1490 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1491 return BT_STATUS_FAIL; 1492 } 1493 else { 1494 int hex_bytes_filled; 1495 size_t len = (strlen(report) + 1) / 2; 1496 UINT8 *hexbuf = osi_calloc(len); 1497 1498 /* Build a SetReport data buffer */ 1499 //TODO 1500 hex_bytes_filled = ascii_2_hex(report, len, hexbuf); 1501 LOG_INFO(LOG_TAG, "Hex bytes filled, hex value: %d", hex_bytes_filled); 1502 if (hex_bytes_filled) { 1503 BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf); 1504 if (p_buf == NULL) { 1505 BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d", 1506 __FUNCTION__, hex_bytes_filled); 1507 osi_free(hexbuf); 1508 return BT_STATUS_FAIL; 1509 } 1510 BTA_HhSetReport(p_dev->dev_handle, reportType, p_buf); 1511 osi_free(hexbuf); 1512 return BT_STATUS_SUCCESS; 1513 } 1514 osi_free(hexbuf); 1515 return BT_STATUS_FAIL; 1516 } 1517} 1518 1519/******************************************************************************* 1520** 1521** Function send_data 1522** 1523** Description Send a SEND_DATA to HID device. 1524** 1525** Returns bt_status_t 1526** 1527*******************************************************************************/ 1528static bt_status_t send_data (bt_bdaddr_t *bd_addr, char* data) 1529{ 1530 CHECK_BTHH_INIT(); 1531 btif_hh_device_t *p_dev; 1532 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1533 1534 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 1535 1536 BTIF_TRACE_DEBUG("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1537 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1538 1539 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1540 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1541 return BT_STATUS_FAIL; 1542 } 1543 1544 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1545 if (p_dev == NULL) { 1546 BTIF_TRACE_ERROR("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", __func__, 1547 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1548 return BT_STATUS_FAIL; 1549 } 1550 1551 else { 1552 int hex_bytes_filled; 1553 size_t len = (strlen(data) + 1) / 2; 1554 UINT8 *hexbuf = osi_calloc(len); 1555 1556 /* Build a SendData data buffer */ 1557 hex_bytes_filled = ascii_2_hex(data, len, hexbuf); 1558 BTIF_TRACE_ERROR("Hex bytes filled, hex value: %d, %d", hex_bytes_filled, len); 1559 1560 if (hex_bytes_filled) { 1561 BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf); 1562 if (p_buf == NULL) { 1563 BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d", 1564 __FUNCTION__, hex_bytes_filled); 1565 osi_free(hexbuf); 1566 return BT_STATUS_FAIL; 1567 } 1568 p_buf->layer_specific = BTA_HH_RPTT_OUTPUT; 1569 BTA_HhSendData(p_dev->dev_handle, *bda, p_buf); 1570 osi_free(hexbuf); 1571 return BT_STATUS_SUCCESS; 1572 } 1573 osi_free(hexbuf); 1574 return BT_STATUS_FAIL; 1575 } 1576} 1577 1578/******************************************************************************* 1579** 1580** Function cleanup 1581** 1582** Description Closes the HH interface 1583** 1584** Returns bt_status_t 1585** 1586*******************************************************************************/ 1587static void cleanup( void ) 1588{ 1589 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1590 btif_hh_device_t *p_dev; 1591 int i; 1592 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1593 BTIF_TRACE_WARNING("%s: HH disabling or disabled already, status = %d", __FUNCTION__, btif_hh_cb.status); 1594 return; 1595 } 1596 btif_hh_cb.status = BTIF_HH_DISABLING; 1597 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 1598 p_dev = &btif_hh_cb.devices[i]; 1599 if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) { 1600 BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); 1601 if (p_dev->fd >= 0) { 1602 bta_hh_co_destroy(p_dev->fd); 1603 p_dev->fd = -1; 1604 } 1605 p_dev->hh_keep_polling = 0; 1606 p_dev->hh_poll_thread_id = -1; 1607 } 1608 } 1609 1610 if (bt_hh_callbacks) 1611 { 1612 btif_disable_service(BTA_HID_SERVICE_ID); 1613 bt_hh_callbacks = NULL; 1614 } 1615 1616} 1617 1618static const bthh_interface_t bthhInterface = { 1619 sizeof(bthhInterface), 1620 init, 1621 connect, 1622 disconnect, 1623 virtual_unplug, 1624 set_info, 1625 get_protocol, 1626 set_protocol, 1627// get_idle_time, 1628// set_idle_time, 1629 get_report, 1630 set_report, 1631 send_data, 1632 cleanup, 1633}; 1634 1635/******************************************************************************* 1636** 1637** Function btif_hh_execute_service 1638** 1639** Description Initializes/Shuts down the service 1640** 1641** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 1642** 1643*******************************************************************************/ 1644bt_status_t btif_hh_execute_service(BOOLEAN b_enable) 1645{ 1646 if (b_enable) 1647 { 1648 /* Enable and register with BTA-HH */ 1649 BTA_HhEnable(BTUI_HH_SECURITY, bte_hh_evt); 1650 } 1651 else { 1652 /* Disable HH */ 1653 BTA_HhDisable(); 1654 } 1655 return BT_STATUS_SUCCESS; 1656} 1657 1658/******************************************************************************* 1659** 1660** Function btif_hh_get_interface 1661** 1662** Description Get the hh callback interface 1663** 1664** Returns bthh_interface_t 1665** 1666*******************************************************************************/ 1667const bthh_interface_t *btif_hh_get_interface() 1668{ 1669 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1670 return &bthhInterface; 1671} 1672