1 /****************************************************************************** 2 * 3 * Copyright 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * this file contains GATT utility functions 22 * 23 ******************************************************************************/ 24 #include "bt_target.h" 25 #include "bt_utils.h" 26 #include "osi/include/osi.h" 27 28 #include <string.h> 29 #include "bt_common.h" 30 #include "stdio.h" 31 32 #include "btm_int.h" 33 #include "gatt_api.h" 34 #include "gatt_int.h" 35 #include "gattdefs.h" 36 #include "l2cdefs.h" 37 #include "sdp_api.h" 38 39 using base::StringPrintf; 40 using bluetooth::Uuid; 41 42 /* check if [x, y] and [a, b] have overlapping range */ 43 #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b) ((y) >= (a) && (x) <= (b)) 44 45 #define GATT_GET_NEXT_VALID_HANDLE(x) (((x) / 10 + 1) * 10) 46 47 const char* const op_code_name[] = {"UNKNOWN", 48 "ATT_RSP_ERROR", 49 "ATT_REQ_MTU", 50 "ATT_RSP_MTU", 51 "ATT_REQ_READ_INFO", 52 "ATT_RSP_READ_INFO", 53 "ATT_REQ_FIND_TYPE_VALUE", 54 "ATT_RSP_FIND_TYPE_VALUE", 55 "ATT_REQ_READ_BY_TYPE", 56 "ATT_RSP_READ_BY_TYPE", 57 "ATT_REQ_READ", 58 "ATT_RSP_READ", 59 "ATT_REQ_READ_BLOB", 60 "ATT_RSP_READ_BLOB", 61 "GATT_REQ_READ_MULTI", 62 "GATT_RSP_READ_MULTI", 63 "GATT_REQ_READ_BY_GRP_TYPE", 64 "GATT_RSP_READ_BY_GRP_TYPE", 65 "ATT_REQ_WRITE", 66 "ATT_RSP_WRITE", 67 "ATT_CMD_WRITE", 68 "ATT_SIGN_CMD_WRITE", 69 "ATT_REQ_PREPARE_WRITE", 70 "ATT_RSP_PREPARE_WRITE", 71 "ATT_REQ_EXEC_WRITE", 72 "ATT_RSP_EXEC_WRITE", 73 "Reserved", 74 "ATT_HANDLE_VALUE_NOTIF", 75 "Reserved", 76 "ATT_HANDLE_VALUE_IND", 77 "ATT_HANDLE_VALUE_CONF", 78 "ATT_OP_CODE_MAX"}; 79 80 /******************************************************************************* 81 * 82 * Function gatt_free_pending_ind 83 * 84 * Description Free all pending indications 85 * 86 * Returns None 87 * 88 ******************************************************************************/ 89 void gatt_free_pending_ind(tGATT_TCB* p_tcb) { 90 VLOG(1) << __func__; 91 92 if (p_tcb->pending_ind_q == NULL) return; 93 94 /* release all queued indications */ 95 while (!fixed_queue_is_empty(p_tcb->pending_ind_q)) 96 osi_free(fixed_queue_try_dequeue(p_tcb->pending_ind_q)); 97 fixed_queue_free(p_tcb->pending_ind_q, NULL); 98 p_tcb->pending_ind_q = NULL; 99 } 100 101 /******************************************************************************* 102 * 103 * Function gatt_delete_dev_from_srv_chg_clt_list 104 * 105 * Description Delete a device from the service changed client lit 106 * 107 * Returns None 108 * 109 ******************************************************************************/ 110 void gatt_delete_dev_from_srv_chg_clt_list(const RawAddress& bd_addr) { 111 VLOG(1) << __func__; 112 113 tGATTS_SRV_CHG* p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr); 114 if (p_buf != NULL) { 115 if (gatt_cb.cb_info.p_srv_chg_callback) { 116 /* delete from NV */ 117 tGATTS_SRV_CHG_REQ req; 118 req.srv_chg.bda = bd_addr; 119 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT, 120 &req, NULL); 121 } 122 osi_free(fixed_queue_try_remove_from_queue(gatt_cb.srv_chg_clt_q, p_buf)); 123 } 124 } 125 126 /******************************************************************************* 127 * 128 * Function gatt_set_srv_chg 129 * 130 * Description Set the service changed flag to true 131 * 132 * Returns None 133 * 134 ******************************************************************************/ 135 void gatt_set_srv_chg(void) { 136 VLOG(1) << __func__; 137 138 if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return; 139 140 list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q); 141 for (const list_node_t* node = list_begin(list); node != list_end(list); 142 node = list_next(node)) { 143 VLOG(1) << "found a srv_chg clt"; 144 145 tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node); 146 if (!p_buf->srv_changed) { 147 VLOG(1) << "set srv_changed to true"; 148 p_buf->srv_changed = true; 149 tGATTS_SRV_CHG_REQ req; 150 memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG)); 151 if (gatt_cb.cb_info.p_srv_chg_callback) 152 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT, 153 &req, NULL); 154 } 155 } 156 } 157 158 /******************************************************************************* 159 * 160 * Function gatt_add_pending_ind 161 * 162 * Description Add a pending indication 163 * 164 * Returns Pointer to the current pending indication buffer, NULL no buffer 165 * available 166 * 167 ******************************************************************************/ 168 tGATT_VALUE* gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind) { 169 tGATT_VALUE* p_buf = (tGATT_VALUE*)osi_malloc(sizeof(tGATT_VALUE)); 170 171 VLOG(1) << __func__ << "enqueue a pending indication"; 172 173 memcpy(p_buf, p_ind, sizeof(tGATT_VALUE)); 174 fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf); 175 176 return p_buf; 177 } 178 179 /******************************************************************************* 180 * 181 * Function gatt_add_srv_chg_clt 182 * 183 * Description Add a service chnage client to the service change client queue 184 * 185 * Returns Pointer to the service change client buffer; Null no buffer 186 * available 187 * 188 ******************************************************************************/ 189 tGATTS_SRV_CHG* gatt_add_srv_chg_clt(tGATTS_SRV_CHG* p_srv_chg) { 190 tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)osi_malloc(sizeof(tGATTS_SRV_CHG)); 191 VLOG(1) << __func__ << "enqueue a srv chg client"; 192 193 memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG)); 194 fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf); 195 196 return p_buf; 197 } 198 199 /** 200 * Returns pointer to the handle range buffer starting at handle |handle|, 201 * nullptr 202 * if no buffer available 203 */ 204 tGATT_HDL_LIST_ELEM* gatt_find_hdl_buffer_by_handle(uint16_t handle) { 205 for (auto& elem : *gatt_cb.hdl_list_info) { 206 if (elem.asgn_range.s_handle == handle) return &elem; 207 } 208 209 return nullptr; 210 } 211 /******************************************************************************* 212 * 213 * Description Find handle range buffer by app ID, service and service instance 214 * ID. 215 * 216 * Returns Pointer to the buffer, NULL no buffer available 217 * 218 ******************************************************************************/ 219 std::list<tGATT_HDL_LIST_ELEM>::iterator gatt_find_hdl_buffer_by_app_id( 220 const Uuid& app_uuid128, Uuid* p_svc_uuid, uint16_t start_handle) { 221 auto end_it = gatt_cb.hdl_list_info->end(); 222 auto it = gatt_cb.hdl_list_info->begin(); 223 for (; it != end_it; it++) { 224 if (app_uuid128 == it->asgn_range.app_uuid128 && 225 *p_svc_uuid == it->asgn_range.svc_uuid && 226 (start_handle == it->asgn_range.s_handle)) { 227 return it; 228 } 229 } 230 231 return it; 232 } 233 234 /** 235 * free the service attribute database buffers by the owner of the service app 236 * ID. 237 */ 238 void gatt_free_srvc_db_buffer_app_id(const Uuid& app_id) { 239 auto it = gatt_cb.hdl_list_info->begin(); 240 auto end = gatt_cb.hdl_list_info->end(); 241 while (it != end) { 242 if (app_id == it->asgn_range.app_uuid128) { 243 it = gatt_cb.hdl_list_info->erase(it); 244 } else { 245 it++; 246 } 247 } 248 } 249 250 /******************************************************************************* 251 * 252 * Function gatt_find_the_connected_bda 253 * 254 * Description This function find the connected bda 255 * 256 * Returns true if found 257 * 258 ******************************************************************************/ 259 bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda, 260 uint8_t* p_found_idx, 261 tBT_TRANSPORT* p_transport) { 262 uint8_t i; 263 bool found = false; 264 VLOG(1) << __func__ << " start_idx=" << +start_idx; 265 266 for (i = start_idx; i < GATT_MAX_PHY_CHANNEL; i++) { 267 if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) { 268 bda = gatt_cb.tcb[i].peer_bda; 269 *p_found_idx = i; 270 *p_transport = gatt_cb.tcb[i].transport; 271 found = true; 272 VLOG(1) << " bda :" << bda; 273 break; 274 } 275 } 276 VLOG(1) << StringPrintf(" found=%d found_idx=%d", found, i); 277 return found; 278 } 279 280 /******************************************************************************* 281 * 282 * Function gatt_is_srv_chg_ind_pending 283 * 284 * Description Check whether a service chnaged is in the indication pending 285 * queue or waiting for an Ack already 286 * 287 * Returns bool 288 * 289 ******************************************************************************/ 290 bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb) { 291 VLOG(1) << __func__ 292 << " is_queue_empty=" << fixed_queue_is_empty(p_tcb->pending_ind_q); 293 294 if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) return true; 295 296 if (fixed_queue_is_empty(p_tcb->pending_ind_q)) return false; 297 298 list_t* list = fixed_queue_get_list(p_tcb->pending_ind_q); 299 for (const list_node_t* node = list_begin(list); node != list_end(list); 300 node = list_next(node)) { 301 tGATT_VALUE* p_buf = (tGATT_VALUE*)list_node(node); 302 if (p_buf->handle == gatt_cb.handle_of_h_r) { 303 return true; 304 } 305 } 306 307 return false; 308 } 309 310 /******************************************************************************* 311 * 312 * Function gatt_is_bda_in_the_srv_chg_clt_list 313 * 314 * Description This function check the specified bda is in the srv chg 315 * client list or not 316 * 317 * Returns pointer to the found elemenet otherwise NULL 318 * 319 ******************************************************************************/ 320 tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(const RawAddress& bda) { 321 tGATTS_SRV_CHG* p_buf = NULL; 322 323 VLOG(1) << __func__ << ": " << bda; 324 325 if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return NULL; 326 327 list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q); 328 for (const list_node_t* node = list_begin(list); node != list_end(list); 329 node = list_next(node)) { 330 tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node); 331 if (bda == p_buf->bda) { 332 VLOG(1) << "bda is in the srv chg clt list"; 333 break; 334 } 335 } 336 337 return p_buf; 338 } 339 340 /******************************************************************************* 341 * 342 * Function gatt_is_bda_connected 343 * 344 * Description 345 * 346 * Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 347 * 348 ******************************************************************************/ 349 bool gatt_is_bda_connected(const RawAddress& bda) { 350 uint8_t i = 0; 351 bool connected = false; 352 353 for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) { 354 if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].peer_bda == bda) { 355 connected = true; 356 break; 357 } 358 } 359 return connected; 360 } 361 362 /******************************************************************************* 363 * 364 * Function gatt_find_i_tcb_by_addr 365 * 366 * Description Search for an empty tcb entry, and return the index. 367 * 368 * Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 369 * 370 ******************************************************************************/ 371 uint8_t gatt_find_i_tcb_by_addr(const RawAddress& bda, 372 tBT_TRANSPORT transport) { 373 uint8_t i = 0; 374 375 for (; i < GATT_MAX_PHY_CHANNEL; i++) { 376 if (gatt_cb.tcb[i].peer_bda == bda && 377 gatt_cb.tcb[i].transport == transport) { 378 return i; 379 } 380 } 381 return GATT_INDEX_INVALID; 382 } 383 384 /******************************************************************************* 385 * 386 * Function gatt_get_tcb_by_idx 387 * 388 * Description The function get TCB using the TCB index 389 * 390 * Returns NULL if not found. Otherwise index to the tcb. 391 * 392 ******************************************************************************/ 393 tGATT_TCB* gatt_get_tcb_by_idx(uint8_t tcb_idx) { 394 tGATT_TCB* p_tcb = NULL; 395 396 if ((tcb_idx < GATT_MAX_PHY_CHANNEL) && gatt_cb.tcb[tcb_idx].in_use) 397 p_tcb = &gatt_cb.tcb[tcb_idx]; 398 399 return p_tcb; 400 } 401 402 /******************************************************************************* 403 * 404 * Function gatt_find_tcb_by_addr 405 * 406 * Description Search for an empty tcb entry, and return pointer. 407 * 408 * Returns NULL if not found. Otherwise index to the tcb. 409 * 410 ******************************************************************************/ 411 tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda, 412 tBT_TRANSPORT transport) { 413 tGATT_TCB* p_tcb = NULL; 414 uint8_t i = 0; 415 416 i = gatt_find_i_tcb_by_addr(bda, transport); 417 if (i != GATT_INDEX_INVALID) p_tcb = &gatt_cb.tcb[i]; 418 419 return p_tcb; 420 } 421 422 /******************************************************************************* 423 * 424 * Function gatt_allocate_tcb_by_bdaddr 425 * 426 * Description Locate or allocate a new tcb entry for matching bda. 427 * 428 * Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 429 * 430 ******************************************************************************/ 431 tGATT_TCB* gatt_allocate_tcb_by_bdaddr(const RawAddress& bda, 432 tBT_TRANSPORT transport) { 433 /* search for existing tcb with matching bda */ 434 uint8_t j = gatt_find_i_tcb_by_addr(bda, transport); 435 if (j != GATT_INDEX_INVALID) return &gatt_cb.tcb[j]; 436 437 /* find free tcb */ 438 for (int i = 0; i < GATT_MAX_PHY_CHANNEL; i++) { 439 tGATT_TCB* p_tcb = &gatt_cb.tcb[i]; 440 if (p_tcb->in_use) continue; 441 442 *p_tcb = tGATT_TCB(); 443 444 p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX); 445 p_tcb->conf_timer = alarm_new("gatt.conf_timer"); 446 p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer"); 447 p_tcb->in_use = true; 448 p_tcb->tcb_idx = i; 449 p_tcb->transport = transport; 450 p_tcb->peer_bda = bda; 451 return p_tcb; 452 } 453 454 return NULL; 455 } 456 457 /** gatt_build_uuid_to_stream will convert 32bit UUIDs to 128bit. This function 458 * will return lenght required to build uuid, either |UUID:kNumBytes16| or 459 * |UUID::kNumBytes128| */ 460 uint8_t gatt_build_uuid_to_stream_len(const Uuid& uuid) { 461 size_t len = uuid.GetShortestRepresentationSize(); 462 return len == Uuid::kNumBytes32 ? Uuid::kNumBytes128 : len; 463 } 464 465 /** Add UUID into stream. Returns UUID length. */ 466 uint8_t gatt_build_uuid_to_stream(uint8_t** p_dst, const Uuid& uuid) { 467 uint8_t* p = *p_dst; 468 size_t len = uuid.GetShortestRepresentationSize(); 469 470 if (uuid.IsEmpty()) { 471 return 0; 472 } 473 474 if (len == Uuid::kNumBytes16) { 475 UINT16_TO_STREAM(p, uuid.As16Bit()); 476 } else if (len == Uuid::kNumBytes32) { 477 /* always convert 32 bits into 128 bits */ 478 ARRAY_TO_STREAM(p, uuid.To128BitLE(), (int)Uuid::kNumBytes128); 479 len = Uuid::kNumBytes128; 480 } else if (len == Uuid::kNumBytes128) { 481 ARRAY_TO_STREAM(p, uuid.To128BitLE(), (int)Uuid::kNumBytes128); 482 } 483 484 *p_dst = p; 485 return len; 486 } 487 488 bool gatt_parse_uuid_from_cmd(Uuid* p_uuid_rec, uint16_t uuid_size, 489 uint8_t** p_data) { 490 bool ret = true; 491 uint8_t* p_uuid = *p_data; 492 493 switch (uuid_size) { 494 case Uuid::kNumBytes16: { 495 uint16_t val; 496 STREAM_TO_UINT16(val, p_uuid); 497 *p_uuid_rec = Uuid::From16Bit(val); 498 *p_data += Uuid::kNumBytes16; 499 return true; 500 } 501 502 case Uuid::kNumBytes128: { 503 *p_uuid_rec = Uuid::From128BitLE(p_uuid); 504 *p_data += Uuid::kNumBytes128; 505 return true; 506 } 507 508 /* do not allow 32 bits UUID in ATT PDU now */ 509 case Uuid::kNumBytes32: 510 LOG(ERROR) << "DO NOT ALLOW 32 BITS UUID IN ATT PDU"; 511 return false; 512 case 0: 513 default: 514 if (uuid_size != 0) ret = false; 515 LOG(WARNING) << __func__ << ": invalid uuid size"; 516 break; 517 } 518 519 return (ret); 520 } 521 522 /******************************************************************************* 523 * 524 * Function gatt_start_rsp_timer 525 * 526 * Description Start a wait_for_response timer. 527 * 528 * Returns void 529 * 530 ******************************************************************************/ 531 void gatt_start_rsp_timer(tGATT_CLCB* p_clcb) { 532 period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS; 533 534 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && 535 p_clcb->op_subtype == GATT_DISC_SRVC_ALL) { 536 timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS; 537 } 538 539 // TODO: The tGATT_CLCB memory and state management needs cleanup, 540 // and then the timers can be allocated elsewhere. 541 if (p_clcb->gatt_rsp_timer_ent == NULL) { 542 p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent"); 543 } 544 alarm_set_on_mloop(p_clcb->gatt_rsp_timer_ent, timeout_ms, gatt_rsp_timeout, 545 p_clcb); 546 } 547 548 /******************************************************************************* 549 * 550 * Function gatt_start_conf_timer 551 * 552 * Description Start a wait_for_confirmation timer. 553 * 554 * Returns void 555 * 556 ******************************************************************************/ 557 void gatt_start_conf_timer(tGATT_TCB* p_tcb) { 558 alarm_set_on_mloop(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 559 gatt_indication_confirmation_timeout, p_tcb); 560 } 561 562 /******************************************************************************* 563 * 564 * Function gatt_start_ind_ack_timer 565 * 566 * Description start the application ack timer 567 * 568 * Returns void 569 * 570 ******************************************************************************/ 571 void gatt_start_ind_ack_timer(tGATT_TCB& tcb) { 572 /* start notification cache timer */ 573 alarm_set_on_mloop(tcb.ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 574 gatt_ind_ack_timeout, &tcb); 575 } 576 577 /******************************************************************************* 578 * 579 * Function gatt_rsp_timeout 580 * 581 * Description Called when GATT wait for ATT command response timer expires 582 * 583 * Returns void 584 * 585 ******************************************************************************/ 586 void gatt_rsp_timeout(void* data) { 587 tGATT_CLCB* p_clcb = (tGATT_CLCB*)data; 588 589 if (p_clcb == NULL || p_clcb->p_tcb == NULL) { 590 LOG(WARNING) << __func__ << " clcb is already deleted"; 591 return; 592 } 593 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && 594 p_clcb->op_subtype == GATT_DISC_SRVC_ALL && 595 p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) { 596 uint8_t rsp_code; 597 LOG(WARNING) << __func__ << " retry discovery primary service"; 598 if (p_clcb != gatt_cmd_dequeue(*p_clcb->p_tcb, &rsp_code)) { 599 LOG(ERROR) << __func__ << " command queue out of sync, disconnect"; 600 } else { 601 p_clcb->retry_count++; 602 gatt_act_discovery(p_clcb); 603 return; 604 } 605 } 606 607 LOG(WARNING) << __func__ << " disconnecting..."; 608 gatt_disconnect(p_clcb->p_tcb); 609 } 610 611 /******************************************************************************* 612 * 613 * Function gatt_indication_confirmation_timeout 614 * 615 * Description Called when the indication confirmation timer expires 616 * 617 * Returns void 618 * 619 ******************************************************************************/ 620 void gatt_indication_confirmation_timeout(void* data) { 621 tGATT_TCB* p_tcb = (tGATT_TCB*)data; 622 623 LOG(WARNING) << __func__ << " disconnecting..."; 624 gatt_disconnect(p_tcb); 625 } 626 627 /******************************************************************************* 628 * 629 * Function gatt_ind_ack_timeout 630 * 631 * Description Called when GATT wait for ATT handle confirmation timeout 632 * 633 * Returns void 634 * 635 ******************************************************************************/ 636 void gatt_ind_ack_timeout(void* data) { 637 tGATT_TCB* p_tcb = (tGATT_TCB*)data; 638 CHECK(p_tcb); 639 640 LOG(WARNING) << __func__ << ": send ack now"; 641 p_tcb->ind_count = 0; 642 attp_send_cl_msg(*p_tcb, nullptr, GATT_HANDLE_VALUE_CONF, NULL); 643 } 644 /******************************************************************************* 645 * 646 * Description Search for a service that owns a specific handle. 647 * 648 * Returns GATT_MAX_SR_PROFILES if not found. Otherwise the index of 649 * the service. 650 * 651 ******************************************************************************/ 652 std::list<tGATT_SRV_LIST_ELEM>::iterator gatt_sr_find_i_rcb_by_handle( 653 uint16_t handle) { 654 auto it = gatt_cb.srv_list_info->begin(); 655 656 for (; it != gatt_cb.srv_list_info->end(); it++) { 657 if (it->s_hdl <= handle && it->e_hdl >= handle) { 658 return it; 659 } 660 } 661 662 return it; 663 } 664 665 /******************************************************************************* 666 * 667 * Function gatt_sr_get_sec_info 668 * 669 * Description Get the security flag and key size information for the peer 670 * device. 671 * 672 * Returns void 673 * 674 ******************************************************************************/ 675 void gatt_sr_get_sec_info(const RawAddress& rem_bda, tBT_TRANSPORT transport, 676 uint8_t* p_sec_flag, uint8_t* p_key_size) { 677 uint8_t sec_flag = 0; 678 679 BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport); 680 681 sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | 682 GATT_SEC_FLAG_ENCRYPTED); 683 684 *p_key_size = btm_ble_read_sec_key_size(rem_bda); 685 *p_sec_flag = sec_flag; 686 } 687 /******************************************************************************* 688 * 689 * Function gatt_sr_send_req_callback 690 * 691 * Description 692 * 693 * 694 * Returns void 695 * 696 ******************************************************************************/ 697 void gatt_sr_send_req_callback(uint16_t conn_id, uint32_t trans_id, 698 tGATTS_REQ_TYPE type, tGATTS_DATA* p_data) { 699 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 700 tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 701 702 if (!p_reg) { 703 LOG(ERROR) << "p_reg not found discard request"; 704 return; 705 } 706 707 if (p_reg->in_use && p_reg->app_cb.p_req_cb) { 708 (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data); 709 } else { 710 LOG(WARNING) << "Call back not found for application conn_id=" << conn_id; 711 } 712 } 713 714 /******************************************************************************* 715 * 716 * Function gatt_send_error_rsp 717 * 718 * Description This function sends an error response. 719 * 720 * Returns void 721 * 722 ******************************************************************************/ 723 tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint8_t err_code, 724 uint8_t op_code, uint16_t handle, bool deq) { 725 tGATT_STATUS status; 726 BT_HDR* p_buf; 727 728 tGATT_SR_MSG msg; 729 msg.error.cmd_code = op_code; 730 msg.error.reason = err_code; 731 msg.error.handle = handle; 732 733 p_buf = attp_build_sr_msg(tcb, GATT_RSP_ERROR, &msg); 734 if (p_buf != NULL) { 735 status = attp_send_sr_msg(tcb, p_buf); 736 } else 737 status = GATT_INSUF_RESOURCE; 738 739 if (deq) gatt_dequeue_sr_cmd(tcb); 740 741 return status; 742 } 743 744 /******************************************************************************* 745 * 746 * Function gatt_add_sdp_record 747 * 748 * Description This function add a SDP record for a GATT primary service 749 * 750 * Returns 0 if error else sdp handle for the record. 751 * 752 ******************************************************************************/ 753 uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl, 754 uint16_t end_hdl) { 755 uint8_t buff[60]; 756 uint8_t* p = buff; 757 758 VLOG(1) << __func__ 759 << StringPrintf(" s_hdl=0x%x s_hdl=0x%x", start_hdl, end_hdl); 760 761 uint32_t sdp_handle = SDP_CreateRecord(); 762 if (sdp_handle == 0) return 0; 763 764 switch (uuid.GetShortestRepresentationSize()) { 765 case Uuid::kNumBytes16: { 766 uint16_t tmp = uuid.As16Bit(); 767 SDP_AddServiceClassIdList(sdp_handle, 1, &tmp); 768 break; 769 } 770 771 case Uuid::kNumBytes32: { 772 UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); 773 uint32_t tmp = uuid.As32Bit(); 774 UINT32_TO_BE_STREAM(p, tmp); 775 SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, 776 DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff); 777 break; 778 } 779 780 case Uuid::kNumBytes128: 781 UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); 782 ARRAY_TO_BE_STREAM(p, uuid.To128BitBE().data(), (int)Uuid::kNumBytes128); 783 SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, 784 DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff); 785 break; 786 } 787 788 /*** Fill out the protocol element sequence for SDP ***/ 789 tSDP_PROTOCOL_ELEM proto_elem_list[2]; 790 proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP; 791 proto_elem_list[0].num_params = 1; 792 proto_elem_list[0].params[0] = BT_PSM_ATT; 793 proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT; 794 proto_elem_list[1].num_params = 2; 795 proto_elem_list[1].params[0] = start_hdl; 796 proto_elem_list[1].params[1] = end_hdl; 797 798 SDP_AddProtocolList(sdp_handle, 2, proto_elem_list); 799 800 /* Make the service browseable */ 801 uint16_t list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; 802 SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list); 803 804 return (sdp_handle); 805 } 806 807 #if GATT_CONFORMANCE_TESTING == TRUE 808 /******************************************************************************* 809 * 810 * Function gatt_set_err_rsp 811 * 812 * Description This function is called to set the test confirm value 813 * 814 * Returns void 815 * 816 ******************************************************************************/ 817 void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status) { 818 VLOG(1) << __func__ 819 << StringPrintf(" enable=%d op_code=%d, err_status=%d", enable, 820 req_op_code, err_status); 821 gatt_cb.enable_err_rsp = enable; 822 gatt_cb.req_op_code = req_op_code; 823 gatt_cb.err_status = err_status; 824 } 825 #endif 826 827 /******************************************************************************* 828 * 829 * Function gatt_get_regcb 830 * 831 * Description The function returns the registration control block. 832 * 833 * Returns pointer to the registration control block or NULL 834 * 835 ******************************************************************************/ 836 tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if) { 837 uint8_t ii = (uint8_t)gatt_if; 838 tGATT_REG* p_reg = NULL; 839 840 if (ii < 1 || ii > GATT_MAX_APPS) { 841 LOG(WARNING) << "gatt_if out of range = " << +ii; 842 return NULL; 843 } 844 845 // Index for cl_rcb is always 1 less than gatt_if. 846 p_reg = &gatt_cb.cl_rcb[ii - 1]; 847 848 if (!p_reg->in_use) { 849 LOG(WARNING) << "gatt_if found but not in use."; 850 return NULL; 851 } 852 853 return p_reg; 854 } 855 856 /******************************************************************************* 857 * 858 * Function gatt_is_clcb_allocated 859 * 860 * Description The function check clcb for conn_id is allocated or not 861 * 862 * Returns True already allocated 863 * 864 ******************************************************************************/ 865 866 bool gatt_is_clcb_allocated(uint16_t conn_id) { 867 uint8_t i = 0; 868 bool is_allocated = false; 869 870 for (i = 0; i < GATT_CL_MAX_LCB; i++) { 871 if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id)) { 872 is_allocated = true; 873 break; 874 } 875 } 876 877 return is_allocated; 878 } 879 880 /******************************************************************************* 881 * 882 * Function gatt_clcb_alloc 883 * 884 * Description The function allocates a GATT connection link control block 885 * 886 * Returns NULL if not found. Otherwise pointer to the connection link 887 * block. 888 * 889 ******************************************************************************/ 890 tGATT_CLCB* gatt_clcb_alloc(uint16_t conn_id) { 891 uint8_t i = 0; 892 tGATT_CLCB* p_clcb = NULL; 893 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 894 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 895 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 896 tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 897 898 for (i = 0; i < GATT_CL_MAX_LCB; i++) { 899 if (!gatt_cb.clcb[i].in_use) { 900 p_clcb = &gatt_cb.clcb[i]; 901 902 p_clcb->in_use = true; 903 p_clcb->conn_id = conn_id; 904 p_clcb->p_reg = p_reg; 905 p_clcb->p_tcb = p_tcb; 906 break; 907 } 908 } 909 910 return p_clcb; 911 } 912 913 /******************************************************************************* 914 * 915 * Function gatt_clcb_dealloc 916 * 917 * Description The function de-allocates a GATT connection link control 918 * block 919 * 920 * Returns None 921 * 922 ******************************************************************************/ 923 void gatt_clcb_dealloc(tGATT_CLCB* p_clcb) { 924 if (p_clcb && p_clcb->in_use) { 925 alarm_free(p_clcb->gatt_rsp_timer_ent); 926 memset(p_clcb, 0, sizeof(tGATT_CLCB)); 927 } 928 } 929 930 /******************************************************************************* 931 * 932 * Function gatt_find_tcb_by_cid 933 * 934 * Description The function searches for an empty entry 935 * in registration info table for GATT client 936 * 937 * Returns NULL if not found. Otherwise pointer to the rcb. 938 * 939 ******************************************************************************/ 940 tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid) { 941 uint16_t xx = 0; 942 tGATT_TCB* p_tcb = NULL; 943 944 for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++) { 945 if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid) { 946 p_tcb = &gatt_cb.tcb[xx]; 947 break; 948 } 949 } 950 return p_tcb; 951 } 952 953 /******************************************************************************* 954 * 955 * Function gatt_num_clcb_by_bd_addr 956 * 957 * Description The function searches all LCB with macthing bd address 958 * 959 * Returns total number of clcb found. 960 * 961 ******************************************************************************/ 962 uint8_t gatt_num_clcb_by_bd_addr(const RawAddress& bda) { 963 uint8_t i, num = 0; 964 965 for (i = 0; i < GATT_CL_MAX_LCB; i++) { 966 if (gatt_cb.clcb[i].in_use && gatt_cb.clcb[i].p_tcb->peer_bda == bda) num++; 967 } 968 return num; 969 } 970 971 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB& tcb) { 972 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) { 973 if (tcb.prep_cnt[i]) { 974 tcb.sr_cmd.cback_cnt[i] = 1; 975 } 976 } 977 } 978 979 /******************************************************************************* 980 * 981 * Function gatt_sr_is_cback_cnt_zero 982 * 983 * Description The function searches all LCB with macthing bd address 984 * 985 * Returns True if thetotal application callback count is zero 986 * 987 ******************************************************************************/ 988 bool gatt_sr_is_cback_cnt_zero(tGATT_TCB& tcb) { 989 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) { 990 if (tcb.sr_cmd.cback_cnt[i]) { 991 return false; 992 } 993 } 994 return true; 995 } 996 997 /******************************************************************************* 998 * 999 * Function gatt_sr_is_prep_cnt_zero 1000 * 1001 * Description Check the prepare write request count is zero or not 1002 * 1003 * Returns True no prepare write request 1004 * 1005 ******************************************************************************/ 1006 bool gatt_sr_is_prep_cnt_zero(tGATT_TCB& tcb) { 1007 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) { 1008 if (tcb.prep_cnt[i]) { 1009 return false; 1010 } 1011 } 1012 return true; 1013 } 1014 1015 /******************************************************************************* 1016 * 1017 * Function gatt_sr_reset_cback_cnt 1018 * 1019 * Description Reset the application callback count to zero 1020 * 1021 * Returns None 1022 * 1023 ******************************************************************************/ 1024 void gatt_sr_reset_cback_cnt(tGATT_TCB& tcb) { 1025 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) { 1026 tcb.sr_cmd.cback_cnt[i] = 0; 1027 } 1028 } 1029 1030 /******************************************************************************* 1031 * 1032 * Function gatt_sr_reset_prep_cnt 1033 * 1034 * Description Reset the prep write count to zero 1035 * 1036 * Returns None 1037 * 1038 ******************************************************************************/ 1039 void gatt_sr_reset_prep_cnt(tGATT_TCB& tcb) { 1040 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) { 1041 tcb.prep_cnt[i] = 0; 1042 } 1043 } 1044 1045 /******************************************************************************* 1046 * 1047 * Function gatt_sr_update_cback_cnt 1048 * 1049 * Description Update the teh applicaiton callback count 1050 * 1051 * Returns None 1052 * 1053 ******************************************************************************/ 1054 void gatt_sr_update_cback_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc, 1055 bool is_reset_first) { 1056 uint8_t idx = ((uint8_t)gatt_if) - 1; 1057 1058 if (is_reset_first) { 1059 gatt_sr_reset_cback_cnt(tcb); 1060 } 1061 if (is_inc) { 1062 tcb.sr_cmd.cback_cnt[idx]++; 1063 } else { 1064 if (tcb.sr_cmd.cback_cnt[idx]) { 1065 tcb.sr_cmd.cback_cnt[idx]--; 1066 } 1067 } 1068 } 1069 1070 /******************************************************************************* 1071 * 1072 * Function gatt_sr_update_prep_cnt 1073 * 1074 * Description Update the teh prepare write request count 1075 * 1076 * Returns None 1077 * 1078 ******************************************************************************/ 1079 void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc, 1080 bool is_reset_first) { 1081 uint8_t idx = ((uint8_t)gatt_if) - 1; 1082 1083 VLOG(1) << StringPrintf( 1084 "%s tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d", __func__, 1085 tcb.tcb_idx, gatt_if, is_inc, is_reset_first); 1086 1087 if (is_reset_first) { 1088 gatt_sr_reset_prep_cnt(tcb); 1089 } 1090 if (is_inc) { 1091 tcb.prep_cnt[idx]++; 1092 } else { 1093 if (tcb.prep_cnt[idx]) { 1094 tcb.prep_cnt[idx]--; 1095 } 1096 } 1097 } 1098 /******************************************************************************* 1099 * 1100 * Function gatt_cancel_open 1101 * 1102 * Description Cancel open request 1103 * 1104 * Returns Boolean 1105 * 1106 ******************************************************************************/ 1107 bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) { 1108 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE); 1109 if (!p_tcb) return true; 1110 1111 if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) { 1112 LOG(ERROR) << __func__ << ": link connected Too late to cancel"; 1113 return false; 1114 } 1115 1116 gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false); 1117 1118 if (p_tcb->app_hold_link.empty()) gatt_disconnect(p_tcb); 1119 1120 return true; 1121 } 1122 1123 /** Enqueue this command */ 1124 void gatt_cmd_enq(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, bool to_send, 1125 uint8_t op_code, BT_HDR* p_buf) { 1126 tGATT_CMD_Q cmd; 1127 cmd.to_send = to_send; /* waiting to be sent */ 1128 cmd.op_code = op_code; 1129 cmd.p_cmd = p_buf; 1130 cmd.p_clcb = p_clcb; 1131 1132 if (!to_send) { 1133 // TODO: WTF why do we clear the queue here ?! 1134 tcb.cl_cmd_q = std::queue<tGATT_CMD_Q>(); 1135 } 1136 1137 tcb.cl_cmd_q.push(cmd); 1138 } 1139 1140 /** dequeue the command in the client CCB command queue */ 1141 tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint8_t* p_op_code) { 1142 if (tcb.cl_cmd_q.empty()) return nullptr; 1143 1144 tGATT_CMD_Q cmd = tcb.cl_cmd_q.front(); 1145 tGATT_CLCB* p_clcb = cmd.p_clcb; 1146 *p_op_code = cmd.op_code; 1147 tcb.cl_cmd_q.pop(); 1148 1149 return p_clcb; 1150 } 1151 1152 /** Send out the ATT message for write */ 1153 uint8_t gatt_send_write_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t op_code, 1154 uint16_t handle, uint16_t len, uint16_t offset, 1155 uint8_t* p_data) { 1156 tGATT_CL_MSG msg; 1157 msg.attr_value.handle = handle; 1158 msg.attr_value.len = len; 1159 msg.attr_value.offset = offset; 1160 memcpy(msg.attr_value.value, p_data, len); 1161 1162 /* write by handle */ 1163 return attp_send_cl_msg(tcb, p_clcb, op_code, &msg); 1164 } 1165 1166 /******************************************************************************* 1167 * 1168 * Function gatt_end_operation 1169 * 1170 * Description This function ends a discovery, send callback and finalize 1171 * some control value. 1172 * 1173 * Returns 16 bits uuid. 1174 * 1175 ******************************************************************************/ 1176 void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) { 1177 tGATT_CL_COMPLETE cb_data; 1178 tGATT_CMPL_CBACK* p_cmpl_cb = 1179 (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL; 1180 uint8_t op = p_clcb->operation, disc_type = GATT_DISC_MAX; 1181 tGATT_DISC_CMPL_CB* p_disc_cmpl_cb = 1182 (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL; 1183 uint16_t conn_id; 1184 uint8_t operation; 1185 1186 VLOG(1) << __func__ 1187 << StringPrintf(" status=%d op=%d subtype=%d", status, 1188 p_clcb->operation, p_clcb->op_subtype); 1189 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); 1190 1191 if (p_cmpl_cb != NULL && p_clcb->operation != 0) { 1192 if (p_clcb->operation == GATTC_OPTYPE_READ) { 1193 cb_data.att_value.handle = p_clcb->s_handle; 1194 cb_data.att_value.len = p_clcb->counter; 1195 1196 if (p_data && p_clcb->counter) 1197 memcpy(cb_data.att_value.value, p_data, cb_data.att_value.len); 1198 } 1199 1200 if (p_clcb->operation == GATTC_OPTYPE_WRITE) { 1201 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); 1202 cb_data.handle = cb_data.att_value.handle = p_clcb->s_handle; 1203 if (p_clcb->op_subtype == GATT_WRITE_PREPARE) { 1204 if (p_data) { 1205 cb_data.att_value = *((tGATT_VALUE*)p_data); 1206 } else { 1207 VLOG(1) << "Rcv Prepare write rsp but no data"; 1208 } 1209 } 1210 } 1211 1212 if (p_clcb->operation == GATTC_OPTYPE_CONFIG) 1213 cb_data.mtu = p_clcb->p_tcb->payload_size; 1214 1215 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) { 1216 disc_type = p_clcb->op_subtype; 1217 } 1218 } 1219 1220 osi_free_and_reset((void**)&p_clcb->p_attr_buf); 1221 1222 operation = p_clcb->operation; 1223 conn_id = p_clcb->conn_id; 1224 alarm_cancel(p_clcb->gatt_rsp_timer_ent); 1225 1226 gatt_clcb_dealloc(p_clcb); 1227 1228 if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY)) 1229 (*p_disc_cmpl_cb)(conn_id, disc_type, status); 1230 else if (p_cmpl_cb && op) 1231 (*p_cmpl_cb)(conn_id, op, status, &cb_data); 1232 else 1233 LOG(WARNING) << __func__ 1234 << StringPrintf( 1235 ": not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p", 1236 operation, p_disc_cmpl_cb, p_cmpl_cb); 1237 } 1238 1239 /** This function cleans up the control blocks when L2CAP channel disconnect */ 1240 void gatt_cleanup_upon_disc(const RawAddress& bda, uint16_t reason, 1241 tBT_TRANSPORT transport) { 1242 VLOG(1) << __func__; 1243 1244 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, transport); 1245 if (!p_tcb) return; 1246 1247 gatt_set_ch_state(p_tcb, GATT_CH_CLOSE); 1248 for (uint8_t i = 0; i < GATT_CL_MAX_LCB; i++) { 1249 tGATT_CLCB* p_clcb = &gatt_cb.clcb[i]; 1250 if (!p_clcb->in_use || p_clcb->p_tcb != p_tcb) continue; 1251 1252 alarm_cancel(p_clcb->gatt_rsp_timer_ent); 1253 VLOG(1) << "found p_clcb conn_id=" << +p_clcb->conn_id; 1254 if (p_clcb->operation == GATTC_OPTYPE_NONE) { 1255 gatt_clcb_dealloc(p_clcb); 1256 continue; 1257 } 1258 1259 gatt_end_operation(p_clcb, GATT_ERROR, NULL); 1260 } 1261 1262 alarm_free(p_tcb->ind_ack_timer); 1263 p_tcb->ind_ack_timer = NULL; 1264 alarm_free(p_tcb->conf_timer); 1265 p_tcb->conf_timer = NULL; 1266 gatt_free_pending_ind(p_tcb); 1267 fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL); 1268 p_tcb->sr_cmd.multi_rsp_q = NULL; 1269 1270 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) { 1271 tGATT_REG* p_reg = &gatt_cb.cl_rcb[i]; 1272 if (p_reg->in_use && p_reg->app_cb.p_conn_cb) { 1273 uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); 1274 VLOG(1) << StringPrintf("found p_reg tcb_idx=%d gatt_if=%d conn_id=0x%x", 1275 p_tcb->tcb_idx, p_reg->gatt_if, conn_id); 1276 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, false, reason, 1277 transport); 1278 } 1279 } 1280 1281 *p_tcb = tGATT_TCB(); 1282 VLOG(1) << __func__ << ": exit"; 1283 } 1284 /******************************************************************************* 1285 * 1286 * Function gatt_dbg_req_op_name 1287 * 1288 * Description Get op code description name, for debug information. 1289 * 1290 * Returns uint8_t *: name of the operation. 1291 * 1292 ******************************************************************************/ 1293 uint8_t* gatt_dbg_op_name(uint8_t op_code) { 1294 uint8_t pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK); 1295 1296 if (op_code == GATT_CMD_WRITE) { 1297 pseduo_op_code_idx = 0x14; /* just an index to op_code_name */ 1298 } 1299 1300 if (op_code == GATT_SIGN_CMD_WRITE) { 1301 pseduo_op_code_idx = 0x15; /* just an index to op_code_name */ 1302 } 1303 1304 if (pseduo_op_code_idx <= GATT_OP_CODE_MAX) 1305 return (uint8_t*)op_code_name[pseduo_op_code_idx]; 1306 else 1307 return (uint8_t*)"Op Code Exceed Max"; 1308 } 1309 1310 /** Returns true if this is one of the background devices for the application, 1311 * false otherwise */ 1312 bool gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV* p_dev, tGATT_IF gatt_if) { 1313 return p_dev->gatt_if.count(gatt_if); 1314 } 1315 1316 /** background connection device from the list. Returns pointer to the device 1317 * record, or nullptr if not found */ 1318 tGATT_BG_CONN_DEV* gatt_find_bg_dev(const RawAddress& remote_bda) { 1319 for (tGATT_BG_CONN_DEV& dev : gatt_cb.bgconn_dev) { 1320 if (dev.remote_bda == remote_bda) { 1321 return &dev; 1322 } 1323 } 1324 return nullptr; 1325 } 1326 1327 std::list<tGATT_BG_CONN_DEV>::iterator gatt_find_bg_dev_it( 1328 const RawAddress& remote_bda) { 1329 auto& list = gatt_cb.bgconn_dev; 1330 for (auto it = list.begin(); it != list.end(); it++) { 1331 if (it->remote_bda == remote_bda) { 1332 return it; 1333 } 1334 } 1335 return list.end(); 1336 } 1337 1338 /** Add a device from the background connection list. Returns true if device 1339 * added to the list, or already in list, false otherwise */ 1340 bool gatt_add_bg_dev_list(tGATT_REG* p_reg, const RawAddress& bd_addr) { 1341 tGATT_IF gatt_if = p_reg->gatt_if; 1342 1343 tGATT_BG_CONN_DEV* p_dev = gatt_find_bg_dev(bd_addr); 1344 if (p_dev) { 1345 // device already in the whitelist, just add interested app to the list 1346 if (!p_dev->gatt_if.insert(gatt_if).second) { 1347 LOG(ERROR) << "device already in iniator white list"; 1348 } 1349 1350 return true; 1351 } 1352 // the device is not in the whitelist 1353 1354 if (!BTM_BleUpdateBgConnDev(true, bd_addr)) return false; 1355 1356 gatt_cb.bgconn_dev.emplace_back(); 1357 tGATT_BG_CONN_DEV& dev = gatt_cb.bgconn_dev.back(); 1358 dev.remote_bda = bd_addr; 1359 dev.gatt_if.insert(gatt_if); 1360 return true; 1361 } 1362 1363 /** Remove the application interface for the specified background device */ 1364 bool gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, const RawAddress& bd_addr) { 1365 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 1366 bool status; 1367 1368 if (p_tcb) gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false); 1369 status = gatt_update_auto_connect_dev(gatt_if, false, bd_addr); 1370 return status; 1371 } 1372 1373 /** Removes all registrations for background connection for given device. 1374 * Returns true if anything was removed, false otherwise */ 1375 uint8_t gatt_clear_bg_dev_for_addr(const RawAddress& bd_addr) { 1376 auto dev_it = gatt_find_bg_dev_it(bd_addr); 1377 if (dev_it == gatt_cb.bgconn_dev.end()) return false; 1378 1379 CHECK(BTM_BleUpdateBgConnDev(false, dev_it->remote_bda)); 1380 gatt_cb.bgconn_dev.erase(dev_it); 1381 return true; 1382 } 1383 1384 /** Remove device from the background connection device list or listening to 1385 * advertising list. Returns true if device was on the list and was succesfully 1386 * removed */ 1387 bool gatt_remove_bg_dev_from_list(tGATT_REG* p_reg, const RawAddress& bd_addr) { 1388 tGATT_IF gatt_if = p_reg->gatt_if; 1389 auto dev_it = gatt_find_bg_dev_it(bd_addr); 1390 if (dev_it == gatt_cb.bgconn_dev.end()) return false; 1391 1392 if (!dev_it->gatt_if.erase(gatt_if)) return false; 1393 1394 if (!dev_it->gatt_if.empty()) return true; 1395 1396 // no more apps interested - remove from whitelist and delete record 1397 CHECK(BTM_BleUpdateBgConnDev(false, dev_it->remote_bda)); 1398 gatt_cb.bgconn_dev.erase(dev_it); 1399 return true; 1400 } 1401 /** deregister all related back ground connetion device. */ 1402 void gatt_deregister_bgdev_list(tGATT_IF gatt_if) { 1403 auto it = gatt_cb.bgconn_dev.begin(); 1404 auto end = gatt_cb.bgconn_dev.end(); 1405 /* update the BG conn device list */ 1406 while (it != end) { 1407 it->gatt_if.erase(gatt_if); 1408 if (it->gatt_if.size()) { 1409 it++; 1410 continue; 1411 } 1412 1413 BTM_BleUpdateBgConnDev(false, it->remote_bda); 1414 it = gatt_cb.bgconn_dev.erase(it); 1415 } 1416 } 1417 1418 /******************************************************************************* 1419 * 1420 * Function gatt_reset_bgdev_list 1421 * 1422 * Description reset bg device list 1423 * 1424 * Returns pointer to the device record 1425 * 1426 ******************************************************************************/ 1427 void gatt_reset_bgdev_list(void) { gatt_cb.bgconn_dev.clear(); } 1428 /******************************************************************************* 1429 * 1430 * Function gatt_update_auto_connect_dev 1431 * 1432 * Description This function add or remove a device for background 1433 * connection procedure. 1434 * 1435 * Parameters gatt_if: Application ID. 1436 * add: add peer device 1437 * bd_addr: peer device address. 1438 * 1439 * Returns true if connection started; false otherwise. 1440 * 1441 ******************************************************************************/ 1442 bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add, 1443 const RawAddress& bd_addr) { 1444 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 1445 1446 VLOG(1) << __func__; 1447 /* Make sure app is registered */ 1448 tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 1449 if (!p_reg) { 1450 LOG(ERROR) << __func__ << " gatt_if is not registered " << +gatt_if; 1451 return false; 1452 } 1453 1454 if (!add) return gatt_remove_bg_dev_from_list(p_reg, bd_addr); 1455 1456 bool ret = gatt_add_bg_dev_list(p_reg, bd_addr); 1457 if (ret && p_tcb != NULL) { 1458 /* if a connected device, update the link holding number */ 1459 gatt_update_app_use_link_flag(gatt_if, p_tcb, true, true); 1460 } 1461 return ret; 1462 } 1463