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 if (added_dev == NULL || 605 (added_dev->attr_mask & HID_NORMALLY_CONNECTABLE) != 0 || 606 (added_dev->attr_mask & HID_RECONN_INIT) == 0) 607 { 608 tBTA_SEC sec_mask = BTUI_HH_SECURITY; 609 btif_hh_cb.status = BTIF_HH_DEV_CONNECTING; 610 BD_ADDR *bda = (BD_ADDR*)bd_addr; 611 BTA_HhOpen(*bda, BTA_HH_PROTO_RPT_MODE, sec_mask); 612 } 613 else { 614 // This device shall be connected from the host side. 615 BTIF_TRACE_ERROR2("%s: Error, device %s can only be reconnected from device side", 616 __FUNCTION__, bda_str); 617 //TODO 618 /* if ((remote_class & BT_DEV_CLASS_MASK) == BT_DEV_CLASS_HID_POINTING) { 619 //SIG_HH_CONNECTION, *bda, HH_CONN_STATUS_FAILED_MOUSE_FROM_HOST); 620 } 621 else { 622 // SIG_HH_CONNECTION, *bda, HH_CONN_STATUS_FAILED_KBD_FROM_HOST); 623 }*/ 624 return BT_STATUS_FAIL; 625 626 } 627 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, BTHH_CONN_STATE_CONNECTING); 628 return BT_STATUS_SUCCESS; 629} 630 631/******************************************************************************* 632** 633** Function btif_hh_disconnect 634** 635** Description disconnection initiated from the BTIF thread context 636** 637** Returns void 638** 639*******************************************************************************/ 640 641void btif_hh_disconnect(bt_bdaddr_t *bd_addr) 642{ 643 BD_ADDR *bda = (BD_ADDR*)bd_addr; 644 btif_hh_device_t *p_dev; 645 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 646 if (p_dev != NULL) 647 { 648 BTA_HhClose(p_dev->dev_handle); 649 } 650 else 651 BTIF_TRACE_DEBUG1("%s-- Error: device not connected:",__FUNCTION__); 652} 653 654 655/******************************************************************************* 656** 657** Function btif_btif_hh_setreport 658** 659** Description setreport initiated from the BTIF thread context 660** 661** Returns void 662** 663*******************************************************************************/ 664 665void btif_hh_setreport(btif_hh_device_t *p_dev, bthh_report_type_t r_type, UINT16 size, 666 UINT8* report) 667{ 668 UINT8 hexbuf[20]; 669 UINT16 len = size; 670 int i = 0; 671 if (p_dev->p_buf != NULL) { 672 GKI_freebuf(p_dev->p_buf); 673 } 674 p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR))); 675 if (p_dev->p_buf == NULL) { 676 APPL_TRACE_ERROR2("%s: Error, failed to allocate RPT buffer, len = %d", __FUNCTION__, len); 677 return; 678 } 679 680 p_dev->p_buf->len = len; 681 p_dev->p_buf->offset = BTA_HH_MIN_OFFSET; 682 683 //Build a SetReport data buffer 684 memset(hexbuf, 0, 20); 685 for(i=0; i<len; i++) 686 hexbuf[i] = report[i]; 687 688 UINT8* pbuf_data; 689 pbuf_data = (UINT8*) (p_dev->p_buf + 1) + p_dev->p_buf->offset; 690 memcpy(pbuf_data, hexbuf, len); 691 BTA_HhSetReport(p_dev->dev_handle, r_type, p_dev->p_buf); 692 693} 694 695/***************************************************************************** 696** Section name (Group of functions) 697*****************************************************************************/ 698 699/***************************************************************************** 700** 701** btif hh api functions (no context switch) 702** 703*****************************************************************************/ 704 705 706/******************************************************************************* 707** 708** Function btif_hh_upstreams_evt 709** 710** Description Executes HH UPSTREAMS events in btif context 711** 712** Returns void 713** 714*******************************************************************************/ 715static void btif_hh_upstreams_evt(UINT16 event, char* p_param) 716{ 717 tBTA_HH *p_data = (tBTA_HH *)p_param; 718 bdstr_t bdstr; 719 btif_hh_device_t *p_dev = NULL; 720 int i; 721 int len, tmplen; 722 723 BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_hh_event(event)); 724 725 switch (event) 726 { 727 case BTA_HH_ENABLE_EVT: 728 BTIF_TRACE_DEBUG2("%s: BTA_HH_ENABLE_EVT: status =%d",__FUNCTION__, p_data->status); 729 if (p_data->status == BTA_HH_OK) { 730 btif_hh_cb.status = BTIF_HH_ENABLED; 731 BTIF_TRACE_DEBUG1("%s--Loading added devices",__FUNCTION__); 732 /* Add hid descriptors for already bonded hid devices*/ 733 btif_storage_load_bonded_hid_info(); 734 } 735 else { 736 btif_hh_cb.status = BTIF_HH_DISABLED; 737 BTIF_TRACE_WARNING1("BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d", p_data->status); 738 } 739 break; 740 741 case BTA_HH_DISABLE_EVT: 742 btif_hh_cb.status = BTIF_HH_DISABLED; 743 if (p_data->status == BTA_HH_OK) { 744 int i; 745 //Clear the control block 746 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb)); 747 for (i = 0; i < BTIF_HH_MAX_HID; i++){ 748 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN; 749 } 750 } 751 else 752 BTIF_TRACE_WARNING1("BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d", p_data->status); 753 break; 754 755 case BTA_HH_OPEN_EVT: 756 BTIF_TRACE_WARNING3("%s: BTA_HH_OPN_EVT: handle=%d, status =%d",__FUNCTION__, p_data->conn.handle, p_data->conn.status); 757 if (p_data->conn.status == BTA_HH_OK) { 758 p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle); 759 if (p_dev == NULL) { 760 BTIF_TRACE_WARNING1("BTA_HH_OPEN_EVT: Error, cannot find device with handle %d", p_data->conn.handle); 761 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 762 // The connect request must come from device side and exceeded the connected 763 // HID device number. 764 BTA_HhClose(p_data->conn.handle); 765 HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED); 766 } 767 else if (p_dev->fd < 0) { 768 BTIF_TRACE_WARNING0("BTA_HH_OPEN_EVT: Error, failed to find the uhid driver..."); 769 memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN); 770 //remove the connection and then try again to reconnect from the mouse side to recover 771 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 772 BTA_HhClose(p_data->conn.handle); 773 } 774 else { 775 BTIF_TRACE_WARNING1("BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle ... %d",p_data->conn.handle); 776 memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN); 777 btif_hh_cb.status = BTIF_HH_DEV_CONNECTED; 778 // Send set_idle if the peer_device is a keyboard 779 if (check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_KEYBOARD )|| 780 check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_COMBO)) 781 BTA_HhSetIdle(p_data->conn.handle, 0); 782 btif_hh_cb.p_curr_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle); 783 BTA_HhGetDscpInfo(p_data->conn.handle); 784 p_dev->dev_status = BTHH_CONN_STATE_CONNECTED; 785 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); 786 } 787 } 788 else { 789 bt_bdaddr_t *bdaddr = (bt_bdaddr_t*)p_data->conn.bda; 790 HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED); 791 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 792 } 793 break; 794 case BTA_HH_CLOSE_EVT: 795 BTIF_TRACE_DEBUG2("BTA_HH_CLOSE_EVT: status = %d, handle = %d", 796 p_data->dev_status.status, p_data->dev_status.handle); 797 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 798 if (p_dev != NULL) { 799 BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); 800 if (p_dev->fd >= 0){ 801 UINT8 hidreport[9]; 802 memset(hidreport,0,9); 803 hidreport[0]=1; 804 bta_hh_co_write(p_dev->fd , hidreport, sizeof(hidreport)); 805 } 806 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 807 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; 808 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); 809 BTIF_TRACE_DEBUG2("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); 810 bta_hh_co_destroy(p_dev->fd); 811 p_dev->fd = -1; 812 } 813 else { 814 BTIF_TRACE_WARNING1("Error: cannot find device with handle %d", p_data->dev_status.handle); 815 } 816 break; 817 case BTA_HH_GET_RPT_EVT: 818 BTIF_TRACE_DEBUG2("BTA_HH_GET_RPT_EVT: status = %d, handle = %d", 819 p_data->hs_data.status, p_data->hs_data.handle); 820 p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle); 821 HAL_CBACK(bt_hh_callbacks, get_report_cb,(bt_bdaddr_t*) &(p_dev->bd_addr), (bthh_status_t) p_data->hs_data.status, 822 (uint8_t*) p_data->hs_data.rsp_data.p_rpt_data, BT_HDR_SIZE); 823 break; 824 825 case BTA_HH_SET_RPT_EVT: 826 BTIF_TRACE_DEBUG2("BTA_HH_SET_RPT_EVT: status = %d, handle = %d", 827 p_data->dev_status.status, p_data->dev_status.handle); 828 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 829 if (p_dev != NULL && p_dev->p_buf != NULL) { 830 BTIF_TRACE_DEBUG0("Freeing buffer..." ); 831 GKI_freebuf(p_dev->p_buf); 832 p_dev->p_buf = NULL; 833 } 834 break; 835 836 case BTA_HH_GET_PROTO_EVT: 837 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 838 BTIF_TRACE_WARNING4("BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s", 839 p_data->hs_data.status, p_data->hs_data.handle, 840 p_data->hs_data.rsp_data.proto_mode, 841 (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) ? "Report Mode" : 842 (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE) ? "Boot Mode" : "Unsupported"); 843 HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,(bt_bdaddr_t*) &(p_dev->bd_addr), (bthh_status_t)p_data->hs_data.status, 844 (bthh_protocol_mode_t) p_data->hs_data.rsp_data.proto_mode); 845 break; 846 847 case BTA_HH_SET_PROTO_EVT: 848 BTIF_TRACE_DEBUG2("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d", 849 p_data->dev_status.status, p_data->dev_status.handle); 850 break; 851 852 case BTA_HH_GET_IDLE_EVT: 853 BTIF_TRACE_DEBUG3("BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d", 854 p_data->hs_data.handle, p_data->hs_data.status, 855 p_data->hs_data.rsp_data.idle_rate); 856 break; 857 858 case BTA_HH_SET_IDLE_EVT: 859 BTIF_TRACE_DEBUG2("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d", 860 p_data->dev_status.status, p_data->dev_status.handle); 861 break; 862 863 case BTA_HH_GET_DSCP_EVT: 864 BTIF_TRACE_WARNING2("BTA_HH_GET_DSCP_EVT: status = %d, handle = %d", 865 p_data->dev_status.status, p_data->dev_status.handle); 866 len = p_data->dscp_info.descriptor.dl_len; 867 BTIF_TRACE_DEBUG1("BTA_HH_GET_DSCP_EVT: len = %d", len); 868 p_dev = btif_hh_cb.p_curr_dev; 869 if (p_dev == NULL) { 870 BTIF_TRACE_ERROR0("BTA_HH_GET_DSCP_EVT: No HID device is currently connected"); 871 return; 872 } 873 if (p_dev->fd < 0) { 874 ALOGE("BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver..."); 875 return; 876 } 877 { 878 char *cached_name = NULL; 879 char name[] = "Broadcom Bluetooth HID"; 880 if (cached_name == NULL) { 881 cached_name = name; 882 } 883 884 BTIF_TRACE_WARNING2("%s: name = %s", __FUNCTION__, cached_name); 885 bta_hh_co_send_hid_info(p_dev, cached_name, 886 p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, 887 p_data->dscp_info.version, p_data->dscp_info.ctry_code, 888 len, p_data->dscp_info.descriptor.dsc_list); 889 if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) { 890 BD_ADDR bda; 891 bdcpy(bda, p_dev->bd_addr.address); 892 tBTA_HH_DEV_DSCP_INFO dscp_info; 893 bt_status_t ret; 894 bdcpy(bda, p_dev->bd_addr.address); 895 btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info); 896 BTIF_TRACE_DEBUG6("BTA_HH_GET_DSCP_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x", 897 p_dev->bd_addr.address[0], p_dev->bd_addr.address[1], p_dev->bd_addr.address[2], 898 p_dev->bd_addr.address[3], p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]); 899 BTA_HhAddDev(bda, p_dev->attr_mask,p_dev->sub_class,p_dev->app_id, dscp_info); 900 // write hid info to nvram 901 ret = btif_storage_add_hid_device_info(&(p_dev->bd_addr), p_dev->attr_mask,p_dev->sub_class,p_dev->app_id, 902 p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, 903 p_data->dscp_info.version, p_data->dscp_info.ctry_code, 904 len, p_data->dscp_info.descriptor.dsc_list); 905 906 ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret); 907 BTIF_TRACE_WARNING0("BTA_HH_GET_DSCP_EVT: Called add device"); 908 909 //Free buffer created for dscp_info; 910 if (dscp_info.descriptor.dl_len >0 && dscp_info.descriptor.dsc_list != NULL) 911 { 912 GKI_freebuf(dscp_info.descriptor.dsc_list); 913 dscp_info.descriptor.dsc_list = NULL; 914 dscp_info.descriptor.dl_len=0; 915 } 916 } 917 else { 918 //Device already added. 919 BTIF_TRACE_WARNING1("%s: Device already added ",__FUNCTION__); 920 } 921 /*Sync HID Keyboard lockstates */ 922 tmplen = sizeof(hid_kb_numlock_on_list) 923 / sizeof(tHID_KB_LIST); 924 for(i = 0; i< tmplen; i++) 925 { 926 if(p_data->dscp_info.vendor_id 927 == hid_kb_numlock_on_list[i].version_id && 928 p_data->dscp_info.product_id 929 == hid_kb_numlock_on_list[i].product_id) 930 { 931 BTIF_TRACE_DEBUG3("%s() idx[%d] Enabling "\ 932 "NUMLOCK for device :: %s", __FUNCTION__, 933 i, hid_kb_numlock_on_list[i].kb_name); 934 /* Enable NUMLOCK by default so that numeric 935 keys work from first keyboard connect */ 936 set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, 937 TRUE); 938 sync_lockstate_on_connect(p_dev); 939 /* End Sync HID Keyboard lockstates */ 940 break; 941 } 942 } 943 } 944 break; 945 946 case BTA_HH_ADD_DEV_EVT: 947 BTIF_TRACE_WARNING2("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",p_data->dev_info.status, p_data->dev_info.handle); 948 int i; 949 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { 950 if (memcmp(btif_hh_cb.added_devices[i].bd_addr.address, p_data->dev_info.bda, 6) == 0) { 951 if (p_data->dev_info.status == BTA_HH_OK) { 952 btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle; 953 } 954 else { 955 memset(btif_hh_cb.added_devices[i].bd_addr.address, 0, 6); 956 btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE; 957 } 958 break; 959 } 960 } 961 break; 962 case BTA_HH_RMV_DEV_EVT: 963 BTIF_TRACE_DEBUG2("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d", 964 p_data->dev_info.status, p_data->dev_info.handle); 965 BTIF_TRACE_DEBUG6("BTA_HH_RMV_DEV_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x", 966 p_data->dev_info.bda[0], p_data->dev_info.bda[1], p_data->dev_info.bda[2], 967 p_data->dev_info.bda[3], p_data->dev_info.bda[4], p_data->dev_info.bda[5]); 968 break; 969 970 971 case BTA_HH_VC_UNPLUG_EVT: 972 BTIF_TRACE_DEBUG2("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d", 973 p_data->dev_status.status, p_data->dev_status.handle); 974 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); 975 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; 976 if (p_dev != NULL) { 977 BTIF_TRACE_DEBUG6("BTA_HH_VC_UNPLUG_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x", 978 p_dev->bd_addr.address[0], p_dev->bd_addr.address[1], p_dev->bd_addr.address[2], 979 p_dev->bd_addr.address[3], p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]); 980 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; 981 BTIF_TRACE_DEBUG1("%s---Sending connection state change", __FUNCTION__); 982 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); 983 BTIF_TRACE_DEBUG1("%s---Removing HID mouse bond", __FUNCTION__); 984 BTA_DmRemoveDevice((UINT8 *)p_dev->bd_addr.address); 985 HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb,&(p_dev->bd_addr),p_data->dev_status.status); 986 } 987 break; 988 989 case BTA_HH_API_ERR_EVT : 990 ALOGI("BTA_HH API_ERR"); 991 break; 992 993 994 995 default: 996 BTIF_TRACE_WARNING2("%s: Unhandled event: %d", __FUNCTION__, event); 997 break; 998 } 999} 1000 1001/******************************************************************************* 1002** 1003** Function bte_hh_evt 1004** 1005** Description Switches context from BTE to BTIF for all HH events 1006** 1007** Returns void 1008** 1009*******************************************************************************/ 1010 1011static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH *p_data) 1012{ 1013 bt_status_t status; 1014 int param_len = 0; 1015 1016 if (BTA_HH_ENABLE_EVT == event) 1017 param_len = sizeof(tBTA_HH_STATUS); 1018 else if (BTA_HH_OPEN_EVT == event) 1019 param_len = sizeof(tBTA_HH_CONN); 1020 else if (BTA_HH_DISABLE_EVT == event) 1021 param_len = sizeof(tBTA_HH_STATUS); 1022 else if (BTA_HH_CLOSE_EVT == event) 1023 param_len = sizeof(tBTA_HH_CBDATA); 1024 else if (BTA_HH_GET_DSCP_EVT == event) 1025 param_len = sizeof(tBTA_HH_DEV_DSCP_INFO); 1026 else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event)|| (BTA_HH_GET_IDLE_EVT == event)) 1027 param_len = sizeof(tBTA_HH_HSDATA); 1028 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)) 1029 param_len = sizeof(tBTA_HH_CBDATA); 1030 else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event) ) 1031 param_len = sizeof(tBTA_HH_DEV_INFO); 1032 else if (BTA_HH_API_ERR_EVT == event) 1033 param_len = 0; 1034 /* switch context to btif task context (copy full union size for convenience) */ 1035 status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL); 1036 1037 /* catch any failed context transfers */ 1038 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 1039} 1040 1041/******************************************************************************* 1042** 1043** Function btif_hh_handle_evt 1044** 1045** Description Switches context for immediate callback 1046** 1047** Returns void 1048** 1049*******************************************************************************/ 1050 1051static void btif_hh_handle_evt(UINT16 event, char *p_param) 1052{ 1053 bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)p_param; 1054 BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event); 1055 int ret; 1056 switch(event) 1057 { 1058 case BTIF_HH_CONNECT_REQ_EVT: 1059 { 1060 ret = btif_hh_connect(bd_addr); 1061 if(ret == BT_STATUS_SUCCESS) 1062 { 1063 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_CONNECTING); 1064 } 1065 else 1066 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_DISCONNECTED); 1067 } 1068 break; 1069 1070 case BTIF_HH_DISCONNECT_REQ_EVT: 1071 { 1072 BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event); 1073 btif_hh_disconnect(bd_addr); 1074 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_DISCONNECTING); 1075 } 1076 break; 1077 1078 case BTIF_HH_VUP_REQ_EVT: 1079 { 1080 BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event); 1081 ret = btif_hh_virtual_unplug(bd_addr); 1082 } 1083 break; 1084 1085 default: 1086 { 1087 BTIF_TRACE_WARNING2("%s : Unknown event 0x%x", __FUNCTION__, event); 1088 } 1089 break; 1090 } 1091} 1092 1093 1094/******************************************************************************* 1095** 1096** Function btif_hh_init 1097** 1098** Description initializes the hh interface 1099** 1100** Returns bt_status_t 1101** 1102*******************************************************************************/ 1103static bt_status_t init( bthh_callbacks_t* callbacks ) 1104{ 1105 UINT32 i; 1106 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1107 1108 bt_hh_callbacks = callbacks; 1109 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb)); 1110 for (i = 0; i < BTIF_HH_MAX_HID; i++){ 1111 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN; 1112 } 1113 /* Invoke the enable service API to the core to set the appropriate service_id */ 1114 btif_enable_service(BTA_HID_SERVICE_ID); 1115 return BT_STATUS_SUCCESS; 1116} 1117 1118/******************************************************************************* 1119** 1120** Function connect 1121** 1122** Description connect to hid device 1123** 1124** Returns bt_status_t 1125** 1126*******************************************************************************/ 1127static bt_status_t connect( bt_bdaddr_t *bd_addr) 1128{ 1129 if(btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) 1130 { 1131 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT, 1132 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1133 return BT_STATUS_SUCCESS; 1134 } 1135 else 1136 return BT_STATUS_BUSY; 1137} 1138 1139/******************************************************************************* 1140** 1141** Function disconnect 1142** 1143** Description disconnect from hid device 1144** 1145** Returns bt_status_t 1146** 1147*******************************************************************************/ 1148static bt_status_t disconnect( bt_bdaddr_t *bd_addr ) 1149{ 1150 CHECK_BTHH_INIT(); 1151 btif_hh_device_t *p_dev; 1152 1153 if (btif_hh_cb.status == BTIF_HH_DISABLED) 1154 { 1155 BTIF_TRACE_WARNING2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1156 return BT_STATUS_FAIL; 1157 } 1158 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1159 if (p_dev != NULL) 1160 { 1161 return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT, 1162 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1163 } 1164 else 1165 { 1166 BTIF_TRACE_WARNING1("%s: Error, device not opened.", __FUNCTION__); 1167 return BT_STATUS_FAIL; 1168 } 1169} 1170 1171/******************************************************************************* 1172** 1173** Function virtual_unplug 1174** 1175** Description Virtual UnPlug (VUP) the specified HID device. 1176** 1177** Returns bt_status_t 1178** 1179*******************************************************************************/ 1180static bt_status_t virtual_unplug (bt_bdaddr_t *bd_addr) 1181{ 1182 CHECK_BTHH_INIT(); 1183 btif_hh_device_t *p_dev; 1184 char bd_str[18]; 1185 sprintf(bd_str, "%02X:%02X:%02X:%02X:%02X:%02X", 1186 bd_addr->address[0], bd_addr->address[1], bd_addr->address[2], bd_addr->address[3], 1187 bd_addr->address[4], bd_addr->address[5]); 1188 if (btif_hh_cb.status == BTIF_HH_DISABLED) 1189 { 1190 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1191 return BT_STATUS_FAIL; 1192 } 1193 p_dev = btif_hh_find_dev_by_bda(bd_addr); 1194 if (!p_dev) 1195 { 1196 BTIF_TRACE_ERROR2("%s: Error, device %s not opened.", __FUNCTION__, bd_str); 1197 return BT_STATUS_FAIL; 1198 } 1199 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, 1200 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1201 return BT_STATUS_SUCCESS; 1202} 1203 1204 1205/******************************************************************************* 1206** 1207** Function set_info 1208** 1209** Description Set the HID device descriptor for the specified HID device. 1210** 1211** Returns bt_status_t 1212** 1213*******************************************************************************/ 1214static bt_status_t set_info (bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info ) 1215{ 1216 CHECK_BTHH_INIT(); 1217 tBTA_HH_DEV_DSCP_INFO dscp_info; 1218 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1219 1220 BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1221 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1222 BTIF_TRACE_DEBUG6("%s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, " 1223 "product_id = 0x%04x, version= 0x%04x", 1224 __FUNCTION__, hid_info.sub_class, 1225 hid_info.app_id, hid_info.vendor_id, hid_info.product_id, 1226 hid_info.version); 1227 1228 if (btif_hh_cb.status == BTIF_HH_DISABLED) 1229 { 1230 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1231 return BT_STATUS_FAIL; 1232 } 1233 1234 dscp_info.vendor_id = hid_info.vendor_id; 1235 dscp_info.product_id = hid_info.product_id; 1236 dscp_info.version = hid_info.version; 1237 dscp_info.ctry_code = hid_info.ctry_code; 1238 1239 dscp_info.descriptor.dl_len = hid_info.dl_len; 1240 dscp_info.descriptor.dsc_list = (UINT8 *) GKI_getbuf(dscp_info.descriptor.dl_len); 1241 if (dscp_info.descriptor.dsc_list == NULL) 1242 { 1243 ALOGE("%s: Failed to allocate DSCP for CB", __FUNCTION__); 1244 return BT_STATUS_FAIL; 1245 } 1246 memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len); 1247 1248 if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) 1249 { 1250 BTA_HhAddDev(*bda, hid_info.attr_mask, hid_info.sub_class, 1251 hid_info.app_id, dscp_info); 1252 } 1253 1254 GKI_freebuf(dscp_info.descriptor.dsc_list); 1255 1256 return BT_STATUS_SUCCESS; 1257} 1258/******************************************************************************* 1259** 1260** Function get_idle_time 1261** 1262** Description Get the HID idle time 1263** 1264** Returns bt_status_t 1265** 1266*******************************************************************************/ 1267static bt_status_t get_idle_time(bt_bdaddr_t *bd_addr) 1268{ 1269 CHECK_BTHH_INIT(); 1270 btif_hh_device_t *p_dev; 1271 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1272 1273 BTIF_TRACE_DEBUG6(" addr = %02X:%02X:%02X:%02X:%02X:%02X", 1274 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1275 1276 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1277 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1278 return BT_STATUS_FAIL; 1279 } 1280 1281 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1282 if (p_dev != NULL) { 1283 //BTA_HhGetIdle(p_dev->dev_handle); 1284 } 1285 else { 1286 return BT_STATUS_FAIL; 1287 } 1288 return BT_STATUS_SUCCESS; 1289} 1290 1291/******************************************************************************* 1292** 1293** Function set_idle_time 1294** 1295** Description Set the HID idle time 1296** 1297** Returns bt_status_t 1298** 1299*******************************************************************************/ 1300static bt_status_t set_idle_time (bt_bdaddr_t *bd_addr, uint8_t idle_time) 1301{ 1302 CHECK_BTHH_INIT(); 1303 btif_hh_device_t *p_dev; 1304 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1305 1306 BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1307 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1308 1309 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1310 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1311 return BT_STATUS_FAIL; 1312 } 1313 1314 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1315 if (p_dev == NULL) { 1316 BTIF_TRACE_WARNING6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1317 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1318 return BT_STATUS_FAIL; 1319 } 1320 else { 1321 //BTA_HhSetIdle(p_dev->dev_handle, idle_time); 1322 } 1323 return BT_STATUS_SUCCESS; 1324} 1325 1326/******************************************************************************* 1327** 1328** Function get_protocol 1329** 1330** Description Get the HID proto mode. 1331** 1332** Returns bt_status_t 1333** 1334*******************************************************************************/ 1335static bt_status_t get_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode) 1336{ 1337 CHECK_BTHH_INIT(); 1338 btif_hh_device_t *p_dev; 1339 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1340 1341 BTIF_TRACE_DEBUG6(" addr = %02X:%02X:%02X:%02X:%02X:%02X", 1342 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1343 1344 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1345 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1346 return BT_STATUS_FAIL; 1347 } 1348 1349 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1350 if (p_dev != NULL) { 1351 BTA_HhGetProtoMode(p_dev->dev_handle); 1352 } 1353 else { 1354 return BT_STATUS_FAIL; 1355 } 1356 return BT_STATUS_SUCCESS; 1357} 1358 1359/******************************************************************************* 1360** 1361** Function set_protocol 1362** 1363** Description Set the HID proto mode. 1364** 1365** Returns bt_status_t 1366** 1367*******************************************************************************/ 1368static bt_status_t set_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode) 1369{ 1370 CHECK_BTHH_INIT(); 1371 btif_hh_device_t *p_dev; 1372 UINT8 proto_mode = protocolMode; 1373 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1374 1375 BTIF_TRACE_DEBUG2("%s:proto_mode = %d", __FUNCTION__,protocolMode); 1376 1377 BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1378 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1379 1380 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1381 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1382 return BT_STATUS_FAIL; 1383 } 1384 1385 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1386 if (p_dev == NULL) { 1387 BTIF_TRACE_WARNING6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1388 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1389 return BT_STATUS_FAIL; 1390 } 1391 else if (protocolMode != BTA_HH_PROTO_RPT_MODE && protocolMode != BTA_HH_PROTO_BOOT_MODE) { 1392 BTIF_TRACE_WARNING2("s: Error, device proto_mode = %d.", __FUNCTION__, proto_mode); 1393 return BT_STATUS_FAIL; 1394 } 1395 else { 1396 BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode); 1397 } 1398 1399 1400 return BT_STATUS_SUCCESS; 1401} 1402 1403/******************************************************************************* 1404** 1405** Function get_report 1406** 1407** Description Send a GET_REPORT to HID device. 1408** 1409** Returns bt_status_t 1410** 1411*******************************************************************************/ 1412static bt_status_t get_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, uint8_t reportId, int bufferSize) 1413{ 1414 CHECK_BTHH_INIT(); 1415 btif_hh_device_t *p_dev; 1416 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1417 1418 BTIF_TRACE_DEBUG4("%s:proto_mode = %dr_type = %d, rpt_id = %d, buf_size = %d", __FUNCTION__, 1419 reportType, reportId, bufferSize); 1420 1421 BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1422 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1423 1424 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1425 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1426 return BT_STATUS_FAIL; 1427 } 1428 1429 1430 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1431 if (p_dev == NULL) { 1432 BTIF_TRACE_ERROR6("%s: 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 if ( ((int) reportType) <= BTA_HH_RPTT_RESRV || ((int) reportType) > BTA_HH_RPTT_FEATURE) { 1437 BTIF_TRACE_ERROR6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1438 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1439 return BT_STATUS_FAIL; 1440 } 1441 else { 1442 BTA_HhGetReport(p_dev->dev_handle, reportType, 1443 reportId, bufferSize); 1444 } 1445 1446 return BT_STATUS_SUCCESS; 1447} 1448 1449/******************************************************************************* 1450** 1451** Function set_report 1452** 1453** Description Send a SET_REPORT to HID device. 1454** 1455** Returns bt_status_t 1456** 1457*******************************************************************************/ 1458static bt_status_t set_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, char* report) 1459{ 1460 CHECK_BTHH_INIT(); 1461 btif_hh_device_t *p_dev; 1462 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1463 1464 BTIF_TRACE_DEBUG2("%s:reportType = %d", __FUNCTION__,reportType); 1465 1466 BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1467 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1468 1469 1470 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1471 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1472 return BT_STATUS_FAIL; 1473 } 1474 1475 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1476 if (p_dev == NULL) { 1477 BTIF_TRACE_ERROR6("%s: 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 if ( ( (int) reportType) <= BTA_HH_RPTT_RESRV || ( (int) reportType) > BTA_HH_RPTT_FEATURE) { 1482 BTIF_TRACE_ERROR6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1483 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1484 return BT_STATUS_FAIL; 1485 } 1486 else { 1487 int hex_bytes_filled; 1488 UINT8 hexbuf[200]; 1489 UINT16 len = (strlen(report) + 1) / 2; 1490 1491 if (p_dev->p_buf != NULL) { 1492 GKI_freebuf(p_dev->p_buf); 1493 } 1494 p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR))); 1495 if (p_dev->p_buf == NULL) { 1496 BTIF_TRACE_ERROR2("%s: Error, failed to allocate RPT buffer, len = %d", __FUNCTION__, len); 1497 return BT_STATUS_FAIL; 1498 } 1499 1500 p_dev->p_buf->len = len; 1501 p_dev->p_buf->offset = BTA_HH_MIN_OFFSET; 1502 1503 /* Build a SetReport data buffer */ 1504 memset(hexbuf, 0, 200); 1505 //TODO 1506 hex_bytes_filled = ascii_2_hex(report, len, hexbuf); 1507 ALOGI("Hex bytes filled, hex value: %d", hex_bytes_filled); 1508 1509 if (hex_bytes_filled) { 1510 UINT8* pbuf_data; 1511 pbuf_data = (UINT8*) (p_dev->p_buf + 1) + p_dev->p_buf->offset; 1512 memcpy(pbuf_data, hexbuf, hex_bytes_filled); 1513 BTA_HhSetReport(p_dev->dev_handle, reportType, p_dev->p_buf); 1514 } 1515 return BT_STATUS_SUCCESS; 1516 } 1517 1518 1519} 1520 1521/******************************************************************************* 1522** 1523** Function send_data 1524** 1525** Description Send a SEND_DATA to HID device. 1526** 1527** Returns bt_status_t 1528** 1529*******************************************************************************/ 1530static bt_status_t send_data (bt_bdaddr_t *bd_addr, char* data) 1531{ 1532 CHECK_BTHH_INIT(); 1533 btif_hh_device_t *p_dev; 1534 BD_ADDR* bda = (BD_ADDR*) bd_addr; 1535 1536 BTIF_TRACE_DEBUG1("%s", __FUNCTION__); 1537 1538 BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X", 1539 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1540 1541 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1542 BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status); 1543 return BT_STATUS_FAIL; 1544 } 1545 1546 p_dev = btif_hh_find_connected_dev_by_bda(bd_addr); 1547 if (p_dev == NULL) { 1548 BTIF_TRACE_ERROR6("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", 1549 (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]); 1550 return BT_STATUS_FAIL; 1551 } 1552 1553 else { 1554 int hex_bytes_filled; 1555 UINT8 hexbuf[200]; 1556 UINT16 len = (strlen(data) + 1) / 2; 1557 1558 if (p_dev->p_buf != NULL) { 1559 GKI_freebuf(p_dev->p_buf); 1560 } 1561 p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR))); 1562 if (p_dev->p_buf == NULL) { 1563 BTIF_TRACE_ERROR2("%s: Error, failed to allocate RPT buffer, len = %d", __FUNCTION__, len); 1564 return BT_STATUS_FAIL; 1565 } 1566 1567 p_dev->p_buf->len = len; 1568 p_dev->p_buf->offset = BTA_HH_MIN_OFFSET; 1569 1570 /* Build a SetReport data buffer */ 1571 memset(hexbuf, 0, 200); 1572 hex_bytes_filled = ascii_2_hex(data, len, hexbuf); 1573 BTIF_TRACE_ERROR2("Hex bytes filled, hex value: %d, %d", hex_bytes_filled, len); 1574 1575 if (hex_bytes_filled) { 1576 UINT8* pbuf_data; 1577 pbuf_data = (UINT8*) (p_dev->p_buf + 1) + p_dev->p_buf->offset; 1578 memcpy(pbuf_data, hexbuf, hex_bytes_filled); 1579 BTA_HhSendData(p_dev->dev_handle, *bda, p_dev->p_buf); 1580 return BT_STATUS_SUCCESS; 1581 } 1582 1583 } 1584 return BT_STATUS_FAIL; 1585} 1586 1587 1588/******************************************************************************* 1589** 1590** Function cleanup 1591** 1592** Description Closes the HH interface 1593** 1594** Returns bt_status_t 1595** 1596*******************************************************************************/ 1597static void cleanup( void ) 1598{ 1599 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1600 btif_hh_device_t *p_dev; 1601 int i; 1602 if (btif_hh_cb.status == BTIF_HH_DISABLED) { 1603 BTIF_TRACE_WARNING2("%s: HH disabling or disabled already, status = %d", __FUNCTION__, btif_hh_cb.status); 1604 return; 1605 } 1606 btif_hh_cb.status = BTIF_HH_DISABLING; 1607 for (i = 0; i < BTIF_HH_MAX_HID; i++) { 1608 p_dev = &btif_hh_cb.devices[i]; 1609 if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) { 1610 BTIF_TRACE_DEBUG2("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); 1611 bta_hh_co_destroy(p_dev->fd); 1612 p_dev->fd = -1; 1613 p_dev->hh_keep_polling = 0; 1614 p_dev->hh_poll_thread_id = -1; 1615 } 1616 } 1617 1618 if (bt_hh_callbacks) 1619 { 1620 btif_disable_service(BTA_HID_SERVICE_ID); 1621 bt_hh_callbacks = NULL; 1622 } 1623 1624} 1625 1626static const bthh_interface_t bthhInterface = { 1627 sizeof(bt_interface_t), 1628 init, 1629 connect, 1630 disconnect, 1631 virtual_unplug, 1632 set_info, 1633 get_protocol, 1634 set_protocol, 1635// get_idle_time, 1636// set_idle_time, 1637 get_report, 1638 set_report, 1639 send_data, 1640 cleanup, 1641}; 1642 1643/******************************************************************************* 1644** 1645** Function btif_hh_execute_service 1646** 1647** Description Initializes/Shuts down the service 1648** 1649** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 1650** 1651*******************************************************************************/ 1652bt_status_t btif_hh_execute_service(BOOLEAN b_enable) 1653{ 1654 if (b_enable) 1655 { 1656 /* Enable and register with BTA-HH */ 1657 BTA_HhEnable(BTA_SEC_NONE, FALSE, bte_hh_evt); 1658 } 1659 else { 1660 /* Disable HH */ 1661 BTA_HhDisable(); 1662 } 1663 return BT_STATUS_SUCCESS; 1664} 1665 1666/******************************************************************************* 1667** 1668** Function btif_hh_get_interface 1669** 1670** Description Get the hh callback interface 1671** 1672** Returns bthh_interface_t 1673** 1674*******************************************************************************/ 1675const bthh_interface_t *btif_hh_get_interface() 1676{ 1677 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1678 return &bthhInterface; 1679} 1680