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