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 27 #if BLE_INCLUDED == TRUE 28 #include <string.h> 29 #include "stdio.h" 30 #include "bt_common.h" 31 32 #include "l2cdefs.h" 33 #include "gatt_int.h" 34 #include "gatt_api.h" 35 #include "gattdefs.h" 36 #include "sdp_api.h" 37 #include "btm_int.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[] = 44 { 45 "UNKNOWN", 46 "ATT_RSP_ERROR", 47 "ATT_REQ_MTU", 48 "ATT_RSP_MTU", 49 "ATT_REQ_READ_INFO", 50 "ATT_RSP_READ_INFO", 51 "ATT_REQ_FIND_TYPE_VALUE", 52 "ATT_RSP_FIND_TYPE_VALUE", 53 "ATT_REQ_READ_BY_TYPE", 54 "ATT_RSP_READ_BY_TYPE", 55 "ATT_REQ_READ", 56 "ATT_RSP_READ", 57 "ATT_REQ_READ_BLOB", 58 "ATT_RSP_READ_BLOB", 59 "GATT_REQ_READ_MULTI", 60 "GATT_RSP_READ_MULTI", 61 "GATT_REQ_READ_BY_GRP_TYPE", 62 "GATT_RSP_READ_BY_GRP_TYPE", 63 "ATT_REQ_WRITE", 64 "ATT_RSP_WRITE", 65 "ATT_CMD_WRITE", 66 "ATT_SIGN_CMD_WRITE", 67 "ATT_REQ_PREPARE_WRITE", 68 "ATT_RSP_PREPARE_WRITE", 69 "ATT_REQ_EXEC_WRITE", 70 "ATT_RSP_EXEC_WRITE", 71 "Reserved", 72 "ATT_HANDLE_VALUE_NOTIF", 73 "Reserved", 74 "ATT_HANDLE_VALUE_IND", 75 "ATT_HANDLE_VALUE_CONF", 76 "ATT_OP_CODE_MAX" 77 }; 78 79 static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 80 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 81 82 extern fixed_queue_t *btu_general_alarm_queue; 83 84 /******************************************************************************* 85 ** 86 ** Function gatt_free_pending_ind 87 ** 88 ** Description Free all pending indications 89 ** 90 ** Returns None 91 ** 92 *******************************************************************************/ 93 void gatt_free_pending_ind(tGATT_TCB *p_tcb) 94 { 95 GATT_TRACE_DEBUG("%s", __func__); 96 97 if (p_tcb->pending_ind_q == NULL) 98 return; 99 100 /* release all queued indications */ 101 while (!fixed_queue_is_empty(p_tcb->pending_ind_q)) 102 osi_free(fixed_queue_try_dequeue(p_tcb->pending_ind_q)); 103 fixed_queue_free(p_tcb->pending_ind_q, NULL); 104 p_tcb->pending_ind_q = NULL; 105 } 106 107 /******************************************************************************* 108 ** 109 ** Function gatt_free_pending_enc_queue 110 ** 111 ** Description Free all buffers in pending encyption queue 112 ** 113 ** Returns None 114 ** 115 *******************************************************************************/ 116 void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb) 117 { 118 GATT_TRACE_DEBUG("%s", __func__); 119 120 if (p_tcb->pending_enc_clcb == NULL) 121 return; 122 123 /* release all queued indications */ 124 while (!fixed_queue_is_empty(p_tcb->pending_enc_clcb)) 125 osi_free(fixed_queue_try_dequeue(p_tcb->pending_enc_clcb)); 126 fixed_queue_free(p_tcb->pending_enc_clcb, NULL); 127 p_tcb->pending_enc_clcb = NULL; 128 } 129 130 /******************************************************************************* 131 ** 132 ** Function gatt_delete_dev_from_srv_chg_clt_list 133 ** 134 ** Description Delete a device from the service changed client lit 135 ** 136 ** Returns None 137 ** 138 *******************************************************************************/ 139 void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr) 140 { 141 GATT_TRACE_DEBUG("gatt_delete_dev_from_srv_chg_clt_list"); 142 143 tGATTS_SRV_CHG *p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr); 144 if (p_buf != NULL) 145 { 146 if (gatt_cb.cb_info.p_srv_chg_callback) 147 { 148 /* delete from NV */ 149 tGATTS_SRV_CHG_REQ req; 150 memcpy(req.srv_chg.bda, bd_addr, BD_ADDR_LEN); 151 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT,&req, NULL); 152 } 153 osi_free(fixed_queue_try_remove_from_queue(gatt_cb.srv_chg_clt_q, 154 p_buf)); 155 } 156 } 157 158 /******************************************************************************* 159 ** 160 ** Function gatt_set_srv_chg 161 ** 162 ** Description Set the service changed flag to TRUE 163 ** 164 ** Returns None 165 ** 166 *******************************************************************************/ 167 void gatt_set_srv_chg(void) 168 { 169 GATT_TRACE_DEBUG ("gatt_set_srv_chg"); 170 171 if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) 172 return; 173 174 list_t *list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q); 175 for (const list_node_t *node = list_begin(list); node != list_end(list); 176 node = list_next(node)) { 177 GATT_TRACE_DEBUG ("found a srv_chg clt"); 178 179 tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)list_node(node); 180 if (!p_buf->srv_changed) 181 { 182 GATT_TRACE_DEBUG("set srv_changed to TRUE"); 183 p_buf->srv_changed = TRUE; 184 tGATTS_SRV_CHG_REQ req; 185 memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG)); 186 if (gatt_cb.cb_info.p_srv_chg_callback) 187 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,&req, NULL); 188 } 189 } 190 } 191 192 /******************************************************************************* 193 ** 194 ** Function gatt_sr_is_new_srv_chg 195 ** 196 ** Description Find the app id in on the new service changed list 197 ** 198 ** Returns Pointer to the found new service changed item othwerwise NULL 199 ** 200 *******************************************************************************/ 201 tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst) 202 { 203 tGATTS_PENDING_NEW_SRV_START *p_buf = NULL; 204 205 if (fixed_queue_is_empty(gatt_cb.pending_new_srv_start_q)) 206 return NULL; 207 208 list_t *list = fixed_queue_get_list(gatt_cb.pending_new_srv_start_q); 209 for (const list_node_t *node = list_begin(list); node != list_end(list); 210 node = list_next(node)) { 211 p_buf = (tGATTS_PENDING_NEW_SRV_START *)list_node(node); 212 tGATTS_HNDL_RANGE *p = p_buf->p_new_srv_start; 213 if (gatt_uuid_compare(*p_app_uuid128, p->app_uuid128) 214 && gatt_uuid_compare (*p_svc_uuid, p->svc_uuid) 215 && (svc_inst == p->svc_inst)) { 216 GATT_TRACE_DEBUG("gatt_sr_is_new_srv_chg: Yes"); 217 break; 218 } 219 } 220 221 return p_buf; 222 } 223 224 225 /******************************************************************************* 226 ** 227 ** Function gatt_add_pending_ind 228 ** 229 ** Description Add a pending indication 230 ** 231 ** Returns Pointer to the current pending indication buffer, NULL no buffer available 232 ** 233 *******************************************************************************/ 234 tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind) 235 { 236 tGATT_VALUE *p_buf = (tGATT_VALUE *)osi_malloc(sizeof(tGATT_VALUE)); 237 238 GATT_TRACE_DEBUG("%s", __func__); 239 GATT_TRACE_DEBUG("enqueue a pending indication"); 240 241 memcpy(p_buf, p_ind, sizeof(tGATT_VALUE)); 242 fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf); 243 244 return p_buf; 245 } 246 247 /******************************************************************************* 248 ** 249 ** Function gatt_add_pending_new_srv_start 250 ** 251 ** Description Add a pending new srv start to the new service start queue 252 ** 253 ** Returns Pointer to the new service start buffer, NULL no buffer available 254 ** 255 *******************************************************************************/ 256 tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start(tGATTS_HNDL_RANGE *p_new_srv_start) 257 { 258 tGATTS_PENDING_NEW_SRV_START *p_buf = 259 (tGATTS_PENDING_NEW_SRV_START *)osi_malloc(sizeof(tGATTS_PENDING_NEW_SRV_START)); 260 261 GATT_TRACE_DEBUG("%s", __func__); 262 GATT_TRACE_DEBUG("enqueue a new pending new srv start"); 263 264 p_buf->p_new_srv_start = p_new_srv_start; 265 fixed_queue_enqueue(gatt_cb.pending_new_srv_start_q, p_buf); 266 267 return p_buf; 268 } 269 270 271 /******************************************************************************* 272 ** 273 ** Function gatt_add_srv_chg_clt 274 ** 275 ** Description Add a service chnage client to the service change client queue 276 ** 277 ** Returns Pointer to the service change client buffer; Null no buffer available 278 ** 279 *******************************************************************************/ 280 tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg) 281 { 282 tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)osi_malloc(sizeof(tGATTS_SRV_CHG)); 283 284 GATT_TRACE_DEBUG("%s", __func__); 285 GATT_TRACE_DEBUG("enqueue a srv chg client"); 286 287 memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG)); 288 fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf); 289 290 return p_buf; 291 } 292 293 /******************************************************************************* 294 ** 295 ** Function gatt_alloc_hdl_buffer 296 ** 297 ** Description Allocate a handle buufer 298 ** 299 ** Returns Pointer to the allocated buffer, NULL no buffer available 300 ** 301 *******************************************************************************/ 302 tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void) 303 { 304 UINT8 i; 305 tGATT_CB *p_cb = &gatt_cb; 306 tGATT_HDL_LIST_ELEM * p_elem= &p_cb->hdl_list[0]; 307 308 for (i = 0; i < GATT_MAX_SR_PROFILES; i++, p_elem++) 309 { 310 if (!p_cb->hdl_list[i].in_use) 311 { 312 memset(p_elem, 0, sizeof(tGATT_HDL_LIST_ELEM)); 313 p_elem->in_use = TRUE; 314 p_elem->svc_db.svc_buffer = fixed_queue_new(SIZE_MAX); 315 return p_elem; 316 } 317 } 318 319 return NULL; 320 } 321 322 /******************************************************************************* 323 ** 324 ** Function gatt_find_hdl_buffer_by_handle 325 ** 326 ** Description Find handle range buffer by service handle. 327 ** 328 ** Returns Pointer to the buffer, NULL no buffer available 329 ** 330 *******************************************************************************/ 331 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle) 332 { 333 tGATT_HDL_LIST_INFO *p_list_info= &gatt_cb.hdl_list_info; 334 tGATT_HDL_LIST_ELEM *p_list = NULL; 335 336 p_list = p_list_info->p_first; 337 338 while (p_list != NULL) 339 { 340 if (p_list->in_use && p_list->asgn_range.s_handle == handle) 341 { 342 return(p_list); 343 } 344 p_list = p_list->p_next; 345 } 346 return NULL; 347 } 348 /******************************************************************************* 349 ** 350 ** Function gatt_find_hdl_buffer_by_app_id 351 ** 352 ** Description Find handle range buffer by app ID, service and service instance ID. 353 ** 354 ** Returns Pointer to the buffer, NULL no buffer available 355 ** 356 *******************************************************************************/ 357 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, 358 tBT_UUID *p_svc_uuid, 359 UINT16 svc_inst) 360 { 361 tGATT_HDL_LIST_INFO *p_list_info= &gatt_cb.hdl_list_info; 362 tGATT_HDL_LIST_ELEM *p_list = NULL; 363 364 p_list = p_list_info->p_first; 365 366 while (p_list != NULL) 367 { 368 if ( gatt_uuid_compare (*p_app_uuid128, p_list->asgn_range.app_uuid128) 369 && gatt_uuid_compare (*p_svc_uuid, p_list->asgn_range.svc_uuid) 370 && (svc_inst == p_list->asgn_range.svc_inst) ) 371 { 372 GATT_TRACE_DEBUG ("Already allocated handles for this service before!!"); 373 return(p_list); 374 } 375 p_list = p_list->p_next; 376 } 377 return NULL; 378 } 379 /******************************************************************************* 380 ** 381 ** Function gatt_free_hdl_buffer 382 ** 383 ** Description free a handle buffer 384 ** 385 ** Returns None 386 ** 387 *******************************************************************************/ 388 void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p) 389 { 390 391 if (p) 392 { 393 while (!fixed_queue_is_empty(p->svc_db.svc_buffer)) 394 osi_free(fixed_queue_try_dequeue(p->svc_db.svc_buffer)); 395 fixed_queue_free(p->svc_db.svc_buffer, NULL); 396 memset(p, 0, sizeof(tGATT_HDL_LIST_ELEM)); 397 } 398 } 399 /******************************************************************************* 400 ** 401 ** Function gatt_free_srvc_db_buffer_app_id 402 ** 403 ** Description free the service attribute database buffers by the owner of the 404 ** service app ID. 405 ** 406 ** Returns None 407 ** 408 *******************************************************************************/ 409 void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id) 410 { 411 tGATT_HDL_LIST_ELEM *p_elem = &gatt_cb.hdl_list[0]; 412 UINT8 i; 413 414 for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_elem ++) 415 { 416 if (memcmp(p_app_id, &p_elem->asgn_range.app_uuid128, sizeof(tBT_UUID)) == 0) 417 { 418 while (!fixed_queue_is_empty(p_elem->svc_db.svc_buffer)) 419 osi_free(fixed_queue_try_dequeue(p_elem->svc_db.svc_buffer)); 420 fixed_queue_free(p_elem->svc_db.svc_buffer, NULL); 421 p_elem->svc_db.svc_buffer = NULL; 422 423 p_elem->svc_db.mem_free = 0; 424 p_elem->svc_db.p_attr_list = p_elem->svc_db.p_free_mem = NULL; 425 } 426 } 427 } 428 /******************************************************************************* 429 ** 430 ** Function gatt_is_last_attribute 431 ** 432 ** Description Check this is the last attribute of the specified value or not 433 ** 434 ** Returns TRUE - yes this is the last attribute 435 ** 436 *******************************************************************************/ 437 BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value) 438 { 439 tGATT_SRV_LIST_ELEM *p_srv= p_start->p_next; 440 BOOLEAN is_last_attribute = TRUE; 441 tGATT_SR_REG *p_rcb = NULL; 442 tBT_UUID *p_svc_uuid; 443 444 p_list->p_last_primary = NULL; 445 446 while (p_srv) 447 { 448 p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 449 450 p_svc_uuid = gatts_get_service_uuid (p_rcb->p_db); 451 452 if (gatt_uuid_compare(value, *p_svc_uuid)) 453 { 454 is_last_attribute = FALSE; 455 break; 456 457 } 458 p_srv = p_srv->p_next; 459 } 460 461 return is_last_attribute; 462 463 } 464 465 /******************************************************************************* 466 ** 467 ** Function gatt_update_last_pri_srv_info 468 ** 469 ** Description Update the the last primary info for the service list info 470 ** 471 ** Returns None 472 ** 473 *******************************************************************************/ 474 void gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO *p_list) 475 { 476 tGATT_SRV_LIST_ELEM *p_srv= p_list->p_first; 477 478 p_list->p_last_primary = NULL; 479 480 while (p_srv) 481 { 482 if (p_srv->is_primary) 483 { 484 p_list->p_last_primary = p_srv; 485 } 486 p_srv = p_srv->p_next; 487 } 488 489 } 490 /******************************************************************************* 491 ** 492 ** Function gatts_update_srv_list_elem 493 ** 494 ** Description update an element in the service list. 495 ** 496 ** Returns None. 497 ** 498 *******************************************************************************/ 499 void gatts_update_srv_list_elem(UINT8 i_sreg, UINT16 handle, BOOLEAN is_primary) 500 { 501 UNUSED(handle); 502 503 gatt_cb.srv_list[i_sreg].in_use = TRUE; 504 gatt_cb.srv_list[i_sreg].i_sreg = i_sreg; 505 gatt_cb.srv_list[i_sreg].s_hdl = gatt_cb.sr_reg[i_sreg].s_hdl; 506 gatt_cb.srv_list[i_sreg].is_primary = is_primary; 507 508 return; 509 } 510 /******************************************************************************* 511 ** 512 ** Function gatt_add_a_srv_to_list 513 ** 514 ** Description add an service to the list in ascending 515 ** order of the start handle 516 ** 517 ** Returns BOOLEAN TRUE-if add is successful 518 ** 519 *******************************************************************************/ 520 BOOLEAN gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_new) 521 { 522 tGATT_SRV_LIST_ELEM *p_old; 523 524 if (!p_new) 525 { 526 GATT_TRACE_DEBUG("p_new==NULL"); 527 return FALSE; 528 } 529 530 if (!p_list->p_first) 531 { 532 /* this is an empty list */ 533 p_list->p_first = 534 p_list->p_last = p_new; 535 p_new->p_next = 536 p_new->p_prev = NULL; 537 } 538 else 539 { 540 p_old = p_list->p_first; 541 while (1) 542 { 543 if (p_old == NULL) 544 { 545 p_list->p_last->p_next = p_new; 546 p_new->p_prev = p_list->p_last; 547 p_new->p_next = NULL; 548 p_list->p_last = p_new; 549 break; 550 } 551 else 552 { 553 if (p_new->s_hdl < p_old->s_hdl) 554 { 555 /* if not the first in list */ 556 if (p_old->p_prev != NULL) 557 p_old->p_prev->p_next = p_new; 558 else 559 p_list->p_first = p_new; 560 561 p_new->p_prev = p_old->p_prev; 562 p_new->p_next = p_old; 563 p_old->p_prev = p_new; 564 break; 565 } 566 } 567 p_old = p_old->p_next; 568 } 569 } 570 p_list->count++; 571 572 gatt_update_last_pri_srv_info(p_list); 573 return TRUE; 574 575 } 576 577 /******************************************************************************* 578 ** 579 ** Function gatt_remove_a_srv_from_list 580 ** 581 ** Description Remove a service from the list 582 ** 583 ** Returns BOOLEAN TRUE-if remove is successful 584 ** 585 *******************************************************************************/ 586 BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_remove) 587 { 588 if (!p_remove || !p_list->p_first) 589 { 590 GATT_TRACE_DEBUG("p_remove==NULL || p_list->p_first==NULL"); 591 return FALSE; 592 } 593 594 if (p_remove->p_prev == NULL) 595 { 596 p_list->p_first = p_remove->p_next; 597 if (p_remove->p_next) 598 p_remove->p_next->p_prev = NULL; 599 } 600 else if (p_remove->p_next == NULL) 601 { 602 p_list->p_last = p_remove->p_prev; 603 p_remove->p_prev->p_next = NULL; 604 } 605 else 606 { 607 p_remove->p_next->p_prev = p_remove->p_prev; 608 p_remove->p_prev->p_next = p_remove->p_next; 609 } 610 p_list->count--; 611 gatt_update_last_pri_srv_info(p_list); 612 return TRUE; 613 614 } 615 616 /******************************************************************************* 617 ** 618 ** Function gatt_add_an_item_to_list 619 ** 620 ** Description add an service handle range to the list in decending 621 ** order of the start handle 622 ** 623 ** Returns BOOLEAN TRUE-if add is successful 624 ** 625 *******************************************************************************/ 626 BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_new) 627 { 628 tGATT_HDL_LIST_ELEM *p_old; 629 if (!p_new) 630 { 631 GATT_TRACE_DEBUG("p_new==NULL"); 632 return FALSE; 633 } 634 635 if (!p_list->p_first) 636 { 637 /* this is an empty list */ 638 p_list->p_first = 639 p_list->p_last = p_new; 640 p_new->p_next = 641 p_new->p_prev = NULL; 642 } 643 else 644 { 645 p_old = p_list->p_first; 646 while (1) 647 { 648 if (p_old == NULL) 649 { 650 p_list->p_last->p_next = p_new; 651 p_new->p_prev = p_list->p_last; 652 p_new->p_next = NULL; 653 p_list->p_last = p_new; 654 655 break; 656 657 } 658 else 659 { 660 if (p_new->asgn_range.s_handle > p_old->asgn_range.s_handle) 661 { 662 if (p_old == p_list->p_first) 663 p_list->p_first = p_new; 664 665 p_new->p_prev = p_old->p_prev; 666 p_new->p_next = p_old; 667 668 669 p_old->p_prev = p_new; 670 break; 671 } 672 } 673 p_old = p_old->p_next; 674 } 675 } 676 p_list->count++; 677 return TRUE; 678 679 } 680 681 /******************************************************************************* 682 ** 683 ** Function gatt_remove_an_item_from_list 684 ** 685 ** Description Remove an service handle range from the list 686 ** 687 ** Returns BOOLEAN TRUE-if remove is successful 688 ** 689 *******************************************************************************/ 690 BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove) 691 { 692 if (!p_remove || !p_list->p_first) 693 { 694 GATT_TRACE_DEBUG("p_remove==NULL || p_list->p_first==NULL"); 695 return FALSE; 696 } 697 698 if (p_remove->p_prev == NULL) 699 { 700 p_list->p_first = p_remove->p_next; 701 if (p_remove->p_next) 702 p_remove->p_next->p_prev = NULL; 703 } 704 else if (p_remove->p_next == NULL) 705 { 706 p_list->p_last = p_remove->p_prev; 707 p_remove->p_prev->p_next = NULL; 708 } 709 else 710 { 711 p_remove->p_next->p_prev = p_remove->p_prev; 712 p_remove->p_prev->p_next = p_remove->p_next; 713 } 714 p_list->count--; 715 return TRUE; 716 717 } 718 719 /******************************************************************************* 720 ** 721 ** Function gatt_find_the_connected_bda 722 ** 723 ** Description This function find the connected bda 724 ** 725 ** Returns TRUE if found 726 ** 727 *******************************************************************************/ 728 BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, 729 tBT_TRANSPORT *p_transport) 730 { 731 UINT8 i; 732 BOOLEAN found = FALSE; 733 GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d",start_idx); 734 735 for (i = start_idx ; i < GATT_MAX_PHY_CHANNEL; i ++) 736 { 737 if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) 738 { 739 memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN); 740 *p_found_idx = i; 741 *p_transport = gatt_cb.tcb[i].transport; 742 found = TRUE; 743 GATT_TRACE_DEBUG("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x", 744 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); 745 break; 746 } 747 } 748 GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found, i); 749 return found; 750 } 751 752 753 754 /******************************************************************************* 755 ** 756 ** Function gatt_is_srv_chg_ind_pending 757 ** 758 ** Description Check whether a service chnaged is in the indication pending queue 759 ** or waiting for an Ack already 760 ** 761 ** Returns BOOLEAN 762 ** 763 *******************************************************************************/ 764 BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb) 765 { 766 BOOLEAN srv_chg_ind_pending = FALSE; 767 768 GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d", 769 fixed_queue_is_empty(p_tcb->pending_ind_q)); 770 771 if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) 772 { 773 srv_chg_ind_pending = TRUE; 774 } 775 else if (! fixed_queue_is_empty(p_tcb->pending_ind_q)) 776 { 777 list_t *list = fixed_queue_get_list(p_tcb->pending_ind_q); 778 for (const list_node_t *node = list_begin(list); 779 node != list_end(list); 780 node = list_next(node)) { 781 tGATT_VALUE *p_buf = (tGATT_VALUE *)list_node(node); 782 if (p_buf->handle == gatt_cb.handle_of_h_r) 783 { 784 srv_chg_ind_pending = TRUE; 785 break; 786 } 787 } 788 } 789 790 GATT_TRACE_DEBUG("srv_chg_ind_pending = %d", srv_chg_ind_pending); 791 return srv_chg_ind_pending; 792 } 793 794 795 /******************************************************************************* 796 ** 797 ** Function gatt_is_bda_in_the_srv_chg_clt_list 798 ** 799 ** Description This function check the specified bda is in the srv chg clinet list or not 800 ** 801 ** Returns pointer to the found elemenet otherwise NULL 802 ** 803 *******************************************************************************/ 804 tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda) 805 { 806 tGATTS_SRV_CHG *p_buf = NULL; 807 808 GATT_TRACE_DEBUG("gatt_is_bda_in_the_srv_chg_clt_list :%02x-%02x-%02x-%02x-%02x-%02x", 809 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); 810 811 if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) 812 return NULL; 813 814 list_t *list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q); 815 for (const list_node_t *node = list_begin(list); node != list_end(list); 816 node = list_next(node)) { 817 tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)list_node(node); 818 if (!memcmp( bda, p_buf->bda, BD_ADDR_LEN)) 819 { 820 GATT_TRACE_DEBUG("bda is in the srv chg clt list"); 821 break; 822 } 823 } 824 825 return p_buf; 826 } 827 828 829 /******************************************************************************* 830 ** 831 ** Function gatt_is_bda_connected 832 ** 833 ** Description 834 ** 835 ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 836 ** 837 *******************************************************************************/ 838 BOOLEAN gatt_is_bda_connected(BD_ADDR bda) 839 { 840 UINT8 i = 0; 841 BOOLEAN connected=FALSE; 842 843 for ( i=0; i < GATT_MAX_PHY_CHANNEL; i ++) 844 { 845 if (gatt_cb.tcb[i].in_use && 846 !memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN)) 847 { 848 connected = TRUE; 849 break; 850 } 851 } 852 return connected; 853 } 854 855 /******************************************************************************* 856 ** 857 ** Function gatt_find_i_tcb_by_addr 858 ** 859 ** Description The function searches for an empty tcb entry, and return the index. 860 ** 861 ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 862 ** 863 *******************************************************************************/ 864 UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) 865 { 866 UINT8 i = 0; 867 868 for ( ; i < GATT_MAX_PHY_CHANNEL; i ++) 869 { 870 if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) && 871 gatt_cb.tcb[i].transport == transport) 872 { 873 return i; 874 } 875 } 876 return GATT_INDEX_INVALID; 877 } 878 879 880 /******************************************************************************* 881 ** 882 ** Function gatt_get_tcb_by_idx 883 ** 884 ** Description The function get TCB using the TCB index 885 ** 886 ** Returns NULL if not found. Otherwise index to the tcb. 887 ** 888 *******************************************************************************/ 889 tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx) 890 { 891 tGATT_TCB *p_tcb = NULL; 892 893 if ( (tcb_idx < GATT_MAX_PHY_CHANNEL) && gatt_cb.tcb[tcb_idx].in_use) 894 p_tcb = &gatt_cb.tcb[tcb_idx]; 895 896 return p_tcb; 897 } 898 899 /******************************************************************************* 900 ** 901 ** Function gatt_find_tcb_by_addr 902 ** 903 ** Description The function searches for an empty tcb entry, and return pointer. 904 ** 905 ** Returns NULL if not found. Otherwise index to the tcb. 906 ** 907 *******************************************************************************/ 908 tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) 909 { 910 tGATT_TCB *p_tcb = NULL; 911 UINT8 i = 0; 912 913 if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID) 914 p_tcb = &gatt_cb.tcb[i]; 915 916 return p_tcb; 917 } 918 /******************************************************************************* 919 ** 920 ** Function gatt_find_i_tcb_free 921 ** 922 ** Description The function searches for an empty tcb entry, and return the index. 923 ** 924 ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 925 ** 926 *******************************************************************************/ 927 UINT8 gatt_find_i_tcb_free(void) 928 { 929 UINT8 i = 0, j = GATT_INDEX_INVALID; 930 931 for (i = 0; i < GATT_MAX_PHY_CHANNEL; i ++) 932 { 933 if (!gatt_cb.tcb[i].in_use) 934 { 935 j = i; 936 break; 937 } 938 } 939 return j; 940 } 941 /******************************************************************************* 942 ** 943 ** Function gatt_allocate_tcb_by_bdaddr 944 ** 945 ** Description The function locate or allocate new tcb entry for matching bda. 946 ** 947 ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. 948 ** 949 *******************************************************************************/ 950 tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) 951 { 952 UINT8 i = 0; 953 BOOLEAN allocated = FALSE; 954 tGATT_TCB *p_tcb = NULL; 955 956 /* search for existing tcb with matching bda */ 957 i = gatt_find_i_tcb_by_addr(bda, transport); 958 /* find free tcb */ 959 if (i == GATT_INDEX_INVALID) 960 { 961 i = gatt_find_i_tcb_free(); 962 allocated = TRUE; 963 } 964 if (i != GATT_INDEX_INVALID) 965 { 966 p_tcb = &gatt_cb.tcb[i]; 967 968 if (allocated) 969 { 970 memset(p_tcb, 0, sizeof(tGATT_TCB)); 971 p_tcb->pending_enc_clcb = fixed_queue_new(SIZE_MAX); 972 p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX); 973 p_tcb->conf_timer = alarm_new("gatt.conf_timer"); 974 p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer"); 975 p_tcb->sr_cmd.multi_rsp_q = fixed_queue_new(SIZE_MAX); 976 p_tcb->in_use = TRUE; 977 p_tcb->tcb_idx = i; 978 p_tcb->transport = transport; 979 } 980 memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); 981 } 982 return p_tcb; 983 } 984 985 /******************************************************************************* 986 ** 987 ** Function gatt_convert_uuid16_to_uuid128 988 ** 989 ** Description Convert a 16 bits UUID to be an standard 128 bits one. 990 ** 991 ** Returns TRUE if two uuid match; FALSE otherwise. 992 ** 993 *******************************************************************************/ 994 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16) 995 { 996 UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; 997 998 memcpy (uuid_128, base_uuid, LEN_UUID_128); 999 1000 UINT16_TO_STREAM(p, uuid_16); 1001 } 1002 1003 /******************************************************************************* 1004 ** 1005 ** Function gatt_convert_uuid32_to_uuid128 1006 ** 1007 ** Description Convert a 32 bits UUID to be an standard 128 bits one. 1008 ** 1009 ** Returns TRUE if two uuid match; FALSE otherwise. 1010 ** 1011 *******************************************************************************/ 1012 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32) 1013 { 1014 UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; 1015 1016 memcpy (uuid_128, base_uuid, LEN_UUID_128); 1017 1018 UINT32_TO_STREAM(p, uuid_32); 1019 } 1020 /******************************************************************************* 1021 ** 1022 ** Function gatt_uuid_compare 1023 ** 1024 ** Description Compare two UUID to see if they are the same. 1025 ** 1026 ** Returns TRUE if two uuid match; FALSE otherwise. 1027 ** 1028 *******************************************************************************/ 1029 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) 1030 { 1031 UINT8 su[LEN_UUID_128], tu[LEN_UUID_128]; 1032 UINT8 *ps, *pt; 1033 1034 /* any of the UUID is unspecified */ 1035 if (src.len == 0 || tar.len == 0) 1036 { 1037 return TRUE; 1038 } 1039 1040 /* If both are 16-bit, we can do a simple compare */ 1041 if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) 1042 { 1043 return src.uu.uuid16 == tar.uu.uuid16; 1044 } 1045 1046 /* If both are 32-bit, we can do a simple compare */ 1047 if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) 1048 { 1049 return src.uu.uuid32 == tar.uu.uuid32; 1050 } 1051 1052 /* One or both of the UUIDs is 128-bit */ 1053 if (src.len == LEN_UUID_16) 1054 { 1055 /* convert a 16 bits UUID to 128 bits value */ 1056 gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16); 1057 ps = su; 1058 } 1059 else if (src.len == LEN_UUID_32) 1060 { 1061 gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32); 1062 ps = su; 1063 } 1064 else 1065 ps = src.uu.uuid128; 1066 1067 if (tar.len == LEN_UUID_16) 1068 { 1069 /* convert a 16 bits UUID to 128 bits value */ 1070 gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16); 1071 pt = tu; 1072 } 1073 else if (tar.len == LEN_UUID_32) 1074 { 1075 /* convert a 32 bits UUID to 128 bits value */ 1076 gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32); 1077 pt = tu; 1078 } 1079 else 1080 pt = tar.uu.uuid128; 1081 1082 return(memcmp(ps, pt, LEN_UUID_128) == 0); 1083 } 1084 1085 /******************************************************************************* 1086 ** 1087 ** Function gatt_build_uuid_to_stream 1088 ** 1089 ** Description Add UUID into stream. 1090 ** 1091 ** Returns UUID length. 1092 ** 1093 *******************************************************************************/ 1094 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid) 1095 { 1096 UINT8 *p = *p_dst; 1097 UINT8 len = 0; 1098 1099 if (uuid.len == LEN_UUID_16) 1100 { 1101 UINT16_TO_STREAM (p, uuid.uu.uuid16); 1102 len = LEN_UUID_16; 1103 } 1104 else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */ 1105 { 1106 gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32); 1107 p += LEN_UUID_128; 1108 len = LEN_UUID_128; 1109 } 1110 else if (uuid.len == LEN_UUID_128) 1111 { 1112 ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128); 1113 len = LEN_UUID_128; 1114 } 1115 1116 *p_dst = p; 1117 return len; 1118 } 1119 1120 /******************************************************************************* 1121 ** 1122 ** Function gatt_parse_uuid_from_cmd 1123 ** 1124 ** Description Convert a 128 bits UUID into a 16 bits UUID. 1125 ** 1126 ** Returns TRUE if command sent, otherwise FALSE. 1127 ** 1128 *******************************************************************************/ 1129 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data) 1130 { 1131 BOOLEAN is_base_uuid, ret = TRUE; 1132 UINT8 xx; 1133 UINT8 *p_uuid = *p_data; 1134 1135 memset(p_uuid_rec, 0, sizeof(tBT_UUID)); 1136 1137 switch (uuid_size) 1138 { 1139 case LEN_UUID_16: 1140 p_uuid_rec->len = uuid_size; 1141 STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid); 1142 *p_data += LEN_UUID_16; 1143 break; 1144 1145 case LEN_UUID_128: 1146 /* See if we can compress his UUID down to 16 or 32bit UUIDs */ 1147 is_base_uuid = TRUE; 1148 for (xx = 0; xx < LEN_UUID_128 - 4; xx++) 1149 { 1150 if (p_uuid[xx] != base_uuid[xx]) 1151 { 1152 is_base_uuid = FALSE; 1153 break; 1154 } 1155 } 1156 if (is_base_uuid) 1157 { 1158 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0)) 1159 { 1160 p_uuid += (LEN_UUID_128 - 4); 1161 p_uuid_rec->len = LEN_UUID_16; 1162 STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid); 1163 } 1164 else 1165 { 1166 p_uuid += (LEN_UUID_128 - LEN_UUID_32); 1167 p_uuid_rec->len = LEN_UUID_32; 1168 STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid); 1169 } 1170 } 1171 if (!is_base_uuid) 1172 { 1173 p_uuid_rec->len = LEN_UUID_128; 1174 memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128); 1175 } 1176 *p_data += LEN_UUID_128; 1177 break; 1178 1179 /* do not allow 32 bits UUID in ATT PDU now */ 1180 case LEN_UUID_32: 1181 GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU"); 1182 case 0: 1183 default: 1184 if (uuid_size != 0) ret = FALSE; 1185 GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size"); 1186 break; 1187 } 1188 1189 return( ret); 1190 } 1191 1192 /******************************************************************************* 1193 ** 1194 ** Function gatt_start_rsp_timer 1195 ** 1196 ** Description Start a wait_for_response timer. 1197 ** 1198 ** Returns void 1199 ** 1200 *******************************************************************************/ 1201 void gatt_start_rsp_timer(UINT16 clcb_idx) 1202 { 1203 tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx]; 1204 period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS; 1205 1206 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && 1207 p_clcb->op_subtype == GATT_DISC_SRVC_ALL) { 1208 timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS; 1209 } 1210 1211 // TODO: The tGATT_CLCB memory and state management needs cleanup, 1212 // and then the timers can be allocated elsewhere. 1213 if (p_clcb->gatt_rsp_timer_ent == NULL) { 1214 p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent"); 1215 } 1216 alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms, 1217 gatt_rsp_timeout, p_clcb, btu_general_alarm_queue); 1218 } 1219 1220 /******************************************************************************* 1221 ** 1222 ** Function gatt_start_conf_timer 1223 ** 1224 ** Description Start a wait_for_confirmation timer. 1225 ** 1226 ** Returns void 1227 ** 1228 *******************************************************************************/ 1229 void gatt_start_conf_timer(tGATT_TCB *p_tcb) 1230 { 1231 alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 1232 gatt_indication_confirmation_timeout, p_tcb, 1233 btu_general_alarm_queue); 1234 } 1235 1236 /******************************************************************************* 1237 ** 1238 ** Function gatt_start_ind_ack_timer 1239 ** 1240 ** Description start the application ack timer 1241 ** 1242 ** Returns void 1243 ** 1244 *******************************************************************************/ 1245 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb) 1246 { 1247 /* start notification cache timer */ 1248 alarm_set_on_queue(p_tcb->ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 1249 gatt_ind_ack_timeout, p_tcb, btu_general_alarm_queue); 1250 } 1251 1252 /******************************************************************************* 1253 ** 1254 ** Function gatt_rsp_timeout 1255 ** 1256 ** Description Called when GATT wait for ATT command response timer expires 1257 ** 1258 ** Returns void 1259 ** 1260 *******************************************************************************/ 1261 void gatt_rsp_timeout(void *data) 1262 { 1263 tGATT_CLCB *p_clcb = (tGATT_CLCB *)data; 1264 1265 if (p_clcb == NULL || p_clcb->p_tcb == NULL) 1266 { 1267 GATT_TRACE_WARNING("%s clcb is already deleted", __func__); 1268 return; 1269 } 1270 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && 1271 p_clcb->op_subtype == GATT_DISC_SRVC_ALL && 1272 p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) 1273 { 1274 UINT8 rsp_code; 1275 GATT_TRACE_WARNING("%s retry discovery primary service", __func__); 1276 if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code)) 1277 { 1278 GATT_TRACE_ERROR("%s command queue out of sync, disconnect", 1279 __func__); 1280 } 1281 else 1282 { 1283 p_clcb->retry_count++; 1284 gatt_act_discovery(p_clcb); 1285 return; 1286 } 1287 } 1288 1289 GATT_TRACE_WARNING("%s disconnecting...", __func__); 1290 gatt_disconnect (p_clcb->p_tcb); 1291 } 1292 1293 /******************************************************************************* 1294 ** 1295 ** Function gatt_indication_confirmation_timeout 1296 ** 1297 ** Description Called when the indication confirmation timer expires 1298 ** 1299 ** Returns void 1300 ** 1301 *******************************************************************************/ 1302 void gatt_indication_confirmation_timeout(void *data) 1303 { 1304 tGATT_TCB *p_tcb = (tGATT_TCB *)data; 1305 1306 GATT_TRACE_WARNING("%s disconnecting...", __func__); 1307 gatt_disconnect(p_tcb); 1308 } 1309 1310 /******************************************************************************* 1311 ** 1312 ** Function gatt_ind_ack_timeout 1313 ** 1314 ** Description Called when GATT wait for ATT handle confirmation timeout 1315 ** 1316 ** Returns void 1317 ** 1318 *******************************************************************************/ 1319 void gatt_ind_ack_timeout(void *data) 1320 { 1321 tGATT_TCB *p_tcb = (tGATT_TCB *)data; 1322 1323 GATT_TRACE_WARNING("%s send ack now", __func__); 1324 1325 if (p_tcb != NULL) 1326 p_tcb->ind_count = 0; 1327 1328 attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL); 1329 } 1330 /******************************************************************************* 1331 ** 1332 ** Function gatt_sr_find_i_rcb_by_handle 1333 ** 1334 ** Description The function searches for a service that owns a specific handle. 1335 ** 1336 ** Returns GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice. 1337 ** 1338 *******************************************************************************/ 1339 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle) 1340 { 1341 UINT8 i_rcb = 0; 1342 1343 for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++) 1344 { 1345 if (gatt_cb.sr_reg[i_rcb].in_use && 1346 gatt_cb.sr_reg[i_rcb].s_hdl <= handle && 1347 gatt_cb.sr_reg[i_rcb].e_hdl >= handle ) 1348 { 1349 break; 1350 } 1351 } 1352 return i_rcb; 1353 } 1354 1355 /******************************************************************************* 1356 ** 1357 ** Function gatt_sr_find_i_rcb_by_handle 1358 ** 1359 ** Description The function searches for a service that owns a specific handle. 1360 ** 1361 ** Returns 0 if not found. Otherwise index of th eservice. 1362 ** 1363 *******************************************************************************/ 1364 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst) 1365 { 1366 UINT8 i_rcb = 0; 1367 tGATT_SR_REG *p_sreg; 1368 tBT_UUID *p_this_uuid; 1369 1370 for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++) 1371 { 1372 if ( p_sreg->in_use ) 1373 { 1374 p_this_uuid = gatts_get_service_uuid (p_sreg->p_db); 1375 1376 if (p_this_uuid && 1377 gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) && 1378 gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) && 1379 (svc_inst == p_sreg->service_instance)) 1380 { 1381 GATT_TRACE_ERROR ("Active Service Found "); 1382 gatt_dbg_display_uuid(*p_svc_uuid); 1383 1384 break; 1385 } 1386 } 1387 } 1388 return i_rcb; 1389 } 1390 /******************************************************************************* 1391 ** 1392 ** Function gatt_sr_find_i_rcb_by_handle 1393 ** 1394 ** Description The function searches for a service that owns a specific handle. 1395 ** 1396 ** Returns 0 if not found. Otherwise index of th eservice. 1397 ** 1398 *******************************************************************************/ 1399 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list ) 1400 { 1401 UINT8 ii = 0; 1402 tGATT_SR_REG *p_sreg = NULL; 1403 1404 /*this is a new application servoce start */ 1405 for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++) 1406 { 1407 if (!p_sreg->in_use) 1408 { 1409 memset (p_sreg, 0, sizeof(tGATT_SR_REG)); 1410 1411 p_sreg->in_use = TRUE; 1412 memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID)); 1413 1414 p_sreg->service_instance = p_list->asgn_range.svc_inst; 1415 p_sreg->type = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE; 1416 p_sreg->s_hdl = p_list->asgn_range.s_handle; 1417 p_sreg->e_hdl = p_list->asgn_range.e_handle; 1418 p_sreg->p_db = &p_list->svc_db; 1419 1420 GATT_TRACE_DEBUG("total buffer in db [%d]", 1421 fixed_queue_length(p_sreg->p_db->svc_buffer)); 1422 break; 1423 } 1424 } 1425 1426 return ii; 1427 } 1428 /******************************************************************************* 1429 ** 1430 ** Function gatt_sr_get_sec_info 1431 ** 1432 ** Description Get the security flag and key size information for the peer 1433 ** device. 1434 ** 1435 ** Returns void 1436 ** 1437 *******************************************************************************/ 1438 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size) 1439 { 1440 UINT8 sec_flag = 0; 1441 1442 BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport); 1443 1444 sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED); 1445 1446 *p_key_size = btm_ble_read_sec_key_size(rem_bda); 1447 *p_sec_flag = sec_flag; 1448 } 1449 /******************************************************************************* 1450 ** 1451 ** Function gatt_sr_send_req_callback 1452 ** 1453 ** Description 1454 ** 1455 ** 1456 ** Returns void 1457 ** 1458 *******************************************************************************/ 1459 void gatt_sr_send_req_callback(UINT16 conn_id, 1460 UINT32 trans_id, 1461 tGATTS_REQ_TYPE type, tGATTS_DATA *p_data) 1462 { 1463 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 1464 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 1465 1466 if (!p_reg ) 1467 { 1468 GATT_TRACE_ERROR ("p_reg not found discard request"); 1469 return; 1470 } 1471 1472 if ( p_reg->in_use && 1473 p_reg->app_cb.p_req_cb) 1474 { 1475 (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data); 1476 } 1477 else 1478 { 1479 GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id); 1480 } 1481 1482 } 1483 1484 /******************************************************************************* 1485 ** 1486 ** Function gatt_send_error_rsp 1487 ** 1488 ** Description This function sends an error response. 1489 ** 1490 ** Returns void 1491 ** 1492 *******************************************************************************/ 1493 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code, 1494 UINT16 handle, BOOLEAN deq) 1495 { 1496 tGATT_ERROR error; 1497 tGATT_STATUS status; 1498 BT_HDR *p_buf; 1499 1500 error.cmd_code = op_code; 1501 error.reason = err_code; 1502 error.handle =handle; 1503 1504 if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL) 1505 { 1506 status = attp_send_sr_msg (p_tcb, p_buf); 1507 } 1508 else 1509 status = GATT_INSUF_RESOURCE; 1510 1511 if (deq) 1512 gatt_dequeue_sr_cmd(p_tcb); 1513 1514 return status; 1515 } 1516 1517 1518 /******************************************************************************* 1519 ** 1520 ** Function gatt_add_sdp_record 1521 ** 1522 ** Description This function add a SDP record for a GATT primary service 1523 ** 1524 ** Returns 0 if error else sdp handle for the record. 1525 ** 1526 *******************************************************************************/ 1527 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) 1528 { 1529 tSDP_PROTOCOL_ELEM proto_elem_list[2]; 1530 UINT32 sdp_handle; 1531 UINT16 list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; 1532 UINT8 buff[60]; 1533 UINT8 *p = buff; 1534 1535 GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x s_hdl=0x%x",start_hdl, end_hdl); 1536 1537 if ((sdp_handle = SDP_CreateRecord()) == 0) 1538 return 0; 1539 1540 switch (p_uuid->len) 1541 { 1542 case LEN_UUID_16: 1543 SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16); 1544 break; 1545 1546 case LEN_UUID_32: 1547 UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); 1548 UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32); 1549 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, 1550 (UINT32) (p - buff), buff); 1551 break; 1552 1553 case LEN_UUID_128: 1554 UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); 1555 ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128); 1556 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, 1557 (UINT32) (p - buff), buff); 1558 break; 1559 1560 default: 1561 GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len); 1562 SDP_DeleteRecord(sdp_handle); 1563 return 0; 1564 break; 1565 } 1566 1567 /*** Fill out the protocol element sequence for SDP ***/ 1568 proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP; 1569 proto_elem_list[0].num_params = 1; 1570 proto_elem_list[0].params[0] = BT_PSM_ATT; 1571 proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT; 1572 proto_elem_list[1].num_params = 2; 1573 proto_elem_list[1].params[0] = start_hdl; 1574 proto_elem_list[1].params[1] = end_hdl; 1575 1576 SDP_AddProtocolList(sdp_handle, 2, proto_elem_list); 1577 1578 /* Make the service browseable */ 1579 SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list); 1580 1581 return(sdp_handle); 1582 } 1583 1584 1585 #if GATT_CONFORMANCE_TESTING == TRUE 1586 /******************************************************************************* 1587 ** 1588 ** Function gatt_set_err_rsp 1589 ** 1590 ** Description This function is called to set the test confirm value 1591 ** 1592 ** Returns void 1593 ** 1594 *******************************************************************************/ 1595 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status) 1596 { 1597 GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status); 1598 gatt_cb.enable_err_rsp = enable; 1599 gatt_cb.req_op_code = req_op_code; 1600 gatt_cb.err_status = err_status; 1601 } 1602 #endif 1603 1604 1605 1606 /******************************************************************************* 1607 ** 1608 ** Function gatt_get_regcb 1609 ** 1610 ** Description The function returns the registration control block. 1611 ** 1612 ** Returns pointer to the registration control block or NULL 1613 ** 1614 *******************************************************************************/ 1615 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if) 1616 { 1617 UINT8 ii = (UINT8)gatt_if; 1618 tGATT_REG *p_reg = NULL; 1619 1620 if (ii < 1 || ii > GATT_MAX_APPS) { 1621 GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii); 1622 return NULL; 1623 } 1624 1625 // Index for cl_rcb is always 1 less than gatt_if. 1626 p_reg = &gatt_cb.cl_rcb[ii - 1]; 1627 1628 if (!p_reg->in_use) { 1629 GATT_TRACE_WARNING("gatt_if found but not in use."); 1630 return NULL; 1631 } 1632 1633 return p_reg; 1634 } 1635 1636 1637 /******************************************************************************* 1638 ** 1639 ** Function gatt_is_clcb_allocated 1640 ** 1641 ** Description The function check clcb for conn_id is allocated or not 1642 ** 1643 ** Returns True already allocated 1644 ** 1645 *******************************************************************************/ 1646 1647 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id) 1648 { 1649 UINT8 i = 0; 1650 BOOLEAN is_allocated= FALSE; 1651 1652 for (i = 0; i < GATT_CL_MAX_LCB; i++) 1653 { 1654 if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id)) 1655 { 1656 is_allocated = TRUE; 1657 break; 1658 } 1659 } 1660 1661 return is_allocated; 1662 } 1663 1664 /******************************************************************************* 1665 ** 1666 ** Function gatt_clcb_alloc 1667 ** 1668 ** Description The function allocates a GATT connection link control block 1669 ** 1670 ** Returns NULL if not found. Otherwise pointer to the connection link block. 1671 ** 1672 *******************************************************************************/ 1673 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id) 1674 { 1675 UINT8 i = 0; 1676 tGATT_CLCB *p_clcb = NULL; 1677 tGATT_IF gatt_if=GATT_GET_GATT_IF(conn_id); 1678 UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); 1679 tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx); 1680 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 1681 1682 for (i = 0; i < GATT_CL_MAX_LCB; i++) 1683 { 1684 if (!gatt_cb.clcb[i].in_use) 1685 { 1686 p_clcb = &gatt_cb.clcb[i]; 1687 1688 p_clcb->in_use = TRUE; 1689 p_clcb->conn_id = conn_id; 1690 p_clcb->clcb_idx = i; 1691 p_clcb->p_reg = p_reg; 1692 p_clcb->p_tcb = p_tcb; 1693 break; 1694 } 1695 } 1696 return p_clcb; 1697 } 1698 1699 /******************************************************************************* 1700 ** 1701 ** Function gatt_clcb_dealloc 1702 ** 1703 ** Description The function de allocates a GATT connection link control block 1704 ** 1705 ** Returns None 1706 ** 1707 *******************************************************************************/ 1708 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb) 1709 { 1710 if (p_clcb && p_clcb->in_use) 1711 { 1712 alarm_free(p_clcb->gatt_rsp_timer_ent); 1713 memset(p_clcb, 0, sizeof(tGATT_CLCB)); 1714 } 1715 } 1716 1717 1718 1719 /******************************************************************************* 1720 ** 1721 ** Function gatt_find_tcb_by_cid 1722 ** 1723 ** Description The function searches for an empty entry 1724 ** in registration info table for GATT client 1725 ** 1726 ** Returns NULL if not found. Otherwise pointer to the rcb. 1727 ** 1728 *******************************************************************************/ 1729 tGATT_TCB * gatt_find_tcb_by_cid (UINT16 lcid) 1730 { 1731 UINT16 xx = 0; 1732 tGATT_TCB *p_tcb = NULL; 1733 1734 for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++) 1735 { 1736 if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid) 1737 { 1738 p_tcb = &gatt_cb.tcb[xx]; 1739 break; 1740 } 1741 } 1742 return p_tcb; 1743 } 1744 1745 1746 /******************************************************************************* 1747 ** 1748 ** Function gatt_num_apps_hold_link 1749 ** 1750 ** Description The function find the number of applcaitions is holding the link 1751 ** 1752 ** Returns total number of applications holding this acl link. 1753 ** 1754 *******************************************************************************/ 1755 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb) 1756 { 1757 UINT8 i, num = 0; 1758 1759 for (i = 0; i < GATT_MAX_APPS; i ++) 1760 { 1761 if (p_tcb->app_hold_link[i]) 1762 num ++; 1763 } 1764 1765 GATT_TRACE_DEBUG("gatt_num_apps_hold_link num=%d", num); 1766 return num; 1767 } 1768 1769 1770 /******************************************************************************* 1771 ** 1772 ** Function gatt_num_clcb_by_bd_addr 1773 ** 1774 ** Description The function searches all LCB with macthing bd address 1775 ** 1776 ** Returns total number of clcb found. 1777 ** 1778 *******************************************************************************/ 1779 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda) 1780 { 1781 UINT8 i, num = 0; 1782 1783 for (i = 0; i < GATT_CL_MAX_LCB; i ++) 1784 { 1785 if (gatt_cb.clcb[i].in_use && memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0) 1786 num ++; 1787 } 1788 return num; 1789 } 1790 1791 /******************************************************************************* 1792 ** 1793 ** Function gatt_sr_update_cback_cnt 1794 ** 1795 ** Description The function searches all LCB with macthing bd address 1796 ** 1797 ** Returns total number of clcb found. 1798 ** 1799 *******************************************************************************/ 1800 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb ) 1801 { 1802 UINT8 i; 1803 1804 if (p_tcb) 1805 { 1806 for (i = 0; i < GATT_MAX_APPS; i ++) 1807 { 1808 if (p_tcb->prep_cnt[i]) 1809 { 1810 p_tcb->sr_cmd.cback_cnt[i]=1; 1811 } 1812 } 1813 } 1814 1815 } 1816 1817 /******************************************************************************* 1818 ** 1819 ** Function gatt_sr_is_cback_cnt_zero 1820 ** 1821 ** Description The function searches all LCB with macthing bd address 1822 ** 1823 ** Returns True if thetotal application callback count is zero 1824 ** 1825 *******************************************************************************/ 1826 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb ) 1827 { 1828 BOOLEAN status = TRUE; 1829 UINT8 i; 1830 1831 if (p_tcb) 1832 { 1833 for (i = 0; i < GATT_MAX_APPS; i ++) 1834 { 1835 if (p_tcb->sr_cmd.cback_cnt[i]) 1836 { 1837 status = FALSE; 1838 break; 1839 } 1840 } 1841 } 1842 else 1843 { 1844 status = FALSE; 1845 } 1846 return status; 1847 } 1848 1849 /******************************************************************************* 1850 ** 1851 ** Function gatt_sr_is_prep_cnt_zero 1852 ** 1853 ** Description Check the prepare write request count is zero or not 1854 ** 1855 ** Returns True no prepare write request 1856 ** 1857 *******************************************************************************/ 1858 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb) 1859 { 1860 BOOLEAN status = TRUE; 1861 UINT8 i; 1862 1863 if (p_tcb) 1864 { 1865 for (i = 0; i < GATT_MAX_APPS; i ++) 1866 { 1867 if (p_tcb->prep_cnt[i]) 1868 { 1869 status = FALSE; 1870 break; 1871 } 1872 } 1873 } 1874 else 1875 { 1876 status = FALSE; 1877 } 1878 return status; 1879 } 1880 1881 1882 /******************************************************************************* 1883 ** 1884 ** Function gatt_sr_reset_cback_cnt 1885 ** 1886 ** Description Reset the application callback count to zero 1887 ** 1888 ** Returns None 1889 ** 1890 *******************************************************************************/ 1891 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb ) 1892 { 1893 UINT8 i; 1894 1895 if (p_tcb) 1896 { 1897 for (i = 0; i < GATT_MAX_APPS; i ++) 1898 { 1899 p_tcb->sr_cmd.cback_cnt[i]=0; 1900 } 1901 } 1902 } 1903 1904 /******************************************************************************* 1905 ** 1906 ** Function gatt_sr_reset_prep_cnt 1907 ** 1908 ** Description Reset the prep write count to zero 1909 ** 1910 ** Returns None 1911 ** 1912 *******************************************************************************/ 1913 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb ) 1914 { 1915 UINT8 i; 1916 if (p_tcb) 1917 { 1918 for (i = 0; i < GATT_MAX_APPS; i ++) 1919 { 1920 p_tcb->prep_cnt[i]=0; 1921 } 1922 } 1923 } 1924 1925 1926 /******************************************************************************* 1927 ** 1928 ** Function gatt_sr_update_cback_cnt 1929 ** 1930 ** Description Update the teh applicaiton callback count 1931 ** 1932 ** Returns None 1933 ** 1934 *******************************************************************************/ 1935 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first) 1936 { 1937 1938 UINT8 idx = ((UINT8) gatt_if) - 1 ; 1939 1940 if (p_tcb) 1941 { 1942 if (is_reset_first) 1943 { 1944 gatt_sr_reset_cback_cnt(p_tcb); 1945 } 1946 if (is_inc) 1947 { 1948 p_tcb->sr_cmd.cback_cnt[idx]++; 1949 } 1950 else 1951 { 1952 if ( p_tcb->sr_cmd.cback_cnt[idx]) 1953 { 1954 p_tcb->sr_cmd.cback_cnt[idx]--; 1955 } 1956 } 1957 } 1958 } 1959 1960 1961 /******************************************************************************* 1962 ** 1963 ** Function gatt_sr_update_prep_cnt 1964 ** 1965 ** Description Update the teh prepare write request count 1966 ** 1967 ** Returns None 1968 ** 1969 *******************************************************************************/ 1970 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first) 1971 { 1972 UINT8 idx = ((UINT8) gatt_if) - 1 ; 1973 1974 GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d", 1975 p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first); 1976 1977 if (p_tcb) 1978 { 1979 if (is_reset_first) 1980 { 1981 gatt_sr_reset_prep_cnt(p_tcb); 1982 } 1983 if (is_inc) 1984 { 1985 p_tcb->prep_cnt[idx]++; 1986 } 1987 else 1988 { 1989 if (p_tcb->prep_cnt[idx]) 1990 { 1991 p_tcb->prep_cnt[idx]--; 1992 } 1993 } 1994 } 1995 } 1996 /******************************************************************************* 1997 ** 1998 ** Function gatt_cancel_open 1999 ** 2000 ** Description Cancel open request 2001 ** 2002 ** Returns Boolean 2003 ** 2004 *******************************************************************************/ 2005 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) 2006 { 2007 tGATT_TCB *p_tcb=NULL; 2008 BOOLEAN status= TRUE; 2009 2010 p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE); 2011 2012 if (p_tcb) 2013 { 2014 if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) 2015 { 2016 GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel"); 2017 status = FALSE; 2018 } 2019 else 2020 { 2021 gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); 2022 if (!gatt_num_apps_hold_link(p_tcb)) 2023 { 2024 gatt_disconnect(p_tcb); 2025 } 2026 } 2027 } 2028 2029 return status; 2030 } 2031 2032 /******************************************************************************* 2033 ** 2034 ** Function gatt_find_app_hold_link 2035 ** 2036 ** Description find the applicaiton that is holding the specified link 2037 ** 2038 ** Returns Boolean 2039 ** 2040 *******************************************************************************/ 2041 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if) 2042 { 2043 UINT8 i; 2044 BOOLEAN found= FALSE; 2045 2046 for (i = start_idx; i < GATT_MAX_APPS; i ++) 2047 { 2048 if (p_tcb->app_hold_link[i]) 2049 { 2050 *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if; 2051 *p_found_idx = i; 2052 found = TRUE; 2053 break; 2054 } 2055 } 2056 return found; 2057 } 2058 2059 /******************************************************************************* 2060 ** 2061 ** Function gatt_cmd_enq 2062 ** 2063 ** Description Enqueue this command. 2064 ** 2065 ** Returns None. 2066 ** 2067 *******************************************************************************/ 2068 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf) 2069 { 2070 tGATT_CMD_Q *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq]; 2071 2072 p_cmd->to_send = to_send; /* waiting to be sent */ 2073 p_cmd->op_code = op_code; 2074 p_cmd->p_cmd = p_buf; 2075 p_cmd->clcb_idx = clcb_idx; 2076 2077 if (!to_send) 2078 { 2079 p_tcb->pending_cl_req = p_tcb->next_slot_inq; 2080 } 2081 2082 p_tcb->next_slot_inq ++; 2083 p_tcb->next_slot_inq %= GATT_CL_MAX_LCB; 2084 2085 return TRUE; 2086 } 2087 2088 /******************************************************************************* 2089 ** 2090 ** Function gatt_cmd_dequeue 2091 ** 2092 ** Description dequeue the command in the client CCB command queue. 2093 ** 2094 ** Returns total number of clcb found. 2095 ** 2096 *******************************************************************************/ 2097 tGATT_CLCB * gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code) 2098 { 2099 tGATT_CMD_Q *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req]; 2100 tGATT_CLCB *p_clcb = NULL; 2101 2102 if (p_tcb->pending_cl_req != p_tcb->next_slot_inq) 2103 { 2104 p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx]; 2105 2106 *p_op_code = p_cmd->op_code; 2107 2108 p_tcb->pending_cl_req ++; 2109 p_tcb->pending_cl_req %= GATT_CL_MAX_LCB; 2110 } 2111 2112 return p_clcb; 2113 } 2114 2115 /******************************************************************************* 2116 ** 2117 ** Function gatt_send_write_msg 2118 ** 2119 ** Description This real function send out the ATT message for write. 2120 ** 2121 ** Returns status code 2122 ** 2123 *******************************************************************************/ 2124 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, 2125 UINT16 handle, UINT16 len, 2126 UINT16 offset, UINT8 *p_data) 2127 { 2128 tGATT_CL_MSG msg; 2129 2130 msg.attr_value.handle = handle; 2131 msg.attr_value.len = len; 2132 msg.attr_value.offset = offset; 2133 2134 memcpy (msg.attr_value.value, p_data, len); 2135 2136 /* write by handle */ 2137 return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg); 2138 } 2139 2140 /******************************************************************************* 2141 ** 2142 ** Function gatt_act_send_browse 2143 ** 2144 ** Description This function ends a browse command request, including read 2145 ** information request and read by type request. 2146 ** 2147 ** Returns status code 2148 ** 2149 *******************************************************************************/ 2150 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle, 2151 UINT16 e_handle, tBT_UUID uuid) 2152 { 2153 tGATT_CL_MSG msg; 2154 2155 msg.browse.s_handle = s_handle; 2156 msg.browse.e_handle = e_handle; 2157 memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID)); 2158 2159 /* write by handle */ 2160 return attp_send_cl_msg(p_tcb, index, op, &msg); 2161 } 2162 2163 /******************************************************************************* 2164 ** 2165 ** Function gatt_end_operation 2166 ** 2167 ** Description This function ends a discovery, send callback and finalize 2168 ** some control value. 2169 ** 2170 ** Returns 16 bits uuid. 2171 ** 2172 *******************************************************************************/ 2173 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data) 2174 { 2175 tGATT_CL_COMPLETE cb_data; 2176 tGATT_CMPL_CBACK *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL; 2177 UINT8 op = p_clcb->operation, disc_type=GATT_DISC_MAX; 2178 tGATT_DISC_CMPL_CB *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL; 2179 UINT16 conn_id; 2180 UINT8 operation; 2181 2182 GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d", 2183 status, p_clcb->operation, p_clcb->op_subtype); 2184 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); 2185 2186 if (p_cmpl_cb != NULL && p_clcb->operation != 0) 2187 { 2188 if (p_clcb->operation == GATTC_OPTYPE_READ) 2189 { 2190 cb_data.att_value.handle = p_clcb->s_handle; 2191 cb_data.att_value.len = p_clcb->counter; 2192 2193 if (p_data && p_clcb->counter) 2194 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len); 2195 } 2196 2197 if (p_clcb->operation == GATTC_OPTYPE_WRITE) 2198 { 2199 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); 2200 cb_data.handle = 2201 cb_data.att_value.handle = p_clcb->s_handle; 2202 if (p_clcb->op_subtype == GATT_WRITE_PREPARE) 2203 { 2204 if (p_data) 2205 { 2206 cb_data.att_value = *((tGATT_VALUE *) p_data); 2207 } 2208 else 2209 { 2210 GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data"); 2211 } 2212 } 2213 } 2214 2215 if (p_clcb->operation == GATTC_OPTYPE_CONFIG) 2216 cb_data.mtu = p_clcb->p_tcb->payload_size; 2217 2218 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) 2219 { 2220 disc_type = p_clcb->op_subtype; 2221 } 2222 } 2223 2224 osi_free_and_reset((void **)&p_clcb->p_attr_buf); 2225 2226 operation = p_clcb->operation; 2227 conn_id = p_clcb->conn_id; 2228 alarm_cancel(p_clcb->gatt_rsp_timer_ent); 2229 2230 gatt_clcb_dealloc(p_clcb); 2231 2232 if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY)) 2233 (*p_disc_cmpl_cb)(conn_id, disc_type, status); 2234 else if (p_cmpl_cb && op) 2235 (*p_cmpl_cb)(conn_id, op, status, &cb_data); 2236 else 2237 GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p", 2238 operation, p_disc_cmpl_cb, p_cmpl_cb); 2239 } 2240 2241 /******************************************************************************* 2242 ** 2243 ** Function gatt_cleanup_upon_disc 2244 ** 2245 ** Description This function cleans up the control blocks when L2CAP channel 2246 ** disconnect. 2247 ** 2248 ** Returns 16 bits uuid. 2249 ** 2250 *******************************************************************************/ 2251 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) 2252 { 2253 tGATT_TCB *p_tcb = NULL; 2254 tGATT_CLCB *p_clcb; 2255 UINT8 i; 2256 UINT16 conn_id; 2257 tGATT_REG *p_reg=NULL; 2258 2259 2260 GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc "); 2261 2262 if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) 2263 { 2264 GATT_TRACE_DEBUG ("found p_tcb "); 2265 gatt_set_ch_state(p_tcb, GATT_CH_CLOSE); 2266 for (i = 0; i < GATT_CL_MAX_LCB; i ++) 2267 { 2268 p_clcb = &gatt_cb.clcb[i]; 2269 if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) 2270 { 2271 alarm_cancel(p_clcb->gatt_rsp_timer_ent); 2272 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx); 2273 if (p_clcb->operation != GATTC_OPTYPE_NONE) 2274 gatt_end_operation(p_clcb, GATT_ERROR, NULL); 2275 2276 gatt_clcb_dealloc(p_clcb); 2277 2278 } 2279 } 2280 2281 alarm_free(p_tcb->ind_ack_timer); 2282 p_tcb->ind_ack_timer = NULL; 2283 alarm_free(p_tcb->conf_timer); 2284 p_tcb->conf_timer = NULL; 2285 gatt_free_pending_ind(p_tcb); 2286 gatt_free_pending_enc_queue(p_tcb); 2287 fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL); 2288 p_tcb->sr_cmd.multi_rsp_q = NULL; 2289 2290 for (i = 0; i < GATT_MAX_APPS; i ++) 2291 { 2292 p_reg = &gatt_cb.cl_rcb[i]; 2293 if (p_reg->in_use && p_reg->app_cb.p_conn_cb) 2294 { 2295 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); 2296 GATT_TRACE_DEBUG ("found p_reg tcb_idx=%d gatt_if=%d conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id); 2297 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason, transport); 2298 } 2299 } 2300 memset(p_tcb, 0, sizeof(tGATT_TCB)); 2301 2302 } 2303 GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc "); 2304 } 2305 /******************************************************************************* 2306 ** 2307 ** Function gatt_dbg_req_op_name 2308 ** 2309 ** Description Get op code description name, for debug information. 2310 ** 2311 ** Returns UINT8 *: name of the operation. 2312 ** 2313 *******************************************************************************/ 2314 UINT8 * gatt_dbg_op_name(UINT8 op_code) 2315 { 2316 UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK); 2317 2318 if (op_code == GATT_CMD_WRITE ) 2319 { 2320 pseduo_op_code_idx = 0x14; /* just an index to op_code_name */ 2321 2322 } 2323 2324 if (op_code == GATT_SIGN_CMD_WRITE) 2325 { 2326 pseduo_op_code_idx = 0x15; /* just an index to op_code_name */ 2327 } 2328 2329 if (pseduo_op_code_idx <= GATT_OP_CODE_MAX) 2330 return(UINT8*) op_code_name[pseduo_op_code_idx]; 2331 else 2332 return(UINT8 *)"Op Code Exceed Max"; 2333 } 2334 2335 /******************************************************************************* 2336 ** 2337 ** Function gatt_dbg_display_uuid 2338 ** 2339 ** Description Disaplay the UUID 2340 ** 2341 ** Returns None 2342 ** 2343 *******************************************************************************/ 2344 void gatt_dbg_display_uuid(tBT_UUID bt_uuid) 2345 { 2346 char str_buf[50]; 2347 int x = 0; 2348 2349 if (bt_uuid.len == LEN_UUID_16) 2350 { 2351 sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16); 2352 } 2353 else if (bt_uuid.len == LEN_UUID_32) 2354 { 2355 sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32); 2356 } 2357 else if (bt_uuid.len == LEN_UUID_128) 2358 { 2359 x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x", 2360 bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14], 2361 bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12], 2362 bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10], 2363 bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]); 2364 sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x", 2365 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6], 2366 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4], 2367 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2], 2368 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]); 2369 } 2370 else 2371 strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf)); 2372 2373 GATT_TRACE_DEBUG ("UUID=[%s]", str_buf); 2374 } 2375 2376 2377 /******************************************************************************* 2378 ** 2379 ** Function gatt_is_bg_dev_for_app 2380 ** 2381 ** Description find is this one of the background devices for the application 2382 ** 2383 ** Returns TRUE this is one of the background devices for the application 2384 ** 2385 *******************************************************************************/ 2386 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if) 2387 { 2388 UINT8 i; 2389 2390 for (i = 0; i < GATT_MAX_APPS; i ++ ) 2391 { 2392 if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if)) 2393 { 2394 return TRUE; 2395 } 2396 } 2397 return FALSE; 2398 } 2399 /******************************************************************************* 2400 ** 2401 ** Function gatt_find_bg_dev 2402 ** 2403 ** Description find background connection device from the list. 2404 ** 2405 ** Returns pointer to the device record 2406 ** 2407 *******************************************************************************/ 2408 tGATT_BG_CONN_DEV * gatt_find_bg_dev(BD_ADDR remote_bda) 2409 { 2410 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2411 UINT8 i; 2412 2413 for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) 2414 { 2415 if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN)) 2416 { 2417 return p_dev_list; 2418 } 2419 } 2420 return NULL; 2421 } 2422 /******************************************************************************* 2423 ** 2424 ** Function gatt_alloc_bg_dev 2425 ** 2426 ** Description allocate a background connection device record 2427 ** 2428 ** Returns pointer to the device record 2429 ** 2430 *******************************************************************************/ 2431 tGATT_BG_CONN_DEV * gatt_alloc_bg_dev(BD_ADDR remote_bda) 2432 { 2433 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2434 UINT8 i; 2435 2436 for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) 2437 { 2438 if (!p_dev_list->in_use) 2439 { 2440 p_dev_list->in_use = TRUE; 2441 memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN); 2442 2443 return p_dev_list; 2444 } 2445 } 2446 return NULL; 2447 } 2448 2449 /******************************************************************************* 2450 ** 2451 ** Function gatt_add_bg_dev_list 2452 ** 2453 ** Description add/remove device from the back ground connection device list 2454 ** 2455 ** Returns TRUE if device added to the list; FALSE failed 2456 ** 2457 *******************************************************************************/ 2458 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initator) 2459 { 2460 tGATT_IF gatt_if = p_reg->gatt_if; 2461 tGATT_BG_CONN_DEV *p_dev = NULL; 2462 UINT8 i; 2463 BOOLEAN ret = FALSE; 2464 2465 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2466 { 2467 p_dev = gatt_alloc_bg_dev(bd_addr); 2468 } 2469 2470 if (p_dev) 2471 { 2472 for (i = 0; i < GATT_MAX_APPS; i ++) 2473 { 2474 if (is_initator) 2475 { 2476 if (p_dev->gatt_if[i] == gatt_if) 2477 { 2478 GATT_TRACE_ERROR("device already in iniator white list"); 2479 return TRUE; 2480 } 2481 else if (p_dev->gatt_if[i] == 0) 2482 { 2483 p_dev->gatt_if[i] = gatt_if; 2484 if (i == 0) 2485 ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr); 2486 else 2487 ret = TRUE; 2488 break; 2489 } 2490 } 2491 else 2492 { 2493 if (p_dev->listen_gif[i] == gatt_if) 2494 { 2495 GATT_TRACE_ERROR("device already in adv white list"); 2496 return TRUE; 2497 } 2498 else if (p_dev->listen_gif[i] == 0) 2499 { 2500 if (p_reg->listening == GATT_LISTEN_TO_ALL) 2501 p_reg->listening = GATT_LISTEN_TO_NONE; 2502 2503 p_reg->listening ++; 2504 p_dev->listen_gif[i] = gatt_if; 2505 2506 if (i == 0) 2507 ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr); 2508 else 2509 ret = TRUE; 2510 break; 2511 } 2512 } 2513 } 2514 } 2515 else 2516 { 2517 GATT_TRACE_ERROR("no device record available"); 2518 } 2519 2520 return ret; 2521 } 2522 2523 /******************************************************************************* 2524 ** 2525 ** Function gatt_remove_bg_dev_for_app 2526 ** 2527 ** Description Remove the application interface for the specified background device 2528 ** 2529 ** Returns Boolean 2530 ** 2531 *******************************************************************************/ 2532 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) 2533 { 2534 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 2535 BOOLEAN status; 2536 2537 if (p_tcb) 2538 gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); 2539 status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE); 2540 return status; 2541 } 2542 2543 2544 /******************************************************************************* 2545 ** 2546 ** Function gatt_get_num_apps_for_bg_dev 2547 ** 2548 ** Description Gte the number of applciations for the specified background device 2549 ** 2550 ** Returns UINT8 total number fo applications 2551 ** 2552 *******************************************************************************/ 2553 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr) 2554 { 2555 tGATT_BG_CONN_DEV *p_dev = NULL; 2556 UINT8 i; 2557 UINT8 cnt = 0; 2558 2559 if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL) 2560 { 2561 for (i = 0; i < GATT_MAX_APPS; i ++) 2562 { 2563 if (p_dev->gatt_if[i]) 2564 cnt++; 2565 } 2566 } 2567 return cnt; 2568 } 2569 2570 /******************************************************************************* 2571 ** 2572 ** Function gatt_find_app_for_bg_dev 2573 ** 2574 ** Description find the application interface for the specified background device 2575 ** 2576 ** Returns Boolean 2577 ** 2578 *******************************************************************************/ 2579 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if) 2580 { 2581 tGATT_BG_CONN_DEV *p_dev = NULL; 2582 UINT8 i; 2583 BOOLEAN ret = FALSE; 2584 2585 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2586 { 2587 return ret; 2588 } 2589 2590 for (i = 0; i < GATT_MAX_APPS; i ++) 2591 { 2592 if (p_dev->gatt_if[i] != 0 ) 2593 { 2594 *p_gatt_if = p_dev->gatt_if[i]; 2595 ret = TRUE; 2596 break; 2597 } 2598 } 2599 return ret; 2600 } 2601 2602 2603 /******************************************************************************* 2604 ** 2605 ** Function gatt_remove_bg_dev_from_list 2606 ** 2607 ** Description add/remove device from the back ground connection device list or 2608 ** listening to advertising list. 2609 ** 2610 ** Returns pointer to the device record 2611 ** 2612 *******************************************************************************/ 2613 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator) 2614 { 2615 tGATT_IF gatt_if = p_reg->gatt_if; 2616 tGATT_BG_CONN_DEV *p_dev = NULL; 2617 UINT8 i, j; 2618 BOOLEAN ret = FALSE; 2619 2620 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2621 { 2622 return ret; 2623 } 2624 2625 for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++) 2626 { 2627 if (is_initiator) 2628 { 2629 if (p_dev->gatt_if[i] == gatt_if) 2630 { 2631 p_dev->gatt_if[i] = 0; 2632 /* move all element behind one forward */ 2633 for (j = i + 1; j < GATT_MAX_APPS; j ++) 2634 p_dev->gatt_if[j - 1] = p_dev->gatt_if[j]; 2635 2636 if (p_dev->gatt_if[0] == 0) 2637 ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda); 2638 else 2639 ret = TRUE; 2640 2641 break; 2642 } 2643 } 2644 else 2645 { 2646 if (p_dev->listen_gif[i] == gatt_if) 2647 { 2648 p_dev->listen_gif[i] = 0; 2649 p_reg->listening --; 2650 /* move all element behind one forward */ 2651 for (j = i + 1; j < GATT_MAX_APPS; j ++) 2652 p_dev->listen_gif[j - 1] = p_dev->listen_gif[j]; 2653 2654 if (p_dev->listen_gif[0] == 0) 2655 ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda); 2656 else 2657 ret = TRUE; 2658 break; 2659 } 2660 } 2661 } 2662 2663 if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0) 2664 { 2665 memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV)); 2666 } 2667 2668 return ret; 2669 } 2670 /******************************************************************************* 2671 ** 2672 ** Function gatt_deregister_bgdev_list 2673 ** 2674 ** Description deregister all related back ground connetion device. 2675 ** 2676 ** Returns pointer to the device record 2677 ** 2678 *******************************************************************************/ 2679 void gatt_deregister_bgdev_list(tGATT_IF gatt_if) 2680 { 2681 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2682 UINT8 i , j, k; 2683 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 2684 2685 /* update the BG conn device list */ 2686 for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ ) 2687 { 2688 if (p_dev_list->in_use) 2689 { 2690 for (j = 0; j < GATT_MAX_APPS; j ++) 2691 { 2692 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0) 2693 break; 2694 2695 if (p_dev_list->gatt_if[j] == gatt_if) 2696 { 2697 for (k = j + 1; k < GATT_MAX_APPS; k ++) 2698 p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k]; 2699 2700 if (p_dev_list->gatt_if[0] == 0) 2701 BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda); 2702 } 2703 2704 if (p_dev_list->listen_gif[j] == gatt_if) 2705 { 2706 p_dev_list->listen_gif[j] = 0; 2707 2708 if (p_reg != NULL && p_reg->listening > 0) 2709 p_reg->listening --; 2710 2711 /* move all element behind one forward */ 2712 for (k = j + 1; k < GATT_MAX_APPS; k ++) 2713 p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k]; 2714 2715 if (p_dev_list->listen_gif[0] == 0) 2716 BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda); 2717 } 2718 } 2719 } 2720 } 2721 } 2722 2723 2724 /******************************************************************************* 2725 ** 2726 ** Function gatt_reset_bgdev_list 2727 ** 2728 ** Description reset bg device list 2729 ** 2730 ** Returns pointer to the device record 2731 ** 2732 *******************************************************************************/ 2733 void gatt_reset_bgdev_list(void) 2734 { 2735 memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV); 2736 2737 } 2738 /******************************************************************************* 2739 ** 2740 ** Function gatt_update_auto_connect_dev 2741 ** 2742 ** Description This function add or remove a device for background connection 2743 ** procedure. 2744 ** 2745 ** Parameters gatt_if: Application ID. 2746 ** add: add peer device 2747 ** bd_addr: peer device address. 2748 ** 2749 ** Returns TRUE if connection started; FALSE if connection start failure. 2750 ** 2751 *******************************************************************************/ 2752 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator) 2753 { 2754 BOOLEAN ret = FALSE; 2755 tGATT_REG *p_reg; 2756 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 2757 2758 GATT_TRACE_API ("gatt_update_auto_connect_dev "); 2759 /* Make sure app is registered */ 2760 if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) 2761 { 2762 GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if is not registered", gatt_if); 2763 return(FALSE); 2764 } 2765 2766 if (add) 2767 { 2768 ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator); 2769 2770 if (ret && p_tcb != NULL) 2771 { 2772 /* if a connected device, update the link holding number */ 2773 gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE); 2774 } 2775 } 2776 else 2777 { 2778 ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator); 2779 } 2780 return ret; 2781 } 2782 2783 2784 2785 /******************************************************************************* 2786 ** 2787 ** Function gatt_add_pending_new_srv_start 2788 ** 2789 ** Description Add a pending new srv start to the new service start queue 2790 ** 2791 ** Returns Pointer to the new service start buffer, NULL no buffer available 2792 ** 2793 *******************************************************************************/ 2794 tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb) 2795 { 2796 tGATT_PENDING_ENC_CLCB *p_buf = 2797 (tGATT_PENDING_ENC_CLCB *)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB)); 2798 2799 GATT_TRACE_DEBUG ("%s", __func__); 2800 GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb"); 2801 2802 p_buf->p_clcb = p_clcb; 2803 fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf); 2804 2805 return p_buf; 2806 } 2807 /******************************************************************************* 2808 ** 2809 ** Function gatt_update_listen_mode 2810 ** 2811 ** Description update peripheral role listening mode 2812 ** 2813 ** Returns Pointer to the new service start buffer, NULL no buffer available 2814 ** 2815 *******************************************************************************/ 2816 BOOLEAN gatt_update_listen_mode(void) 2817 { 2818 UINT8 ii = 0; 2819 tGATT_REG *p_reg = &gatt_cb.cl_rcb[0]; 2820 UINT8 listening = 0; 2821 UINT16 connectability, window, interval; 2822 BOOLEAN rt = TRUE; 2823 2824 for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) 2825 { 2826 if ( p_reg->in_use && p_reg->listening > listening) 2827 { 2828 listening = p_reg->listening; 2829 } 2830 } 2831 2832 if (listening == GATT_LISTEN_TO_ALL || 2833 listening == GATT_LISTEN_TO_NONE) 2834 BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL); 2835 else 2836 BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL); 2837 2838 if (rt) 2839 { 2840 connectability = BTM_ReadConnectability (&window, &interval); 2841 2842 if (listening != GATT_LISTEN_TO_NONE) 2843 { 2844 connectability |= BTM_BLE_CONNECTABLE; 2845 } 2846 else 2847 { 2848 if ((connectability & BTM_BLE_CONNECTABLE) == 0) 2849 connectability &= ~BTM_BLE_CONNECTABLE; 2850 } 2851 /* turning on the adv now */ 2852 btm_ble_set_connectability(connectability); 2853 } 2854 2855 return rt; 2856 2857 } 2858 #endif 2859 2860 2861