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