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