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