1/****************************************************************************** 2 * 3 * Copyright (C) 2003-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 the GATT client action functions for the state 22 * machine. 23 * 24 ******************************************************************************/ 25 26#include "bt_target.h" 27 28#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) 29 30 31#include "utl.h" 32#include "gki.h" 33#include "bd.h" 34#include "bta_sys.h" 35 36#include "bta_gattc_int.h" 37#include "l2c_api.h" 38 39 40#include <string.h> 41 42/***************************************************************************** 43** Constants 44*****************************************************************************/ 45static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, 46 BOOLEAN connected, tGATT_DISCONN_REASON reason); 47 48static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, 49 tGATT_CL_COMPLETE *p_data); 50 51static tGATT_CBACK bta_gattc_cl_cback = 52{ 53 bta_gattc_conn_cback, 54 bta_gattc_cmpl_cback, 55 bta_gattc_disc_res_cback, 56 bta_gattc_disc_cmpl_cback, 57 NULL 58}; 59 60/* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */ 61static UINT16 bta_gattc_opcode_to_int_evt[] = 62{ 63 BTA_GATTC_API_READ_EVT, 64 BTA_GATTC_API_WRITE_EVT, 65 BTA_GATTC_API_EXEC_EVT 66}; 67 68#if (BT_TRACE_VERBOSE == TRUE) 69static const char *bta_gattc_op_code_name[] = 70{ 71 "Unknown", 72 "Discovery", 73 "Read", 74 "Write", 75 "Exec", 76 "Config", 77 "Notification", 78 "Indication" 79}; 80#endif 81/***************************************************************************** 82** Action Functions 83*****************************************************************************/ 84 85/******************************************************************************* 86** 87** Function bta_gattc_register 88** 89** Description Register a GATT client application with BTA. 90** 91** Returns void 92** 93*******************************************************************************/ 94void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) 95{ 96 tBTA_GATTC cb_data; 97 UINT8 i; 98 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid; 99 tBTA_GATTC_INT_START_IF *p_buf; 100 101 102 /* todo need to check duplicate uuid */ 103 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) 104 { 105 if (!p_cb->cl_rcb[i].in_use) 106 { 107 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) 108 { 109 APPL_TRACE_ERROR0("Register with GATT stack failed."); 110 cb_data.reg_oper.status = BTA_GATT_ERROR; 111 } 112 else 113 114 { 115 p_cb->cl_rcb[i].in_use = TRUE; 116 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback; 117 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID)); 118 119 /* BTA use the same client interface as BTE GATT statck */ 120 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if; 121// btla-specific ++ 122 memcpy(&(cb_data.reg_oper.app_uuid),p_app_uuid,sizeof(tBT_UUID)); 123// btla-specific -- 124 125 cb_data.reg_oper.status = BTA_GATT_OK; 126 127 if ((p_buf = (tBTA_GATTC_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) 128 { 129 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT; 130 p_buf->client_if = p_cb->cl_rcb[i].client_if; 131 132 bta_sys_sendmsg(p_buf); 133 } 134 else 135 { 136 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES; 137 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB)); 138 } 139 break; 140 } 141 } 142 } 143 /* callback with register event */ 144 if (p_data->api_reg.p_cback) 145 { 146 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data); 147 } 148} 149 150/******************************************************************************* 151** 152** Function bta_gattc_start_if 153** 154** Description start an application interface. 155** 156** Returns none. 157** 158*******************************************************************************/ 159void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) 160{ 161 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) !=NULL ) 162 { 163 GATT_StartIf(p_msg->int_start_if.client_if); 164 } 165 else 166 { 167 APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.client_if ); 168 } 169} 170 171 172/******************************************************************************* 173** 174** Function bta_gattc_deregister_cmpl 175** 176** Description De-Register a GATT client application with BTA completed. 177** 178** Returns void 179** 180*******************************************************************************/ 181void bta_gattc_int_deregister_cmpl(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_IF client_if) 182{ 183 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback; 184 tBTA_GATTC cb_data; 185 186 187 APPL_TRACE_DEBUG1("bta_gattc_int_deregister_cmpl client_if=%d", client_if ); 188 189 GATT_Deregister(p_clreg->client_if); 190 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB)); 191 192 cb_data.reg_oper.client_if = client_if; 193 cb_data.reg_oper.status = BTA_GATT_OK; 194 195 if (p_cback) 196 /* callback with de-register event */ 197 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data); 198} 199 200 201/******************************************************************************* 202** 203** Function bta_gattc_deregister_cmpl 204** 205** Description De-Register a GATT client application with BTA completed. 206** 207** Returns void 208** 209*******************************************************************************/ 210void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_IF client_if) 211{ 212 tBTA_GATTC_INT_DEREG *p_buf; 213 214 APPL_TRACE_DEBUG1("bta_gattc_deregister_cmpl client_if=%d", client_if ); 215 216 if ((p_buf = (tBTA_GATTC_INT_DEREG *) GKI_getbuf(sizeof(tBTA_GATTC_INT_DEREG))) != NULL) 217 { 218 p_buf->hdr.event = BTA_GATTC_INT_DEREG_EVT; 219 p_buf->client_if = client_if; 220 bta_sys_sendmsg(p_buf); 221 } 222 else 223 { 224 APPL_TRACE_ERROR1("bta_gattc_deregister_cmpl unable to allocate buffer to complete dereg=%d", client_if); 225 } 226 227} 228 229/******************************************************************************* 230** 231** Function bta_gattc_deregister 232** 233** Description De-Register a GATT client application with BTA. 234** 235** Returns void 236** 237*******************************************************************************/ 238void bta_gattc_int_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) 239{ 240 241 tBTA_GATTC_IF client_if = p_data->int_dereg.client_if; 242 tBTA_GATTC_CBACK *p_cback; 243 tBTA_GATTC cb_data; 244 tBTA_GATTC_RCB *p_clreg; 245 246 247 APPL_TRACE_DEBUG1("bta_gattc_int_deregister_cmpl client_if=%d", client_if ); 248 249 if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL) 250 { 251 p_cback = p_clreg->p_cback; 252 GATT_Deregister(client_if); 253 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB)); 254 cb_data.reg_oper.client_if = client_if; 255 cb_data.reg_oper.status = BTA_GATT_OK; 256 257 if (p_cback) 258 /* callback with de-register event */ 259 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data); 260 } 261 else 262 { 263 APPL_TRACE_ERROR1("bta_gattc_int_deregister Deregister Failed, unknown client_if: %d", p_data->int_dereg.client_if); 264 } 265} 266 267 268/******************************************************************************* 269** 270** Function bta_gattc_deregister 271** 272** Description De-Register a GATT client application with BTA. 273** 274** Returns void 275** 276*******************************************************************************/ 277void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) 278{ 279 tBTA_GATTC_RCB *p_clreg; 280 UINT8 i; 281 BT_HDR buf; 282 283 if ((p_clreg = bta_gattc_cl_get_regcb(p_data->api_dereg.client_if)) != NULL) 284 { 285 if (p_clreg->num_clcb > 0) 286 { 287 /* close all CLCB related to this app */ 288 for (i= 0; i < BTA_GATTC_CLCB_MAX; i ++) 289 { 290 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg)) 291 { 292 p_clreg->dereg_pending = TRUE; 293 294 buf.event = BTA_GATTC_API_CLOSE_EVT; 295 buf.layer_specific = p_cb->clcb[i].bta_conn_id; 296 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ; 297 } 298 } 299 } 300 else 301 bta_gattc_deregister_cmpl(p_clreg, p_clreg->client_if); 302 } 303 else 304 { 305 APPL_TRACE_ERROR1("bta_gattc_deregister Deregister Failed, unknown client_if: %d", p_data->api_dereg.client_if); 306 } 307} 308/******************************************************************************* 309** 310** Function bta_gattc_process_api_open 311** 312** Description process connect API request. 313** 314** Returns void 315** 316*******************************************************************************/ 317void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 318{ 319 UINT16 event = ((BT_HDR *)p_msg)->event; 320 tBTA_GATTC_CLCB *p_clcb = NULL; 321 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if); 322 323 if (p_clreg != NULL) 324 { 325 if (p_msg->api_conn.is_direct) 326 { 327 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if, 328 p_msg->api_conn.remote_bda)) != NULL) 329 { 330 bta_gattc_sm_execute(p_clcb, event, p_msg); 331 } 332 else 333 { 334 APPL_TRACE_ERROR0("No resources to open a new connection."); 335 336 bta_gattc_send_open_cback(p_clreg, 337 BTA_GATT_NO_RESOURCES, 338 p_msg->api_conn.remote_bda, 339 BTA_GATT_INVALID_CONN_ID); 340 } 341 } 342 else 343 { 344 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg); 345 } 346 } 347 else 348 { 349 APPL_TRACE_ERROR1("bta_gattc_process_api_open Failed, unknown client_if: %d", 350 p_msg->api_conn.client_if); 351 } 352} 353/******************************************************************************* 354** 355** Function bta_gattc_process_api_open_cancel 356** 357** Description process connect API request. 358** 359** Returns void 360** 361*******************************************************************************/ 362void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 363{ 364 UINT16 event = ((BT_HDR *)p_msg)->event; 365 tBTA_GATTC_CLCB *p_clcb = NULL; 366 tBTA_GATTC_RCB *p_clreg; 367 tBTA_GATT_STATUS status = BTA_GATT_ERROR; 368 369 if (p_msg->api_cancel_conn.is_direct) 370 { 371 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if, 372 p_msg->api_cancel_conn.remote_bda)) != NULL) 373 { 374 bta_gattc_sm_execute(p_clcb, event, p_msg); 375 } 376 else 377 { 378 APPL_TRACE_ERROR0("No such connection need to be cancelled"); 379 380 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if); 381 382 if (p_clreg && p_clreg->p_cback) 383 { 384 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, (tBTA_GATTC *)&status); 385 } 386 } 387 } 388 else 389 { 390 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn); 391 392 } 393} 394 395/******************************************************************************* 396** 397** Function bta_gattc_cancel_open_error 398** 399** Description 400** 401** Returns void 402** 403*******************************************************************************/ 404void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 405{ 406 tBTA_GATT_STATUS status=BTA_GATT_ERROR; 407 408 if ( p_clcb->p_rcb->p_cback ) 409 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, (tBTA_GATTC *)&status); 410} 411 412/******************************************************************************* 413** 414** Function bta_gattc_open_error 415** 416** Description 417** 418** Returns void 419** 420*******************************************************************************/ 421void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 422{ 423 APPL_TRACE_ERROR0("Connection already opened. wrong state"); 424 425 bta_gattc_send_open_cback(p_clcb->p_rcb, 426 BTA_GATT_ALREADY_OPEN, 427 p_clcb->bda, 428 p_clcb->bta_conn_id); 429} 430/******************************************************************************* 431** 432** Function bta_gattc_open_fail 433** 434** Description 435** 436** Returns void 437** 438*******************************************************************************/ 439void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 440{ 441 bta_gattc_open_error(p_clcb, p_data); 442 /* open failure, remove clcb */ 443 bta_gattc_clcb_dealloc(p_clcb); 444} 445 446/******************************************************************************* 447** 448** Function bta_gattc_open 449** 450** Description Process API connection function. 451** 452** Returns void 453** 454*******************************************************************************/ 455void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 456{ 457 tBTA_GATTC_DATA gattc_data; 458 459 /* open/hold a connection */ 460 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, TRUE)) 461 { 462 APPL_TRACE_ERROR0("Connection open failure"); 463 464 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data); 465 } 466 else 467 { 468 /* a connected remote device */ 469 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if, 470 p_data->api_conn.remote_bda, 471 &p_clcb->bta_conn_id)) 472 { 473 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id; 474 475 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data); 476 } 477 /* else wait for the callback event */ 478 } 479} 480/******************************************************************************* 481** 482** Function bta_gattc_init_bk_conn 483** 484** Description Process API Open for a background connection 485** 486** Returns void 487** 488*******************************************************************************/ 489void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg) 490{ 491 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES; 492 UINT16 conn_id; 493 tBTA_GATTC_CLCB *p_clcb; 494 tBTA_GATTC_DATA gattc_data; 495 496 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE)) 497 { 498 /* alwaya call open to hold a connection */ 499 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE)) 500 { 501 status = BTA_GATT_ERROR; 502 APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed"); 503 } 504 else 505 { 506 status = BTA_GATT_OK; 507 508 /* if is a connected remote device */ 509 if (GATT_GetConnIdIfConnected(p_data->client_if, 510 p_data->remote_bda, 511 &conn_id)) 512 { 513 if ((p_clcb = bta_gattc_clcb_alloc(p_data->client_if, p_data->remote_bda)) != NULL) 514 { 515 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; 516 517 /* open connection */ 518 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data); 519 status = BTA_GATT_OK; 520 } 521 } 522 } 523 } 524 525 /* open failure, report OPEN_EVT */ 526 if (status != BTA_GATT_OK) 527 { 528 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, BTA_GATT_INVALID_CONN_ID); 529 } 530} 531/******************************************************************************* 532** 533** Function bta_gattc_cancel_bk_conn 534** 535** Description Process API Cancel Open for a background connection 536** 537** Returns void 538** 539*******************************************************************************/ 540void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data) 541{ 542 tBTA_GATTC_RCB *p_clreg; 543 tBTA_GATT_STATUS status = BTA_GATT_ERROR; 544 545 /* remove the device from the bg connection mask */ 546 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE)) 547 { 548 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE)) 549 { 550 status = BTA_GATT_OK; 551 } 552 else 553 { 554 APPL_TRACE_ERROR0("bta_gattc_cancel_bk_conn failed"); 555 } 556 } 557 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if); 558 559 if (p_clreg && p_clreg->p_cback) 560 { 561 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, (tBTA_GATTC *)&status); 562 } 563 564} 565/******************************************************************************* 566** 567** Function bta_gattc_int_cancel_open_ok 568** 569** Description 570** 571** Returns void 572** 573*******************************************************************************/ 574void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 575{ 576 tBTA_GATT_STATUS status = BTA_GATT_OK; 577 578 if ( p_clcb->p_rcb->p_cback ) 579 { 580 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, (tBTA_GATTC *)&status); 581 } 582 583 bta_gattc_clcb_dealloc(p_clcb); 584} 585 586/******************************************************************************* 587** 588** Function bta_gattc_cancel_open 589** 590** Description 591** 592** Returns void 593** 594*******************************************************************************/ 595void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 596{ 597 tBTA_GATT_STATUS status=BTA_GATT_ERROR; 598 599 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE)) 600 { 601 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data); 602 } 603 else 604 { 605 if ( p_clcb->p_rcb->p_cback ) 606 { 607 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, (tBTA_GATTC *)&status); 608 } 609 } 610} 611/******************************************************************************* 612** 613** Function bta_gattc_conn 614** 615** Description receive connection callback from stack 616** 617** Returns void 618** 619*******************************************************************************/ 620void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 621{ 622 tBTA_GATTC_IF gatt_if; 623 APPL_TRACE_DEBUG1("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state); 624 625 if (p_data != NULL) 626 { 627 APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific); 628 629 p_clcb->p_srcb->connected = TRUE; 630 p_clcb->bta_conn_id = p_data->hdr.layer_specific; 631 GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda); 632 633 /* start database cache if needed */ 634 if (p_clcb->p_srcb->p_srvc_cache == NULL) 635 { 636 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) 637 { 638 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; 639 bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, p_data); 640 } 641 else /* cache is building */ 642 p_clcb->state = BTA_GATTC_DISCOVER_ST; 643 } 644 645 else 646 { 647 /* a pending service handle change indication */ 648 if (p_clcb->p_srcb->srvc_hdl_chg) 649 { 650 p_clcb->p_srcb->srvc_hdl_chg = FALSE; 651 /* start discovery */ 652 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 653 } 654 } 655 656 if (p_clcb->p_rcb) 657 { 658 bta_gattc_send_open_cback(p_clcb->p_rcb, 659 BTA_GATT_OK, 660 p_clcb->bda, 661 p_clcb->bta_conn_id); 662 } 663 } 664} 665 666/******************************************************************************* 667** 668** Function bta_gattc_close_fail 669** 670** Description close a connection. 671** 672** Returns void 673** 674*******************************************************************************/ 675void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 676{ 677 tBTA_GATTC cb_data; 678 679 if ( p_clcb->p_rcb->p_cback ) 680 { 681 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 682 cb_data.close.client_if = p_clcb->p_rcb->client_if; 683 cb_data.close.conn_id = p_data->hdr.layer_specific; 684 bdcpy(cb_data.close.remote_bda, p_clcb->bda); 685 cb_data.close.status = BTA_GATT_ERROR; 686 cb_data.close.reason = BTA_GATT_CONN_NONE; 687 688 689 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data); 690 } 691} 692/******************************************************************************* 693** 694** Function bta_gattc_api_close 695** 696** Description close a GATTC connection. 697** 698** Returns void 699** 700*******************************************************************************/ 701void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 702{ 703 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback; 704 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb; 705 tBTA_GATTC cb_data; 706 707 APPL_TRACE_DEBUG1("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id); 708 709 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) 710 p_clcb->status = GATT_Disconnect(p_clcb->bta_conn_id); 711 712 cb_data.close.client_if = p_clcb->p_rcb->client_if; 713 cb_data.close.conn_id = p_clcb->bta_conn_id; 714 cb_data.close.status = p_clcb->status; 715 cb_data.close.reason = p_clcb->reason; 716 bdcpy(cb_data.close.remote_bda, p_clcb->bda); 717 718 if (p_clcb->status == BTA_GATT_OK) 719 { 720 /* if the srcb is no longer needed, reset the state */ 721 if ( -- p_clcb->p_srcb->num_clcb == 0) 722 { 723 APPL_TRACE_DEBUG0("Update srcb connection status"); 724 p_clcb->p_srcb->connected = FALSE; 725 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; 726 } 727 728 bta_gattc_clcb_dealloc(p_clcb); 729 } 730 731 ( * p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data); 732 733 if (-- p_clreg->num_clcb == 0 && p_clreg->dereg_pending) 734 { 735 bta_gattc_deregister_cmpl(p_clreg, p_clreg->client_if); 736 } 737 738} 739 740/******************************************************************************* 741** 742** Function bta_gattc_reset_discover_st 743** 744** Description when a SRCB finished discovery, tell all related clcb. 745** 746** Returns None. 747** 748*******************************************************************************/ 749void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb) 750{ 751 tBTA_GATTC_CB *p_cb = &bta_gattc_cb; 752 UINT8 i; 753 754 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) 755 { 756 if (p_cb->clcb[i].p_srcb == p_srcb) 757 { 758 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL); 759 } 760 } 761} 762/******************************************************************************* 763** 764** Function bta_gattc_set_discover_st 765** 766** Description when a SRCB start discovery, tell all related clcb and set 767** the state. 768** 769** Returns None. 770** 771*******************************************************************************/ 772void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb) 773{ 774 tBTA_GATTC_CB *p_cb = &bta_gattc_cb; 775 UINT8 i; 776 777#if BLE_INCLUDED == TRUE 778 L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE); 779#endif 780 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) 781 { 782 if (p_cb->clcb[i].p_srcb == p_srcb) 783 { 784 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST; 785 } 786 } 787} 788/******************************************************************************* 789** 790** Function bta_gattc_start_discover 791** 792** Description Start a discovery on server. 793** 794** Returns None. 795** 796*******************************************************************************/ 797void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 798{ 799 /* pending operation, wait until it finishes */ 800 801 APPL_TRACE_DEBUG1("bta_gattc_start_discover conn_id=%d",p_clcb->bta_conn_id); 802 if (p_clcb->p_q_cmd != NULL && p_clcb->auto_update == BTA_GATTC_NO_SCHEDULE && 803 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) 804 { 805 p_clcb->auto_update = BTA_GATTC_DISC_WAITING; 806 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */ 807 } 808 else /* no pending operation, start discovery right away */ 809 { 810 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE; 811 812 if (p_clcb->p_srcb != NULL) 813 { 814 /* clear the service change mask */ 815 p_clcb->p_srcb->srvc_hdl_chg = FALSE; 816 p_clcb->p_srcb->update_count = 0; 817 818 /* set all srcb related clcb into discovery ST */ 819 bta_gattc_set_discover_st(p_clcb->p_srcb); 820 821 if ( bta_gattc_init_cache(p_clcb->p_srcb) || 822 bta_gattc_discover_pri_service(p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL) != BTA_GATT_OK) 823 { 824 APPL_TRACE_ERROR0("discovery on server failed"); 825 bta_gattc_reset_discover_st(p_clcb->p_srcb); 826 } 827 } 828 else 829 { 830 APPL_TRACE_ERROR0("unknown device, can not start discovery"); 831 } 832 } 833} 834/******************************************************************************* 835** 836** Function bta_gattc_disc_cmpl 837** 838** Description discovery on server is finished 839** 840** Returns None. 841** 842*******************************************************************************/ 843void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 844{ 845 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd; 846 APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id); 847 848#if BLE_INCLUDED == TRUE 849 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); 850#endif 851 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; 852 853 /* release pending attribute list buffer */ 854 utl_freebuf((void **)&p_clcb->p_srcb->p_srvc_list); 855 856 /* get any queued command to proceed */ 857 if (p_q_cmd != NULL) 858 { 859 p_clcb->p_q_cmd = NULL; 860 861 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); 862 863 utl_freebuf((void **)&p_q_cmd); 864 865 } 866} 867/******************************************************************************* 868** 869** Function bta_gattc_read 870** 871** Description Read an attribute 872** 873** Returns None. 874** 875*******************************************************************************/ 876void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 877{ 878 UINT16 handle = 0; 879 tGATT_READ_PARAM read_param; 880 tBTA_GATTC_OP_CMPL op_cmpl; 881 882 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM)); 883 memset (&op_cmpl, 0 ,sizeof(tBTA_GATTC_OP_CMPL)); 884 885 if (bta_gattc_enqueue(p_clcb, p_data)) 886 { 887 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb, 888 &p_data->api_read.srvc_id, 889 &p_data->api_read.char_id, 890 p_data->api_read.descr_type)) == 0) 891 { 892 op_cmpl.status = BTA_GATT_ERROR; 893 } 894 else 895 { 896 read_param.by_handle.handle = handle; 897 read_param.by_handle.auth_req = p_data->api_read.auth_req; 898 899 op_cmpl.status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param); 900 } 901 902 /* read fail */ 903 if (op_cmpl.status != BTA_GATT_OK) 904 { 905 op_cmpl.op_code = GATTC_OPTYPE_READ; 906 op_cmpl.p_cmpl = NULL; 907 908 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 909 } 910 } 911} 912/******************************************************************************* 913** 914** Function bta_gattc_read_multi 915** 916** Description read multiple 917** 918** Returns None. 919*********************************************************************************/ 920void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 921{ 922 UINT16 i, handle; 923 tBTA_GATT_STATUS status = BTA_GATT_OK; 924 tGATT_READ_PARAM read_param; 925 tBTA_GATTC_OP_CMPL op_cmpl; 926 tBTA_GATTC_ATTR_ID *p_id; 927 tBT_UUID dummy_uuid; 928 929 if (bta_gattc_enqueue(p_clcb, p_data)) 930 { 931 memset(&dummy_uuid, 0, sizeof(tBT_UUID)); 932 memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); 933 934 p_id = p_data->api_read_multi.p_id_list; 935 936 for (i = 0; i < p_data->api_read_multi.num_attr && p_id; i ++, p_id ++) 937 { 938 handle = 0; 939 940 if (p_id->id_type == BTA_GATT_TYPE_CHAR) 941 { 942 handle = bta_gattc_id2handle(p_clcb->p_srcb, 943 &p_id->id_value.char_id.srvc_id, 944 &p_id->id_value.char_id.char_id, 945 dummy_uuid); 946 } 947 else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR) 948 { 949 handle = bta_gattc_id2handle(p_clcb->p_srcb, 950 &p_id->id_value.char_descr_id.char_id.srvc_id, 951 &p_id->id_value.char_descr_id.char_id.char_id, 952 p_id->id_value.char_descr_id.descr_type); 953 } 954 else 955 { 956 APPL_TRACE_ERROR1("invalud ID type: %d", p_id->id_type); 957 } 958 959 if (handle == 0) 960 { 961 status = BTA_GATT_ERROR; 962 break; 963 } 964 } 965 if (status == BTA_GATT_OK) 966 { 967 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr; 968 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req; 969 970 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param); 971 } 972 973 /* read fail */ 974 if (status != BTA_GATT_OK) 975 { 976 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 977 978 op_cmpl.status = status; 979 op_cmpl.op_code = GATTC_OPTYPE_READ; 980 op_cmpl.p_cmpl = NULL; 981 982 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 983 } 984 } 985} 986/******************************************************************************* 987** 988** Function bta_gattc_write 989** 990** Description Write an attribute 991** 992** Returns None. 993** 994*******************************************************************************/ 995void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 996{ 997 UINT16 handle = 0; 998 tGATT_VALUE attr = {0}; 999 tBTA_GATTC_OP_CMPL op_cmpl; 1000 tBTA_GATT_STATUS status = BTA_GATT_OK; 1001 1002 if (bta_gattc_enqueue(p_clcb, p_data)) 1003 { 1004 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb, 1005 &p_data->api_write.srvc_id, 1006 &p_data->api_write.char_id, 1007 p_data->api_write.descr_type)) == 0) 1008 { 1009 status = BTA_GATT_ERROR; 1010 } 1011 else 1012 { 1013 attr.handle= handle; 1014 attr.offset = p_data->api_write.offset; 1015 attr.len = p_data->api_write.len; 1016 attr.auth_req = p_data->api_write.auth_req; 1017 1018 if (p_data->api_write.p_value) 1019 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len); 1020 1021 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr); 1022 } 1023 1024 /* write fail */ 1025 if (status != BTA_GATT_OK) 1026 { 1027 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 1028 1029 op_cmpl.status = status; 1030 op_cmpl.op_code = GATTC_OPTYPE_WRITE; 1031 op_cmpl.p_cmpl = NULL; 1032 1033 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 1034 } 1035 } 1036} 1037/******************************************************************************* 1038** 1039** Function bta_gattc_execute 1040** 1041** Description send execute write 1042** 1043** Returns None. 1044*********************************************************************************/ 1045void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1046{ 1047 tBTA_GATTC_OP_CMPL op_cmpl; 1048 tBTA_GATT_STATUS status; 1049 1050 if (bta_gattc_enqueue(p_clcb, p_data)) 1051 { 1052 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute); 1053 1054 if (status != BTA_GATT_OK) 1055 { 1056 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 1057 1058 op_cmpl.status = status; 1059 op_cmpl.op_code = GATTC_OPTYPE_EXE_WRITE; 1060 op_cmpl.p_cmpl = NULL; 1061 1062 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 1063 } 1064 } 1065} 1066 1067/******************************************************************************* 1068** 1069** Function bta_gattc_confirm 1070** 1071** Description send handle value confirmation 1072** 1073** Returns None. 1074** 1075*******************************************************************************/ 1076void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1077{ 1078 UINT16 handle; 1079 tBT_UUID null_uuid = {0}; 1080 1081 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb, 1082 &p_data->api_confirm.srvc_id, 1083 &p_data->api_confirm.char_id, 1084 null_uuid)) == 0) 1085 { 1086 APPL_TRACE_ERROR0("Can not map service/char ID into valid handle"); 1087 } 1088 else 1089 { 1090 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle) 1091 != GATT_SUCCESS) 1092 { 1093 APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle); 1094 } 1095 } 1096} 1097/******************************************************************************* 1098** 1099** Function bta_gattc_read_cmpl 1100** 1101** Description read complete 1102** 1103** Returns None. 1104** 1105*******************************************************************************/ 1106void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1107{ 1108 UINT8 event; 1109 tBTA_GATTC cb_data; 1110 tBTA_GATT_READ_VAL read_value; 1111 1112 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 1113 memset(&read_value, 0, sizeof(tBTA_GATT_READ_VAL)); 1114 1115 cb_data.read.status = p_data->status; 1116 1117 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) 1118 { 1119 if (bta_gattc_handle2id(p_clcb->p_srcb, 1120 p_data->p_cmpl->att_value.handle, 1121 &cb_data.read.srvc_id, 1122 &cb_data.read.char_id, 1123 &cb_data.read.descr_type) == FALSE) 1124 { 1125 cb_data.read.status = BTA_GATT_INTERNAL_ERROR; 1126 APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", p_data->p_cmpl->att_value.handle); 1127 } 1128 else 1129 { 1130 cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb, 1131 cb_data.read.descr_type, 1132 &p_data->p_cmpl->att_value, 1133 &read_value); 1134 cb_data.read.p_value = &read_value; 1135 } 1136 } 1137 else 1138 { 1139 cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id; 1140 cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id; 1141 cb_data.read.descr_type = p_clcb->p_q_cmd->api_read.descr_type; 1142 } 1143 1144 event = (p_clcb->p_q_cmd->api_read.descr_type.len == 0) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT; 1145 cb_data.read.conn_id = p_clcb->bta_conn_id; 1146 1147 utl_freebuf((void **)&p_clcb->p_q_cmd); 1148 /* read complete, callback */ 1149 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data); 1150 1151} 1152/******************************************************************************* 1153** 1154** Function bta_gattc_write_cmpl 1155** 1156** Description read complete 1157** 1158** Returns None. 1159** 1160*******************************************************************************/ 1161void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1162{ 1163 tBTA_GATTC cb_data = {0}; 1164 UINT8 event; 1165 1166 cb_data.write.status = p_data->status; 1167 1168 if (p_data->p_cmpl != NULL) 1169 { 1170 bta_gattc_handle2id(p_clcb->p_srcb, p_data->p_cmpl->handle, 1171 &cb_data.write.srvc_id, &cb_data.write.char_id, 1172 &cb_data.write.descr_type); 1173 } 1174 else 1175 { 1176 cb_data.write.srvc_id = p_clcb->p_q_cmd->api_write.srvc_id; 1177 cb_data.write.char_id = p_clcb->p_q_cmd->api_write.char_id; 1178 cb_data.write.descr_type = p_clcb->p_q_cmd->api_write.descr_type; 1179 } 1180 1181 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT && 1182 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) 1183 1184 event = BTA_GATTC_PREP_WRITE_EVT; 1185 1186 else if (p_clcb->p_q_cmd->api_write.descr_type.len == 0) 1187 1188 event = BTA_GATTC_WRITE_CHAR_EVT; 1189 1190 else 1191 event = BTA_GATTC_WRITE_DESCR_EVT; 1192 1193 utl_freebuf((void **)&p_clcb->p_q_cmd); 1194 cb_data.write.conn_id = p_clcb->bta_conn_id; 1195 /* write complete, callback */ 1196 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data); 1197 1198} 1199/******************************************************************************* 1200** 1201** Function bta_gattc_exec_cmpl 1202** 1203** Description execute write complete 1204** 1205** Returns None. 1206** 1207*******************************************************************************/ 1208void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1209{ 1210 tBTA_GATTC cb_data; 1211 1212 utl_freebuf((void **)&p_clcb->p_q_cmd); 1213 1214 p_clcb->status = BTA_GATT_OK; 1215 1216 /* execute complete, callback */ 1217 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id; 1218 cb_data.exec_cmpl.status = p_data->status; 1219 1220 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data); 1221 1222} 1223 1224 1225/******************************************************************************* 1226** 1227** Function bta_gattc_op_cmpl 1228** 1229** Description operation completed. 1230** 1231** Returns None. 1232** 1233*******************************************************************************/ 1234void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1235{ 1236 UINT8 op = (UINT8)p_data->op_cmpl.op_code; 1237 UINT8 mapped_op = 0; 1238 1239 APPL_TRACE_DEBUG1("bta_gattc_op_cmpl op = %d", op); 1240 1241 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) 1242 { 1243 APPL_TRACE_ERROR0("unexpected operation, ignored"); 1244 } 1245 else if (op >= GATTC_OPTYPE_READ) 1246 { 1247 if (p_clcb->p_q_cmd == NULL) 1248 { 1249 APPL_TRACE_ERROR0("No pending command"); 1250 return; 1251 } 1252 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) 1253 { 1254 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ; 1255 if ( mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0; 1256 1257#if (BT_TRACE_VERBOSE == TRUE) 1258 APPL_TRACE_ERROR3("expect op:(%s :0x%04x), receive unexpected operation (%s).", 1259 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event, 1260 bta_gattc_op_code_name[op]); 1261#else 1262 APPL_TRACE_ERROR3("expect op:(%u :0x%04x), receive unexpected operation (%u).", 1263 mapped_op , p_clcb->p_q_cmd->hdr.event, op); 1264#endif 1265 return; 1266 } 1267 1268 /* service handle change void the response, discard it */ 1269 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) 1270 { 1271 p_clcb->auto_update = BTA_GATTC_REQ_WAITING; 1272 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 1273 } 1274 else if (op == GATTC_OPTYPE_READ) 1275 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl); 1276 1277 else if (op == GATTC_OPTYPE_WRITE) 1278 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl); 1279 1280 else if (op == GATTC_OPTYPE_EXE_WRITE) 1281 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl); 1282 /* 1283 else if (op == GATTC_OPTYPE_CONFIG) // API to be added 1284 { 1285 } 1286 */ 1287 } 1288} 1289/******************************************************************************* 1290** 1291** Function bta_gattc_op_cmpl 1292** 1293** Description operation completed. 1294** 1295** Returns None. 1296** 1297*******************************************************************************/ 1298void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1299{ 1300 /* receive op complete when discovery is started, ignore the response, 1301 and wait for discovery finish and resent */ 1302 APPL_TRACE_DEBUG1("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific); 1303 1304} 1305/******************************************************************************* 1306** 1307** Function bta_gattc_search 1308** 1309** Description start a search in the local server cache 1310** 1311** Returns None. 1312** 1313*******************************************************************************/ 1314void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1315{ 1316 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR; 1317 tBTA_GATTC cb_data; 1318 APPL_TRACE_DEBUG1("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id); 1319 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) 1320 { 1321 status = BTA_GATT_OK; 1322 /* search the local cache of a server device */ 1323 bta_gattc_search_service(p_clcb, p_data->api_search.srvc_uuid); 1324 } 1325 cb_data.search_cmpl.status = status; 1326 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id; 1327 1328 /* end of search or no server cache available */ 1329 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data); 1330} 1331/******************************************************************************* 1332** 1333** Function bta_gattc_q_cmd 1334** 1335** Description enqueue a command into control block, usually because discovery 1336** operation is busy. 1337** 1338** Returns None. 1339** 1340*******************************************************************************/ 1341void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1342{ 1343 bta_gattc_enqueue(p_clcb, p_data); 1344} 1345/******************************************************************************* 1346** 1347** Function bta_gattc_cache_open 1348** 1349** Description open a NV cache for loading 1350** 1351** Returns void 1352** 1353*******************************************************************************/ 1354void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1355{ 1356 bta_gattc_set_discover_st(p_clcb->p_srcb); 1357 1358 APPL_TRACE_DEBUG1("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id); 1359 bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, 1360 p_clcb->bta_conn_id, FALSE); 1361} 1362/******************************************************************************* 1363** 1364** Function bta_gattc_start_load 1365** 1366** Description start cache loading by sending callout open cache 1367** 1368** Returns None. 1369** 1370*******************************************************************************/ 1371void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1372{ 1373 APPL_TRACE_DEBUG2("bta_gattc_ci_open conn_id=%d server state=%d" , 1374 p_clcb->bta_conn_id, p_clcb->p_srcb->state); 1375 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD) 1376 { 1377 if (p_data->ci_open.status == BTA_GATT_OK) 1378 { 1379 p_clcb->p_srcb->attr_index = 0; 1380 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, 1381 BTA_GATTC_CI_CACHE_LOAD_EVT, 1382 p_clcb->p_srcb->attr_index, 1383 p_clcb->bta_conn_id); 1384 } 1385 else 1386 { 1387 /* cache open failure, start discovery */ 1388 bta_gattc_start_discover(p_clcb, NULL); 1389 } 1390 } 1391 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE) 1392 { 1393 if (p_data->ci_open.status == BTA_GATT_OK) 1394 { 1395 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) 1396 { 1397 p_data->ci_open.status = BTA_GATT_ERROR; 1398 } 1399 } 1400 if (p_data->ci_open.status != BTA_GATT_OK) 1401 { 1402 p_clcb->p_srcb->attr_index = 0; 1403 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id); 1404 bta_gattc_reset_discover_st(p_clcb->p_srcb); 1405 1406 } 1407 } 1408} 1409/******************************************************************************* 1410** 1411** Function bta_gattc_ci_load 1412** 1413** Description cache loading received. 1414** 1415** Returns None. 1416** 1417*******************************************************************************/ 1418void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1419{ 1420 1421 APPL_TRACE_DEBUG2("bta_gattc_ci_load conn_id=%d load status=%d" , 1422 p_clcb->bta_conn_id, p_data->ci_load.status ); 1423 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); 1424 1425 if ((p_data->ci_load.status == BTA_GATT_OK || 1426 p_data->ci_load.status == BTA_GATT_MORE) && 1427 p_data->ci_load.num_attr > 0) 1428 { 1429 bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index); 1430 1431 if (p_data->ci_load.status == BTA_GATT_OK) 1432 { 1433 p_clcb->p_srcb->attr_index = 0; 1434 bta_gattc_reset_discover_st(p_clcb->p_srcb); 1435 1436 } 1437 else /* load more */ 1438 { 1439 p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr; 1440 1441 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, 1442 BTA_GATTC_CI_CACHE_LOAD_EVT, 1443 p_clcb->p_srcb->attr_index, 1444 p_clcb->bta_conn_id); 1445 } 1446 } 1447 else 1448 { 1449 p_clcb->p_srcb->attr_index = 0; 1450 /* cache open failure, start discovery */ 1451 bta_gattc_start_discover(p_clcb, NULL); 1452 } 1453} 1454/******************************************************************************* 1455** 1456** Function bta_gattc_ci_load 1457** 1458** Description cache loading received. 1459** 1460** Returns None. 1461** 1462*******************************************************************************/ 1463void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1464{ 1465 APPL_TRACE_DEBUG1("bta_gattc_ci_save conn_id=%d " , 1466 p_clcb->bta_conn_id ); 1467 1468 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) 1469 { 1470 p_clcb->p_srcb->attr_index = 0; 1471 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); 1472 bta_gattc_reset_discover_st(p_clcb->p_srcb); 1473 } 1474} 1475 1476/******************************************************************************* 1477** 1478** Function bta_gattc_fail 1479** 1480** Description report API call failure back to apps 1481** 1482** Returns None. 1483** 1484*******************************************************************************/ 1485void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1486{ 1487 if (p_clcb->status == BTA_GATT_OK) 1488 { 1489 APPL_TRACE_ERROR1("operation not supported at current state [%d]", p_clcb->state); 1490 } 1491} 1492/******************************************************************************* 1493** 1494** Function bta_gattc_conn_cback 1495** bta_gattc_cmpl_cback 1496** 1497** Description callback functions to GATT client stack. 1498** 1499** Returns void 1500** 1501*******************************************************************************/ 1502static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, 1503 BOOLEAN connected, tGATT_DISCONN_REASON reason) 1504{ 1505 BT_HDR *p_buf; 1506 tBTA_GATTC_CLCB *p_clcb = NULL; 1507 1508 APPL_TRACE_DEBUG4("bta_gattc_conn_cback: cif = %d connected = %d conn_id = %d reaosn = 0x%04x", 1509 gattc_if, connected, conn_id, reason); 1510 1511 if (connected) 1512 { 1513 /* outgoing connection : locate a logic channel */ 1514 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL) 1515 { 1516 1517#if BLE_INCLUDED == TRUE 1518 /* for a background connection */ 1519 if (L2CA_GetBleConnRole(bda)== HCI_ROLE_MASTER && 1520 bta_gattc_check_bg_conn(gattc_if, bda)) 1521 { 1522 /* allocate a new channel */ 1523 p_clcb = bta_gattc_clcb_alloc(gattc_if, bda); 1524 } 1525#endif 1526 } 1527 if (p_clcb != NULL) 1528 { 1529 p_clcb->bta_conn_id = conn_id; 1530 1531 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 1532 { 1533 p_buf->event = BTA_GATTC_INT_CONN_EVT; 1534 p_buf->layer_specific = conn_id; 1535 1536 bta_sys_sendmsg(p_buf); 1537 } 1538 } 1539 } 1540 else 1541 { 1542 /* connection attempt timeout, send connection callback event */ 1543 if (reason == GATT_CONN_CANCEL ) 1544 { 1545 p_clcb = bta_gattc_clcb_alloc(gattc_if, bda); 1546 p_clcb->bta_conn_id = conn_id; 1547 } 1548 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL) 1549 { 1550 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 1551 { 1552 p_buf->event = BTA_GATTC_INT_DISCONN_EVT; 1553 p_buf->layer_specific = conn_id; 1554 p_clcb->reason = reason; 1555 1556 bta_sys_sendmsg(p_buf); 1557 } 1558 } 1559 else 1560 { 1561 APPL_TRACE_DEBUG1(" connection ID: [%d] not used by BTA", conn_id); 1562 } 1563 } 1564} 1565/******************************************************************************* 1566** 1567** Function bta_gattc_process_srvc_chg_ind 1568** 1569** Description process service change indication. 1570** 1571** Returns None. 1572** 1573*******************************************************************************/ 1574BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id, 1575 tBTA_GATTC_RCB *p_clrcb, 1576 tBTA_GATTC_SERV *p_srcb, 1577 tBTA_GATTC_CLCB *p_clcb, 1578 tBTA_GATTC_NOTIFY *p_notify, 1579 UINT16 handle) 1580{ 1581 tBT_UUID gattp_uuid, srvc_chg_uuid; 1582 BOOLEAN processed = FALSE; 1583 UINT8 i; 1584 1585 gattp_uuid.len = 2; 1586 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER; 1587 1588 srvc_chg_uuid.len = 2; 1589 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD; 1590 1591 if (bta_gattc_uuid_compare(p_notify->char_id.srvc_id.id.uuid, gattp_uuid, TRUE) && 1592 bta_gattc_uuid_compare(p_notify->char_id.char_id.uuid, srvc_chg_uuid, TRUE)) 1593 { 1594 processed = TRUE; 1595 /* mark service handle change pending */ 1596 p_srcb->srvc_hdl_chg = TRUE; 1597 /* clear up all notification/indication registration */ 1598 bta_gattc_clear_notif_registration(conn_id); 1599 /* service change indication all received, do discovery update */ 1600 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) 1601 { 1602 /* not an opened connection; or connection busy */ 1603 /* search for first available clcb and start discovery */ 1604 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) 1605 { 1606 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) 1607 { 1608 if (bta_gattc_cb.clcb[i].in_use && 1609 bta_gattc_cb.clcb[i].p_srcb == p_srcb && 1610 bta_gattc_cb.clcb[i].p_q_cmd == NULL) 1611 { 1612 p_clcb = &bta_gattc_cb.clcb[i]; 1613 break; 1614 } 1615 } 1616 } 1617 /* send confirmation here if this is an indication, it should always be */ 1618 GATTC_SendHandleValueConfirm(conn_id, handle); 1619 1620 /* if connection available, refresh cache by doing discovery now */ 1621 if (p_clcb != NULL) 1622 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 1623 } 1624 /* notify applicationf or service change */ 1625 if (p_clrcb->p_cback != NULL) 1626 { 1627 APPL_TRACE_ERROR0("bta_gattc_process_srvc_chg_ind 2"); 1628 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda); 1629 } 1630 1631 } 1632 1633 return processed; 1634 1635} 1636/******************************************************************************* 1637** 1638** Function bta_gattc_proc_other_indication 1639** 1640** Description process all non-service change indication/notification. 1641** 1642** Returns None. 1643** 1644*******************************************************************************/ 1645void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op, 1646 tGATT_CL_COMPLETE *p_data, 1647 tBTA_GATTC_NOTIFY *p_notify) 1648{ 1649 APPL_TRACE_DEBUG2("bta_gattc_proc_other_indication check \ 1650 p_data->att_value.handle=%d p_data->handle=%d", 1651 p_data->att_value.handle, p_data->handle); 1652 APPL_TRACE_DEBUG1("is_notify", p_notify->is_notify); 1653 1654 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE; 1655 p_notify->len = p_data->att_value.len; 1656 bdcpy(p_notify->bda, p_clcb->bda); 1657 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len); 1658 p_notify->conn_id = p_clcb->bta_conn_id; 1659 1660 if (p_clcb->p_rcb->p_cback) 1661 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify); 1662 1663} 1664/******************************************************************************* 1665** 1666** Function bta_gattc_process_indicate 1667** 1668** Description process indication/notification. 1669** 1670** Returns None. 1671** 1672*******************************************************************************/ 1673void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data) 1674{ 1675 UINT16 handle = p_data->att_value.handle; 1676 tBTA_GATTC_CLCB *p_clcb ; 1677 tBTA_GATTC_RCB *p_clrcb = NULL; 1678 tBTA_GATTC_SERV *p_srcb = NULL; 1679 tBTA_GATTC_NOTIFY notify; 1680 BD_ADDR remote_bda; 1681 tBTA_GATTC_IF gatt_if; 1682 1683 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda)) 1684 { 1685 APPL_TRACE_ERROR0("indication/notif for unknown app"); 1686 return; 1687 } 1688 1689 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) 1690 { 1691 APPL_TRACE_ERROR0("indication/notif for unregistered app"); 1692 return; 1693 } 1694 1695 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) 1696 { 1697 APPL_TRACE_ERROR0("indication/notif for unknown device, ignore"); 1698 return; 1699 } 1700 1701 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); 1702 1703 if (bta_gattc_handle2id(p_srcb, handle, 1704 ¬ify.char_id.srvc_id, 1705 ¬ify.char_id.char_id, 1706 ¬ify.descr_type)) 1707 { 1708 /* if non-service change indication/notification, forward to application */ 1709 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, handle)) 1710 { 1711 /* if app registered for the notification */ 1712 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) 1713 { 1714 /* connection not open yet */ 1715 if (p_clcb == NULL) 1716 { 1717 if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda)) != NULL) 1718 { 1719 p_clcb->bta_conn_id = conn_id; 1720 1721 /* send connection event */ 1722 bta_gattc_send_open_cback(p_clrcb, 1723 BTA_GATT_OK, 1724 remote_bda, 1725 conn_id); 1726 } 1727 else 1728 { 1729 APPL_TRACE_ERROR0("No resources"); 1730 } 1731 } 1732 1733 if (p_clcb != NULL) 1734 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify); 1735 } 1736 /* no one intersted and need ack? */ 1737 else if (op == GATTC_OPTYPE_INDICATION) 1738 { 1739 APPL_TRACE_DEBUG0("no one interested, ack now"); 1740 GATTC_SendHandleValueConfirm(conn_id, handle); 1741 } 1742 } 1743 } 1744 else 1745 { 1746 APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", handle); 1747 } 1748} 1749 1750/******************************************************************************* 1751** 1752** Function bta_gattc_cmpl_cback 1753** 1754** Description client operation complete callback register with BTE GATT. 1755** 1756** Returns None. 1757** 1758*******************************************************************************/ 1759static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, 1760 tGATT_CL_COMPLETE *p_data) 1761{ 1762 tBTA_GATTC_CLCB *p_clcb ; 1763 tBTA_GATTC_OP_CMPL *p_buf; 1764 UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE); 1765 1766 APPL_TRACE_DEBUG3("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d", 1767 conn_id, op, status); 1768 1769 /* notification and indication processed right away */ 1770 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) 1771 { 1772 bta_gattc_process_indicate(conn_id, op, p_data); 1773 return; 1774 } 1775 /* for all other operation, not expected if w/o connection */ 1776 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) 1777 { 1778 APPL_TRACE_ERROR1("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id); 1779 return; 1780 } 1781 1782 1783 if ((p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len)) != NULL) 1784 { 1785 memset(p_buf, 0, len); 1786 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT; 1787 p_buf->hdr.layer_specific = conn_id; 1788 p_buf->status = status; 1789 p_buf->op_code = op; 1790 1791 if (p_data != NULL) 1792 { 1793 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1); 1794 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE)); 1795 } 1796 1797 bta_sys_sendmsg(p_buf); 1798 } 1799 1800 return; 1801} 1802#endif /* BTA_GATT_INCLUDED */ 1803