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