1 /****************************************************************************** 2 * 3 * Copyright (C) 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 24 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) 25 26 #include <string.h> 27 28 #include "bta_api.h" 29 #include "bta_gatt_api.h" 30 #include "bta_hh_co.h" 31 #include "btm_api.h" 32 #include "btm_ble_api.h" 33 #include "btm_int.h" 34 #include "osi/include/log.h" 35 #include "srvc_api.h" 36 #include "stack/include/l2c_api.h" 37 #include "utl.h" 38 39 #ifndef BTA_HH_LE_RECONN 40 #define BTA_HH_LE_RECONN TRUE 41 #endif 42 43 #define BTA_HH_APP_ID_LE 0xff 44 45 #define BTA_HH_LE_RPT_TYPE_VALID(x) ((x) <= BTA_LE_HID_RPT_FEATURE && (x)>=BTA_LE_HID_RPT_INPUT) 46 47 #define BTA_HH_LE_PROTO_BOOT_MODE 0x00 48 #define BTA_HH_LE_PROTO_REPORT_MODE 0x01 49 50 #define BTA_LE_HID_RTP_UUID_MAX 5 51 static const UINT16 bta_hh_uuid_to_rtp_type[BTA_LE_HID_RTP_UUID_MAX][2] = 52 { 53 {GATT_UUID_HID_REPORT, BTA_HH_RPTT_INPUT}, 54 {GATT_UUID_HID_BT_KB_INPUT, BTA_HH_RPTT_INPUT}, 55 {GATT_UUID_HID_BT_KB_OUTPUT, BTA_HH_RPTT_OUTPUT}, 56 {GATT_UUID_HID_BT_MOUSE_INPUT, BTA_HH_RPTT_INPUT}, 57 {GATT_UUID_BATTERY_LEVEL, BTA_HH_RPTT_INPUT} 58 }; 59 60 61 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data); 62 static void bta_hh_le_register_scpp_notif(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATT_STATUS status); 63 static void bta_hh_le_register_scpp_notif_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATT_STATUS status); 64 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond); 65 //TODO(jpawlowski): uncomment when fixed 66 // static void bta_hh_process_cache_rpt (tBTA_HH_DEV_CB *p_cb, 67 // tBTA_HH_RPT_CACHE_ENTRY *p_rpt_cache, 68 // UINT8 num_rpt); 69 70 #define GATT_READ_CHAR 0 71 #define GATT_READ_DESC 1 72 #define GATT_WRITE_CHAR 2 73 #define GATT_WRITE_DESC 3 74 75 /* Holds pending GATT operations */ 76 typedef struct { 77 UINT8 type; 78 UINT16 conn_id; 79 UINT16 handle; 80 81 /* write-specific fields */ 82 tBTA_GATTC_WRITE_TYPE write_type; 83 UINT16 len; 84 UINT8 p_value[GATT_MAX_ATTR_LEN]; 85 } gatt_operation; 86 87 static list_t *gatt_op_queue = NULL; // list of gatt_operation 88 static list_t *gatt_op_queue_executing = NULL; // list of UINT16 connection ids that currently execute 89 90 static void mark_as_executing(UINT16 conn_id) { 91 UINT16 *executing_conn_id = osi_malloc(sizeof(UINT16)); 92 *executing_conn_id = conn_id; 93 if (!gatt_op_queue_executing) 94 gatt_op_queue_executing = list_new(osi_free); 95 96 list_append(gatt_op_queue_executing, executing_conn_id); 97 } 98 99 static bool rm_exec_conn_id(void *data, void *context) { 100 UINT16 *conn_id = context; 101 UINT16 *conn_id2 = data; 102 if (*conn_id == *conn_id2) 103 list_remove(gatt_op_queue_executing, data); 104 105 return TRUE; 106 } 107 108 static void mark_as_not_executing(UINT16 conn_id) { 109 if (gatt_op_queue_executing) 110 list_foreach(gatt_op_queue_executing, rm_exec_conn_id, &conn_id); 111 } 112 113 static bool exec_list_contains(void *data, void *context) { 114 UINT16 *conn_id = context; 115 UINT16 *conn_id2 = data; 116 if (*conn_id == *conn_id2) 117 return FALSE; 118 119 return TRUE; 120 } 121 122 static bool rm_op_by_conn_id(void *data, void *context) { 123 UINT16 *conn_id = context; 124 gatt_operation *op = data; 125 if(op->conn_id == *conn_id) 126 list_remove(gatt_op_queue, data); 127 128 return TRUE; 129 } 130 131 static void gatt_op_queue_clean(UINT16 conn_id) { 132 if (gatt_op_queue) 133 list_foreach(gatt_op_queue, rm_op_by_conn_id, &conn_id); 134 135 mark_as_not_executing(conn_id); 136 } 137 138 static bool find_op_by_conn_id(void *data, void *context) { 139 UINT16 *conn_id = context; 140 gatt_operation *op = data; 141 if(op->conn_id == *conn_id) 142 return FALSE; 143 144 return TRUE; 145 } 146 147 static void gatt_execute_next_op(UINT16 conn_id) { 148 APPL_TRACE_DEBUG("%s:", __func__, conn_id); 149 if (!gatt_op_queue || list_is_empty(gatt_op_queue)) { 150 APPL_TRACE_DEBUG("%s: op queue is empty", __func__); 151 return; 152 } 153 154 list_node_t *op_node = list_foreach(gatt_op_queue, find_op_by_conn_id, &conn_id); 155 if (op_node == NULL) { 156 APPL_TRACE_DEBUG("%s: no more operations queued for conn_id %d", __func__, conn_id); 157 return; 158 } 159 gatt_operation *op = list_node(op_node); 160 161 if (gatt_op_queue_executing && list_foreach(gatt_op_queue_executing, exec_list_contains, &conn_id)) { 162 APPL_TRACE_DEBUG("%s: can't enqueue next op, already executing", __func__); 163 return; 164 } 165 166 if (op->type == GATT_READ_CHAR) { 167 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(op->conn_id, op->handle); 168 169 mark_as_executing(conn_id); 170 BTA_GATTC_ReadCharacteristic(op->conn_id, p_char->handle, BTA_GATT_AUTH_REQ_NONE); 171 list_remove(gatt_op_queue, op); 172 173 } else if (op->type == GATT_READ_DESC) { 174 const tBTA_GATTC_DESCRIPTOR *p_desc = BTA_GATTC_GetDescriptor(op->conn_id, op->handle); 175 176 mark_as_executing(conn_id); 177 BTA_GATTC_ReadCharDescr(op->conn_id, p_desc->handle, BTA_GATT_AUTH_REQ_NONE); 178 list_remove(gatt_op_queue, op); 179 } else if (op->type == GATT_WRITE_CHAR) { 180 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(op->conn_id, op->handle); 181 mark_as_executing(conn_id); 182 BTA_GATTC_WriteCharValue(op->conn_id, p_char->handle, op->write_type, op->len, 183 op->p_value, BTA_GATT_AUTH_REQ_NONE); 184 185 list_remove(gatt_op_queue, op); 186 } else if (op->type == GATT_WRITE_DESC) { 187 const tBTA_GATTC_DESCRIPTOR *p_desc = BTA_GATTC_GetDescriptor(op->conn_id, op->handle); 188 189 tBTA_GATT_UNFMT value; 190 value.len = op->len; 191 value.p_value = op->p_value; 192 193 mark_as_executing(conn_id); 194 BTA_GATTC_WriteCharDescr(op->conn_id, p_desc->handle, BTA_GATTC_TYPE_WRITE, 195 &value, BTA_GATT_AUTH_REQ_NONE); 196 list_remove(gatt_op_queue, op); 197 } 198 } 199 200 static void gatt_queue_read_op(UINT8 op_type, UINT16 conn_id, UINT16 handle) { 201 if (gatt_op_queue == NULL) { 202 gatt_op_queue = list_new(osi_free); 203 } 204 205 gatt_operation *op = osi_malloc(sizeof(gatt_operation)); 206 op->type = op_type; 207 op->conn_id = conn_id; 208 op->handle = handle; 209 210 list_append(gatt_op_queue, op); 211 gatt_execute_next_op(conn_id); 212 } 213 214 static void gatt_queue_write_op(UINT8 op_type, UINT16 conn_id, UINT16 handle, UINT16 len, 215 UINT8 *p_value, tBTA_GATTC_WRITE_TYPE write_type) { 216 if (gatt_op_queue == NULL) { 217 gatt_op_queue = list_new(osi_free); 218 } 219 220 gatt_operation *op = osi_malloc(sizeof(gatt_operation)); 221 op->type = op_type; 222 op->conn_id = conn_id; 223 op->handle = handle; 224 op->write_type = write_type; 225 op->len = len; 226 memcpy(op->p_value, p_value, len); 227 228 list_append(gatt_op_queue, op); 229 gatt_execute_next_op(conn_id); 230 } 231 232 #if BTA_HH_DEBUG == TRUE 233 static const char *bta_hh_le_rpt_name[4] = 234 { 235 "UNKNOWN", 236 "INPUT", 237 "OUTPUT", 238 "FEATURE" 239 }; 240 241 /******************************************************************************* 242 ** 243 ** Function bta_hh_le_hid_report_dbg 244 ** 245 ** Description debug function to print out all HID report available on remote 246 ** device. 247 ** 248 ** Returns void 249 ** 250 *******************************************************************************/ 251 static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB *p_cb) 252 { 253 APPL_TRACE_DEBUG("%s: HID Report DB", __func__); 254 255 if (!p_cb->hid_srvc.in_use) 256 return; 257 258 tBTA_HH_LE_RPT *p_rpt = &p_cb->hid_srvc.report[0]; 259 260 for (int j = 0; j < BTA_HH_LE_RPT_MAX; j ++, p_rpt++) 261 { 262 char * rpt_name = "Unknown"; 263 264 if (!p_rpt->in_use) 265 break; 266 267 if (p_rpt->uuid == GATT_UUID_HID_REPORT) 268 rpt_name = "Report"; 269 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT) 270 rpt_name = "Boot KB Input"; 271 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_OUTPUT) 272 rpt_name = "Boot KB Output"; 273 if (p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) 274 rpt_name = "Boot MI Input"; 275 276 APPL_TRACE_DEBUG("\t\t [%s- 0x%04x] [Type: %s], [ReportID: %d] [srvc_inst_id: %d] [char_inst_id: %d] [Clt_cfg: %d]", 277 rpt_name, 278 p_rpt->uuid , 279 ((p_rpt->rpt_type < 4) ? bta_hh_le_rpt_name[p_rpt->rpt_type] : "UNKNOWN"), 280 p_rpt->rpt_id, 281 p_rpt->srvc_inst_id, 282 p_rpt->char_inst_id, 283 p_rpt->client_cfg_value); 284 } 285 } 286 287 /******************************************************************************* 288 ** 289 ** Function bta_hh_uuid_to_str 290 ** 291 ** Description 292 ** 293 ** Returns void 294 ** 295 *******************************************************************************/ 296 static char *bta_hh_uuid_to_str(UINT16 uuid) 297 { 298 switch(uuid) 299 { 300 case GATT_UUID_HID_INFORMATION: 301 return "GATT_UUID_HID_INFORMATION"; 302 case GATT_UUID_HID_REPORT_MAP: 303 return "GATT_UUID_HID_REPORT_MAP"; 304 case GATT_UUID_HID_CONTROL_POINT: 305 return "GATT_UUID_HID_CONTROL_POINT"; 306 case GATT_UUID_HID_REPORT: 307 return "GATT_UUID_HID_REPORT"; 308 case GATT_UUID_HID_PROTO_MODE: 309 return "GATT_UUID_HID_PROTO_MODE"; 310 case GATT_UUID_HID_BT_KB_INPUT: 311 return "GATT_UUID_HID_BT_KB_INPUT"; 312 case GATT_UUID_HID_BT_KB_OUTPUT: 313 return "GATT_UUID_HID_BT_KB_OUTPUT"; 314 case GATT_UUID_HID_BT_MOUSE_INPUT: 315 return "GATT_UUID_HID_BT_MOUSE_INPUT"; 316 case GATT_UUID_CHAR_CLIENT_CONFIG: 317 return "GATT_UUID_CHAR_CLIENT_CONFIG"; 318 case GATT_UUID_EXT_RPT_REF_DESCR: 319 return "GATT_UUID_EXT_RPT_REF_DESCR"; 320 case GATT_UUID_RPT_REF_DESCR: 321 return "GATT_UUID_RPT_REF_DESCR"; 322 default: 323 return "Unknown UUID"; 324 } 325 } 326 327 #endif 328 /******************************************************************************* 329 ** 330 ** Function bta_hh_le_enable 331 ** 332 ** Description initialize LE HID related functionality 333 ** 334 ** 335 ** Returns void 336 ** 337 *******************************************************************************/ 338 void bta_hh_le_enable(void) 339 { 340 char app_name[LEN_UUID_128 + 1]; 341 tBT_UUID app_uuid = {LEN_UUID_128,{0}}; 342 UINT8 xx; 343 344 bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF; 345 346 for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx ++) 347 bta_hh_cb.le_cb_index[xx] = BTA_HH_IDX_INVALID; 348 349 memset (app_name, 0, LEN_UUID_128 + 1); 350 strncpy(app_name, "BTA HH OVER LE", LEN_UUID_128); 351 352 memcpy((void *)app_uuid.uu.uuid128, (void *)app_name, LEN_UUID_128); 353 354 BTA_GATTC_AppRegister(&app_uuid, bta_hh_gattc_callback); 355 356 return; 357 } 358 359 /******************************************************************************* 360 ** 361 ** Function bta_hh_le_register_cmpl 362 ** 363 ** Description BTA HH register with BTA GATTC completed 364 ** 365 ** Parameters: 366 ** 367 *******************************************************************************/ 368 void bta_hh_le_register_cmpl(tBTA_GATTC_REG *p_reg) 369 { 370 tBTA_HH_STATUS status = BTA_HH_ERR; 371 372 if (p_reg->status == BTA_GATT_OK) 373 { 374 bta_hh_cb.gatt_if = p_reg->client_if; 375 status = BTA_HH_OK; 376 } 377 else 378 bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF; 379 380 /* signal BTA call back event */ 381 (* bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, (tBTA_HH *)&status); 382 } 383 384 /******************************************************************************* 385 ** 386 ** Function bta_hh_le_is_hh_gatt_if 387 ** 388 ** Description Check to see if client_if is BTA HH LE GATT interface 389 ** 390 ** 391 ** Returns whether it is HH GATT IF 392 ** 393 *******************************************************************************/ 394 BOOLEAN bta_hh_le_is_hh_gatt_if(tBTA_GATTC_IF client_if) 395 { 396 return (bta_hh_cb.gatt_if == client_if); 397 } 398 399 /******************************************************************************* 400 ** 401 ** Function bta_hh_le_deregister 402 ** 403 ** Description De-register BTA HH from BTA GATTC 404 ** 405 ** 406 ** Returns void 407 ** 408 *******************************************************************************/ 409 void bta_hh_le_deregister(void) 410 { 411 BTA_GATTC_AppDeregister(bta_hh_cb.gatt_if); 412 } 413 414 /******************************************************************************* 415 ** 416 ** Function bta_hh_is_le_device 417 ** 418 ** Description Check to see if the remote device is a LE only device 419 ** 420 ** Parameters: 421 ** 422 *******************************************************************************/ 423 BOOLEAN bta_hh_is_le_device(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda) 424 { 425 p_cb->is_le_device = BTM_UseLeLink (remote_bda); 426 427 return p_cb->is_le_device; 428 } 429 430 /******************************************************************************* 431 ** 432 ** Function bta_hh_le_open_conn 433 ** 434 ** Description open a GATT connection first. 435 ** 436 ** Parameters: 437 ** 438 *******************************************************************************/ 439 void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda) 440 { 441 /* update cb_index[] map */ 442 p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index); 443 memcpy(p_cb->addr, remote_bda, BD_ADDR_LEN); 444 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; 445 p_cb->in_use = TRUE; 446 447 BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE, BTA_GATT_TRANSPORT_LE); 448 } 449 450 /******************************************************************************* 451 ** 452 ** Function bta_hh_le_find_dev_cb_by_conn_id 453 ** 454 ** Description Utility function find a device control block by connection ID. 455 ** 456 *******************************************************************************/ 457 tBTA_HH_DEV_CB * bta_hh_le_find_dev_cb_by_conn_id(UINT16 conn_id) 458 { 459 UINT8 i; 460 tBTA_HH_DEV_CB *p_dev_cb = &bta_hh_cb.kdev[0]; 461 462 for (i = 0; i < BTA_HH_MAX_DEVICE; i ++, p_dev_cb ++) 463 { 464 if (p_dev_cb->in_use && p_dev_cb->conn_id == conn_id) 465 return p_dev_cb; 466 } 467 return NULL; 468 } 469 470 /******************************************************************************* 471 ** 472 ** Function bta_hh_le_find_dev_cb_by_bda 473 ** 474 ** Description Utility function find a device control block by BD address. 475 ** 476 *******************************************************************************/ 477 tBTA_HH_DEV_CB * bta_hh_le_find_dev_cb_by_bda(BD_ADDR bda) 478 { 479 UINT8 i; 480 tBTA_HH_DEV_CB *p_dev_cb = &bta_hh_cb.kdev[0]; 481 482 for (i = 0; i < BTA_HH_MAX_DEVICE; i ++, p_dev_cb ++) 483 { 484 if (p_dev_cb->in_use && 485 memcmp(p_dev_cb->addr, bda, BD_ADDR_LEN) == 0) 486 return p_dev_cb; 487 } 488 return NULL; 489 } 490 491 /******************************************************************************* 492 ** 493 ** Function bta_hh_le_find_service_inst_by_battery_inst_id 494 ** 495 ** Description find HID service instance ID by battery service instance ID 496 ** 497 *******************************************************************************/ 498 UINT8 bta_hh_le_find_service_inst_by_battery_inst_id(tBTA_HH_DEV_CB *p_cb, UINT8 ba_inst_id) 499 { 500 if (p_cb->hid_srvc.in_use && 501 p_cb->hid_srvc.incl_srvc_inst == ba_inst_id) 502 { 503 return p_cb->hid_srvc.srvc_inst_id; 504 } 505 return BTA_HH_IDX_INVALID; 506 } 507 508 /******************************************************************************* 509 ** 510 ** Function bta_hh_le_find_report_entry 511 ** 512 ** Description find the report entry by service instance and report UUID and 513 ** instance ID 514 ** 515 *******************************************************************************/ 516 tBTA_HH_LE_RPT * bta_hh_le_find_report_entry(tBTA_HH_DEV_CB *p_cb, 517 UINT8 srvc_inst_id, /* service instance ID */ 518 UINT16 rpt_uuid, 519 UINT8 char_inst_id) 520 { 521 UINT8 i; 522 UINT8 hid_inst_id = srvc_inst_id; 523 tBTA_HH_LE_RPT *p_rpt; 524 525 if (rpt_uuid == GATT_UUID_BATTERY_LEVEL) 526 { 527 hid_inst_id = bta_hh_le_find_service_inst_by_battery_inst_id(p_cb, srvc_inst_id); 528 529 if (hid_inst_id == BTA_HH_IDX_INVALID) 530 return NULL; 531 } 532 533 p_rpt = &p_cb->hid_srvc.report[0]; 534 535 for (i = 0; i < BTA_HH_LE_RPT_MAX; i ++, p_rpt ++) 536 { 537 if (p_rpt->uuid == rpt_uuid && 538 p_rpt->srvc_inst_id == srvc_inst_id && 539 p_rpt->char_inst_id == char_inst_id) 540 { 541 542 return p_rpt; 543 } 544 } 545 return NULL; 546 547 } 548 549 /******************************************************************************* 550 ** 551 ** Function bta_hh_le_find_rpt_by_idtype 552 ** 553 ** Description find a report entry by report ID and protocol mode 554 ** 555 ** Returns void 556 ** 557 *******************************************************************************/ 558 tBTA_HH_LE_RPT * bta_hh_le_find_rpt_by_idtype(tBTA_HH_LE_RPT*p_head, UINT8 mode, 559 tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id) 560 { 561 tBTA_HH_LE_RPT *p_rpt = p_head; 562 UINT8 i; 563 564 #if BTA_HH_DEBUG == TRUE 565 APPL_TRACE_DEBUG("bta_hh_le_find_rpt_by_idtype: r_type: %d rpt_id: %d", r_type, rpt_id); 566 #endif 567 568 for (i = 0 ; i < BTA_HH_LE_RPT_MAX; i ++, p_rpt++) 569 { 570 if (p_rpt->in_use && p_rpt->rpt_id == rpt_id && r_type == p_rpt->rpt_type) 571 { 572 /* return battery report w/o condition */ 573 if (p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) 574 return p_rpt; 575 576 if (mode == BTA_HH_PROTO_RPT_MODE && p_rpt->uuid == GATT_UUID_HID_REPORT) 577 return p_rpt; 578 579 if ( mode ==BTA_HH_PROTO_BOOT_MODE && 580 (p_rpt->uuid >= GATT_UUID_HID_BT_KB_INPUT && p_rpt->uuid <= GATT_UUID_HID_BT_MOUSE_INPUT)) 581 return p_rpt; 582 } 583 } 584 return NULL; 585 } 586 587 /******************************************************************************* 588 ** 589 ** Function bta_hh_le_find_alloc_report_entry 590 ** 591 ** Description find or allocate a report entry in the HID service report list. 592 ** 593 *******************************************************************************/ 594 tBTA_HH_LE_RPT * bta_hh_le_find_alloc_report_entry(tBTA_HH_DEV_CB *p_cb, 595 UINT8 srvc_inst_id, 596 UINT16 rpt_uuid, 597 UINT8 inst_id) 598 { 599 UINT8 i, hid_inst_id = srvc_inst_id; 600 tBTA_HH_LE_RPT *p_rpt; 601 602 if (rpt_uuid == GATT_UUID_BATTERY_LEVEL) 603 { 604 hid_inst_id = bta_hh_le_find_service_inst_by_battery_inst_id(p_cb, srvc_inst_id); 605 606 if (hid_inst_id == BTA_HH_IDX_INVALID) 607 return NULL; 608 } 609 p_rpt = &p_cb->hid_srvc.report[0]; 610 611 for (i = 0; i < BTA_HH_LE_RPT_MAX; i ++, p_rpt ++) 612 { 613 if (!p_rpt->in_use || 614 (p_rpt->uuid == rpt_uuid && 615 p_rpt->srvc_inst_id == srvc_inst_id && 616 p_rpt->char_inst_id == inst_id)) 617 { 618 if (!p_rpt->in_use) 619 { 620 p_rpt->in_use = TRUE; 621 p_rpt->index = i; 622 p_rpt->srvc_inst_id = srvc_inst_id; 623 p_rpt->char_inst_id = inst_id; 624 p_rpt->uuid = rpt_uuid; 625 626 /* assign report type */ 627 for (i = 0; i < BTA_LE_HID_RTP_UUID_MAX; i ++) 628 { 629 if (bta_hh_uuid_to_rtp_type[i][0] == rpt_uuid) 630 { 631 p_rpt->rpt_type = (tBTA_HH_RPT_TYPE)bta_hh_uuid_to_rtp_type[i][1]; 632 633 if (rpt_uuid == GATT_UUID_HID_BT_KB_INPUT || rpt_uuid == GATT_UUID_HID_BT_KB_OUTPUT) 634 p_rpt->rpt_id = BTA_HH_KEYBD_RPT_ID; 635 636 if (rpt_uuid == GATT_UUID_HID_BT_MOUSE_INPUT) 637 p_rpt->rpt_id = BTA_HH_MOUSE_RPT_ID; 638 639 break; 640 } 641 } 642 } 643 return p_rpt; 644 } 645 } 646 return NULL; 647 } 648 649 static tBTA_GATTC_DESCRIPTOR *find_descriptor_by_short_uuid(UINT16 conn_id, 650 UINT16 char_handle, 651 UINT16 short_uuid) { 652 const tBTA_GATTC_CHARACTERISTIC *p_char = 653 BTA_GATTC_GetCharacteristic(conn_id, char_handle); 654 655 if (!p_char) { 656 LOG_WARN(LOG_TAG, "%s No such characteristic: %d", __func__, char_handle); 657 return NULL; 658 } 659 660 if (!p_char->descriptors || list_is_empty(p_char->descriptors)) 661 return NULL; 662 663 for (list_node_t *dn = list_begin(p_char->descriptors); 664 dn != list_end(p_char->descriptors); dn = list_next(dn)) { 665 tBTA_GATTC_DESCRIPTOR *p_desc = list_node(dn); 666 667 if (p_char->uuid.len == LEN_UUID_16 && 668 p_desc->uuid.uu.uuid16 == short_uuid) 669 return p_desc; 670 } 671 672 return NULL; 673 } 674 675 /******************************************************************************* 676 ** 677 ** Function bta_hh_le_read_char_dscrpt 678 ** 679 ** Description read characteristic descriptor 680 ** 681 *******************************************************************************/ 682 static tBTA_HH_STATUS bta_hh_le_read_char_dscrpt(tBTA_HH_DEV_CB *p_cb, UINT16 char_handle, UINT16 short_uuid) 683 { 684 const tBTA_GATTC_DESCRIPTOR *p_desc = find_descriptor_by_short_uuid(p_cb->conn_id, char_handle, short_uuid); 685 if (!p_desc) 686 return BTA_HH_ERR; 687 688 gatt_queue_read_op(GATT_READ_DESC, p_cb->conn_id, p_desc->handle); 689 return BTA_HH_OK; 690 } 691 692 /******************************************************************************* 693 ** 694 ** Function bta_hh_le_save_rpt_ref 695 ** 696 ** Description save report reference information and move to next one. 697 ** 698 ** Parameters: 699 ** 700 *******************************************************************************/ 701 void bta_hh_le_save_rpt_ref(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_LE_RPT *p_rpt, 702 tBTA_GATTC_READ *p_data) 703 { 704 /* if the length of the descriptor value is right, parse it */ 705 if (p_data->status == BTA_GATT_OK && 706 p_data->p_value && p_data->p_value->len == 2) 707 { 708 UINT8 *pp = p_data->p_value->p_value; 709 710 STREAM_TO_UINT8(p_rpt->rpt_id, pp); 711 STREAM_TO_UINT8(p_rpt->rpt_type, pp); 712 713 if (p_rpt->rpt_type > BTA_HH_RPTT_FEATURE) /* invalid report type */ 714 p_rpt->rpt_type = BTA_HH_RPTT_RESRV; 715 716 #if BTA_HH_DEBUG == TRUE 717 APPL_TRACE_DEBUG("%s: report ID: %d", __func__, p_rpt->rpt_id); 718 #endif 719 tBTA_HH_RPT_CACHE_ENTRY rpt_entry; 720 rpt_entry.rpt_id = p_rpt->rpt_id; 721 rpt_entry.rpt_type = p_rpt->rpt_type; 722 rpt_entry.rpt_uuid = p_rpt->uuid; 723 rpt_entry.srvc_inst_id = p_rpt->srvc_inst_id; 724 rpt_entry.char_inst_id = p_rpt->char_inst_id; 725 726 bta_hh_le_co_rpt_info(p_dev_cb->addr, 727 &rpt_entry, 728 p_dev_cb->app_id); 729 } 730 else if (p_data->status == BTA_GATT_INSUF_AUTHENTICATION) 731 { 732 /* close connection right away */ 733 p_dev_cb->status = BTA_HH_ERR_AUTH_FAILED; 734 /* close the connection and report service discovery complete with error */ 735 bta_hh_le_api_disc_act(p_dev_cb); 736 return; 737 } 738 739 if (p_rpt->index < BTA_HH_LE_RPT_MAX - 1) 740 p_rpt ++; 741 else 742 p_rpt = NULL; 743 } 744 745 /******************************************************************************* 746 ** 747 ** Function bta_hh_le_save_rpt_ref 748 ** 749 ** Description save report reference information and move to next one. 750 ** 751 ** Parameters: 752 ** 753 *******************************************************************************/ 754 void bta_hh_le_save_ext_rpt_ref(tBTA_HH_DEV_CB *p_dev_cb, 755 tBTA_GATTC_READ *p_data) 756 { 757 /* if the length of the descriptor value is right, parse it 758 assume it's a 16 bits UUID */ 759 if (p_data->status == BTA_GATT_OK && 760 p_data->p_value && p_data->p_value->len == 2) { 761 UINT8 *pp = p_data->p_value->p_value; 762 STREAM_TO_UINT16(p_dev_cb->hid_srvc.ext_rpt_ref, pp); 763 764 #if BTA_HH_DEBUG == TRUE 765 APPL_TRACE_DEBUG("%s: External Report Reference UUID 0x%04x", __func__, 766 p_dev_cb->hid_srvc.ext_rpt_ref); 767 #endif 768 } 769 } 770 771 /******************************************************************************* 772 ** 773 ** Function bta_hh_le_register_input_notif 774 ** 775 ** Description Register for all notifications for the report applicable 776 ** for the protocol mode. 777 ** 778 ** Parameters: 779 ** 780 *******************************************************************************/ 781 void bta_hh_le_register_input_notif(tBTA_HH_DEV_CB *p_dev_cb, UINT8 proto_mode, BOOLEAN register_ba) 782 { 783 tBTA_HH_LE_RPT *p_rpt = &p_dev_cb->hid_srvc.report[0]; 784 785 #if BTA_HH_DEBUG == TRUE 786 APPL_TRACE_DEBUG("%s: bta_hh_le_register_input_notif mode: %d", __func__, proto_mode); 787 #endif 788 789 for (int i = 0; i < BTA_HH_LE_RPT_MAX; i ++, p_rpt ++) 790 { 791 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) 792 { 793 794 if (register_ba && p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) 795 { 796 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 797 p_rpt->char_inst_id); 798 } 799 /* boot mode, deregister report input notification */ 800 else if (proto_mode == BTA_HH_PROTO_BOOT_MODE) 801 { 802 if (p_rpt->uuid == GATT_UUID_HID_REPORT && 803 p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION) 804 { 805 APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__, p_rpt->rpt_id); 806 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 807 p_rpt->char_inst_id); 808 } 809 /* register boot reports notification */ 810 else if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 811 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) 812 { 813 APPL_TRACE_DEBUG("%s <--- Register Boot Report ID: %d", __func__, p_rpt->rpt_id); 814 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 815 p_rpt->char_inst_id); 816 } 817 } 818 else if (proto_mode == BTA_HH_PROTO_RPT_MODE) 819 { 820 if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 821 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) && 822 p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION) 823 { 824 825 APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__, p_rpt->rpt_id); 826 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 827 p_rpt->char_inst_id); 828 } 829 else if (p_rpt->uuid == GATT_UUID_HID_REPORT && 830 p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION) 831 { 832 APPL_TRACE_DEBUG("%s <--- Register Report ID: %d", __func__, p_rpt->rpt_id); 833 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 834 p_rpt->char_inst_id); 835 } 836 } 837 /* 838 else unknow protocol mode */ 839 } 840 } 841 } 842 843 /******************************************************************************* 844 ** 845 ** Function bta_hh_le_deregister_input_notif 846 ** 847 ** Description Deregister all notifications 848 ** 849 *******************************************************************************/ 850 void bta_hh_le_deregister_input_notif(tBTA_HH_DEV_CB *p_dev_cb) 851 { 852 tBTA_HH_LE_RPT *p_rpt = &p_dev_cb->hid_srvc.report[0]; 853 854 for (UINT8 i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) 855 { 856 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) 857 { 858 if (p_rpt->uuid == GATT_UUID_HID_REPORT && 859 p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION) 860 { 861 APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__, p_rpt->rpt_id); 862 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 863 p_rpt->char_inst_id); 864 } 865 else if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 866 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) && 867 p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION) 868 { 869 APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__, p_rpt->rpt_id); 870 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 871 p_rpt->char_inst_id); 872 } 873 } 874 } 875 } 876 877 878 /******************************************************************************* 879 ** 880 ** Function bta_hh_le_open_cmpl 881 ** 882 ** Description HID over GATT connection sucessfully opened 883 ** 884 *******************************************************************************/ 885 void bta_hh_le_open_cmpl(tBTA_HH_DEV_CB *p_cb) 886 { 887 if ( p_cb->disc_active == BTA_HH_LE_DISC_NONE) 888 { 889 #if BTA_HH_DEBUG 890 bta_hh_le_hid_report_dbg(p_cb); 891 #endif 892 bta_hh_le_register_input_notif(p_cb, p_cb->mode, TRUE); 893 bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL); 894 895 #if (BTA_HH_LE_RECONN == TRUE) 896 if (p_cb->status == BTA_HH_OK) 897 { 898 bta_hh_le_add_dev_bg_conn(p_cb, TRUE); 899 } 900 #endif 901 } 902 } 903 904 /******************************************************************************* 905 ** 906 ** Function bta_hh_le_write_char_clt_cfg 907 ** 908 ** Description Utility function to find and write client configuration of 909 ** a characteristic 910 ** 911 *******************************************************************************/ 912 BOOLEAN bta_hh_le_write_char_clt_cfg(tBTA_HH_DEV_CB *p_cb, 913 UINT8 char_handle, 914 UINT16 clt_cfg_value) 915 { 916 UINT8 buf[2], *pp = buf; 917 918 tBTA_GATTC_DESCRIPTOR *p_desc = find_descriptor_by_short_uuid(p_cb->conn_id, 919 char_handle, GATT_UUID_CHAR_CLIENT_CONFIG); 920 if (!p_desc) 921 return FALSE; 922 923 UINT16_TO_STREAM(pp, clt_cfg_value); 924 gatt_queue_write_op(GATT_WRITE_DESC, p_cb->conn_id, 925 p_desc->handle, 2, buf, BTA_GATTC_TYPE_WRITE); 926 return TRUE; 927 } 928 929 /******************************************************************************* 930 ** 931 ** Function bta_hh_le_write_rpt_clt_cfg 932 ** 933 ** Description write client configuration. This is only for input report 934 ** enable all input notification upon connection open. 935 ** 936 *******************************************************************************/ 937 BOOLEAN bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB *p_cb, UINT8 srvc_inst_id) 938 { 939 UINT8 i; 940 tBTA_HH_LE_RPT *p_rpt = &p_cb->hid_srvc.report[p_cb->clt_cfg_idx]; 941 942 for (i = p_cb->clt_cfg_idx; i < BTA_HH_LE_RPT_MAX && p_rpt->in_use; i ++, p_rpt ++) 943 { 944 /* enable notification for all input report, regardless mode */ 945 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) 946 { 947 if (bta_hh_le_write_char_clt_cfg(p_cb, 948 p_rpt->char_inst_id, 949 BTA_GATT_CLT_CONFIG_NOTIFICATION)) 950 { 951 p_cb->clt_cfg_idx = i; 952 return TRUE; 953 } 954 } 955 } 956 p_cb->clt_cfg_idx = 0; 957 958 /* client configuration is completed, send open callback */ 959 if (p_cb->state == BTA_HH_W4_CONN_ST) 960 { 961 p_cb->disc_active &= ~BTA_HH_LE_DISC_HIDS; 962 963 bta_hh_le_open_cmpl(p_cb); 964 } 965 return FALSE; 966 } 967 968 /******************************************************************************* 969 ** 970 ** Function bta_hh_le_set_protocol_mode 971 ** 972 ** Description Set remote device protocol mode. 973 ** 974 *******************************************************************************/ 975 BOOLEAN bta_hh_le_set_protocol_mode(tBTA_HH_DEV_CB *p_cb, tBTA_HH_PROTO_MODE mode) 976 { 977 tBTA_HH_CBDATA cback_data; 978 BOOLEAN exec = FALSE; 979 980 APPL_TRACE_DEBUG("%s attempt mode: %s", __func__, 981 (mode == BTA_HH_PROTO_RPT_MODE)? "Report": "Boot"); 982 983 cback_data.handle = p_cb->hid_handle; 984 /* boot mode is not supported in the remote device */ 985 if (p_cb->hid_srvc.proto_mode_handle == 0) 986 { 987 p_cb->mode = BTA_HH_PROTO_RPT_MODE; 988 989 if (mode == BTA_HH_PROTO_BOOT_MODE) 990 { 991 APPL_TRACE_ERROR("Set Boot Mode failed!! No PROTO_MODE Char!"); 992 cback_data.status = BTA_HH_ERR; 993 } 994 else 995 { 996 /* if set to report mode, need to de-register all input report notification */ 997 bta_hh_le_register_input_notif(p_cb, p_cb->mode, FALSE); 998 cback_data.status = BTA_HH_OK; 999 } 1000 if (p_cb->state == BTA_HH_W4_CONN_ST) 1001 { 1002 p_cb->status = (cback_data.status == BTA_HH_OK)? BTA_HH_OK: BTA_HH_ERR_PROTO; 1003 } 1004 else 1005 (* bta_hh_cb.p_cback)(BTA_HH_SET_PROTO_EVT, (tBTA_HH *)&cback_data); 1006 } else if (p_cb->mode != mode) { 1007 p_cb->mode = mode; 1008 mode = (mode == BTA_HH_PROTO_BOOT_MODE)? BTA_HH_LE_PROTO_BOOT_MODE : BTA_HH_LE_PROTO_REPORT_MODE; 1009 1010 gatt_queue_write_op(GATT_WRITE_CHAR, p_cb->conn_id, p_cb->hid_srvc.proto_mode_handle, 1, 1011 &mode, BTA_GATTC_TYPE_WRITE_NO_RSP); 1012 exec = TRUE; 1013 } 1014 1015 return exec; 1016 } 1017 1018 /******************************************************************************* 1019 ** 1020 ** Function bta_hh_le_get_protocol_mode 1021 ** 1022 ** Description Get remote device protocol mode. 1023 ** 1024 *******************************************************************************/ 1025 void bta_hh_le_get_protocol_mode(tBTA_HH_DEV_CB *p_cb) 1026 { 1027 tBTA_HH_HSDATA hs_data; 1028 p_cb->w4_evt = BTA_HH_GET_PROTO_EVT; 1029 1030 if (p_cb->hid_srvc.in_use && p_cb->hid_srvc.proto_mode_handle != 0) { 1031 gatt_queue_read_op(GATT_READ_CHAR, p_cb->conn_id, p_cb->hid_srvc.proto_mode_handle); 1032 return; 1033 } 1034 1035 /* no service support protocol_mode, by default report mode */ 1036 hs_data.status = BTA_HH_OK; 1037 hs_data.handle = p_cb->hid_handle; 1038 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE; 1039 p_cb->w4_evt = 0; 1040 (* bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH *)&hs_data); 1041 } 1042 1043 /******************************************************************************* 1044 ** 1045 ** Function bta_hh_le_dis_cback 1046 ** 1047 ** Description DIS read complete callback 1048 ** 1049 ** Parameters: 1050 ** 1051 *******************************************************************************/ 1052 void bta_hh_le_dis_cback(BD_ADDR addr, tDIS_VALUE *p_dis_value) 1053 { 1054 tBTA_HH_DEV_CB *p_cb = bta_hh_le_find_dev_cb_by_bda(addr); 1055 1056 1057 if (p_cb == NULL || p_dis_value == NULL) 1058 { 1059 APPL_TRACE_ERROR("received unexpected/error DIS callback"); 1060 return; 1061 } 1062 1063 p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS; 1064 /* plug in the PnP info for this device */ 1065 if (p_dis_value->attr_mask & DIS_ATTR_PNP_ID_BIT) 1066 { 1067 #if BTA_HH_DEBUG == TRUE 1068 APPL_TRACE_DEBUG("Plug in PnP info: product_id = %02x, vendor_id = %04x, version = %04x", 1069 p_dis_value->pnp_id.product_id, 1070 p_dis_value->pnp_id.vendor_id, 1071 p_dis_value->pnp_id.product_version); 1072 #endif 1073 p_cb->dscp_info.product_id = p_dis_value->pnp_id.product_id; 1074 p_cb->dscp_info.vendor_id = p_dis_value->pnp_id.vendor_id; 1075 p_cb->dscp_info.version = p_dis_value->pnp_id.product_version; 1076 } 1077 bta_hh_le_open_cmpl(p_cb); 1078 } 1079 1080 /******************************************************************************* 1081 ** 1082 ** Function bta_hh_le_pri_service_discovery 1083 ** 1084 ** Description Initialize GATT discovery on the remote LE HID device by opening 1085 ** a GATT connection first. 1086 ** 1087 ** Parameters: 1088 ** 1089 *******************************************************************************/ 1090 void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB *p_cb) 1091 { 1092 tBT_UUID pri_srvc; 1093 1094 bta_hh_le_co_reset_rpt_cache(p_cb->addr, p_cb->app_id); 1095 1096 p_cb->disc_active |= (BTA_HH_LE_DISC_HIDS|BTA_HH_LE_DISC_DIS); 1097 1098 /* read DIS info */ 1099 if (!DIS_ReadDISInfo(p_cb->addr, bta_hh_le_dis_cback, DIS_ATTR_PNP_ID_BIT)) 1100 { 1101 APPL_TRACE_ERROR("read DIS failed"); 1102 p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS; 1103 } 1104 1105 /* in parallel */ 1106 /* start primary service discovery for HID service */ 1107 pri_srvc.len = LEN_UUID_16; 1108 pri_srvc.uu.uuid16 = UUID_SERVCLASS_LE_HID; 1109 BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &pri_srvc); 1110 return; 1111 } 1112 1113 /******************************************************************************* 1114 ** 1115 ** Function bta_hh_le_encrypt_cback 1116 ** 1117 ** Description link encryption complete callback for bond verification. 1118 ** 1119 ** Returns None 1120 ** 1121 *******************************************************************************/ 1122 void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, tBTA_GATT_TRANSPORT transport, 1123 void *p_ref_data, tBTM_STATUS result) 1124 { 1125 UINT8 idx = bta_hh_find_cb(bd_addr); 1126 tBTA_HH_DEV_CB *p_dev_cb; 1127 UNUSED(p_ref_data); 1128 UNUSED (transport); 1129 1130 if (idx != BTA_HH_IDX_INVALID) 1131 p_dev_cb = &bta_hh_cb.kdev[idx]; 1132 else 1133 { 1134 APPL_TRACE_ERROR("unexpected encryption callback, ignore"); 1135 return; 1136 } 1137 p_dev_cb->status = (result == BTM_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR_SEC; 1138 p_dev_cb->reason = result; 1139 1140 bta_hh_sm_execute(p_dev_cb, BTA_HH_ENC_CMPL_EVT, NULL); 1141 } 1142 1143 /******************************************************************************* 1144 ** 1145 ** Function bta_hh_security_cmpl 1146 ** 1147 ** Description Security check completed, start the service discovery 1148 ** if no cache available, otherwise report connection open completed 1149 ** 1150 ** Parameters: 1151 ** 1152 *******************************************************************************/ 1153 void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf) 1154 { 1155 UNUSED(p_buf); 1156 1157 APPL_TRACE_DEBUG("%s", __func__); 1158 if (p_cb->status == BTA_HH_OK) 1159 { 1160 if (!p_cb->hid_srvc.in_use) 1161 { 1162 APPL_TRACE_DEBUG("bta_hh_security_cmpl no reports loaded, try to load"); 1163 1164 /* start loading the cache if not in stack */ 1165 //TODO(jpawlowski): cache storage is broken, fix it 1166 // tBTA_HH_RPT_CACHE_ENTRY *p_rpt_cache; 1167 // UINT8 num_rpt = 0; 1168 // if ((p_rpt_cache = bta_hh_le_co_cache_load(p_cb->addr, &num_rpt, p_cb->app_id)) != NULL) 1169 // { 1170 // bta_hh_process_cache_rpt(p_cb, p_rpt_cache, num_rpt); 1171 // } 1172 } 1173 /* discovery has been done for HID service */ 1174 if (p_cb->app_id != 0 && p_cb->hid_srvc.in_use) 1175 { 1176 APPL_TRACE_DEBUG("%s: discovery has been done for HID service", __func__); 1177 /* configure protocol mode */ 1178 if (bta_hh_le_set_protocol_mode(p_cb, p_cb->mode) == FALSE) 1179 { 1180 bta_hh_le_open_cmpl(p_cb); 1181 } 1182 } 1183 /* start primary service discovery for HID service */ 1184 else 1185 { 1186 APPL_TRACE_DEBUG("%s: Starting service discovery", __func__); 1187 bta_hh_le_pri_service_discovery(p_cb); 1188 } 1189 } 1190 else 1191 { 1192 APPL_TRACE_ERROR("%s() - encryption failed; status=0x%04x, reason=0x%04x", 1193 __FUNCTION__, p_cb->status, p_cb->reason); 1194 if (!(p_cb->status == BTA_HH_ERR_SEC && p_cb->reason == BTM_ERR_PROCESSING)) 1195 bta_hh_le_api_disc_act(p_cb); 1196 } 1197 } 1198 1199 /******************************************************************************* 1200 ** 1201 ** Function bta_hh_le_notify_enc_cmpl 1202 ** 1203 ** Description process GATT encryption complete event 1204 ** 1205 ** Returns 1206 ** 1207 *******************************************************************************/ 1208 void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf) 1209 { 1210 if (p_cb == NULL || p_cb->security_pending == FALSE || 1211 p_buf == NULL || p_buf->le_enc_cmpl.client_if != bta_hh_cb.gatt_if) 1212 { 1213 return; 1214 } 1215 1216 p_cb->security_pending = FALSE; 1217 bta_hh_start_security(p_cb, NULL); 1218 } 1219 1220 /******************************************************************************* 1221 ** 1222 ** Function bta_hh_clear_service_cache 1223 ** 1224 ** Description clear the service cache 1225 ** 1226 ** Parameters: 1227 ** 1228 *******************************************************************************/ 1229 void bta_hh_clear_service_cache(tBTA_HH_DEV_CB *p_cb) 1230 { 1231 tBTA_HH_LE_HID_SRVC *p_hid_srvc = &p_cb->hid_srvc; 1232 1233 p_cb->app_id = 0; 1234 p_cb->dscp_info.descriptor.dsc_list = NULL; 1235 1236 osi_free_and_reset((void **)&p_hid_srvc->rpt_map); 1237 memset(p_hid_srvc, 0, sizeof(tBTA_HH_LE_HID_SRVC)); 1238 } 1239 1240 /******************************************************************************* 1241 ** 1242 ** Function bta_hh_start_security 1243 ** 1244 ** Description start the security check of the established connection 1245 ** 1246 ** Parameters: 1247 ** 1248 *******************************************************************************/ 1249 void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf) 1250 { 1251 UINT8 sec_flag=0; 1252 tBTM_SEC_DEV_REC *p_dev_rec; 1253 UNUSED(p_buf); 1254 1255 p_dev_rec = btm_find_dev(p_cb->addr); 1256 if (p_dev_rec) 1257 { 1258 if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING || 1259 p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING) 1260 { 1261 /* if security collision happened, wait for encryption done */ 1262 p_cb->security_pending = TRUE; 1263 return; 1264 } 1265 } 1266 1267 /* verify bond */ 1268 BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE); 1269 1270 /* if link has been encrypted */ 1271 if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) 1272 { 1273 bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL); 1274 } 1275 /* if bonded and link not encrypted */ 1276 else if (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) 1277 { 1278 sec_flag = BTM_BLE_SEC_ENCRYPT; 1279 p_cb->status = BTA_HH_ERR_AUTH_FAILED; 1280 BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, NULL, sec_flag); 1281 } 1282 /* unbonded device, report security error here */ 1283 else if (p_cb->sec_mask != BTA_SEC_NONE) 1284 { 1285 sec_flag = BTM_BLE_SEC_ENCRYPT_NO_MITM; 1286 p_cb->status = BTA_HH_ERR_AUTH_FAILED; 1287 bta_hh_clear_service_cache(p_cb); 1288 BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, NULL, sec_flag); 1289 } 1290 /* otherwise let it go through */ 1291 else 1292 { 1293 bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL); 1294 } 1295 1296 1297 } 1298 1299 /******************************************************************************* 1300 ** 1301 ** Function bta_hh_gatt_open 1302 ** 1303 ** Description process GATT open event. 1304 ** 1305 ** Parameters: 1306 ** 1307 *******************************************************************************/ 1308 void bta_hh_gatt_open(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf) 1309 { 1310 tBTA_GATTC_OPEN *p_data = &p_buf->le_open; 1311 UINT8 *p2; 1312 tHID_STATUS status = BTA_HH_ERR; 1313 1314 /* if received invalid callback data , ignore it */ 1315 if (p_cb == NULL || p_data == NULL) 1316 return; 1317 1318 p2 = p_data->remote_bda; 1319 1320 APPL_TRACE_DEBUG("bta_hh_gatt_open BTA_GATTC_OPEN_EVT bda= [%08x%04x] status =%d", 1321 ((p2[0])<<24)+((p2[1])<<16)+((p2[2])<<8)+(p2[3]), 1322 ((p2[4])<<8)+ p2[5],p_data->status); 1323 1324 if (p_data->status == BTA_GATT_OK) 1325 { 1326 p_cb->is_le_device = TRUE; 1327 p_cb->in_use = TRUE; 1328 p_cb->conn_id = p_data->conn_id; 1329 p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index); 1330 1331 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; 1332 1333 gatt_op_queue_clean(p_cb->conn_id); 1334 1335 #if BTA_HH_DEBUG == TRUE 1336 APPL_TRACE_DEBUG("hid_handle = %2x conn_id = %04x cb_index = %d", p_cb->hid_handle, p_cb->conn_id, p_cb->index); 1337 #endif 1338 1339 bta_hh_sm_execute(p_cb, BTA_HH_START_ENC_EVT, NULL); 1340 1341 } 1342 else /* open failure */ 1343 { 1344 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status); 1345 } 1346 1347 } 1348 1349 /******************************************************************************* 1350 ** 1351 ** Function bta_hh_le_close 1352 ** 1353 ** Description This function process the GATT close event and post it as a 1354 ** BTA HH internal event 1355 ** 1356 ** Parameters: 1357 ** 1358 *******************************************************************************/ 1359 void bta_hh_le_close(tBTA_GATTC_CLOSE * p_data) 1360 { 1361 tBTA_HH_DEV_CB *p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->remote_bda); 1362 UINT16 sm_event = BTA_HH_GATT_CLOSE_EVT; 1363 1364 if (p_dev_cb != NULL) { 1365 tBTA_HH_LE_CLOSE *p_buf = 1366 (tBTA_HH_LE_CLOSE *)osi_malloc(sizeof(tBTA_HH_LE_CLOSE)); 1367 p_buf->hdr.event = sm_event; 1368 p_buf->hdr.layer_specific = (UINT16)p_dev_cb->hid_handle; 1369 p_buf->conn_id = p_data->conn_id; 1370 p_buf->reason = p_data->reason; 1371 1372 p_dev_cb->conn_id = BTA_GATT_INVALID_CONN_ID; 1373 p_dev_cb->security_pending = FALSE; 1374 bta_sys_sendmsg(p_buf); 1375 } 1376 } 1377 1378 /******************************************************************************* 1379 ** 1380 ** Function bta_hh_le_gatt_disc_cmpl 1381 ** 1382 ** Description Check to see if the remote device is a LE only device 1383 ** 1384 ** Parameters: 1385 ** 1386 *******************************************************************************/ 1387 void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_STATUS status) 1388 { 1389 APPL_TRACE_DEBUG("bta_hh_le_gatt_disc_cmpl "); 1390 1391 /* if open sucessful or protocol mode not desired, keep the connection open but inform app */ 1392 if (status == BTA_HH_OK || status == BTA_HH_ERR_PROTO) 1393 { 1394 /* assign a special APP ID temp, since device type unknown */ 1395 p_cb->app_id = BTA_HH_APP_ID_LE; 1396 1397 /* set report notification configuration */ 1398 p_cb->clt_cfg_idx = 0; 1399 bta_hh_le_write_rpt_clt_cfg(p_cb, p_cb->hid_srvc.srvc_inst_id); 1400 } 1401 else /* error, close the GATT connection */ 1402 { 1403 /* close GATT connection if it's on */ 1404 bta_hh_le_api_disc_act(p_cb); 1405 } 1406 } 1407 1408 void process_included(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATTC_SERVICE *service) { 1409 if (!service->included_svc || list_is_empty(service->included_svc)) { 1410 APPL_TRACE_ERROR("%s: Remote device does not have battery level", __func__); 1411 return; 1412 } 1413 1414 for (list_node_t *isn = list_begin(service->included_svc); 1415 isn != list_end(service->included_svc); isn = list_next(isn)) { 1416 tBTA_GATTC_INCLUDED_SVC *p_isvc = list_node(isn); 1417 tBTA_GATTC_SERVICE *incl_svc = p_isvc->included_service; 1418 if (incl_svc->uuid.uu.uuid16 == UUID_SERVCLASS_BATTERY && 1419 incl_svc->uuid.len == LEN_UUID_16) { 1420 1421 /* read include service UUID */ 1422 p_dev_cb->hid_srvc.incl_srvc_inst = incl_svc->handle; 1423 1424 for (list_node_t *cn = list_begin(incl_svc->characteristics); 1425 cn != list_end(incl_svc->characteristics); cn = list_next(cn)) { 1426 tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn); 1427 if (p_char->uuid.uu.uuid16 == GATT_UUID_BATTERY_LEVEL && 1428 p_char->uuid.len == LEN_UUID_16) { 1429 1430 if (bta_hh_le_find_alloc_report_entry(p_dev_cb, 1431 incl_svc->s_handle, 1432 GATT_UUID_BATTERY_LEVEL, 1433 p_char->handle) == NULL) 1434 APPL_TRACE_ERROR("Add battery report entry failed !!!"); 1435 1436 gatt_queue_read_op(GATT_READ_CHAR, p_dev_cb->conn_id, p_char->handle); 1437 return; 1438 } 1439 } 1440 } 1441 } 1442 1443 APPL_TRACE_ERROR("%s: Remote device does not have battery level", __func__); 1444 } 1445 1446 /******************************************************************************* 1447 ** 1448 ** Function bta_hh_le_search_hid_chars 1449 ** 1450 ** Description This function discover all characteristics a service and 1451 ** all descriptors available. 1452 ** 1453 ** Parameters: 1454 ** 1455 *******************************************************************************/ 1456 static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATTC_SERVICE *service) 1457 { 1458 tBTA_HH_LE_RPT *p_rpt; 1459 1460 for (list_node_t *cn = list_begin(service->characteristics); 1461 cn != list_end(service->characteristics); cn = list_next(cn)) { 1462 tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn); 1463 1464 if(p_char->uuid.len != LEN_UUID_16) 1465 continue; 1466 1467 LOG_DEBUG(LOG_TAG, "%s: %s 0x%04d", __func__, bta_hh_uuid_to_str(p_char->uuid.uu.uuid16), 1468 p_char->uuid.uu.uuid16); 1469 1470 switch (p_char->uuid.uu.uuid16) 1471 { 1472 case GATT_UUID_HID_CONTROL_POINT: 1473 p_dev_cb->hid_srvc.control_point_handle = p_char->handle; 1474 break; 1475 case GATT_UUID_HID_INFORMATION: 1476 case GATT_UUID_HID_REPORT_MAP: 1477 /* read the char value */ 1478 gatt_queue_read_op(GATT_READ_CHAR, p_dev_cb->conn_id, p_char->handle); 1479 1480 bta_hh_le_read_char_dscrpt(p_dev_cb, p_char->handle, 1481 GATT_UUID_EXT_RPT_REF_DESCR); 1482 break; 1483 1484 case GATT_UUID_HID_REPORT: 1485 p_rpt = bta_hh_le_find_alloc_report_entry(p_dev_cb, 1486 p_dev_cb->hid_srvc.srvc_inst_id, 1487 GATT_UUID_HID_REPORT, 1488 p_char->handle); 1489 if (p_rpt == NULL) { 1490 APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__); 1491 break; 1492 } 1493 1494 if (p_rpt->rpt_type != BTA_HH_RPTT_INPUT) 1495 break; 1496 1497 bta_hh_le_read_char_dscrpt(p_dev_cb, p_char->handle, GATT_UUID_RPT_REF_DESCR); 1498 break; 1499 1500 /* found boot mode report types */ 1501 case GATT_UUID_HID_BT_KB_OUTPUT: 1502 case GATT_UUID_HID_BT_MOUSE_INPUT: 1503 case GATT_UUID_HID_BT_KB_INPUT: 1504 if (bta_hh_le_find_alloc_report_entry(p_dev_cb, 1505 service->handle, 1506 p_char->uuid.uu.uuid16, 1507 p_char->handle) == NULL) 1508 APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__); 1509 1510 break; 1511 1512 default: 1513 APPL_TRACE_DEBUG("%s: not processing %s 0x%04d", __func__, 1514 bta_hh_uuid_to_str(p_char->uuid.uu.uuid16), 1515 p_char->uuid.uu.uuid16); 1516 } 1517 } 1518 1519 /* Make sure PROTO_MODE is processed as last */ 1520 for (list_node_t *cn = list_begin(service->characteristics); 1521 cn != list_end(service->characteristics); cn = list_next(cn)) { 1522 tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn); 1523 1524 if(p_char->uuid.len != LEN_UUID_16 && 1525 p_char->uuid.uu.uuid16 == GATT_UUID_HID_PROTO_MODE) { 1526 p_dev_cb->hid_srvc.proto_mode_handle = p_char->handle; 1527 bta_hh_le_set_protocol_mode(p_dev_cb, p_dev_cb->mode); 1528 break; 1529 } 1530 } 1531 } 1532 1533 /******************************************************************************* 1534 ** 1535 ** Function bta_hh_le_srvc_search_cmpl 1536 ** 1537 ** Description This function process the GATT service search complete. 1538 ** 1539 ** Parameters: 1540 ** 1541 *******************************************************************************/ 1542 void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL *p_data) 1543 { 1544 tBTA_HH_DEV_CB *p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id); 1545 1546 /* service search exception or no HID service is supported on remote */ 1547 if (p_dev_cb == NULL) 1548 return; 1549 1550 if(p_data->status != BTA_GATT_OK) 1551 { 1552 p_dev_cb->status = BTA_HH_ERR_SDP; 1553 /* close the connection and report service discovery complete with error */ 1554 bta_hh_le_api_disc_act(p_dev_cb); 1555 return; 1556 } 1557 1558 const list_t *services = BTA_GATTC_GetServices(p_data->conn_id); 1559 1560 bool have_hid = false; 1561 for (list_node_t *sn = list_begin(services); 1562 sn != list_end(services); sn = list_next(sn)) { 1563 tBTA_GATTC_SERVICE *service = list_node(sn); 1564 1565 if (service->uuid.uu.uuid16 == UUID_SERVCLASS_LE_HID && 1566 service->is_primary && !have_hid) { 1567 have_hid = true; 1568 1569 /* found HID primamry service */ 1570 p_dev_cb->hid_srvc.in_use = TRUE; 1571 p_dev_cb->hid_srvc.srvc_inst_id = service->handle; 1572 p_dev_cb->hid_srvc.proto_mode_handle = 0; 1573 p_dev_cb->hid_srvc.control_point_handle = 0; 1574 1575 process_included(p_dev_cb, service); 1576 bta_hh_le_search_hid_chars(p_dev_cb, service); 1577 1578 APPL_TRACE_DEBUG("%s: have HID service inst_id= %d", __func__, p_dev_cb->hid_srvc.srvc_inst_id); 1579 } else if (service->uuid.uu.uuid16 == UUID_SERVCLASS_SCAN_PARAM) { 1580 p_dev_cb->scan_refresh_char_handle = 0; 1581 1582 for (list_node_t *cn = list_begin(service->characteristics); 1583 cn != list_end(service->characteristics); cn = list_next(cn)) { 1584 tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn); 1585 if (p_char->uuid.len == LEN_UUID_16 && 1586 p_char->uuid.uu.uuid16 == GATT_UUID_SCAN_REFRESH) { 1587 1588 p_dev_cb->scan_refresh_char_handle = p_char->handle; 1589 1590 if (p_char->properties & BTA_GATT_CHAR_PROP_BIT_NOTIFY) 1591 p_dev_cb->scps_notify |= BTA_HH_LE_SCPS_NOTIFY_SPT; 1592 else 1593 p_dev_cb->scps_notify = BTA_HH_LE_SCPS_NOTIFY_NONE; 1594 1595 break; 1596 } 1597 } 1598 } else if (service->uuid.uu.uuid16 == UUID_SERVCLASS_GAP_SERVER) { 1599 //TODO(jpawlowski): this should be done by GAP profile, remove when GAP is fixed. 1600 for (list_node_t *cn = list_begin(service->characteristics); 1601 cn != list_end(service->characteristics); cn = list_next(cn)) { 1602 tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn); 1603 if (p_char->uuid.len == LEN_UUID_16 && 1604 p_char->uuid.uu.uuid16 == GATT_UUID_GAP_PREF_CONN_PARAM) { 1605 1606 /* read the char value */ 1607 gatt_queue_read_op(GATT_READ_CHAR, p_dev_cb->conn_id, p_char->handle); 1608 1609 break; 1610 } 1611 } 1612 } 1613 } 1614 1615 bta_hh_le_gatt_disc_cmpl(p_dev_cb, p_dev_cb->status); 1616 } 1617 1618 /******************************************************************************* 1619 ** 1620 ** Function bta_hh_read_battery_level_cmpl 1621 ** 1622 ** Description This function process the battery level read 1623 ** 1624 ** Parameters: 1625 ** 1626 *******************************************************************************/ 1627 void bta_hh_read_battery_level_cmpl(UINT8 status, tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATTC_READ *p_data) 1628 { 1629 UNUSED(status); 1630 UNUSED(p_data); 1631 p_dev_cb->hid_srvc.expl_incl_srvc = TRUE; 1632 } 1633 1634 1635 /******************************************************************************* 1636 ** 1637 ** Function bta_hh_le_save_rpt_map 1638 ** 1639 ** Description save the report map into the control block. 1640 ** 1641 ** Parameters: 1642 ** 1643 *******************************************************************************/ 1644 void bta_hh_le_save_rpt_map(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATTC_READ *p_data) 1645 { 1646 tBTA_HH_LE_HID_SRVC *p_srvc = &p_dev_cb->hid_srvc; 1647 1648 osi_free_and_reset((void **)&p_srvc->rpt_map); 1649 1650 if (p_data->p_value->len > 0) 1651 p_srvc->rpt_map = (UINT8 *)osi_malloc(p_data->p_value->len); 1652 1653 if (p_srvc->rpt_map != NULL) 1654 { 1655 UINT8 *pp = p_data->p_value->p_value; 1656 STREAM_TO_ARRAY(p_srvc->rpt_map, pp, p_data->p_value->len); 1657 p_srvc->descriptor.dl_len = p_data->p_value->len; 1658 p_srvc->descriptor.dsc_list = p_dev_cb->hid_srvc.rpt_map; 1659 } 1660 } 1661 1662 /******************************************************************************* 1663 ** 1664 ** Function bta_hh_le_proc_get_rpt_cmpl 1665 ** 1666 ** Description Process the Read report complete, send GET_REPORT_EVT to application 1667 ** with the report data. 1668 ** 1669 ** Parameters: 1670 ** 1671 *******************************************************************************/ 1672 void bta_hh_le_proc_get_rpt_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATTC_READ *p_data) 1673 { 1674 BT_HDR *p_buf = NULL; 1675 tBTA_HH_LE_RPT *p_rpt; 1676 tBTA_HH_HSDATA hs_data; 1677 UINT8 *pp ; 1678 1679 if (p_dev_cb->w4_evt != BTA_HH_GET_RPT_EVT) 1680 { 1681 APPL_TRACE_ERROR("Unexpected READ cmpl, w4_evt = %d", p_dev_cb->w4_evt); 1682 return; 1683 } 1684 1685 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, 1686 p_data->handle); 1687 1688 memset(&hs_data, 0, sizeof(hs_data)); 1689 hs_data.status = BTA_HH_ERR; 1690 hs_data.handle = p_dev_cb->hid_handle; 1691 1692 if (p_data->status == BTA_GATT_OK) 1693 { 1694 p_rpt = bta_hh_le_find_report_entry(p_dev_cb, 1695 p_char->service->handle, 1696 p_char->uuid.uu.uuid16, 1697 p_char->handle); 1698 1699 if (p_rpt != NULL && p_data->p_value != NULL) { 1700 p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + p_data->p_value->len + 1); 1701 /* pack data send to app */ 1702 hs_data.status = BTA_HH_OK; 1703 p_buf->len = p_data->p_value->len + 1; 1704 p_buf->layer_specific = 0; 1705 p_buf->offset = 0; 1706 1707 /* attach report ID as the first byte of the report before sending it to USB HID driver */ 1708 pp = (UINT8*)(p_buf + 1); 1709 UINT8_TO_STREAM(pp, p_rpt->rpt_id); 1710 memcpy(pp, p_data->p_value->p_value, p_data->p_value->len); 1711 1712 hs_data.rsp_data.p_rpt_data =p_buf; 1713 } 1714 } 1715 1716 p_dev_cb->w4_evt = 0; 1717 (* bta_hh_cb.p_cback)(BTA_HH_GET_RPT_EVT, (tBTA_HH *)&hs_data); 1718 1719 osi_free_and_reset((void **)&p_buf); 1720 } 1721 1722 /******************************************************************************* 1723 ** 1724 ** Function bta_hh_le_proc_read_proto_mode 1725 ** 1726 ** Description Process the Read protocol mode, send GET_PROTO_EVT to application 1727 ** with the protocol mode. 1728 ** 1729 *******************************************************************************/ 1730 void bta_hh_le_proc_read_proto_mode(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATTC_READ *p_data) 1731 { 1732 tBTA_HH_HSDATA hs_data; 1733 1734 hs_data.status = BTA_HH_ERR; 1735 hs_data.handle = p_dev_cb->hid_handle; 1736 hs_data.rsp_data.proto_mode = p_dev_cb->mode; 1737 1738 if (p_data->status == BTA_GATT_OK && p_data->p_value) 1739 { 1740 hs_data.status = BTA_HH_OK; 1741 /* match up BTE/BTA report/boot mode def*/ 1742 hs_data.rsp_data.proto_mode = *(p_data->p_value->p_value); 1743 /* LE repot mode is the opposite value of BR/EDR report mode, flip it here */ 1744 if (hs_data.rsp_data.proto_mode == 0) 1745 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_BOOT_MODE; 1746 else 1747 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE; 1748 1749 p_dev_cb->mode = hs_data.rsp_data.proto_mode; 1750 } 1751 #if BTA_HH_DEBUG 1752 APPL_TRACE_DEBUG("LE GET_PROTOCOL Mode = [%s]", 1753 (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)? "Report" : "Boot"); 1754 #endif 1755 1756 p_dev_cb->w4_evt = 0; 1757 (* bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH *)&hs_data); 1758 1759 } 1760 1761 /******************************************************************************* 1762 ** 1763 ** Function bta_hh_w4_le_read_char_cmpl 1764 ** 1765 ** Description process the GATT read complete in W4_CONN state. 1766 ** 1767 ** Parameters: 1768 ** 1769 *******************************************************************************/ 1770 void bta_hh_w4_le_read_char_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 1771 { 1772 tBTA_GATTC_READ * p_data = (tBTA_GATTC_READ *)p_buf; 1773 UINT8 *pp ; 1774 1775 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, 1776 p_data->handle); 1777 UINT16 char_uuid = p_char->uuid.uu.uuid16; 1778 1779 if (char_uuid == GATT_UUID_BATTERY_LEVEL) 1780 { 1781 bta_hh_read_battery_level_cmpl(p_data->status, p_dev_cb, p_data); 1782 } 1783 else if (char_uuid == GATT_UUID_GAP_PREF_CONN_PARAM) 1784 { 1785 //TODO(jpawlowski): this should be done by GAP profile, remove when GAP is fixed. 1786 UINT8 *pp = p_data->p_value->p_value; 1787 UINT16 min, max, latency, tout; 1788 STREAM_TO_UINT16 (min, pp); 1789 STREAM_TO_UINT16 (max, pp); 1790 STREAM_TO_UINT16 (latency, pp); 1791 STREAM_TO_UINT16 (tout, pp); 1792 1793 // Make sure both min, and max are bigger than 11.25ms, lower values can introduce 1794 // audio issues if A2DP is also active. 1795 if (min < BTM_BLE_CONN_INT_MIN_LIMIT) 1796 min = BTM_BLE_CONN_INT_MIN_LIMIT; 1797 if (max < BTM_BLE_CONN_INT_MIN_LIMIT) 1798 max = BTM_BLE_CONN_INT_MIN_LIMIT; 1799 1800 if (tout < BTM_BLE_CONN_TIMEOUT_MIN_DEF) 1801 tout = BTM_BLE_CONN_TIMEOUT_MIN_DEF; 1802 1803 BTM_BleSetPrefConnParams (p_dev_cb->addr, min, max, latency, tout); 1804 L2CA_UpdateBleConnParams(p_dev_cb->addr, min, max, latency, tout); 1805 } 1806 else 1807 { 1808 if (p_data->status == BTA_GATT_OK && p_data->p_value) 1809 { 1810 pp = p_data->p_value->p_value; 1811 1812 switch (char_uuid) 1813 { 1814 /* save device information */ 1815 case GATT_UUID_HID_INFORMATION: 1816 STREAM_TO_UINT16(p_dev_cb->dscp_info.version, pp); 1817 STREAM_TO_UINT8(p_dev_cb->dscp_info.ctry_code, pp); 1818 STREAM_TO_UINT8(p_dev_cb->dscp_info.flag, pp); 1819 break; 1820 1821 case GATT_UUID_HID_REPORT_MAP: 1822 bta_hh_le_save_rpt_map(p_dev_cb, p_data); 1823 return; 1824 1825 default: 1826 #if BTA_HH_DEBUG == TRUE 1827 APPL_TRACE_ERROR("Unexpected read %s(0x%04x)", 1828 bta_hh_uuid_to_str(char_uuid), char_uuid); 1829 #endif 1830 break; 1831 } 1832 } 1833 else 1834 { 1835 #if BTA_HH_DEBUG == TRUE 1836 APPL_TRACE_ERROR("read uuid %s[0x%04x] error: %d", bta_hh_uuid_to_str(char_uuid), 1837 char_uuid, p_data->status); 1838 #else 1839 APPL_TRACE_ERROR("read uuid [0x%04x] error: %d", char_uuid, p_data->status); 1840 #endif 1841 } 1842 } 1843 1844 } 1845 1846 /******************************************************************************* 1847 ** 1848 ** Function bta_hh_le_read_char_cmpl 1849 ** 1850 ** Description a characteristic value is received. 1851 ** 1852 ** Parameters: 1853 ** 1854 *******************************************************************************/ 1855 void bta_hh_le_read_char_cmpl (tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 1856 { 1857 tBTA_GATTC_READ * p_data = (tBTA_GATTC_READ *)p_buf; 1858 1859 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, 1860 p_data->handle); 1861 UINT16 char_uuid = p_char->uuid.uu.uuid16; 1862 1863 switch (char_uuid) 1864 { 1865 /* GET_REPORT */ 1866 case GATT_UUID_HID_REPORT: 1867 case GATT_UUID_HID_BT_KB_INPUT: 1868 case GATT_UUID_HID_BT_KB_OUTPUT: 1869 case GATT_UUID_HID_BT_MOUSE_INPUT: 1870 case GATT_UUID_BATTERY_LEVEL: /* read battery level */ 1871 bta_hh_le_proc_get_rpt_cmpl(p_dev_cb, p_data); 1872 break; 1873 1874 case GATT_UUID_HID_PROTO_MODE: 1875 bta_hh_le_proc_read_proto_mode(p_dev_cb, p_data); 1876 break; 1877 1878 default: 1879 APPL_TRACE_ERROR("Unexpected Read UUID: 0x%04x", char_uuid); 1880 break; 1881 } 1882 1883 } 1884 1885 /******************************************************************************* 1886 ** 1887 ** Function bta_hh_le_read_descr_cmpl 1888 ** 1889 ** Description read characteristic descriptor is completed in CONN st. 1890 ** 1891 ** Parameters: 1892 ** 1893 *******************************************************************************/ 1894 void bta_hh_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 1895 { 1896 tBTA_HH_LE_RPT *p_rpt; 1897 tBTA_GATTC_READ * p_data = (tBTA_GATTC_READ *)p_buf; 1898 UINT8 *pp; 1899 1900 const tBTA_GATTC_DESCRIPTOR *p_desc = BTA_GATTC_GetDescriptor(p_data->conn_id, p_data->handle); 1901 1902 /* if a report client configuration */ 1903 if (p_desc->uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) 1904 { 1905 if ((p_rpt = bta_hh_le_find_report_entry(p_dev_cb, 1906 p_desc->characteristic->service->handle, 1907 p_desc->characteristic->uuid.uu.uuid16, 1908 p_desc->characteristic->handle)) != NULL) 1909 { 1910 pp = p_data->p_value->p_value; 1911 STREAM_TO_UINT16(p_rpt->client_cfg_value, pp); 1912 1913 APPL_TRACE_DEBUG("Read Client Configuration: 0x%04x", p_rpt->client_cfg_value); 1914 } 1915 } 1916 } 1917 1918 /******************************************************************************* 1919 ** 1920 ** Function bta_hh_w4_le_read_descr_cmpl 1921 ** 1922 ** Description read characteristic descriptor is completed in W4_CONN st. 1923 ** 1924 ** Parameters: 1925 ** 1926 *******************************************************************************/ 1927 void bta_hh_w4_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 1928 { 1929 tBTA_HH_LE_RPT *p_rpt; 1930 tBTA_GATTC_READ * p_data = (tBTA_GATTC_READ *)p_buf; 1931 UINT16 char_uuid16; 1932 1933 if (p_data == NULL) 1934 return; 1935 1936 const tBTA_GATTC_DESCRIPTOR *p_desc = BTA_GATTC_GetDescriptor(p_data->conn_id, p_data->handle); 1937 1938 if (p_desc == NULL) { 1939 APPL_TRACE_ERROR("%s: p_descr is NULL %d", __func__, p_data->handle); 1940 return; 1941 } 1942 1943 char_uuid16 = p_desc->characteristic->uuid.uu.uuid16; 1944 1945 #if BTA_HH_DEBUG == TRUE 1946 APPL_TRACE_DEBUG("bta_hh_w4_le_read_descr_cmpl uuid: %s(0x%04x)", 1947 bta_hh_uuid_to_str(p_desc->uuid.uu.uuid16), 1948 p_desc->uuid.uu.uuid16); 1949 #endif 1950 switch (char_uuid16) 1951 { 1952 case GATT_UUID_HID_REPORT: 1953 if ((p_rpt = bta_hh_le_find_report_entry(p_dev_cb, 1954 p_desc->characteristic->service->handle, 1955 GATT_UUID_HID_REPORT, 1956 p_desc->characteristic->handle))) 1957 bta_hh_le_save_rpt_ref(p_dev_cb, p_rpt, p_data); 1958 break; 1959 1960 case GATT_UUID_HID_REPORT_MAP: 1961 bta_hh_le_save_ext_rpt_ref(p_dev_cb, p_data); 1962 break; 1963 1964 case GATT_UUID_BATTERY_LEVEL: 1965 if ((p_rpt = bta_hh_le_find_report_entry(p_dev_cb, 1966 p_desc->characteristic->service->handle, 1967 GATT_UUID_BATTERY_LEVEL, 1968 p_desc->characteristic->handle))) 1969 bta_hh_le_save_rpt_ref(p_dev_cb, p_rpt, p_data); 1970 1971 break; 1972 1973 default: 1974 APPL_TRACE_ERROR("unknown descriptor read complete for uuid: 0x%04x", char_uuid16); 1975 break; 1976 } 1977 } 1978 1979 /******************************************************************************* 1980 ** 1981 ** Function bta_hh_w4_le_write_cmpl 1982 ** 1983 ** Description Write charactersitic complete event at W4_CONN st. 1984 ** 1985 ** Parameters: 1986 ** 1987 *******************************************************************************/ 1988 void bta_hh_w4_le_write_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 1989 { 1990 tBTA_GATTC_WRITE *p_data = (tBTA_GATTC_WRITE *)p_buf; 1991 1992 if (p_data == NULL) 1993 return; 1994 1995 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, 1996 p_data->handle); 1997 1998 if (p_char->uuid.uu.uuid16 == GATT_UUID_HID_PROTO_MODE) 1999 { 2000 p_dev_cb->status = (p_data->status == BTA_GATT_OK) ? BTA_HH_OK : BTA_HH_ERR_PROTO; 2001 2002 if ((p_dev_cb->disc_active & BTA_HH_LE_DISC_HIDS) == 0) 2003 bta_hh_le_open_cmpl(p_dev_cb); 2004 } 2005 } 2006 2007 /******************************************************************************* 2008 ** 2009 ** Function bta_hh_le_write_cmpl 2010 ** 2011 ** Description Write charactersitic complete event at CONN st. 2012 ** 2013 ** Parameters: 2014 ** 2015 *******************************************************************************/ 2016 void bta_hh_le_write_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 2017 { 2018 tBTA_GATTC_WRITE *p_data = (tBTA_GATTC_WRITE *)p_buf; 2019 tBTA_HH_CBDATA cback_data ; 2020 UINT16 cb_evt = p_dev_cb->w4_evt; 2021 2022 if (p_data == NULL || cb_evt == 0) 2023 return; 2024 2025 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, 2026 p_data->handle); 2027 2028 #if BTA_HH_DEBUG 2029 APPL_TRACE_DEBUG("bta_hh_le_write_cmpl w4_evt: %d", p_dev_cb->w4_evt); 2030 #endif 2031 switch (p_char->uuid.uu.uuid16) 2032 { 2033 /* Set protocol finished */ 2034 case GATT_UUID_HID_PROTO_MODE: 2035 cback_data.handle = p_dev_cb->hid_handle; 2036 if (p_data->status == BTA_GATT_OK) 2037 { 2038 bta_hh_le_register_input_notif(p_dev_cb, p_dev_cb->mode, FALSE); 2039 cback_data.status = BTA_HH_OK; 2040 } 2041 else 2042 cback_data.status = BTA_HH_ERR; 2043 p_dev_cb->w4_evt = 0; 2044 (* bta_hh_cb.p_cback)(cb_evt, (tBTA_HH *)&cback_data); 2045 break; 2046 2047 /* Set Report finished */ 2048 case GATT_UUID_HID_REPORT: 2049 case GATT_UUID_HID_BT_KB_INPUT: 2050 case GATT_UUID_HID_BT_MOUSE_INPUT: 2051 case GATT_UUID_HID_BT_KB_OUTPUT: 2052 cback_data.handle = p_dev_cb->hid_handle; 2053 cback_data.status = (p_data->status == BTA_GATT_OK)? BTA_HH_OK : BTA_HH_ERR; 2054 p_dev_cb->w4_evt = 0; 2055 (* bta_hh_cb.p_cback)(cb_evt, (tBTA_HH *)&cback_data); 2056 break; 2057 2058 case GATT_UUID_SCAN_INT_WINDOW: 2059 bta_hh_le_register_scpp_notif(p_dev_cb, p_data->status); 2060 break; 2061 2062 default: 2063 break; 2064 } 2065 2066 } 2067 2068 /******************************************************************************* 2069 ** 2070 ** Function bta_hh_le_write_char_descr_cmpl 2071 ** 2072 ** Description Write charactersitic descriptor complete event 2073 ** 2074 ** Parameters: 2075 ** 2076 *******************************************************************************/ 2077 void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 2078 { 2079 tBTA_GATTC_WRITE *p_data = (tBTA_GATTC_WRITE *)p_buf; 2080 UINT8 srvc_inst_id, hid_inst_id; 2081 2082 const tBTA_GATTC_DESCRIPTOR *p_desc = BTA_GATTC_GetDescriptor(p_dev_cb->conn_id, 2083 p_data->handle); 2084 2085 UINT16 desc_uuid = p_desc->uuid.uu.uuid16; 2086 UINT16 char_uuid = p_desc->characteristic->uuid.uu.uuid16; 2087 /* only write client configuration possible */ 2088 if (desc_uuid == GATT_UUID_CHAR_CLIENT_CONFIG) 2089 { 2090 srvc_inst_id = p_desc->characteristic->service->handle; 2091 hid_inst_id = srvc_inst_id; 2092 switch (char_uuid) 2093 { 2094 case GATT_UUID_BATTERY_LEVEL: /* battery level clt cfg registered */ 2095 hid_inst_id = bta_hh_le_find_service_inst_by_battery_inst_id(p_dev_cb, srvc_inst_id); 2096 /* fall through */ 2097 case GATT_UUID_HID_BT_KB_INPUT: 2098 case GATT_UUID_HID_BT_MOUSE_INPUT: 2099 case GATT_UUID_HID_REPORT: 2100 if (p_data->status == BTA_GATT_OK) 2101 p_dev_cb->hid_srvc.report[p_dev_cb->clt_cfg_idx].client_cfg_value = 2102 BTA_GATT_CLT_CONFIG_NOTIFICATION; 2103 p_dev_cb->clt_cfg_idx ++; 2104 bta_hh_le_write_rpt_clt_cfg(p_dev_cb, hid_inst_id); 2105 2106 break; 2107 2108 case GATT_UUID_SCAN_REFRESH: 2109 bta_hh_le_register_scpp_notif_cmpl(p_dev_cb, p_data->status); 2110 break; 2111 2112 default: 2113 APPL_TRACE_ERROR("Unknown char ID clt cfg: 0x%04x", char_uuid); 2114 } 2115 } 2116 else 2117 { 2118 #if BTA_HH_DEBUG == TRUE 2119 APPL_TRACE_ERROR("Unexpected write to %s(0x%04x)", 2120 bta_hh_uuid_to_str(desc_uuid), desc_uuid); 2121 #else 2122 APPL_TRACE_ERROR("Unexpected write to (0x%04x)", desc_uuid); 2123 #endif 2124 } 2125 2126 } 2127 2128 /******************************************************************************* 2129 ** 2130 ** Function bta_hh_le_input_rpt_notify 2131 ** 2132 ** Description process the notificaton event, most likely for input report. 2133 ** 2134 ** Parameters: 2135 ** 2136 *******************************************************************************/ 2137 void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY *p_data) 2138 { 2139 tBTA_HH_DEV_CB *p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id); 2140 UINT8 app_id; 2141 UINT8 *p_buf; 2142 tBTA_HH_LE_RPT *p_rpt; 2143 2144 if (p_dev_cb == NULL) 2145 { 2146 APPL_TRACE_ERROR("notification received from Unknown device"); 2147 return; 2148 } 2149 2150 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, 2151 p_data->handle); 2152 2153 app_id= p_dev_cb->app_id; 2154 2155 p_rpt = bta_hh_le_find_report_entry(p_dev_cb, 2156 p_dev_cb->hid_srvc.srvc_inst_id, 2157 p_char->uuid.uu.uuid16, 2158 p_char->handle); 2159 if (p_rpt == NULL) 2160 { 2161 APPL_TRACE_ERROR("notification received for Unknown Report"); 2162 return; 2163 } 2164 2165 if (p_char->uuid.uu.uuid16 == GATT_UUID_HID_BT_MOUSE_INPUT) 2166 app_id = BTA_HH_APP_ID_MI; 2167 else if (p_char->uuid.uu.uuid16 == GATT_UUID_HID_BT_KB_INPUT) 2168 app_id = BTA_HH_APP_ID_KB; 2169 2170 APPL_TRACE_DEBUG("Notification received on report ID: %d", p_rpt->rpt_id); 2171 2172 /* need to append report ID to the head of data */ 2173 if (p_rpt->rpt_id != 0) 2174 { 2175 p_buf = (UINT8 *)osi_malloc(p_data->len + 1); 2176 2177 p_buf[0] = p_rpt->rpt_id; 2178 memcpy(&p_buf[1], p_data->value, p_data->len); 2179 ++p_data->len; 2180 } else { 2181 p_buf = p_data->value; 2182 } 2183 2184 bta_hh_co_data((UINT8)p_dev_cb->hid_handle, 2185 p_buf, 2186 p_data->len, 2187 p_dev_cb->mode, 2188 0 , /* no sub class*/ 2189 p_dev_cb->dscp_info.ctry_code, 2190 p_dev_cb->addr, 2191 app_id); 2192 2193 if (p_buf != p_data->value) 2194 osi_free(p_buf); 2195 } 2196 2197 /******************************************************************************* 2198 ** 2199 ** Function bta_hh_gatt_open_fail 2200 ** 2201 ** Description action function to process the open fail 2202 ** 2203 ** Returns void 2204 ** 2205 *******************************************************************************/ 2206 void bta_hh_le_open_fail(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) 2207 { 2208 tBTA_HH_CONN conn_dat ; 2209 2210 /* open failure in the middle of service discovery, clear all services */ 2211 if (p_cb->disc_active & BTA_HH_LE_DISC_HIDS) 2212 { 2213 bta_hh_clear_service_cache(p_cb); 2214 } 2215 2216 p_cb->disc_active = BTA_HH_LE_DISC_NONE; 2217 /* Failure in opening connection or GATT discovery failure */ 2218 conn_dat.handle = p_cb->hid_handle; 2219 memcpy(conn_dat.bda, p_cb->addr, BD_ADDR_LEN); 2220 conn_dat.le_hid = TRUE; 2221 conn_dat.scps_supported = p_cb->scps_supported; 2222 2223 if (p_cb->status == BTA_HH_OK) 2224 conn_dat.status = (p_data->le_close.reason == BTA_GATT_CONN_UNKNOWN) ? p_cb->status : BTA_HH_ERR; 2225 else 2226 conn_dat.status = p_cb->status; 2227 2228 /* Report OPEN fail event */ 2229 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat); 2230 2231 } 2232 2233 /******************************************************************************* 2234 ** 2235 ** Function bta_hh_gatt_close 2236 ** 2237 ** Description action function to process the GATT close int he state machine. 2238 ** 2239 ** Returns void 2240 ** 2241 *******************************************************************************/ 2242 void bta_hh_gatt_close(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) 2243 { 2244 tBTA_HH_CBDATA disc_dat = {BTA_HH_OK, 0}; 2245 2246 /* deregister all notification */ 2247 bta_hh_le_deregister_input_notif(p_cb); 2248 /* finaliza device driver */ 2249 bta_hh_co_close(p_cb->hid_handle, p_cb->app_id); 2250 /* update total conn number */ 2251 bta_hh_cb.cnt_num --; 2252 2253 disc_dat.handle = p_cb->hid_handle; 2254 disc_dat.status = p_cb->status; 2255 2256 (*bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, (tBTA_HH *)&disc_dat); 2257 2258 /* if no connection is active and HH disable is signaled, disable service */ 2259 if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) 2260 { 2261 bta_hh_disc_cmpl(); 2262 } 2263 else 2264 { 2265 #if (BTA_HH_LE_RECONN == TRUE) 2266 if (p_data->le_close.reason == BTA_GATT_CONN_TIMEOUT) 2267 { 2268 bta_hh_le_add_dev_bg_conn(p_cb, FALSE); 2269 } 2270 #endif 2271 } 2272 2273 return; 2274 2275 } 2276 2277 /******************************************************************************* 2278 ** 2279 ** Function bta_hh_le_api_disc_act 2280 ** 2281 ** Description initaite a Close API to a remote HID device 2282 ** 2283 ** Returns void 2284 ** 2285 *******************************************************************************/ 2286 void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB *p_cb) 2287 { 2288 if (p_cb->conn_id != BTA_GATT_INVALID_CONN_ID) 2289 { 2290 gatt_op_queue_clean(p_cb->conn_id); 2291 BTA_GATTC_Close(p_cb->conn_id); 2292 /* remove device from background connection if intended to disconnect, 2293 do not allow reconnection */ 2294 bta_hh_le_remove_dev_bg_conn(p_cb); 2295 } 2296 } 2297 2298 /******************************************************************************* 2299 ** 2300 ** Function bta_hh_le_get_rpt 2301 ** 2302 ** Description GET_REPORT on a LE HID Report 2303 ** 2304 ** Returns void 2305 ** 2306 *******************************************************************************/ 2307 void bta_hh_le_get_rpt(tBTA_HH_DEV_CB *p_cb, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id) 2308 { 2309 tBTA_HH_LE_RPT *p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id); 2310 2311 if (p_rpt == NULL) { 2312 APPL_TRACE_ERROR("%s: no matching report", __func__); 2313 return; 2314 } 2315 2316 p_cb->w4_evt = BTA_HH_GET_RPT_EVT; 2317 gatt_queue_read_op(GATT_READ_CHAR, p_cb->conn_id, p_rpt->char_inst_id); 2318 } 2319 2320 /******************************************************************************* 2321 ** 2322 ** Function bta_hh_le_write_rpt 2323 ** 2324 ** Description SET_REPORT/or DATA output on a LE HID Report 2325 ** 2326 ** Returns void 2327 ** 2328 *******************************************************************************/ 2329 void bta_hh_le_write_rpt(tBTA_HH_DEV_CB *p_cb, 2330 tBTA_HH_RPT_TYPE r_type, 2331 BT_HDR *p_buf, UINT16 w4_evt ) 2332 { 2333 tBTA_HH_LE_RPT *p_rpt; 2334 UINT8 *p_value, rpt_id; 2335 2336 if (p_buf == NULL || p_buf->len == 0) 2337 { 2338 APPL_TRACE_ERROR("bta_hh_le_write_rpt: Illegal data"); 2339 return; 2340 } 2341 2342 /* strip report ID from the data */ 2343 p_value = (UINT8 *)(p_buf + 1) + p_buf->offset; 2344 STREAM_TO_UINT8(rpt_id, p_value); 2345 p_buf->len -= 1; 2346 2347 p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id); 2348 2349 if (p_rpt == NULL) { 2350 APPL_TRACE_ERROR("%s: no matching report", __func__); 2351 osi_free(p_buf); 2352 return; 2353 } 2354 2355 p_cb->w4_evt = w4_evt; 2356 2357 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_cb->conn_id, 2358 p_rpt->char_inst_id); 2359 2360 tBTA_GATTC_WRITE_TYPE write_type = BTA_GATTC_TYPE_WRITE; 2361 if (p_char && (p_char->properties & BTA_GATT_CHAR_PROP_BIT_WRITE_NR)) 2362 write_type = BTA_GATTC_TYPE_WRITE_NO_RSP; 2363 2364 gatt_queue_write_op(GATT_WRITE_CHAR, p_cb->conn_id, p_rpt->char_inst_id, 2365 p_buf->len, p_value, write_type); 2366 } 2367 2368 /******************************************************************************* 2369 ** 2370 ** Function bta_hh_le_suspend 2371 ** 2372 ** Description send LE suspend or exit suspend mode to remote device. 2373 ** 2374 ** Returns void 2375 ** 2376 *******************************************************************************/ 2377 void bta_hh_le_suspend(tBTA_HH_DEV_CB *p_cb, tBTA_HH_TRANS_CTRL_TYPE ctrl_type) 2378 { 2379 ctrl_type -= BTA_HH_CTRL_SUSPEND; 2380 2381 gatt_queue_write_op(GATT_WRITE_CHAR, p_cb->conn_id, p_cb->hid_srvc.control_point_handle, 1, 2382 &ctrl_type, BTA_GATTC_TYPE_WRITE_NO_RSP); 2383 } 2384 2385 /******************************************************************************* 2386 ** 2387 ** Function bta_hh_le_write_dev_act 2388 ** 2389 ** Description Write LE device action. can be SET/GET/DATA transaction. 2390 ** 2391 ** Returns void 2392 ** 2393 *******************************************************************************/ 2394 void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) 2395 { 2396 switch(p_data->api_sndcmd.t_type) 2397 { 2398 case HID_TRANS_SET_PROTOCOL: 2399 p_cb->w4_evt = BTA_HH_SET_PROTO_EVT; 2400 bta_hh_le_set_protocol_mode(p_cb, p_data->api_sndcmd.param); 2401 break; 2402 2403 case HID_TRANS_GET_PROTOCOL: 2404 bta_hh_le_get_protocol_mode(p_cb); 2405 break; 2406 2407 case HID_TRANS_GET_REPORT: 2408 bta_hh_le_get_rpt(p_cb, 2409 p_data->api_sndcmd.param, 2410 p_data->api_sndcmd.rpt_id); 2411 break; 2412 2413 case HID_TRANS_SET_REPORT: 2414 bta_hh_le_write_rpt(p_cb, 2415 p_data->api_sndcmd.param, 2416 p_data->api_sndcmd.p_data, 2417 BTA_HH_SET_RPT_EVT); 2418 break; 2419 2420 case HID_TRANS_DATA: /* output report */ 2421 2422 bta_hh_le_write_rpt(p_cb, 2423 p_data->api_sndcmd.param, 2424 p_data->api_sndcmd.p_data, 2425 BTA_HH_DATA_EVT); 2426 break; 2427 2428 case HID_TRANS_CONTROL: 2429 /* no handshake event will be generated */ 2430 /* if VC_UNPLUG is issued, set flag */ 2431 if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND || 2432 p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND) 2433 { 2434 bta_hh_le_suspend(p_cb, p_data->api_sndcmd.param); 2435 } 2436 break; 2437 2438 default: 2439 APPL_TRACE_ERROR("%s unsupported transaction for BLE HID device: %d", 2440 __func__, p_data->api_sndcmd.t_type); 2441 break; 2442 } 2443 } 2444 2445 /******************************************************************************* 2446 ** 2447 ** Function bta_hh_le_get_dscp_act 2448 ** 2449 ** Description Send ReportDescriptor to application for all HID services. 2450 ** 2451 ** Returns void 2452 ** 2453 *******************************************************************************/ 2454 void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB *p_cb) 2455 { 2456 if (p_cb->hid_srvc.in_use) 2457 { 2458 p_cb->dscp_info.descriptor.dl_len = p_cb->hid_srvc.descriptor.dl_len; 2459 p_cb->dscp_info.descriptor.dsc_list = p_cb->hid_srvc.descriptor.dsc_list; 2460 2461 (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH *)&p_cb->dscp_info); 2462 } 2463 } 2464 2465 /******************************************************************************* 2466 ** 2467 ** Function bta_hh_le_add_dev_bg_conn 2468 ** 2469 ** Description Remove a LE HID device from back ground connection procedure. 2470 ** 2471 ** Returns void 2472 ** 2473 *******************************************************************************/ 2474 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond) 2475 { 2476 UINT8 sec_flag=0; 2477 BOOLEAN to_add = TRUE; 2478 2479 if (check_bond) 2480 { 2481 /* start reconnection if remote is a bonded device */ 2482 /* verify bond */ 2483 BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE); 2484 2485 if ((sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) == 0) 2486 to_add = FALSE; 2487 } 2488 2489 if (/*p_cb->dscp_info.flag & BTA_HH_LE_NORMAL_CONN &&*/ 2490 !p_cb->in_bg_conn && to_add) 2491 { 2492 /* add device into BG connection to accept remote initiated connection */ 2493 BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE, BTA_GATT_TRANSPORT_LE); 2494 p_cb->in_bg_conn = TRUE; 2495 2496 BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL); 2497 } 2498 return; 2499 } 2500 2501 /******************************************************************************* 2502 ** 2503 ** Function bta_hh_le_add_device 2504 ** 2505 ** Description Add a LE HID device as a known device, and also add the address 2506 ** into back ground connection WL for incoming connection. 2507 ** 2508 ** Returns void 2509 ** 2510 *******************************************************************************/ 2511 UINT8 bta_hh_le_add_device(tBTA_HH_DEV_CB *p_cb, tBTA_HH_MAINT_DEV *p_dev_info) 2512 { 2513 p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index); 2514 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; 2515 2516 /* update DI information */ 2517 bta_hh_update_di_info(p_cb, 2518 p_dev_info->dscp_info.vendor_id, 2519 p_dev_info->dscp_info.product_id, 2520 p_dev_info->dscp_info.version, 2521 p_dev_info->dscp_info.flag); 2522 2523 /* add to BTA device list */ 2524 bta_hh_add_device_to_list(p_cb, p_cb->hid_handle, 2525 p_dev_info->attr_mask, 2526 &p_dev_info->dscp_info.descriptor, 2527 p_dev_info->sub_class, 2528 p_dev_info->dscp_info.ssr_max_latency, 2529 p_dev_info->dscp_info.ssr_min_tout, 2530 p_dev_info->app_id); 2531 2532 bta_hh_le_add_dev_bg_conn(p_cb, FALSE); 2533 2534 return p_cb->hid_handle; 2535 } 2536 2537 /******************************************************************************* 2538 ** 2539 ** Function bta_hh_le_remove_dev_bg_conn 2540 ** 2541 ** Description Remove a LE HID device from back ground connection procedure. 2542 ** 2543 ** Returns void 2544 ** 2545 *******************************************************************************/ 2546 void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB *p_dev_cb) 2547 { 2548 if (p_dev_cb->in_bg_conn) 2549 { 2550 p_dev_cb->in_bg_conn = FALSE; 2551 2552 BTA_GATTC_CancelOpen(bta_hh_cb.gatt_if, p_dev_cb->addr, FALSE); 2553 } 2554 } 2555 2556 /******************************************************************************* 2557 ** 2558 ** Function bta_hh_le_update_scpp 2559 ** 2560 ** Description action function to update the scan parameters on remote HID 2561 ** device 2562 ** 2563 ** Parameters: 2564 ** 2565 *******************************************************************************/ 2566 void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf) 2567 { 2568 UINT8 value[4], *p = value; 2569 tBTA_HH_CBDATA cback_data; 2570 2571 if (!p_dev_cb->is_le_device || 2572 p_dev_cb->mode != BTA_HH_PROTO_RPT_MODE || 2573 p_dev_cb->scps_supported == FALSE) { 2574 APPL_TRACE_ERROR("Can not set ScPP scan paramter as boot host, or remote does not support ScPP "); 2575 2576 cback_data.handle = p_dev_cb->hid_handle; 2577 cback_data.status = BTA_HH_ERR; 2578 (* bta_hh_cb.p_cback)(BTA_HH_UPDATE_SCPP_EVT, (tBTA_HH *)&cback_data); 2579 2580 return; 2581 } 2582 2583 p_dev_cb->w4_evt = BTA_HH_UPDATE_SCPP_EVT; 2584 2585 UINT16_TO_STREAM(p, p_buf->le_scpp_update.scan_int); 2586 UINT16_TO_STREAM(p, p_buf->le_scpp_update.scan_win); 2587 2588 gatt_queue_write_op(GATT_WRITE_CHAR, p_dev_cb->conn_id, p_dev_cb->scan_refresh_char_handle, 2, 2589 value, BTA_GATTC_TYPE_WRITE_NO_RSP); 2590 } 2591 2592 /******************************************************************************* 2593 ** 2594 ** Function bta_hh_gattc_callback 2595 ** 2596 ** Description This is GATT client callback function used in BTA HH. 2597 ** 2598 ** Parameters: 2599 ** 2600 *******************************************************************************/ 2601 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data) 2602 { 2603 tBTA_HH_DEV_CB *p_dev_cb; 2604 UINT16 evt; 2605 #if BTA_HH_DEBUG 2606 APPL_TRACE_DEBUG("bta_hh_gattc_callback event = %d", event); 2607 #endif 2608 if (p_data == NULL) 2609 return; 2610 2611 switch (event) 2612 { 2613 case BTA_GATTC_REG_EVT: /* 0 */ 2614 bta_hh_le_register_cmpl(&p_data->reg_oper); 2615 break; 2616 2617 case BTA_GATTC_DEREG_EVT: /* 1 */ 2618 bta_hh_cleanup_disable(p_data->reg_oper.status); 2619 break; 2620 2621 case BTA_GATTC_OPEN_EVT: /* 2 */ 2622 p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda); 2623 if (p_dev_cb) { 2624 bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA *)&p_data->open); 2625 } 2626 break; 2627 2628 case BTA_GATTC_READ_CHAR_EVT: /* 3 */ 2629 case BTA_GATTC_READ_DESCR_EVT: /* 8 */ 2630 mark_as_not_executing(p_data->read.conn_id); 2631 gatt_execute_next_op(p_data->read.conn_id); 2632 p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->read.conn_id); 2633 if (event == BTA_GATTC_READ_CHAR_EVT) 2634 evt = BTA_HH_GATT_READ_CHAR_CMPL_EVT; 2635 else 2636 evt = BTA_HH_GATT_READ_DESCR_CMPL_EVT; 2637 2638 bta_hh_sm_execute(p_dev_cb, evt, (tBTA_HH_DATA *)&p_data->read); 2639 break; 2640 2641 case BTA_GATTC_WRITE_DESCR_EVT: /* 9 */ 2642 case BTA_GATTC_WRITE_CHAR_EVT: /* 4 */ 2643 mark_as_not_executing(p_data->write.conn_id); 2644 gatt_execute_next_op(p_data->write.conn_id); 2645 p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->write.conn_id); 2646 if (event == BTA_GATTC_WRITE_CHAR_EVT) 2647 evt = BTA_HH_GATT_WRITE_CHAR_CMPL_EVT; 2648 else 2649 evt = BTA_HH_GATT_WRITE_DESCR_CMPL_EVT; 2650 2651 bta_hh_sm_execute(p_dev_cb, evt, (tBTA_HH_DATA *)&p_data->write); 2652 break; 2653 2654 case BTA_GATTC_CLOSE_EVT: /* 5 */ 2655 bta_hh_le_close(&p_data->close); 2656 break; 2657 2658 case BTA_GATTC_SEARCH_CMPL_EVT: /* 6 */ 2659 bta_hh_le_srvc_search_cmpl(&p_data->search_cmpl); 2660 break; 2661 2662 case BTA_GATTC_NOTIF_EVT: /* 10 */ 2663 bta_hh_le_input_rpt_notify(&p_data->notify); 2664 break; 2665 2666 case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */ 2667 p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda); 2668 if (p_dev_cb) { 2669 bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT, 2670 (tBTA_HH_DATA *)&p_data->enc_cmpl); 2671 } 2672 break; 2673 2674 default: 2675 break; 2676 } 2677 } 2678 2679 /******************************************************************************* 2680 ** 2681 ** Function bta_hh_le_hid_read_rpt_clt_cfg 2682 ** 2683 ** Description a test command to read report descriptor client configuration 2684 ** 2685 ** Returns void 2686 ** 2687 *******************************************************************************/ 2688 void bta_hh_le_hid_read_rpt_clt_cfg(BD_ADDR bd_addr, UINT8 rpt_id) 2689 { 2690 tBTA_HH_DEV_CB *p_cb = NULL; 2691 tBTA_HH_LE_RPT *p_rpt ; 2692 UINT8 index = BTA_HH_IDX_INVALID; 2693 2694 index = bta_hh_find_cb(bd_addr); 2695 if ((index = bta_hh_find_cb(bd_addr))== BTA_HH_IDX_INVALID) 2696 { 2697 APPL_TRACE_ERROR("unknown device"); 2698 return; 2699 } 2700 2701 p_cb = &bta_hh_cb.kdev[index]; 2702 2703 p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode, BTA_HH_RPTT_INPUT, rpt_id); 2704 2705 if (p_rpt == NULL) 2706 { 2707 APPL_TRACE_ERROR("bta_hh_le_write_rpt: no matching report"); 2708 return; 2709 } 2710 2711 bta_hh_le_read_char_dscrpt(p_cb, p_rpt->char_inst_id, GATT_UUID_CHAR_CLIENT_CONFIG); 2712 return; 2713 } 2714 2715 /******************************************************************************* 2716 ** 2717 ** Function bta_hh_le_register_scpp_notif 2718 ** 2719 ** Description register scan parameter refresh notitication complete 2720 ** 2721 ** 2722 ** Parameters: 2723 ** 2724 *******************************************************************************/ 2725 static void bta_hh_le_register_scpp_notif(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATT_STATUS status) 2726 { 2727 UINT8 sec_flag=0; 2728 2729 /* if write scan parameter sucessful */ 2730 /* if bonded and notification is not enabled, configure the client configuration */ 2731 if (status == BTA_GATT_OK && 2732 (p_dev_cb->scps_notify & BTA_HH_LE_SCPS_NOTIFY_SPT) != 0 && 2733 (p_dev_cb->scps_notify & BTA_HH_LE_SCPS_NOTIFY_ENB) == 0) 2734 { 2735 BTM_GetSecurityFlagsByTransport(p_dev_cb->addr, &sec_flag, BT_TRANSPORT_LE); 2736 if ((sec_flag & BTM_SEC_FLAG_LKEY_KNOWN)) 2737 { 2738 if (bta_hh_le_write_char_clt_cfg (p_dev_cb, p_dev_cb->scan_refresh_char_handle, 2739 BTA_GATT_CLT_CONFIG_NOTIFICATION)) 2740 { 2741 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, 2742 p_dev_cb->scan_refresh_char_handle); 2743 return; 2744 } 2745 } 2746 } 2747 bta_hh_le_register_scpp_notif_cmpl(p_dev_cb, status); 2748 } 2749 2750 /******************************************************************************* 2751 ** 2752 ** Function bta_hh_le_register_scpp_notif_cmpl 2753 ** 2754 ** Description action function to register scan parameter refresh notitication 2755 ** 2756 ** Parameters: 2757 ** 2758 *******************************************************************************/ 2759 static void bta_hh_le_register_scpp_notif_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATT_STATUS status) 2760 { 2761 tBTA_HH_CBDATA cback_data ; 2762 UINT16 cb_evt = p_dev_cb->w4_evt; 2763 2764 if (status == BTA_GATT_OK) 2765 p_dev_cb->scps_notify = (BTA_HH_LE_SCPS_NOTIFY_ENB | BTA_HH_LE_SCPS_NOTIFY_SPT); 2766 2767 cback_data.handle = p_dev_cb->hid_handle; 2768 cback_data.status = (status == BTA_GATT_OK)? BTA_HH_OK : BTA_HH_ERR; 2769 p_dev_cb->w4_evt = 0; 2770 (* bta_hh_cb.p_cback)(cb_evt, (tBTA_HH *)&cback_data); 2771 } 2772 2773 /******************************************************************************* 2774 ** 2775 ** Function bta_hh_process_cache_rpt 2776 ** 2777 ** Description Process the cached reports 2778 ** 2779 ** Parameters: 2780 ** 2781 *******************************************************************************/ 2782 //TODO(jpawlowski): uncomment when fixed 2783 // static void bta_hh_process_cache_rpt (tBTA_HH_DEV_CB *p_cb, 2784 // tBTA_HH_RPT_CACHE_ENTRY *p_rpt_cache, 2785 // UINT8 num_rpt) 2786 // { 2787 // UINT8 i = 0; 2788 // tBTA_HH_LE_RPT *p_rpt; 2789 2790 // if (num_rpt != 0) /* no cache is found */ 2791 // { 2792 // p_cb->hid_srvc.in_use = TRUE; 2793 2794 // /* set the descriptor info */ 2795 // p_cb->hid_srvc.descriptor.dl_len = 2796 // p_cb->dscp_info.descriptor.dl_len; 2797 // p_cb->hid_srvc.descriptor.dsc_list = 2798 // p_cb->dscp_info.descriptor.dsc_list; 2799 2800 // for (; i <num_rpt; i ++, p_rpt_cache ++) 2801 // { 2802 // if ((p_rpt = bta_hh_le_find_alloc_report_entry (p_cb, 2803 // p_rpt_cache->srvc_inst_id, 2804 // p_rpt_cache->rpt_uuid, 2805 // p_rpt_cache->char_inst_id, 2806 // p_rpt_cache->prop)) == NULL) 2807 // { 2808 // APPL_TRACE_ERROR("bta_hh_process_cache_rpt: allocation report entry failure"); 2809 // break; 2810 // } 2811 // else 2812 // { 2813 // p_rpt->rpt_type = p_rpt_cache->rpt_type; 2814 // p_rpt->rpt_id = p_rpt_cache->rpt_id; 2815 2816 // if(p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || 2817 // p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT || 2818 // (p_rpt->uuid == GATT_UUID_HID_REPORT && p_rpt->rpt_type == BTA_HH_RPTT_INPUT)) 2819 // { 2820 // p_rpt->client_cfg_value = BTA_GATT_CLT_CONFIG_NOTIFICATION; 2821 // } 2822 // } 2823 // } 2824 // } 2825 // } 2826 2827 #endif 2828 2829 2830 2831 2832