1 /******************************************************************************
3 * Copyright (C) 2003-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains the GATT client action functions for the state
24 ******************************************************************************/
25 #define LOG_TAG "bt_bta_gattc"
27 #include "common/bt_target.h"
30 #include "bta/bta_sys.h"
32 #include "bta_gattc_int.h"
33 #include "stack/l2c_api.h"
36 #include "osi/allocator.h"
37 #include "osi/mutex.h"
39 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
40 #include "bta_hh_int.h"
43 // #include "btif/include/btif_debug_conn.h"
47 // #include "osi/include/log.h"
49 #if GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE
51 /*****************************************************************************
53 *****************************************************************************/
54 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
55 BOOLEAN connected, tGATT_DISCONN_REASON reason,
56 tBT_TRANSPORT transport);
58 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
59 tGATT_CL_COMPLETE *p_data);
60 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
61 tBTA_GATT_STATUS status,
62 tGATT_CL_COMPLETE *p_data);
63 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
65 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
66 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
67 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
68 static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
69 static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda);
71 static tGATT_CBACK bta_gattc_cl_cback = {
74 bta_gattc_disc_res_cback,
75 bta_gattc_disc_cmpl_cback,
77 bta_gattc_enc_cmpl_cback,
81 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
82 static UINT16 bta_gattc_opcode_to_int_evt[] = {
83 BTA_GATTC_API_READ_EVT,
84 BTA_GATTC_API_WRITE_EVT,
85 BTA_GATTC_API_EXEC_EVT,
86 BTA_GATTC_API_CFG_MTU_EVT,
87 BTA_GATTC_API_READ_MULTI_EVT
90 #if (BT_TRACE_VERBOSE == TRUE)
91 static const char *bta_gattc_op_code_name[] = {
102 /*****************************************************************************
104 *****************************************************************************/
107 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status);
109 /*******************************************************************************
111 ** Function bta_gattc_enable
113 ** Description Enables GATTC module
118 *******************************************************************************/
119 static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
121 APPL_TRACE_DEBUG("bta_gattc_enable");
123 if (p_cb->state == BTA_GATTC_STATE_DISABLED) {
124 /* initialize control block */
125 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
126 p_cb->state = BTA_GATTC_STATE_ENABLED;
128 APPL_TRACE_DEBUG("GATTC is already enabled");
133 /*******************************************************************************
135 ** Function bta_gattc_disable
137 ** Description Disable GATTC module by cleaning up all active connections
138 ** and deregister all application.
142 *******************************************************************************/
143 void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
147 APPL_TRACE_DEBUG("bta_gattc_disable");
149 if (p_cb->state != BTA_GATTC_STATE_ENABLED) {
150 APPL_TRACE_ERROR("not enabled or disable in pogress");
154 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
155 if (p_cb->cl_rcb[i].in_use) {
156 p_cb->state = BTA_GATTC_STATE_DISABLING;
157 /* don't deregister HH GATT IF */
158 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
159 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
160 if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) {
162 bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
163 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
169 /* no registered apps, indicate disable completed */
170 if (p_cb->state != BTA_GATTC_STATE_DISABLING) {
171 p_cb->state = BTA_GATTC_STATE_DISABLED;
172 memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
176 /*******************************************************************************
178 ** Function bta_gattc_register
180 ** Description Register a GATT client application with BTA.
184 *******************************************************************************/
185 void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
189 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
190 tBTA_GATTC_INT_START_IF *p_buf;
191 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
194 APPL_TRACE_DEBUG("bta_gattc_register state %d\n", p_cb->state);
195 memset(&cb_data, 0, sizeof(cb_data));
196 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
198 /* check if GATTC module is already enabled . Else enable */
199 if (p_cb->state == BTA_GATTC_STATE_DISABLED) {
200 bta_gattc_enable (p_cb);
202 /* todo need to check duplicate uuid */
203 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
204 if (!p_cb->cl_rcb[i].in_use) {
205 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) {
206 APPL_TRACE_ERROR("Register with GATT stack failed.\n");
207 status = BTA_GATT_ERROR;
209 p_cb->cl_rcb[i].in_use = TRUE;
210 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
211 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
213 /* BTA use the same client interface as BTE GATT statck */
214 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
216 if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) {
217 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
218 p_buf->client_if = p_cb->cl_rcb[i].client_if;
219 APPL_TRACE_DEBUG("GATTC getbuf sucess.\n");
220 bta_sys_sendmsg(p_buf);
221 status = BTA_GATT_OK;
223 GATT_Deregister(p_cb->cl_rcb[i].client_if);
225 status = BTA_GATT_NO_RESOURCES;
226 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
233 /* callback with register event */
234 if (p_data->api_reg.p_cback) {
235 if (p_app_uuid != NULL) {
236 memcpy(&(cb_data.reg_oper.app_uuid), p_app_uuid, sizeof(tBT_UUID));
238 cb_data.reg_oper.status = status;
239 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data);
242 /*******************************************************************************
244 ** Function bta_gattc_start_if
246 ** Description start an application interface.
250 *******************************************************************************/
251 void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
255 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) != NULL ) {
256 GATT_StartIf(p_msg->int_start_if.client_if);
258 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d", p_msg->int_start_if.client_if );
262 /*******************************************************************************
264 ** Function bta_gattc_deregister
266 ** Description De-Register a GATT client application with BTA.
270 *******************************************************************************/
271 void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg)
276 if (p_clreg != NULL) {
277 /* remove bg connection associated with this rcb */
278 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++) {
279 if (p_cb->bg_track[i].in_use) {
280 if (p_cb->bg_track[i].cif_mask & (1 << (p_clreg->client_if - 1))) {
281 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE);
282 GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
284 if (p_cb->bg_track[i].cif_adv_mask & (1 << (p_clreg->client_if - 1))) {
285 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
290 if (p_clreg->num_clcb > 0) {
291 /* close all CLCB related to this app */
292 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
293 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg)) {
294 p_clreg->dereg_pending = TRUE;
296 buf.event = BTA_GATTC_API_CLOSE_EVT;
297 buf.layer_specific = p_cb->clcb[i].bta_conn_id;
298 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ;
302 bta_gattc_deregister_cmpl(p_clreg);
305 APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
308 /*******************************************************************************
310 ** Function bta_gattc_process_api_open
312 ** Description process connect API request.
316 *******************************************************************************/
317 void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
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);
324 if (p_clreg != NULL) {
325 if (p_msg->api_conn.is_direct) {
326 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
327 p_msg->api_conn.remote_bda,
328 p_msg->api_conn.transport)) != NULL) {
329 bta_gattc_sm_execute(p_clcb, event, p_msg);
331 APPL_TRACE_ERROR("No resources to open a new connection.");
333 bta_gattc_send_open_cback(p_clreg,
334 BTA_GATT_NO_RESOURCES,
335 p_msg->api_conn.remote_bda,
336 BTA_GATT_INVALID_CONN_ID,
337 p_msg->api_conn.transport, 0);
340 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
343 APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
344 p_msg->api_conn.client_if);
347 /*******************************************************************************
349 ** Function bta_gattc_process_api_open_cancel
351 ** Description process connect API request.
355 *******************************************************************************/
356 void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
358 UINT16 event = ((BT_HDR *)p_msg)->event;
359 tBTA_GATTC_CLCB *p_clcb = NULL;
360 tBTA_GATTC_RCB *p_clreg;
364 if (p_msg->api_cancel_conn.is_direct) {
365 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
366 p_msg->api_cancel_conn.remote_bda,
367 BTA_GATT_TRANSPORT_LE)) != NULL) {
368 bta_gattc_sm_execute(p_clcb, event, p_msg);
370 APPL_TRACE_ERROR("No such connection need to be cancelled");
372 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
374 if (p_clreg && p_clreg->p_cback) {
375 cb_data.status = BTA_GATT_ERROR;
376 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
380 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
385 /*******************************************************************************
387 ** Function bta_gattc_process_enc_cmpl
389 ** Description process encryption complete message.
393 *******************************************************************************/
394 void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
396 tBTA_GATTC_RCB *p_clreg;
400 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
402 if (p_clreg && p_clreg->p_cback) {
403 memset(&cb_data, 0, sizeof(tBTA_GATTC));
405 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
406 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
408 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
412 /*******************************************************************************
414 ** Function bta_gattc_cancel_open_error
420 *******************************************************************************/
421 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
426 cb_data.status = BTA_GATT_ERROR;
428 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback ) {
429 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
433 /*******************************************************************************
435 ** Function bta_gattc_open_error
441 *******************************************************************************/
442 void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
446 APPL_TRACE_ERROR("Connection already opened. wrong state");
448 bta_gattc_send_open_cback(p_clcb->p_rcb,
455 /*******************************************************************************
457 ** Function bta_gattc_open_fail
463 *******************************************************************************/
464 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
468 bta_gattc_send_open_cback(p_clcb->p_rcb,
474 /* open failure, remove clcb */
475 bta_gattc_clcb_dealloc(p_clcb);
478 /*******************************************************************************
480 ** Function bta_gattc_open
482 ** Description Process API connection function.
486 *******************************************************************************/
487 void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
489 tBTA_GATTC_DATA gattc_data;
490 BOOLEAN found_app = FALSE;
492 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(p_data->api_conn.remote_bda, BT_TRANSPORT_LE);
493 if(p_tcb && p_clcb && p_data) {
494 found_app = gatt_find_specific_app_in_hold_link(p_tcb, p_clcb->p_rcb->client_if);
496 /* open/hold a connection */
497 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, p_data->api_conn.remote_addr_type,
498 TRUE, p_data->api_conn.transport)) {
499 APPL_TRACE_ERROR("Connection open failure");
501 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
503 /* a connected remote device */
504 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
505 p_data->api_conn.remote_bda,
506 &p_clcb->bta_conn_id,
507 p_data->api_conn.transport)) {
508 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
509 gattc_data.int_conn.already_connect = found_app;
510 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
512 /* else wait for the callback event */
515 /*******************************************************************************
517 ** Function bta_gattc_init_bk_conn
519 ** Description Process API Open for a background connection
523 *******************************************************************************/
524 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
526 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
528 tBTA_GATTC_CLCB *p_clcb;
529 tBTA_GATTC_DATA gattc_data;
531 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) {
532 /* always call open to hold a connection */
533 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, p_data->remote_addr_type, FALSE, p_data->transport)) {
534 uint8_t *bda = (uint8_t *)p_data->remote_bda;
535 status = BTA_GATT_ERROR;
536 APPL_TRACE_ERROR("%s unable to connect to remote bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
537 __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
540 status = BTA_GATT_OK;
542 /* if is a connected remote device */
543 if (GATT_GetConnIdIfConnected(p_data->client_if,
546 p_data->transport)) {
547 if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
548 BTA_GATT_TRANSPORT_LE)) != NULL) {
549 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
551 /* open connection */
552 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
553 status = BTA_GATT_OK;
559 /* open failure, report OPEN_EVT */
560 if (status != BTA_GATT_OK) {
561 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
562 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
565 /*******************************************************************************
567 ** Function bta_gattc_cancel_bk_conn
569 ** Description Process API Cancel Open for a background connection
573 *******************************************************************************/
574 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
576 tBTA_GATTC_RCB *p_clreg;
578 cb_data.status = BTA_GATT_ERROR;
580 /* remove the device from the bg connection mask */
581 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE)) {
582 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE)) {
583 cb_data.status = BTA_GATT_OK;
585 APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
588 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
590 if (p_clreg && p_clreg->p_cback) {
591 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
595 /*******************************************************************************
597 ** Function bta_gattc_int_cancel_open_ok
603 *******************************************************************************/
604 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
609 if ( p_clcb->p_rcb->p_cback ) {
610 cb_data.status = BTA_GATT_OK;
611 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
614 bta_gattc_clcb_dealloc(p_clcb);
616 /*******************************************************************************
618 ** Function bta_gattc_cancel_open
624 *******************************************************************************/
625 void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
629 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE)) {
630 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
632 if ( p_clcb->p_rcb->p_cback ) {
633 cb_data.status = BTA_GATT_ERROR;
634 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
638 /*******************************************************************************
640 ** Function bta_gattc_conn
642 ** Description receive connection callback from stack
646 *******************************************************************************/
647 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
649 tBTA_GATTC_IF gatt_if;
650 APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d", p_clcb->p_srcb->state);
652 if (p_data != NULL) {
653 APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d", p_data->hdr.layer_specific);
654 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
656 GATT_GetConnectionInfor(p_data->hdr.layer_specific,
657 &gatt_if, p_clcb->bda, &p_clcb->transport);
660 p_clcb->p_srcb->connected = TRUE;
662 if (p_clcb->p_srcb->mtu == 0) {
663 p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
666 /* start database cache if needed */
667 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
668 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
669 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
670 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
671 if (bta_gattc_cache_load(p_clcb)) {
672 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
673 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
674 } else { /* cache is building */
675 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
676 /* cache load failure, start discovery */
677 bta_gattc_start_discover(p_clcb, NULL);
679 } else { /* cache is building */
680 p_clcb->state = BTA_GATTC_DISCOVER_ST;
683 /* a pending service handle change indication */
684 if (p_clcb->p_srcb->srvc_hdl_chg) {
685 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
686 /* start discovery */
687 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
692 /* there is no RM for GATT */
693 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
694 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
696 tBTA_GATT_STATUS status = BTA_GATT_OK;
697 if (p_data && p_data->int_conn.already_connect) {
698 //clear already_connect
699 p_data->int_conn.already_connect = FALSE;
700 status = BTA_GATT_ALREADY_OPEN;
702 bta_gattc_send_open_cback(p_clcb->p_rcb,
707 p_clcb->p_srcb->mtu);
711 /*******************************************************************************
713 ** Function bta_gattc_conncback
715 ** Description receive connection callback from stack
719 *******************************************************************************/
720 void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
723 bta_gattc_send_connect_cback(p_rcb,
724 p_data->int_conn.remote_bda,
725 p_data->int_conn.hdr.layer_specific);
729 /*******************************************************************************
731 ** Function bta_gattc_disconncback
733 ** Description receive disconnection callback from stack
737 *******************************************************************************/
738 void bta_gattc_disconncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
741 bta_gattc_send_disconnect_cback(p_rcb,
742 p_data->int_conn.reason,
743 p_data->int_conn.remote_bda,
744 p_data->int_conn.hdr.layer_specific);
748 /*******************************************************************************
750 ** Function bta_gattc_close_fail
752 ** Description close a connection.
756 *******************************************************************************/
757 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
761 if ( p_clcb->p_rcb->p_cback ) {
762 memset(&cb_data, 0, sizeof(tBTA_GATTC));
763 cb_data.close.client_if = p_clcb->p_rcb->client_if;
764 cb_data.close.conn_id = p_data->hdr.layer_specific;
765 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
766 cb_data.close.status = BTA_GATT_ERROR;
767 cb_data.close.reason = BTA_GATT_CONN_NONE;
770 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
773 /*******************************************************************************
775 ** Function bta_gattc_api_close
777 ** Description close a GATTC connection.
781 *******************************************************************************/
782 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
784 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
785 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
788 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
790 cb_data.close.client_if = p_clcb->p_rcb->client_if;
791 cb_data.close.conn_id = p_clcb->bta_conn_id;
792 cb_data.close.reason = p_clcb->reason;
793 cb_data.close.status = p_clcb->status;
794 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
796 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
797 bta_sys_conn_close( BTA_ID_GATTC , BTA_ALL_APP_ID, p_clcb->bda);
800 bta_gattc_clcb_dealloc(p_clcb);
802 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
803 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
804 } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
805 cb_data.close.status = BTA_GATT_OK;
806 cb_data.close.reason = p_data->int_conn.reason;
810 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
813 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
814 bta_gattc_deregister_cmpl(p_clreg);
817 /*******************************************************************************
819 ** Function bta_gattc_reset_discover_st
821 ** Description when a SRCB finished discovery, tell all related clcb.
825 *******************************************************************************/
826 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
828 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
831 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
832 if (p_cb->clcb[i].p_srcb == p_srcb) {
833 p_cb->clcb[i].status = status;
834 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
838 /*******************************************************************************
840 ** Function bta_gattc_disc_close
842 ** Description close a GATTC connection while in discovery state.
846 *******************************************************************************/
847 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
849 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
850 p_clcb->bta_conn_id);
852 if (p_clcb->disc_active) {
853 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
855 p_clcb->state = BTA_GATTC_CONN_ST;
858 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
859 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
860 // connection itself still needs to be closed to resolve the original event.
861 if (p_clcb->state == BTA_GATTC_CONN_ST) {
862 APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
863 "Trigger connection close");
864 bta_gattc_close(p_clcb, p_data);
867 /*******************************************************************************
869 ** Function bta_gattc_set_discover_st
871 ** Description when a SRCB start discovery, tell all related clcb and set
876 *******************************************************************************/
877 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
879 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
882 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
883 if (p_cb->clcb[i].p_srcb == p_srcb) {
884 p_cb->clcb[i].status = BTA_GATT_OK;
885 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
889 /*******************************************************************************
891 ** Function bta_gattc_restart_discover
893 ** Description process service change in discovery state, mark up the auto
894 ** update flag and set status to be discovery cancel for current
899 *******************************************************************************/
900 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
904 p_clcb->status = BTA_GATT_CANCEL;
905 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
908 /*******************************************************************************
910 ** Function bta_gattc_cfg_mtu
912 ** Description Configure MTU size on the GATT connection.
916 *******************************************************************************/
917 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
919 tBTA_GATT_STATUS status;
921 if (bta_gattc_enqueue(p_clcb, p_data)) {
922 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id);
924 /* if failed, return callback here */
925 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
926 /* Dequeue the data, if it was enqueued */
927 if (p_clcb->p_q_cmd == p_data) {
928 p_clcb->p_q_cmd = NULL;
929 bta_gattc_pop_command_to_send(p_clcb);
932 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
936 /*******************************************************************************
938 ** Function bta_gattc_start_discover
940 ** Description Start a discovery send to server.
944 *******************************************************************************/
945 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
949 APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
950 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
952 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
953 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
954 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) {
955 /* no pending operation, start discovery right away */
956 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
958 if (p_clcb->p_srcb != NULL) {
959 /* clear the service change mask */
960 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
961 p_clcb->p_srcb->update_count = 0;
962 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
964 if (p_clcb->transport == BTA_TRANSPORT_LE) {
965 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
968 /* set all srcb related clcb into discovery ST */
969 bta_gattc_set_discover_st(p_clcb->p_srcb);
971 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) {
972 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
973 p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
975 if (p_clcb->status != BTA_GATT_OK) {
976 APPL_TRACE_ERROR("discovery on server failed");
977 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
979 p_clcb->disc_active = TRUE;
982 APPL_TRACE_ERROR("unknown device, can not start discovery");
985 /* pending operation, wait until it finishes */
987 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
989 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
990 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
995 /*******************************************************************************
997 ** Function bta_gattc_disc_cmpl
999 ** Description discovery on server is finished
1003 *******************************************************************************/
1004 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1006 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1009 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d, status = %d", p_clcb->bta_conn_id, p_clcb->status);
1011 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1012 p_clcb->disc_active = FALSE;
1014 if (p_clcb->status != GATT_SUCCESS) {
1015 /* clean up cache */
1016 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1017 list_free(p_clcb->p_srcb->p_srvc_cache);
1018 p_clcb->p_srcb->p_srvc_cache = NULL;
1021 /* used to reset cache in application */
1022 bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
1024 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
1025 /* release pending attribute list buffer */
1026 osi_free(p_clcb->p_srcb->p_srvc_list);
1027 p_clcb->p_srcb->p_srvc_list = NULL;
1028 //osi_free_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
1031 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1032 /* start discovery again */
1033 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1035 /* get any queued command to proceed */
1036 else if (p_q_cmd != NULL) {
1037 p_clcb->p_q_cmd = NULL;
1038 /* execute pending operation of link block still present */
1039 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1040 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1042 /* if the command executed requeued the cmd, we don't
1043 * want to free the underlying buffer that's being
1044 * referenced by p_clcb->p_q_cmd
1046 if (p_q_cmd != p_clcb->p_q_cmd) {
1052 //register service change
1053 bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
1056 /*******************************************************************************
1058 ** Function bta_gattc_read
1060 ** Description Read an attribute
1064 *******************************************************************************/
1065 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1067 if (!bta_gattc_enqueue(p_clcb, p_data))
1070 tGATT_READ_PARAM read_param;
1071 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1072 read_param.by_handle.handle = p_data->api_read.handle;
1073 read_param.by_handle.auth_req = p_data->api_read.auth_req;
1075 tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1078 if (status != BTA_GATT_OK) {
1079 /* Dequeue the data, if it was enqueued */
1080 if (p_clcb->p_q_cmd == p_data) {
1081 p_clcb->p_q_cmd = NULL;
1082 bta_gattc_pop_command_to_send(p_clcb);
1085 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1088 /*******************************************************************************
1090 ** Function bta_gattc_read_multi
1092 ** Description read multiple
1095 *********************************************************************************/
1096 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1098 tBTA_GATT_STATUS status = BTA_GATT_OK;
1099 tGATT_READ_PARAM read_param;
1101 if (bta_gattc_enqueue(p_clcb, p_data)) {
1102 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1104 if (status == BTA_GATT_OK) {
1105 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1106 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1107 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
1108 sizeof(UINT16) * p_data->api_read_multi.num_attr);
1110 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1114 if (status != BTA_GATT_OK) {
1115 /* Dequeue the data, if it was enqueued */
1116 if (p_clcb->p_q_cmd == p_data) {
1117 p_clcb->p_q_cmd = NULL;
1118 bta_gattc_pop_command_to_send(p_clcb);
1121 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1125 /*******************************************************************************
1127 ** Function bta_gattc_write
1129 ** Description Write an attribute
1133 *******************************************************************************/
1134 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1136 if (!bta_gattc_enqueue(p_clcb, p_data))
1139 tBTA_GATT_STATUS status = BTA_GATT_OK;
1142 attr.conn_id = p_clcb->bta_conn_id;
1143 attr.handle = p_data->api_write.handle;
1144 attr.offset = p_data->api_write.offset;
1145 attr.len = p_data->api_write.len;
1146 attr.auth_req = p_data->api_write.auth_req;
1148 if (p_data->api_write.p_value) {
1149 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1152 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1155 if (status != BTA_GATT_OK) {
1156 /* Dequeue the data, if it was enqueued */
1157 if (p_clcb->p_q_cmd == p_data) {
1158 p_clcb->p_q_cmd = NULL;
1159 bta_gattc_pop_command_to_send(p_clcb);
1162 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
1165 /*******************************************************************************
1167 ** Function bta_gattc_execute
1169 ** Description send execute write
1172 *********************************************************************************/
1173 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1175 tBTA_GATT_STATUS status;
1177 if (bta_gattc_enqueue(p_clcb, p_data)) {
1178 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1180 if (status != BTA_GATT_OK) {
1181 /* Dequeue the data, if it was enqueued */
1182 if (p_clcb->p_q_cmd == p_data) {
1183 p_clcb->p_q_cmd = NULL;
1184 bta_gattc_pop_command_to_send(p_clcb);
1187 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
1191 /*******************************************************************************
1193 ** Function bta_gattc_confirm
1195 ** Description send handle value confirmation
1199 *******************************************************************************/
1200 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1202 UINT16 handle = p_data->api_confirm.handle;
1204 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1206 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1208 /* if over BR_EDR, inform PM for mode change */
1209 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1210 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1211 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1215 /*******************************************************************************
1217 ** Function bta_gattc_read_cmpl
1219 ** Description read complete
1223 *******************************************************************************/
1224 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1228 tBTA_GATT_UNFMT read_value;
1230 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1231 memset(&read_value, 0, sizeof(tBTA_GATT_UNFMT));
1233 cb_data.read.status = p_data->status;
1235 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) {
1236 cb_data.read.handle = p_data->p_cmpl->att_value.handle;
1238 read_value.len = p_data->p_cmpl->att_value.len;
1239 read_value.p_value = p_data->p_cmpl->att_value.value;
1240 cb_data.read.p_value = &read_value;
1242 cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle;
1245 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1246 event = p_clcb->p_q_cmd->api_read.cmpl_evt;
1248 event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt;
1250 cb_data.read.conn_id = p_clcb->bta_conn_id;
1251 //free the command data store in the queue.
1252 bta_gattc_free_command_data(p_clcb);
1253 bta_gattc_pop_command_to_send(p_clcb);
1254 /* read complete, callback */
1255 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1258 /*******************************************************************************
1260 ** Function bta_gattc_write_cmpl
1262 ** Description write complete
1266 *******************************************************************************/
1267 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1269 tBTA_GATTC cb_data = {0};
1271 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_clcb->bda);
1273 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1275 cb_data.write.status = p_data->status;
1276 cb_data.write.handle = p_data->p_cmpl->att_value.handle;
1277 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1278 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) {
1279 // Should check the value received from the peer device is correct or not.
1280 if (memcmp(p_clcb->p_q_cmd->api_write.p_value, p_data->p_cmpl->att_value.value,
1281 p_data->p_cmpl->att_value.len) != 0) {
1282 cb_data.write.status = BTA_GATT_INVALID_PDU;
1285 event = BTA_GATTC_PREP_WRITE_EVT;
1287 event = p_clcb->p_q_cmd->api_write.cmpl_evt;
1289 //free the command data store in the queue.
1290 bta_gattc_free_command_data(p_clcb);
1291 bta_gattc_pop_command_to_send(p_clcb);
1292 cb_data.write.conn_id = p_clcb->bta_conn_id;
1293 if (p_conn && p_conn->svc_change_descr_handle == cb_data.write.handle) {
1294 if(cb_data.write.status != BTA_GATT_OK) {
1295 APPL_TRACE_ERROR("service change write ccc failed");
1299 /* write complete, callback */
1300 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1303 /*******************************************************************************
1305 ** Function bta_gattc_exec_cmpl
1307 ** Description execute write complete
1311 *******************************************************************************/
1312 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1315 //free the command data store in the queue.
1316 bta_gattc_free_command_data(p_clcb);
1317 bta_gattc_pop_command_to_send(p_clcb);
1318 p_clcb->status = BTA_GATT_OK;
1320 /* execute complete, callback */
1321 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1322 cb_data.exec_cmpl.status = p_data->status;
1324 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1328 /*******************************************************************************
1330 ** Function bta_gattc_cfg_mtu_cmpl
1332 ** Description configure MTU operation complete
1336 *******************************************************************************/
1337 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1340 //free the command data store in the queue.
1341 bta_gattc_free_command_data(p_clcb);
1342 bta_gattc_pop_command_to_send(p_clcb);
1344 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) {
1345 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1348 /* configure MTU complete, callback */
1349 p_clcb->status = p_data->status;
1350 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1351 cb_data.cfg_mtu.status = p_data->status;
1352 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1354 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data);
1357 /*******************************************************************************
1359 ** Function bta_gattc_op_cmpl
1361 ** Description operation completed.
1365 *******************************************************************************/
1366 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1368 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1369 UINT8 mapped_op = 0;
1371 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1373 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
1374 APPL_TRACE_ERROR("unexpected operation, ignored");
1375 } else if (op >= GATTC_OPTYPE_READ) {
1376 if (p_clcb->p_q_cmd == NULL) {
1377 APPL_TRACE_ERROR("No pending command");
1380 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
1381 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1382 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1383 if ( mapped_op > GATTC_OPTYPE_INDICATION) {
1387 #if (BT_TRACE_VERBOSE == TRUE)
1388 APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1389 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1390 bta_gattc_op_code_name[op]);
1392 APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1393 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1399 /* discard responses if service change indication is received before operation completed */
1400 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg) {
1401 APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1402 p_data->op_cmpl.status = GATT_ERROR;
1405 /* service handle change void the response, discard it */
1406 if (op == GATTC_OPTYPE_READ) {
1407 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1410 else if (op == GATTC_OPTYPE_WRITE) {
1411 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1414 else if (op == GATTC_OPTYPE_EXE_WRITE) {
1415 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1418 else if (op == GATTC_OPTYPE_CONFIG) {
1419 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1422 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1423 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1424 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1428 /*******************************************************************************
1430 ** Function bta_gattc_op_cmpl
1432 ** Description operation completed.
1436 *******************************************************************************/
1437 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1441 /* receive op complete when discovery is started, ignore the response,
1442 and wait for discovery finish and resent */
1443 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1446 /*******************************************************************************
1448 ** Function bta_gattc_search
1450 ** Description start a search in the local server cache
1454 *******************************************************************************/
1455 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1457 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1459 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
1460 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1461 status = BTA_GATT_OK;
1462 /* search the local cache of a server device */
1463 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1465 cb_data.search_cmpl.status = status;
1466 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1468 /* end of search or no server cache available */
1469 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1471 /*******************************************************************************
1473 ** Function bta_gattc_q_cmd
1475 ** Description enqueue a command into control block, usually because discovery
1476 ** operation is busy.
1480 *******************************************************************************/
1481 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1483 bta_gattc_enqueue(p_clcb, p_data);
1485 /*******************************************************************************
1487 ** Function bta_gattc_pop_command_to_send
1489 ** Description dequeue a command into control block.
1490 ** Check if there has command pending in the command queue or not,
1491 ** if there has command pending in the command queue, sent it to the state machine to decision
1492 ** should be sent it to the remote device or not.
1496 *******************************************************************************/
1497 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb)
1499 if (!list_is_empty(p_clcb->p_cmd_list)) {
1500 list_node_t *node = list_begin(p_clcb->p_cmd_list);
1501 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1502 if (p_data != NULL) {
1503 /* execute pending operation of link block still present */
1504 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1505 // The data to be sent to the gattc state machine for processing
1506 if(bta_gattc_sm_execute(p_clcb, p_data->hdr.event, p_data)) {
1507 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1510 if (p_clcb->is_full) {
1511 tBTA_GATTC cb_data = {0};
1512 p_clcb->is_full = FALSE;
1513 cb_data.status = GATT_SUCCESS;
1514 cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
1515 cb_data.queue_full.is_full = FALSE;
1516 if (p_clcb->p_rcb->p_cback != NULL) {
1517 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
1524 /*******************************************************************************
1526 ** Function bta_gattc_free_command_data
1528 ** Description free the command data into control block.
1532 *******************************************************************************/
1533 void bta_gattc_free_command_data(tBTA_GATTC_CLCB *p_clcb)
1535 assert(p_clcb->p_cmd_list);
1536 //Check the list is empty or not.
1537 if (!list_is_empty(p_clcb->p_cmd_list)) {
1538 /* Traversal the command queue, check the p_q_cmd is point to the queue data or not, if the p_q_cmd point to the
1539 command queue,should remove it from the list */
1540 for (list_node_t *node = list_begin(p_clcb->p_cmd_list); node != list_end(p_clcb->p_cmd_list);
1541 node = list_next(node)) {
1542 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1543 if (p_data == p_clcb->p_q_cmd) {
1544 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1545 p_clcb->p_q_cmd = NULL;
1550 osi_free(p_clcb->p_q_cmd);
1551 p_clcb->p_q_cmd = NULL;
1553 osi_free(p_clcb->p_q_cmd);
1554 p_clcb->p_q_cmd = NULL;
1558 /*******************************************************************************
1560 ** Function bta_gattc_fail
1562 ** Description report API call failure back to apps
1566 *******************************************************************************/
1567 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1571 if (p_clcb->status == BTA_GATT_OK) {
1572 APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1576 /*******************************************************************************
1578 ** Function bta_gattc_deregister_cmpl
1580 ** Description De-Register a GATT client application with BTA completed.
1584 *******************************************************************************/
1585 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1587 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
1588 tBTA_GATTC_IF client_if = p_clreg->client_if;
1590 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
1592 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1594 GATT_Deregister(p_clreg->client_if);
1595 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1597 cb_data.reg_oper.client_if = client_if;
1598 cb_data.reg_oper.status = BTA_GATT_OK;
1601 /* callback with de-register event */
1603 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
1606 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) {
1607 p_cb->state = BTA_GATTC_STATE_DISABLED;
1611 /*******************************************************************************
1613 ** Function bta_gattc_conn_cback
1615 ** Description callback functions to GATT client stack.
1619 *******************************************************************************/
1620 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1621 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1622 tBT_TRANSPORT transport)
1624 tBTA_GATTC_DATA *p_buf;
1627 APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1628 __FUNCTION__, gattc_if, connected, conn_id, reason);
1632 bdcpy(bdaddr.address, bda);
1634 if ((p_buf = (tBTA_GATTC_DATA *) osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1635 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1637 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT :
1638 BTA_GATTC_INT_DISCONN_EVT;
1639 p_buf->int_conn.hdr.layer_specific = conn_id;
1640 p_buf->int_conn.client_if = gattc_if;
1641 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1642 p_buf->int_conn.reason = reason;
1643 p_buf->int_conn.transport = transport;
1644 bdcpy(p_buf->int_conn.remote_bda, bda);
1646 bta_sys_sendmsg(p_buf);
1650 /*******************************************************************************
1652 ** Function bta_gattc_enc_cmpl_cback
1654 ** Description encryption complete callback function to GATT client stack.
1658 *******************************************************************************/
1659 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1661 tBTA_GATTC_DATA *p_buf;
1662 tBTA_GATTC_CLCB *p_clcb = NULL;
1664 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) {
1668 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1669 /* filter this event just for BTA HH LE GATT client,
1670 In the future, if we want to enable encryption complete event
1671 for all GATT clients, we can remove this code */
1672 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
1677 APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1679 if ((p_buf = (tBTA_GATTC_DATA *) osi_calloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1680 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1682 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1683 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1684 p_buf->enc_cmpl.client_if = gattc_if;
1685 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1687 bta_sys_sendmsg(p_buf);
1691 /*******************************************************************************
1693 ** Function bta_gattc_process_api_refresh
1695 ** Description process refresh API to delete cache and start a new discovery
1696 ** if currently connected.
1700 *******************************************************************************/
1701 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1703 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1704 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1705 BOOLEAN found = FALSE;
1709 if (p_srvc_cb != NULL) {
1710 /* try to find a CLCB */
1711 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
1712 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
1713 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
1719 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1720 bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
1724 /* in all other cases, mark it and delete the cache */
1725 if (p_srvc_cb->p_srvc_cache != NULL) {
1726 list_free(p_srvc_cb->p_srvc_cache);
1727 p_srvc_cb->p_srvc_cache = NULL;
1730 /* used to reset cache in application */
1731 bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
1734 void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1736 tBTA_GATTC gattc_cb = {0};
1737 gattc_cb.set_assoc.client_if = p_msg->api_assoc.client_if;
1738 BOOLEAN state = FALSE;
1739 tBTA_GATTC_CLCB *p_assoc_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_assoc.client_if,
1740 p_msg->api_assoc.assoc_addr, BTA_TRANSPORT_LE);
1741 tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_assoc.client_if);
1742 if (p_assoc_clcb != NULL) {
1743 if (p_assoc_clcb->state == BTA_GATTC_CONN_ST || p_assoc_clcb->state == BTA_GATTC_DISCOVER_ST) {
1744 gattc_cb.set_assoc.status = BTA_GATT_BUSY;
1745 if (p_clrcb != NULL) {
1746 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1752 if (p_msg->api_assoc.is_assoc) {
1753 if ((state = bta_gattc_co_cache_append_assoc_addr(p_msg->api_assoc.src_addr, p_msg->api_assoc.assoc_addr)) == TRUE) {
1754 gattc_cb.set_assoc.status = BTA_GATT_OK;
1757 gattc_cb.set_assoc.status = BTA_GATT_ERROR;
1758 if (p_clrcb != NULL) {
1759 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1764 if (( state = bta_gattc_co_cache_remove_assoc_addr(p_msg->api_assoc.src_addr, p_msg->api_assoc.assoc_addr)) == TRUE) {
1765 gattc_cb.set_assoc.status = BTA_GATT_OK;
1767 gattc_cb.set_assoc.status = BTA_GATT_ERROR;
1768 if (p_clrcb != NULL) {
1769 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1775 if (p_clrcb != NULL) {
1776 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1782 void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1784 tBTA_GATTC gattc_cb = {0};
1785 tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_get_addr.client_if);
1786 UINT8 num_addr = bta_gattc_co_get_addr_num();
1787 gattc_cb.get_addr_list.client_if = p_msg->api_get_addr.client_if;
1789 if (num_addr != 0) {
1790 gattc_cb.get_addr_list.num_addr = num_addr;
1791 gattc_cb.get_addr_list.bda_list = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR)*num_addr);
1792 if (gattc_cb.get_addr_list.bda_list != NULL) {
1793 bta_gattc_co_get_addr_list(gattc_cb.get_addr_list.bda_list);
1794 gattc_cb.get_addr_list.status = BTA_GATT_OK;
1796 gattc_cb.get_addr_list.status = BTA_GATT_ERROR;
1799 gattc_cb.get_addr_list.status = BTA_GATT_NOT_FOUND;
1802 if (p_clrcb != NULL) {
1803 (* p_clrcb->p_cback)(BTA_GATTC_GET_ADDR_LIST_EVT, &gattc_cb);
1806 //release the address list buffer after used.
1807 if (gattc_cb.get_addr_list.bda_list != NULL) {
1808 osi_free((void *)gattc_cb.get_addr_list.bda_list);
1812 /*******************************************************************************
1814 ** Function bta_gattc_process_srvc_chg_ind
1816 ** Description process service change indication.
1820 *******************************************************************************/
1821 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1822 tBTA_GATTC_RCB *p_clrcb,
1823 tBTA_GATTC_SERV *p_srcb,
1824 tBTA_GATTC_CLCB *p_clcb,
1825 tBTA_GATTC_NOTIFY *p_notify,
1826 tGATT_VALUE *att_value)
1828 tBT_UUID gattp_uuid, srvc_chg_uuid;
1829 BOOLEAN processed = FALSE;
1833 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1835 srvc_chg_uuid.len = 2;
1836 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1838 const tBTA_GATTC_CHARACTERISTIC *p_char = bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
1839 if (p_char && bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, TRUE) &&
1840 bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, TRUE)) {
1841 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
1842 APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
1846 UINT8 *p = att_value->value;
1847 UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
1848 UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
1850 APPL_TRACE_DEBUG("%s: service changed s_handle:0x%04x e_handle:0x%04x",
1851 __func__, s_handle, e_handle);
1854 /* mark service handle change pending */
1855 p_srcb->srvc_hdl_chg = TRUE;
1856 /* clear up all notification/indication registration */
1857 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
1858 /* service change indication all received, do discovery update */
1859 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
1860 /* not an opened connection; or connection busy */
1861 /* search for first available clcb and start discovery */
1862 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
1863 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) {
1864 if (bta_gattc_cb.clcb[i].in_use &&
1865 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1866 bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
1867 p_clcb = &bta_gattc_cb.clcb[i];
1872 /* send confirmation here if this is an indication, it should always be */
1873 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
1875 /* if connection available, refresh cache by doing discovery now */
1876 if (p_clcb != NULL) {
1877 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1880 /* notify applicationf or service change */
1881 if (p_clrcb->p_cback != NULL) {
1882 tBTA_GATTC_SERVICE_CHANGE srvc_chg= {0};
1883 memcpy(srvc_chg.remote_bda, p_srcb->server_bda, sizeof(BD_ADDR));
1884 srvc_chg.conn_id = conn_id;
1885 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)&srvc_chg);
1893 /*******************************************************************************
1895 ** Function bta_gattc_proc_other_indication
1897 ** Description process all non-service change indication/notification.
1901 *******************************************************************************/
1902 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
1903 tGATT_CL_COMPLETE *p_data,
1904 tBTA_GATTC_NOTIFY *p_notify)
1906 APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check p_data->att_value.handle=%d p_data->handle=%d",
1907 p_data->att_value.handle, p_data->handle);
1908 APPL_TRACE_DEBUG("is_notify %d", p_notify->is_notify);
1910 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
1911 p_notify->len = p_data->att_value.len;
1912 bdcpy(p_notify->bda, p_clcb->bda);
1913 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
1914 p_notify->conn_id = p_clcb->bta_conn_id;
1916 if (p_clcb->p_rcb->p_cback) {
1917 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
1921 /*******************************************************************************
1923 ** Function bta_gattc_process_indicate
1925 ** Description process indication/notification.
1929 *******************************************************************************/
1930 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
1932 UINT16 handle = p_data->att_value.handle;
1933 tBTA_GATTC_CLCB *p_clcb ;
1934 tBTA_GATTC_RCB *p_clrcb = NULL;
1935 tBTA_GATTC_SERV *p_srcb = NULL;
1936 tBTA_GATTC_NOTIFY notify;
1938 tBTA_GATTC_IF gatt_if;
1939 tBTA_TRANSPORT transport;
1941 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
1942 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
1943 if (op == GATTC_OPTYPE_INDICATION) {
1944 GATTC_SendHandleValueConfirm(conn_id, handle);
1949 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) {
1950 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
1951 if (op == GATTC_OPTYPE_INDICATION) {
1952 GATTC_SendHandleValueConfirm(conn_id, handle);
1957 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
1958 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore", __func__);
1959 if (op == GATTC_OPTYPE_INDICATION) {
1960 GATTC_SendHandleValueConfirm(conn_id, handle);
1965 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1967 notify.handle = handle;
1968 /* if non-service change indication/notification, forward to application */
1969 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value)) {
1970 /* if app registered for the notification */
1971 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
1972 /* connection not open yet */
1973 if (p_clcb == NULL) {
1974 p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
1976 if (p_clcb == NULL) {
1977 APPL_TRACE_ERROR("No resources");
1981 p_clcb->bta_conn_id = conn_id;
1982 p_clcb->transport = transport;
1984 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
1987 if (p_clcb != NULL) {
1988 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
1990 } else if (op == GATTC_OPTYPE_INDICATION) {
1991 /* no one intersted and need ack? */
1992 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
1993 GATTC_SendHandleValueConfirm(conn_id, handle);
1997 /*******************************************************************************
1999 ** Function bta_gattc_cmpl_cback
2001 ** Description client operation complete callback register with BTE GATT.
2005 *******************************************************************************/
2006 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
2007 tGATT_CL_COMPLETE *p_data)
2009 tBTA_GATTC_CLCB *p_clcb;
2010 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
2011 conn_id, op, status);
2013 /* notification and indication processed right away */
2014 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
2015 bta_gattc_process_indicate(conn_id, op, p_data);
2018 /* for all other operation, not expected if w/o connection */
2019 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) {
2020 APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
2024 /* if over BR_EDR, inform PM for mode change */
2025 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
2026 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2027 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2030 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
2033 /*******************************************************************************
2035 ** Function bta_gattc_cmpl_sendmsg
2037 ** Description client operation complete send message
2041 *******************************************************************************/
2042 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
2043 tBTA_GATT_STATUS status,
2044 tGATT_CL_COMPLETE *p_data)
2046 const UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
2047 tBTA_GATTC_OP_CMPL *p_buf = (tBTA_GATTC_OP_CMPL *) osi_malloc(len);
2049 if (p_buf != NULL) {
2050 memset(p_buf, 0, len);
2051 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
2052 p_buf->hdr.layer_specific = conn_id;
2053 p_buf->status = status;
2054 p_buf->op_code = op;
2056 if (p_data != NULL) {
2057 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2058 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2061 bta_sys_sendmsg(p_buf);
2065 /*******************************************************************************
2067 ** Function bta_gattc_cong_cback
2069 ** Description congestion callback for BTA GATT client.
2073 ********************************************************************************/
2074 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2076 tBTA_GATTC_CLCB *p_clcb;
2079 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL) {
2080 if (p_clcb->p_rcb->p_cback) {
2081 cb_data.congest.conn_id = conn_id;
2082 cb_data.congest.congested = congested;
2084 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
2089 /*******************************************************************************
2091 ** Function bta_gattc_req_cback
2093 ** Description GATT request command callback for BTA GATT client.
2097 ********************************************************************************/
2098 static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
2100 /* GATTC doesn't need to process the GATT request commands.
2101 * Add this callback here to avoid the warning "Call back not found for application"
2102 * printed in the function gatt_sr_send_req_callback
2110 #if BLE_INCLUDED == TRUE
2111 /*******************************************************************************
2113 ** Function bta_gattc_init_clcb_conn
2115 ** Description Initaite a BTA CLCB connection
2119 ********************************************************************************/
2120 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2122 tBTA_GATTC_CLCB *p_clcb = NULL;
2123 tBTA_GATTC_DATA gattc_data;
2126 /* should always get the connection ID */
2127 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) {
2128 APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2132 /* initaite a new connection here */
2133 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
2134 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2136 gattc_data.api_conn.client_if = cif;
2137 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2138 gattc_data.api_conn.is_direct = TRUE;
2140 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2142 APPL_TRACE_ERROR("No resources");
2145 /*******************************************************************************
2147 ** Function bta_gattc_process_listen_all
2149 ** Description process listen all, send open callback to application for all
2150 ** connected slave LE link.
2154 ********************************************************************************/
2155 void bta_gattc_process_listen_all(UINT8 cif)
2158 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
2160 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
2161 if (p_conn->in_use ) {
2162 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) {
2163 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2165 /* else already connected */
2169 /*******************************************************************************
2171 ** Function bta_gattc_listen
2173 ** Description Start or stop a listen for connection
2177 ********************************************************************************/
2178 void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2180 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2184 cb_data.reg_oper.status = BTA_GATT_ERROR;
2185 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2187 if (p_clreg == NULL) {
2188 APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2189 p_msg->api_listen.client_if);
2192 /* mark bg conn record */
2193 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2194 (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2195 p_msg->api_listen.start,
2197 if (!GATT_Listen(p_msg->api_listen.client_if,
2198 p_msg->api_listen.start,
2199 p_msg->api_listen.remote_bda)) {
2200 APPL_TRACE_ERROR("Listen failure");
2201 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2203 cb_data.status = BTA_GATT_OK;
2205 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2207 if (p_msg->api_listen.start) {
2208 /* if listen to a specific target */
2209 if (p_msg->api_listen.remote_bda != NULL) {
2211 /* if is a connected remote device */
2212 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2213 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2214 p_msg->api_listen.remote_bda,
2215 BTA_GATT_TRANSPORT_LE) == NULL) {
2217 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2218 p_msg->api_listen.remote_bda);
2221 /* if listen to all */
2223 APPL_TRACE_DEBUG("Listen For All now");
2224 /* go through all connected device and send
2225 callback for all connected slave connection */
2226 bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2233 /*******************************************************************************
2235 ** Function bta_gattc_broadcast
2237 ** Description Start or stop broadcasting
2241 ********************************************************************************/
2242 void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2244 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2248 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2249 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
2250 //TODO need modify callback if used
2251 if (p_clreg && p_clreg->p_cback) {
2252 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2256 /*******************************************************************************
2258 ** Function bta_gattc_register_service_change_notify
2260 ** Description Find remote device's gatt service change characteristic ccc's handle and write 2 to this
2263 ** Returns Return result of service change ccc service discovery result
2265 *******************************************************************************/
2266 tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda)
2268 tBTA_GATTC_SERV *p_srcb = NULL;
2269 list_t *p_cache = NULL;
2270 tBTA_GATTC_SERVICE *p_service = NULL;
2271 tBTA_GATTC_CHARACTERISTIC *p_char = NULL;
2272 tBTA_GATTC_DESCRIPTOR *p_desc = NULL;
2273 tBTA_GATTC_FIND_SERVICE_CB result;
2274 BOOLEAN gatt_cache_found = FALSE;
2275 BOOLEAN gatt_service_found = FALSE;
2276 BOOLEAN gatt_service_change_found = FALSE;
2277 BOOLEAN gatt_ccc_found = FALSE;
2279 tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
2280 tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
2281 tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
2283 p_srcb = bta_gattc_find_srcb(remote_bda);
2284 if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
2285 p_cache = p_srcb->p_srvc_cache;
2286 gatt_cache_found = TRUE;
2289 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2291 /* start to find gatt service */
2292 if (gatt_cache_found == TRUE) {
2293 for (list_node_t *sn = list_begin(p_cache);
2294 sn != list_end(p_cache); sn = list_next(sn)) {
2295 p_service = list_node(sn);
2296 if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_service->uuid, TRUE)) {
2297 gatt_service_found = TRUE;
2303 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2306 /* start to find gatt service change characteristic */
2307 if (gatt_service_found == TRUE) {
2308 if (p_service->characteristics) {
2309 for (list_node_t *cn = list_begin(p_service->characteristics);
2310 cn != list_end(p_service->characteristics); cn = list_next(cn)) {
2311 p_char = list_node(cn);
2312 if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_char->uuid, TRUE)) {
2313 gatt_service_change_found = TRUE;
2319 else if (gatt_cache_found == TRUE) {
2320 /* Gatt service not found, start a timer to wait for service discovery */
2321 result = SERVICE_CHANGE_SERVICE_NOT_FOUND;
2323 /* start to find gatt service change characteristic ccc */
2324 if (gatt_service_change_found == TRUE) {
2325 if (p_char->descriptors) {
2326 for (list_node_t *dn = list_begin(p_char->descriptors);
2327 dn != list_end(p_char->descriptors); dn = list_next(dn)) {
2328 p_desc = list_node(dn);
2329 if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_desc->uuid, TRUE)) {
2330 gatt_ccc_found = TRUE;
2336 else if (gatt_service_found ==TRUE) {
2337 /* Gatt service found, but service change char not found,
2338 * Case1: remote device doesn't have service change char, we don't need to start a timer here to
2339 * wait for service discovery
2340 * Case2: remote device exist service change char, we have found gatt service, but have not found
2341 * service change char, we need to start a timer here*/
2342 result = SERVICE_CHANGE_CHAR_NOT_FOUND;
2345 if (gatt_ccc_found == TRUE){
2346 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
2348 p_conn->svc_change_descr_handle = p_desc->handle;
2350 result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
2351 uint16_t indicate_value = GATT_CLT_CONFIG_INDICATION;
2352 tBTA_GATT_UNFMT indicate_v;
2354 indicate_v.p_value = (uint8_t *)&indicate_value;
2355 BTA_GATTC_WriteCharDescr (conn_id, p_desc->handle, BTA_GATTC_TYPE_WRITE, &indicate_v, BTA_GATT_AUTH_REQ_NONE);
2358 else if (gatt_service_change_found == TRUE) {
2359 /* Gatt service char found, but service change char ccc not found,
2360 * Case1: remote device doesn't have service change char ccc, we don't need to start a timer here to
2361 * wait for service discovery
2362 * Case2: remote device exist service change char ccc, we have found gatt service change char, but have not found
2363 * service change char ccc, we need to start a timer here */
2364 result = SERVICE_CHANGE_CCC_NOT_FOUND;
2371 #endif ///GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE