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