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