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 "bt_target.h"
32 #include "bta_gattc_int.h"
36 #include "allocator.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 static osi_mutex_t write_ccc_mutex;
53 /*****************************************************************************
55 *****************************************************************************/
56 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
57 BOOLEAN connected, tGATT_DISCONN_REASON reason,
58 tBT_TRANSPORT transport);
60 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
61 tGATT_CL_COMPLETE *p_data);
62 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
63 tBTA_GATT_STATUS status,
64 tGATT_CL_COMPLETE *p_data);
65 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
67 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
68 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
69 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
70 static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda, BOOLEAN *need_timer);
71 static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle);
72 static void bta_gattc_start_service_change_ccc_timer(UINT16 conn_id, BD_ADDR bda,UINT32 timeout_ms,
73 UINT8 timer_cnt, UINT8 last_status, TIMER_LIST_ENT *ccc_timer);
75 static tGATT_CBACK bta_gattc_cl_cback = {
78 bta_gattc_disc_res_cback,
79 bta_gattc_disc_cmpl_cback,
81 bta_gattc_enc_cmpl_cback,
85 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
86 static UINT16 bta_gattc_opcode_to_int_evt[] = {
87 BTA_GATTC_API_READ_EVT,
88 BTA_GATTC_API_WRITE_EVT,
89 BTA_GATTC_API_EXEC_EVT,
90 BTA_GATTC_API_CFG_MTU_EVT,
91 BTA_GATTC_API_READ_MULTI_EVT
94 #if (BT_TRACE_VERBOSE == TRUE)
95 static const char *bta_gattc_op_code_name[] = {
106 /*****************************************************************************
108 *****************************************************************************/
111 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status);
113 /*******************************************************************************
115 ** Function bta_gattc_enable
117 ** Description Enables GATTC module
122 *******************************************************************************/
123 static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
125 APPL_TRACE_DEBUG("bta_gattc_enable");
127 if (p_cb->state == BTA_GATTC_STATE_DISABLED) {
128 /* initialize control block */
129 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
130 p_cb->state = BTA_GATTC_STATE_ENABLED;
131 // Create a write ccc mutex when the gatt client enable
132 osi_mutex_new(&write_ccc_mutex);
134 APPL_TRACE_DEBUG("GATTC is arelady enabled");
139 /*******************************************************************************
141 ** Function bta_gattc_disable
143 ** Description Disable GATTC module by cleaning up all active connections
144 ** and deregister all application.
148 *******************************************************************************/
149 void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
153 APPL_TRACE_DEBUG("bta_gattc_disable");
155 if (p_cb->state != BTA_GATTC_STATE_ENABLED) {
156 APPL_TRACE_ERROR("not enabled or disable in pogress");
159 // Free the write ccc mutex when the gatt client disable
160 osi_mutex_free(&write_ccc_mutex);
162 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
163 if (p_cb->cl_rcb[i].in_use) {
164 p_cb->state = BTA_GATTC_STATE_DISABLING;
165 /* don't deregister HH GATT IF */
166 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
167 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
168 if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) {
170 bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
171 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
177 /* no registered apps, indicate disable completed */
178 if (p_cb->state != BTA_GATTC_STATE_DISABLING) {
179 p_cb->state = BTA_GATTC_STATE_DISABLED;
180 memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
184 /*******************************************************************************
186 ** Function bta_gattc_register
188 ** Description Register a GATT client application with BTA.
192 *******************************************************************************/
193 void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
197 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
198 tBTA_GATTC_INT_START_IF *p_buf;
199 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
202 APPL_TRACE_DEBUG("bta_gattc_register state %d\n", p_cb->state);
203 memset(&cb_data, 0, sizeof(cb_data));
204 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
206 /* check if GATTC module is already enabled . Else enable */
207 if (p_cb->state == BTA_GATTC_STATE_DISABLED) {
208 bta_gattc_enable (p_cb);
210 /* todo need to check duplicate uuid */
211 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
212 if (!p_cb->cl_rcb[i].in_use) {
213 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) {
214 APPL_TRACE_ERROR("Register with GATT stack failed.\n");
215 status = BTA_GATT_ERROR;
217 p_cb->cl_rcb[i].in_use = TRUE;
218 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
219 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
221 /* BTA use the same client interface as BTE GATT statck */
222 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
224 if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) {
225 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
226 p_buf->client_if = p_cb->cl_rcb[i].client_if;
227 APPL_TRACE_DEBUG("GATTC getbuf sucess.\n");
228 bta_sys_sendmsg(p_buf);
229 status = BTA_GATT_OK;
231 GATT_Deregister(p_cb->cl_rcb[i].client_if);
233 status = BTA_GATT_NO_RESOURCES;
234 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
241 /* callback with register event */
242 if (p_data->api_reg.p_cback) {
243 if (p_app_uuid != NULL) {
244 memcpy(&(cb_data.reg_oper.app_uuid), p_app_uuid, sizeof(tBT_UUID));
246 cb_data.reg_oper.status = status;
247 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data);
250 /*******************************************************************************
252 ** Function bta_gattc_start_if
254 ** Description start an application interface.
258 *******************************************************************************/
259 void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
263 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) != NULL ) {
264 GATT_StartIf(p_msg->int_start_if.client_if);
266 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d", p_msg->int_start_if.client_if );
270 /*******************************************************************************
272 ** Function bta_gattc_deregister
274 ** Description De-Register a GATT client application with BTA.
278 *******************************************************************************/
279 void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg)
284 if (p_clreg != NULL) {
285 /* remove bg connection associated with this rcb */
286 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++) {
287 if (p_cb->bg_track[i].in_use) {
288 if (p_cb->bg_track[i].cif_mask & (1 << (p_clreg->client_if - 1))) {
289 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE);
290 GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
292 if (p_cb->bg_track[i].cif_adv_mask & (1 << (p_clreg->client_if - 1))) {
293 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
298 if (p_clreg->num_clcb > 0) {
299 /* close all CLCB related to this app */
300 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
301 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg)) {
302 p_clreg->dereg_pending = TRUE;
304 buf.event = BTA_GATTC_API_CLOSE_EVT;
305 buf.layer_specific = p_cb->clcb[i].bta_conn_id;
306 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ;
310 bta_gattc_deregister_cmpl(p_clreg);
313 APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
316 /*******************************************************************************
318 ** Function bta_gattc_process_api_open
320 ** Description process connect API request.
324 *******************************************************************************/
325 void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
327 UINT16 event = ((BT_HDR *)p_msg)->event;
328 tBTA_GATTC_CLCB *p_clcb = NULL;
329 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
332 if (p_clreg != NULL) {
333 if (p_msg->api_conn.is_direct) {
334 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
335 p_msg->api_conn.remote_bda,
336 p_msg->api_conn.transport)) != NULL) {
337 bta_gattc_sm_execute(p_clcb, event, p_msg);
339 APPL_TRACE_ERROR("No resources to open a new connection.");
341 bta_gattc_send_open_cback(p_clreg,
342 BTA_GATT_NO_RESOURCES,
343 p_msg->api_conn.remote_bda,
344 BTA_GATT_INVALID_CONN_ID,
345 p_msg->api_conn.transport, 0);
348 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
351 APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
352 p_msg->api_conn.client_if);
355 /*******************************************************************************
357 ** Function bta_gattc_process_api_open_cancel
359 ** Description process connect API request.
363 *******************************************************************************/
364 void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
366 UINT16 event = ((BT_HDR *)p_msg)->event;
367 tBTA_GATTC_CLCB *p_clcb = NULL;
368 tBTA_GATTC_RCB *p_clreg;
372 if (p_msg->api_cancel_conn.is_direct) {
373 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
374 p_msg->api_cancel_conn.remote_bda,
375 BTA_GATT_TRANSPORT_LE)) != NULL) {
376 bta_gattc_sm_execute(p_clcb, event, p_msg);
378 APPL_TRACE_ERROR("No such connection need to be cancelled");
380 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
382 if (p_clreg && p_clreg->p_cback) {
383 cb_data.status = BTA_GATT_ERROR;
384 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
388 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
393 /*******************************************************************************
395 ** Function bta_gattc_process_enc_cmpl
397 ** Description process encryption complete message.
401 *******************************************************************************/
402 void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
404 tBTA_GATTC_RCB *p_clreg;
408 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
410 if (p_clreg && p_clreg->p_cback) {
411 memset(&cb_data, 0, sizeof(tBTA_GATTC));
413 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
414 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
416 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
420 /*******************************************************************************
422 ** Function bta_gattc_cancel_open_error
428 *******************************************************************************/
429 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
434 cb_data.status = BTA_GATT_ERROR;
436 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback ) {
437 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
441 /*******************************************************************************
443 ** Function bta_gattc_open_error
449 *******************************************************************************/
450 void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
454 APPL_TRACE_ERROR("Connection already opened. wrong state");
456 bta_gattc_send_open_cback(p_clcb->p_rcb,
463 /*******************************************************************************
465 ** Function bta_gattc_open_fail
471 *******************************************************************************/
472 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
476 bta_gattc_send_open_cback(p_clcb->p_rcb,
482 /* open failure, remove clcb */
483 bta_gattc_clcb_dealloc(p_clcb);
486 /*******************************************************************************
488 ** Function bta_gattc_open
490 ** Description Process API connection function.
494 *******************************************************************************/
495 void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
497 tBTA_GATTC_DATA gattc_data;
499 /* open/hold a connection */
500 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
501 TRUE, p_data->api_conn.transport)) {
502 APPL_TRACE_ERROR("Connection open failure");
504 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
506 /* a connected remote device */
507 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
508 p_data->api_conn.remote_bda,
509 &p_clcb->bta_conn_id,
510 p_data->api_conn.transport)) {
511 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
513 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
515 /* else wait for the callback event */
518 /*******************************************************************************
520 ** Function bta_gattc_init_bk_conn
522 ** Description Process API Open for a background connection
526 *******************************************************************************/
527 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
529 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
531 tBTA_GATTC_CLCB *p_clcb;
532 tBTA_GATTC_DATA gattc_data;
534 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) {
535 /* always call open to hold a connection */
536 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport)) {
537 uint8_t *bda = (uint8_t *)p_data->remote_bda;
538 status = BTA_GATT_ERROR;
539 APPL_TRACE_ERROR("%s unable to connect to remote bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
540 __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
543 status = BTA_GATT_OK;
545 /* if is a connected remote device */
546 if (GATT_GetConnIdIfConnected(p_data->client_if,
549 p_data->transport)) {
550 if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
551 BTA_GATT_TRANSPORT_LE)) != NULL) {
552 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
554 /* open connection */
555 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
556 status = BTA_GATT_OK;
562 /* open failure, report OPEN_EVT */
563 if (status != BTA_GATT_OK) {
564 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
565 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
568 /*******************************************************************************
570 ** Function bta_gattc_cancel_bk_conn
572 ** Description Process API Cancel Open for a background connection
576 *******************************************************************************/
577 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
579 tBTA_GATTC_RCB *p_clreg;
581 cb_data.status = BTA_GATT_ERROR;
583 /* remove the device from the bg connection mask */
584 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE)) {
585 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE)) {
586 cb_data.status = BTA_GATT_OK;
588 APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
591 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
593 if (p_clreg && p_clreg->p_cback) {
594 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
598 /*******************************************************************************
600 ** Function bta_gattc_int_cancel_open_ok
606 *******************************************************************************/
607 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
612 if ( p_clcb->p_rcb->p_cback ) {
613 cb_data.status = BTA_GATT_OK;
614 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
617 bta_gattc_clcb_dealloc(p_clcb);
619 /*******************************************************************************
621 ** Function bta_gattc_cancel_open
627 *******************************************************************************/
628 void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
632 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE)) {
633 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
635 if ( p_clcb->p_rcb->p_cback ) {
636 cb_data.status = BTA_GATT_ERROR;
637 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
641 /*******************************************************************************
643 ** Function bta_gattc_conn
645 ** Description receive connection callback from stack
649 *******************************************************************************/
650 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
652 tBTA_GATTC_IF gatt_if;
653 APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d", p_clcb->p_srcb->state);
655 if (p_data != NULL) {
656 APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d", p_data->hdr.layer_specific);
657 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
659 GATT_GetConnectionInfor(p_data->hdr.layer_specific,
660 &gatt_if, p_clcb->bda, &p_clcb->transport);
663 p_clcb->p_srcb->connected = TRUE;
665 if (p_clcb->p_srcb->mtu == 0) {
666 p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
669 /* start database cache if needed */
670 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
671 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
672 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
673 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
674 if (bta_gattc_cache_load(p_clcb)) {
675 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
676 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
677 } else { /* 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);
700 bta_gattc_send_open_cback(p_clcb->p_rcb,
705 p_clcb->p_srcb->mtu);
709 /*******************************************************************************
711 ** Function bta_gattc_conncback
713 ** Description receive connection callback from stack
717 *******************************************************************************/
718 void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
721 bta_gattc_send_connect_cback(p_rcb,
722 p_data->int_conn.remote_bda,
723 p_data->int_conn.hdr.layer_specific);
727 /*******************************************************************************
729 ** Function bta_gattc_disconncback
731 ** Description receive disconnection callback from stack
735 *******************************************************************************/
736 void bta_gattc_disconncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
739 bta_gattc_send_disconnect_cback(p_rcb,
740 p_data->int_conn.reason,
741 p_data->int_conn.remote_bda,
742 p_data->int_conn.hdr.layer_specific);
746 /*******************************************************************************
748 ** Function bta_gattc_close_fail
750 ** Description close a connection.
754 *******************************************************************************/
755 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
759 if ( p_clcb->p_rcb->p_cback ) {
760 memset(&cb_data, 0, sizeof(tBTA_GATTC));
761 cb_data.close.client_if = p_clcb->p_rcb->client_if;
762 cb_data.close.conn_id = p_data->hdr.layer_specific;
763 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
764 cb_data.close.status = BTA_GATT_ERROR;
765 cb_data.close.reason = BTA_GATT_CONN_NONE;
768 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
771 /*******************************************************************************
773 ** Function bta_gattc_api_close
775 ** Description close a GATTC connection.
779 *******************************************************************************/
780 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
782 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
783 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
786 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
788 cb_data.close.client_if = p_clcb->p_rcb->client_if;
789 cb_data.close.conn_id = p_clcb->bta_conn_id;
790 cb_data.close.reason = p_clcb->reason;
791 cb_data.close.status = p_clcb->status;
792 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
794 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
795 bta_sys_conn_close( BTA_ID_GATTC , BTA_ALL_APP_ID, p_clcb->bda);
798 bta_gattc_clcb_dealloc(p_clcb);
800 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
801 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
802 } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
803 cb_data.close.status = BTA_GATT_OK;
804 cb_data.close.reason = p_data->int_conn.reason;
808 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
811 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
812 bta_gattc_deregister_cmpl(p_clreg);
815 /*******************************************************************************
817 ** Function bta_gattc_reset_discover_st
819 ** Description when a SRCB finished discovery, tell all related clcb.
823 *******************************************************************************/
824 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
826 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
829 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
830 if (p_cb->clcb[i].p_srcb == p_srcb) {
831 p_cb->clcb[i].status = status;
832 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
836 /*******************************************************************************
838 ** Function bta_gattc_disc_close
840 ** Description close a GATTC connection while in discovery state.
844 *******************************************************************************/
845 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
847 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
848 p_clcb->bta_conn_id);
850 if (p_clcb->disc_active) {
851 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
853 p_clcb->state = BTA_GATTC_CONN_ST;
856 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
857 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
858 // connection itself still needs to be closed to resolve the original event.
859 if (p_clcb->state == BTA_GATTC_CONN_ST) {
860 APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
861 "Trigger connection close");
862 bta_gattc_close(p_clcb, p_data);
865 /*******************************************************************************
867 ** Function bta_gattc_set_discover_st
869 ** Description when a SRCB start discovery, tell all related clcb and set
874 *******************************************************************************/
875 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
877 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
880 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
881 if (p_cb->clcb[i].p_srcb == p_srcb) {
882 p_cb->clcb[i].status = BTA_GATT_OK;
883 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
887 /*******************************************************************************
889 ** Function bta_gattc_restart_discover
891 ** Description process service change in discovery state, mark up the auto
892 ** update flag and set status to be discovery cancel for current
897 *******************************************************************************/
898 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
902 p_clcb->status = BTA_GATT_CANCEL;
903 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
906 /*******************************************************************************
908 ** Function bta_gattc_cfg_mtu
910 ** Description Configure MTU size on the GATT connection.
914 *******************************************************************************/
915 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
917 tBTA_GATT_STATUS status;
919 if (bta_gattc_enqueue(p_clcb, p_data)) {
920 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id);
922 /* if failed, return callback here */
923 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
924 /* Dequeue the data, if it was enqueued */
925 if (p_clcb->p_q_cmd == p_data) {
926 p_clcb->p_q_cmd = NULL;
927 bta_gattc_pop_command_to_send(p_clcb);
930 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
934 /*******************************************************************************
936 ** Function bta_gattc_start_discover
938 ** Description Start a discovery send to server.
942 *******************************************************************************/
943 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
947 APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
948 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
950 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
951 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
952 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) {
953 /* no pending operation, start discovery right away */
954 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
956 if (p_clcb->p_srcb != NULL) {
957 /* clear the service change mask */
958 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
959 p_clcb->p_srcb->update_count = 0;
960 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
962 if (p_clcb->transport == BTA_TRANSPORT_LE) {
963 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
966 /* set all srcb related clcb into discovery ST */
967 bta_gattc_set_discover_st(p_clcb->p_srcb);
969 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) {
970 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
971 p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
973 if (p_clcb->status != BTA_GATT_OK) {
974 APPL_TRACE_ERROR("discovery on server failed");
975 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
977 p_clcb->disc_active = TRUE;
980 APPL_TRACE_ERROR("unknown device, can not start discovery");
983 /* pending operation, wait until it finishes */
985 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
987 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
988 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
993 /*******************************************************************************
995 ** Function bta_gattc_disc_cmpl
997 ** Description discovery on server is finished
1001 *******************************************************************************/
1002 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1004 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1007 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d, status = %d", p_clcb->bta_conn_id, p_clcb->status);
1009 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1010 p_clcb->disc_active = FALSE;
1012 if (p_clcb->status != GATT_SUCCESS) {
1013 /* clean up cache */
1014 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1015 list_free(p_clcb->p_srcb->p_srvc_cache);
1016 p_clcb->p_srcb->p_srvc_cache = NULL;
1019 /* used to reset cache in application */
1020 bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
1022 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
1023 /* release pending attribute list buffer */
1024 osi_free(p_clcb->p_srcb->p_srvc_list);
1025 p_clcb->p_srcb->p_srvc_list = NULL;
1026 //osi_free_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
1029 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1030 /* start discovery again */
1031 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1033 /* get any queued command to proceed */
1034 else if (p_q_cmd != NULL) {
1035 p_clcb->p_q_cmd = NULL;
1036 /* execute pending operation of link block still present */
1037 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1038 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1040 /* if the command executed requeued the cmd, we don't
1041 * want to free the underlying buffer that's being
1042 * referenced by p_clcb->p_q_cmd
1044 if (p_q_cmd != p_clcb->p_q_cmd) {
1050 /*******************************************************************************
1052 ** Function bta_gattc_read
1054 ** Description Read an attribute
1058 *******************************************************************************/
1059 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1061 if (!bta_gattc_enqueue(p_clcb, p_data))
1064 tGATT_READ_PARAM read_param;
1065 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1066 read_param.by_handle.handle = p_data->api_read.handle;
1067 read_param.by_handle.auth_req = p_data->api_read.auth_req;
1069 tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1072 if (status != BTA_GATT_OK) {
1073 /* Dequeue the data, if it was enqueued */
1074 if (p_clcb->p_q_cmd == p_data) {
1075 p_clcb->p_q_cmd = NULL;
1076 bta_gattc_pop_command_to_send(p_clcb);
1079 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1082 /*******************************************************************************
1084 ** Function bta_gattc_read_multi
1086 ** Description read multiple
1089 *********************************************************************************/
1090 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1092 tBTA_GATT_STATUS status = BTA_GATT_OK;
1093 tGATT_READ_PARAM read_param;
1095 if (bta_gattc_enqueue(p_clcb, p_data)) {
1096 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1098 if (status == BTA_GATT_OK) {
1099 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1100 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1101 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
1102 sizeof(UINT16) * p_data->api_read_multi.num_attr);
1104 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1108 if (status != BTA_GATT_OK) {
1109 /* Dequeue the data, if it was enqueued */
1110 if (p_clcb->p_q_cmd == p_data) {
1111 p_clcb->p_q_cmd = NULL;
1112 bta_gattc_pop_command_to_send(p_clcb);
1115 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1119 /*******************************************************************************
1121 ** Function bta_gattc_write
1123 ** Description Write an attribute
1127 *******************************************************************************/
1128 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1130 if (!bta_gattc_enqueue(p_clcb, p_data))
1133 tBTA_GATT_STATUS status = BTA_GATT_OK;
1136 attr.conn_id = p_clcb->bta_conn_id;
1137 attr.handle = p_data->api_write.handle;
1138 attr.offset = p_data->api_write.offset;
1139 attr.len = p_data->api_write.len;
1140 attr.auth_req = p_data->api_write.auth_req;
1142 if (p_data->api_write.p_value) {
1143 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1146 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1149 if (status != BTA_GATT_OK) {
1150 /* Dequeue the data, if it was enqueued */
1151 if (p_clcb->p_q_cmd == p_data) {
1152 p_clcb->p_q_cmd = NULL;
1153 bta_gattc_pop_command_to_send(p_clcb);
1156 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
1159 /*******************************************************************************
1161 ** Function bta_gattc_execute
1163 ** Description send execute write
1166 *********************************************************************************/
1167 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1169 tBTA_GATT_STATUS status;
1171 if (bta_gattc_enqueue(p_clcb, p_data)) {
1172 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1174 if (status != BTA_GATT_OK) {
1175 /* Dequeue the data, if it was enqueued */
1176 if (p_clcb->p_q_cmd == p_data) {
1177 p_clcb->p_q_cmd = NULL;
1178 bta_gattc_pop_command_to_send(p_clcb);
1181 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
1185 /*******************************************************************************
1187 ** Function bta_gattc_confirm
1189 ** Description send handle value confirmation
1193 *******************************************************************************/
1194 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1196 UINT16 handle = p_data->api_confirm.handle;
1198 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1200 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1202 /* if over BR_EDR, inform PM for mode change */
1203 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1204 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1205 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1209 /*******************************************************************************
1211 ** Function bta_gattc_read_cmpl
1213 ** Description read complete
1217 *******************************************************************************/
1218 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1222 tBTA_GATT_UNFMT read_value;
1224 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1225 memset(&read_value, 0, sizeof(tBTA_GATT_UNFMT));
1227 cb_data.read.status = p_data->status;
1229 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) {
1230 cb_data.read.handle = p_data->p_cmpl->att_value.handle;
1232 read_value.len = p_data->p_cmpl->att_value.len;
1233 read_value.p_value = p_data->p_cmpl->att_value.value;
1234 cb_data.read.p_value = &read_value;
1236 cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle;
1239 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1240 event = p_clcb->p_q_cmd->api_read.cmpl_evt;
1242 event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt;
1244 cb_data.read.conn_id = p_clcb->bta_conn_id;
1245 //free the command data store in the queue.
1246 bta_gattc_free_command_data(p_clcb);
1247 bta_gattc_pop_command_to_send(p_clcb);
1248 /* read complete, callback */
1249 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1252 /*******************************************************************************
1254 ** Function bta_gattc_write_cmpl
1256 ** Description write complete
1260 *******************************************************************************/
1261 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1263 tBTA_GATTC cb_data = {0};
1266 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1268 cb_data.write.status = p_data->status;
1269 cb_data.write.handle = p_data->p_cmpl->att_value.handle;
1271 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1272 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) {
1274 event = BTA_GATTC_PREP_WRITE_EVT;
1276 event = p_clcb->p_q_cmd->api_write.cmpl_evt;
1278 //free the command data store in the queue.
1279 bta_gattc_free_command_data(p_clcb);
1280 bta_gattc_pop_command_to_send(p_clcb);
1281 cb_data.write.conn_id = p_clcb->bta_conn_id;
1282 /* write complete, callback */
1283 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1286 /*******************************************************************************
1288 ** Function bta_gattc_exec_cmpl
1290 ** Description execute write complete
1294 *******************************************************************************/
1295 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1298 //free the command data store in the queue.
1299 bta_gattc_free_command_data(p_clcb);
1300 bta_gattc_pop_command_to_send(p_clcb);
1301 p_clcb->status = BTA_GATT_OK;
1303 /* execute complete, callback */
1304 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1305 cb_data.exec_cmpl.status = p_data->status;
1307 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1311 /*******************************************************************************
1313 ** Function bta_gattc_cfg_mtu_cmpl
1315 ** Description configure MTU operation complete
1319 *******************************************************************************/
1320 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1323 //free the command data store in the queue.
1324 bta_gattc_free_command_data(p_clcb);
1325 bta_gattc_pop_command_to_send(p_clcb);
1327 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) {
1328 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1331 /* configure MTU complete, callback */
1332 p_clcb->status = p_data->status;
1333 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1334 cb_data.cfg_mtu.status = p_data->status;
1335 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1337 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data);
1340 /*******************************************************************************
1342 ** Function bta_gattc_op_cmpl
1344 ** Description operation completed.
1348 *******************************************************************************/
1349 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1351 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1352 UINT8 mapped_op = 0;
1354 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1356 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
1357 APPL_TRACE_ERROR("unexpected operation, ignored");
1358 } else if (op >= GATTC_OPTYPE_READ) {
1359 if (p_clcb->p_q_cmd == NULL) {
1360 APPL_TRACE_ERROR("No pending command");
1363 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
1364 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1365 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1366 if ( mapped_op > GATTC_OPTYPE_INDICATION) {
1370 #if (BT_TRACE_VERBOSE == TRUE)
1371 APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1372 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1373 bta_gattc_op_code_name[op]);
1375 APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1376 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1382 /* discard responses if service change indication is received before operation completed */
1383 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg) {
1384 APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1385 p_data->op_cmpl.status = GATT_ERROR;
1388 /* service handle change void the response, discard it */
1389 if (op == GATTC_OPTYPE_READ) {
1390 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1393 else if (op == GATTC_OPTYPE_WRITE) {
1394 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1397 else if (op == GATTC_OPTYPE_EXE_WRITE) {
1398 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1401 else if (op == GATTC_OPTYPE_CONFIG) {
1402 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1405 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1406 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1407 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1411 /*******************************************************************************
1413 ** Function bta_gattc_op_cmpl
1415 ** Description operation completed.
1419 *******************************************************************************/
1420 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1424 /* receive op complete when discovery is started, ignore the response,
1425 and wait for discovery finish and resent */
1426 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1429 /*******************************************************************************
1431 ** Function bta_gattc_search
1433 ** Description start a search in the local server cache
1437 *******************************************************************************/
1438 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1440 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1442 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
1443 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1444 status = BTA_GATT_OK;
1445 /* search the local cache of a server device */
1446 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1448 cb_data.search_cmpl.status = status;
1449 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1451 /* end of search or no server cache available */
1452 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1454 /*******************************************************************************
1456 ** Function bta_gattc_q_cmd
1458 ** Description enqueue a command into control block, usually because discovery
1459 ** operation is busy.
1463 *******************************************************************************/
1464 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1466 bta_gattc_enqueue(p_clcb, p_data);
1468 /*******************************************************************************
1470 ** Function bta_gattc_pop_command_to_send
1472 ** Description dequeue a command into control block.
1473 ** Check if there has command pending in the command queue or not,
1474 ** if there has command pending in the command queue, sent it to the state machine to decision
1475 ** should be sent it to the remote device or not.
1479 *******************************************************************************/
1480 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb)
1482 if (!list_is_empty(p_clcb->p_cmd_list)) {
1483 list_node_t *node = list_begin(p_clcb->p_cmd_list);
1484 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1485 if (p_data != NULL) {
1486 /* execute pending operation of link block still present */
1487 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1488 // The data to be sent to the gattc state machine for processing
1489 if(bta_gattc_sm_execute(p_clcb, p_data->hdr.event, p_data)) {
1490 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1493 if (p_clcb->is_full) {
1494 tBTA_GATTC cb_data = {0};
1495 p_clcb->is_full = FALSE;
1496 cb_data.status = GATT_SUCCESS;
1497 cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
1498 cb_data.queue_full.is_full = FALSE;
1499 if (p_clcb->p_rcb->p_cback != NULL) {
1500 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
1507 /*******************************************************************************
1509 ** Function bta_gattc_free_command_data
1511 ** Description free the command data into control block.
1515 *******************************************************************************/
1516 void bta_gattc_free_command_data(tBTA_GATTC_CLCB *p_clcb)
1518 assert(p_clcb->p_cmd_list);
1519 //Check the list is empty or not.
1520 if (!list_is_empty(p_clcb->p_cmd_list)) {
1521 /* 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
1522 command queue,should remove it from the list */
1523 for (list_node_t *node = list_begin(p_clcb->p_cmd_list); node != list_end(p_clcb->p_cmd_list);
1524 node = list_next(node)) {
1525 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1526 if (p_data == p_clcb->p_q_cmd) {
1527 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1528 p_clcb->p_q_cmd = NULL;
1533 osi_free(p_clcb->p_q_cmd);
1534 p_clcb->p_q_cmd = NULL;
1536 osi_free(p_clcb->p_q_cmd);
1537 p_clcb->p_q_cmd = NULL;
1541 /*******************************************************************************
1543 ** Function bta_gattc_fail
1545 ** Description report API call failure back to apps
1549 *******************************************************************************/
1550 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1554 if (p_clcb->status == BTA_GATT_OK) {
1555 APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1559 /*******************************************************************************
1561 ** Function bta_gattc_deregister_cmpl
1563 ** Description De-Register a GATT client application with BTA completed.
1567 *******************************************************************************/
1568 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1570 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
1571 tBTA_GATTC_IF client_if = p_clreg->client_if;
1573 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
1575 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1577 GATT_Deregister(p_clreg->client_if);
1578 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1580 cb_data.reg_oper.client_if = client_if;
1581 cb_data.reg_oper.status = BTA_GATT_OK;
1584 /* callback with de-register event */
1586 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
1589 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) {
1590 p_cb->state = BTA_GATTC_STATE_DISABLED;
1594 /*******************************************************************************
1596 ** Function bta_gattc_conn_cback
1598 ** Description callback functions to GATT client stack.
1602 *******************************************************************************/
1603 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1604 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1605 tBT_TRANSPORT transport)
1607 tBTA_GATTC_DATA *p_buf;
1608 BOOLEAN start_ccc_timer = FALSE;
1609 tBTA_GATTC_CONN *p_conn = NULL;
1610 tBTA_GATTC_FIND_SERVICE_CB result;
1613 APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1614 __FUNCTION__, gattc_if, connected, conn_id, reason);
1617 if (connected == TRUE){
1618 p_conn = bta_gattc_conn_find_alloc(bda);
1620 else if (connected == FALSE){
1621 p_conn = bta_gattc_conn_find(bda);
1624 if (p_conn == NULL){
1625 APPL_TRACE_ERROR("p_conn is NULL in %s\n", __func__);
1628 if ((transport == BT_TRANSPORT_LE) && (connected == TRUE) && (p_conn != NULL) \
1629 && (p_conn->service_change_ccc_written == FALSE) && (p_conn->ccc_timer_used == FALSE)) {
1630 result = bta_gattc_register_service_change_notify(conn_id, bda, &start_ccc_timer);
1631 if (start_ccc_timer == TRUE) {
1632 TIMER_LIST_ENT *ccc_timer = &(p_conn->service_change_ccc_timer);
1633 /* start a 1000ms timer to wait for service discovery finished */
1634 bta_gattc_start_service_change_ccc_timer(conn_id, bda, 1000, 0, result, ccc_timer);
1635 p_conn->ccc_timer_used = TRUE;
1638 /* Has written service change ccc; or service change ccc doesn't exist in remote device's gatt database */
1639 p_conn->service_change_ccc_written = TRUE;
1640 p_conn->ccc_timer_used = FALSE;
1644 else if ((transport == BT_TRANSPORT_LE) && (connected == FALSE) && (p_conn != NULL)){
1645 p_conn->service_change_ccc_written = FALSE;
1646 if (p_conn->ccc_timer_used == TRUE){
1647 assert(write_ccc_mutex != NULL);
1648 osi_mutex_lock(&write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
1650 if (p_conn->service_change_ccc_timer.param != 0) {
1651 osi_free((void *)p_conn->service_change_ccc_timer.param);
1652 p_conn->service_change_ccc_timer.param = (TIMER_PARAM_TYPE)0;
1654 bta_sys_stop_timer(&(p_conn->service_change_ccc_timer));
1655 p_conn->ccc_timer_used = FALSE;
1656 osi_mutex_unlock(&write_ccc_mutex);
1661 bdcpy(bdaddr.address, bda);
1663 if ((p_buf = (tBTA_GATTC_DATA *) osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1664 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1666 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT :
1667 BTA_GATTC_INT_DISCONN_EVT;
1668 p_buf->int_conn.hdr.layer_specific = conn_id;
1669 p_buf->int_conn.client_if = gattc_if;
1670 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1671 p_buf->int_conn.reason = reason;
1672 p_buf->int_conn.transport = transport;
1673 bdcpy(p_buf->int_conn.remote_bda, bda);
1675 bta_sys_sendmsg(p_buf);
1679 /*******************************************************************************
1681 ** Function bta_gattc_enc_cmpl_cback
1683 ** Description encryption complete callback function to GATT client stack.
1687 *******************************************************************************/
1688 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1690 tBTA_GATTC_DATA *p_buf;
1691 tBTA_GATTC_CLCB *p_clcb = NULL;
1693 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) {
1697 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1698 /* filter this event just for BTA HH LE GATT client,
1699 In the future, if we want to enable encryption complete event
1700 for all GATT clients, we can remove this code */
1701 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
1706 APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1708 if ((p_buf = (tBTA_GATTC_DATA *) osi_calloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1709 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1711 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1712 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1713 p_buf->enc_cmpl.client_if = gattc_if;
1714 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1716 bta_sys_sendmsg(p_buf);
1720 /*******************************************************************************
1722 ** Function bta_gattc_process_api_refresh
1724 ** Description process refresh API to delete cache and start a new discovery
1725 ** if currently connected.
1729 *******************************************************************************/
1730 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1732 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1733 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1734 BOOLEAN found = FALSE;
1738 if (p_srvc_cb != NULL) {
1739 /* try to find a CLCB */
1740 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
1741 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
1742 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
1748 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1752 /* in all other cases, mark it and delete the cache */
1753 if (p_srvc_cb->p_srvc_cache != NULL) {
1754 list_free(p_srvc_cb->p_srvc_cache);
1755 p_srvc_cb->p_srvc_cache = NULL;
1758 /* used to reset cache in application */
1759 bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
1762 /*******************************************************************************
1764 ** Function bta_gattc_process_srvc_chg_ind
1766 ** Description process service change indication.
1770 *******************************************************************************/
1771 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1772 tBTA_GATTC_RCB *p_clrcb,
1773 tBTA_GATTC_SERV *p_srcb,
1774 tBTA_GATTC_CLCB *p_clcb,
1775 tBTA_GATTC_NOTIFY *p_notify,
1776 tGATT_VALUE *att_value)
1778 tBT_UUID gattp_uuid, srvc_chg_uuid;
1779 BOOLEAN processed = FALSE;
1783 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1785 srvc_chg_uuid.len = 2;
1786 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1788 const tBTA_GATTC_CHARACTERISTIC *p_char = bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
1789 if (p_char && bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, TRUE) &&
1790 bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, TRUE)) {
1791 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
1792 APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
1796 UINT8 *p = att_value->value;
1797 UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
1798 UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
1800 APPL_TRACE_ERROR("%s: service changed s_handle:0x%04x e_handle:0x%04x",
1801 __func__, s_handle, e_handle);
1804 /* mark service handle change pending */
1805 p_srcb->srvc_hdl_chg = TRUE;
1806 /* clear up all notification/indication registration */
1807 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
1808 /* service change indication all received, do discovery update */
1809 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
1810 /* not an opened connection; or connection busy */
1811 /* search for first available clcb and start discovery */
1812 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
1813 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) {
1814 if (bta_gattc_cb.clcb[i].in_use &&
1815 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1816 bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
1817 p_clcb = &bta_gattc_cb.clcb[i];
1822 /* send confirmation here if this is an indication, it should always be */
1823 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
1825 /* if connection available, refresh cache by doing discovery now */
1826 if (p_clcb != NULL) {
1827 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1830 /* notify applicationf or service change */
1831 if (p_clrcb->p_cback != NULL) {
1832 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda);
1840 /*******************************************************************************
1842 ** Function bta_gattc_proc_other_indication
1844 ** Description process all non-service change indication/notification.
1848 *******************************************************************************/
1849 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
1850 tGATT_CL_COMPLETE *p_data,
1851 tBTA_GATTC_NOTIFY *p_notify)
1853 APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check p_data->att_value.handle=%d p_data->handle=%d",
1854 p_data->att_value.handle, p_data->handle);
1855 APPL_TRACE_DEBUG("is_notify %d", p_notify->is_notify);
1857 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
1858 p_notify->len = p_data->att_value.len;
1859 bdcpy(p_notify->bda, p_clcb->bda);
1860 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
1861 p_notify->conn_id = p_clcb->bta_conn_id;
1863 if (p_clcb->p_rcb->p_cback) {
1864 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
1868 /*******************************************************************************
1870 ** Function bta_gattc_process_indicate
1872 ** Description process indication/notification.
1876 *******************************************************************************/
1877 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
1879 UINT16 handle = p_data->att_value.handle;
1880 tBTA_GATTC_CLCB *p_clcb ;
1881 tBTA_GATTC_RCB *p_clrcb = NULL;
1882 tBTA_GATTC_SERV *p_srcb = NULL;
1883 tBTA_GATTC_NOTIFY notify;
1885 tBTA_GATTC_IF gatt_if;
1886 tBTA_TRANSPORT transport;
1888 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
1889 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
1890 if (op == GATTC_OPTYPE_INDICATION) {
1891 GATTC_SendHandleValueConfirm(conn_id, handle);
1896 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) {
1897 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
1898 if (op == GATTC_OPTYPE_INDICATION) {
1899 GATTC_SendHandleValueConfirm(conn_id, handle);
1904 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
1905 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore", __func__);
1906 if (op == GATTC_OPTYPE_INDICATION) {
1907 GATTC_SendHandleValueConfirm(conn_id, handle);
1912 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1914 notify.handle = handle;
1915 /* if non-service change indication/notification, forward to application */
1916 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value)) {
1917 /* if app registered for the notification */
1918 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
1919 /* connection not open yet */
1920 if (p_clcb == NULL) {
1921 p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
1923 if (p_clcb == NULL) {
1924 APPL_TRACE_ERROR("No resources");
1928 p_clcb->bta_conn_id = conn_id;
1929 p_clcb->transport = transport;
1931 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
1934 if (p_clcb != NULL) {
1935 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
1937 } else if (op == GATTC_OPTYPE_INDICATION) {
1938 /* no one intersted and need ack? */
1939 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
1940 GATTC_SendHandleValueConfirm(conn_id, handle);
1944 /*******************************************************************************
1946 ** Function bta_gattc_cmpl_cback
1948 ** Description client operation complete callback register with BTE GATT.
1952 *******************************************************************************/
1953 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
1954 tGATT_CL_COMPLETE *p_data)
1956 tBTA_GATTC_CLCB *p_clcb;
1957 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
1958 conn_id, op, status);
1960 /* notification and indication processed right away */
1961 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
1962 bta_gattc_process_indicate(conn_id, op, p_data);
1965 /* for all other operation, not expected if w/o connection */
1966 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) {
1967 APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
1971 /* if over BR_EDR, inform PM for mode change */
1972 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1973 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1974 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1977 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
1980 /*******************************************************************************
1982 ** Function bta_gattc_cmpl_sendmsg
1984 ** Description client operation complete send message
1988 *******************************************************************************/
1989 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
1990 tBTA_GATT_STATUS status,
1991 tGATT_CL_COMPLETE *p_data)
1993 const UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
1994 tBTA_GATTC_OP_CMPL *p_buf = (tBTA_GATTC_OP_CMPL *) osi_malloc(len);
1996 if (p_buf != NULL) {
1997 memset(p_buf, 0, len);
1998 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
1999 p_buf->hdr.layer_specific = conn_id;
2000 p_buf->status = status;
2001 p_buf->op_code = op;
2003 if (p_data != NULL) {
2004 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2005 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2008 bta_sys_sendmsg(p_buf);
2012 /*******************************************************************************
2014 ** Function bta_gattc_cong_cback
2016 ** Description congestion callback for BTA GATT client.
2020 ********************************************************************************/
2021 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2023 tBTA_GATTC_CLCB *p_clcb;
2026 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL) {
2027 if (p_clcb->p_rcb->p_cback) {
2028 cb_data.congest.conn_id = conn_id;
2029 cb_data.congest.congested = congested;
2031 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
2036 #if BLE_INCLUDED == TRUE
2037 /*******************************************************************************
2039 ** Function bta_gattc_init_clcb_conn
2041 ** Description Initaite a BTA CLCB connection
2045 ********************************************************************************/
2046 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2048 tBTA_GATTC_CLCB *p_clcb = NULL;
2049 tBTA_GATTC_DATA gattc_data;
2052 /* should always get the connection ID */
2053 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) {
2054 APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2058 /* initaite a new connection here */
2059 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
2060 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2062 gattc_data.api_conn.client_if = cif;
2063 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2064 gattc_data.api_conn.is_direct = TRUE;
2066 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2068 APPL_TRACE_ERROR("No resources");
2071 /*******************************************************************************
2073 ** Function bta_gattc_process_listen_all
2075 ** Description process listen all, send open callback to application for all
2076 ** connected slave LE link.
2080 ********************************************************************************/
2081 void bta_gattc_process_listen_all(UINT8 cif)
2084 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
2086 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
2087 if (p_conn->in_use ) {
2088 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) {
2089 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2091 /* else already connected */
2095 /*******************************************************************************
2097 ** Function bta_gattc_listen
2099 ** Description Start or stop a listen for connection
2103 ********************************************************************************/
2104 void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2106 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2110 cb_data.reg_oper.status = BTA_GATT_ERROR;
2111 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2113 if (p_clreg == NULL) {
2114 APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2115 p_msg->api_listen.client_if);
2118 /* mark bg conn record */
2119 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2120 (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2121 p_msg->api_listen.start,
2123 if (!GATT_Listen(p_msg->api_listen.client_if,
2124 p_msg->api_listen.start,
2125 p_msg->api_listen.remote_bda)) {
2126 APPL_TRACE_ERROR("Listen failure");
2127 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2129 cb_data.status = BTA_GATT_OK;
2131 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2133 if (p_msg->api_listen.start) {
2134 /* if listen to a specific target */
2135 if (p_msg->api_listen.remote_bda != NULL) {
2137 /* if is a connected remote device */
2138 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2139 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2140 p_msg->api_listen.remote_bda,
2141 BTA_GATT_TRANSPORT_LE) == NULL) {
2143 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2144 p_msg->api_listen.remote_bda);
2147 /* if listen to all */
2149 LOG_DEBUG("Listen For All now");
2150 /* go through all connected device and send
2151 callback for all connected slave connection */
2152 bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2159 /*******************************************************************************
2161 ** Function bta_gattc_broadcast
2163 ** Description Start or stop broadcasting
2167 ********************************************************************************/
2168 void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2170 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2174 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2175 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
2176 //TODO need modify callback if used
2177 if (p_clreg && p_clreg->p_cback) {
2178 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2182 /*******************************************************************************
2184 ** Function bta_gattc_start_service_change_ccc_timer
2186 ** Description start a timer to wait for service change ccc discovered
2190 *******************************************************************************/
2191 void bta_gattc_start_service_change_ccc_timer(UINT16 conn_id, BD_ADDR bda,UINT32 timeout_ms,
2192 UINT8 timer_cnt, UINT8 last_status, TIMER_LIST_ENT *ccc_timer)
2194 tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) osi_malloc(sizeof(tBTA_GATTC_WAIT_CCC_TIMER));
2195 if (p_timer_param != NULL) {
2196 p_timer_param->conn_id = conn_id;
2197 memcpy(p_timer_param->remote_bda, bda, sizeof(BD_ADDR));
2198 p_timer_param->count = timer_cnt;
2199 p_timer_param->last_status = last_status;
2200 ccc_timer->param = (UINT32)p_timer_param;
2201 ccc_timer->p_cback = (TIMER_CBACK *)&bta_gattc_wait4_service_change_ccc_cback;
2202 bta_sys_start_timer(ccc_timer, 0, timeout_ms);
2205 APPL_TRACE_ERROR("%s, allocate p_timer_param failed\n", __func__);
2209 /*******************************************************************************
2211 ** Function bta_gattc_register_service_change_notify
2213 ** Description Find remote device's gatt service change characteristic ccc's handle and write 2 to this
2214 ** this ccc. If not found, start a timer to wait for service discovery finished.
2216 ** Returns Return result of service change ccc service discovery result result and written operate result
2218 *******************************************************************************/
2219 tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda, BOOLEAN *need_timer)
2221 tBTA_GATTC_SERV *p_srcb = NULL;
2222 list_t *p_cache = NULL;
2223 tBTA_GATTC_SERVICE *p_service = NULL;
2224 tBTA_GATTC_CHARACTERISTIC *p_char = NULL;
2225 tBTA_GATTC_DESCRIPTOR *p_desc = NULL;
2226 tGATT_STATUS write_status;
2227 tGATT_VALUE ccc_value;
2228 tBTA_GATTC_FIND_SERVICE_CB result;
2229 BOOLEAN gatt_cache_found = FALSE;
2230 BOOLEAN gatt_service_found = FALSE;
2231 BOOLEAN gatt_service_change_found = FALSE;
2232 BOOLEAN gatt_ccc_found = FALSE;
2233 BOOLEAN start_find_ccc_timer = FALSE;
2235 tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
2236 tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
2237 tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
2239 p_srcb = bta_gattc_find_srcb(remote_bda);
2240 if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
2241 p_cache = p_srcb->p_srvc_cache;
2242 gatt_cache_found = TRUE;
2245 start_find_ccc_timer = TRUE;
2246 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2248 /* start to find gatt service */
2249 if (gatt_cache_found == TRUE) {
2250 for (list_node_t *sn = list_begin(p_cache);
2251 sn != list_end(p_cache); sn = list_next(sn)) {
2252 p_service = list_node(sn);
2253 if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_service->uuid, TRUE)) {
2254 gatt_service_found = TRUE;
2260 start_find_ccc_timer = TRUE;
2261 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2264 /* start to find gatt service change characteristic */
2265 if (gatt_service_found == TRUE) {
2266 if (p_service->characteristics) {
2267 for (list_node_t *cn = list_begin(p_service->characteristics);
2268 cn != list_end(p_service->characteristics); cn = list_next(cn)) {
2269 p_char = list_node(cn);
2270 if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_char->uuid, TRUE)) {
2271 gatt_service_change_found = TRUE;
2277 else if (gatt_cache_found == TRUE) {
2278 /* Gatt service not found, start a timer to wait for service discovery */
2279 start_find_ccc_timer = TRUE;
2280 result = SERVICE_CHANGE_SERVICE_NOT_FOUND;
2282 /* start to find gatt service change characteristic ccc */
2283 if (gatt_service_change_found == TRUE) {
2284 if (p_char->descriptors) {
2285 for (list_node_t *dn = list_begin(p_char->descriptors);
2286 dn != list_end(p_char->descriptors); dn = list_next(dn)) {
2287 p_desc = list_node(dn);
2288 if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_desc->uuid, TRUE)) {
2289 gatt_ccc_found = TRUE;
2295 else if (gatt_service_found ==TRUE) {
2296 /* Gatt service found, but service change char not found,
2297 * Case1: remote device doesn't have service change char, we don't need to start a timer here to
2298 * wait for service discovery
2299 * Case2: remote device exist service change char, we have found gatt service, but have not found
2300 * service change char, we need to start a timer here*/
2301 start_find_ccc_timer = TRUE;
2302 result = SERVICE_CHANGE_CHAR_NOT_FOUND;
2305 if (gatt_ccc_found == TRUE){
2306 ccc_value.handle = p_desc->handle;
2308 ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION;
2309 ccc_value.auth_req = GATT_AUTH_REQ_NONE;
2310 if (gatt_is_clcb_allocated(conn_id)) {
2311 APPL_TRACE_DEBUG("%s, GATTC_Write GATT_BUSY conn_id = %d", __func__, conn_id);
2312 write_status = GATT_BUSY;
2314 write_status = GATTC_Write (conn_id, GATT_WRITE, &ccc_value);
2316 if (write_status != GATT_SUCCESS) {
2317 start_find_ccc_timer = TRUE;
2318 result = SERVICE_CHANGE_WRITE_CCC_FAILED;
2321 start_find_ccc_timer = FALSE;
2322 result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
2325 else if (gatt_service_change_found == TRUE) {
2326 /* Gatt service char found, but service change char ccc not found,
2327 * Case1: remote device doesn't have service change char ccc, we don't need to start a timer here to
2328 * wait for service discovery
2329 * Case2: remote device exist service change char ccc, we have found gatt service change char, but have not found
2330 * service change char ccc, we need to start a timer here */
2331 start_find_ccc_timer = TRUE;
2332 result = SERVICE_CHANGE_CCC_NOT_FOUND;
2335 if (need_timer != NULL) {
2336 *need_timer = start_find_ccc_timer;
2342 /*******************************************************************************
2344 ** Function bta_gattc_wait4_service_change_ccc_cback
2346 ** Description callback function of service_change_ccc_timer
2350 *******************************************************************************/
2351 static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle)
2353 tBTA_GATTC_FIND_SERVICE_CB result;
2354 BOOLEAN start_ccc_timer = FALSE;
2357 assert(write_ccc_mutex != NULL);
2358 osi_mutex_lock(&write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
2360 tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) p_tle->param;
2361 p_tle->param = (TIMER_PARAM_TYPE)0;
2362 if (p_timer_param == NULL){
2363 APPL_TRACE_ERROR("p_timer_param is NULL in %s\n", __func__);
2364 osi_mutex_unlock(&write_ccc_mutex);
2368 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_timer_param->remote_bda);
2369 if (p_conn == NULL){
2370 APPL_TRACE_ERROR("p_conn is NULL in %s\n", __func__);
2371 osi_free(p_timer_param);
2372 osi_mutex_unlock(&write_ccc_mutex);
2376 result = bta_gattc_register_service_change_notify(p_timer_param->conn_id, p_timer_param->remote_bda, &start_ccc_timer);
2377 /* If return SERVICE_CHANGE_CHAR_NOT_FOUND or SERVICE_CHANGE_CCC_NOT_FOUND twice, means remote device doesn't have
2378 * service change char or ccc, stop timer */
2379 if ((result == p_timer_param->last_status) \
2380 && ((result == SERVICE_CHANGE_CHAR_NOT_FOUND) || (result == SERVICE_CHANGE_CCC_NOT_FOUND))){
2381 start_ccc_timer = FALSE;
2384 if ((start_ccc_timer == TRUE) && (p_timer_param->count < 10)){
2385 TIMER_LIST_ENT *ccc_timer = &(p_conn->service_change_ccc_timer);
2386 if (result == SERVICE_CHANGE_WRITE_CCC_FAILED){
2387 /* retry to write service change ccc, needn't to add counter */
2391 /* retry to find service change ccc */
2393 p_timer_param->count ++;
2395 bta_gattc_start_service_change_ccc_timer(p_timer_param->conn_id, p_timer_param->remote_bda, \
2396 new_timeout, p_timer_param->count, result, ccc_timer);
2399 p_conn->ccc_timer_used = FALSE;
2400 p_conn->service_change_ccc_written = TRUE;
2403 osi_free(p_timer_param);
2404 osi_mutex_unlock(&write_ccc_mutex);
2408 #endif ///GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE