1 /****************************************************************************** 2 * 3 * Copyright 2009-2013 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 #define LOG_TAG "bt_bta_hh" 20 21 #include "bta_api.h" 22 #include "bta_hh_int.h" 23 #include "osi/include/osi.h" 24 25 #if (BTA_HH_LE_INCLUDED == TRUE) 26 27 #include <string.h> 28 29 #include <base/bind.h> 30 #include <base/callback.h> 31 32 #include "bta_gatt_api.h" 33 #include "bta_gatt_queue.h" 34 #include "bta_hh_co.h" 35 #include "btm_api.h" 36 #include "btm_ble_api.h" 37 #include "btm_int.h" 38 #include "device/include/interop.h" 39 #include "osi/include/log.h" 40 #include "srvc_api.h" 41 #include "stack/include/l2c_api.h" 42 #include "utl.h" 43 44 using bluetooth::Uuid; 45 using std::vector; 46 47 #ifndef BTA_HH_LE_RECONN 48 #define BTA_HH_LE_RECONN TRUE 49 #endif 50 51 #define BTA_HH_APP_ID_LE 0xff 52 53 #define BTA_HH_LE_RPT_TYPE_VALID(x) \ 54 ((x) <= BTA_LE_HID_RPT_FEATURE && (x) >= BTA_LE_HID_RPT_INPUT) 55 56 #define BTA_HH_LE_PROTO_BOOT_MODE 0x00 57 #define BTA_HH_LE_PROTO_REPORT_MODE 0x01 58 59 #define BTA_LE_HID_RTP_UUID_MAX 5 60 static const uint16_t bta_hh_uuid_to_rtp_type[BTA_LE_HID_RTP_UUID_MAX][2] = { 61 {GATT_UUID_HID_REPORT, BTA_HH_RPTT_INPUT}, 62 {GATT_UUID_HID_BT_KB_INPUT, BTA_HH_RPTT_INPUT}, 63 {GATT_UUID_HID_BT_KB_OUTPUT, BTA_HH_RPTT_OUTPUT}, 64 {GATT_UUID_HID_BT_MOUSE_INPUT, BTA_HH_RPTT_INPUT}, 65 {GATT_UUID_BATTERY_LEVEL, BTA_HH_RPTT_INPUT}}; 66 67 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); 68 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond); 69 // TODO(jpawlowski): uncomment when fixed 70 // static void bta_hh_process_cache_rpt (tBTA_HH_DEV_CB *p_cb, 71 // tBTA_HH_RPT_CACHE_ENTRY *p_rpt_cache, 72 // uint8_t num_rpt); 73 74 #if (BTA_HH_DEBUG == TRUE) 75 static const char* bta_hh_le_rpt_name[4] = {"UNKNOWN", "INPUT", "OUTPUT", 76 "FEATURE"}; 77 78 /******************************************************************************* 79 * 80 * Function bta_hh_le_hid_report_dbg 81 * 82 * Description debug function to print out all HID report available on 83 * remote device. 84 * 85 * Returns void 86 * 87 ******************************************************************************/ 88 static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB* p_cb) { 89 APPL_TRACE_DEBUG("%s: HID Report DB", __func__); 90 91 if (!p_cb->hid_srvc.in_use) return; 92 93 tBTA_HH_LE_RPT* p_rpt = &p_cb->hid_srvc.report[0]; 94 95 for (int j = 0; j < BTA_HH_LE_RPT_MAX; j++, p_rpt++) { 96 const char* rpt_name = "Unknown"; 97 98 if (!p_rpt->in_use) break; 99 100 if (p_rpt->uuid == GATT_UUID_HID_REPORT) rpt_name = "Report"; 101 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT) rpt_name = "Boot KB Input"; 102 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_OUTPUT) rpt_name = "Boot KB Output"; 103 if (p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) rpt_name = "Boot MI Input"; 104 105 APPL_TRACE_DEBUG( 106 "\t\t [%s- 0x%04x] [Type: %s], [ReportID: %d] [srvc_inst_id: %d] " 107 "[char_inst_id: %d] [Clt_cfg: %d]", 108 rpt_name, p_rpt->uuid, 109 ((p_rpt->rpt_type < 4) ? bta_hh_le_rpt_name[p_rpt->rpt_type] 110 : "UNKNOWN"), 111 p_rpt->rpt_id, p_rpt->srvc_inst_id, p_rpt->char_inst_id, 112 p_rpt->client_cfg_value); 113 } 114 } 115 116 /******************************************************************************* 117 * 118 * Function bta_hh_uuid_to_str 119 * 120 * Description 121 * 122 * Returns void 123 * 124 ******************************************************************************/ 125 static const char* bta_hh_uuid_to_str(uint16_t uuid) { 126 switch (uuid) { 127 case GATT_UUID_HID_INFORMATION: 128 return "GATT_UUID_HID_INFORMATION"; 129 case GATT_UUID_HID_REPORT_MAP: 130 return "GATT_UUID_HID_REPORT_MAP"; 131 case GATT_UUID_HID_CONTROL_POINT: 132 return "GATT_UUID_HID_CONTROL_POINT"; 133 case GATT_UUID_HID_REPORT: 134 return "GATT_UUID_HID_REPORT"; 135 case GATT_UUID_HID_PROTO_MODE: 136 return "GATT_UUID_HID_PROTO_MODE"; 137 case GATT_UUID_HID_BT_KB_INPUT: 138 return "GATT_UUID_HID_BT_KB_INPUT"; 139 case GATT_UUID_HID_BT_KB_OUTPUT: 140 return "GATT_UUID_HID_BT_KB_OUTPUT"; 141 case GATT_UUID_HID_BT_MOUSE_INPUT: 142 return "GATT_UUID_HID_BT_MOUSE_INPUT"; 143 case GATT_UUID_CHAR_CLIENT_CONFIG: 144 return "GATT_UUID_CHAR_CLIENT_CONFIG"; 145 case GATT_UUID_EXT_RPT_REF_DESCR: 146 return "GATT_UUID_EXT_RPT_REF_DESCR"; 147 case GATT_UUID_RPT_REF_DESCR: 148 return "GATT_UUID_RPT_REF_DESCR"; 149 default: 150 return "Unknown UUID"; 151 } 152 } 153 154 #endif 155 /******************************************************************************* 156 * 157 * Function bta_hh_le_enable 158 * 159 * Description initialize LE HID related functionality 160 * 161 * 162 * Returns void 163 * 164 ******************************************************************************/ 165 void bta_hh_le_enable(void) { 166 uint8_t xx; 167 168 bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF; 169 170 for (xx = 0; xx < ARRAY_SIZE(bta_hh_cb.le_cb_index); xx++) 171 bta_hh_cb.le_cb_index[xx] = BTA_HH_IDX_INVALID; 172 173 BTA_GATTC_AppRegister(bta_hh_gattc_callback, 174 base::Bind([](uint8_t client_id, uint8_t r_status) { 175 tBTA_HH bta_hh; 176 bta_hh.status = BTA_HH_ERR; 177 178 if (r_status == GATT_SUCCESS) { 179 bta_hh_cb.gatt_if = client_id; 180 bta_hh.status = BTA_HH_OK; 181 } else { 182 bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF; 183 } 184 185 /* null check is needed in case HID profile is shut 186 * down before BTA_GATTC_AppRegister is done */ 187 if (bta_hh_cb.p_cback) { 188 /* signal BTA call back event */ 189 (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, &bta_hh); 190 } 191 })); 192 } 193 194 /******************************************************************************* 195 * 196 * Function bta_hh_le_is_hh_gatt_if 197 * 198 * Description Check to see if client_if is BTA HH LE GATT interface 199 * 200 * 201 * Returns whether it is HH GATT IF 202 * 203 ******************************************************************************/ 204 bool bta_hh_le_is_hh_gatt_if(tGATT_IF client_if) { 205 return (bta_hh_cb.gatt_if == client_if); 206 } 207 208 /******************************************************************************* 209 * 210 * Function bta_hh_le_deregister 211 * 212 * Description De-register BTA HH from BTA GATTC 213 * 214 * 215 * Returns void 216 * 217 ******************************************************************************/ 218 void bta_hh_le_deregister(void) { BTA_GATTC_AppDeregister(bta_hh_cb.gatt_if); } 219 220 /******************************************************************************* 221 * 222 * Function bta_hh_is_le_device 223 * 224 * Description Check to see if the remote device is a LE only device 225 * 226 * Parameters: 227 * 228 ******************************************************************************/ 229 bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) { 230 p_cb->is_le_device = BTM_UseLeLink(remote_bda); 231 232 return p_cb->is_le_device; 233 } 234 235 /****************************************************************************** 236 * 237 * Function bta_hh_le_get_le_cb 238 * 239 * Description Allocate bta_hh_cb.le_cb_index 240 * 241 * Parameters: 242 * 243 ******************************************************************************/ 244 uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) { 245 uint8_t i; 246 for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) { 247 if (bta_hh_cb.le_cb_index[i] == cb_index) return BTA_HH_GET_LE_DEV_HDL(i); 248 } 249 250 for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) { 251 if (bta_hh_cb.le_cb_index[i] == BTA_HH_IDX_INVALID) 252 return BTA_HH_GET_LE_DEV_HDL(i); 253 } 254 return BTA_HH_IDX_INVALID; 255 } 256 257 /******************************************************************************* 258 * 259 * Function bta_hh_le_open_conn 260 * 261 * Description open a GATT connection first. 262 * 263 * Parameters: 264 * 265 ******************************************************************************/ 266 void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) { 267 tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES; 268 269 /* update cb_index[] map */ 270 p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index); 271 if (p_cb->hid_handle == BTA_HH_IDX_INVALID) { 272 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status); 273 return; 274 } 275 276 p_cb->addr = remote_bda; 277 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; 278 p_cb->in_use = true; 279 280 BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, true, GATT_TRANSPORT_LE, false); 281 } 282 283 /******************************************************************************* 284 * 285 * Function bta_hh_le_find_dev_cb_by_conn_id 286 * 287 * Description Utility function find a device control block by connection 288 * ID. 289 * 290 ******************************************************************************/ 291 tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id) { 292 uint8_t i; 293 tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0]; 294 295 for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) { 296 if (p_dev_cb->in_use && p_dev_cb->conn_id == conn_id) return p_dev_cb; 297 } 298 return NULL; 299 } 300 301 /******************************************************************************* 302 * 303 * Function bta_hh_le_find_dev_cb_by_bda 304 * 305 * Description Utility function find a device control block by BD address. 306 * 307 ******************************************************************************/ 308 tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(const RawAddress& bda) { 309 uint8_t i; 310 tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0]; 311 312 for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) { 313 if (p_dev_cb->in_use && p_dev_cb->addr == bda) return p_dev_cb; 314 } 315 return NULL; 316 } 317 318 /******************************************************************************* 319 * 320 * Function bta_hh_le_find_service_inst_by_battery_inst_id 321 * 322 * Description find HID service instance ID by battery service instance ID 323 * 324 ******************************************************************************/ 325 uint8_t bta_hh_le_find_service_inst_by_battery_inst_id(tBTA_HH_DEV_CB* p_cb, 326 uint8_t ba_inst_id) { 327 if (p_cb->hid_srvc.in_use && p_cb->hid_srvc.incl_srvc_inst == ba_inst_id) { 328 return p_cb->hid_srvc.srvc_inst_id; 329 } 330 return BTA_HH_IDX_INVALID; 331 } 332 333 /******************************************************************************* 334 * 335 * Function bta_hh_le_find_report_entry 336 * 337 * Description find the report entry by service instance and report UUID 338 * and instance ID 339 * 340 ******************************************************************************/ 341 tBTA_HH_LE_RPT* bta_hh_le_find_report_entry( 342 tBTA_HH_DEV_CB* p_cb, uint8_t srvc_inst_id, /* service instance ID */ 343 uint16_t rpt_uuid, uint8_t char_inst_id) { 344 uint8_t i; 345 uint8_t hid_inst_id = srvc_inst_id; 346 tBTA_HH_LE_RPT* p_rpt; 347 348 if (rpt_uuid == GATT_UUID_BATTERY_LEVEL) { 349 hid_inst_id = 350 bta_hh_le_find_service_inst_by_battery_inst_id(p_cb, srvc_inst_id); 351 352 if (hid_inst_id == BTA_HH_IDX_INVALID) return NULL; 353 } 354 355 p_rpt = &p_cb->hid_srvc.report[0]; 356 357 for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { 358 if (p_rpt->uuid == rpt_uuid && p_rpt->srvc_inst_id == srvc_inst_id && 359 p_rpt->char_inst_id == char_inst_id) { 360 return p_rpt; 361 } 362 } 363 return NULL; 364 } 365 366 /******************************************************************************* 367 * 368 * Function bta_hh_le_find_rpt_by_idtype 369 * 370 * Description find a report entry by report ID and protocol mode 371 * 372 * Returns void 373 * 374 ******************************************************************************/ 375 tBTA_HH_LE_RPT* bta_hh_le_find_rpt_by_idtype(tBTA_HH_LE_RPT* p_head, 376 uint8_t mode, 377 tBTA_HH_RPT_TYPE r_type, 378 uint8_t rpt_id) { 379 tBTA_HH_LE_RPT* p_rpt = p_head; 380 uint8_t i; 381 382 #if (BTA_HH_DEBUG == TRUE) 383 APPL_TRACE_DEBUG("bta_hh_le_find_rpt_by_idtype: r_type: %d rpt_id: %d", 384 r_type, rpt_id); 385 #endif 386 387 for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { 388 if (p_rpt->in_use && p_rpt->rpt_id == rpt_id && r_type == p_rpt->rpt_type) { 389 /* return battery report w/o condition */ 390 if (p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) return p_rpt; 391 392 if (mode == BTA_HH_PROTO_RPT_MODE && p_rpt->uuid == GATT_UUID_HID_REPORT) 393 return p_rpt; 394 395 if (mode == BTA_HH_PROTO_BOOT_MODE && 396 (p_rpt->uuid >= GATT_UUID_HID_BT_KB_INPUT && 397 p_rpt->uuid <= GATT_UUID_HID_BT_MOUSE_INPUT)) 398 return p_rpt; 399 } 400 } 401 return NULL; 402 } 403 404 /******************************************************************************* 405 * 406 * Function bta_hh_le_find_alloc_report_entry 407 * 408 * Description find or allocate a report entry in the HID service report 409 * list. 410 * 411 ******************************************************************************/ 412 tBTA_HH_LE_RPT* bta_hh_le_find_alloc_report_entry(tBTA_HH_DEV_CB* p_cb, 413 uint8_t srvc_inst_id, 414 uint16_t rpt_uuid, 415 uint8_t inst_id) { 416 uint8_t i, hid_inst_id = srvc_inst_id; 417 tBTA_HH_LE_RPT* p_rpt; 418 419 if (rpt_uuid == GATT_UUID_BATTERY_LEVEL) { 420 hid_inst_id = 421 bta_hh_le_find_service_inst_by_battery_inst_id(p_cb, srvc_inst_id); 422 423 if (hid_inst_id == BTA_HH_IDX_INVALID) return NULL; 424 } 425 p_rpt = &p_cb->hid_srvc.report[0]; 426 427 for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { 428 if (!p_rpt->in_use || 429 (p_rpt->uuid == rpt_uuid && p_rpt->srvc_inst_id == srvc_inst_id && 430 p_rpt->char_inst_id == inst_id)) { 431 if (!p_rpt->in_use) { 432 p_rpt->in_use = true; 433 p_rpt->index = i; 434 p_rpt->srvc_inst_id = srvc_inst_id; 435 p_rpt->char_inst_id = inst_id; 436 p_rpt->uuid = rpt_uuid; 437 438 /* assign report type */ 439 for (i = 0; i < BTA_LE_HID_RTP_UUID_MAX; i++) { 440 if (bta_hh_uuid_to_rtp_type[i][0] == rpt_uuid) { 441 p_rpt->rpt_type = (tBTA_HH_RPT_TYPE)bta_hh_uuid_to_rtp_type[i][1]; 442 443 if (rpt_uuid == GATT_UUID_HID_BT_KB_INPUT || 444 rpt_uuid == GATT_UUID_HID_BT_KB_OUTPUT) 445 p_rpt->rpt_id = BTA_HH_KEYBD_RPT_ID; 446 447 if (rpt_uuid == GATT_UUID_HID_BT_MOUSE_INPUT) 448 p_rpt->rpt_id = BTA_HH_MOUSE_RPT_ID; 449 450 break; 451 } 452 } 453 } 454 return p_rpt; 455 } 456 } 457 return NULL; 458 } 459 460 static const tBTA_GATTC_DESCRIPTOR* find_descriptor_by_short_uuid( 461 uint16_t conn_id, uint16_t char_handle, uint16_t short_uuid) { 462 const tBTA_GATTC_CHARACTERISTIC* p_char = 463 BTA_GATTC_GetCharacteristic(conn_id, char_handle); 464 465 if (!p_char) { 466 LOG_WARN(LOG_TAG, "%s No such characteristic: %d", __func__, char_handle); 467 return NULL; 468 } 469 470 for (const tBTA_GATTC_DESCRIPTOR& desc : p_char->descriptors) { 471 if (desc.uuid == Uuid::From16Bit(short_uuid)) return &desc; 472 } 473 474 return NULL; 475 } 476 477 /******************************************************************************* 478 * 479 * Function bta_hh_le_read_char_descriptor 480 * 481 * Description read characteristic descriptor 482 * 483 ******************************************************************************/ 484 static tBTA_HH_STATUS bta_hh_le_read_char_descriptor(tBTA_HH_DEV_CB* p_cb, 485 uint16_t char_handle, 486 uint16_t short_uuid, 487 GATT_READ_OP_CB cb, 488 void* cb_data) { 489 const tBTA_GATTC_DESCRIPTOR* p_desc = 490 find_descriptor_by_short_uuid(p_cb->conn_id, char_handle, short_uuid); 491 if (!p_desc) return BTA_HH_ERR; 492 493 BtaGattQueue::ReadDescriptor(p_cb->conn_id, p_desc->handle, cb, cb_data); 494 return BTA_HH_OK; 495 } 496 497 /******************************************************************************* 498 * 499 * Function bta_hh_le_save_report_ref 500 * 501 * Description save report reference information and move to next one. 502 * 503 * Parameters: 504 * 505 ******************************************************************************/ 506 void bta_hh_le_save_report_ref(tBTA_HH_DEV_CB* p_dev_cb, tBTA_HH_LE_RPT* p_rpt, 507 tGATT_STATUS status, uint8_t* value, 508 uint16_t len) { 509 if (status == GATT_INSUF_AUTHENTICATION) { 510 /* close connection right away */ 511 p_dev_cb->status = BTA_HH_ERR_AUTH_FAILED; 512 /* close the connection and report service discovery complete with error */ 513 bta_hh_le_api_disc_act(p_dev_cb); 514 return; 515 } 516 517 /* if the length of the descriptor value is right, parse it */ 518 if (status == GATT_SUCCESS && len == 2) { 519 uint8_t* pp = value; 520 521 STREAM_TO_UINT8(p_rpt->rpt_id, pp); 522 STREAM_TO_UINT8(p_rpt->rpt_type, pp); 523 524 if (p_rpt->rpt_type > BTA_HH_RPTT_FEATURE) /* invalid report type */ 525 p_rpt->rpt_type = BTA_HH_RPTT_RESRV; 526 527 #if (BTA_HH_DEBUG == TRUE) 528 APPL_TRACE_DEBUG("%s: report ID: %d", __func__, p_rpt->rpt_id); 529 #endif 530 tBTA_HH_RPT_CACHE_ENTRY rpt_entry; 531 rpt_entry.rpt_id = p_rpt->rpt_id; 532 rpt_entry.rpt_type = p_rpt->rpt_type; 533 rpt_entry.rpt_uuid = p_rpt->uuid; 534 rpt_entry.srvc_inst_id = p_rpt->srvc_inst_id; 535 rpt_entry.char_inst_id = p_rpt->char_inst_id; 536 537 bta_hh_le_co_rpt_info(p_dev_cb->addr, &rpt_entry, p_dev_cb->app_id); 538 } 539 540 if (p_rpt->index < BTA_HH_LE_RPT_MAX - 1) 541 p_rpt++; 542 else 543 p_rpt = NULL; 544 } 545 546 /******************************************************************************* 547 * 548 * Function bta_hh_le_register_input_notif 549 * 550 * Description Register for all notifications for the report applicable 551 * for the protocol mode. 552 * 553 * Parameters: 554 * 555 ******************************************************************************/ 556 void bta_hh_le_register_input_notif(tBTA_HH_DEV_CB* p_dev_cb, 557 uint8_t proto_mode, bool register_ba) { 558 tBTA_HH_LE_RPT* p_rpt = &p_dev_cb->hid_srvc.report[0]; 559 560 #if (BTA_HH_DEBUG == TRUE) 561 APPL_TRACE_DEBUG("%s: bta_hh_le_register_input_notif mode: %d", __func__, 562 proto_mode); 563 #endif 564 565 for (int i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { 566 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) { 567 if (register_ba && p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) { 568 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 569 p_rpt->char_inst_id); 570 } 571 /* boot mode, deregister report input notification */ 572 else if (proto_mode == BTA_HH_PROTO_BOOT_MODE) { 573 if (p_rpt->uuid == GATT_UUID_HID_REPORT && 574 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { 575 APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__, 576 p_rpt->rpt_id); 577 BTA_GATTC_DeregisterForNotifications( 578 bta_hh_cb.gatt_if, p_dev_cb->addr, p_rpt->char_inst_id); 579 } 580 /* register boot reports notification */ 581 else if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 582 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) { 583 APPL_TRACE_DEBUG("%s <--- Register Boot Report ID: %d", __func__, 584 p_rpt->rpt_id); 585 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 586 p_rpt->char_inst_id); 587 } 588 } else if (proto_mode == BTA_HH_PROTO_RPT_MODE) { 589 if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 590 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) && 591 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { 592 APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__, 593 p_rpt->rpt_id); 594 BTA_GATTC_DeregisterForNotifications( 595 bta_hh_cb.gatt_if, p_dev_cb->addr, p_rpt->char_inst_id); 596 } else if (p_rpt->uuid == GATT_UUID_HID_REPORT && 597 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { 598 APPL_TRACE_DEBUG("%s <--- Register Report ID: %d", __func__, 599 p_rpt->rpt_id); 600 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 601 p_rpt->char_inst_id); 602 } 603 } 604 /* 605 else unknow protocol mode */ 606 } 607 } 608 } 609 610 /******************************************************************************* 611 * 612 * Function bta_hh_le_deregister_input_notif 613 * 614 * Description Deregister all notifications 615 * 616 ******************************************************************************/ 617 void bta_hh_le_deregister_input_notif(tBTA_HH_DEV_CB* p_dev_cb) { 618 tBTA_HH_LE_RPT* p_rpt = &p_dev_cb->hid_srvc.report[0]; 619 620 for (uint8_t i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { 621 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) { 622 if (p_rpt->uuid == GATT_UUID_HID_REPORT && 623 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { 624 APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__, 625 p_rpt->rpt_id); 626 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 627 p_rpt->char_inst_id); 628 } else if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 629 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) && 630 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { 631 APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__, 632 p_rpt->rpt_id); 633 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 634 p_rpt->char_inst_id); 635 } 636 } 637 } 638 } 639 640 /******************************************************************************* 641 * 642 * Function bta_hh_le_open_cmpl 643 * 644 * Description HID over GATT connection sucessfully opened 645 * 646 ******************************************************************************/ 647 void bta_hh_le_open_cmpl(tBTA_HH_DEV_CB* p_cb) { 648 if (p_cb->disc_active == BTA_HH_LE_DISC_NONE) { 649 #if (BTA_HH_DEBUG == TRUE) 650 bta_hh_le_hid_report_dbg(p_cb); 651 #endif 652 bta_hh_le_register_input_notif(p_cb, p_cb->mode, true); 653 bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL); 654 655 #if (BTA_HH_LE_RECONN == TRUE) 656 if (p_cb->status == BTA_HH_OK) { 657 bta_hh_le_add_dev_bg_conn(p_cb, true); 658 } 659 #endif 660 } 661 } 662 663 /******************************************************************************* 664 * 665 * Function bta_hh_le_write_ccc 666 * 667 * Description Utility function to find and write client configuration of 668 * a characteristic 669 * 670 ******************************************************************************/ 671 bool bta_hh_le_write_ccc(tBTA_HH_DEV_CB* p_cb, uint8_t char_handle, 672 uint16_t clt_cfg_value, GATT_WRITE_OP_CB cb, 673 void* cb_data) { 674 const tBTA_GATTC_DESCRIPTOR* p_desc = find_descriptor_by_short_uuid( 675 p_cb->conn_id, char_handle, GATT_UUID_CHAR_CLIENT_CONFIG); 676 if (!p_desc) return false; 677 678 vector<uint8_t> value(2); 679 uint8_t* ptr = value.data(); 680 UINT16_TO_STREAM(ptr, clt_cfg_value); 681 682 BtaGattQueue::WriteDescriptor(p_cb->conn_id, p_desc->handle, std::move(value), 683 GATT_WRITE, cb, cb_data); 684 return true; 685 } 686 687 bool bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB* p_cb); 688 689 static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status, 690 uint16_t handle, void* data) { 691 uint8_t srvc_inst_id, hid_inst_id; 692 693 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 694 const tBTA_GATTC_CHARACTERISTIC* characteristic = 695 BTA_GATTC_GetOwningCharacteristic(conn_id, handle); 696 uint16_t char_uuid = characteristic->uuid.As16Bit(); 697 698 srvc_inst_id = BTA_GATTC_GetOwningService(conn_id, handle)->handle; 699 hid_inst_id = srvc_inst_id; 700 switch (char_uuid) { 701 case GATT_UUID_BATTERY_LEVEL: /* battery level clt cfg registered */ 702 hid_inst_id = bta_hh_le_find_service_inst_by_battery_inst_id( 703 p_dev_cb, srvc_inst_id); 704 /* FALLTHROUGH */ 705 case GATT_UUID_HID_BT_KB_INPUT: 706 case GATT_UUID_HID_BT_MOUSE_INPUT: 707 case GATT_UUID_HID_REPORT: 708 if (status == GATT_SUCCESS) 709 p_dev_cb->hid_srvc.report[p_dev_cb->clt_cfg_idx].client_cfg_value = 710 GATT_CLT_CONFIG_NOTIFICATION; 711 p_dev_cb->clt_cfg_idx++; 712 bta_hh_le_write_rpt_clt_cfg(p_dev_cb); 713 break; 714 715 default: 716 APPL_TRACE_ERROR("Unknown char ID clt cfg: 0x%04x", char_uuid); 717 } 718 } 719 /******************************************************************************* 720 * 721 * Function bta_hh_le_write_rpt_clt_cfg 722 * 723 * Description write client configuration. This is only for input report 724 * enable all input notification upon connection open. 725 * 726 ******************************************************************************/ 727 bool bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB* p_cb) { 728 uint8_t i; 729 tBTA_HH_LE_RPT* p_rpt = &p_cb->hid_srvc.report[p_cb->clt_cfg_idx]; 730 731 for (i = p_cb->clt_cfg_idx; i < BTA_HH_LE_RPT_MAX && p_rpt->in_use; 732 i++, p_rpt++) { 733 /* enable notification for all input report, regardless mode */ 734 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) { 735 if (bta_hh_le_write_ccc(p_cb, p_rpt->char_inst_id, 736 GATT_CLT_CONFIG_NOTIFICATION, 737 write_rpt_ctl_cfg_cb, p_cb)) { 738 p_cb->clt_cfg_idx = i; 739 return true; 740 } 741 } 742 } 743 p_cb->clt_cfg_idx = 0; 744 745 /* client configuration is completed, send open callback */ 746 if (p_cb->state == BTA_HH_W4_CONN_ST) { 747 p_cb->disc_active &= ~BTA_HH_LE_DISC_HIDS; 748 749 bta_hh_le_open_cmpl(p_cb); 750 } 751 return false; 752 } 753 754 static void write_proto_mode_cb(uint16_t conn_id, tGATT_STATUS status, 755 uint16_t handle, void* data) { 756 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 757 758 if (p_dev_cb->state == BTA_HH_CONN_ST) { 759 /* Set protocol finished in CONN state*/ 760 761 uint16_t cb_evt = p_dev_cb->w4_evt; 762 if (cb_evt == 0) return; 763 764 tBTA_HH_CBDATA cback_data; 765 766 cback_data.handle = p_dev_cb->hid_handle; 767 cback_data.status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR; 768 769 if (status == GATT_SUCCESS) 770 bta_hh_le_register_input_notif(p_dev_cb, p_dev_cb->mode, false); 771 772 p_dev_cb->w4_evt = 0; 773 (*bta_hh_cb.p_cback)(cb_evt, (tBTA_HH*)&cback_data); 774 } else if (p_dev_cb->state == BTA_HH_W4_CONN_ST) { 775 p_dev_cb->status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR_PROTO; 776 777 if ((p_dev_cb->disc_active & BTA_HH_LE_DISC_HIDS) == 0) 778 bta_hh_le_open_cmpl(p_dev_cb); 779 } 780 } 781 782 /******************************************************************************* 783 * 784 * Function bta_hh_le_set_protocol_mode 785 * 786 * Description Set remote device protocol mode. 787 * 788 ******************************************************************************/ 789 bool bta_hh_le_set_protocol_mode(tBTA_HH_DEV_CB* p_cb, 790 tBTA_HH_PROTO_MODE mode) { 791 tBTA_HH_CBDATA cback_data; 792 793 APPL_TRACE_DEBUG("%s attempt mode: %s", __func__, 794 (mode == BTA_HH_PROTO_RPT_MODE) ? "Report" : "Boot"); 795 796 cback_data.handle = p_cb->hid_handle; 797 /* boot mode is not supported in the remote device */ 798 if (p_cb->hid_srvc.proto_mode_handle == 0) { 799 p_cb->mode = BTA_HH_PROTO_RPT_MODE; 800 801 if (mode == BTA_HH_PROTO_BOOT_MODE) { 802 APPL_TRACE_ERROR("Set Boot Mode failed!! No PROTO_MODE Char!"); 803 cback_data.status = BTA_HH_ERR; 804 } else { 805 /* if set to report mode, need to de-register all input report 806 * notification */ 807 bta_hh_le_register_input_notif(p_cb, p_cb->mode, false); 808 cback_data.status = BTA_HH_OK; 809 } 810 if (p_cb->state == BTA_HH_W4_CONN_ST) { 811 p_cb->status = 812 (cback_data.status == BTA_HH_OK) ? BTA_HH_OK : BTA_HH_ERR_PROTO; 813 } else 814 (*bta_hh_cb.p_cback)(BTA_HH_SET_PROTO_EVT, (tBTA_HH*)&cback_data); 815 } else if (p_cb->mode != mode) { 816 p_cb->mode = mode; 817 mode = (mode == BTA_HH_PROTO_BOOT_MODE) ? BTA_HH_LE_PROTO_BOOT_MODE 818 : BTA_HH_LE_PROTO_REPORT_MODE; 819 820 BtaGattQueue::WriteCharacteristic( 821 p_cb->conn_id, p_cb->hid_srvc.proto_mode_handle, {mode}, 822 GATT_WRITE_NO_RSP, write_proto_mode_cb, p_cb); 823 return true; 824 } 825 826 return false; 827 } 828 829 /******************************************************************************* 830 * Function get_protocol_mode_cb 831 * 832 * Description Process the Read protocol mode, send GET_PROTO_EVT to 833 * application with the protocol mode. 834 * 835 ******************************************************************************/ 836 static void get_protocol_mode_cb(uint16_t conn_id, tGATT_STATUS status, 837 uint16_t handle, uint16_t len, uint8_t* value, 838 void* data) { 839 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 840 tBTA_HH_HSDATA hs_data; 841 842 hs_data.status = BTA_HH_ERR; 843 hs_data.handle = p_dev_cb->hid_handle; 844 hs_data.rsp_data.proto_mode = p_dev_cb->mode; 845 846 if (status == GATT_SUCCESS && len) { 847 hs_data.status = BTA_HH_OK; 848 /* match up BTE/BTA report/boot mode def*/ 849 hs_data.rsp_data.proto_mode = *(value); 850 /* LE repot mode is the opposite value of BR/EDR report mode, flip it here 851 */ 852 if (hs_data.rsp_data.proto_mode == 0) 853 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_BOOT_MODE; 854 else 855 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE; 856 857 p_dev_cb->mode = hs_data.rsp_data.proto_mode; 858 } 859 860 #if (BTA_HH_DEBUG == TRUE) 861 APPL_TRACE_DEBUG("LE GET_PROTOCOL Mode = [%s]", 862 (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) 863 ? "Report" 864 : "Boot"); 865 #endif 866 867 p_dev_cb->w4_evt = 0; 868 (*bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH*)&hs_data); 869 } 870 871 /******************************************************************************* 872 * 873 * Function bta_hh_le_get_protocol_mode 874 * 875 * Description Get remote device protocol mode. 876 * 877 ******************************************************************************/ 878 void bta_hh_le_get_protocol_mode(tBTA_HH_DEV_CB* p_cb) { 879 tBTA_HH_HSDATA hs_data; 880 p_cb->w4_evt = BTA_HH_GET_PROTO_EVT; 881 882 if (p_cb->hid_srvc.in_use && p_cb->hid_srvc.proto_mode_handle != 0) { 883 BtaGattQueue::ReadCharacteristic(p_cb->conn_id, 884 p_cb->hid_srvc.proto_mode_handle, 885 get_protocol_mode_cb, p_cb); 886 return; 887 } 888 889 /* no service support protocol_mode, by default report mode */ 890 hs_data.status = BTA_HH_OK; 891 hs_data.handle = p_cb->hid_handle; 892 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE; 893 p_cb->w4_evt = 0; 894 (*bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH*)&hs_data); 895 } 896 897 /******************************************************************************* 898 * 899 * Function bta_hh_le_dis_cback 900 * 901 * Description DIS read complete callback 902 * 903 * Parameters: 904 * 905 ******************************************************************************/ 906 void bta_hh_le_dis_cback(const RawAddress& addr, tDIS_VALUE* p_dis_value) { 907 tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(addr); 908 909 if (p_cb == NULL || p_dis_value == NULL) { 910 APPL_TRACE_ERROR("received unexpected/error DIS callback"); 911 return; 912 } 913 914 p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS; 915 /* plug in the PnP info for this device */ 916 if (p_dis_value->attr_mask & DIS_ATTR_PNP_ID_BIT) { 917 #if (BTA_HH_DEBUG == TRUE) 918 APPL_TRACE_DEBUG( 919 "Plug in PnP info: product_id = %02x, vendor_id = %04x, version = %04x", 920 p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.vendor_id, 921 p_dis_value->pnp_id.product_version); 922 #endif 923 p_cb->dscp_info.product_id = p_dis_value->pnp_id.product_id; 924 p_cb->dscp_info.vendor_id = p_dis_value->pnp_id.vendor_id; 925 p_cb->dscp_info.version = p_dis_value->pnp_id.product_version; 926 } 927 bta_hh_le_open_cmpl(p_cb); 928 } 929 930 /******************************************************************************* 931 * 932 * Function bta_hh_le_pri_service_discovery 933 * 934 * Description Initialize GATT discovery on the remote LE HID device by 935 * opening a GATT connection first. 936 * 937 * Parameters: 938 * 939 ******************************************************************************/ 940 void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB* p_cb) { 941 bta_hh_le_co_reset_rpt_cache(p_cb->addr, p_cb->app_id); 942 943 p_cb->disc_active |= (BTA_HH_LE_DISC_HIDS | BTA_HH_LE_DISC_DIS); 944 945 /* read DIS info */ 946 if (!DIS_ReadDISInfo(p_cb->addr, bta_hh_le_dis_cback, DIS_ATTR_PNP_ID_BIT)) { 947 APPL_TRACE_ERROR("read DIS failed"); 948 p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS; 949 } 950 951 /* in parallel */ 952 /* start primary service discovery for HID service */ 953 Uuid pri_srvc = Uuid::From16Bit(UUID_SERVCLASS_LE_HID); 954 BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &pri_srvc); 955 return; 956 } 957 958 /******************************************************************************* 959 * 960 * Function bta_hh_le_encrypt_cback 961 * 962 * Description link encryption complete callback for bond verification. 963 * 964 * Returns None 965 * 966 ******************************************************************************/ 967 void bta_hh_le_encrypt_cback(const RawAddress* bd_addr, 968 UNUSED_ATTR tGATT_TRANSPORT transport, 969 UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) { 970 uint8_t idx = bta_hh_find_cb(*bd_addr); 971 tBTA_HH_DEV_CB* p_dev_cb; 972 973 if (idx != BTA_HH_IDX_INVALID) 974 p_dev_cb = &bta_hh_cb.kdev[idx]; 975 else { 976 APPL_TRACE_ERROR("unexpected encryption callback, ignore"); 977 return; 978 } 979 p_dev_cb->status = (result == BTM_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR_SEC; 980 p_dev_cb->reason = result; 981 982 bta_hh_sm_execute(p_dev_cb, BTA_HH_ENC_CMPL_EVT, NULL); 983 } 984 985 /******************************************************************************* 986 * 987 * Function bta_hh_security_cmpl 988 * 989 * Description Security check completed, start the service discovery 990 * if no cache available, otherwise report connection open 991 * completed 992 * 993 * Parameters: 994 * 995 ******************************************************************************/ 996 void bta_hh_security_cmpl(tBTA_HH_DEV_CB* p_cb, 997 UNUSED_ATTR tBTA_HH_DATA* p_buf) { 998 APPL_TRACE_DEBUG("%s", __func__); 999 if (p_cb->status == BTA_HH_OK) { 1000 if (!p_cb->hid_srvc.in_use) { 1001 APPL_TRACE_DEBUG("bta_hh_security_cmpl no reports loaded, try to load"); 1002 1003 /* start loading the cache if not in stack */ 1004 // TODO(jpawlowski): cache storage is broken, fix it 1005 // tBTA_HH_RPT_CACHE_ENTRY *p_rpt_cache; 1006 // uint8_t num_rpt = 0; 1007 // if ((p_rpt_cache = bta_hh_le_co_cache_load(p_cb->addr, &num_rpt, 1008 // p_cb->app_id)) != NULL) 1009 // { 1010 // bta_hh_process_cache_rpt(p_cb, p_rpt_cache, num_rpt); 1011 // } 1012 } 1013 /* discovery has been done for HID service */ 1014 if (p_cb->app_id != 0 && p_cb->hid_srvc.in_use) { 1015 APPL_TRACE_DEBUG("%s: discovery has been done for HID service", __func__); 1016 /* configure protocol mode */ 1017 if (!bta_hh_le_set_protocol_mode(p_cb, p_cb->mode)) { 1018 bta_hh_le_open_cmpl(p_cb); 1019 } 1020 } 1021 /* start primary service discovery for HID service */ 1022 else { 1023 APPL_TRACE_DEBUG("%s: Starting service discovery", __func__); 1024 bta_hh_le_pri_service_discovery(p_cb); 1025 } 1026 } else { 1027 APPL_TRACE_ERROR("%s() - encryption failed; status=0x%04x, reason=0x%04x", 1028 __func__, p_cb->status, p_cb->reason); 1029 if (!(p_cb->status == BTA_HH_ERR_SEC && p_cb->reason == BTM_ERR_PROCESSING)) 1030 bta_hh_le_api_disc_act(p_cb); 1031 } 1032 } 1033 1034 /******************************************************************************* 1035 * 1036 * Function bta_hh_le_notify_enc_cmpl 1037 * 1038 * Description process GATT encryption complete event 1039 * 1040 * Returns 1041 * 1042 ******************************************************************************/ 1043 void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_buf) { 1044 if (p_cb == NULL || !p_cb->security_pending || p_buf == NULL || 1045 p_buf->le_enc_cmpl.client_if != bta_hh_cb.gatt_if) { 1046 return; 1047 } 1048 1049 p_cb->security_pending = false; 1050 bta_hh_start_security(p_cb, NULL); 1051 } 1052 1053 /******************************************************************************* 1054 * 1055 * Function bta_hh_clear_service_cache 1056 * 1057 * Description clear the service cache 1058 * 1059 * Parameters: 1060 * 1061 ******************************************************************************/ 1062 void bta_hh_clear_service_cache(tBTA_HH_DEV_CB* p_cb) { 1063 tBTA_HH_LE_HID_SRVC* p_hid_srvc = &p_cb->hid_srvc; 1064 1065 p_cb->app_id = 0; 1066 p_cb->dscp_info.descriptor.dsc_list = NULL; 1067 1068 osi_free_and_reset((void**)&p_hid_srvc->rpt_map); 1069 memset(p_hid_srvc, 0, sizeof(tBTA_HH_LE_HID_SRVC)); 1070 } 1071 1072 /******************************************************************************* 1073 * 1074 * Function bta_hh_start_security 1075 * 1076 * Description start the security check of the established connection 1077 * 1078 * Parameters: 1079 * 1080 ******************************************************************************/ 1081 void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb, 1082 UNUSED_ATTR tBTA_HH_DATA* p_buf) { 1083 uint8_t sec_flag = 0; 1084 tBTM_SEC_DEV_REC* p_dev_rec; 1085 1086 p_dev_rec = btm_find_dev(p_cb->addr); 1087 if (p_dev_rec) { 1088 if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING || 1089 p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING) { 1090 /* if security collision happened, wait for encryption done */ 1091 p_cb->security_pending = true; 1092 return; 1093 } 1094 } 1095 1096 /* verify bond */ 1097 BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE); 1098 1099 /* if link has been encrypted */ 1100 if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) { 1101 p_cb->status = BTA_HH_OK; 1102 bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL); 1103 } 1104 /* if bonded and link not encrypted */ 1105 else if (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) { 1106 sec_flag = BTM_BLE_SEC_ENCRYPT; 1107 p_cb->status = BTA_HH_ERR_AUTH_FAILED; 1108 BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, 1109 NULL, sec_flag); 1110 } 1111 /* unbonded device, report security error here */ 1112 else if (p_cb->sec_mask != BTA_SEC_NONE) { 1113 sec_flag = BTM_BLE_SEC_ENCRYPT_NO_MITM; 1114 p_cb->status = BTA_HH_ERR_AUTH_FAILED; 1115 bta_hh_clear_service_cache(p_cb); 1116 BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, 1117 NULL, sec_flag); 1118 } 1119 /* otherwise let it go through */ 1120 else { 1121 bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL); 1122 } 1123 } 1124 1125 /******************************************************************************* 1126 * 1127 * Function bta_hh_gatt_open 1128 * 1129 * Description process GATT open event. 1130 * 1131 * Parameters: 1132 * 1133 ******************************************************************************/ 1134 void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_buf) { 1135 tBTA_GATTC_OPEN* p_data = &p_buf->le_open; 1136 uint8_t* p2; 1137 1138 /* if received invalid callback data , ignore it */ 1139 if (p_cb == NULL || p_data == NULL) return; 1140 1141 p2 = p_data->remote_bda.address; 1142 1143 APPL_TRACE_DEBUG( 1144 "bta_hh_gatt_open BTA_GATTC_OPEN_EVT bda= [%08x%04x] status =%d", 1145 ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]), 1146 ((p2[4]) << 8) + p2[5], p_data->status); 1147 1148 if (p_data->status == GATT_SUCCESS) { 1149 p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index); 1150 if (p_cb->hid_handle == BTA_HH_IDX_INVALID) { 1151 p_cb->conn_id = p_data->conn_id; 1152 bta_hh_le_api_disc_act(p_cb); 1153 return; 1154 } 1155 p_cb->is_le_device = true; 1156 p_cb->in_use = true; 1157 p_cb->conn_id = p_data->conn_id; 1158 1159 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; 1160 1161 BtaGattQueue::Clean(p_cb->conn_id); 1162 1163 #if (BTA_HH_DEBUG == TRUE) 1164 APPL_TRACE_DEBUG("hid_handle = %2x conn_id = %04x cb_index = %d", 1165 p_cb->hid_handle, p_cb->conn_id, p_cb->index); 1166 #endif 1167 1168 bta_hh_sm_execute(p_cb, BTA_HH_START_ENC_EVT, NULL); 1169 1170 } else { 1171 /* open failure */ 1172 tBTA_HH_DATA bta_hh_data; 1173 bta_hh_data.status = BTA_HH_ERR; 1174 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); 1175 } 1176 } 1177 1178 /******************************************************************************* 1179 * 1180 * Function bta_hh_le_close 1181 * 1182 * Description This function process the GATT close event and post it as a 1183 * BTA HH internal event 1184 * 1185 * Parameters: 1186 * 1187 ******************************************************************************/ 1188 void bta_hh_le_close(tBTA_GATTC_CLOSE* p_data) { 1189 tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->remote_bda); 1190 uint16_t sm_event = BTA_HH_GATT_CLOSE_EVT; 1191 1192 if (p_dev_cb != NULL) { 1193 tBTA_HH_LE_CLOSE* p_buf = 1194 (tBTA_HH_LE_CLOSE*)osi_malloc(sizeof(tBTA_HH_LE_CLOSE)); 1195 p_buf->hdr.event = sm_event; 1196 p_buf->hdr.layer_specific = (uint16_t)p_dev_cb->hid_handle; 1197 p_buf->conn_id = p_data->conn_id; 1198 p_buf->reason = p_data->reason; 1199 1200 p_dev_cb->conn_id = GATT_INVALID_CONN_ID; 1201 p_dev_cb->security_pending = false; 1202 bta_sys_sendmsg(p_buf); 1203 } 1204 } 1205 1206 /******************************************************************************* 1207 * 1208 * Function bta_hh_le_gatt_disc_cmpl 1209 * 1210 * Description Check to see if the remote device is a LE only device 1211 * 1212 * Parameters: 1213 * 1214 ******************************************************************************/ 1215 void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB* p_cb, tBTA_HH_STATUS status) { 1216 APPL_TRACE_DEBUG("bta_hh_le_gatt_disc_cmpl "); 1217 1218 /* if open sucessful or protocol mode not desired, keep the connection open 1219 * but inform app */ 1220 if (status == BTA_HH_OK || status == BTA_HH_ERR_PROTO) { 1221 /* assign a special APP ID temp, since device type unknown */ 1222 p_cb->app_id = BTA_HH_APP_ID_LE; 1223 1224 /* set report notification configuration */ 1225 p_cb->clt_cfg_idx = 0; 1226 bta_hh_le_write_rpt_clt_cfg(p_cb); 1227 } else /* error, close the GATT connection */ 1228 { 1229 /* close GATT connection if it's on */ 1230 bta_hh_le_api_disc_act(p_cb); 1231 } 1232 } 1233 1234 static void read_hid_info_cb(uint16_t conn_id, tGATT_STATUS status, 1235 uint16_t handle, uint16_t len, uint8_t* value, 1236 void* data) { 1237 if (status != GATT_SUCCESS) { 1238 APPL_TRACE_ERROR("%s: error: %d", __func__, status); 1239 return; 1240 } 1241 1242 if (len != 4) { 1243 APPL_TRACE_ERROR("%s: wrong length: %d", __func__, len); 1244 return; 1245 } 1246 1247 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1248 uint8_t* pp = value; 1249 /* save device information */ 1250 STREAM_TO_UINT16(p_dev_cb->dscp_info.version, pp); 1251 STREAM_TO_UINT8(p_dev_cb->dscp_info.ctry_code, pp); 1252 STREAM_TO_UINT8(p_dev_cb->dscp_info.flag, pp); 1253 } 1254 1255 static void read_hid_report_map_cb(uint16_t conn_id, tGATT_STATUS status, 1256 uint16_t handle, uint16_t len, 1257 uint8_t* value, void* data) { 1258 if (status != GATT_SUCCESS) { 1259 APPL_TRACE_ERROR("%s: error reading characteristic: %d", __func__, status); 1260 return; 1261 } 1262 1263 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1264 tBTA_HH_LE_HID_SRVC* p_srvc = &p_dev_cb->hid_srvc; 1265 1266 osi_free_and_reset((void**)&p_srvc->rpt_map); 1267 1268 if (len > 0) { 1269 p_srvc->rpt_map = (uint8_t*)osi_malloc(len); 1270 1271 uint8_t* pp = value; 1272 STREAM_TO_ARRAY(p_srvc->rpt_map, pp, len); 1273 p_srvc->descriptor.dl_len = len; 1274 p_srvc->descriptor.dsc_list = p_dev_cb->hid_srvc.rpt_map; 1275 } 1276 } 1277 1278 static void read_ext_rpt_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status, 1279 uint16_t handle, uint16_t len, 1280 uint8_t* value, void* data) { 1281 if (status != GATT_SUCCESS) { 1282 APPL_TRACE_ERROR("%s: error: %d", __func__, status); 1283 return; 1284 } 1285 1286 /* if the length of the descriptor value is right, parse it assume it's a 16 1287 * bits UUID */ 1288 if (len != Uuid::kNumBytes16) { 1289 APPL_TRACE_ERROR("%s: we support only 16bit UUID: %d", __func__, len); 1290 return; 1291 } 1292 1293 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1294 uint8_t* pp = value; 1295 1296 STREAM_TO_UINT16(p_dev_cb->hid_srvc.ext_rpt_ref, pp); 1297 1298 #if (BTA_HH_DEBUG == TRUE) 1299 APPL_TRACE_DEBUG("%s: External Report Reference UUID 0x%04x", __func__, 1300 p_dev_cb->hid_srvc.ext_rpt_ref); 1301 #endif 1302 } 1303 1304 static void read_report_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status, 1305 uint16_t handle, uint16_t len, 1306 uint8_t* value, void* data) { 1307 if (status != GATT_SUCCESS) { 1308 APPL_TRACE_ERROR("%s: error: %d", __func__, status); 1309 return; 1310 } 1311 1312 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1313 const tBTA_GATTC_DESCRIPTOR* p_desc = 1314 BTA_GATTC_GetDescriptor(conn_id, handle); 1315 1316 if (!p_desc) { 1317 APPL_TRACE_ERROR("%s: error: descriptor is null!", __func__); 1318 return; 1319 } 1320 1321 const tBTA_GATTC_CHARACTERISTIC* characteristic = 1322 BTA_GATTC_GetOwningCharacteristic(conn_id, handle); 1323 const tBTA_GATTC_SERVICE* service = 1324 BTA_GATTC_GetOwningService(conn_id, characteristic->value_handle); 1325 1326 tBTA_HH_LE_RPT* p_rpt; 1327 p_rpt = bta_hh_le_find_report_entry(p_dev_cb, service->handle, 1328 GATT_UUID_HID_REPORT, 1329 characteristic->value_handle); 1330 if (p_rpt) bta_hh_le_save_report_ref(p_dev_cb, p_rpt, status, value, len); 1331 } 1332 1333 void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status, 1334 uint16_t handle, uint16_t len, uint8_t* value, 1335 void* data) { 1336 if (status != GATT_SUCCESS) { 1337 APPL_TRACE_ERROR("%s: error: %d", __func__, status); 1338 return; 1339 } 1340 1341 if (len != 8) { 1342 APPL_TRACE_ERROR("%s: we support only 16bit UUID: %d", __func__, len); 1343 return; 1344 } 1345 1346 // TODO(jpawlowski): this should be done by GAP profile, remove when GAP is 1347 // fixed. 1348 uint8_t* pp = value; 1349 uint16_t min_interval, max_interval, latency, timeout; 1350 STREAM_TO_UINT16(min_interval, pp); 1351 STREAM_TO_UINT16(max_interval, pp); 1352 STREAM_TO_UINT16(latency, pp); 1353 STREAM_TO_UINT16(timeout, pp); 1354 1355 // Make sure both min, and max are bigger than 11.25ms, lower values can 1356 // introduce audio issues if A2DP is also active. 1357 L2CA_AdjustConnectionIntervals(&min_interval, &max_interval, 1358 BTM_BLE_CONN_INT_MIN_LIMIT); 1359 1360 // If the device has no preferred connection timeout, use the default. 1361 if (timeout == BTM_BLE_CONN_PARAM_UNDEF) timeout = BTM_BLE_CONN_TIMEOUT_DEF; 1362 1363 if (min_interval < BTM_BLE_CONN_INT_MIN || 1364 min_interval > BTM_BLE_CONN_INT_MAX || 1365 max_interval < BTM_BLE_CONN_INT_MIN || 1366 max_interval > BTM_BLE_CONN_INT_MAX || 1367 latency > BTM_BLE_CONN_LATENCY_MAX || 1368 timeout < BTM_BLE_CONN_SUP_TOUT_MIN || 1369 timeout > BTM_BLE_CONN_SUP_TOUT_MAX || max_interval < min_interval) { 1370 APPL_TRACE_ERROR( 1371 "%s: Invalid connection parameters. min=%d, max=%d, latency=%d, " 1372 "timeout=%d", 1373 __func__, min_interval, max_interval, latency, timeout); 1374 return; 1375 } 1376 1377 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1378 1379 if (interop_match_addr(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S, 1380 (RawAddress*)&p_dev_cb->addr)) { 1381 if (timeout < 300) timeout = 300; 1382 } 1383 1384 BTM_BleSetPrefConnParams(p_dev_cb->addr, min_interval, max_interval, latency, 1385 timeout); 1386 L2CA_UpdateBleConnParams(p_dev_cb->addr, min_interval, max_interval, latency, 1387 timeout); 1388 } 1389 1390 /******************************************************************************* 1391 * 1392 * Function bta_hh_le_search_hid_chars 1393 * 1394 * Description This function discover all characteristics a service and 1395 * all descriptors available. 1396 * 1397 * Parameters: 1398 * 1399 ******************************************************************************/ 1400 static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB* p_dev_cb, 1401 const tBTA_GATTC_SERVICE* service) { 1402 tBTA_HH_LE_RPT* p_rpt; 1403 1404 for (const tBTA_GATTC_CHARACTERISTIC& charac : service->characteristics) { 1405 if (!charac.uuid.Is16Bit()) continue; 1406 1407 uint16_t uuid16 = charac.uuid.As16Bit(); 1408 LOG_DEBUG(LOG_TAG, "%s: %s %s", __func__, bta_hh_uuid_to_str(uuid16), 1409 charac.uuid.ToString().c_str()); 1410 1411 switch (uuid16) { 1412 case GATT_UUID_HID_CONTROL_POINT: 1413 p_dev_cb->hid_srvc.control_point_handle = charac.value_handle; 1414 break; 1415 case GATT_UUID_HID_INFORMATION: 1416 /* only one instance per HID service */ 1417 BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, charac.value_handle, 1418 read_hid_info_cb, p_dev_cb); 1419 break; 1420 case GATT_UUID_HID_REPORT_MAP: 1421 /* only one instance per HID service */ 1422 BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, charac.value_handle, 1423 read_hid_report_map_cb, p_dev_cb); 1424 /* descriptor is optional */ 1425 bta_hh_le_read_char_descriptor(p_dev_cb, charac.value_handle, 1426 GATT_UUID_EXT_RPT_REF_DESCR, 1427 read_ext_rpt_ref_desc_cb, p_dev_cb); 1428 break; 1429 1430 case GATT_UUID_HID_REPORT: 1431 p_rpt = bta_hh_le_find_alloc_report_entry( 1432 p_dev_cb, p_dev_cb->hid_srvc.srvc_inst_id, GATT_UUID_HID_REPORT, 1433 charac.value_handle); 1434 if (p_rpt == NULL) { 1435 APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__); 1436 break; 1437 } 1438 1439 if (p_rpt->rpt_type != BTA_HH_RPTT_INPUT) break; 1440 1441 bta_hh_le_read_char_descriptor(p_dev_cb, charac.value_handle, 1442 GATT_UUID_RPT_REF_DESCR, 1443 read_report_ref_desc_cb, p_dev_cb); 1444 break; 1445 1446 /* found boot mode report types */ 1447 case GATT_UUID_HID_BT_KB_OUTPUT: 1448 case GATT_UUID_HID_BT_MOUSE_INPUT: 1449 case GATT_UUID_HID_BT_KB_INPUT: 1450 if (bta_hh_le_find_alloc_report_entry(p_dev_cb, service->handle, uuid16, 1451 charac.value_handle) == NULL) 1452 APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__); 1453 1454 break; 1455 1456 default: 1457 APPL_TRACE_DEBUG("%s: not processing %s 0x%04d", __func__, 1458 bta_hh_uuid_to_str(uuid16), uuid16); 1459 } 1460 } 1461 1462 /* Make sure PROTO_MODE is processed as last */ 1463 for (const tBTA_GATTC_CHARACTERISTIC& charac : service->characteristics) { 1464 if (charac.uuid == Uuid::From16Bit(GATT_UUID_HID_PROTO_MODE)) { 1465 p_dev_cb->hid_srvc.proto_mode_handle = charac.value_handle; 1466 bta_hh_le_set_protocol_mode(p_dev_cb, p_dev_cb->mode); 1467 break; 1468 } 1469 } 1470 } 1471 1472 /******************************************************************************* 1473 * 1474 * Function bta_hh_le_srvc_search_cmpl 1475 * 1476 * Description This function process the GATT service search complete. 1477 * 1478 * Parameters: 1479 * 1480 ******************************************************************************/ 1481 void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL* p_data) { 1482 tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id); 1483 1484 /* service search exception or no HID service is supported on remote */ 1485 if (p_dev_cb == NULL) return; 1486 1487 if (p_data->status != GATT_SUCCESS) { 1488 p_dev_cb->status = BTA_HH_ERR_SDP; 1489 /* close the connection and report service discovery complete with error */ 1490 bta_hh_le_api_disc_act(p_dev_cb); 1491 return; 1492 } 1493 1494 const std::vector<tBTA_GATTC_SERVICE>* services = 1495 BTA_GATTC_GetServices(p_data->conn_id); 1496 1497 bool have_hid = false; 1498 for (const tBTA_GATTC_SERVICE& service : *services) { 1499 if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_LE_HID) && 1500 service.is_primary && !have_hid) { 1501 have_hid = true; 1502 1503 /* found HID primamry service */ 1504 p_dev_cb->hid_srvc.in_use = true; 1505 p_dev_cb->hid_srvc.srvc_inst_id = service.handle; 1506 p_dev_cb->hid_srvc.proto_mode_handle = 0; 1507 p_dev_cb->hid_srvc.control_point_handle = 0; 1508 1509 bta_hh_le_search_hid_chars(p_dev_cb, &service); 1510 1511 APPL_TRACE_DEBUG("%s: have HID service inst_id= %d", __func__, 1512 p_dev_cb->hid_srvc.srvc_inst_id); 1513 } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_SCAN_PARAM)) { 1514 p_dev_cb->scan_refresh_char_handle = 0; 1515 1516 for (const tBTA_GATTC_CHARACTERISTIC& charac : service.characteristics) { 1517 if (charac.uuid == Uuid::From16Bit(GATT_UUID_SCAN_REFRESH)) { 1518 p_dev_cb->scan_refresh_char_handle = charac.value_handle; 1519 1520 if (charac.properties & GATT_CHAR_PROP_BIT_NOTIFY) 1521 p_dev_cb->scps_notify |= BTA_HH_LE_SCPS_NOTIFY_SPT; 1522 else 1523 p_dev_cb->scps_notify = BTA_HH_LE_SCPS_NOTIFY_NONE; 1524 1525 break; 1526 } 1527 } 1528 } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) { 1529 // TODO(jpawlowski): this should be done by GAP profile, remove when GAP 1530 // is fixed. 1531 for (const tBTA_GATTC_CHARACTERISTIC& charac : service.characteristics) { 1532 if (charac.uuid == Uuid::From16Bit(GATT_UUID_GAP_PREF_CONN_PARAM)) { 1533 /* read the char value */ 1534 BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, 1535 charac.value_handle, 1536 read_pref_conn_params_cb, p_dev_cb); 1537 break; 1538 } 1539 } 1540 } 1541 } 1542 1543 bta_hh_le_gatt_disc_cmpl(p_dev_cb, p_dev_cb->status); 1544 } 1545 1546 /******************************************************************************* 1547 * 1548 * Function bta_hh_le_input_rpt_notify 1549 * 1550 * Description process the notificaton event, most likely for input report. 1551 * 1552 * Parameters: 1553 * 1554 ******************************************************************************/ 1555 void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) { 1556 tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id); 1557 uint8_t app_id; 1558 uint8_t* p_buf; 1559 tBTA_HH_LE_RPT* p_rpt; 1560 1561 if (p_dev_cb == NULL) { 1562 APPL_TRACE_ERROR( 1563 "%s: notification received from Unknown device, conn_id: 0x%04x", 1564 __func__, p_data->conn_id); 1565 return; 1566 } 1567 1568 const tBTA_GATTC_CHARACTERISTIC* p_char = 1569 BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, p_data->handle); 1570 if (p_char == NULL) { 1571 APPL_TRACE_ERROR( 1572 "%s: notification received for Unknown Characteristic, conn_id: " 1573 "0x%04x, handle: 0x%04x", 1574 __func__, p_dev_cb->conn_id, p_data->handle); 1575 return; 1576 } 1577 1578 app_id = p_dev_cb->app_id; 1579 1580 p_rpt = 1581 bta_hh_le_find_report_entry(p_dev_cb, p_dev_cb->hid_srvc.srvc_inst_id, 1582 p_char->uuid.As16Bit(), p_char->value_handle); 1583 if (p_rpt == NULL) { 1584 APPL_TRACE_ERROR( 1585 "%s: notification received for Unknown Report, uuid: %s, handle: " 1586 "0x%04x", 1587 __func__, p_char->uuid.ToString().c_str(), p_char->value_handle); 1588 return; 1589 } 1590 1591 if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_MOUSE_INPUT)) 1592 app_id = BTA_HH_APP_ID_MI; 1593 else if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_KB_INPUT)) 1594 app_id = BTA_HH_APP_ID_KB; 1595 1596 APPL_TRACE_DEBUG("Notification received on report ID: %d", p_rpt->rpt_id); 1597 1598 /* need to append report ID to the head of data */ 1599 if (p_rpt->rpt_id != 0) { 1600 p_buf = (uint8_t*)osi_malloc(p_data->len + 1); 1601 1602 p_buf[0] = p_rpt->rpt_id; 1603 memcpy(&p_buf[1], p_data->value, p_data->len); 1604 ++p_data->len; 1605 } else { 1606 p_buf = p_data->value; 1607 } 1608 1609 bta_hh_co_data((uint8_t)p_dev_cb->hid_handle, p_buf, p_data->len, 1610 p_dev_cb->mode, 0, /* no sub class*/ 1611 p_dev_cb->dscp_info.ctry_code, p_dev_cb->addr, app_id); 1612 1613 if (p_buf != p_data->value) osi_free(p_buf); 1614 } 1615 1616 /******************************************************************************* 1617 * 1618 * Function bta_hh_gatt_open_fail 1619 * 1620 * Description action function to process the open fail 1621 * 1622 * Returns void 1623 * 1624 ******************************************************************************/ 1625 void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 1626 tBTA_HH_CONN conn_dat; 1627 1628 /* open failure in the middle of service discovery, clear all services */ 1629 if (p_cb->disc_active & BTA_HH_LE_DISC_HIDS) { 1630 bta_hh_clear_service_cache(p_cb); 1631 } 1632 1633 p_cb->disc_active = BTA_HH_LE_DISC_NONE; 1634 /* Failure in opening connection or GATT discovery failure */ 1635 conn_dat.handle = p_cb->hid_handle; 1636 conn_dat.bda = p_cb->addr; 1637 conn_dat.le_hid = true; 1638 conn_dat.scps_supported = p_cb->scps_supported; 1639 1640 if (p_cb->status == BTA_HH_OK) 1641 conn_dat.status = (p_data->le_close.reason == GATT_CONN_UNKNOWN) 1642 ? p_cb->status 1643 : BTA_HH_ERR; 1644 else 1645 conn_dat.status = p_cb->status; 1646 1647 /* Report OPEN fail event */ 1648 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat); 1649 } 1650 1651 /******************************************************************************* 1652 * 1653 * Function bta_hh_gatt_close 1654 * 1655 * Description action function to process the GATT close int he state 1656 * machine. 1657 * 1658 * Returns void 1659 * 1660 ******************************************************************************/ 1661 void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 1662 tBTA_HH_CBDATA disc_dat = {BTA_HH_OK, 0}; 1663 1664 /* deregister all notification */ 1665 bta_hh_le_deregister_input_notif(p_cb); 1666 /* finaliza device driver */ 1667 bta_hh_co_close(p_cb->hid_handle, p_cb->app_id); 1668 /* update total conn number */ 1669 bta_hh_cb.cnt_num--; 1670 1671 disc_dat.handle = p_cb->hid_handle; 1672 disc_dat.status = p_cb->status; 1673 1674 (*bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, (tBTA_HH*)&disc_dat); 1675 1676 /* if no connection is active and HH disable is signaled, disable service */ 1677 if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) { 1678 bta_hh_disc_cmpl(); 1679 } else { 1680 #if (BTA_HH_LE_RECONN == TRUE) 1681 if (p_data->le_close.reason == GATT_CONN_TIMEOUT) { 1682 bta_hh_le_add_dev_bg_conn(p_cb, false); 1683 } 1684 #endif 1685 } 1686 1687 return; 1688 } 1689 1690 /******************************************************************************* 1691 * 1692 * Function bta_hh_le_api_disc_act 1693 * 1694 * Description initaite a Close API to a remote HID device 1695 * 1696 * Returns void 1697 * 1698 ******************************************************************************/ 1699 void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb) { 1700 if (p_cb->conn_id != GATT_INVALID_CONN_ID) { 1701 BtaGattQueue::Clean(p_cb->conn_id); 1702 BTA_GATTC_Close(p_cb->conn_id); 1703 /* remove device from background connection if intended to disconnect, 1704 do not allow reconnection */ 1705 bta_hh_le_remove_dev_bg_conn(p_cb); 1706 } 1707 } 1708 1709 /******************************************************************************* 1710 * 1711 * Function read_report_cb 1712 * 1713 * Description Process the Read report complete, send GET_REPORT_EVT to 1714 * application with the report data. 1715 * 1716 * Parameters: 1717 * 1718 ******************************************************************************/ 1719 static void read_report_cb(uint16_t conn_id, tGATT_STATUS status, 1720 uint16_t handle, uint16_t len, uint8_t* value, 1721 void* data) { 1722 const tBTA_GATTC_CHARACTERISTIC* p_char = 1723 BTA_GATTC_GetCharacteristic(conn_id, handle); 1724 1725 if (p_char == NULL) return; 1726 1727 uint16_t char_uuid = p_char->uuid.As16Bit(); 1728 1729 if (char_uuid != GATT_UUID_HID_REPORT && 1730 char_uuid != GATT_UUID_HID_BT_KB_INPUT && 1731 char_uuid != GATT_UUID_HID_BT_KB_OUTPUT && 1732 char_uuid != GATT_UUID_HID_BT_MOUSE_INPUT && 1733 char_uuid != GATT_UUID_BATTERY_LEVEL) { 1734 APPL_TRACE_ERROR("%s: Unexpected Read UUID: 0x%04x", __func__, char_uuid); 1735 return; 1736 } 1737 1738 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1739 if (p_dev_cb->w4_evt != BTA_HH_GET_RPT_EVT) { 1740 APPL_TRACE_ERROR("Unexpected READ cmpl, w4_evt = %d", p_dev_cb->w4_evt); 1741 return; 1742 } 1743 1744 /* GET_REPORT */ 1745 BT_HDR* p_buf = NULL; 1746 tBTA_HH_LE_RPT* p_rpt; 1747 tBTA_HH_HSDATA hs_data; 1748 uint8_t* pp; 1749 1750 memset(&hs_data, 0, sizeof(hs_data)); 1751 hs_data.status = BTA_HH_ERR; 1752 hs_data.handle = p_dev_cb->hid_handle; 1753 1754 if (status == GATT_SUCCESS) { 1755 const tBTA_GATTC_SERVICE* p_svc = 1756 BTA_GATTC_GetOwningService(conn_id, p_char->value_handle); 1757 1758 p_rpt = bta_hh_le_find_report_entry(p_dev_cb, p_svc->handle, char_uuid, 1759 p_char->value_handle); 1760 1761 if (p_rpt != NULL && len) { 1762 p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + len + 1); 1763 /* pack data send to app */ 1764 hs_data.status = BTA_HH_OK; 1765 p_buf->len = len + 1; 1766 p_buf->layer_specific = 0; 1767 p_buf->offset = 0; 1768 1769 /* attach report ID as the first byte of the report before sending it to 1770 * USB HID driver */ 1771 pp = (uint8_t*)(p_buf + 1); 1772 UINT8_TO_STREAM(pp, p_rpt->rpt_id); 1773 memcpy(pp, value, len); 1774 1775 hs_data.rsp_data.p_rpt_data = p_buf; 1776 } 1777 } 1778 1779 p_dev_cb->w4_evt = 0; 1780 (*bta_hh_cb.p_cback)(BTA_HH_GET_RPT_EVT, (tBTA_HH*)&hs_data); 1781 1782 osi_free_and_reset((void**)&p_buf); 1783 } 1784 1785 /******************************************************************************* 1786 * 1787 * Function bta_hh_le_get_rpt 1788 * 1789 * Description GET_REPORT on a LE HID Report 1790 * 1791 * Returns void 1792 * 1793 ******************************************************************************/ 1794 void bta_hh_le_get_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type, 1795 uint8_t rpt_id) { 1796 tBTA_HH_LE_RPT* p_rpt = bta_hh_le_find_rpt_by_idtype( 1797 p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id); 1798 1799 if (p_rpt == NULL) { 1800 APPL_TRACE_ERROR("%s: no matching report", __func__); 1801 return; 1802 } 1803 1804 p_cb->w4_evt = BTA_HH_GET_RPT_EVT; 1805 BtaGattQueue::ReadCharacteristic(p_cb->conn_id, p_rpt->char_inst_id, 1806 read_report_cb, p_cb); 1807 } 1808 1809 static void write_report_cb(uint16_t conn_id, tGATT_STATUS status, 1810 uint16_t handle, void* data) { 1811 tBTA_HH_CBDATA cback_data; 1812 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; 1813 uint16_t cb_evt = p_dev_cb->w4_evt; 1814 1815 if (cb_evt == 0) return; 1816 1817 #if (BTA_HH_DEBUG == TRUE) 1818 APPL_TRACE_DEBUG("bta_hh_le_write_cmpl w4_evt: %d", p_dev_cb->w4_evt); 1819 #endif 1820 1821 const tBTA_GATTC_CHARACTERISTIC* p_char = 1822 BTA_GATTC_GetCharacteristic(conn_id, handle); 1823 uint16_t uuid = p_char->uuid.As16Bit(); 1824 if (uuid != GATT_UUID_HID_REPORT && uuid != GATT_UUID_HID_BT_KB_INPUT && 1825 uuid != GATT_UUID_HID_BT_MOUSE_INPUT && 1826 uuid != GATT_UUID_HID_BT_KB_OUTPUT) { 1827 return; 1828 } 1829 1830 /* Set Report finished */ 1831 cback_data.handle = p_dev_cb->hid_handle; 1832 cback_data.status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR; 1833 p_dev_cb->w4_evt = 0; 1834 (*bta_hh_cb.p_cback)(cb_evt, (tBTA_HH*)&cback_data); 1835 } 1836 /******************************************************************************* 1837 * 1838 * Function bta_hh_le_write_rpt 1839 * 1840 * Description SET_REPORT/or DATA output on a LE HID Report 1841 * 1842 * Returns void 1843 * 1844 ******************************************************************************/ 1845 void bta_hh_le_write_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type, 1846 BT_HDR* p_buf, uint16_t w4_evt) { 1847 tBTA_HH_LE_RPT* p_rpt; 1848 uint8_t rpt_id; 1849 1850 if (p_buf == NULL || p_buf->len == 0) { 1851 APPL_TRACE_ERROR("%s: Illegal data", __func__); 1852 return; 1853 } 1854 1855 /* strip report ID from the data */ 1856 uint8_t* vec_start = (uint8_t*)(p_buf + 1) + p_buf->offset; 1857 STREAM_TO_UINT8(rpt_id, vec_start); 1858 vector<uint8_t> value(vec_start, vec_start + p_buf->len - 1); 1859 1860 p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode, 1861 r_type, rpt_id); 1862 if (p_rpt == NULL) { 1863 APPL_TRACE_ERROR("%s: no matching report", __func__); 1864 osi_free(p_buf); 1865 return; 1866 } 1867 1868 p_cb->w4_evt = w4_evt; 1869 1870 const tBTA_GATTC_CHARACTERISTIC* p_char = 1871 BTA_GATTC_GetCharacteristic(p_cb->conn_id, p_rpt->char_inst_id); 1872 1873 tGATT_WRITE_TYPE write_type = GATT_WRITE; 1874 if (p_char && (p_char->properties & GATT_CHAR_PROP_BIT_WRITE_NR)) 1875 write_type = GATT_WRITE_NO_RSP; 1876 1877 BtaGattQueue::WriteCharacteristic(p_cb->conn_id, p_rpt->char_inst_id, 1878 std::move(value), write_type, 1879 write_report_cb, p_cb); 1880 } 1881 1882 /******************************************************************************* 1883 * 1884 * Function bta_hh_le_suspend 1885 * 1886 * Description send LE suspend or exit suspend mode to remote device. 1887 * 1888 * Returns void 1889 * 1890 ******************************************************************************/ 1891 void bta_hh_le_suspend(tBTA_HH_DEV_CB* p_cb, 1892 tBTA_HH_TRANS_CTRL_TYPE ctrl_type) { 1893 ctrl_type -= BTA_HH_CTRL_SUSPEND; 1894 1895 // We don't care about response 1896 BtaGattQueue::WriteCharacteristic( 1897 p_cb->conn_id, p_cb->hid_srvc.control_point_handle, {(uint8_t)ctrl_type}, 1898 GATT_WRITE_NO_RSP, NULL, NULL); 1899 } 1900 1901 /******************************************************************************* 1902 * 1903 * Function bta_hh_le_write_dev_act 1904 * 1905 * Description Write LE device action. can be SET/GET/DATA transaction. 1906 * 1907 * Returns void 1908 * 1909 ******************************************************************************/ 1910 void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { 1911 switch (p_data->api_sndcmd.t_type) { 1912 case HID_TRANS_SET_PROTOCOL: 1913 p_cb->w4_evt = BTA_HH_SET_PROTO_EVT; 1914 bta_hh_le_set_protocol_mode(p_cb, p_data->api_sndcmd.param); 1915 break; 1916 1917 case HID_TRANS_GET_PROTOCOL: 1918 bta_hh_le_get_protocol_mode(p_cb); 1919 break; 1920 1921 case HID_TRANS_GET_REPORT: 1922 bta_hh_le_get_rpt(p_cb, p_data->api_sndcmd.param, 1923 p_data->api_sndcmd.rpt_id); 1924 break; 1925 1926 case HID_TRANS_SET_REPORT: 1927 bta_hh_le_write_rpt(p_cb, p_data->api_sndcmd.param, 1928 p_data->api_sndcmd.p_data, BTA_HH_SET_RPT_EVT); 1929 break; 1930 1931 case HID_TRANS_DATA: /* output report */ 1932 1933 bta_hh_le_write_rpt(p_cb, p_data->api_sndcmd.param, 1934 p_data->api_sndcmd.p_data, BTA_HH_DATA_EVT); 1935 break; 1936 1937 case HID_TRANS_CONTROL: 1938 /* no handshake event will be generated */ 1939 /* if VC_UNPLUG is issued, set flag */ 1940 if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND || 1941 p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND) { 1942 bta_hh_le_suspend(p_cb, p_data->api_sndcmd.param); 1943 } 1944 break; 1945 1946 default: 1947 APPL_TRACE_ERROR("%s unsupported transaction for BLE HID device: %d", 1948 __func__, p_data->api_sndcmd.t_type); 1949 break; 1950 } 1951 } 1952 1953 /******************************************************************************* 1954 * 1955 * Function bta_hh_le_get_dscp_act 1956 * 1957 * Description Send ReportDescriptor to application for all HID services. 1958 * 1959 * Returns void 1960 * 1961 ******************************************************************************/ 1962 void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb) { 1963 if (p_cb->hid_srvc.in_use) { 1964 p_cb->dscp_info.descriptor.dl_len = p_cb->hid_srvc.descriptor.dl_len; 1965 p_cb->dscp_info.descriptor.dsc_list = p_cb->hid_srvc.descriptor.dsc_list; 1966 1967 (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH*)&p_cb->dscp_info); 1968 } 1969 } 1970 1971 /******************************************************************************* 1972 * 1973 * Function bta_hh_le_add_dev_bg_conn 1974 * 1975 * Description Remove a LE HID device from back ground connection 1976 * procedure. 1977 * 1978 * Returns void 1979 * 1980 ******************************************************************************/ 1981 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond) { 1982 uint8_t sec_flag = 0; 1983 bool to_add = true; 1984 1985 if (check_bond) { 1986 /* start reconnection if remote is a bonded device */ 1987 /* verify bond */ 1988 BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE); 1989 1990 if ((sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) == 0) to_add = false; 1991 } 1992 1993 if (/*p_cb->dscp_info.flag & BTA_HH_LE_NORMAL_CONN &&*/ 1994 !p_cb->in_bg_conn && to_add) { 1995 /* add device into BG connection to accept remote initiated connection */ 1996 BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, false, GATT_TRANSPORT_LE, 1997 false); 1998 p_cb->in_bg_conn = true; 1999 2000 BTA_DmBleStartAutoConn(); 2001 } 2002 return; 2003 } 2004 2005 /******************************************************************************* 2006 * 2007 * Function bta_hh_le_add_device 2008 * 2009 * Description Add a LE HID device as a known device, and also add the 2010 * address 2011 * into back ground connection WL for incoming connection. 2012 * 2013 * Returns void 2014 * 2015 ******************************************************************************/ 2016 uint8_t bta_hh_le_add_device(tBTA_HH_DEV_CB* p_cb, 2017 tBTA_HH_MAINT_DEV* p_dev_info) { 2018 p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index); 2019 if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) return BTA_HH_INVALID_HANDLE; 2020 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; 2021 2022 /* update DI information */ 2023 bta_hh_update_di_info( 2024 p_cb, p_dev_info->dscp_info.vendor_id, p_dev_info->dscp_info.product_id, 2025 p_dev_info->dscp_info.version, p_dev_info->dscp_info.flag); 2026 2027 /* add to BTA device list */ 2028 bta_hh_add_device_to_list( 2029 p_cb, p_cb->hid_handle, p_dev_info->attr_mask, 2030 &p_dev_info->dscp_info.descriptor, p_dev_info->sub_class, 2031 p_dev_info->dscp_info.ssr_max_latency, p_dev_info->dscp_info.ssr_min_tout, 2032 p_dev_info->app_id); 2033 2034 bta_hh_le_add_dev_bg_conn(p_cb, false); 2035 2036 return p_cb->hid_handle; 2037 } 2038 2039 /******************************************************************************* 2040 * 2041 * Function bta_hh_le_remove_dev_bg_conn 2042 * 2043 * Description Remove a LE HID device from back ground connection 2044 * procedure. 2045 * 2046 * Returns void 2047 * 2048 ******************************************************************************/ 2049 void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB* p_dev_cb) { 2050 if (p_dev_cb->in_bg_conn) { 2051 p_dev_cb->in_bg_conn = false; 2052 2053 BTA_GATTC_CancelOpen(bta_hh_cb.gatt_if, p_dev_cb->addr, false); 2054 } 2055 2056 /* deregister all notifications */ 2057 bta_hh_le_deregister_input_notif(p_dev_cb); 2058 } 2059 2060 /******************************************************************************* 2061 * 2062 * Function bta_hh_gattc_callback 2063 * 2064 * Description This is GATT client callback function used in BTA HH. 2065 * 2066 * Parameters: 2067 * 2068 ******************************************************************************/ 2069 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { 2070 tBTA_HH_DEV_CB* p_dev_cb; 2071 #if (BTA_HH_DEBUG == TRUE) 2072 APPL_TRACE_DEBUG("bta_hh_gattc_callback event = %d", event); 2073 #endif 2074 if (p_data == NULL) return; 2075 2076 switch (event) { 2077 case BTA_GATTC_DEREG_EVT: /* 1 */ 2078 bta_hh_cleanup_disable(p_data->reg_oper.status); 2079 break; 2080 2081 case BTA_GATTC_OPEN_EVT: /* 2 */ 2082 p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda); 2083 if (p_dev_cb) { 2084 bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, 2085 (tBTA_HH_DATA*)&p_data->open); 2086 } 2087 break; 2088 2089 case BTA_GATTC_CLOSE_EVT: /* 5 */ 2090 bta_hh_le_close(&p_data->close); 2091 break; 2092 2093 case BTA_GATTC_SEARCH_CMPL_EVT: /* 6 */ 2094 bta_hh_le_srvc_search_cmpl(&p_data->search_cmpl); 2095 break; 2096 2097 case BTA_GATTC_NOTIF_EVT: /* 10 */ 2098 bta_hh_le_input_rpt_notify(&p_data->notify); 2099 break; 2100 2101 case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */ 2102 p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda); 2103 if (p_dev_cb) { 2104 bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT, 2105 (tBTA_HH_DATA*)&p_data->enc_cmpl); 2106 } 2107 break; 2108 2109 default: 2110 break; 2111 } 2112 } 2113 2114 static void read_report_descriptor_ccc_cb(uint16_t conn_id, tGATT_STATUS status, 2115 uint16_t handle, uint16_t len, 2116 uint8_t* value, void* data) { 2117 tBTA_HH_LE_RPT* p_rpt = (tBTA_HH_LE_RPT*)data; 2118 uint8_t* pp = value; 2119 STREAM_TO_UINT16(p_rpt->client_cfg_value, pp); 2120 2121 APPL_TRACE_DEBUG("Read Client Configuration: 0x%04x", 2122 p_rpt->client_cfg_value); 2123 } 2124 2125 /******************************************************************************* 2126 * 2127 * Function bta_hh_le_hid_read_rpt_clt_cfg 2128 * 2129 * Description a test command to read report descriptor client 2130 * configuration 2131 * 2132 * Returns void 2133 * 2134 ******************************************************************************/ 2135 void bta_hh_le_hid_read_rpt_clt_cfg(const RawAddress& bd_addr, uint8_t rpt_id) { 2136 tBTA_HH_DEV_CB* p_cb = NULL; 2137 tBTA_HH_LE_RPT* p_rpt; 2138 uint8_t index = BTA_HH_IDX_INVALID; 2139 2140 index = bta_hh_find_cb(bd_addr); 2141 if (index == BTA_HH_IDX_INVALID) { 2142 APPL_TRACE_ERROR("%s: unknown device", __func__); 2143 return; 2144 } 2145 2146 p_cb = &bta_hh_cb.kdev[index]; 2147 2148 p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode, 2149 BTA_HH_RPTT_INPUT, rpt_id); 2150 2151 if (p_rpt == NULL) { 2152 APPL_TRACE_ERROR("%s: no matching report", __func__); 2153 return; 2154 } 2155 2156 bta_hh_le_read_char_descriptor(p_cb, p_rpt->char_inst_id, 2157 GATT_UUID_CHAR_CLIENT_CONFIG, 2158 read_report_descriptor_ccc_cb, p_rpt); 2159 return; 2160 } 2161 2162 /******************************************************************************* 2163 * 2164 * Function bta_hh_process_cache_rpt 2165 * 2166 * Description Process the cached reports 2167 * 2168 * Parameters: 2169 * 2170 ******************************************************************************/ 2171 // TODO(jpawlowski): uncomment when fixed 2172 // static void bta_hh_process_cache_rpt (tBTA_HH_DEV_CB *p_cb, 2173 // tBTA_HH_RPT_CACHE_ENTRY *p_rpt_cache, 2174 // uint8_t num_rpt) 2175 // { 2176 // uint8_t i = 0; 2177 // tBTA_HH_LE_RPT *p_rpt; 2178 2179 // if (num_rpt != 0) /* no cache is found */ 2180 // { 2181 // p_cb->hid_srvc.in_use = true; 2182 2183 // /* set the descriptor info */ 2184 // p_cb->hid_srvc.descriptor.dl_len = 2185 // p_cb->dscp_info.descriptor.dl_len; 2186 // p_cb->hid_srvc.descriptor.dsc_list = 2187 // p_cb->dscp_info.descriptor.dsc_list; 2188 2189 // for (; i <num_rpt; i ++, p_rpt_cache ++) 2190 // { 2191 // if ((p_rpt = bta_hh_le_find_alloc_report_entry (p_cb, 2192 // p_rpt_cache->srvc_inst_id, 2193 // p_rpt_cache->rpt_uuid, 2194 // p_rpt_cache->char_inst_id, 2195 // p_rpt_cache->prop)) == NULL) 2196 // { 2197 // APPL_TRACE_ERROR("bta_hh_process_cache_rpt: allocation report 2198 // entry failure"); 2199 // break; 2200 // } 2201 // else 2202 // { 2203 // p_rpt->rpt_type = p_rpt_cache->rpt_type; 2204 // p_rpt->rpt_id = p_rpt_cache->rpt_id; 2205 2206 // if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 2207 // p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT || 2208 // (p_rpt->uuid == GATT_UUID_HID_REPORT && p_rpt->rpt_type 2209 // == BTA_HH_RPTT_INPUT)) 2210 // { 2211 // p_rpt->client_cfg_value = 2212 // GATT_CLT_CONFIG_NOTIFICATION; 2213 // } 2214 // } 2215 // } 2216 // } 2217 // } 2218 2219 #endif 2220