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 42const 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 78static 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*******************************************************************************/ 91void 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*******************************************************************************/ 108void 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*******************************************************************************/ 125void 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*******************************************************************************/ 153void 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*******************************************************************************/ 183tGATTS_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*******************************************************************************/ 214tGATT_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*******************************************************************************/ 237tGATTS_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*******************************************************************************/ 261tGATTS_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*******************************************************************************/ 285tGATT_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*******************************************************************************/ 313tGATT_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*******************************************************************************/ 339tGATT_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*******************************************************************************/ 370void 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*******************************************************************************/ 390void 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*******************************************************************************/ 416BOOLEAN 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*******************************************************************************/ 453void 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*******************************************************************************/ 478void 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*******************************************************************************/ 497BOOLEAN 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*******************************************************************************/ 563BOOLEAN 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*******************************************************************************/ 603BOOLEAN 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*******************************************************************************/ 667BOOLEAN 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*******************************************************************************/ 705BOOLEAN 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 && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) 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*******************************************************************************/ 739BOOLEAN 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*******************************************************************************/ 777tGATTS_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*******************************************************************************/ 807BOOLEAN 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*******************************************************************************/ 833UINT8 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*******************************************************************************/ 858tGATT_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*******************************************************************************/ 877tGATT_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*******************************************************************************/ 896UINT8 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*******************************************************************************/ 919tGATT_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*******************************************************************************/ 959void 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*******************************************************************************/ 977BOOLEAN 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*******************************************************************************/ 1025UINT8 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*******************************************************************************/ 1054BOOLEAN 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*******************************************************************************/ 1119void 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*******************************************************************************/ 1134void 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*******************************************************************************/ 1149void 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*******************************************************************************/ 1166void 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*******************************************************************************/ 1181void 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*******************************************************************************/ 1201UINT8 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*******************************************************************************/ 1226UINT8 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*******************************************************************************/ 1261UINT8 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*******************************************************************************/ 1299void 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*******************************************************************************/ 1320void 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*******************************************************************************/ 1354tGATT_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*******************************************************************************/ 1388UINT32 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*******************************************************************************/ 1448void 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*******************************************************************************/ 1468tGATT_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 1495BOOLEAN 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*******************************************************************************/ 1521tGATT_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*******************************************************************************/ 1556void 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*******************************************************************************/ 1576tGATT_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*******************************************************************************/ 1602UINT8 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*******************************************************************************/ 1626UINT8 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*******************************************************************************/ 1647void 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*******************************************************************************/ 1673BOOLEAN 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*******************************************************************************/ 1705BOOLEAN 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*******************************************************************************/ 1738void 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*******************************************************************************/ 1760void 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*******************************************************************************/ 1782void 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*******************************************************************************/ 1817void 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*******************************************************************************/ 1852BOOLEAN 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*******************************************************************************/ 1887BOOLEAN 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*******************************************************************************/ 1914BOOLEAN 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*******************************************************************************/ 1943tGATT_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*******************************************************************************/ 1970UINT8 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*******************************************************************************/ 1996UINT8 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*******************************************************************************/ 2019void 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*******************************************************************************/ 2098void 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*******************************************************************************/ 2156UINT8 * 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*******************************************************************************/ 2186void 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*******************************************************************************/ 2225BOOLEAN 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*******************************************************************************/ 2247tGATT_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*******************************************************************************/ 2270tGATT_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*******************************************************************************/ 2297BOOLEAN 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 return TRUE; 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 else 2326 ret = TRUE; 2327 break; 2328 } 2329 } 2330 else 2331 { 2332 if (p_dev->listen_gif[i] == gatt_if) 2333 { 2334 GATT_TRACE_ERROR0("device already in adv white list"); 2335 return TRUE; 2336 } 2337 else if (p_dev->listen_gif[i] == 0) 2338 { 2339 if (p_reg->listening == GATT_LISTEN_TO_ALL) 2340 p_reg->listening = GATT_LISTEN_TO_NONE; 2341 2342 p_reg->listening ++; 2343 p_dev->listen_gif[i] = gatt_if; 2344 2345 if (i == 0) 2346 ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr); 2347 else 2348 ret = TRUE; 2349 break; 2350 } 2351 } 2352 } 2353 } 2354 else 2355 { 2356 GATT_TRACE_ERROR0("no device record available"); 2357 } 2358 2359 return ret; 2360} 2361 2362/******************************************************************************* 2363** 2364** Function gatt_remove_bg_dev_for_app 2365** 2366** Description Remove the application interface for the specified background device 2367** 2368** Returns Boolean 2369** 2370*******************************************************************************/ 2371BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) 2372{ 2373 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); 2374 BOOLEAN status; 2375 2376 if (p_tcb) 2377 gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); 2378 status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE); 2379 return status; 2380} 2381 2382 2383/******************************************************************************* 2384** 2385** Function gatt_get_num_apps_for_bg_dev 2386** 2387** Description Gte the number of applciations for the specified background device 2388** 2389** Returns UINT8 total number fo applications 2390** 2391*******************************************************************************/ 2392UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr) 2393{ 2394 tGATT_BG_CONN_DEV *p_dev = NULL; 2395 UINT8 i; 2396 UINT8 cnt = 0; 2397 2398 if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL) 2399 { 2400 for (i = 0; i < GATT_MAX_APPS; i ++) 2401 { 2402 if (p_dev->gatt_if[i]) 2403 cnt++; 2404 } 2405 } 2406 return cnt; 2407} 2408 2409/******************************************************************************* 2410** 2411** Function gatt_find_app_for_bg_dev 2412** 2413** Description find the application interface for the specified background device 2414** 2415** Returns Boolean 2416** 2417*******************************************************************************/ 2418BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if) 2419{ 2420 tGATT_BG_CONN_DEV *p_dev = NULL; 2421 UINT8 i; 2422 BOOLEAN ret = FALSE; 2423 2424 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2425 { 2426 return ret; 2427 } 2428 2429 for (i = 0; i < GATT_MAX_APPS; i ++) 2430 { 2431 if (p_dev->gatt_if[i] != 0 ) 2432 { 2433 *p_gatt_if = p_dev->gatt_if[i]; 2434 ret = TRUE; 2435 break; 2436 } 2437 } 2438 return ret; 2439} 2440 2441 2442/******************************************************************************* 2443** 2444** Function gatt_remove_bg_dev_from_list 2445** 2446** Description add/remove device from the back ground connection device list or 2447** listening to advertising list. 2448** 2449** Returns pointer to the device record 2450** 2451*******************************************************************************/ 2452BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator) 2453{ 2454 tGATT_IF gatt_if = p_reg->gatt_if; 2455 tGATT_BG_CONN_DEV *p_dev = NULL; 2456 UINT8 i, j; 2457 BOOLEAN ret = FALSE; 2458 2459 if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) 2460 { 2461 return ret; 2462 } 2463 2464 for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++) 2465 { 2466 if (is_initiator) 2467 { 2468 if (p_dev->gatt_if[i] == gatt_if) 2469 { 2470 p_dev->gatt_if[i] = 0; 2471 /* move all element behind one forward */ 2472 for (j = i + 1; j < GATT_MAX_APPS; j ++) 2473 p_dev->gatt_if[j - 1] = p_dev->gatt_if[j]; 2474 2475 if (p_dev->gatt_if[0] == 0) 2476 ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda); 2477 else 2478 ret = TRUE; 2479 2480 break; 2481 } 2482 } 2483 else 2484 { 2485 if (p_dev->listen_gif[i] == gatt_if) 2486 { 2487 p_dev->listen_gif[i] = 0; 2488 p_reg->listening --; 2489 /* move all element behind one forward */ 2490 for (j = i + 1; j < GATT_MAX_APPS; j ++) 2491 p_dev->listen_gif[j - 1] = p_dev->listen_gif[j]; 2492 2493 if (p_dev->listen_gif[0] == 0) 2494 ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda); 2495 else 2496 ret = TRUE; 2497 break; 2498 } 2499 } 2500 } 2501 2502 if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0) 2503 { 2504 memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV)); 2505 } 2506 2507 return ret; 2508} 2509/******************************************************************************* 2510** 2511** Function gatt_deregister_bgdev_list 2512** 2513** Description deregister all related back ground connetion device. 2514** 2515** Returns pointer to the device record 2516** 2517*******************************************************************************/ 2518void gatt_deregister_bgdev_list(tGATT_IF gatt_if) 2519{ 2520 tGATT_BG_CONN_DEV *p_dev_list = &gatt_cb.bgconn_dev[0]; 2521 UINT8 i , j, k; 2522 tGATT_REG *p_reg = gatt_get_regcb(gatt_if); 2523 2524 /* update the BG conn device list */ 2525 for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ ) 2526 { 2527 if (p_dev_list->in_use) 2528 { 2529 for (j = 0; j < GATT_MAX_APPS; j ++) 2530 { 2531 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0) 2532 break; 2533 2534 if (p_dev_list->gatt_if[j] == gatt_if) 2535 { 2536 for (k = j + 1; k < GATT_MAX_APPS; k ++) 2537 p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k]; 2538 2539 if (p_dev_list->gatt_if[0] == 0) 2540 BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda); 2541 } 2542 2543 if (p_dev_list->listen_gif[j] == gatt_if) 2544 { 2545 p_dev_list->listen_gif[j] = 0; 2546 2547 if (p_reg != NULL && p_reg->listening > 0) 2548 p_reg->listening --; 2549 2550 /* move all element behind one forward */ 2551 for (k = j + 1; k < GATT_MAX_APPS; k ++) 2552 p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k]; 2553 2554 if (p_dev_list->listen_gif[0] == 0) 2555 BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda); 2556 } 2557 } 2558 } 2559 } 2560} 2561 2562 2563/******************************************************************************* 2564** 2565** Function gatt_reset_bgdev_list 2566** 2567** Description reset bg device list 2568** 2569** Returns pointer to the device record 2570** 2571*******************************************************************************/ 2572void gatt_reset_bgdev_list(void) 2573{ 2574 memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV); 2575 2576} 2577/******************************************************************************* 2578** 2579** Function gatt_update_auto_connect_dev 2580** 2581** Description This function add or remove a device for background connection 2582** procedure. 2583** 2584** Parameters gatt_if: Application ID. 2585** add: add peer device 2586** bd_addr: peer device address. 2587** 2588** Returns TRUE if connection started; FALSE if connection start failure. 2589** 2590*******************************************************************************/ 2591BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator) 2592{ 2593 BOOLEAN ret = FALSE; 2594 tGATT_REG *p_reg; 2595 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); 2596 2597 GATT_TRACE_API0 ("gatt_update_auto_connect_dev "); 2598 /* Make sure app is registered */ 2599 if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) 2600 { 2601 GATT_TRACE_ERROR1("gatt_update_auto_connect_dev - gatt_if is not registered", gatt_if); 2602 return(FALSE); 2603 } 2604 2605 if (add) 2606 { 2607 ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator); 2608 2609 if (ret && p_tcb != NULL) 2610 { 2611 /* if a connected device, update the link holding number */ 2612 gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE); 2613 } 2614 } 2615 else 2616 { 2617 ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator); 2618 } 2619 return ret; 2620} 2621 2622 2623 2624/******************************************************************************* 2625** 2626** Function gatt_get_conn_id 2627** 2628** Description This function returns a connecttion handle to a ATT server 2629** if the server is already connected 2630** 2631** Parameters gatt_if: client interface. 2632** bd_addr: peer device address. 2633** 2634** Returns Connection handle or invalid handle value 2635** 2636*******************************************************************************/ 2637UINT16 gatt_get_conn_id (tGATT_IF gatt_if, BD_ADDR bd_addr) 2638{ 2639 tGATT_REG *p_reg; 2640 tGATT_CLCB *p_clcb; 2641 tGATT_TCB *p_tcb; 2642 UINT8 i; 2643 2644 GATT_TRACE_API1 ("GATTC_GetConnIfConnected gatt_if=%d", gatt_if); 2645 /* Do we have a transport to the peer ? If not, we are not connected */ 2646 if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) == NULL) 2647 { 2648 GATT_TRACE_EVENT0 ("GATTC_GetConnIfConnected - no TCB found"); 2649 return(GATT_INVALID_CONN_ID); 2650 } 2651 2652 /* Make sure app is registered */ 2653 if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) 2654 { 2655 GATT_TRACE_ERROR1("GATTC_GetConnIfConnected - gatt_if is not registered", gatt_if); 2656 return(GATT_INVALID_CONN_ID); 2657 } 2658 2659 /* Now see if the app already has a client control block to that peer */ 2660 for (i = 0, p_clcb = gatt_cb.clcb; i < GATT_CL_MAX_LCB; i++, p_clcb++) 2661 { 2662 if ( p_clcb->in_use && (p_clcb->p_reg == p_reg) && (p_clcb->p_tcb == p_tcb) ) 2663 { 2664 return(p_clcb->conn_id); 2665 } 2666 } 2667 2668 /* If here, failed to allocate a client control block */ 2669 GATT_TRACE_ERROR1 ("gatt_get_conn_id: not connected- gatt_if: %u", gatt_if); 2670 return(GATT_INVALID_CONN_ID); 2671} 2672/******************************************************************************* 2673** 2674** Function gatt_add_pending_new_srv_start 2675** 2676** Description Add a pending new srv start to the new service start queue 2677** 2678** Returns Pointer to the new service start buffer, NULL no buffer available 2679** 2680*******************************************************************************/ 2681tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb ) 2682{ 2683 tGATT_PENDING_ENC_CLCB *p_buf; 2684 2685 GATT_TRACE_DEBUG0 ("gatt_add_pending_new_srv_start"); 2686 if ((p_buf = (tGATT_PENDING_ENC_CLCB *)GKI_getbuf((UINT16)sizeof(tGATT_PENDING_ENC_CLCB))) != NULL) 2687 { 2688 GATT_TRACE_DEBUG0 ("enqueue a new pending encryption channel clcb"); 2689 p_buf->p_clcb = p_clcb; 2690 GKI_enqueue (&p_tcb->pending_enc_clcb, p_buf); 2691 } 2692 return p_buf; 2693} 2694/******************************************************************************* 2695** 2696** Function gatt_update_listen_mode 2697** 2698** Description update peripheral role listening mode 2699** 2700** Returns Pointer to the new service start buffer, NULL no buffer available 2701** 2702*******************************************************************************/ 2703void gatt_update_listen_mode(void) 2704{ 2705 UINT8 ii = 0; 2706 tGATT_REG *p_reg = &gatt_cb.cl_rcb[0]; 2707 UINT8 listening = 0; 2708 UINT16 connectability, window, interval; 2709 2710 for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) 2711 { 2712 if ( p_reg->in_use && p_reg->listening > listening) 2713 { 2714 listening = p_reg->listening; 2715 } 2716 } 2717 2718 if (listening == GATT_LISTEN_TO_ALL || 2719 listening == GATT_LISTEN_TO_NONE) 2720 BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL); 2721 else 2722 BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL); 2723 2724 connectability = BTM_ReadConnectability (&window, &interval); 2725 2726 if (listening != GATT_LISTEN_TO_NONE) 2727 { 2728 connectability |= BTM_BLE_CONNECTABLE; 2729 } 2730 else 2731 connectability &= ~BTM_BLE_CONNECTABLE; 2732 /* turning on the adv now */ 2733 BTM_SetConnectability(connectability, window, interval); 2734 2735} 2736#endif 2737 2738 2739