1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-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 the GATT client utility function. 22 * 23 ******************************************************************************/ 24 25 #include "bt_target.h" 26 27 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) 28 29 #include <string.h> 30 #include "utl.h" 31 #include "gki.h" 32 #include "bta_sys.h" 33 #include "bta_gattc_int.h" 34 #include "bd.h" 35 36 /***************************************************************************** 37 ** Constants 38 *****************************************************************************/ 39 40 41 static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 42 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 43 44 /******************************************************************************* 45 ** 46 ** Function bta_gatt_convert_uuid16_to_uuid128 47 ** 48 ** Description Convert a 16 bits UUID to be an standard 128 bits one. 49 ** 50 ** Returns TRUE if two uuid match; FALSE otherwise. 51 ** 52 *******************************************************************************/ 53 void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16) 54 { 55 UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; 56 57 memcpy (uuid_128, base_uuid, LEN_UUID_128); 58 59 UINT16_TO_STREAM(p, uuid_16); 60 } 61 /******************************************************************************* 62 ** 63 ** Function bta_gattc_uuid_compare 64 ** 65 ** Description Compare two UUID to see if they are the same. 66 ** 67 ** Returns TRUE if two uuid match; FALSE otherwise. 68 ** 69 *******************************************************************************/ 70 BOOLEAN bta_gattc_uuid_compare (tBT_UUID src, tBT_UUID tar, BOOLEAN is_precise) 71 { 72 UINT8 su[LEN_UUID_128], tu[LEN_UUID_128]; 73 UINT8 *ps, *pt; 74 75 /* any of the UUID is unspecified */ 76 if (src.len == 0 || tar.len == 0) 77 { 78 if (is_precise) 79 return FALSE; 80 else 81 return TRUE; 82 } 83 84 /* If both are 16-bit, we can do a simple compare */ 85 if (src.len == 2 && tar.len == 2) 86 { 87 return src.uu.uuid16 == tar.uu.uuid16; 88 } 89 90 /* One or both of the UUIDs is 128-bit */ 91 if (src.len == LEN_UUID_16) 92 { 93 /* convert a 16 bits UUID to 128 bits value */ 94 bta_gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16); 95 ps = su; 96 } 97 else 98 ps = src.uu.uuid128; 99 100 if (tar.len == LEN_UUID_16) 101 { 102 /* convert a 16 bits UUID to 128 bits value */ 103 bta_gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16); 104 pt = tu; 105 } 106 else 107 pt = tar.uu.uuid128; 108 109 return(memcmp(ps, pt, LEN_UUID_128) == 0); 110 } 111 112 /******************************************************************************* 113 ** 114 ** Function bta_gattc_cl_get_regcb 115 ** 116 ** Description get registration control block by client interface. 117 ** 118 ** Returns pointer to the regcb 119 ** 120 *******************************************************************************/ 121 tBTA_GATTC_RCB * bta_gattc_cl_get_regcb(UINT8 client_if) 122 { 123 UINT8 i = 0; 124 tBTA_GATTC_RCB *p_clrcb = &bta_gattc_cb.cl_rcb[0]; 125 126 for (i = 0; i < BTA_GATTC_CL_MAX; i ++, p_clrcb ++) 127 { 128 if (p_clrcb->in_use && 129 p_clrcb->client_if == client_if) 130 return p_clrcb; 131 } 132 return NULL; 133 } 134 /******************************************************************************* 135 ** 136 ** Function bta_gattc_num_reg_app 137 ** 138 ** Description find the number of registered application. 139 ** 140 ** Returns pointer to the regcb 141 ** 142 *******************************************************************************/ 143 UINT8 bta_gattc_num_reg_app(void) 144 { 145 UINT8 i = 0, j = 0; 146 147 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) 148 { 149 if (bta_gattc_cb.cl_rcb[i].in_use) 150 j ++; 151 } 152 return j; 153 } 154 /******************************************************************************* 155 ** 156 ** Function bta_gattc_find_clcb_by_cif 157 ** 158 ** Description get clcb by client interface and remote bd adddress 159 ** 160 ** Returns pointer to the clcb 161 ** 162 *******************************************************************************/ 163 tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda) 164 { 165 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0]; 166 UINT8 i; 167 168 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) 169 { 170 if (p_clcb->in_use && 171 p_clcb->p_rcb->client_if == client_if && 172 p_clcb->p_srcb && 173 bdcmp(p_clcb->p_srcb->server_bda, remote_bda) == 0) 174 return p_clcb; 175 } 176 return NULL; 177 } 178 /******************************************************************************* 179 ** 180 ** Function bta_gattc_find_clcb_by_conn_id 181 ** 182 ** Description get clcb by connection ID 183 ** 184 ** Returns pointer to the clcb 185 ** 186 *******************************************************************************/ 187 tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id) 188 { 189 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0]; 190 UINT8 i; 191 192 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) 193 { 194 if (p_clcb->in_use && 195 p_clcb->bta_conn_id == conn_id) 196 return p_clcb; 197 } 198 return NULL; 199 } 200 201 /******************************************************************************* 202 ** 203 ** Function bta_gattc_clcb_alloc 204 ** 205 ** Description allocate CLCB 206 ** 207 ** Returns pointer to the clcb 208 ** 209 *******************************************************************************/ 210 tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda) 211 { 212 UINT8 i_clcb = 0; 213 tBTA_GATTC_CLCB *p_clcb = NULL; 214 215 for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) 216 { 217 if (!bta_gattc_cb.clcb[i_clcb].in_use) 218 { 219 #if BTA_GATT_DEBUG == TRUE 220 APPL_TRACE_DEBUG1("bta_gattc_clcb_alloc: found clcb[%d] available",i_clcb); 221 #endif 222 p_clcb = &bta_gattc_cb.clcb[i_clcb]; 223 p_clcb->in_use = TRUE; 224 p_clcb->status = BTA_GATT_OK; 225 bdcpy(p_clcb->bda, remote_bda); 226 227 p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if); 228 229 if ((p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) 230 p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda); 231 232 if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) 233 { 234 p_clcb->p_srcb->num_clcb ++; 235 p_clcb->p_rcb->num_clcb ++; 236 } 237 else 238 { 239 /* release this clcb if clcb or srcb allocation failed */ 240 p_clcb->in_use = FALSE; 241 p_clcb = NULL; 242 } 243 break; 244 } 245 } 246 return p_clcb; 247 } 248 /******************************************************************************* 249 ** 250 ** Function bta_gattc_find_alloc_clcb 251 ** 252 ** Description find or allocate CLCB if not found. 253 ** 254 ** Returns pointer to the clcb 255 ** 256 *******************************************************************************/ 257 tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda) 258 { 259 tBTA_GATTC_CLCB *p_clcb ; 260 261 if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda)) == NULL) 262 { 263 p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda); 264 } 265 return p_clcb; 266 } 267 268 /******************************************************************************* 269 ** 270 ** Function bta_gattc_clcb_dealloc 271 ** 272 ** Description Deallocte a clcb 273 ** 274 ** Returns pointer to the clcb 275 ** 276 *******************************************************************************/ 277 void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb) 278 { 279 tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb; 280 281 if (p_clcb) 282 { 283 if (p_srcb->num_clcb) 284 p_srcb->num_clcb --; 285 286 if (p_clcb->p_rcb->num_clcb) 287 p_clcb->p_rcb->num_clcb --; 288 if ( p_srcb->num_clcb == 0) 289 { 290 p_srcb->connected = FALSE; 291 p_srcb->state = BTA_GATTC_SERV_IDLE; 292 } 293 294 utl_freebuf((void **)&p_clcb->p_q_cmd); 295 296 memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB)); 297 } 298 else 299 { 300 APPL_TRACE_ERROR0("bta_gattc_clcb_dealloc p_clcb=NULL"); 301 } 302 } 303 304 /******************************************************************************* 305 ** 306 ** Function bta_gattc_find_srcb 307 ** 308 ** Description find server cache by remote bd address currently in use 309 ** 310 ** Returns pointer to the server cache. 311 ** 312 *******************************************************************************/ 313 tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda) 314 { 315 tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0]; 316 UINT8 i; 317 318 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) 319 { 320 if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0) 321 return p_srcb; 322 } 323 return NULL; 324 } 325 326 /******************************************************************************* 327 ** 328 ** Function bta_gattc_find_srvr_cache 329 ** 330 ** Description find server cache by remote bd address 331 ** 332 ** Returns pointer to the server cache. 333 ** 334 *******************************************************************************/ 335 tBTA_GATTC_SERV * bta_gattc_find_srvr_cache(BD_ADDR bda) 336 { 337 tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0]; 338 UINT8 i; 339 340 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) 341 { 342 if (bdcmp(p_srcb->server_bda, bda) == 0) 343 return p_srcb; 344 } 345 return NULL; 346 } 347 /******************************************************************************* 348 ** 349 ** Function bta_gattc_find_scb_by_cid 350 ** 351 ** Description find server control block by connection ID 352 ** 353 ** Returns pointer to the server cache. 354 ** 355 *******************************************************************************/ 356 tBTA_GATTC_SERV * bta_gattc_find_scb_by_cid (UINT16 conn_id) 357 { 358 tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); 359 360 if (p_clcb) 361 return p_clcb->p_srcb; 362 else 363 return NULL; 364 } 365 /******************************************************************************* 366 ** 367 ** Function bta_gattc_srcb_alloc 368 ** 369 ** Description allocate server cache control block 370 ** 371 ** Returns pointer to the server cache. 372 ** 373 *******************************************************************************/ 374 tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda) 375 { 376 tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0], 377 *p_recycle = NULL; 378 BOOLEAN found = FALSE; 379 UINT8 i; 380 381 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++) 382 { 383 if (!p_tcb->in_use) 384 { 385 found = TRUE; 386 break; 387 } 388 else if (!p_tcb->connected) 389 { 390 p_recycle = p_tcb; 391 } 392 } 393 394 /* if not found, try to recycle one known device */ 395 if (!found && !p_recycle) 396 p_tcb = NULL; 397 else if (p_recycle) 398 p_tcb = p_recycle; 399 400 if (p_tcb != NULL) 401 { 402 while (p_tcb->cache_buffer.p_first) 403 GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer)); 404 405 utl_freebuf((void **)&p_tcb->p_srvc_list); 406 memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV)); 407 408 p_tcb->in_use = TRUE; 409 bdcpy(p_tcb->server_bda, bda); 410 } 411 return p_tcb; 412 } 413 /******************************************************************************* 414 ** 415 ** Function bta_gattc_enqueue 416 ** 417 ** Description enqueue a client request in clcb. 418 ** 419 ** Returns success or failure. 420 ** 421 *******************************************************************************/ 422 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 423 { 424 BOOLEAN in_q = FALSE; 425 426 if (p_clcb->p_q_cmd == NULL) 427 { 428 p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(sizeof(tBTA_GATTC_DATA)); 429 430 if (p_data) 431 memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_DATA)); 432 433 in_q = TRUE; 434 } 435 else 436 { 437 APPL_TRACE_ERROR0("already has a pending command!!"); 438 /* skip the callback now. ----- need to send callback ? */ 439 } 440 return in_q; 441 } 442 /******************************************************************************* 443 ** 444 ** Function bta_gattc_pack_attr_uuid 445 ** 446 ** Description pack UUID into a stream. 447 ** 448 ** Returns 449 ** 450 *******************************************************************************/ 451 void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid) 452 { 453 UINT8 *pp = (UINT8 *)p_attr->p_uuid; 454 455 memset(p_uuid, 0, sizeof(tBT_UUID)); 456 457 p_uuid->len = p_attr->uuid_len; 458 459 if (p_attr->uuid_len == LEN_UUID_16) 460 { 461 STREAM_TO_UINT16(p_uuid->uu.uuid16, pp); 462 } 463 else 464 { 465 memcpy(p_uuid->uu.uuid128, pp, LEN_UUID_128); 466 } 467 468 return; 469 } 470 /******************************************************************************* 471 ** 472 ** Function bta_gattc_cpygattid 473 ** 474 ** Description copy two tBTA_GATT_ID value 475 ** 476 ** Returns 477 ** 478 *******************************************************************************/ 479 void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src) 480 { 481 memset ((void *)p_des, 0, sizeof(tBTA_GATT_ID)); 482 483 p_des->inst_id = p_src->inst_id; 484 485 p_des->uuid.len = p_src->uuid.len; 486 487 if (p_des->uuid.len == LEN_UUID_16) 488 { 489 p_des->uuid.uu.uuid16 = p_src->uuid.uu.uuid16; 490 } 491 else if (p_des->uuid.len == LEN_UUID_128) 492 { 493 memcpy(p_des->uuid.uu.uuid128, p_src->uuid.uu.uuid128, LEN_UUID_128); 494 } 495 } 496 /******************************************************************************* 497 ** 498 ** Function bta_gattc_gattid_compare 499 ** 500 ** Description compare two tBTA_GATT_ID type of pointer 501 ** 502 ** Returns 503 ** 504 *******************************************************************************/ 505 BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar) 506 { 507 if (p_src->inst_id == p_tar->inst_id && 508 bta_gattc_uuid_compare (p_src->uuid, p_tar->uuid, TRUE )) 509 return TRUE; 510 else 511 return FALSE; 512 513 } 514 /******************************************************************************* 515 ** 516 ** Function bta_gattc_srvcid_compare 517 ** 518 ** Description compare two tBTA_GATT_SRVC_ID type of pointer 519 ** 520 ** Returns 521 ** 522 *******************************************************************************/ 523 BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar) 524 { 525 if (p_src->is_primary == p_tar->is_primary && 526 bta_gattc_gattid_compare (&p_src->id, &p_tar->id)) 527 return TRUE; 528 else 529 return FALSE; 530 } 531 /******************************************************************************* 532 ** 533 ** Function bta_gattc_charid_compare 534 ** 535 ** Description compare two tBTA_GATTC_CHAR_ID type of pointer 536 ** 537 ** Returns 538 ** 539 *******************************************************************************/ 540 BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar) 541 { 542 if (bta_gattc_gattid_compare (&p_src->char_id, &p_tar->char_id) && 543 bta_gattc_srvcid_compare (&p_src->srvc_id, &p_tar->srvc_id)) 544 return TRUE; 545 else 546 return FALSE; 547 } 548 549 /******************************************************************************* 550 ** 551 ** Function bta_gattc_check_notif_registry 552 ** 553 ** Description check if the service notificaition has been registered. 554 ** 555 ** Returns 556 ** 557 *******************************************************************************/ 558 BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb, 559 tBTA_GATTC_NOTIFY *p_notify) 560 { 561 UINT8 i; 562 563 for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) 564 { 565 if (p_clreg->notif_reg[i].in_use && 566 bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 && 567 bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id)) 568 { 569 APPL_TRACE_DEBUG0("Notification registered!"); 570 return TRUE; 571 } 572 } 573 return FALSE; 574 575 } 576 /******************************************************************************* 577 ** 578 ** Function bta_gattc_clear_notif_registration 579 ** 580 ** Description clear up the notification registration information by BD_ADDR. 581 ** 582 ** Returns None. 583 ** 584 *******************************************************************************/ 585 void bta_gattc_clear_notif_registration(UINT16 conn_id) 586 { 587 BD_ADDR remote_bda; 588 tBTA_GATTC_IF gatt_if; 589 tBTA_GATTC_RCB *p_clrcb ; 590 UINT8 i; 591 592 if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda)) 593 { 594 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) 595 { 596 for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) 597 { 598 if (p_clrcb->notif_reg[i].in_use && !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) 599 memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG)); 600 } 601 } 602 } 603 else 604 { 605 APPL_TRACE_ERROR0("can not clear indication/notif registration for unknown app"); 606 } 607 return; 608 } 609 610 /******************************************************************************* 611 ** 612 ** Function bta_gattc_pack_cb_data 613 ** 614 ** Description pack the data from read response into callback data structure. 615 ** 616 ** Returns 617 ** 618 *******************************************************************************/ 619 tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID descr_uuid, 620 tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value) 621 { 622 UINT8 i = 0, *pp = p_attr->value; 623 tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}}; 624 UINT16 handle; 625 tBTA_GATT_STATUS status = BTA_GATT_OK; 626 627 /* GATT_UUID_CHAR_AGG_FORMAT */ 628 if (bta_gattc_uuid_compare (uuid, descr_uuid, TRUE)) 629 { 630 while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX) 631 { 632 STREAM_TO_UINT16(handle, pp); 633 634 if (bta_gattc_handle2id(p_srcb, 635 handle, 636 &p_value->aggre_value.pre_format[i].char_id.srvc_id, 637 &p_value->aggre_value.pre_format[i].char_id.char_id, 638 &p_value->aggre_value.pre_format[i].descr_type) == FALSE) 639 { 640 status = BTA_GATT_INTERNAL_ERROR; 641 APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", handle); 642 break; 643 } 644 i ++; 645 p_attr->len -= 2; 646 } 647 p_value->aggre_value.num_pres_fmt = i; 648 } 649 else 650 { 651 /* all others, take as raw format */ 652 p_value->unformat.len = p_attr->len; 653 p_value->unformat.p_value = p_attr->value; 654 } 655 return status; 656 } 657 /******************************************************************************* 658 ** 659 ** Function bta_gattc_mark_bg_conn 660 ** 661 ** Description mark background connection status when a bg connection is initiated 662 ** or terminated. 663 ** 664 ** Returns TRUE if success; FALSE otherwise. 665 ** 666 *******************************************************************************/ 667 BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda_ptr, 668 BOOLEAN add, BOOLEAN is_listen) 669 { 670 tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0]; 671 UINT8 i = 0; 672 tBTA_GATTC_CIF_MASK *p_cif_mask; 673 674 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) 675 { 676 if (p_bg_tck->in_use && 677 ((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) || 678 (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, bd_addr_null) == 0))) 679 { 680 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask; 681 682 if (add) 683 /* mask on the cif bit */ 684 *p_cif_mask |= (1 <<(client_if - 1)); 685 else 686 { 687 if (client_if != 0) 688 *p_cif_mask &= (~(1 <<(client_if - 1))); 689 else 690 *p_cif_mask = 0; 691 } 692 /* no BG connection for this device, make it available */ 693 if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0) 694 { 695 memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK)); 696 } 697 return TRUE; 698 } 699 } 700 if (!add) 701 { 702 APPL_TRACE_ERROR0("Do not find the bg connection mask for the remote device"); 703 return FALSE; 704 } 705 else /* adding a new device mask */ 706 { 707 for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0]; 708 i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) 709 { 710 if (!p_bg_tck->in_use) 711 { 712 p_bg_tck->in_use = TRUE; 713 if (remote_bda_ptr) 714 bdcpy(p_bg_tck->remote_bda, remote_bda_ptr); 715 else 716 bdcpy(p_bg_tck->remote_bda, bd_addr_null); 717 718 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask; 719 720 *p_cif_mask = (1 <<(client_if - 1)); 721 return TRUE; 722 } 723 } 724 APPL_TRACE_ERROR0("no available space to mark the bg connection status"); 725 return FALSE; 726 } 727 } 728 /******************************************************************************* 729 ** 730 ** Function bta_gattc_check_bg_conn 731 ** 732 ** Description check if this is a background connection background connection. 733 ** 734 ** Returns TRUE if success; FALSE otherwise. 735 ** 736 *******************************************************************************/ 737 BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role) 738 { 739 tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0]; 740 UINT8 i = 0; 741 BOOLEAN is_bg_conn = FALSE; 742 743 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++) 744 { 745 if (p_bg_tck->in_use && 746 (bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 || 747 bdcmp(p_bg_tck->remote_bda, bd_addr_null) == 0)) 748 { 749 if (((p_bg_tck->cif_mask &(1 <<(client_if - 1))) != 0) && 750 role == HCI_ROLE_MASTER) 751 is_bg_conn = TRUE; 752 753 if (((p_bg_tck->cif_adv_mask &(1 <<(client_if - 1))) != 0) && 754 role == HCI_ROLE_SLAVE) 755 is_bg_conn = TRUE; 756 } 757 } 758 return is_bg_conn; 759 } 760 /******************************************************************************* 761 ** 762 ** Function bta_gattc_send_open_cback 763 ** 764 ** Description send open callback 765 ** 766 ** Returns 767 ** 768 *******************************************************************************/ 769 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status, 770 BD_ADDR remote_bda, UINT16 conn_id) 771 { 772 tBTA_GATTC cb_data; 773 774 if (p_clreg->p_cback) 775 { 776 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 777 778 cb_data.open.status = status; 779 cb_data.open.client_if = p_clreg->client_if; 780 cb_data.open.conn_id = conn_id; 781 bdcpy(cb_data.open.remote_bda, remote_bda); 782 783 (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data); 784 } 785 } 786 /******************************************************************************* 787 ** 788 ** Function bta_gattc_conn_alloc 789 ** 790 ** Description allocate connection tracking spot 791 ** 792 ** Returns pointer to the clcb 793 ** 794 *******************************************************************************/ 795 tBTA_GATTC_CONN * bta_gattc_conn_alloc(BD_ADDR remote_bda) 796 { 797 UINT8 i_conn = 0; 798 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0]; 799 800 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) 801 { 802 if (!p_conn->in_use) 803 { 804 #if BTA_GATT_DEBUG == TRUE 805 APPL_TRACE_DEBUG1("bta_gattc_conn_alloc: found conn_track[%d] available",i_conn); 806 #endif 807 p_conn->in_use = TRUE; 808 bdcpy(p_conn->remote_bda, remote_bda); 809 return p_conn; 810 } 811 } 812 return NULL; 813 } 814 815 /******************************************************************************* 816 ** 817 ** Function bta_gattc_conn_find 818 ** 819 ** Description allocate connection tracking spot 820 ** 821 ** Returns pointer to the clcb 822 ** 823 *******************************************************************************/ 824 tBTA_GATTC_CONN * bta_gattc_conn_find(BD_ADDR remote_bda) 825 { 826 UINT8 i_conn = 0; 827 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0]; 828 829 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) 830 { 831 if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0) 832 { 833 #if BTA_GATT_DEBUG == TRUE 834 APPL_TRACE_DEBUG1("bta_gattc_conn_find: found conn_track[%d] matched",i_conn); 835 #endif 836 return p_conn; 837 } 838 } 839 return NULL; 840 } 841 842 843 /******************************************************************************* 844 ** 845 ** Function bta_gattc_conn_find_alloc 846 ** 847 ** Description find or allocate connection tracking spot 848 ** 849 ** Returns pointer to the clcb 850 ** 851 *******************************************************************************/ 852 tBTA_GATTC_CONN * bta_gattc_conn_find_alloc(BD_ADDR remote_bda) 853 { 854 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda); 855 856 if (p_conn == NULL) 857 { 858 p_conn = bta_gattc_conn_alloc(remote_bda); 859 } 860 return p_conn; 861 } 862 863 /******************************************************************************* 864 ** 865 ** Function bta_gattc_conn_dealloc 866 ** 867 ** Description de-allocate connection tracking spot 868 ** 869 ** Returns pointer to the clcb 870 ** 871 *******************************************************************************/ 872 BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda) 873 { 874 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda); 875 876 if (p_conn != NULL) 877 { 878 p_conn->in_use = FALSE; 879 memset(p_conn->remote_bda, 0, BD_ADDR_LEN); 880 return TRUE; 881 } 882 return FALSE; 883 } 884 885 #endif /* BTA_GATT_INCLUDED */ 886