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