1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * this file contains GATT utility functions 22 * 23 ******************************************************************************/ 24 #include "bt_target.h" 25 26 #if BLE_INCLUDED == TRUE 27 #include <string.h> 28 #include "stdio.h" 29 #include "gki.h" 30 31 #include "l2cdefs.h" 32 #include "gatt_int.h" 33 #include "gatt_api.h" 34 #include "gattdefs.h" 35 #include "sdp_api.h" 36 #include "btm_int.h" 37 /* check if [x, y] and [a, b] have overlapping range */ 38 #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b) (y >= a && x <= b) 39 40 #define GATT_GET_NEXT_VALID_HANDLE(x) (((x)/10 + 1) * 10) 41 42 const char * const op_code_name[] = 43 { 44 "UNKNOWN", 45 "ATT_RSP_ERROR", 46 "ATT_REQ_MTU", 47 "ATT_RSP_MTU", 48 "ATT_REQ_READ_INFO", 49 "ATT_RSP_READ_INFO", 50 "ATT_REQ_FIND_TYPE_VALUE", 51 "ATT_RSP_FIND_TYPE_VALUE", 52 "ATT_REQ_READ_BY_TYPE", 53 "ATT_RSP_READ_BY_TYPE", 54 "ATT_REQ_READ", 55 "ATT_RSP_READ", 56 "ATT_REQ_READ_BLOB", 57 "ATT_RSP_READ_BLOB", 58 "GATT_REQ_READ_MULTI", 59 "GATT_RSP_READ_MULTI", 60 "GATT_REQ_READ_BY_GRP_TYPE", 61 "GATT_RSP_READ_BY_GRP_TYPE", 62 "ATT_REQ_WRITE", 63 "ATT_RSP_WRITE", 64 "ATT_CMD_WRITE", 65 "ATT_SIGN_CMD_WRITE", 66 "ATT_REQ_PREPARE_WRITE", 67 "ATT_RSP_PREPARE_WRITE", 68 "ATT_REQ_EXEC_WRITE", 69 "ATT_RSP_EXEC_WRITE", 70 "Reserved", 71 "ATT_HANDLE_VALUE_NOTIF", 72 "Reserved", 73 "ATT_HANDLE_VALUE_IND", 74 "ATT_HANDLE_VALUE_CONF", 75 "ATT_OP_CODE_MAX" 76 }; 77 78 static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 79 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 80 81 82 /******************************************************************************* 83 ** 84 ** Function gatt_free_pending_ind 85 ** 86 ** Description Free all pending indications 87 ** 88 ** Returns None 89 ** 90 *******************************************************************************/ 91 void gatt_free_pending_ind(tGATT_TCB *p_tcb) 92 { 93 GATT_TRACE_DEBUG0("gatt_free_pending_ind"); 94 /* release all queued indications */ 95 while (p_tcb->pending_ind_q.p_first) 96 GKI_freebuf (GKI_dequeue (&p_tcb->pending_ind_q)); 97 } 98 99 /******************************************************************************* 100 ** 101 ** Function gatt_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 *******************************************************************************/ 108 void 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 *******************************************************************************/ 136 void 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 *******************************************************************************/ 166 tGATTS_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 *******************************************************************************/ 197 tGATT_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 *******************************************************************************/ 220 tGATTS_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 *******************************************************************************/ 244 tGATTS_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 *******************************************************************************/ 268 tGATT_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 *******************************************************************************/ 296 tGATT_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 *******************************************************************************/ 322 tGATT_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 *******************************************************************************/ 353 void 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 *******************************************************************************/ 373 void 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 *******************************************************************************/ 399 BOOLEAN 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 *******************************************************************************/ 436 void 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 *******************************************************************************/ 461 void 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 *******************************************************************************/ 480 BOOLEAN 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 *******************************************************************************/ 546 BOOLEAN 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 *******************************************************************************/ 586 BOOLEAN 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 *******************************************************************************/ 650 BOOLEAN 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 *******************************************************************************/ 688 BOOLEAN 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 *******************************************************************************/ 722 BOOLEAN 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 *******************************************************************************/ 760 tGATTS_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 *******************************************************************************/ 790 BOOLEAN 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 *******************************************************************************/ 816 UINT8 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 *******************************************************************************/ 841 tGATT_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 *******************************************************************************/ 860 tGATT_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 *******************************************************************************/ 879 UINT8 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 *******************************************************************************/ 902 tGATT_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 *******************************************************************************/ 940 void 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 *******************************************************************************/ 958 BOOLEAN 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 *******************************************************************************/ 1006 UINT8 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 *******************************************************************************/ 1035 BOOLEAN 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 *******************************************************************************/ 1100 void 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 *******************************************************************************/ 1115 void 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 *******************************************************************************/ 1130 void 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 *******************************************************************************/ 1147 void 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 *******************************************************************************/ 1162 void 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 *******************************************************************************/ 1182 UINT8 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 *******************************************************************************/ 1207 UINT8 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 *******************************************************************************/ 1242 UINT8 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 *******************************************************************************/ 1281 void 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 *******************************************************************************/ 1302 void 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 *******************************************************************************/ 1336 tGATT_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 *******************************************************************************/ 1370 UINT32 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 *******************************************************************************/ 1430 void 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 *******************************************************************************/ 1450 tGATT_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 1477 BOOLEAN 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 *******************************************************************************/ 1503 tGATT_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 *******************************************************************************/ 1538 void 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 *******************************************************************************/ 1558 tGATT_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 *******************************************************************************/ 1584 UINT8 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 *******************************************************************************/ 1608 UINT8 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 *******************************************************************************/ 1629 void 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 *******************************************************************************/ 1655 BOOLEAN 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 *******************************************************************************/ 1687 BOOLEAN 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 *******************************************************************************/ 1720 void 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 *******************************************************************************/ 1742 void 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 *******************************************************************************/ 1764 void 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 *******************************************************************************/ 1799 void 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 *******************************************************************************/ 1834 BOOLEAN 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 *******************************************************************************/ 1869 BOOLEAN 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 *******************************************************************************/ 1896 BOOLEAN 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 *******************************************************************************/ 1925 tGATT_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 *******************************************************************************/ 1952 UINT8 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 *******************************************************************************/ 1978 UINT8 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 *******************************************************************************/ 2001 void 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 *******************************************************************************/ 2080 void 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 *******************************************************************************/ 2137 UINT8 * 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 *******************************************************************************/ 2167 void 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 *******************************************************************************/ 2206 BOOLEAN 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 *******************************************************************************/ 2228 tGATT_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 *******************************************************************************/ 2251 tGATT_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 *******************************************************************************/ 2278 BOOLEAN 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 *******************************************************************************/ 2321 BOOLEAN 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 *******************************************************************************/ 2342 UINT8 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 *******************************************************************************/ 2368 BOOLEAN 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 *******************************************************************************/ 2401 BOOLEAN 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 *******************************************************************************/ 2444 void 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 *******************************************************************************/ 2484 void 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 *******************************************************************************/ 2503 BOOLEAN 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 *******************************************************************************/ 2559 UINT16 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