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