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