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 #if (GATTC_CACHE_NVS == TRUE)
671 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
672 if (bta_gattc_cache_load(p_clcb)) {
673 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
674 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
677 { /* cache is building */
678 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
679 /* cache load failure, start discovery */
680 bta_gattc_start_discover(p_clcb, NULL);
682 } else { /* cache is building */
683 p_clcb->state = BTA_GATTC_DISCOVER_ST;
686 /* a pending service handle change indication */
687 if (p_clcb->p_srcb->srvc_hdl_chg) {
688 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
689 /* start discovery */
690 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
695 /* there is no RM for GATT */
696 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
697 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
699 tBTA_GATT_STATUS status = BTA_GATT_OK;
700 if (p_data && p_data->int_conn.already_connect) {
701 //clear already_connect
702 p_data->int_conn.already_connect = FALSE;
703 status = BTA_GATT_ALREADY_OPEN;
705 bta_gattc_send_open_cback(p_clcb->p_rcb,
710 p_clcb->p_srcb->mtu);
714 /*******************************************************************************
716 ** Function bta_gattc_conncback
718 ** Description receive connection callback from stack
722 *******************************************************************************/
723 void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
726 bta_gattc_send_connect_cback(p_rcb,
727 p_data->int_conn.remote_bda,
728 p_data->int_conn.hdr.layer_specific);
732 /*******************************************************************************
734 ** Function bta_gattc_disconncback
736 ** Description receive disconnection callback from stack
740 *******************************************************************************/
741 void bta_gattc_disconncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
744 bta_gattc_send_disconnect_cback(p_rcb,
745 p_data->int_conn.reason,
746 p_data->int_conn.remote_bda,
747 p_data->int_conn.hdr.layer_specific);
751 /*******************************************************************************
753 ** Function bta_gattc_close_fail
755 ** Description close a connection.
759 *******************************************************************************/
760 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
764 if ( p_clcb->p_rcb->p_cback ) {
765 memset(&cb_data, 0, sizeof(tBTA_GATTC));
766 cb_data.close.client_if = p_clcb->p_rcb->client_if;
767 cb_data.close.conn_id = p_data->hdr.layer_specific;
768 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
769 cb_data.close.status = BTA_GATT_ERROR;
770 cb_data.close.reason = BTA_GATT_CONN_NONE;
773 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
776 /*******************************************************************************
778 ** Function bta_gattc_api_close
780 ** Description close a GATTC connection.
784 *******************************************************************************/
785 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
787 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
788 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
791 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
793 cb_data.close.client_if = p_clcb->p_rcb->client_if;
794 cb_data.close.conn_id = p_clcb->bta_conn_id;
795 cb_data.close.reason = p_clcb->reason;
796 cb_data.close.status = p_clcb->status;
797 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
799 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
800 bta_sys_conn_close( BTA_ID_GATTC , BTA_ALL_APP_ID, p_clcb->bda);
803 bta_gattc_clcb_dealloc(p_clcb);
805 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
806 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
807 } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
808 cb_data.close.status = BTA_GATT_OK;
809 cb_data.close.reason = p_data->int_conn.reason;
813 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
816 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
817 bta_gattc_deregister_cmpl(p_clreg);
820 /*******************************************************************************
822 ** Function bta_gattc_reset_discover_st
824 ** Description when a SRCB finished discovery, tell all related clcb.
828 *******************************************************************************/
829 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
831 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
834 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
835 if (p_cb->clcb[i].p_srcb == p_srcb) {
836 p_cb->clcb[i].status = status;
837 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
841 /*******************************************************************************
843 ** Function bta_gattc_disc_close
845 ** Description close a GATTC connection while in discovery state.
849 *******************************************************************************/
850 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
852 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
853 p_clcb->bta_conn_id);
855 if (p_clcb->disc_active) {
856 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
858 p_clcb->state = BTA_GATTC_CONN_ST;
861 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
862 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
863 // connection itself still needs to be closed to resolve the original event.
864 if (p_clcb->state == BTA_GATTC_CONN_ST) {
865 APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
866 "Trigger connection close");
867 bta_gattc_close(p_clcb, p_data);
870 /*******************************************************************************
872 ** Function bta_gattc_set_discover_st
874 ** Description when a SRCB start discovery, tell all related clcb and set
879 *******************************************************************************/
880 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
882 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
885 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
886 if (p_cb->clcb[i].p_srcb == p_srcb) {
887 p_cb->clcb[i].status = BTA_GATT_OK;
888 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
892 /*******************************************************************************
894 ** Function bta_gattc_restart_discover
896 ** Description process service change in discovery state, mark up the auto
897 ** update flag and set status to be discovery cancel for current
902 *******************************************************************************/
903 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
907 p_clcb->status = BTA_GATT_CANCEL;
908 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
911 /*******************************************************************************
913 ** Function bta_gattc_cfg_mtu
915 ** Description Configure MTU size on the GATT connection.
919 *******************************************************************************/
920 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
922 tBTA_GATT_STATUS status;
924 if (bta_gattc_enqueue(p_clcb, p_data)) {
925 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id);
927 /* if failed, return callback here */
928 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
929 /* Dequeue the data, if it was enqueued */
930 if (p_clcb->p_q_cmd == p_data) {
931 p_clcb->p_q_cmd = NULL;
932 bta_gattc_pop_command_to_send(p_clcb);
935 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
939 /*******************************************************************************
941 ** Function bta_gattc_start_discover
943 ** Description Start a discovery send to server.
947 *******************************************************************************/
948 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
952 APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
953 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
955 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
956 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
957 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) {
958 /* no pending operation, start discovery right away */
959 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
961 if (p_clcb->p_srcb != NULL) {
962 /* clear the service change mask */
963 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
964 p_clcb->p_srcb->update_count = 0;
965 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
967 if (p_clcb->transport == BTA_TRANSPORT_LE) {
968 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
971 /* set all srcb related clcb into discovery ST */
972 bta_gattc_set_discover_st(p_clcb->p_srcb);
974 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) {
975 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
976 p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
978 if (p_clcb->status != BTA_GATT_OK) {
979 APPL_TRACE_ERROR("discovery on server failed");
980 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
982 p_clcb->disc_active = TRUE;
985 APPL_TRACE_ERROR("unknown device, can not start discovery");
988 /* pending operation, wait until it finishes */
990 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
992 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
993 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
998 /*******************************************************************************
1000 ** Function bta_gattc_disc_cmpl
1002 ** Description discovery on server is finished
1006 *******************************************************************************/
1007 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1009 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1012 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d, status = %d", p_clcb->bta_conn_id, p_clcb->status);
1014 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1015 p_clcb->disc_active = FALSE;
1017 if (p_clcb->status != GATT_SUCCESS) {
1018 /* clean up cache */
1019 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1020 list_free(p_clcb->p_srcb->p_srvc_cache);
1021 p_clcb->p_srcb->p_srvc_cache = NULL;
1023 #if(GATTC_CACHE_NVS == TRUE)
1024 /* used to reset cache in application */
1025 bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
1028 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
1029 /* release pending attribute list buffer */
1030 osi_free(p_clcb->p_srcb->p_srvc_list);
1031 p_clcb->p_srcb->p_srvc_list = NULL;
1032 //osi_free_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
1035 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1036 /* start discovery again */
1037 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1039 /* get any queued command to proceed */
1040 else if (p_q_cmd != NULL) {
1041 p_clcb->p_q_cmd = NULL;
1042 /* execute pending operation of link block still present */
1043 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1044 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1046 /* if the command executed requeued the cmd, we don't
1047 * want to free the underlying buffer that's being
1048 * referenced by p_clcb->p_q_cmd
1050 if (p_q_cmd != p_clcb->p_q_cmd) {
1056 //register service change
1057 bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
1060 /*******************************************************************************
1062 ** Function bta_gattc_read
1064 ** Description Read an attribute
1068 *******************************************************************************/
1069 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1071 if (!bta_gattc_enqueue(p_clcb, p_data))
1074 tGATT_READ_PARAM read_param;
1075 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1076 read_param.by_handle.handle = p_data->api_read.handle;
1077 read_param.by_handle.auth_req = p_data->api_read.auth_req;
1079 tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1082 if (status != BTA_GATT_OK) {
1083 /* Dequeue the data, if it was enqueued */
1084 if (p_clcb->p_q_cmd == p_data) {
1085 p_clcb->p_q_cmd = NULL;
1086 bta_gattc_pop_command_to_send(p_clcb);
1089 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1092 /*******************************************************************************
1094 ** Function bta_gattc_read_multi
1096 ** Description read multiple
1099 *********************************************************************************/
1100 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1102 tBTA_GATT_STATUS status = BTA_GATT_OK;
1103 tGATT_READ_PARAM read_param;
1105 if (bta_gattc_enqueue(p_clcb, p_data)) {
1106 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1108 if (status == BTA_GATT_OK) {
1109 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1110 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1111 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
1112 sizeof(UINT16) * p_data->api_read_multi.num_attr);
1114 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1118 if (status != BTA_GATT_OK) {
1119 /* Dequeue the data, if it was enqueued */
1120 if (p_clcb->p_q_cmd == p_data) {
1121 p_clcb->p_q_cmd = NULL;
1122 bta_gattc_pop_command_to_send(p_clcb);
1125 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1129 /*******************************************************************************
1131 ** Function bta_gattc_write
1133 ** Description Write an attribute
1137 *******************************************************************************/
1138 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1140 if (!bta_gattc_enqueue(p_clcb, p_data))
1143 tBTA_GATT_STATUS status = BTA_GATT_OK;
1146 attr.conn_id = p_clcb->bta_conn_id;
1147 attr.handle = p_data->api_write.handle;
1148 attr.offset = p_data->api_write.offset;
1149 attr.len = p_data->api_write.len;
1150 attr.auth_req = p_data->api_write.auth_req;
1152 if (p_data->api_write.p_value) {
1153 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1156 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1159 if (status != BTA_GATT_OK) {
1160 /* Dequeue the data, if it was enqueued */
1161 if (p_clcb->p_q_cmd == p_data) {
1162 p_clcb->p_q_cmd = NULL;
1163 bta_gattc_pop_command_to_send(p_clcb);
1166 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
1169 /*******************************************************************************
1171 ** Function bta_gattc_execute
1173 ** Description send execute write
1176 *********************************************************************************/
1177 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1179 tBTA_GATT_STATUS status;
1181 if (bta_gattc_enqueue(p_clcb, p_data)) {
1182 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1184 if (status != BTA_GATT_OK) {
1185 /* Dequeue the data, if it was enqueued */
1186 if (p_clcb->p_q_cmd == p_data) {
1187 p_clcb->p_q_cmd = NULL;
1188 bta_gattc_pop_command_to_send(p_clcb);
1191 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
1195 /*******************************************************************************
1197 ** Function bta_gattc_confirm
1199 ** Description send handle value confirmation
1203 *******************************************************************************/
1204 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1206 UINT16 handle = p_data->api_confirm.handle;
1208 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1210 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1212 /* if over BR_EDR, inform PM for mode change */
1213 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1214 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1215 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1219 /*******************************************************************************
1221 ** Function bta_gattc_read_cmpl
1223 ** Description read complete
1227 *******************************************************************************/
1228 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1232 tBTA_GATT_UNFMT read_value;
1234 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1235 memset(&read_value, 0, sizeof(tBTA_GATT_UNFMT));
1237 cb_data.read.status = p_data->status;
1239 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) {
1240 cb_data.read.handle = p_data->p_cmpl->att_value.handle;
1242 read_value.len = p_data->p_cmpl->att_value.len;
1243 read_value.p_value = p_data->p_cmpl->att_value.value;
1244 cb_data.read.p_value = &read_value;
1246 cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle;
1249 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1250 event = p_clcb->p_q_cmd->api_read.cmpl_evt;
1252 event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt;
1254 cb_data.read.conn_id = p_clcb->bta_conn_id;
1255 //free the command data store in the queue.
1256 bta_gattc_free_command_data(p_clcb);
1257 bta_gattc_pop_command_to_send(p_clcb);
1258 /* read complete, callback */
1259 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1262 /*******************************************************************************
1264 ** Function bta_gattc_write_cmpl
1266 ** Description write complete
1270 *******************************************************************************/
1271 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1273 tBTA_GATTC cb_data = {0};
1275 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_clcb->bda);
1277 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1279 cb_data.write.status = p_data->status;
1280 cb_data.write.handle = p_data->p_cmpl->att_value.handle;
1281 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1282 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) {
1283 // Should check the value received from the peer device is correct or not.
1284 if (memcmp(p_clcb->p_q_cmd->api_write.p_value, p_data->p_cmpl->att_value.value,
1285 p_data->p_cmpl->att_value.len) != 0) {
1286 cb_data.write.status = BTA_GATT_INVALID_PDU;
1289 event = BTA_GATTC_PREP_WRITE_EVT;
1291 event = p_clcb->p_q_cmd->api_write.cmpl_evt;
1293 //free the command data store in the queue.
1294 bta_gattc_free_command_data(p_clcb);
1295 bta_gattc_pop_command_to_send(p_clcb);
1296 cb_data.write.conn_id = p_clcb->bta_conn_id;
1297 if (p_conn && p_conn->svc_change_descr_handle == cb_data.write.handle) {
1298 if(cb_data.write.status != BTA_GATT_OK) {
1299 APPL_TRACE_ERROR("service change write ccc failed");
1303 /* write complete, callback */
1304 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1307 /*******************************************************************************
1309 ** Function bta_gattc_exec_cmpl
1311 ** Description execute write complete
1315 *******************************************************************************/
1316 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1319 //free the command data store in the queue.
1320 bta_gattc_free_command_data(p_clcb);
1321 bta_gattc_pop_command_to_send(p_clcb);
1322 p_clcb->status = BTA_GATT_OK;
1324 /* execute complete, callback */
1325 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1326 cb_data.exec_cmpl.status = p_data->status;
1328 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1332 /*******************************************************************************
1334 ** Function bta_gattc_cfg_mtu_cmpl
1336 ** Description configure MTU operation complete
1340 *******************************************************************************/
1341 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1344 //free the command data store in the queue.
1345 bta_gattc_free_command_data(p_clcb);
1346 bta_gattc_pop_command_to_send(p_clcb);
1348 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) {
1349 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1352 /* configure MTU complete, callback */
1353 p_clcb->status = p_data->status;
1354 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1355 cb_data.cfg_mtu.status = p_data->status;
1356 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1358 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data);
1361 /*******************************************************************************
1363 ** Function bta_gattc_op_cmpl
1365 ** Description operation completed.
1369 *******************************************************************************/
1370 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1372 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1373 UINT8 mapped_op = 0;
1375 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1377 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
1378 APPL_TRACE_ERROR("unexpected operation, ignored");
1379 } else if (op >= GATTC_OPTYPE_READ) {
1380 if (p_clcb->p_q_cmd == NULL) {
1381 APPL_TRACE_ERROR("No pending command");
1384 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
1385 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1386 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1387 if ( mapped_op > GATTC_OPTYPE_INDICATION) {
1391 #if (BT_TRACE_VERBOSE == TRUE)
1392 APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1393 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1394 bta_gattc_op_code_name[op]);
1396 APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1397 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1403 /* discard responses if service change indication is received before operation completed */
1404 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg) {
1405 APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1406 p_data->op_cmpl.status = GATT_ERROR;
1409 /* service handle change void the response, discard it */
1410 if (op == GATTC_OPTYPE_READ) {
1411 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1414 else if (op == GATTC_OPTYPE_WRITE) {
1415 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1418 else if (op == GATTC_OPTYPE_EXE_WRITE) {
1419 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1422 else if (op == GATTC_OPTYPE_CONFIG) {
1423 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1426 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1427 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1428 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1432 /*******************************************************************************
1434 ** Function bta_gattc_op_cmpl
1436 ** Description operation completed.
1440 *******************************************************************************/
1441 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1445 /* receive op complete when discovery is started, ignore the response,
1446 and wait for discovery finish and resent */
1447 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1450 /*******************************************************************************
1452 ** Function bta_gattc_search
1454 ** Description start a search in the local server cache
1458 *******************************************************************************/
1459 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1461 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1463 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
1464 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1465 status = BTA_GATT_OK;
1466 /* search the local cache of a server device */
1467 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1469 cb_data.search_cmpl.status = status;
1470 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1472 /* end of search or no server cache available */
1473 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1475 /*******************************************************************************
1477 ** Function bta_gattc_q_cmd
1479 ** Description enqueue a command into control block, usually because discovery
1480 ** operation is busy.
1484 *******************************************************************************/
1485 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1487 bta_gattc_enqueue(p_clcb, p_data);
1489 /*******************************************************************************
1491 ** Function bta_gattc_pop_command_to_send
1493 ** Description dequeue a command into control block.
1494 ** Check if there has command pending in the command queue or not,
1495 ** if there has command pending in the command queue, sent it to the state machine to decision
1496 ** should be sent it to the remote device or not.
1500 *******************************************************************************/
1501 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb)
1503 if (!list_is_empty(p_clcb->p_cmd_list)) {
1504 list_node_t *node = list_begin(p_clcb->p_cmd_list);
1505 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1506 if (p_data != NULL) {
1507 /* execute pending operation of link block still present */
1508 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1509 // The data to be sent to the gattc state machine for processing
1510 if(bta_gattc_sm_execute(p_clcb, p_data->hdr.event, p_data)) {
1511 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1514 if (p_clcb->is_full) {
1515 tBTA_GATTC cb_data = {0};
1516 p_clcb->is_full = FALSE;
1517 cb_data.status = GATT_SUCCESS;
1518 cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
1519 cb_data.queue_full.is_full = FALSE;
1520 if (p_clcb->p_rcb->p_cback != NULL) {
1521 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
1528 /*******************************************************************************
1530 ** Function bta_gattc_free_command_data
1532 ** Description free the command data into control block.
1536 *******************************************************************************/
1537 void bta_gattc_free_command_data(tBTA_GATTC_CLCB *p_clcb)
1539 assert(p_clcb->p_cmd_list);
1540 //Check the list is empty or not.
1541 if (!list_is_empty(p_clcb->p_cmd_list)) {
1542 /* 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
1543 command queue,should remove it from the list */
1544 for (list_node_t *node = list_begin(p_clcb->p_cmd_list); node != list_end(p_clcb->p_cmd_list);
1545 node = list_next(node)) {
1546 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1547 if (p_data == p_clcb->p_q_cmd) {
1548 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1549 p_clcb->p_q_cmd = NULL;
1554 osi_free(p_clcb->p_q_cmd);
1555 p_clcb->p_q_cmd = NULL;
1557 osi_free(p_clcb->p_q_cmd);
1558 p_clcb->p_q_cmd = NULL;
1562 /*******************************************************************************
1564 ** Function bta_gattc_fail
1566 ** Description report API call failure back to apps
1570 *******************************************************************************/
1571 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1575 if (p_clcb->status == BTA_GATT_OK) {
1576 APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1580 /*******************************************************************************
1582 ** Function bta_gattc_deregister_cmpl
1584 ** Description De-Register a GATT client application with BTA completed.
1588 *******************************************************************************/
1589 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1591 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
1592 tBTA_GATTC_IF client_if = p_clreg->client_if;
1594 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
1596 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1598 GATT_Deregister(p_clreg->client_if);
1599 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1601 cb_data.reg_oper.client_if = client_if;
1602 cb_data.reg_oper.status = BTA_GATT_OK;
1605 /* callback with de-register event */
1607 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
1610 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) {
1611 p_cb->state = BTA_GATTC_STATE_DISABLED;
1615 /*******************************************************************************
1617 ** Function bta_gattc_conn_cback
1619 ** Description callback functions to GATT client stack.
1623 *******************************************************************************/
1624 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1625 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1626 tBT_TRANSPORT transport)
1628 tBTA_GATTC_DATA *p_buf;
1631 APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1632 __FUNCTION__, gattc_if, connected, conn_id, reason);
1636 bdcpy(bdaddr.address, bda);
1638 if ((p_buf = (tBTA_GATTC_DATA *) osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1639 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1641 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT :
1642 BTA_GATTC_INT_DISCONN_EVT;
1643 p_buf->int_conn.hdr.layer_specific = conn_id;
1644 p_buf->int_conn.client_if = gattc_if;
1645 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1646 p_buf->int_conn.reason = reason;
1647 p_buf->int_conn.transport = transport;
1648 bdcpy(p_buf->int_conn.remote_bda, bda);
1650 bta_sys_sendmsg(p_buf);
1654 /*******************************************************************************
1656 ** Function bta_gattc_enc_cmpl_cback
1658 ** Description encryption complete callback function to GATT client stack.
1662 *******************************************************************************/
1663 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1665 tBTA_GATTC_DATA *p_buf;
1666 tBTA_GATTC_CLCB *p_clcb = NULL;
1668 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) {
1672 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1673 /* filter this event just for BTA HH LE GATT client,
1674 In the future, if we want to enable encryption complete event
1675 for all GATT clients, we can remove this code */
1676 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
1681 APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1683 if ((p_buf = (tBTA_GATTC_DATA *) osi_calloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1684 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1686 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1687 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1688 p_buf->enc_cmpl.client_if = gattc_if;
1689 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1691 bta_sys_sendmsg(p_buf);
1695 /*******************************************************************************
1697 ** Function bta_gattc_process_api_refresh
1699 ** Description process refresh API to delete cache and start a new discovery
1700 ** if currently connected.
1704 *******************************************************************************/
1705 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1707 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1708 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1709 BOOLEAN found = FALSE;
1713 if (p_srvc_cb != NULL) {
1714 /* try to find a CLCB */
1715 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
1716 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
1717 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
1723 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1727 /* in all other cases, mark it and delete the cache */
1728 if (p_srvc_cb->p_srvc_cache != NULL) {
1729 list_free(p_srvc_cb->p_srvc_cache);
1730 p_srvc_cb->p_srvc_cache = NULL;
1735 void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1737 tBTA_GATTC gattc_cb = {0};
1738 gattc_cb.set_assoc.client_if = p_msg->api_assoc.client_if;
1739 BOOLEAN state = FALSE;
1740 tBTA_GATTC_CLCB *p_assoc_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_assoc.client_if,
1741 p_msg->api_assoc.assoc_addr, BTA_TRANSPORT_LE);
1742 tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_assoc.client_if);
1743 if (p_assoc_clcb != NULL) {
1744 if (p_assoc_clcb->state == BTA_GATTC_CONN_ST || p_assoc_clcb->state == BTA_GATTC_DISCOVER_ST) {
1745 gattc_cb.set_assoc.status = BTA_GATT_BUSY;
1746 if (p_clrcb != NULL) {
1747 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1753 if (p_msg->api_assoc.is_assoc) {
1754 if ((state = bta_gattc_co_cache_append_assoc_addr(p_msg->api_assoc.src_addr, p_msg->api_assoc.assoc_addr)) == TRUE) {
1755 gattc_cb.set_assoc.status = BTA_GATT_OK;
1758 gattc_cb.set_assoc.status = BTA_GATT_ERROR;
1759 if (p_clrcb != NULL) {
1760 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1765 if (( state = bta_gattc_co_cache_remove_assoc_addr(p_msg->api_assoc.src_addr, p_msg->api_assoc.assoc_addr)) == TRUE) {
1766 gattc_cb.set_assoc.status = BTA_GATT_OK;
1768 gattc_cb.set_assoc.status = BTA_GATT_ERROR;
1769 if (p_clrcb != NULL) {
1770 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1776 if (p_clrcb != NULL) {
1777 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1783 void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1785 tBTA_GATTC gattc_cb = {0};
1786 tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_get_addr.client_if);
1787 UINT8 num_addr = bta_gattc_co_get_addr_num();
1788 gattc_cb.get_addr_list.client_if = p_msg->api_get_addr.client_if;
1790 if (num_addr != 0) {
1791 gattc_cb.get_addr_list.num_addr = num_addr;
1792 gattc_cb.get_addr_list.bda_list = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR)*num_addr);
1793 if (gattc_cb.get_addr_list.bda_list != NULL) {
1794 bta_gattc_co_get_addr_list(gattc_cb.get_addr_list.bda_list);
1795 gattc_cb.get_addr_list.status = BTA_GATT_OK;
1797 gattc_cb.get_addr_list.status = BTA_GATT_ERROR;
1800 gattc_cb.get_addr_list.status = BTA_GATT_NOT_FOUND;
1803 if (p_clrcb != NULL) {
1804 (* p_clrcb->p_cback)(BTA_GATTC_GET_ADDR_LIST_EVT, &gattc_cb);
1807 //release the address list buffer after used.
1808 if (gattc_cb.get_addr_list.bda_list != NULL) {
1809 osi_free((void *)gattc_cb.get_addr_list.bda_list);
1813 /*******************************************************************************
1815 ** Function bta_gattc_process_srvc_chg_ind
1817 ** Description process service change indication.
1821 *******************************************************************************/
1822 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1823 tBTA_GATTC_RCB *p_clrcb,
1824 tBTA_GATTC_SERV *p_srcb,
1825 tBTA_GATTC_CLCB *p_clcb,
1826 tBTA_GATTC_NOTIFY *p_notify,
1827 tGATT_VALUE *att_value)
1829 tBT_UUID gattp_uuid, srvc_chg_uuid;
1830 BOOLEAN processed = FALSE;
1834 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1836 srvc_chg_uuid.len = 2;
1837 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1839 const tBTA_GATTC_CHARACTERISTIC *p_char = bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
1840 if (p_char && bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, TRUE) &&
1841 bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, TRUE)) {
1842 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
1843 APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
1847 UINT8 *p = att_value->value;
1848 UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
1849 UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
1851 APPL_TRACE_DEBUG("%s: service changed s_handle:0x%04x e_handle:0x%04x",
1852 __func__, s_handle, e_handle);
1855 /* mark service handle change pending */
1856 p_srcb->srvc_hdl_chg = TRUE;
1857 /* clear up all notification/indication registration */
1858 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
1859 /* service change indication all received, do discovery update */
1860 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
1861 /* not an opened connection; or connection busy */
1862 /* search for first available clcb and start discovery */
1863 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
1864 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) {
1865 if (bta_gattc_cb.clcb[i].in_use &&
1866 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1867 bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
1868 p_clcb = &bta_gattc_cb.clcb[i];
1873 /* send confirmation here if this is an indication, it should always be */
1874 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
1876 /* if connection available, refresh cache by doing discovery now */
1877 if (p_clcb != NULL) {
1878 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1881 /* notify applicationf or service change */
1882 if (p_clrcb->p_cback != NULL) {
1883 tBTA_GATTC_SERVICE_CHANGE srvc_chg= {0};
1884 memcpy(srvc_chg.remote_bda, p_srcb->server_bda, sizeof(BD_ADDR));
1885 srvc_chg.conn_id = conn_id;
1886 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)&srvc_chg);
1894 /*******************************************************************************
1896 ** Function bta_gattc_proc_other_indication
1898 ** Description process all non-service change indication/notification.
1902 *******************************************************************************/
1903 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
1904 tGATT_CL_COMPLETE *p_data,
1905 tBTA_GATTC_NOTIFY *p_notify)
1907 APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check p_data->att_value.handle=%d p_data->handle=%d",
1908 p_data->att_value.handle, p_data->handle);
1909 APPL_TRACE_DEBUG("is_notify %d", p_notify->is_notify);
1911 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
1912 p_notify->len = p_data->att_value.len;
1913 bdcpy(p_notify->bda, p_clcb->bda);
1914 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
1915 p_notify->conn_id = p_clcb->bta_conn_id;
1917 if (p_clcb->p_rcb->p_cback) {
1918 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
1922 /*******************************************************************************
1924 ** Function bta_gattc_process_indicate
1926 ** Description process indication/notification.
1930 *******************************************************************************/
1931 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
1933 UINT16 handle = p_data->att_value.handle;
1934 tBTA_GATTC_CLCB *p_clcb ;
1935 tBTA_GATTC_RCB *p_clrcb = NULL;
1936 tBTA_GATTC_SERV *p_srcb = NULL;
1937 tBTA_GATTC_NOTIFY notify;
1939 tBTA_GATTC_IF gatt_if;
1940 tBTA_TRANSPORT transport;
1942 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
1943 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
1944 if (op == GATTC_OPTYPE_INDICATION) {
1945 GATTC_SendHandleValueConfirm(conn_id, handle);
1950 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) {
1951 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
1952 if (op == GATTC_OPTYPE_INDICATION) {
1953 GATTC_SendHandleValueConfirm(conn_id, handle);
1958 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
1959 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore", __func__);
1960 if (op == GATTC_OPTYPE_INDICATION) {
1961 GATTC_SendHandleValueConfirm(conn_id, handle);
1966 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1968 notify.handle = handle;
1969 /* if non-service change indication/notification, forward to application */
1970 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value)) {
1971 /* if app registered for the notification */
1972 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
1973 /* connection not open yet */
1974 if (p_clcb == NULL) {
1975 p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
1977 if (p_clcb == NULL) {
1978 APPL_TRACE_ERROR("No resources");
1982 p_clcb->bta_conn_id = conn_id;
1983 p_clcb->transport = transport;
1985 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
1988 if (p_clcb != NULL) {
1989 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
1991 } else if (op == GATTC_OPTYPE_INDICATION) {
1992 /* no one intersted and need ack? */
1993 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
1994 GATTC_SendHandleValueConfirm(conn_id, handle);
1998 /*******************************************************************************
2000 ** Function bta_gattc_cmpl_cback
2002 ** Description client operation complete callback register with BTE GATT.
2006 *******************************************************************************/
2007 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
2008 tGATT_CL_COMPLETE *p_data)
2010 tBTA_GATTC_CLCB *p_clcb;
2011 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
2012 conn_id, op, status);
2014 /* notification and indication processed right away */
2015 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
2016 bta_gattc_process_indicate(conn_id, op, p_data);
2019 /* for all other operation, not expected if w/o connection */
2020 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) {
2021 APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
2025 /* if over BR_EDR, inform PM for mode change */
2026 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
2027 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2028 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2031 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
2034 /*******************************************************************************
2036 ** Function bta_gattc_cmpl_sendmsg
2038 ** Description client operation complete send message
2042 *******************************************************************************/
2043 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
2044 tBTA_GATT_STATUS status,
2045 tGATT_CL_COMPLETE *p_data)
2047 const UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
2048 tBTA_GATTC_OP_CMPL *p_buf = (tBTA_GATTC_OP_CMPL *) osi_malloc(len);
2050 if (p_buf != NULL) {
2051 memset(p_buf, 0, len);
2052 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
2053 p_buf->hdr.layer_specific = conn_id;
2054 p_buf->status = status;
2055 p_buf->op_code = op;
2057 if (p_data != NULL) {
2058 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2059 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2062 bta_sys_sendmsg(p_buf);
2066 /*******************************************************************************
2068 ** Function bta_gattc_cong_cback
2070 ** Description congestion callback for BTA GATT client.
2074 ********************************************************************************/
2075 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2077 tBTA_GATTC_CLCB *p_clcb;
2080 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL) {
2081 if (p_clcb->p_rcb->p_cback) {
2082 cb_data.congest.conn_id = conn_id;
2083 cb_data.congest.congested = congested;
2085 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
2090 /*******************************************************************************
2092 ** Function bta_gattc_req_cback
2094 ** Description GATT request command callback for BTA GATT client.
2098 ********************************************************************************/
2099 static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
2101 /* GATTC doesn't need to process the GATT request commands.
2102 * Add this callback here to avoid the warning "Call back not found for application"
2103 * printed in the function gatt_sr_send_req_callback
2111 #if BLE_INCLUDED == TRUE
2112 /*******************************************************************************
2114 ** Function bta_gattc_init_clcb_conn
2116 ** Description Initaite a BTA CLCB connection
2120 ********************************************************************************/
2121 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2123 tBTA_GATTC_CLCB *p_clcb = NULL;
2124 tBTA_GATTC_DATA gattc_data;
2127 /* should always get the connection ID */
2128 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) {
2129 APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2133 /* initaite a new connection here */
2134 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
2135 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2137 gattc_data.api_conn.client_if = cif;
2138 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2139 gattc_data.api_conn.is_direct = TRUE;
2141 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2143 APPL_TRACE_ERROR("No resources");
2146 /*******************************************************************************
2148 ** Function bta_gattc_process_listen_all
2150 ** Description process listen all, send open callback to application for all
2151 ** connected slave LE link.
2155 ********************************************************************************/
2156 void bta_gattc_process_listen_all(UINT8 cif)
2159 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
2161 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
2162 if (p_conn->in_use ) {
2163 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) {
2164 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2166 /* else already connected */
2170 /*******************************************************************************
2172 ** Function bta_gattc_listen
2174 ** Description Start or stop a listen for connection
2178 ********************************************************************************/
2179 void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2181 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2185 cb_data.reg_oper.status = BTA_GATT_ERROR;
2186 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2188 if (p_clreg == NULL) {
2189 APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2190 p_msg->api_listen.client_if);
2193 /* mark bg conn record */
2194 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2195 (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2196 p_msg->api_listen.start,
2198 if (!GATT_Listen(p_msg->api_listen.client_if,
2199 p_msg->api_listen.start,
2200 p_msg->api_listen.remote_bda)) {
2201 APPL_TRACE_ERROR("Listen failure");
2202 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2204 cb_data.status = BTA_GATT_OK;
2206 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2208 if (p_msg->api_listen.start) {
2209 /* if listen to a specific target */
2210 if (p_msg->api_listen.remote_bda != NULL) {
2212 /* if is a connected remote device */
2213 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2214 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2215 p_msg->api_listen.remote_bda,
2216 BTA_GATT_TRANSPORT_LE) == NULL) {
2218 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2219 p_msg->api_listen.remote_bda);
2222 /* if listen to all */
2224 APPL_TRACE_DEBUG("Listen For All now");
2225 /* go through all connected device and send
2226 callback for all connected slave connection */
2227 bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2234 /*******************************************************************************
2236 ** Function bta_gattc_broadcast
2238 ** Description Start or stop broadcasting
2242 ********************************************************************************/
2243 void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2245 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2249 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2250 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
2251 //TODO need modify callback if used
2252 if (p_clreg && p_clreg->p_cback) {
2253 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2257 /*******************************************************************************
2259 ** Function bta_gattc_register_service_change_notify
2261 ** Description Find remote device's gatt service change characteristic ccc's handle and write 2 to this
2264 ** Returns Return result of service change ccc service discovery result
2266 *******************************************************************************/
2267 tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda)
2269 tBTA_GATTC_SERV *p_srcb = NULL;
2270 list_t *p_cache = NULL;
2271 tBTA_GATTC_SERVICE *p_service = NULL;
2272 tBTA_GATTC_CHARACTERISTIC *p_char = NULL;
2273 tBTA_GATTC_DESCRIPTOR *p_desc = NULL;
2274 tBTA_GATTC_FIND_SERVICE_CB result;
2275 BOOLEAN gatt_cache_found = FALSE;
2276 BOOLEAN gatt_service_found = FALSE;
2277 BOOLEAN gatt_service_change_found = FALSE;
2278 BOOLEAN gatt_ccc_found = FALSE;
2280 tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
2281 tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
2282 tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
2284 p_srcb = bta_gattc_find_srcb(remote_bda);
2285 if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
2286 p_cache = p_srcb->p_srvc_cache;
2287 gatt_cache_found = TRUE;
2290 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2292 /* start to find gatt service */
2293 if (gatt_cache_found == TRUE) {
2294 for (list_node_t *sn = list_begin(p_cache);
2295 sn != list_end(p_cache); sn = list_next(sn)) {
2296 p_service = list_node(sn);
2297 if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_service->uuid, TRUE)) {
2298 gatt_service_found = TRUE;
2304 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2307 /* start to find gatt service change characteristic */
2308 if (gatt_service_found == TRUE) {
2309 if (p_service->characteristics) {
2310 for (list_node_t *cn = list_begin(p_service->characteristics);
2311 cn != list_end(p_service->characteristics); cn = list_next(cn)) {
2312 p_char = list_node(cn);
2313 if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_char->uuid, TRUE)) {
2314 gatt_service_change_found = TRUE;
2320 else if (gatt_cache_found == TRUE) {
2321 /* Gatt service not found, start a timer to wait for service discovery */
2322 result = SERVICE_CHANGE_SERVICE_NOT_FOUND;
2324 /* start to find gatt service change characteristic ccc */
2325 if (gatt_service_change_found == TRUE) {
2326 if (p_char->descriptors) {
2327 for (list_node_t *dn = list_begin(p_char->descriptors);
2328 dn != list_end(p_char->descriptors); dn = list_next(dn)) {
2329 p_desc = list_node(dn);
2330 if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_desc->uuid, TRUE)) {
2331 gatt_ccc_found = TRUE;
2337 else if (gatt_service_found ==TRUE) {
2338 /* Gatt service found, but service change char not found,
2339 * Case1: remote device doesn't have service change char, we don't need to start a timer here to
2340 * wait for service discovery
2341 * Case2: remote device exist service change char, we have found gatt service, but have not found
2342 * service change char, we need to start a timer here*/
2343 result = SERVICE_CHANGE_CHAR_NOT_FOUND;
2346 if (gatt_ccc_found == TRUE){
2347 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
2349 p_conn->svc_change_descr_handle = p_desc->handle;
2351 result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
2352 uint16_t indicate_value = GATT_CLT_CONFIG_INDICATION;
2353 tBTA_GATT_UNFMT indicate_v;
2355 indicate_v.p_value = (uint8_t *)&indicate_value;
2356 BTA_GATTC_WriteCharDescr (conn_id, p_desc->handle, BTA_GATTC_TYPE_WRITE, &indicate_v, BTA_GATT_AUTH_REQ_NONE);
2359 else if (gatt_service_change_found == TRUE) {
2360 /* Gatt service char found, but service change char ccc not found,
2361 * Case1: remote device doesn't have service change char ccc, we don't need to start a timer here to
2362 * wait for service discovery
2363 * Case2: remote device exist service change char ccc, we have found gatt service change char, but have not found
2364 * service change char ccc, we need to start a timer here */
2365 result = SERVICE_CHANGE_CCC_NOT_FOUND;
2372 #endif ///GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE