bta_gattc_act.c revision 7fa4fba6f59f97df00aff07dbe8fb21b114b3c2c
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#include "utl.h" 29#include "gki.h" 30#include "bd.h" 31#include "bta_sys.h" 32 33#include "bta_gattc_int.h" 34#include "l2c_api.h" 35 36#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) 37#include "bta_hh_int.h" 38#endif 39 40#include <string.h> 41 42#if BTA_GATT_INCLUDED && BLE_INCLUDED == TRUE 43 44/***************************************************************************** 45** Constants 46*****************************************************************************/ 47static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, 48 BOOLEAN connected, tGATT_DISCONN_REASON reason, 49 tBT_TRANSPORT transport); 50 51static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, 52 tGATT_CL_COMPLETE *p_data); 53 54static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); 55 56static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda); 57 58static tGATT_CBACK bta_gattc_cl_cback = 59{ 60 bta_gattc_conn_cback, 61 bta_gattc_cmpl_cback, 62 bta_gattc_disc_res_cback, 63 bta_gattc_disc_cmpl_cback, 64 NULL, 65 bta_gattc_enc_cmpl_cback 66}; 67 68/* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */ 69static UINT16 bta_gattc_opcode_to_int_evt[] = 70{ 71 BTA_GATTC_API_READ_EVT, 72 BTA_GATTC_API_WRITE_EVT, 73 BTA_GATTC_API_EXEC_EVT, 74 BTA_GATTC_API_CFG_MTU_EVT 75}; 76 77#if (BT_TRACE_VERBOSE == TRUE) 78static const char *bta_gattc_op_code_name[] = 79{ 80 "Unknown", 81 "Discovery", 82 "Read", 83 "Write", 84 "Exec", 85 "Config", 86 "Notification", 87 "Indication" 88}; 89#endif 90/***************************************************************************** 91** Action Functions 92*****************************************************************************/ 93 94/******************************************************************************* 95** 96** Function bta_gattc_enable 97** 98** Description Enables GATTC module 99** 100** 101** Returns void 102** 103*******************************************************************************/ 104static void bta_gattc_enable(tBTA_GATTC_CB *p_cb) 105{ 106 APPL_TRACE_DEBUG0("bta_gattc_enable"); 107 108 if (p_cb->state == BTA_GATTC_STATE_DISABLED) 109 { 110 /* initialize control block */ 111 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB)); 112 p_cb->state = BTA_GATTC_STATE_ENABLED; 113 } 114 else 115 { 116 APPL_TRACE_DEBUG0("GATTC is arelady enabled"); 117 } 118} 119 120 121/******************************************************************************* 122** 123** Function bta_gattc_disable 124** 125** Description Disable GATTC module by cleaning up all active connections 126** and deregister all application. 127** 128** Returns void 129** 130*******************************************************************************/ 131void bta_gattc_disable(tBTA_GATTC_CB *p_cb) 132{ 133 UINT8 i; 134 135 APPL_TRACE_DEBUG0("bta_gattc_disable"); 136 137 if (p_cb->state != BTA_GATTC_STATE_ENABLED) 138 { 139 APPL_TRACE_ERROR0("not enabled or disable in pogress"); 140 return; 141 } 142 143 for (i = 0; i <BTA_GATTC_CL_MAX; i ++) 144 { 145 if (p_cb->cl_rcb[i].in_use) 146 { 147 p_cb->state = BTA_GATTC_STATE_DISABLING; 148 /* don't deregister HH GATT IF */ 149 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */ 150#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) 151 if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) { 152#endif 153 bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]); 154#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) 155 } 156#endif 157 } 158 } 159 160 /* no registered apps, indicate disable completed */ 161 if (p_cb->state != BTA_GATTC_STATE_DISABLING) 162 { 163 p_cb->state = BTA_GATTC_STATE_DISABLED; 164 memset(p_cb, 0, sizeof(tBTA_GATTC_CB)); 165 } 166} 167 168/******************************************************************************* 169** 170** Function bta_gattc_register 171** 172** Description Register a GATT client application with BTA. 173** 174** Returns void 175** 176*******************************************************************************/ 177void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) 178{ 179 tBTA_GATTC cb_data; 180 UINT8 i; 181 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid; 182 tBTA_GATTC_INT_START_IF *p_buf; 183 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES; 184 185 186 APPL_TRACE_DEBUG1("bta_gattc_register state %d",p_cb->state); 187 memset(&cb_data, 0, sizeof(cb_data)); 188 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES; 189 190 /* check if GATTC module is already enabled . Else enable */ 191 if (p_cb->state == BTA_GATTC_STATE_DISABLED) 192 { 193 bta_gattc_enable (p_cb); 194 } 195 /* todo need to check duplicate uuid */ 196 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) 197 { 198 if (!p_cb->cl_rcb[i].in_use) 199 { 200 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) 201 { 202 APPL_TRACE_ERROR0("Register with GATT stack failed."); 203 status = BTA_GATT_ERROR; 204 } 205 else 206 { 207 p_cb->cl_rcb[i].in_use = TRUE; 208 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback; 209 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID)); 210 211 /* BTA use the same client interface as BTE GATT statck */ 212 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if; 213 214 if ((p_buf = (tBTA_GATTC_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) 215 { 216 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT; 217 p_buf->client_if = p_cb->cl_rcb[i].client_if; 218 219 bta_sys_sendmsg(p_buf); 220 status = BTA_GATT_OK; 221 } 222 else 223 { 224 GATT_Deregister(p_cb->cl_rcb[i].client_if); 225 226 status = BTA_GATT_NO_RESOURCES; 227 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB)); 228 } 229 break; 230 } 231 } 232 } 233 234 /* callback with register event */ 235 if (p_data->api_reg.p_cback) 236 { 237 if (p_app_uuid != NULL) 238 memcpy(&(cb_data.reg_oper.app_uuid),p_app_uuid,sizeof(tBT_UUID)); 239 240 cb_data.reg_oper.status = status; 241 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data); 242 } 243} 244/******************************************************************************* 245** 246** Function bta_gattc_start_if 247** 248** Description start an application interface. 249** 250** Returns none. 251** 252*******************************************************************************/ 253void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) 254{ 255 UNUSED(p_cb); 256 257 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) !=NULL ) 258 { 259 GATT_StartIf(p_msg->int_start_if.client_if); 260 } 261 else 262 { 263 APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.client_if ); 264 } 265} 266/******************************************************************************* 267** 268** Function bta_gattc_deregister 269** 270** Description De-Register a GATT client application with BTA. 271** 272** Returns void 273** 274*******************************************************************************/ 275void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg) 276{ 277 UINT8 i; 278 BT_HDR buf; 279 280 if (p_clreg != NULL) 281 { 282 /* remove bg connection associated with this rcb */ 283 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++) 284 { 285 if (p_cb->bg_track[i].in_use) 286 { 287 if (p_cb->bg_track[i].cif_mask & (1 <<(p_clreg->client_if - 1))) 288 { 289 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE); 290 GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE); 291 } 292 if (p_cb->bg_track[i].cif_adv_mask & (1 <<(p_clreg->client_if - 1))) 293 { 294 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE); 295 } 296 } 297 } 298 299 if (p_clreg->num_clcb > 0) 300 { 301 /* close all CLCB related to this app */ 302 for (i= 0; i < BTA_GATTC_CLCB_MAX; i ++) 303 { 304 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg)) 305 { 306 p_clreg->dereg_pending = TRUE; 307 308 buf.event = BTA_GATTC_API_CLOSE_EVT; 309 buf.layer_specific = p_cb->clcb[i].bta_conn_id; 310 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ; 311 } 312 } 313 } 314 else 315 bta_gattc_deregister_cmpl(p_clreg); 316 } 317 else 318 { 319 APPL_TRACE_ERROR0("bta_gattc_deregister Deregister Failedm unknown client cif"); 320 } 321} 322/******************************************************************************* 323** 324** Function bta_gattc_process_api_open 325** 326** Description process connect API request. 327** 328** Returns void 329** 330*******************************************************************************/ 331void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 332{ 333 UINT16 event = ((BT_HDR *)p_msg)->event; 334 tBTA_GATTC_CLCB *p_clcb = NULL; 335 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if); 336 UNUSED(p_cb); 337 338 if (p_clreg != NULL) 339 { 340 if (p_msg->api_conn.is_direct) 341 { 342 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if, 343 p_msg->api_conn.remote_bda, 344 p_msg->api_conn.transport)) != NULL) 345 { 346 bta_gattc_sm_execute(p_clcb, event, p_msg); 347 } 348 else 349 { 350 APPL_TRACE_ERROR0("No resources to open a new connection."); 351 352 bta_gattc_send_open_cback(p_clreg, 353 BTA_GATT_NO_RESOURCES, 354 p_msg->api_conn.remote_bda, 355 BTA_GATT_INVALID_CONN_ID, 356 p_msg->api_conn.transport, 0); 357 } 358 } 359 else 360 { 361 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg); 362 } 363 } 364 else 365 { 366 APPL_TRACE_ERROR1("bta_gattc_process_api_open Failed, unknown client_if: %d", 367 p_msg->api_conn.client_if); 368 } 369} 370/******************************************************************************* 371** 372** Function bta_gattc_process_api_open_cancel 373** 374** Description process connect API request. 375** 376** Returns void 377** 378*******************************************************************************/ 379void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 380{ 381 UINT16 event = ((BT_HDR *)p_msg)->event; 382 tBTA_GATTC_CLCB *p_clcb = NULL; 383 tBTA_GATTC_RCB *p_clreg; 384 tBTA_GATTC cb_data; 385 UNUSED(p_cb); 386 387 if (p_msg->api_cancel_conn.is_direct) 388 { 389 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if, 390 p_msg->api_cancel_conn.remote_bda, 391 BTA_GATT_TRANSPORT_LE)) != NULL) 392 { 393 bta_gattc_sm_execute(p_clcb, event, p_msg); 394 } 395 else 396 { 397 APPL_TRACE_ERROR0("No such connection need to be cancelled"); 398 399 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if); 400 401 if (p_clreg && p_clreg->p_cback) 402 { 403 cb_data.status = BTA_GATT_ERROR; 404 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data); 405 } 406 } 407 } 408 else 409 { 410 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn); 411 412 } 413} 414 415/******************************************************************************* 416** 417** Function bta_gattc_process_enc_cmpl 418** 419** Description process encryption complete message. 420** 421** Returns void 422** 423*******************************************************************************/ 424void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) 425{ 426 tBTA_GATTC_RCB *p_clreg; 427 tBTA_GATTC cb_data; 428 UNUSED(p_cb); 429 430 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if); 431 432 if (p_clreg && p_clreg->p_cback) 433 { 434 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 435 436 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if; 437 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda); 438 439 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data); 440 } 441} 442 443/******************************************************************************* 444** 445** Function bta_gattc_cancel_open_error 446** 447** Description 448** 449** Returns void 450** 451*******************************************************************************/ 452void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 453{ 454 tBTA_GATTC cb_data; 455 UNUSED(p_data); 456 457 cb_data.status=BTA_GATT_ERROR; 458 459 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback ) 460 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data); 461} 462 463/******************************************************************************* 464** 465** Function bta_gattc_open_error 466** 467** Description 468** 469** Returns void 470** 471*******************************************************************************/ 472void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 473{ 474 UNUSED(p_data); 475 476 APPL_TRACE_ERROR0("Connection already opened. wrong state"); 477 478 bta_gattc_send_open_cback(p_clcb->p_rcb, 479 BTA_GATT_OK, 480 p_clcb->bda, 481 p_clcb->bta_conn_id, 482 p_clcb->transport, 483 0); 484} 485/******************************************************************************* 486** 487** Function bta_gattc_open_fail 488** 489** Description 490** 491** Returns void 492** 493*******************************************************************************/ 494void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 495{ 496 UNUSED(p_data); 497 498 bta_gattc_send_open_cback(p_clcb->p_rcb, 499 BTA_GATT_ERROR, 500 p_clcb->bda, 501 p_clcb->bta_conn_id, 502 p_clcb->transport, 503 0); 504 /* open failure, remove clcb */ 505 bta_gattc_clcb_dealloc(p_clcb); 506} 507 508/******************************************************************************* 509** 510** Function bta_gattc_open 511** 512** Description Process API connection function. 513** 514** Returns void 515** 516*******************************************************************************/ 517void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 518{ 519 tBTA_GATTC_DATA gattc_data; 520 521 /* open/hold a connection */ 522 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, 523 TRUE, p_data->api_conn.transport)) 524 { 525 APPL_TRACE_ERROR0("Connection open failure"); 526 527 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data); 528 } 529 else 530 { 531 /* a connected remote device */ 532 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if, 533 p_data->api_conn.remote_bda, 534 &p_clcb->bta_conn_id, 535 p_data->api_conn.transport)) 536 { 537 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id; 538 539 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data); 540 } 541 /* else wait for the callback event */ 542 } 543} 544/******************************************************************************* 545** 546** Function bta_gattc_init_bk_conn 547** 548** Description Process API Open for a background connection 549** 550** Returns void 551** 552*******************************************************************************/ 553void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg) 554{ 555 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES; 556 UINT16 conn_id; 557 tBTA_GATTC_CLCB *p_clcb; 558 tBTA_GATTC_DATA gattc_data; 559 560 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) 561 { 562 /* always call open to hold a connection */ 563 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport)) 564 { 565 status = BTA_GATT_ERROR; 566 APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed"); 567 } 568 else 569 { 570 status = BTA_GATT_OK; 571 572 /* if is a connected remote device */ 573 if (GATT_GetConnIdIfConnected(p_data->client_if, 574 p_data->remote_bda, 575 &conn_id, 576 p_data->transport)) 577 { 578 if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda, 579 BTA_GATT_TRANSPORT_LE)) != NULL) 580 { 581 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; 582 583 /* open connection */ 584 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data); 585 status = BTA_GATT_OK; 586 } 587 } 588 } 589 } 590 591 /* open failure, report OPEN_EVT */ 592 if (status != BTA_GATT_OK) 593 { 594 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, 595 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0); 596 } 597} 598/******************************************************************************* 599** 600** Function bta_gattc_cancel_bk_conn 601** 602** Description Process API Cancel Open for a background connection 603** 604** Returns void 605** 606*******************************************************************************/ 607void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data) 608{ 609 tBTA_GATTC_RCB *p_clreg; 610 tBTA_GATTC cb_data; 611 cb_data.status = BTA_GATT_ERROR; 612 613 /* remove the device from the bg connection mask */ 614 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE)) 615 { 616 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE)) 617 { 618 cb_data.status = BTA_GATT_OK; 619 } 620 else 621 { 622 APPL_TRACE_ERROR0("bta_gattc_cancel_bk_conn failed"); 623 } 624 } 625 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if); 626 627 if (p_clreg && p_clreg->p_cback) 628 { 629 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data); 630 } 631 632} 633/******************************************************************************* 634** 635** Function bta_gattc_int_cancel_open_ok 636** 637** Description 638** 639** Returns void 640** 641*******************************************************************************/ 642void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 643{ 644 tBTA_GATTC cb_data; 645 UNUSED(p_data); 646 647 if ( p_clcb->p_rcb->p_cback ) 648 { 649 cb_data.status = BTA_GATT_OK; 650 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data); 651 } 652 653 bta_gattc_clcb_dealloc(p_clcb); 654} 655/******************************************************************************* 656** 657** Function bta_gattc_cancel_open 658** 659** Description 660** 661** Returns void 662** 663*******************************************************************************/ 664void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 665{ 666 tBTA_GATTC cb_data; 667 668 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE)) 669 { 670 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data); 671 } 672 else 673 { 674 if ( p_clcb->p_rcb->p_cback ) 675 { 676 cb_data.status = BTA_GATT_ERROR; 677 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data); 678 } 679 } 680} 681/******************************************************************************* 682** 683** Function bta_gattc_conn 684** 685** Description receive connection callback from stack 686** 687** Returns void 688** 689*******************************************************************************/ 690void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 691{ 692 tBTA_GATTC_IF gatt_if; 693 APPL_TRACE_DEBUG1("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state); 694 695 if (p_data != NULL) 696 { 697 APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific); 698 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific; 699 700 GATT_GetConnectionInfor(p_data->hdr.layer_specific, 701 &gatt_if, p_clcb->bda, &p_clcb->transport); 702 } 703 704 p_clcb->p_srcb->connected = TRUE; 705 706 if (p_clcb->p_srcb->mtu == 0) 707 p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE; 708 709 /* start database cache if needed */ 710 if (p_clcb->p_srcb->p_srvc_cache == NULL || 711 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) 712 { 713 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) 714 { 715 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; 716 bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL); 717 } 718 else /* cache is building */ 719 p_clcb->state = BTA_GATTC_DISCOVER_ST; 720 } 721 722 else 723 { 724 /* a pending service handle change indication */ 725 if (p_clcb->p_srcb->srvc_hdl_chg) 726 { 727 p_clcb->p_srcb->srvc_hdl_chg = FALSE; 728 /* start discovery */ 729 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 730 } 731 } 732 733 if (p_clcb->p_rcb) 734 { 735 /* there is no RM for GATT */ 736 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) 737 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); 738 739 bta_gattc_send_open_cback(p_clcb->p_rcb, 740 BTA_GATT_OK, 741 p_clcb->bda, 742 p_clcb->bta_conn_id, 743 p_clcb->transport, 744 p_clcb->p_srcb->mtu); 745 } 746 } 747/******************************************************************************* 748** 749** Function bta_gattc_close_fail 750** 751** Description close a connection. 752** 753** Returns void 754** 755*******************************************************************************/ 756void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 757{ 758 tBTA_GATTC cb_data; 759 760 if ( p_clcb->p_rcb->p_cback ) 761 { 762 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 763 cb_data.close.client_if = p_clcb->p_rcb->client_if; 764 cb_data.close.conn_id = p_data->hdr.layer_specific; 765 bdcpy(cb_data.close.remote_bda, p_clcb->bda); 766 cb_data.close.status = BTA_GATT_ERROR; 767 cb_data.close.reason = BTA_GATT_CONN_NONE; 768 769 770 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data); 771 } 772} 773/******************************************************************************* 774** 775** Function bta_gattc_api_close 776** 777** Description close a GATTC connection. 778** 779** Returns void 780** 781*******************************************************************************/ 782void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 783{ 784 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback; 785 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb; 786 tBTA_GATTC cb_data; 787 788 APPL_TRACE_DEBUG1("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id); 789 790 cb_data.close.client_if = p_clcb->p_rcb->client_if; 791 cb_data.close.conn_id = p_clcb->bta_conn_id; 792 cb_data.close.reason = p_clcb->reason; 793 cb_data.close.status = p_clcb->status; 794 bdcpy(cb_data.close.remote_bda, p_clcb->bda); 795 796 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) 797 bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda); 798 799 bta_gattc_clcb_dealloc(p_clcb); 800 801 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) 802 { 803 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific); 804 } 805 else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) 806 { 807 cb_data.close.status = p_data->int_conn.reason; 808 } 809 810 if(p_cback) 811 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data); 812 813 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) 814 { 815 bta_gattc_deregister_cmpl(p_clreg); 816 } 817} 818/******************************************************************************* 819** 820** Function bta_gattc_reset_discover_st 821** 822** Description when a SRCB finished discovery, tell all related clcb. 823** 824** Returns None. 825** 826*******************************************************************************/ 827void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status) 828{ 829 tBTA_GATTC_CB *p_cb = &bta_gattc_cb; 830 UINT8 i; 831 832 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) 833 { 834 if (p_cb->clcb[i].p_srcb == p_srcb) 835 { 836 p_cb->clcb[i].status = status; 837 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL); 838 } 839 } 840} 841/******************************************************************************* 842** 843** Function bta_gattc_disc_close 844** 845** Description close a GATTC connection while in discovery state. 846** 847** Returns void 848** 849*******************************************************************************/ 850void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 851{ 852 APPL_TRACE_DEBUG1("Discovery cancel conn_id=%d",p_clcb->bta_conn_id); 853 854 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR); 855 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_CLOSE_EVT, p_data); 856} 857/******************************************************************************* 858** 859** Function bta_gattc_set_discover_st 860** 861** Description when a SRCB start discovery, tell all related clcb and set 862** the state. 863** 864** Returns None. 865** 866*******************************************************************************/ 867void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb) 868{ 869 tBTA_GATTC_CB *p_cb = &bta_gattc_cb; 870 UINT8 i; 871 872#if BLE_INCLUDED == TRUE 873 L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE); 874#endif 875 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) 876 { 877 if (p_cb->clcb[i].p_srcb == p_srcb) 878 { 879 p_cb->clcb[i].status = BTA_GATT_OK; 880 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST; 881 } 882 } 883} 884/******************************************************************************* 885** 886** Function bta_gattc_restart_discover 887** 888** Description process service change in discovery state, mark up the auto 889** update flag and set status to be discovery cancel for current 890** discovery. 891** 892** Returns None. 893** 894*******************************************************************************/ 895void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 896{ 897 UNUSED(p_data); 898 899 p_clcb->status = BTA_GATT_CANCEL; 900 p_clcb->auto_update = BTA_GATTC_DISC_WAITING; 901} 902 903/******************************************************************************* 904** 905** Function bta_gattc_cfg_mtu 906** 907** Description Configure MTU size on the GATT connection. 908** 909** Returns None. 910** 911*******************************************************************************/ 912void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 913{ 914 tBTA_GATTC_OP_CMPL op_cmpl; 915 tBTA_GATT_STATUS status; 916 917 if (bta_gattc_enqueue(p_clcb, p_data)) 918 { 919 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id, p_data->api_mtu.mtu); 920 921 /* if failed, return callback here */ 922 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) 923 { 924 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 925 926 op_cmpl.status = status; 927 op_cmpl.op_code = GATTC_OPTYPE_CONFIG; 928 op_cmpl.p_cmpl = NULL; 929 930 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 931 } 932 } 933} 934/******************************************************************************* 935** 936** Function bta_gattc_start_discover 937** 938** Description Start a discovery on server. 939** 940** Returns None. 941** 942*******************************************************************************/ 943void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 944{ 945 UNUSED(p_data); 946 947 APPL_TRACE_DEBUG2("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ", 948 p_clcb->bta_conn_id, p_clcb->p_srcb->state); 949 950 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) && 951 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) || 952 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) 953 /* no pending operation, start discovery right away */ 954 { 955 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE; 956 957 if (p_clcb->p_srcb != NULL) 958 { 959 /* clear the service change mask */ 960 p_clcb->p_srcb->srvc_hdl_chg = FALSE; 961 p_clcb->p_srcb->update_count = 0; 962 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT; 963 964 if (p_clcb->transport == BTA_TRANSPORT_LE) 965 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE); 966 967 /* set all srcb related clcb into discovery ST */ 968 bta_gattc_set_discover_st(p_clcb->p_srcb); 969 970 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) 971 { 972 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, 973 p_clcb->p_srcb, GATT_DISC_SRVC_ALL); 974 } 975 if (p_clcb->status != BTA_GATT_OK) 976 { 977 APPL_TRACE_ERROR0("discovery on server failed"); 978 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); 979 } 980 } 981 else 982 { 983 APPL_TRACE_ERROR0("unknown device, can not start discovery"); 984 } 985 } 986 /* pending operation, wait until it finishes */ 987 else 988 { 989 p_clcb->auto_update = BTA_GATTC_DISC_WAITING; 990 991 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) 992 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */ 993 } 994 995} 996/******************************************************************************* 997** 998** Function bta_gattc_disc_cmpl 999** 1000** Description discovery on server is finished 1001** 1002** Returns None. 1003** 1004*******************************************************************************/ 1005void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1006{ 1007 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd; 1008 UNUSED(p_data); 1009 1010 APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id); 1011 1012#if BLE_INCLUDED == TRUE 1013 if(p_clcb->transport == BTA_TRANSPORT_LE) 1014 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); 1015#endif 1016 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; 1017 1018 if (p_clcb->status != GATT_SUCCESS) 1019 { 1020 /* clean up cache */ 1021 if(p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) 1022 { 1023 while (p_clcb->p_srcb->cache_buffer.p_first) 1024 { 1025 GKI_freebuf (GKI_dequeue (&p_clcb->p_srcb->cache_buffer)); 1026 } 1027 p_clcb->p_srcb->p_srvc_cache = NULL; 1028 } 1029 1030 /* used to reset cache in application */ 1031 bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda); 1032 } 1033 /* release pending attribute list buffer */ 1034 utl_freebuf((void **)&p_clcb->p_srcb->p_srvc_list); 1035 1036 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) 1037 { 1038 /* start discovery again */ 1039 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 1040 } 1041 /* get any queued command to proceed */ 1042 else if (p_q_cmd != NULL) 1043 { 1044 p_clcb->p_q_cmd = NULL; 1045 1046 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); 1047 1048 utl_freebuf((void **)&p_q_cmd); 1049 1050 } 1051} 1052/******************************************************************************* 1053** 1054** Function bta_gattc_read 1055** 1056** Description Read an attribute 1057** 1058** Returns None. 1059** 1060*******************************************************************************/ 1061void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1062{ 1063 UINT16 handle = 0; 1064 tGATT_READ_PARAM read_param; 1065 tBTA_GATTC_OP_CMPL op_cmpl; 1066 1067 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM)); 1068 memset (&op_cmpl, 0 ,sizeof(tBTA_GATTC_OP_CMPL)); 1069 1070 if (bta_gattc_enqueue(p_clcb, p_data)) 1071 { 1072 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb, 1073 &p_data->api_read.srvc_id, 1074 &p_data->api_read.char_id, 1075 p_data->api_read.p_descr_type)) == 0) 1076 { 1077 op_cmpl.status = BTA_GATT_ERROR; 1078 } 1079 else 1080 { 1081 read_param.by_handle.handle = handle; 1082 read_param.by_handle.auth_req = p_data->api_read.auth_req; 1083 1084 op_cmpl.status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param); 1085 } 1086 1087 /* read fail */ 1088 if (op_cmpl.status != BTA_GATT_OK) 1089 { 1090 op_cmpl.op_code = GATTC_OPTYPE_READ; 1091 op_cmpl.p_cmpl = NULL; 1092 1093 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 1094 } 1095 } 1096} 1097/******************************************************************************* 1098** 1099** Function bta_gattc_read_multi 1100** 1101** Description read multiple 1102** 1103** Returns None. 1104*********************************************************************************/ 1105void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1106{ 1107 UINT16 i, handle; 1108 tBTA_GATT_STATUS status = BTA_GATT_OK; 1109 tGATT_READ_PARAM read_param; 1110 tBTA_GATTC_OP_CMPL op_cmpl; 1111 tBTA_GATTC_ATTR_ID *p_id; 1112 1113 if (bta_gattc_enqueue(p_clcb, p_data)) 1114 { 1115 memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); 1116 1117 p_id = p_data->api_read_multi.p_id_list; 1118 1119 for (i = 0; i < p_data->api_read_multi.num_attr && p_id; i ++, p_id ++) 1120 { 1121 handle = 0; 1122 1123 if (p_id->id_type == BTA_GATT_TYPE_CHAR) 1124 { 1125 handle = bta_gattc_id2handle(p_clcb->p_srcb, 1126 &p_id->id_value.char_id.srvc_id, 1127 &p_id->id_value.char_id.char_id, 1128 NULL); 1129 } 1130 else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR) 1131 { 1132 handle = bta_gattc_id2handle(p_clcb->p_srcb, 1133 &p_id->id_value.char_descr_id.char_id.srvc_id, 1134 &p_id->id_value.char_descr_id.char_id.char_id, 1135 &p_id->id_value.char_descr_id.descr_id); 1136 } 1137 else 1138 { 1139 APPL_TRACE_ERROR1("invalud ID type: %d", p_id->id_type); 1140 } 1141 1142 if (handle == 0) 1143 { 1144 status = BTA_GATT_ERROR; 1145 break; 1146 } 1147 } 1148 if (status == BTA_GATT_OK) 1149 { 1150 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr; 1151 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req; 1152 1153 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param); 1154 } 1155 1156 /* read fail */ 1157 if (status != BTA_GATT_OK) 1158 { 1159 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 1160 1161 op_cmpl.status = status; 1162 op_cmpl.op_code = GATTC_OPTYPE_READ; 1163 op_cmpl.p_cmpl = NULL; 1164 1165 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 1166 } 1167 } 1168} 1169/******************************************************************************* 1170** 1171** Function bta_gattc_write 1172** 1173** Description Write an attribute 1174** 1175** Returns None. 1176** 1177*******************************************************************************/ 1178void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1179{ 1180 UINT16 handle = 0; 1181 tGATT_VALUE attr = {0}; 1182 tBTA_GATTC_OP_CMPL op_cmpl; 1183 tBTA_GATT_STATUS status = BTA_GATT_OK; 1184 1185 if (bta_gattc_enqueue(p_clcb, p_data)) 1186 { 1187 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb, 1188 &p_data->api_write.srvc_id, 1189 &p_data->api_write.char_id, 1190 p_data->api_write.p_descr_type)) == 0) 1191 { 1192 status = BTA_GATT_ERROR; 1193 } 1194 else 1195 { 1196 attr.handle= handle; 1197 attr.offset = p_data->api_write.offset; 1198 attr.len = p_data->api_write.len; 1199 attr.auth_req = p_data->api_write.auth_req; 1200 1201 if (p_data->api_write.p_value) 1202 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len); 1203 1204 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr); 1205 } 1206 1207 /* write fail */ 1208 if (status != BTA_GATT_OK) 1209 { 1210 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 1211 1212 op_cmpl.status = status; 1213 op_cmpl.op_code = GATTC_OPTYPE_WRITE; 1214 op_cmpl.p_cmpl = NULL; 1215 1216 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 1217 } 1218 } 1219} 1220/******************************************************************************* 1221** 1222** Function bta_gattc_execute 1223** 1224** Description send execute write 1225** 1226** Returns None. 1227*********************************************************************************/ 1228void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1229{ 1230 tBTA_GATTC_OP_CMPL op_cmpl; 1231 tBTA_GATT_STATUS status; 1232 1233 if (bta_gattc_enqueue(p_clcb, p_data)) 1234 { 1235 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute); 1236 1237 if (status != BTA_GATT_OK) 1238 { 1239 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL)); 1240 1241 op_cmpl.status = status; 1242 op_cmpl.op_code = GATTC_OPTYPE_EXE_WRITE; 1243 op_cmpl.p_cmpl = NULL; 1244 1245 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl); 1246 } 1247 } 1248} 1249/******************************************************************************* 1250** 1251** Function bta_gattc_confirm 1252** 1253** Description send handle value confirmation 1254** 1255** Returns None. 1256** 1257*******************************************************************************/ 1258void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1259{ 1260 UINT16 handle; 1261 1262 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb, 1263 &p_data->api_confirm.srvc_id, 1264 &p_data->api_confirm.char_id, 1265 NULL)) == 0) 1266 { 1267 APPL_TRACE_ERROR0("Can not map service/char ID into valid handle"); 1268 } 1269 else 1270 { 1271 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle) 1272 != GATT_SUCCESS) 1273 { 1274 APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle); 1275 } 1276 else 1277 { 1278 /* if over BR_EDR, inform PM for mode change */ 1279 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) 1280 { 1281 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); 1282 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); 1283 } 1284 } 1285 } 1286} 1287/******************************************************************************* 1288** 1289** Function bta_gattc_read_cmpl 1290** 1291** Description read complete 1292** 1293** Returns None. 1294** 1295*******************************************************************************/ 1296void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1297{ 1298 UINT8 event; 1299 tBTA_GATTC cb_data; 1300 tBTA_GATT_READ_VAL read_value; 1301 1302 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 1303 memset(&read_value, 0, sizeof(tBTA_GATT_READ_VAL)); 1304 1305 cb_data.read.status = p_data->status; 1306 1307 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) 1308 { 1309 if (bta_gattc_handle2id(p_clcb->p_srcb, 1310 p_data->p_cmpl->att_value.handle, 1311 &cb_data.read.srvc_id, 1312 &cb_data.read.char_id, 1313 &cb_data.read.descr_type) == FALSE) 1314 { 1315 cb_data.read.status = BTA_GATT_INTERNAL_ERROR; 1316 APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", 1317 p_data->p_cmpl->att_value.handle); 1318 } 1319 else 1320 { 1321 cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb, 1322 &cb_data.read.descr_type.uuid, 1323 &p_data->p_cmpl->att_value, 1324 &read_value); 1325 cb_data.read.p_value = &read_value; 1326 } 1327 } 1328 else 1329 { 1330 cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id; 1331 cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id; 1332 if (p_clcb->p_q_cmd->api_read.p_descr_type) 1333 memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type, 1334 sizeof(tBTA_GATT_ID)); 1335 } 1336 1337 event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ? 1338 BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT; 1339 cb_data.read.conn_id = p_clcb->bta_conn_id; 1340 1341 utl_freebuf((void **)&p_clcb->p_q_cmd); 1342 /* read complete, callback */ 1343 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data); 1344 1345} 1346/******************************************************************************* 1347** 1348** Function bta_gattc_write_cmpl 1349** 1350** Description read complete 1351** 1352** Returns None. 1353** 1354*******************************************************************************/ 1355void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1356{ 1357 tBTA_GATTC cb_data = {0}; 1358 UINT8 event; 1359 1360 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 1361 1362 cb_data.write.status = p_data->status; 1363 1364 if (p_data->p_cmpl != NULL) 1365 { 1366 bta_gattc_handle2id(p_clcb->p_srcb, p_data->p_cmpl->handle, 1367 &cb_data.write.srvc_id, &cb_data.write.char_id, 1368 &cb_data.write.descr_type); 1369 } 1370 else 1371 { 1372 memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id, 1373 sizeof(tBTA_GATT_SRVC_ID)); 1374 memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id, 1375 sizeof(tBTA_GATT_ID)); 1376 if (p_clcb->p_q_cmd->api_write.p_descr_type) 1377 memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type, 1378 sizeof(tBTA_GATT_ID)); 1379 } 1380 1381 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT && 1382 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) 1383 1384 event = BTA_GATTC_PREP_WRITE_EVT; 1385 1386 else if (p_clcb->p_q_cmd->api_write.p_descr_type == NULL) 1387 1388 event = BTA_GATTC_WRITE_CHAR_EVT; 1389 1390 else 1391 event = BTA_GATTC_WRITE_DESCR_EVT; 1392 1393 utl_freebuf((void **)&p_clcb->p_q_cmd); 1394 cb_data.write.conn_id = p_clcb->bta_conn_id; 1395 /* write complete, callback */ 1396 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data); 1397 1398} 1399/******************************************************************************* 1400** 1401** Function bta_gattc_exec_cmpl 1402** 1403** Description execute write complete 1404** 1405** Returns None. 1406** 1407*******************************************************************************/ 1408void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1409{ 1410 tBTA_GATTC cb_data; 1411 1412 utl_freebuf((void **)&p_clcb->p_q_cmd); 1413 1414 p_clcb->status = BTA_GATT_OK; 1415 1416 /* execute complete, callback */ 1417 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id; 1418 cb_data.exec_cmpl.status = p_data->status; 1419 1420 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data); 1421 1422} 1423 1424/******************************************************************************* 1425** 1426** Function bta_gattc_cfg_mtu_cmpl 1427** 1428** Description configure MTU operation complete 1429** 1430** Returns None. 1431** 1432*******************************************************************************/ 1433void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) 1434{ 1435 tBTA_GATTC cb_data; 1436 1437 utl_freebuf((void **)&p_clcb->p_q_cmd); 1438 1439 1440 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) 1441 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu; 1442 1443 /* configure MTU complete, callback */ 1444 p_clcb->status = p_data->status; 1445 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id; 1446 cb_data.cfg_mtu.status = p_data->status; 1447 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu; 1448 1449 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data); 1450 1451} 1452/******************************************************************************* 1453** 1454** Function bta_gattc_op_cmpl 1455** 1456** Description operation completed. 1457** 1458** Returns None. 1459** 1460*******************************************************************************/ 1461void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1462{ 1463 UINT8 op = (UINT8)p_data->op_cmpl.op_code; 1464 UINT8 mapped_op = 0; 1465 1466 APPL_TRACE_DEBUG1("bta_gattc_op_cmpl op = %d", op); 1467 1468 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) 1469 { 1470 APPL_TRACE_ERROR0("unexpected operation, ignored"); 1471 } 1472 else if (op >= GATTC_OPTYPE_READ) 1473 { 1474 if (p_clcb->p_q_cmd == NULL) 1475 { 1476 APPL_TRACE_ERROR0("No pending command"); 1477 return; 1478 } 1479 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) 1480 { 1481 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ; 1482 if ( mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0; 1483 1484#if (BT_TRACE_VERBOSE == TRUE) 1485 APPL_TRACE_ERROR3("expect op:(%s :0x%04x), receive unexpected operation (%s).", 1486 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event, 1487 bta_gattc_op_code_name[op]); 1488#else 1489 APPL_TRACE_ERROR3("expect op:(%u :0x%04x), receive unexpected operation (%u).", 1490 mapped_op , p_clcb->p_q_cmd->hdr.event, op); 1491#endif 1492 return; 1493 } 1494 1495 /* service handle change void the response, discard it */ 1496 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) 1497 { 1498 p_clcb->auto_update = BTA_GATTC_REQ_WAITING; 1499 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 1500 } 1501 else if (op == GATTC_OPTYPE_READ) 1502 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl); 1503 1504 else if (op == GATTC_OPTYPE_WRITE) 1505 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl); 1506 1507 else if (op == GATTC_OPTYPE_EXE_WRITE) 1508 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl); 1509 1510 else if (op == GATTC_OPTYPE_CONFIG) 1511 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl); 1512 } 1513} 1514/******************************************************************************* 1515** 1516** Function bta_gattc_op_cmpl 1517** 1518** Description operation completed. 1519** 1520** Returns None. 1521** 1522*******************************************************************************/ 1523void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1524{ 1525 UNUSED(p_clcb); 1526 1527 /* receive op complete when discovery is started, ignore the response, 1528 and wait for discovery finish and resent */ 1529 APPL_TRACE_DEBUG1("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific); 1530 1531} 1532/******************************************************************************* 1533** 1534** Function bta_gattc_search 1535** 1536** Description start a search in the local server cache 1537** 1538** Returns None. 1539** 1540*******************************************************************************/ 1541void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1542{ 1543 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR; 1544 tBTA_GATTC cb_data; 1545 APPL_TRACE_DEBUG1("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id); 1546 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) 1547 { 1548 status = BTA_GATT_OK; 1549 /* search the local cache of a server device */ 1550 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid); 1551 } 1552 cb_data.search_cmpl.status = status; 1553 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id; 1554 1555 /* end of search or no server cache available */ 1556 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data); 1557} 1558/******************************************************************************* 1559** 1560** Function bta_gattc_q_cmd 1561** 1562** Description enqueue a command into control block, usually because discovery 1563** operation is busy. 1564** 1565** Returns None. 1566** 1567*******************************************************************************/ 1568void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1569{ 1570 bta_gattc_enqueue(p_clcb, p_data); 1571} 1572/******************************************************************************* 1573** 1574** Function bta_gattc_cache_open 1575** 1576** Description open a NV cache for loading 1577** 1578** Returns void 1579** 1580*******************************************************************************/ 1581void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1582{ 1583 UNUSED(p_data); 1584 1585 bta_gattc_set_discover_st(p_clcb->p_srcb); 1586 1587 APPL_TRACE_DEBUG1("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id); 1588 bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, 1589 p_clcb->bta_conn_id, FALSE); 1590} 1591/******************************************************************************* 1592** 1593** Function bta_gattc_start_load 1594** 1595** Description start cache loading by sending callout open cache 1596** 1597** Returns None. 1598** 1599*******************************************************************************/ 1600void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1601{ 1602 APPL_TRACE_DEBUG2("bta_gattc_ci_open conn_id=%d server state=%d" , 1603 p_clcb->bta_conn_id, p_clcb->p_srcb->state); 1604 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD) 1605 { 1606 if (p_data->ci_open.status == BTA_GATT_OK) 1607 { 1608 p_clcb->p_srcb->attr_index = 0; 1609 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, 1610 BTA_GATTC_CI_CACHE_LOAD_EVT, 1611 p_clcb->p_srcb->attr_index, 1612 p_clcb->bta_conn_id); 1613 } 1614 else 1615 { 1616 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; 1617 /* cache open failure, start discovery */ 1618 bta_gattc_start_discover(p_clcb, NULL); 1619 } 1620 } 1621 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE) 1622 { 1623 if (p_data->ci_open.status == BTA_GATT_OK) 1624 { 1625 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) 1626 { 1627 p_data->ci_open.status = BTA_GATT_ERROR; 1628 } 1629 } 1630 if (p_data->ci_open.status != BTA_GATT_OK) 1631 { 1632 p_clcb->p_srcb->attr_index = 0; 1633 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id); 1634 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); 1635 1636 } 1637 } 1638} 1639/******************************************************************************* 1640** 1641** Function bta_gattc_ci_load 1642** 1643** Description cache loading received. 1644** 1645** Returns None. 1646** 1647*******************************************************************************/ 1648void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1649{ 1650 1651 APPL_TRACE_DEBUG2("bta_gattc_ci_load conn_id=%d load status=%d" , 1652 p_clcb->bta_conn_id, p_data->ci_load.status ); 1653 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); 1654 1655 if ((p_data->ci_load.status == BTA_GATT_OK || 1656 p_data->ci_load.status == BTA_GATT_MORE) && 1657 p_data->ci_load.num_attr > 0) 1658 { 1659 bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, 1660 p_data->ci_load.attr, p_clcb->p_srcb->attr_index); 1661 1662 if (p_data->ci_load.status == BTA_GATT_OK) 1663 { 1664 p_clcb->p_srcb->attr_index = 0; 1665 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); 1666 1667 } 1668 else /* load more */ 1669 { 1670 p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr; 1671 1672 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda, 1673 BTA_GATTC_CI_CACHE_LOAD_EVT, 1674 p_clcb->p_srcb->attr_index, 1675 p_clcb->bta_conn_id); 1676 } 1677 } 1678 else 1679 { 1680 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; 1681 p_clcb->p_srcb->attr_index = 0; 1682 /* cache load failure, start discovery */ 1683 bta_gattc_start_discover(p_clcb, NULL); 1684 } 1685} 1686/******************************************************************************* 1687** 1688** Function bta_gattc_ci_load 1689** 1690** Description cache loading received. 1691** 1692** Returns None. 1693** 1694*******************************************************************************/ 1695void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1696{ 1697 UNUSED(p_data); 1698 1699 APPL_TRACE_DEBUG1("bta_gattc_ci_save conn_id=%d " , 1700 p_clcb->bta_conn_id ); 1701 1702 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id)) 1703 { 1704 p_clcb->p_srcb->attr_index = 0; 1705 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0); 1706 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); 1707 } 1708} 1709/******************************************************************************* 1710** 1711** Function bta_gattc_fail 1712** 1713** Description report API call failure back to apps 1714** 1715** Returns None. 1716** 1717*******************************************************************************/ 1718void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) 1719{ 1720 UNUSED(p_data); 1721 1722 if (p_clcb->status == BTA_GATT_OK) 1723 { 1724 APPL_TRACE_ERROR1("operation not supported at current state [%d]", p_clcb->state); 1725 } 1726} 1727 1728/******************************************************************************* 1729** 1730** Function bta_gattc_deregister_cmpl 1731** 1732** Description De-Register a GATT client application with BTA completed. 1733** 1734** Returns void 1735** 1736*******************************************************************************/ 1737static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) 1738{ 1739 tBTA_GATTC_CB *p_cb = &bta_gattc_cb; 1740 tBTA_GATTC_IF client_if = p_clreg->client_if; 1741 tBTA_GATTC cb_data; 1742 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback; 1743 1744 memset(&cb_data, 0, sizeof(tBTA_GATTC)); 1745 1746 GATT_Deregister(p_clreg->client_if); 1747 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB)); 1748 1749 cb_data.reg_oper.client_if = client_if; 1750 cb_data.reg_oper.status = BTA_GATT_OK; 1751 1752 if (p_cback) 1753 /* callback with de-register event */ 1754 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data); 1755 1756 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) 1757 { 1758 p_cb->state = BTA_GATTC_STATE_DISABLED; 1759 } 1760} 1761/******************************************************************************* 1762** 1763** Function bta_gattc_conn_cback 1764** bta_gattc_cmpl_cback 1765** 1766** Description callback functions to GATT client stack. 1767** 1768** Returns void 1769** 1770*******************************************************************************/ 1771static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, 1772 BOOLEAN connected, tGATT_DISCONN_REASON reason, 1773 tBT_TRANSPORT transport) 1774{ 1775 tBTA_GATTC_DATA *p_buf; 1776 1777 APPL_TRACE_DEBUG4("bta_gattc_conn_cback: cif = %d connected = %d conn_id = %d reaosn = 0x%04x", 1778 gattc_if, connected, conn_id, reason); 1779 1780 if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL) 1781 { 1782 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA)); 1783 1784 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT: 1785 BTA_GATTC_INT_DISCONN_EVT; 1786 p_buf->int_conn.hdr.layer_specific = conn_id; 1787 p_buf->int_conn.client_if = gattc_if; 1788 p_buf->int_conn.role = L2CA_GetBleConnRole(bda); 1789 p_buf->int_conn.reason = reason; 1790 p_buf->int_conn.transport = transport; 1791 bdcpy(p_buf->int_conn.remote_bda, bda); 1792 1793 bta_sys_sendmsg(p_buf); 1794 } 1795 } 1796 1797/******************************************************************************* 1798** 1799** Function bta_gattc_enc_cmpl_cback 1800** 1801** Description encryption complete callback function to GATT client stack. 1802** 1803** Returns void 1804** 1805*******************************************************************************/ 1806static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda) 1807{ 1808 tBTA_GATTC_DATA *p_buf; 1809 tBTA_GATTC_CLCB *p_clcb = NULL; 1810 1811 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) 1812 { 1813 return; 1814 } 1815 1816#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) 1817 /* filter this event just for BTA HH LE GATT client, 1818 In the future, if we want to enable encryption complete event 1819 for all GATT clients, we can remove this code */ 1820 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) 1821 { 1822 return; 1823 } 1824#endif 1825 1826 APPL_TRACE_DEBUG1("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if); 1827 1828 if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL) 1829 { 1830 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA)); 1831 1832 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT; 1833 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id; 1834 p_buf->enc_cmpl.client_if = gattc_if; 1835 bdcpy(p_buf->enc_cmpl.remote_bda, bda); 1836 1837 bta_sys_sendmsg(p_buf); 1838 } 1839} 1840 1841/******************************************************************************* 1842** 1843** Function bta_gattc_process_api_refresh 1844** 1845** Description process refresh API to delete cache and start a new discovery 1846** if currently connected. 1847** 1848** Returns None. 1849** 1850*******************************************************************************/ 1851void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 1852{ 1853 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda); 1854 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0]; 1855 BOOLEAN found = FALSE; 1856 UINT8 i; 1857 UNUSED(p_cb); 1858 1859 if (p_srvc_cb != NULL) 1860 { 1861 /* try to find a CLCB */ 1862 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) 1863 { 1864 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) 1865 { 1866 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) 1867 { 1868 found = TRUE; 1869 break; 1870 } 1871 } 1872 if (found) 1873 { 1874 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 1875 return; 1876 } 1877 } 1878 /* in all other cases, mark it and delete the cache */ 1879 if (p_srvc_cb->p_srvc_cache != NULL) 1880 { 1881 while (p_srvc_cb->cache_buffer.p_first) 1882 GKI_freebuf (GKI_dequeue (&p_srvc_cb->cache_buffer)); 1883 1884 p_srvc_cb->p_srvc_cache = NULL; 1885 } 1886 } 1887 /* used to reset cache in application */ 1888 bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda); 1889 1890} 1891/******************************************************************************* 1892** 1893** Function bta_gattc_process_srvc_chg_ind 1894** 1895** Description process service change indication. 1896** 1897** Returns None. 1898** 1899*******************************************************************************/ 1900BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id, 1901 tBTA_GATTC_RCB *p_clrcb, 1902 tBTA_GATTC_SERV *p_srcb, 1903 tBTA_GATTC_CLCB *p_clcb, 1904 tBTA_GATTC_NOTIFY *p_notify, 1905 UINT16 handle) 1906{ 1907 tBT_UUID gattp_uuid, srvc_chg_uuid; 1908 BOOLEAN processed = FALSE; 1909 UINT8 i; 1910 1911 gattp_uuid.len = 2; 1912 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER; 1913 1914 srvc_chg_uuid.len = 2; 1915 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD; 1916 1917 if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) && 1918 bta_gattc_uuid_compare(&p_notify->char_id.char_id.uuid, &srvc_chg_uuid, TRUE)) 1919 { 1920 processed = TRUE; 1921 /* mark service handle change pending */ 1922 p_srcb->srvc_hdl_chg = TRUE; 1923 /* clear up all notification/indication registration */ 1924 bta_gattc_clear_notif_registration(conn_id); 1925 /* service change indication all received, do discovery update */ 1926 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) 1927 { 1928 /* not an opened connection; or connection busy */ 1929 /* search for first available clcb and start discovery */ 1930 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) 1931 { 1932 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) 1933 { 1934 if (bta_gattc_cb.clcb[i].in_use && 1935 bta_gattc_cb.clcb[i].p_srcb == p_srcb && 1936 bta_gattc_cb.clcb[i].p_q_cmd == NULL) 1937 { 1938 p_clcb = &bta_gattc_cb.clcb[i]; 1939 break; 1940 } 1941 } 1942 } 1943 /* send confirmation here if this is an indication, it should always be */ 1944 GATTC_SendHandleValueConfirm(conn_id, handle); 1945 1946 /* if connection available, refresh cache by doing discovery now */ 1947 if (p_clcb != NULL) 1948 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); 1949 } 1950 /* notify applicationf or service change */ 1951 if (p_clrcb->p_cback != NULL) 1952 { 1953 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda); 1954 } 1955 1956 } 1957 1958 return processed; 1959 1960} 1961/******************************************************************************* 1962** 1963** Function bta_gattc_proc_other_indication 1964** 1965** Description process all non-service change indication/notification. 1966** 1967** Returns None. 1968** 1969*******************************************************************************/ 1970void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op, 1971 tGATT_CL_COMPLETE *p_data, 1972 tBTA_GATTC_NOTIFY *p_notify) 1973{ 1974 APPL_TRACE_DEBUG2("bta_gattc_proc_other_indication check \ 1975 p_data->att_value.handle=%d p_data->handle=%d", 1976 p_data->att_value.handle, p_data->handle); 1977 APPL_TRACE_DEBUG1("is_notify", p_notify->is_notify); 1978 1979 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE; 1980 p_notify->len = p_data->att_value.len; 1981 bdcpy(p_notify->bda, p_clcb->bda); 1982 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len); 1983 p_notify->conn_id = p_clcb->bta_conn_id; 1984 1985 if (p_clcb->p_rcb->p_cback) 1986 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify); 1987 1988} 1989/******************************************************************************* 1990** 1991** Function bta_gattc_process_indicate 1992** 1993** Description process indication/notification. 1994** 1995** Returns None. 1996** 1997*******************************************************************************/ 1998void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data) 1999{ 2000 UINT16 handle = p_data->att_value.handle; 2001 tBTA_GATTC_CLCB *p_clcb ; 2002 tBTA_GATTC_RCB *p_clrcb = NULL; 2003 tBTA_GATTC_SERV *p_srcb = NULL; 2004 tBTA_GATTC_NOTIFY notify; 2005 BD_ADDR remote_bda; 2006 tBTA_GATTC_IF gatt_if; 2007 tBTA_TRANSPORT transport; 2008 2009 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) 2010 { 2011 APPL_TRACE_ERROR0("indication/notif for unknown app"); 2012 return; 2013 } 2014 2015 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) 2016 { 2017 APPL_TRACE_ERROR0("indication/notif for unregistered app"); 2018 return; 2019 } 2020 2021 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) 2022 { 2023 APPL_TRACE_ERROR0("indication/notif for unknown device, ignore"); 2024 return; 2025 } 2026 2027 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); 2028 2029 if (bta_gattc_handle2id(p_srcb, handle, 2030 ¬ify.char_id.srvc_id, 2031 ¬ify.char_id.char_id, 2032 ¬ify.descr_type)) 2033 { 2034 /* if non-service change indication/notification, forward to application */ 2035 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, handle)) 2036 { 2037 /* if app registered for the notification */ 2038 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) 2039 { 2040 /* connection not open yet */ 2041 if (p_clcb == NULL) 2042 { 2043 if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL) 2044 { 2045 p_clcb->bta_conn_id = conn_id; 2046 p_clcb->transport = transport; 2047 2048 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL); 2049 } 2050 else 2051 { 2052 APPL_TRACE_ERROR0("No resources"); 2053 } 2054 } 2055 2056 if (p_clcb != NULL) 2057 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify); 2058 } 2059 /* no one intersted and need ack? */ 2060 else if (op == GATTC_OPTYPE_INDICATION) 2061 { 2062 APPL_TRACE_DEBUG0("no one interested, ack now"); 2063 GATTC_SendHandleValueConfirm(conn_id, handle); 2064 } 2065 } 2066 } 2067 else 2068 { 2069 APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", 2070 handle); 2071 } 2072} 2073/******************************************************************************* 2074** 2075** Function bta_gattc_cmpl_cback 2076** 2077** Description client operation complete callback register with BTE GATT. 2078** 2079** Returns None. 2080** 2081*******************************************************************************/ 2082static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, 2083 tGATT_CL_COMPLETE *p_data) 2084{ 2085 tBTA_GATTC_CLCB *p_clcb ; 2086 tBTA_GATTC_OP_CMPL *p_buf; 2087 UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE); 2088 2089 APPL_TRACE_DEBUG3("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d", 2090 conn_id, op, status); 2091 2092 /* notification and indication processed right away */ 2093 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) 2094 { 2095 bta_gattc_process_indicate(conn_id, op, p_data); 2096 return; 2097 } 2098 /* for all other operation, not expected if w/o connection */ 2099 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) 2100 { 2101 APPL_TRACE_ERROR1("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id); 2102 return; 2103 } 2104 2105 /* if over BR_EDR, inform PM for mode change */ 2106 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) 2107 { 2108 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); 2109 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); 2110 } 2111 2112 if ((p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len)) != NULL) 2113 { 2114 memset(p_buf, 0, len); 2115 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT; 2116 p_buf->hdr.layer_specific = conn_id; 2117 p_buf->status = status; 2118 p_buf->op_code = op; 2119 2120 if (p_data != NULL) 2121 { 2122 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1); 2123 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE)); 2124 } 2125 2126 bta_sys_sendmsg(p_buf); 2127 } 2128 2129 return; 2130} 2131#if BLE_INCLUDED == TRUE 2132/******************************************************************************* 2133** 2134** Function bta_gattc_init_clcb_conn 2135** 2136** Description Initaite a BTA CLCB connection 2137** 2138** Returns void 2139** 2140********************************************************************************/ 2141void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda) 2142{ 2143 tBTA_GATTC_CLCB *p_clcb = NULL; 2144 tBTA_GATTC_DATA gattc_data; 2145 UINT16 conn_id; 2146 2147 /* should always get the connection ID */ 2148 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) 2149 { 2150 APPL_TRACE_ERROR0("bta_gattc_init_clcb_conn ERROR: not a connected device"); 2151 return; 2152 } 2153 2154 /* initaite a new connection here */ 2155 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) 2156 { 2157 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; 2158 2159 gattc_data.api_conn.client_if = cif; 2160 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN); 2161 gattc_data.api_conn.is_direct = TRUE; 2162 2163 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data); 2164 } 2165 else 2166 { 2167 APPL_TRACE_ERROR0("No resources"); 2168 } 2169} 2170/******************************************************************************* 2171** 2172** Function bta_gattc_process_listen_all 2173** 2174** Description process listen all, send open callback to application for all 2175** connected slave LE link. 2176** 2177** Returns void 2178** 2179********************************************************************************/ 2180void bta_gattc_process_listen_all(UINT8 cif) 2181{ 2182 UINT8 i_conn = 0; 2183 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0]; 2184 2185 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) 2186 { 2187 if (p_conn->in_use ) 2188 { 2189 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) 2190 { 2191 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda); 2192 } 2193 /* else already connected */ 2194 } 2195 } 2196} 2197/******************************************************************************* 2198** 2199** Function bta_gattc_listen 2200** 2201** Description Start or stop a listen for connection 2202** 2203** Returns void 2204** 2205********************************************************************************/ 2206void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 2207{ 2208 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if); 2209 tBTA_GATTC cb_data; 2210 UNUSED(p_cb); 2211 2212 cb_data.reg_oper.status = BTA_GATT_ERROR; 2213 cb_data.reg_oper.client_if = p_msg->api_listen.client_if; 2214 2215 if (p_clreg == NULL) 2216 { 2217 APPL_TRACE_ERROR1("bta_gattc_listen failed, unknown client_if: %d", 2218 p_msg->api_listen.client_if); 2219 return; 2220 } 2221 /* mark bg conn record */ 2222 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if, 2223 (BD_ADDR_PTR) p_msg->api_listen.remote_bda, 2224 p_msg->api_listen.start, 2225 TRUE)) 2226 { 2227 if (!GATT_Listen(p_msg->api_listen.client_if, 2228 p_msg->api_listen.start, 2229 p_msg->api_listen.remote_bda)) 2230 { 2231 APPL_TRACE_ERROR0("Listen failure"); 2232 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data); 2233 } 2234 else 2235 { 2236 cb_data.status = BTA_GATT_OK; 2237 2238 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data); 2239 2240 if (p_msg->api_listen.start) 2241 { 2242 /* if listen to a specific target */ 2243 if (p_msg->api_listen.remote_bda != NULL) 2244 { 2245 2246 /* if is a connected remote device */ 2247 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE && 2248 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if, 2249 p_msg->api_listen.remote_bda, 2250 BTA_GATT_TRANSPORT_LE) == NULL) 2251 { 2252 2253 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if, 2254 p_msg->api_listen.remote_bda); 2255 } 2256 } 2257 /* if listen to all */ 2258 else 2259 { 2260 APPL_TRACE_ERROR0("Listen For All now"); 2261 /* go through all connected device and send 2262 callback for all connected slave connection */ 2263 bta_gattc_process_listen_all(p_msg->api_listen.client_if); 2264 } 2265 } 2266 } 2267 } 2268} 2269 2270/******************************************************************************* 2271** 2272** Function bta_gattc_broadcast 2273** 2274** Description Start or stop broadcasting 2275** 2276** Returns void 2277** 2278********************************************************************************/ 2279void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) 2280{ 2281 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if); 2282 tBTA_GATTC cb_data; 2283 UNUSED(p_cb); 2284 2285 cb_data.reg_oper.client_if = p_msg->api_listen.client_if; 2286 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start); 2287 2288 if (p_clreg && p_clreg->p_cback) 2289 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data); 2290} 2291#endif 2292#endif 2293