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