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->in_use = TRUE; 976 p_tcb->tcb_idx = i; 977 p_tcb->transport = transport; 978 } 979 memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); 980 } 981 return p_tcb; 982 } 983 984 /******************************************************************************* 985 ** 986 ** Function gatt_convert_uuid16_to_uuid128 987 ** 988 ** Description Convert a 16 bits UUID to be an standard 128 bits one. 989 ** 990 ** Returns TRUE if two uuid match; FALSE otherwise. 991 ** 992 *******************************************************************************/ 993 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16) 994 { 995 UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; 996 997 memcpy (uuid_128, base_uuid, LEN_UUID_128); 998 999 UINT16_TO_STREAM(p, uuid_16); 1000 } 1001 1002 /******************************************************************************* 1003 ** 1004 ** Function gatt_convert_uuid32_to_uuid128 1005 ** 1006 ** Description Convert a 32 bits UUID to be an standard 128 bits one. 1007 ** 1008 ** Returns TRUE if two uuid match; FALSE otherwise. 1009 ** 1010 *******************************************************************************/ 1011 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32) 1012 { 1013 UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; 1014 1015 memcpy (uuid_128, base_uuid, LEN_UUID_128); 1016 1017 UINT32_TO_STREAM(p, uuid_32); 1018 } 1019 /******************************************************************************* 1020 ** 1021 ** Function gatt_uuid_compare 1022 ** 1023 ** Description Compare two UUID to see if they are the same. 1024 ** 1025 ** Returns TRUE if two uuid match; FALSE otherwise. 1026 ** 1027 *******************************************************************************/ 1028 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) 1029 { 1030 UINT8 su[LEN_UUID_128], tu[LEN_UUID_128]; 1031 UINT8 *ps, *pt; 1032 1033 /* any of the UUID is unspecified */ 1034 if (src.len == 0 || tar.len == 0) 1035 { 1036 return TRUE; 1037 } 1038 1039 /* If both are 16-bit, we can do a simple compare */ 1040 if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) 1041 { 1042 return src.uu.uuid16 == tar.uu.uuid16; 1043 } 1044 1045 /* If both are 32-bit, we can do a simple compare */ 1046 if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) 1047 { 1048 return src.uu.uuid32 == tar.uu.uuid32; 1049 } 1050 1051 /* One or both of the UUIDs is 128-bit */ 1052 if (src.len == LEN_UUID_16) 1053 { 1054 /* convert a 16 bits UUID to 128 bits value */ 1055 gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16); 1056 ps = su; 1057 } 1058 else if (src.len == LEN_UUID_32) 1059 { 1060 gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32); 1061 ps = su; 1062 } 1063 else 1064 ps = src.uu.uuid128; 1065 1066 if (tar.len == LEN_UUID_16) 1067 { 1068 /* convert a 16 bits UUID to 128 bits value */ 1069 gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16); 1070 pt = tu; 1071 } 1072 else if (tar.len == LEN_UUID_32) 1073 { 1074 /* convert a 32 bits UUID to 128 bits value */ 1075 gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32); 1076 pt = tu; 1077 } 1078 else 1079 pt = tar.uu.uuid128; 1080 1081 return(memcmp(ps, pt, LEN_UUID_128) == 0); 1082 } 1083 1084 /******************************************************************************* 1085 ** 1086 ** Function gatt_build_uuid_to_stream 1087 ** 1088 ** Description Add UUID into stream. 1089 ** 1090 ** Returns UUID length. 1091 ** 1092 *******************************************************************************/ 1093 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid) 1094 { 1095 UINT8 *p = *p_dst; 1096 UINT8 len = 0; 1097 1098 if (uuid.len == LEN_UUID_16) 1099 { 1100 UINT16_TO_STREAM (p, uuid.uu.uuid16); 1101 len = LEN_UUID_16; 1102 } 1103 else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */ 1104 { 1105 gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32); 1106 p += LEN_UUID_128; 1107 len = LEN_UUID_128; 1108 } 1109 else if (uuid.len == LEN_UUID_128) 1110 { 1111 ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128); 1112 len = LEN_UUID_128; 1113 } 1114 1115 *p_dst = p; 1116 return len; 1117 } 1118 1119 /******************************************************************************* 1120 ** 1121 ** Function gatt_parse_uuid_from_cmd 1122 ** 1123 ** Description Convert a 128 bits UUID into a 16 bits UUID. 1124 ** 1125 ** Returns TRUE if command sent, otherwise FALSE. 1126 ** 1127 *******************************************************************************/ 1128 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data) 1129 { 1130 BOOLEAN is_base_uuid, ret = TRUE; 1131 UINT8 xx; 1132 UINT8 *p_uuid = *p_data; 1133 1134 memset(p_uuid_rec, 0, sizeof(tBT_UUID)); 1135 1136 switch (uuid_size) 1137 { 1138 case LEN_UUID_16: 1139 p_uuid_rec->len = uuid_size; 1140 STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid); 1141 *p_data += LEN_UUID_16; 1142 break; 1143 1144 case LEN_UUID_128: 1145 /* See if we can compress his UUID down to 16 or 32bit UUIDs */ 1146 is_base_uuid = TRUE; 1147 for (xx = 0; xx < LEN_UUID_128 - 4; xx++) 1148 { 1149 if (p_uuid[xx] != base_uuid[xx]) 1150 { 1151 is_base_uuid = FALSE; 1152 break; 1153 } 1154 } 1155 if (is_base_uuid) 1156 { 1157 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0)) 1158 { 1159 p_uuid += (LEN_UUID_128 - 4); 1160 p_uuid_rec->len = LEN_UUID_16; 1161 STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid); 1162 } 1163 else 1164 { 1165 p_uuid += (LEN_UUID_128 - LEN_UUID_32); 1166 p_uuid_rec->len = LEN_UUID_32; 1167 STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid); 1168 } 1169 } 1170 if (!is_base_uuid) 1171 { 1172 p_uuid_rec->len = LEN_UUID_128; 1173 memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128); 1174 } 1175 *p_data += LEN_UUID_128; 1176 break; 1177 1178 /* do not allow 32 bits UUID in ATT PDU now */ 1179 case LEN_UUID_32: 1180 GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU"); 1181 case 0: 1182 default: 1183 if (uuid_size != 0) ret = FALSE; 1184 GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size"); 1185 break; 1186 } 1187 1188 return( ret); 1189 } 1190 1191 /******************************************************************************* 1192 ** 1193 ** Function gatt_start_rsp_timer 1194 ** 1195 ** Description Start a wait_for_response timer. 1196 ** 1197 ** Returns void 1198 ** 1199 *******************************************************************************/ 1200 void gatt_start_rsp_timer(UINT16 clcb_idx) 1201 { 1202 tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx]; 1203 period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS; 1204 1205 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && 1206 p_clcb->op_subtype == GATT_DISC_SRVC_ALL) { 1207 timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS; 1208 } 1209 1210 // TODO: The tGATT_CLCB memory and state management needs cleanup, 1211 // and then the timers can be allocated elsewhere. 1212 if (p_clcb->gatt_rsp_timer_ent == NULL) { 1213 p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent"); 1214 } 1215 alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms, 1216 gatt_rsp_timeout, p_clcb, btu_general_alarm_queue); 1217 } 1218 1219 /******************************************************************************* 1220 ** 1221 ** Function gatt_start_conf_timer 1222 ** 1223 ** Description Start a wait_for_confirmation timer. 1224 ** 1225 ** Returns void 1226 ** 1227 *******************************************************************************/ 1228 void gatt_start_conf_timer(tGATT_TCB *p_tcb) 1229 { 1230 alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 1231 gatt_indication_confirmation_timeout, p_tcb, 1232 btu_general_alarm_queue); 1233 } 1234 1235 /******************************************************************************* 1236 ** 1237 ** Function gatt_start_ind_ack_timer 1238 ** 1239 ** Description start the application ack timer 1240 ** 1241 ** Returns void 1242 ** 1243 *******************************************************************************/ 1244 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb) 1245 { 1246 /* start notification cache timer */ 1247 alarm_set_on_queue(p_tcb->ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 1248 gatt_ind_ack_timeout, p_tcb, btu_general_alarm_queue); 1249 } 1250 1251 /******************************************************************************* 1252 ** 1253 ** Function gatt_rsp_timeout 1254 ** 1255 ** Description Called when GATT wait for ATT command response timer expires 1256 ** 1257 ** Returns void 1258 ** 1259 *******************************************************************************/ 1260 void gatt_rsp_timeout(void *data) 1261 { 1262 tGATT_CLCB *p_clcb = (tGATT_CLCB *)data; 1263 1264 if (p_clcb == NULL || p_clcb->p_tcb == NULL) 1265 { 1266 GATT_TRACE_WARNING("%s clcb is already deleted", __func__); 1267 return; 1268 } 1269 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && 1270 p_clcb->op_subtype == GATT_DISC_SRVC_ALL && 1271 p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) 1272 { 1273 UINT8 rsp_code; 1274 GATT_TRACE_WARNING("%s retry discovery primary service", __func__); 1275 if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code)) 1276 { 1277 GATT_TRACE_ERROR("%s command queue out of sync, disconnect", 1278 __func__); 1279 } 1280 else 1281 { 1282 p_clcb->retry_count++; 1283 gatt_act_discovery(p_clcb); 1284 return; 1285 } 1286 } 1287 1288 GATT_TRACE_WARNING("%s disconnecting...", __func__); 1289 gatt_disconnect (p_clcb->p_tcb); 1290 } 1291 1292 /******************************************************************************* 1293 ** 1294 ** Function gatt_indication_confirmation_timeout 1295 ** 1296 ** Description Called when the indication confirmation timer expires 1297 ** 1298 ** Returns void 1299 ** 1300 *******************************************************************************/ 1301 void gatt_indication_confirmation_timeout(void *data) 1302 { 1303 tGATT_TCB *p_tcb = (tGATT_TCB *)data; 1304 1305 GATT_TRACE_WARNING("%s disconnecting...", __func__); 1306 gatt_disconnect(p_tcb); 1307 } 1308 1309 /******************************************************************************* 1310 ** 1311 ** Function gatt_ind_ack_timeout 1312 ** 1313 ** Description Called when GATT wait for ATT handle confirmation timeout 1314 ** 1315 ** Returns void 1316 ** 1317 *******************************************************************************/ 1318 void gatt_ind_ack_timeout(void *data) 1319 { 1320 tGATT_TCB *p_tcb = (tGATT_TCB *)data; 1321 1322 GATT_TRACE_WARNING("%s send ack now", __func__); 1323 1324 if (p_tcb != NULL) 1325 p_tcb->ind_count = 0; 1326 1327 attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL); 1328 } 1329 /******************************************************************************* 1330 ** 1331 ** Function gatt_sr_find_i_rcb_by_handle 1332 ** 1333 ** Description The function searches for a service that owns a specific handle. 1334 ** 1335 ** Returns GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice. 1336 ** 1337 *******************************************************************************/ 1338 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle) 1339 { 1340 UINT8 i_rcb = 0; 1341 1342 for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++) 1343 { 1344 if (gatt_cb.sr_reg[i_rcb].in_use && 1345 gatt_cb.sr_reg[i_rcb].s_hdl <= handle && 1346 gatt_cb.sr_reg[i_rcb].e_hdl >= handle ) 1347 { 1348 break; 1349 } 1350 } 1351 return i_rcb; 1352 } 1353 1354 /******************************************************************************* 1355 ** 1356 ** Function gatt_sr_find_i_rcb_by_handle 1357 ** 1358 ** Description The function searches for a service that owns a specific handle. 1359 ** 1360 ** Returns 0 if not found. Otherwise index of th eservice. 1361 ** 1362 *******************************************************************************/ 1363 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst) 1364 { 1365 UINT8 i_rcb = 0; 1366 tGATT_SR_REG *p_sreg; 1367 tBT_UUID *p_this_uuid; 1368 1369 for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++) 1370 { 1371 if ( p_sreg->in_use ) 1372 { 1373 p_this_uuid = gatts_get_service_uuid (p_sreg->p_db); 1374 1375 if (p_this_uuid && 1376 gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) && 1377 gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) && 1378 (svc_inst == p_sreg->service_instance)) 1379 { 1380 GATT_TRACE_ERROR ("Active Service Found "); 1381 gatt_dbg_display_uuid(*p_svc_uuid); 1382 1383 break; 1384 } 1385 } 1386 } 1387 return i_rcb; 1388 } 1389 /******************************************************************************* 1390 ** 1391 ** Function gatt_sr_find_i_rcb_by_handle 1392 ** 1393 ** Description The function searches for a service that owns a specific handle. 1394 ** 1395 ** Returns 0 if not found. Otherwise index of th eservice. 1396 ** 1397 *******************************************************************************/ 1398 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list ) 1399 { 1400 UINT8 ii = 0; 1401 tGATT_SR_REG *p_sreg = NULL; 1402 1403 /*this is a new application servoce start */ 1404 for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++) 1405 { 1406 if (!p_sreg->in_use) 1407 { 1408 memset (p_sreg, 0, sizeof(tGATT_SR_REG)); 1409 1410 p_sreg->in_use = TRUE; 1411 memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID)); 1412 1413 p_sreg->service_instance = p_list->asgn_range.svc_inst; 1414 p_sreg->type = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE; 1415 p_sreg->s_hdl = p_list->asgn_range.s_handle; 1416 p_sreg->e_hdl = p_list->asgn_range.e_handle; 1417 p_sreg->p_db = &p_list->svc_db; 1418 1419 GATT_TRACE_DEBUG("total buffer in db [%d]", 1420 fixed_queue_length(p_sreg->p_db->svc_buffer)); 1421 break; 1422 } 1423 } 1424 1425 return ii; 1426 } 1427 /******************************************************************************* 1428 ** 1429 ** Function gatt_sr_get_sec_info 1430 ** 1431 ** Description Get the security flag and key size information for the peer 1432 ** device. 1433 ** 1434 ** Returns void 1435 ** 1436 *******************************************************************************/ 1437 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size) 1438 { 1439 UINT8 sec_flag = 0; 1440 1441 BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport); 1442 1443 sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED); 1444 1445 *p_key_size = btm_ble_read_sec_key_size(rem_bda); 1446 *p_sec_flag = sec_flag; 1447 } 1448 /******************************************************************************* 1449 ** 1450 ** Function gatt_sr_send_req_callback 1451 ** 1452 ** Description 1453 ** 1454 ** 1455 ** Returns void 1456 ** 1457 *******************************************************************************/ 1458 void gatt_sr_send_req_callback(UINT16 conn_id, 1459 UINT32 trans_id, 1460 tGATTS_REQ_TYPE type, tGATTS_DATA *p_data) 1461 { 1462 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 1463 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 1464 1465 if (!p_reg ) 1466 { 1467 GATT_TRACE_ERROR ("p_reg not found discard request"); 1468 return; 1469 } 1470 1471 if ( p_reg->in_use && 1472 p_reg->app_cb.p_req_cb) 1473 { 1474 (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data); 1475 } 1476 else 1477 { 1478 GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id); 1479 } 1480 1481 } 1482 1483 /******************************************************************************* 1484 ** 1485 ** Function gatt_send_error_rsp 1486 ** 1487 ** Description This function sends an error response. 1488 ** 1489 ** Returns void 1490 ** 1491 *******************************************************************************/ 1492 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code, 1493 UINT16 handle, BOOLEAN deq) 1494 { 1495 tGATT_ERROR error; 1496 tGATT_STATUS status; 1497 BT_HDR *p_buf; 1498 1499 error.cmd_code = op_code; 1500 error.reason = err_code; 1501 error.handle =handle; 1502 1503 if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL) 1504 { 1505 status = attp_send_sr_msg (p_tcb, p_buf); 1506 } 1507 else 1508 status = GATT_INSUF_RESOURCE; 1509 1510 if (deq) 1511 gatt_dequeue_sr_cmd(p_tcb); 1512 1513 return status; 1514 } 1515 1516 1517 /******************************************************************************* 1518 ** 1519 ** Function gatt_add_sdp_record 1520 ** 1521 ** Description This function add a SDP record for a GATT primary service 1522 ** 1523 ** Returns 0 if error else sdp handle for the record. 1524 ** 1525 *******************************************************************************/ 1526 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) 1527 { 1528 tSDP_PROTOCOL_ELEM proto_elem_list[2]; 1529 UINT32 sdp_handle; 1530 UINT16 list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; 1531 UINT8 buff[60]; 1532 UINT8 *p = buff; 1533 1534 GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x s_hdl=0x%x",start_hdl, end_hdl); 1535 1536 if ((sdp_handle = SDP_CreateRecord()) == 0) 1537 return 0; 1538 1539 switch (p_uuid->len) 1540 { 1541 case LEN_UUID_16: 1542 SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16); 1543 break; 1544 1545 case LEN_UUID_32: 1546 UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); 1547 UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32); 1548 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, 1549 (UINT32) (p - buff), buff); 1550 break; 1551 1552 case LEN_UUID_128: 1553 UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); 1554 ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128); 1555 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, 1556 (UINT32) (p - buff), buff); 1557 break; 1558 1559 default: 1560 GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len); 1561 SDP_DeleteRecord(sdp_handle); 1562 return 0; 1563 break; 1564 } 1565 1566 /*** Fill out the protocol element sequence for SDP ***/ 1567 proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP; 1568 proto_elem_list[0].num_params = 1; 1569 proto_elem_list[0].params[0] = BT_PSM_ATT; 1570 proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT; 1571 proto_elem_list[1].num_params = 2; 1572 proto_elem_list[1].params[0] = start_hdl; 1573 proto_elem_list[1].params[1] = end_hdl; 1574 1575 SDP_AddProtocolList(sdp_handle, 2, proto_elem_list); 1576 1577 /* Make the service browseable */ 1578 SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list); 1579 1580 return(sdp_handle); 1581 } 1582 1583 1584 #if GATT_CONFORMANCE_TESTING == TRUE 1585 /******************************************************************************* 1586 ** 1587 ** Function gatt_set_err_rsp 1588 ** 1589 ** Description This function is called to set the test confirm value 1590 ** 1591 ** Returns void 1592 ** 1593 *******************************************************************************/ 1594 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status) 1595 { 1596 GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status); 1597 gatt_cb.enable_err_rsp = enable; 1598 gatt_cb.req_op_code = req_op_code; 1599 gatt_cb.err_status = err_status; 1600 } 1601 #endif 1602 1603 1604 1605 /******************************************************************************* 1606 ** 1607 ** Function gatt_get_regcb 1608 ** 1609 ** Description The function returns the registration control block. 1610 ** 1611 ** Returns pointer to the registration control block or NULL 1612 ** 1613 *******************************************************************************/ 1614 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if) 1615 { 1616 UINT8 ii = (UINT8)gatt_if; 1617 tGATT_REG *p_reg = NULL; 1618 1619 if (ii < 1 || ii > GATT_MAX_APPS) { 1620 GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii); 1621 return NULL; 1622 } 1623 1624 // Index for cl_rcb is always 1 less than gatt_if. 1625 p_reg = &gatt_cb.cl_rcb[ii - 1]; 1626 1627 if (!p_reg->in_use) { 1628 GATT_TRACE_WARNING("gatt_if found but not in use."); 1629 return NULL; 1630 } 1631 1632 return p_reg; 1633 } 1634 1635 1636 /******************************************************************************* 1637 ** 1638 ** Function gatt_is_clcb_allocated 1639 ** 1640 ** Description The function check clcb for conn_id is allocated or not 1641 ** 1642 ** Returns True already allocated 1643 ** 1644 *******************************************************************************/ 1645 1646 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id) 1647 { 1648 UINT8 i = 0; 1649 BOOLEAN is_allocated= FALSE; 1650 1651 for (i = 0; i < GATT_CL_MAX_LCB; i++) 1652 { 1653 if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id)) 1654 { 1655 is_allocated = TRUE; 1656 break; 1657 } 1658 } 1659 1660 return is_allocated; 1661 } 1662 1663 /******************************************************************************* 1664 ** 1665 ** Function gatt_clcb_alloc 1666 ** 1667 ** Description The function allocates a GATT connection link control block 1668 ** 1669 ** Returns NULL if not found. Otherwise pointer to the connection link block. 1670 ** 1671 *******************************************************************************/ 1672 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id) 1673 { 1674 UINT8 i = 0; 1675 tGATT_CLCB *p_clcb = NULL; 1676 tGATT_IF gatt_if=GATT_GET_GATT_IF(conn_id); 1677 UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); 1678 tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx); 1679 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 1680 1681 for (i = 0; i < GATT_CL_MAX_LCB; i++) 1682 { 1683 if (!gatt_cb.clcb[i].in_use) 1684 { 1685 p_clcb = &gatt_cb.clcb[i]; 1686 1687 p_clcb->in_use = TRUE; 1688 p_clcb->conn_id = conn_id; 1689 p_clcb->clcb_idx = i; 1690 p_clcb->p_reg = p_reg; 1691 p_clcb->p_tcb = p_tcb; 1692 break; 1693 } 1694 } 1695 return p_clcb; 1696 } 1697 1698 /******************************************************************************* 1699 ** 1700 ** Function gatt_clcb_dealloc 1701 ** 1702 ** Description The function de allocates a GATT connection link control block 1703 ** 1704 ** Returns None 1705 ** 1706 *******************************************************************************/ 1707 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb) 1708 { 1709 if (p_clcb && p_clcb->in_use) 1710 { 1711 alarm_free(p_clcb->gatt_rsp_timer_ent); 1712 memset(p_clcb, 0, sizeof(tGATT_CLCB)); 1713 } 1714 } 1715 1716 1717 1718 /******************************************************************************* 1719 ** 1720 ** Function gatt_find_tcb_by_cid 1721 ** 1722 ** Description The function searches for an empty entry 1723 ** in registration info table for GATT client 1724 ** 1725 ** Returns NULL if not found. Otherwise pointer to the rcb. 1726 ** 1727 *******************************************************************************/ 1728 tGATT_TCB * gatt_find_tcb_by_cid (UINT16 lcid) 1729 { 1730 UINT16 xx = 0; 1731 tGATT_TCB *p_tcb = NULL; 1732 1733 for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++) 1734 { 1735 if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid) 1736 { 1737 p_tcb = &gatt_cb.tcb[xx]; 1738 break; 1739 } 1740 } 1741 return p_tcb; 1742 } 1743 1744 1745 /******************************************************************************* 1746 ** 1747 ** Function gatt_num_apps_hold_link 1748 ** 1749 ** Description The function find the number of applcaitions is holding the link 1750 ** 1751 ** Returns total number of applications holding this acl link. 1752 ** 1753 *******************************************************************************/ 1754 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb) 1755 { 1756 UINT8 i, num = 0; 1757 1758 for (i = 0; i < GATT_MAX_APPS; i ++) 1759 { 1760 if (p_tcb->app_hold_link[i]) 1761 num ++; 1762 } 1763 1764 GATT_TRACE_DEBUG("gatt_num_apps_hold_link num=%d", num); 1765 return num; 1766 } 1767 1768 1769 /******************************************************************************* 1770 ** 1771 ** Function gatt_num_clcb_by_bd_addr 1772 ** 1773 ** Description The function searches all LCB with macthing bd address 1774 ** 1775 ** Returns total number of clcb found. 1776 ** 1777 *******************************************************************************/ 1778 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda) 1779 { 1780 UINT8 i, num = 0; 1781 1782 for (i = 0; i < GATT_CL_MAX_LCB; i ++) 1783 { 1784 if (gatt_cb.clcb[i].in_use && memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0) 1785 num ++; 1786 } 1787 return num; 1788 } 1789 1790 /******************************************************************************* 1791 ** 1792 ** Function gatt_sr_update_cback_cnt 1793 ** 1794 ** Description The function searches all LCB with macthing bd address 1795 ** 1796 ** Returns total number of clcb found. 1797 ** 1798 *******************************************************************************/ 1799 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb ) 1800 { 1801 UINT8 i; 1802 1803 if (p_tcb) 1804 { 1805 for (i = 0; i < GATT_MAX_APPS; i ++) 1806 { 1807 if (p_tcb->prep_cnt[i]) 1808 { 1809 p_tcb->sr_cmd.cback_cnt[i]=1; 1810 } 1811 } 1812 } 1813 1814 } 1815 1816 /******************************************************************************* 1817 ** 1818 ** Function gatt_sr_is_cback_cnt_zero 1819 ** 1820 ** Description The function searches all LCB with macthing bd address 1821 ** 1822 ** Returns True if thetotal application callback count is zero 1823 ** 1824 *******************************************************************************/ 1825 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb ) 1826 { 1827 BOOLEAN status = TRUE; 1828 UINT8 i; 1829 1830 if (p_tcb) 1831 { 1832 for (i = 0; i < GATT_MAX_APPS; i ++) 1833 { 1834 if (p_tcb->sr_cmd.cback_cnt[i]) 1835 { 1836 status = FALSE; 1837 break; 1838 } 1839 } 1840 } 1841 else 1842 { 1843 status = FALSE; 1844 } 1845 return status; 1846 } 1847 1848 /******************************************************************************* 1849 ** 1850 ** Function gatt_sr_is_prep_cnt_zero 1851 ** 1852 ** Description Check the prepare write request count is zero or not 1853 ** 1854 ** Returns True no prepare write request 1855 ** 1856 *******************************************************************************/ 1857 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb) 1858 { 1859 BOOLEAN status = TRUE; 1860 UINT8 i; 1861 1862 if (p_tcb) 1863 { 1864 for (i = 0; i < GATT_MAX_APPS; i ++) 1865 { 1866 if (p_tcb->prep_cnt[i]) 1867 { 1868 status = FALSE; 1869 break; 1870 } 1871 } 1872 } 1873 else 1874 { 1875 status = FALSE; 1876 } 1877 return status; 1878 } 1879 1880 1881 /******************************************************************************* 1882 ** 1883 ** Function gatt_sr_reset_cback_cnt 1884 ** 1885 ** Description Reset the application callback count to zero 1886 ** 1887 ** Returns None 1888 ** 1889 *******************************************************************************/ 1890 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb ) 1891 { 1892 UINT8 i; 1893 1894 if (p_tcb) 1895 { 1896 for (i = 0; i < GATT_MAX_APPS; i ++) 1897 { 1898 p_tcb->sr_cmd.cback_cnt[i]=0; 1899 } 1900 } 1901 } 1902 1903 /******************************************************************************* 1904 ** 1905 ** Function gatt_sr_reset_prep_cnt 1906 ** 1907 ** Description Reset the prep write count to zero 1908 ** 1909 ** Returns None 1910 ** 1911 *******************************************************************************/ 1912 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb ) 1913 { 1914 UINT8 i; 1915 if (p_tcb) 1916 { 1917 for (i = 0; i < GATT_MAX_APPS; i ++) 1918 { 1919 p_tcb->prep_cnt[i]=0; 1920 } 1921 } 1922 } 1923 1924 1925 /******************************************************************************* 1926 ** 1927 ** Function gatt_sr_update_cback_cnt 1928 ** 1929 ** Description Update the teh applicaiton callback count 1930 ** 1931 ** Returns None 1932 ** 1933 *******************************************************************************/ 1934 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first) 1935 { 1936 1937 UINT8 idx = ((UINT8) gatt_if) - 1 ; 1938 1939 if (p_tcb) 1940 { 1941 if (is_reset_first) 1942 { 1943 gatt_sr_reset_cback_cnt(p_tcb); 1944 } 1945 if (is_inc) 1946 { 1947 p_tcb->sr_cmd.cback_cnt[idx]++; 1948 } 1949 else 1950 { 1951 if ( p_tcb->sr_cmd.cback_cnt[idx]) 1952 { 1953 p_tcb->sr_cmd.cback_cnt[idx]--; 1954 } 1955 } 1956 } 1957 } 1958 1959 1960 /******************************************************************************* 1961 ** 1962 ** Function gatt_sr_update_prep_cnt 1963 ** 1964 ** Description Update the teh prepare write request count 1965 ** 1966 ** Returns None 1967 ** 1968 *******************************************************************************/ 1969 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first) 1970 { 1971 UINT8 idx = ((UINT8) gatt_if) - 1 ; 1972 1973 GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d", 1974 p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first); 1975 1976 if (p_tcb) 1977 { 1978 if (is_reset_first) 1979 { 1980 gatt_sr_reset_prep_cnt(p_tcb); 1981 } 1982 if (is_inc) 1983 { 1984 p_tcb->prep_cnt[idx]++; 1985 } 1986 else 1987 { 1988 if (p_tcb->prep_cnt[idx]) 1989 { 1990 p_tcb->prep_cnt[idx]--; 1991 } 1992 } 1993 } 1994 } 1995 /******************************************************************************* 1996 ** 1997 ** Function gatt_cancel_open 1998 ** 1999 ** Description Cancel open request 2000 ** 2001 ** Returns Boolean 2002 ** 2003 *******************************************************************************/ 2004 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) 2005 { 2006 tGATT_TCB *p_tcb=NULL; 2007 BOOLEAN status= TRUE; 2008 2009 p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE); 2010 2011 if (p_tcb) 2012 { 2013 if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) 2014 { 2015 GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel"); 2016 status = FALSE; 2017 } 2018 else 2019 { 2020 gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); 2021 if (!gatt_num_apps_hold_link(p_tcb)) 2022 { 2023 gatt_disconnect(p_tcb); 2024 } 2025 } 2026 } 2027 2028 return status; 2029 } 2030 2031 /******************************************************************************* 2032 ** 2033 ** Function gatt_find_app_hold_link 2034 ** 2035 ** Description find the applicaiton that is holding the specified link 2036 ** 2037 ** Returns Boolean 2038 ** 2039 *******************************************************************************/ 2040 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if) 2041 { 2042 UINT8 i; 2043 BOOLEAN found= FALSE; 2044 2045 for (i = start_idx; i < GATT_MAX_APPS; i ++) 2046 { 2047 if (p_tcb->app_hold_link[i]) 2048 { 2049 *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if; 2050 *p_found_idx = i; 2051 found = TRUE; 2052 break; 2053 } 2054 } 2055 return found; 2056 } 2057 2058 /******************************************************************************* 2059 ** 2060 ** Function gatt_cmd_enq 2061 ** 2062 ** Description Enqueue this command. 2063 ** 2064 ** Returns None. 2065 ** 2066 *******************************************************************************/ 2067 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf) 2068 { 2069 tGATT_CMD_Q *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq]; 2070 2071 p_cmd->to_send = to_send; /* waiting to be sent */ 2072 p_cmd->op_code = op_code; 2073 p_cmd->p_cmd = p_buf; 2074 p_cmd->clcb_idx = clcb_idx; 2075 2076 if (!to_send) 2077 { 2078 p_tcb->pending_cl_req = p_tcb->next_slot_inq; 2079 } 2080 2081 p_tcb->next_slot_inq ++; 2082 p_tcb->next_slot_inq %= GATT_CL_MAX_LCB; 2083 2084 return TRUE; 2085 } 2086 2087 /******************************************************************************* 2088 ** 2089 ** Function gatt_cmd_dequeue 2090 ** 2091 ** Description dequeue the command in the client CCB command queue. 2092 ** 2093 ** Returns total number of clcb found. 2094 ** 2095 *******************************************************************************/ 2096 tGATT_CLCB * gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code) 2097 { 2098 tGATT_CMD_Q *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req]; 2099 tGATT_CLCB *p_clcb = NULL; 2100 2101 if (p_tcb->pending_cl_req != p_tcb->next_slot_inq) 2102 { 2103 p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx]; 2104 2105 *p_op_code = p_cmd->op_code; 2106 2107 p_tcb->pending_cl_req ++; 2108 p_tcb->pending_cl_req %= GATT_CL_MAX_LCB; 2109 } 2110 2111 return p_clcb; 2112 } 2113 2114 /******************************************************************************* 2115 ** 2116 ** Function gatt_send_write_msg 2117 ** 2118 ** Description This real function send out the ATT message for write. 2119 ** 2120 ** Returns status code 2121 ** 2122 *******************************************************************************/ 2123 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, 2124 UINT16 handle, UINT16 len, 2125 UINT16 offset, UINT8 *p_data) 2126 { 2127 tGATT_CL_MSG msg; 2128 2129 msg.attr_value.handle = handle; 2130 msg.attr_value.len = len; 2131 msg.attr_value.offset = offset; 2132 2133 memcpy (msg.attr_value.value, p_data, len); 2134 2135 /* write by handle */ 2136 return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg); 2137 } 2138 2139 /******************************************************************************* 2140 ** 2141 ** Function gatt_act_send_browse 2142 ** 2143 ** Description This function ends a browse command request, including read 2144 ** information request and read by type request. 2145 ** 2146 ** Returns status code 2147 ** 2148 *******************************************************************************/ 2149 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle, 2150 UINT16 e_handle, tBT_UUID uuid) 2151 { 2152 tGATT_CL_MSG msg; 2153 2154 msg.browse.s_handle = s_handle; 2155 msg.browse.e_handle = e_handle; 2156 memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID)); 2157 2158 /* write by handle */ 2159 return attp_send_cl_msg(p_tcb, index, op, &msg); 2160 } 2161 2162 /******************************************************************************* 2163 ** 2164 ** Function gatt_end_operation 2165 ** 2166 ** Description This function ends a discovery, send callback and finalize 2167 ** some control value. 2168 ** 2169 ** Returns 16 bits uuid. 2170 ** 2171 *******************************************************************************/ 2172 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data) 2173 { 2174 tGATT_CL_COMPLETE cb_data; 2175 tGATT_CMPL_CBACK *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL; 2176 UINT8 op = p_clcb->operation, disc_type=GATT_DISC_MAX; 2177 tGATT_DISC_CMPL_CB *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL; 2178 UINT16 conn_id; 2179 UINT8 operation; 2180 2181 GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d", 2182 status, p_clcb->operation, p_clcb->op_subtype); 2183 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); 2184 2185 if (p_cmpl_cb != NULL && p_clcb->operation != 0) 2186 { 2187 if (p_clcb->operation == GATTC_OPTYPE_READ) 2188 { 2189 cb_data.att_value.handle = p_clcb->s_handle; 2190 cb_data.att_value.len = p_clcb->counter; 2191 2192 if (p_data && p_clcb->counter) 2193 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len); 2194 } 2195 2196 if (p_clcb->operation == GATTC_OPTYPE_WRITE) 2197 { 2198 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); 2199 cb_data.handle = 2200 cb_data.att_value.handle = p_clcb->s_handle; 2201 if (p_clcb->op_subtype == GATT_WRITE_PREPARE) 2202 { 2203 if (p_data) 2204 { 2205 cb_data.att_value = *((tGATT_VALUE *) p_data); 2206 } 2207 else 2208 { 2209 GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data"); 2210 } 2211 } 2212 } 2213 2214 if (p_clcb->operation == GATTC_OPTYPE_CONFIG) 2215 cb_data.mtu = p_clcb->p_tcb->payload_size; 2216 2217 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) 2218 { 2219 disc_type = p_clcb->op_subtype; 2220 } 2221 } 2222 2223 osi_free_and_reset((void **)&p_clcb->p_attr_buf); 2224 2225 operation = p_clcb->operation; 2226 conn_id = p_clcb->conn_id; 2227 alarm_cancel(p_clcb->gatt_rsp_timer_ent); 2228 2229 gatt_clcb_dealloc(p_clcb); 2230 2231 if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY)) 2232 (*p_disc_cmpl_cb)(conn_id, disc_type, status); 2233 else if (p_cmpl_cb && op) 2234 (*p_cmpl_cb)(conn_id, op, status, &cb_data); 2235 else 2236 GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p", 2237 operation, p_disc_cmpl_cb, p_cmpl_cb); 2238 } 2239 2240 /******************************************************************************* 2241 ** 2242 ** Function gatt_cleanup_upon_disc 2243 ** 2244 ** Description This function cleans up the control blocks when L2CAP channel 2245 ** disconnect. 2246 ** 2247 ** Returns 16 bits uuid. 2248 ** 2249 *******************************************************************************/ 2250 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) 2251 { 2252 tGATT_TCB *p_tcb = NULL; 2253 tGATT_CLCB *p_clcb; 2254 UINT8 i; 2255 UINT16 conn_id; 2256 tGATT_REG *p_reg=NULL; 2257 2258 2259 GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc "); 2260 2261 if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) 2262 { 2263 GATT_TRACE_DEBUG ("found p_tcb "); 2264 gatt_set_ch_state(p_tcb, GATT_CH_CLOSE); 2265 for (i = 0; i < GATT_CL_MAX_LCB; i ++) 2266 { 2267 p_clcb = &gatt_cb.clcb[i]; 2268 if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) 2269 { 2270 alarm_cancel(p_clcb->gatt_rsp_timer_ent); 2271 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx); 2272 if (p_clcb->operation != GATTC_OPTYPE_NONE) 2273 gatt_end_operation(p_clcb, GATT_ERROR, NULL); 2274 2275 gatt_clcb_dealloc(p_clcb); 2276 2277 } 2278 } 2279 2280 alarm_free(p_tcb->ind_ack_timer); 2281 p_tcb->ind_ack_timer = NULL; 2282 alarm_free(p_tcb->conf_timer); 2283 p_tcb->conf_timer = NULL; 2284 gatt_free_pending_ind(p_tcb); 2285 gatt_free_pending_enc_queue(p_tcb); 2286 fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL); 2287 p_tcb->sr_cmd.multi_rsp_q = NULL; 2288 2289 for (i = 0; i < GATT_MAX_APPS; i ++) 2290 { 2291 p_reg = &gatt_cb.cl_rcb[i]; 2292 if (p_reg->in_use && p_reg->app_cb.p_conn_cb) 2293 { 2294 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); 2295 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); 2296 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason, transport); 2297 } 2298 } 2299 memset(p_tcb, 0, sizeof(tGATT_TCB)); 2300 2301 } 2302 GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc "); 2303 } 2304 /******************************************************************************* 2305 ** 2306 ** Function gatt_dbg_req_op_name 2307 ** 2308 ** Description Get op code description name, for debug information. 2309 ** 2310 ** Returns UINT8 *: name of the operation. 2311 ** 2312 *******************************************************************************/ 2313 UINT8 * gatt_dbg_op_name(UINT8 op_code) 2314 { 2315 UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK); 2316 2317 if (op_code == GATT_CMD_WRITE ) 2318 { 2319 pseduo_op_code_idx = 0x14; /* just an index to op_code_name */ 2320 2321 } 2322 2323 if (op_code == GATT_SIGN_CMD_WRITE) 2324 { 2325 pseduo_op_code_idx = 0x15; /* just an index to op_code_name */ 2326 } 2327 2328 if (pseduo_op_code_idx <= GATT_OP_CODE_MAX) 2329 return(UINT8*) op_code_name[pseduo_op_code_idx]; 2330 else 2331 return(UINT8 *)"Op Code Exceed Max"; 2332 } 2333 2334 /******************************************************************************* 2335 ** 2336 ** Function gatt_dbg_display_uuid 2337 ** 2338 ** Description Disaplay the UUID 2339 ** 2340 ** Returns None 2341 ** 2342 *******************************************************************************/ 2343 void gatt_dbg_display_uuid(tBT_UUID bt_uuid) 2344 { 2345 char str_buf[50]; 2346 int x = 0; 2347 2348 if (bt_uuid.len == LEN_UUID_16) 2349 { 2350 sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16); 2351 } 2352 else if (bt_uuid.len == LEN_UUID_32) 2353 { 2354 sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32); 2355 } 2356 else if (bt_uuid.len == LEN_UUID_128) 2357 { 2358 x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x", 2359 bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14], 2360 bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12], 2361 bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10], 2362 bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]); 2363 sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x", 2364 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6], 2365 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4], 2366 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2], 2367 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]); 2368 } 2369 else 2370 strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf)); 2371 2372 GATT_TRACE_DEBUG ("UUID=[%s]", str_buf); 2373 } 2374 2375 2376 /******************************************************************************* 2377 ** 2378 ** Function gatt_is_bg_dev_for_app 2379 ** 2380 ** Description find is this one of the background devices for the application 2381 ** 2382 ** Returns TRUE this is one of the background devices for the application 2383 ** 2384 *******************************************************************************/ 2385 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if) 2386 { 2387 UINT8 i; 2388 2389 for (i = 0; i < GATT_MAX_APPS; i ++ ) 2390 { 2391 if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if)) 2392 { 2393 return TRUE; 2394 } 2395 } 2396 return FALSE; 2397 } 2398 /******************************************************************************* 2399 ** 2400 ** Function gatt_find_bg_dev 2401 ** 2402 ** Description find background connection device from the list. 2403 ** 2404 ** Returns pointer to the device record 2405 ** 2406 *******************************************************************************/ 2407 tGATT_BG_CONN_DEV * gatt_find_bg_dev(BD_ADDR remote_bda) 2408 { 2409 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2410 UINT8 i; 2411 2412 for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) 2413 { 2414 if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN)) 2415 { 2416 return p_dev_list; 2417 } 2418 } 2419 return NULL; 2420 } 2421 /******************************************************************************* 2422 ** 2423 ** Function gatt_alloc_bg_dev 2424 ** 2425 ** Description allocate a background connection device record 2426 ** 2427 ** Returns pointer to the device record 2428 ** 2429 *******************************************************************************/ 2430 tGATT_BG_CONN_DEV * gatt_alloc_bg_dev(BD_ADDR remote_bda) 2431 { 2432 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2433 UINT8 i; 2434 2435 for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) 2436 { 2437 if (!p_dev_list->in_use) 2438 { 2439 p_dev_list->in_use = TRUE; 2440 memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN); 2441 2442 return p_dev_list; 2443 } 2444 } 2445 return NULL; 2446 } 2447 2448 /******************************************************************************* 2449 ** 2450 ** Function gatt_add_bg_dev_list 2451 ** 2452 ** Description add/remove device from the back ground connection device list 2453 ** 2454 ** Returns TRUE if device added to the list; FALSE failed 2455 ** 2456 *******************************************************************************/ 2457 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initator) 2458 { 2459 tGATT_IF gatt_if = p_reg->gatt_if; 2460 tGATT_BG_CONN_DEV *p_dev = NULL; 2461 UINT8 i; 2462 BOOLEAN ret = FALSE; 2463 2464 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2465 { 2466 p_dev = gatt_alloc_bg_dev(bd_addr); 2467 } 2468 2469 if (p_dev) 2470 { 2471 for (i = 0; i < GATT_MAX_APPS; i ++) 2472 { 2473 if (is_initator) 2474 { 2475 if (p_dev->gatt_if[i] == gatt_if) 2476 { 2477 GATT_TRACE_ERROR("device already in iniator white list"); 2478 return TRUE; 2479 } 2480 else if (p_dev->gatt_if[i] == 0) 2481 { 2482 p_dev->gatt_if[i] = gatt_if; 2483 if (i == 0) 2484 ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr); 2485 else 2486 ret = TRUE; 2487 break; 2488 } 2489 } 2490 else 2491 { 2492 if (p_dev->listen_gif[i] == gatt_if) 2493 { 2494 GATT_TRACE_ERROR("device already in adv white list"); 2495 return TRUE; 2496 } 2497 else if (p_dev->listen_gif[i] == 0) 2498 { 2499 if (p_reg->listening == GATT_LISTEN_TO_ALL) 2500 p_reg->listening = GATT_LISTEN_TO_NONE; 2501 2502 p_reg->listening ++; 2503 p_dev->listen_gif[i] = gatt_if; 2504 2505 if (i == 0) 2506 ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr); 2507 else 2508 ret = TRUE; 2509 break; 2510 } 2511 } 2512 } 2513 } 2514 else 2515 { 2516 GATT_TRACE_ERROR("no device record available"); 2517 } 2518 2519 return ret; 2520 } 2521 2522 /******************************************************************************* 2523 ** 2524 ** Function gatt_remove_bg_dev_for_app 2525 ** 2526 ** Description Remove the application interface for the specified background device 2527 ** 2528 ** Returns Boolean 2529 ** 2530 *******************************************************************************/ 2531 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) 2532 { 2533 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 2534 BOOLEAN status; 2535 2536 if (p_tcb) 2537 gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); 2538 status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE); 2539 return status; 2540 } 2541 2542 2543 /******************************************************************************* 2544 ** 2545 ** Function gatt_get_num_apps_for_bg_dev 2546 ** 2547 ** Description Gte the number of applciations for the specified background device 2548 ** 2549 ** Returns UINT8 total number fo applications 2550 ** 2551 *******************************************************************************/ 2552 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr) 2553 { 2554 tGATT_BG_CONN_DEV *p_dev = NULL; 2555 UINT8 i; 2556 UINT8 cnt = 0; 2557 2558 if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL) 2559 { 2560 for (i = 0; i < GATT_MAX_APPS; i ++) 2561 { 2562 if (p_dev->gatt_if[i]) 2563 cnt++; 2564 } 2565 } 2566 return cnt; 2567 } 2568 2569 /******************************************************************************* 2570 ** 2571 ** Function gatt_find_app_for_bg_dev 2572 ** 2573 ** Description find the application interface for the specified background device 2574 ** 2575 ** Returns Boolean 2576 ** 2577 *******************************************************************************/ 2578 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if) 2579 { 2580 tGATT_BG_CONN_DEV *p_dev = NULL; 2581 UINT8 i; 2582 BOOLEAN ret = FALSE; 2583 2584 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2585 { 2586 return ret; 2587 } 2588 2589 for (i = 0; i < GATT_MAX_APPS; i ++) 2590 { 2591 if (p_dev->gatt_if[i] != 0 ) 2592 { 2593 *p_gatt_if = p_dev->gatt_if[i]; 2594 ret = TRUE; 2595 break; 2596 } 2597 } 2598 return ret; 2599 } 2600 2601 2602 /******************************************************************************* 2603 ** 2604 ** Function gatt_remove_bg_dev_from_list 2605 ** 2606 ** Description add/remove device from the back ground connection device list or 2607 ** listening to advertising list. 2608 ** 2609 ** Returns pointer to the device record 2610 ** 2611 *******************************************************************************/ 2612 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator) 2613 { 2614 tGATT_IF gatt_if = p_reg->gatt_if; 2615 tGATT_BG_CONN_DEV *p_dev = NULL; 2616 UINT8 i, j; 2617 BOOLEAN ret = FALSE; 2618 2619 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2620 { 2621 return ret; 2622 } 2623 2624 for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++) 2625 { 2626 if (is_initiator) 2627 { 2628 if (p_dev->gatt_if[i] == gatt_if) 2629 { 2630 p_dev->gatt_if[i] = 0; 2631 /* move all element behind one forward */ 2632 for (j = i + 1; j < GATT_MAX_APPS; j ++) 2633 p_dev->gatt_if[j - 1] = p_dev->gatt_if[j]; 2634 2635 if (p_dev->gatt_if[0] == 0) 2636 ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda); 2637 else 2638 ret = TRUE; 2639 2640 break; 2641 } 2642 } 2643 else 2644 { 2645 if (p_dev->listen_gif[i] == gatt_if) 2646 { 2647 p_dev->listen_gif[i] = 0; 2648 p_reg->listening --; 2649 /* move all element behind one forward */ 2650 for (j = i + 1; j < GATT_MAX_APPS; j ++) 2651 p_dev->listen_gif[j - 1] = p_dev->listen_gif[j]; 2652 2653 if (p_dev->listen_gif[0] == 0) 2654 ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda); 2655 else 2656 ret = TRUE; 2657 break; 2658 } 2659 } 2660 } 2661 2662 if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0) 2663 { 2664 memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV)); 2665 } 2666 2667 return ret; 2668 } 2669 /******************************************************************************* 2670 ** 2671 ** Function gatt_deregister_bgdev_list 2672 ** 2673 ** Description deregister all related back ground connetion device. 2674 ** 2675 ** Returns pointer to the device record 2676 ** 2677 *******************************************************************************/ 2678 void gatt_deregister_bgdev_list(tGATT_IF gatt_if) 2679 { 2680 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2681 UINT8 i , j, k; 2682 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 2683 2684 /* update the BG conn device list */ 2685 for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ ) 2686 { 2687 if (p_dev_list->in_use) 2688 { 2689 for (j = 0; j < GATT_MAX_APPS; j ++) 2690 { 2691 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0) 2692 break; 2693 2694 if (p_dev_list->gatt_if[j] == gatt_if) 2695 { 2696 for (k = j + 1; k < GATT_MAX_APPS; k ++) 2697 p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k]; 2698 2699 if (p_dev_list->gatt_if[0] == 0) 2700 BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda); 2701 } 2702 2703 if (p_dev_list->listen_gif[j] == gatt_if) 2704 { 2705 p_dev_list->listen_gif[j] = 0; 2706 2707 if (p_reg != NULL && p_reg->listening > 0) 2708 p_reg->listening --; 2709 2710 /* move all element behind one forward */ 2711 for (k = j + 1; k < GATT_MAX_APPS; k ++) 2712 p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k]; 2713 2714 if (p_dev_list->listen_gif[0] == 0) 2715 BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda); 2716 } 2717 } 2718 } 2719 } 2720 } 2721 2722 2723 /******************************************************************************* 2724 ** 2725 ** Function gatt_reset_bgdev_list 2726 ** 2727 ** Description reset bg device list 2728 ** 2729 ** Returns pointer to the device record 2730 ** 2731 *******************************************************************************/ 2732 void gatt_reset_bgdev_list(void) 2733 { 2734 memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV); 2735 2736 } 2737 /******************************************************************************* 2738 ** 2739 ** Function gatt_update_auto_connect_dev 2740 ** 2741 ** Description This function add or remove a device for background connection 2742 ** procedure. 2743 ** 2744 ** Parameters gatt_if: Application ID. 2745 ** add: add peer device 2746 ** bd_addr: peer device address. 2747 ** 2748 ** Returns TRUE if connection started; FALSE if connection start failure. 2749 ** 2750 *******************************************************************************/ 2751 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator) 2752 { 2753 BOOLEAN ret = FALSE; 2754 tGATT_REG *p_reg; 2755 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 2756 2757 GATT_TRACE_API ("gatt_update_auto_connect_dev "); 2758 /* Make sure app is registered */ 2759 if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) 2760 { 2761 GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if is not registered", gatt_if); 2762 return(FALSE); 2763 } 2764 2765 if (add) 2766 { 2767 ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator); 2768 2769 if (ret && p_tcb != NULL) 2770 { 2771 /* if a connected device, update the link holding number */ 2772 gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE); 2773 } 2774 } 2775 else 2776 { 2777 ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator); 2778 } 2779 return ret; 2780 } 2781 2782 2783 2784 /******************************************************************************* 2785 ** 2786 ** Function gatt_add_pending_new_srv_start 2787 ** 2788 ** Description Add a pending new srv start to the new service start queue 2789 ** 2790 ** Returns Pointer to the new service start buffer, NULL no buffer available 2791 ** 2792 *******************************************************************************/ 2793 tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb) 2794 { 2795 tGATT_PENDING_ENC_CLCB *p_buf = 2796 (tGATT_PENDING_ENC_CLCB *)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB)); 2797 2798 GATT_TRACE_DEBUG ("%s", __func__); 2799 GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb"); 2800 2801 p_buf->p_clcb = p_clcb; 2802 fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf); 2803 2804 return p_buf; 2805 } 2806 /******************************************************************************* 2807 ** 2808 ** Function gatt_update_listen_mode 2809 ** 2810 ** Description update peripheral role listening mode 2811 ** 2812 ** Returns Pointer to the new service start buffer, NULL no buffer available 2813 ** 2814 *******************************************************************************/ 2815 BOOLEAN gatt_update_listen_mode(void) 2816 { 2817 UINT8 ii = 0; 2818 tGATT_REG *p_reg = &gatt_cb.cl_rcb[0]; 2819 UINT8 listening = 0; 2820 UINT16 connectability, window, interval; 2821 BOOLEAN rt = TRUE; 2822 2823 for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) 2824 { 2825 if ( p_reg->in_use && p_reg->listening > listening) 2826 { 2827 listening = p_reg->listening; 2828 } 2829 } 2830 2831 if (listening == GATT_LISTEN_TO_ALL || 2832 listening == GATT_LISTEN_TO_NONE) 2833 BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL); 2834 else 2835 BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL); 2836 2837 if (rt) 2838 { 2839 connectability = BTM_ReadConnectability (&window, &interval); 2840 2841 if (listening != GATT_LISTEN_TO_NONE) 2842 { 2843 connectability |= BTM_BLE_CONNECTABLE; 2844 } 2845 else 2846 { 2847 if ((connectability & BTM_BLE_CONNECTABLE) == 0) 2848 connectability &= ~BTM_BLE_CONNECTABLE; 2849 } 2850 /* turning on the adv now */ 2851 btm_ble_set_connectability(connectability); 2852 } 2853 2854 return rt; 2855 2856 } 2857 #endif 2858 2859 2860