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