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 /*****************************************************************************
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 tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda, BOOLEAN *need_timer);
69 static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle);
70 static void bta_gattc_start_service_change_ccc_timer(UINT16 conn_id, BD_ADDR bda,UINT32 timeout_ms,
71 UINT8 timer_cnt, UINT8 last_status, TIMER_LIST_ENT *ccc_timer);
73 static tGATT_CBACK bta_gattc_cl_cback = {
76 bta_gattc_disc_res_cback,
77 bta_gattc_disc_cmpl_cback,
79 bta_gattc_enc_cmpl_cback,
83 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
84 static UINT16 bta_gattc_opcode_to_int_evt[] = {
85 BTA_GATTC_API_READ_EVT,
86 BTA_GATTC_API_WRITE_EVT,
87 BTA_GATTC_API_EXEC_EVT,
88 BTA_GATTC_API_CFG_MTU_EVT,
89 BTA_GATTC_API_READ_MULTI_EVT
92 #if (BT_TRACE_VERBOSE == TRUE)
93 static const char *bta_gattc_op_code_name[] = {
104 /*****************************************************************************
106 *****************************************************************************/
109 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status);
111 /*******************************************************************************
113 ** Function bta_gattc_enable
115 ** Description Enables GATTC module
120 *******************************************************************************/
121 static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
123 APPL_TRACE_DEBUG("bta_gattc_enable");
125 if (p_cb->state == BTA_GATTC_STATE_DISABLED) {
126 /* initialize control block */
127 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
128 p_cb->state = BTA_GATTC_STATE_ENABLED;
129 // Create a write ccc mutex when the gatt client enable
130 osi_mutex_new(&bta_gattc_cb.write_ccc_mutex);
132 APPL_TRACE_DEBUG("GATTC is already enabled");
137 /*******************************************************************************
139 ** Function bta_gattc_disable
141 ** Description Disable GATTC module by cleaning up all active connections
142 ** and deregister all application.
146 *******************************************************************************/
147 void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
151 APPL_TRACE_DEBUG("bta_gattc_disable");
153 if (p_cb->state != BTA_GATTC_STATE_ENABLED) {
154 APPL_TRACE_ERROR("not enabled or disable in pogress");
157 // Free the write ccc mutex when the gatt client disable
158 osi_mutex_free(&bta_gattc_cb.write_ccc_mutex);
160 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
161 if (p_cb->cl_rcb[i].in_use) {
162 p_cb->state = BTA_GATTC_STATE_DISABLING;
163 /* don't deregister HH GATT IF */
164 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
165 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
166 if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) {
168 bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
169 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
175 /* no registered apps, indicate disable completed */
176 if (p_cb->state != BTA_GATTC_STATE_DISABLING) {
177 p_cb->state = BTA_GATTC_STATE_DISABLED;
178 memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
182 /*******************************************************************************
184 ** Function bta_gattc_register
186 ** Description Register a GATT client application with BTA.
190 *******************************************************************************/
191 void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
195 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
196 tBTA_GATTC_INT_START_IF *p_buf;
197 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
200 APPL_TRACE_DEBUG("bta_gattc_register state %d\n", p_cb->state);
201 memset(&cb_data, 0, sizeof(cb_data));
202 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
204 /* check if GATTC module is already enabled . Else enable */
205 if (p_cb->state == BTA_GATTC_STATE_DISABLED) {
206 bta_gattc_enable (p_cb);
208 /* todo need to check duplicate uuid */
209 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
210 if (!p_cb->cl_rcb[i].in_use) {
211 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) {
212 APPL_TRACE_ERROR("Register with GATT stack failed.\n");
213 status = BTA_GATT_ERROR;
215 p_cb->cl_rcb[i].in_use = TRUE;
216 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
217 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
219 /* BTA use the same client interface as BTE GATT statck */
220 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
222 if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) {
223 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
224 p_buf->client_if = p_cb->cl_rcb[i].client_if;
225 APPL_TRACE_DEBUG("GATTC getbuf sucess.\n");
226 bta_sys_sendmsg(p_buf);
227 status = BTA_GATT_OK;
229 GATT_Deregister(p_cb->cl_rcb[i].client_if);
231 status = BTA_GATT_NO_RESOURCES;
232 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
239 /* callback with register event */
240 if (p_data->api_reg.p_cback) {
241 if (p_app_uuid != NULL) {
242 memcpy(&(cb_data.reg_oper.app_uuid), p_app_uuid, sizeof(tBT_UUID));
244 cb_data.reg_oper.status = status;
245 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data);
248 /*******************************************************************************
250 ** Function bta_gattc_start_if
252 ** Description start an application interface.
256 *******************************************************************************/
257 void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
261 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) != NULL ) {
262 GATT_StartIf(p_msg->int_start_if.client_if);
264 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d", p_msg->int_start_if.client_if );
268 /*******************************************************************************
270 ** Function bta_gattc_deregister
272 ** Description De-Register a GATT client application with BTA.
276 *******************************************************************************/
277 void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg)
282 if (p_clreg != NULL) {
283 /* remove bg connection associated with this rcb */
284 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++) {
285 if (p_cb->bg_track[i].in_use) {
286 if (p_cb->bg_track[i].cif_mask & (1 << (p_clreg->client_if - 1))) {
287 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE);
288 GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
290 if (p_cb->bg_track[i].cif_adv_mask & (1 << (p_clreg->client_if - 1))) {
291 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
296 if (p_clreg->num_clcb > 0) {
297 /* close all CLCB related to this app */
298 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
299 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg)) {
300 p_clreg->dereg_pending = TRUE;
302 buf.event = BTA_GATTC_API_CLOSE_EVT;
303 buf.layer_specific = p_cb->clcb[i].bta_conn_id;
304 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ;
308 bta_gattc_deregister_cmpl(p_clreg);
311 APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
314 /*******************************************************************************
316 ** Function bta_gattc_process_api_open
318 ** Description process connect API request.
322 *******************************************************************************/
323 void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
325 UINT16 event = ((BT_HDR *)p_msg)->event;
326 tBTA_GATTC_CLCB *p_clcb = NULL;
327 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
330 if (p_clreg != NULL) {
331 if (p_msg->api_conn.is_direct) {
332 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
333 p_msg->api_conn.remote_bda,
334 p_msg->api_conn.transport)) != NULL) {
335 bta_gattc_sm_execute(p_clcb, event, p_msg);
337 APPL_TRACE_ERROR("No resources to open a new connection.");
339 bta_gattc_send_open_cback(p_clreg,
340 BTA_GATT_NO_RESOURCES,
341 p_msg->api_conn.remote_bda,
342 BTA_GATT_INVALID_CONN_ID,
343 p_msg->api_conn.transport, 0);
346 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
349 APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
350 p_msg->api_conn.client_if);
353 /*******************************************************************************
355 ** Function bta_gattc_process_api_open_cancel
357 ** Description process connect API request.
361 *******************************************************************************/
362 void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
364 UINT16 event = ((BT_HDR *)p_msg)->event;
365 tBTA_GATTC_CLCB *p_clcb = NULL;
366 tBTA_GATTC_RCB *p_clreg;
370 if (p_msg->api_cancel_conn.is_direct) {
371 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
372 p_msg->api_cancel_conn.remote_bda,
373 BTA_GATT_TRANSPORT_LE)) != NULL) {
374 bta_gattc_sm_execute(p_clcb, event, p_msg);
376 APPL_TRACE_ERROR("No such connection need to be cancelled");
378 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
380 if (p_clreg && p_clreg->p_cback) {
381 cb_data.status = BTA_GATT_ERROR;
382 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
386 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
391 /*******************************************************************************
393 ** Function bta_gattc_process_enc_cmpl
395 ** Description process encryption complete message.
399 *******************************************************************************/
400 void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
402 tBTA_GATTC_RCB *p_clreg;
406 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
408 if (p_clreg && p_clreg->p_cback) {
409 memset(&cb_data, 0, sizeof(tBTA_GATTC));
411 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
412 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
414 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
418 /*******************************************************************************
420 ** Function bta_gattc_cancel_open_error
426 *******************************************************************************/
427 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
432 cb_data.status = BTA_GATT_ERROR;
434 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback ) {
435 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
439 /*******************************************************************************
441 ** Function bta_gattc_open_error
447 *******************************************************************************/
448 void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
452 APPL_TRACE_ERROR("Connection already opened. wrong state");
454 bta_gattc_send_open_cback(p_clcb->p_rcb,
461 /*******************************************************************************
463 ** Function bta_gattc_open_fail
469 *******************************************************************************/
470 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
474 bta_gattc_send_open_cback(p_clcb->p_rcb,
480 /* open failure, remove clcb */
481 bta_gattc_clcb_dealloc(p_clcb);
484 /*******************************************************************************
486 ** Function bta_gattc_open
488 ** Description Process API connection function.
492 *******************************************************************************/
493 void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
495 tBTA_GATTC_DATA gattc_data;
497 /* open/hold a connection */
498 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
499 TRUE, p_data->api_conn.transport)) {
500 APPL_TRACE_ERROR("Connection open failure");
502 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
504 /* a connected remote device */
505 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
506 p_data->api_conn.remote_bda,
507 &p_clcb->bta_conn_id,
508 p_data->api_conn.transport)) {
509 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
511 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
513 /* else wait for the callback event */
516 /*******************************************************************************
518 ** Function bta_gattc_init_bk_conn
520 ** Description Process API Open for a background connection
524 *******************************************************************************/
525 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
527 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
529 tBTA_GATTC_CLCB *p_clcb;
530 tBTA_GATTC_DATA gattc_data;
532 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) {
533 /* always call open to hold a connection */
534 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport)) {
535 uint8_t *bda = (uint8_t *)p_data->remote_bda;
536 status = BTA_GATT_ERROR;
537 APPL_TRACE_ERROR("%s unable to connect to remote bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
538 __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
541 status = BTA_GATT_OK;
543 /* if is a connected remote device */
544 if (GATT_GetConnIdIfConnected(p_data->client_if,
547 p_data->transport)) {
548 if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
549 BTA_GATT_TRANSPORT_LE)) != NULL) {
550 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
552 /* open connection */
553 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
554 status = BTA_GATT_OK;
560 /* open failure, report OPEN_EVT */
561 if (status != BTA_GATT_OK) {
562 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
563 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
566 /*******************************************************************************
568 ** Function bta_gattc_cancel_bk_conn
570 ** Description Process API Cancel Open for a background connection
574 *******************************************************************************/
575 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
577 tBTA_GATTC_RCB *p_clreg;
579 cb_data.status = BTA_GATT_ERROR;
581 /* remove the device from the bg connection mask */
582 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE)) {
583 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE)) {
584 cb_data.status = BTA_GATT_OK;
586 APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
589 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
591 if (p_clreg && p_clreg->p_cback) {
592 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
596 /*******************************************************************************
598 ** Function bta_gattc_int_cancel_open_ok
604 *******************************************************************************/
605 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
610 if ( p_clcb->p_rcb->p_cback ) {
611 cb_data.status = BTA_GATT_OK;
612 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
615 bta_gattc_clcb_dealloc(p_clcb);
617 /*******************************************************************************
619 ** Function bta_gattc_cancel_open
625 *******************************************************************************/
626 void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
630 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE)) {
631 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
633 if ( p_clcb->p_rcb->p_cback ) {
634 cb_data.status = BTA_GATT_ERROR;
635 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
639 /*******************************************************************************
641 ** Function bta_gattc_conn
643 ** Description receive connection callback from stack
647 *******************************************************************************/
648 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
650 tBTA_GATTC_IF gatt_if;
651 APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d", p_clcb->p_srcb->state);
653 if (p_data != NULL) {
654 APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d", p_data->hdr.layer_specific);
655 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
657 GATT_GetConnectionInfor(p_data->hdr.layer_specific,
658 &gatt_if, p_clcb->bda, &p_clcb->transport);
661 p_clcb->p_srcb->connected = TRUE;
663 if (p_clcb->p_srcb->mtu == 0) {
664 p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
667 /* start database cache if needed */
668 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
669 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
670 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
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);
675 } else { /* cache is building */
676 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
677 /* cache load failure, start discovery */
678 bta_gattc_start_discover(p_clcb, NULL);
680 } else { /* cache is building */
681 p_clcb->state = BTA_GATTC_DISCOVER_ST;
684 /* a pending service handle change indication */
685 if (p_clcb->p_srcb->srvc_hdl_chg) {
686 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
687 /* start discovery */
688 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
693 /* there is no RM for GATT */
694 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
695 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
698 bta_gattc_send_open_cback(p_clcb->p_rcb,
703 p_clcb->p_srcb->mtu);
707 /*******************************************************************************
709 ** Function bta_gattc_conncback
711 ** Description receive connection callback from stack
715 *******************************************************************************/
716 void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
719 bta_gattc_send_connect_cback(p_rcb,
720 p_data->int_conn.remote_bda,
721 p_data->int_conn.hdr.layer_specific);
725 /*******************************************************************************
727 ** Function bta_gattc_disconncback
729 ** Description receive disconnection callback from stack
733 *******************************************************************************/
734 void bta_gattc_disconncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
737 bta_gattc_send_disconnect_cback(p_rcb,
738 p_data->int_conn.reason,
739 p_data->int_conn.remote_bda,
740 p_data->int_conn.hdr.layer_specific);
744 /*******************************************************************************
746 ** Function bta_gattc_close_fail
748 ** Description close a connection.
752 *******************************************************************************/
753 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
757 if ( p_clcb->p_rcb->p_cback ) {
758 memset(&cb_data, 0, sizeof(tBTA_GATTC));
759 cb_data.close.client_if = p_clcb->p_rcb->client_if;
760 cb_data.close.conn_id = p_data->hdr.layer_specific;
761 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
762 cb_data.close.status = BTA_GATT_ERROR;
763 cb_data.close.reason = BTA_GATT_CONN_NONE;
766 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
769 /*******************************************************************************
771 ** Function bta_gattc_api_close
773 ** Description close a GATTC connection.
777 *******************************************************************************/
778 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
780 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
781 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
784 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
786 cb_data.close.client_if = p_clcb->p_rcb->client_if;
787 cb_data.close.conn_id = p_clcb->bta_conn_id;
788 cb_data.close.reason = p_clcb->reason;
789 cb_data.close.status = p_clcb->status;
790 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
792 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
793 bta_sys_conn_close( BTA_ID_GATTC , BTA_ALL_APP_ID, p_clcb->bda);
796 bta_gattc_clcb_dealloc(p_clcb);
798 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
799 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
800 } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
801 cb_data.close.status = BTA_GATT_OK;
802 cb_data.close.reason = p_data->int_conn.reason;
806 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
809 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
810 bta_gattc_deregister_cmpl(p_clreg);
813 /*******************************************************************************
815 ** Function bta_gattc_reset_discover_st
817 ** Description when a SRCB finished discovery, tell all related clcb.
821 *******************************************************************************/
822 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
824 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
827 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
828 if (p_cb->clcb[i].p_srcb == p_srcb) {
829 p_cb->clcb[i].status = status;
830 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
834 /*******************************************************************************
836 ** Function bta_gattc_disc_close
838 ** Description close a GATTC connection while in discovery state.
842 *******************************************************************************/
843 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
845 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
846 p_clcb->bta_conn_id);
848 if (p_clcb->disc_active) {
849 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
851 p_clcb->state = BTA_GATTC_CONN_ST;
854 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
855 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
856 // connection itself still needs to be closed to resolve the original event.
857 if (p_clcb->state == BTA_GATTC_CONN_ST) {
858 APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
859 "Trigger connection close");
860 bta_gattc_close(p_clcb, p_data);
863 /*******************************************************************************
865 ** Function bta_gattc_set_discover_st
867 ** Description when a SRCB start discovery, tell all related clcb and set
872 *******************************************************************************/
873 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
875 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
878 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
879 if (p_cb->clcb[i].p_srcb == p_srcb) {
880 p_cb->clcb[i].status = BTA_GATT_OK;
881 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
885 /*******************************************************************************
887 ** Function bta_gattc_restart_discover
889 ** Description process service change in discovery state, mark up the auto
890 ** update flag and set status to be discovery cancel for current
895 *******************************************************************************/
896 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
900 p_clcb->status = BTA_GATT_CANCEL;
901 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
904 /*******************************************************************************
906 ** Function bta_gattc_cfg_mtu
908 ** Description Configure MTU size on the GATT connection.
912 *******************************************************************************/
913 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
915 tBTA_GATT_STATUS status;
917 if (bta_gattc_enqueue(p_clcb, p_data)) {
918 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id);
920 /* if failed, return callback here */
921 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
922 /* Dequeue the data, if it was enqueued */
923 if (p_clcb->p_q_cmd == p_data) {
924 p_clcb->p_q_cmd = NULL;
925 bta_gattc_pop_command_to_send(p_clcb);
928 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
932 /*******************************************************************************
934 ** Function bta_gattc_start_discover
936 ** Description Start a discovery send to server.
940 *******************************************************************************/
941 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
945 APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
946 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
948 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
949 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
950 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) {
951 /* no pending operation, start discovery right away */
952 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
954 if (p_clcb->p_srcb != NULL) {
955 /* clear the service change mask */
956 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
957 p_clcb->p_srcb->update_count = 0;
958 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
960 if (p_clcb->transport == BTA_TRANSPORT_LE) {
961 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
964 /* set all srcb related clcb into discovery ST */
965 bta_gattc_set_discover_st(p_clcb->p_srcb);
967 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) {
968 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
969 p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
971 if (p_clcb->status != BTA_GATT_OK) {
972 APPL_TRACE_ERROR("discovery on server failed");
973 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
975 p_clcb->disc_active = TRUE;
978 APPL_TRACE_ERROR("unknown device, can not start discovery");
981 /* pending operation, wait until it finishes */
983 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
985 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
986 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
991 /*******************************************************************************
993 ** Function bta_gattc_disc_cmpl
995 ** Description discovery on server is finished
999 *******************************************************************************/
1000 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1002 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1005 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d, status = %d", p_clcb->bta_conn_id, p_clcb->status);
1007 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1008 p_clcb->disc_active = FALSE;
1010 if (p_clcb->status != GATT_SUCCESS) {
1011 /* clean up cache */
1012 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1013 list_free(p_clcb->p_srcb->p_srvc_cache);
1014 p_clcb->p_srcb->p_srvc_cache = NULL;
1017 /* used to reset cache in application */
1018 bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
1020 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
1021 /* release pending attribute list buffer */
1022 osi_free(p_clcb->p_srcb->p_srvc_list);
1023 p_clcb->p_srcb->p_srvc_list = NULL;
1024 //osi_free_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
1027 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1028 /* start discovery again */
1029 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1031 /* get any queued command to proceed */
1032 else if (p_q_cmd != NULL) {
1033 p_clcb->p_q_cmd = NULL;
1034 /* execute pending operation of link block still present */
1035 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1036 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1038 /* if the command executed requeued the cmd, we don't
1039 * want to free the underlying buffer that's being
1040 * referenced by p_clcb->p_q_cmd
1042 if (p_q_cmd != p_clcb->p_q_cmd) {
1048 /*******************************************************************************
1050 ** Function bta_gattc_read
1052 ** Description Read an attribute
1056 *******************************************************************************/
1057 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1059 if (!bta_gattc_enqueue(p_clcb, p_data))
1062 tGATT_READ_PARAM read_param;
1063 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1064 read_param.by_handle.handle = p_data->api_read.handle;
1065 read_param.by_handle.auth_req = p_data->api_read.auth_req;
1067 tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1070 if (status != BTA_GATT_OK) {
1071 /* Dequeue the data, if it was enqueued */
1072 if (p_clcb->p_q_cmd == p_data) {
1073 p_clcb->p_q_cmd = NULL;
1074 bta_gattc_pop_command_to_send(p_clcb);
1077 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1080 /*******************************************************************************
1082 ** Function bta_gattc_read_multi
1084 ** Description read multiple
1087 *********************************************************************************/
1088 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1090 tBTA_GATT_STATUS status = BTA_GATT_OK;
1091 tGATT_READ_PARAM read_param;
1093 if (bta_gattc_enqueue(p_clcb, p_data)) {
1094 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1096 if (status == BTA_GATT_OK) {
1097 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1098 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1099 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
1100 sizeof(UINT16) * p_data->api_read_multi.num_attr);
1102 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1106 if (status != BTA_GATT_OK) {
1107 /* Dequeue the data, if it was enqueued */
1108 if (p_clcb->p_q_cmd == p_data) {
1109 p_clcb->p_q_cmd = NULL;
1110 bta_gattc_pop_command_to_send(p_clcb);
1113 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1117 /*******************************************************************************
1119 ** Function bta_gattc_write
1121 ** Description Write an attribute
1125 *******************************************************************************/
1126 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1128 if (!bta_gattc_enqueue(p_clcb, p_data))
1131 tBTA_GATT_STATUS status = BTA_GATT_OK;
1134 attr.conn_id = p_clcb->bta_conn_id;
1135 attr.handle = p_data->api_write.handle;
1136 attr.offset = p_data->api_write.offset;
1137 attr.len = p_data->api_write.len;
1138 attr.auth_req = p_data->api_write.auth_req;
1140 if (p_data->api_write.p_value) {
1141 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1144 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1147 if (status != BTA_GATT_OK) {
1148 /* Dequeue the data, if it was enqueued */
1149 if (p_clcb->p_q_cmd == p_data) {
1150 p_clcb->p_q_cmd = NULL;
1151 bta_gattc_pop_command_to_send(p_clcb);
1154 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
1157 /*******************************************************************************
1159 ** Function bta_gattc_execute
1161 ** Description send execute write
1164 *********************************************************************************/
1165 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1167 tBTA_GATT_STATUS status;
1169 if (bta_gattc_enqueue(p_clcb, p_data)) {
1170 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1172 if (status != BTA_GATT_OK) {
1173 /* Dequeue the data, if it was enqueued */
1174 if (p_clcb->p_q_cmd == p_data) {
1175 p_clcb->p_q_cmd = NULL;
1176 bta_gattc_pop_command_to_send(p_clcb);
1179 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
1183 /*******************************************************************************
1185 ** Function bta_gattc_confirm
1187 ** Description send handle value confirmation
1191 *******************************************************************************/
1192 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1194 UINT16 handle = p_data->api_confirm.handle;
1196 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1198 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1200 /* if over BR_EDR, inform PM for mode change */
1201 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1202 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1203 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1207 /*******************************************************************************
1209 ** Function bta_gattc_read_cmpl
1211 ** Description read complete
1215 *******************************************************************************/
1216 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1220 tBTA_GATT_UNFMT read_value;
1222 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1223 memset(&read_value, 0, sizeof(tBTA_GATT_UNFMT));
1225 cb_data.read.status = p_data->status;
1227 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) {
1228 cb_data.read.handle = p_data->p_cmpl->att_value.handle;
1230 read_value.len = p_data->p_cmpl->att_value.len;
1231 read_value.p_value = p_data->p_cmpl->att_value.value;
1232 cb_data.read.p_value = &read_value;
1234 cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle;
1237 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1238 event = p_clcb->p_q_cmd->api_read.cmpl_evt;
1240 event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt;
1242 cb_data.read.conn_id = p_clcb->bta_conn_id;
1243 //free the command data store in the queue.
1244 bta_gattc_free_command_data(p_clcb);
1245 bta_gattc_pop_command_to_send(p_clcb);
1246 /* read complete, callback */
1247 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1250 /*******************************************************************************
1252 ** Function bta_gattc_write_cmpl
1254 ** Description write complete
1258 *******************************************************************************/
1259 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1261 tBTA_GATTC cb_data = {0};
1264 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1266 cb_data.write.status = p_data->status;
1267 cb_data.write.handle = p_data->p_cmpl->att_value.handle;
1269 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1270 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) {
1272 event = BTA_GATTC_PREP_WRITE_EVT;
1274 event = p_clcb->p_q_cmd->api_write.cmpl_evt;
1276 //free the command data store in the queue.
1277 bta_gattc_free_command_data(p_clcb);
1278 bta_gattc_pop_command_to_send(p_clcb);
1279 cb_data.write.conn_id = p_clcb->bta_conn_id;
1280 /* write complete, callback */
1281 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1284 /*******************************************************************************
1286 ** Function bta_gattc_exec_cmpl
1288 ** Description execute write complete
1292 *******************************************************************************/
1293 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1296 //free the command data store in the queue.
1297 bta_gattc_free_command_data(p_clcb);
1298 bta_gattc_pop_command_to_send(p_clcb);
1299 p_clcb->status = BTA_GATT_OK;
1301 /* execute complete, callback */
1302 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1303 cb_data.exec_cmpl.status = p_data->status;
1305 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1309 /*******************************************************************************
1311 ** Function bta_gattc_cfg_mtu_cmpl
1313 ** Description configure MTU operation complete
1317 *******************************************************************************/
1318 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1321 //free the command data store in the queue.
1322 bta_gattc_free_command_data(p_clcb);
1323 bta_gattc_pop_command_to_send(p_clcb);
1325 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) {
1326 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1329 /* configure MTU complete, callback */
1330 p_clcb->status = p_data->status;
1331 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1332 cb_data.cfg_mtu.status = p_data->status;
1333 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1335 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data);
1338 /*******************************************************************************
1340 ** Function bta_gattc_op_cmpl
1342 ** Description operation completed.
1346 *******************************************************************************/
1347 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1349 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1350 UINT8 mapped_op = 0;
1352 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1354 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
1355 APPL_TRACE_ERROR("unexpected operation, ignored");
1356 } else if (op >= GATTC_OPTYPE_READ) {
1357 if (p_clcb->p_q_cmd == NULL) {
1358 APPL_TRACE_ERROR("No pending command");
1361 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
1362 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) {
1363 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1364 if ( mapped_op > GATTC_OPTYPE_INDICATION) {
1368 #if (BT_TRACE_VERBOSE == TRUE)
1369 APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1370 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1371 bta_gattc_op_code_name[op]);
1373 APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1374 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1380 /* discard responses if service change indication is received before operation completed */
1381 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg) {
1382 APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1383 p_data->op_cmpl.status = GATT_ERROR;
1386 /* service handle change void the response, discard it */
1387 if (op == GATTC_OPTYPE_READ) {
1388 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1391 else if (op == GATTC_OPTYPE_WRITE) {
1392 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1395 else if (op == GATTC_OPTYPE_EXE_WRITE) {
1396 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1399 else if (op == GATTC_OPTYPE_CONFIG) {
1400 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1403 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1404 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1405 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1409 /*******************************************************************************
1411 ** Function bta_gattc_op_cmpl
1413 ** Description operation completed.
1417 *******************************************************************************/
1418 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1422 /* receive op complete when discovery is started, ignore the response,
1423 and wait for discovery finish and resent */
1424 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1427 /*******************************************************************************
1429 ** Function bta_gattc_search
1431 ** Description start a search in the local server cache
1435 *******************************************************************************/
1436 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1438 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1440 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
1441 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1442 status = BTA_GATT_OK;
1443 /* search the local cache of a server device */
1444 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1446 cb_data.search_cmpl.status = status;
1447 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1449 /* end of search or no server cache available */
1450 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1452 /*******************************************************************************
1454 ** Function bta_gattc_q_cmd
1456 ** Description enqueue a command into control block, usually because discovery
1457 ** operation is busy.
1461 *******************************************************************************/
1462 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1464 bta_gattc_enqueue(p_clcb, p_data);
1466 /*******************************************************************************
1468 ** Function bta_gattc_pop_command_to_send
1470 ** Description dequeue a command into control block.
1471 ** Check if there has command pending in the command queue or not,
1472 ** if there has command pending in the command queue, sent it to the state machine to decision
1473 ** should be sent it to the remote device or not.
1477 *******************************************************************************/
1478 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb)
1480 if (!list_is_empty(p_clcb->p_cmd_list)) {
1481 list_node_t *node = list_begin(p_clcb->p_cmd_list);
1482 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1483 if (p_data != NULL) {
1484 /* execute pending operation of link block still present */
1485 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1486 // The data to be sent to the gattc state machine for processing
1487 if(bta_gattc_sm_execute(p_clcb, p_data->hdr.event, p_data)) {
1488 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1491 if (p_clcb->is_full) {
1492 tBTA_GATTC cb_data = {0};
1493 p_clcb->is_full = FALSE;
1494 cb_data.status = GATT_SUCCESS;
1495 cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
1496 cb_data.queue_full.is_full = FALSE;
1497 if (p_clcb->p_rcb->p_cback != NULL) {
1498 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
1505 /*******************************************************************************
1507 ** Function bta_gattc_free_command_data
1509 ** Description free the command data into control block.
1513 *******************************************************************************/
1514 void bta_gattc_free_command_data(tBTA_GATTC_CLCB *p_clcb)
1516 assert(p_clcb->p_cmd_list);
1517 //Check the list is empty or not.
1518 if (!list_is_empty(p_clcb->p_cmd_list)) {
1519 /* 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
1520 command queue,should remove it from the list */
1521 for (list_node_t *node = list_begin(p_clcb->p_cmd_list); node != list_end(p_clcb->p_cmd_list);
1522 node = list_next(node)) {
1523 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1524 if (p_data == p_clcb->p_q_cmd) {
1525 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1526 p_clcb->p_q_cmd = NULL;
1531 osi_free(p_clcb->p_q_cmd);
1532 p_clcb->p_q_cmd = NULL;
1534 osi_free(p_clcb->p_q_cmd);
1535 p_clcb->p_q_cmd = NULL;
1539 /*******************************************************************************
1541 ** Function bta_gattc_fail
1543 ** Description report API call failure back to apps
1547 *******************************************************************************/
1548 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1552 if (p_clcb->status == BTA_GATT_OK) {
1553 APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1557 /*******************************************************************************
1559 ** Function bta_gattc_deregister_cmpl
1561 ** Description De-Register a GATT client application with BTA completed.
1565 *******************************************************************************/
1566 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1568 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
1569 tBTA_GATTC_IF client_if = p_clreg->client_if;
1571 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
1573 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1575 GATT_Deregister(p_clreg->client_if);
1576 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1578 cb_data.reg_oper.client_if = client_if;
1579 cb_data.reg_oper.status = BTA_GATT_OK;
1582 /* callback with de-register event */
1584 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
1587 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) {
1588 p_cb->state = BTA_GATTC_STATE_DISABLED;
1592 /*******************************************************************************
1594 ** Function bta_gattc_conn_cback
1596 ** Description callback functions to GATT client stack.
1600 *******************************************************************************/
1601 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1602 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1603 tBT_TRANSPORT transport)
1605 tBTA_GATTC_DATA *p_buf;
1606 BOOLEAN start_ccc_timer = FALSE;
1607 tBTA_GATTC_CONN *p_conn = NULL;
1608 tBTA_GATTC_FIND_SERVICE_CB result;
1611 APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1612 __FUNCTION__, gattc_if, connected, conn_id, reason);
1615 if (connected == TRUE){
1616 p_conn = bta_gattc_conn_find_alloc(bda);
1618 else if (connected == FALSE){
1619 p_conn = bta_gattc_conn_find(bda);
1622 if (p_conn == NULL){
1623 APPL_TRACE_ERROR("p_conn is NULL in %s\n", __func__);
1626 if ((transport == BT_TRANSPORT_LE) && (connected == TRUE) && (p_conn != NULL) \
1627 && (p_conn->service_change_ccc_written == FALSE) && (p_conn->ccc_timer_used == FALSE)) {
1628 result = bta_gattc_register_service_change_notify(conn_id, bda, &start_ccc_timer);
1629 if (start_ccc_timer == TRUE) {
1630 TIMER_LIST_ENT *ccc_timer = &(p_conn->service_change_ccc_timer);
1631 /* start a 1000ms timer to wait for service discovery finished */
1632 bta_gattc_start_service_change_ccc_timer(conn_id, bda, 1000, 0, result, ccc_timer);
1633 p_conn->ccc_timer_used = TRUE;
1636 /* Has written service change ccc; or service change ccc doesn't exist in remote device's gatt database */
1637 p_conn->service_change_ccc_written = TRUE;
1638 p_conn->ccc_timer_used = FALSE;
1642 else if ((transport == BT_TRANSPORT_LE) && (connected == FALSE) && (p_conn != NULL)){
1643 p_conn->service_change_ccc_written = FALSE;
1644 if (p_conn->ccc_timer_used == TRUE){
1645 assert(bta_gattc_cb.write_ccc_mutex != NULL);
1646 osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
1648 if (p_conn->service_change_ccc_timer.param != 0) {
1649 osi_free((void *)p_conn->service_change_ccc_timer.param);
1650 p_conn->service_change_ccc_timer.param = (TIMER_PARAM_TYPE)0;
1652 bta_sys_stop_timer(&(p_conn->service_change_ccc_timer));
1653 p_conn->ccc_timer_used = FALSE;
1654 osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
1659 bdcpy(bdaddr.address, bda);
1661 if ((p_buf = (tBTA_GATTC_DATA *) osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1662 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1664 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT :
1665 BTA_GATTC_INT_DISCONN_EVT;
1666 p_buf->int_conn.hdr.layer_specific = conn_id;
1667 p_buf->int_conn.client_if = gattc_if;
1668 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1669 p_buf->int_conn.reason = reason;
1670 p_buf->int_conn.transport = transport;
1671 bdcpy(p_buf->int_conn.remote_bda, bda);
1673 bta_sys_sendmsg(p_buf);
1677 /*******************************************************************************
1679 ** Function bta_gattc_enc_cmpl_cback
1681 ** Description encryption complete callback function to GATT client stack.
1685 *******************************************************************************/
1686 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1688 tBTA_GATTC_DATA *p_buf;
1689 tBTA_GATTC_CLCB *p_clcb = NULL;
1691 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) {
1695 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1696 /* filter this event just for BTA HH LE GATT client,
1697 In the future, if we want to enable encryption complete event
1698 for all GATT clients, we can remove this code */
1699 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
1704 APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1706 if ((p_buf = (tBTA_GATTC_DATA *) osi_calloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1707 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1709 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1710 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1711 p_buf->enc_cmpl.client_if = gattc_if;
1712 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1714 bta_sys_sendmsg(p_buf);
1718 /*******************************************************************************
1720 ** Function bta_gattc_process_api_refresh
1722 ** Description process refresh API to delete cache and start a new discovery
1723 ** if currently connected.
1727 *******************************************************************************/
1728 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1730 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1731 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1732 BOOLEAN found = FALSE;
1736 if (p_srvc_cb != NULL) {
1737 /* try to find a CLCB */
1738 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
1739 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
1740 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
1746 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1750 /* in all other cases, mark it and delete the cache */
1751 if (p_srvc_cb->p_srvc_cache != NULL) {
1752 list_free(p_srvc_cb->p_srvc_cache);
1753 p_srvc_cb->p_srvc_cache = NULL;
1756 /* used to reset cache in application */
1757 bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
1760 /*******************************************************************************
1762 ** Function bta_gattc_process_srvc_chg_ind
1764 ** Description process service change indication.
1768 *******************************************************************************/
1769 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1770 tBTA_GATTC_RCB *p_clrcb,
1771 tBTA_GATTC_SERV *p_srcb,
1772 tBTA_GATTC_CLCB *p_clcb,
1773 tBTA_GATTC_NOTIFY *p_notify,
1774 tGATT_VALUE *att_value)
1776 tBT_UUID gattp_uuid, srvc_chg_uuid;
1777 BOOLEAN processed = FALSE;
1781 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1783 srvc_chg_uuid.len = 2;
1784 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1786 const tBTA_GATTC_CHARACTERISTIC *p_char = bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
1787 if (p_char && bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, TRUE) &&
1788 bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, TRUE)) {
1789 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
1790 APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
1794 UINT8 *p = att_value->value;
1795 UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
1796 UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
1798 APPL_TRACE_ERROR("%s: service changed s_handle:0x%04x e_handle:0x%04x",
1799 __func__, s_handle, e_handle);
1802 /* mark service handle change pending */
1803 p_srcb->srvc_hdl_chg = TRUE;
1804 /* clear up all notification/indication registration */
1805 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
1806 /* service change indication all received, do discovery update */
1807 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
1808 /* not an opened connection; or connection busy */
1809 /* search for first available clcb and start discovery */
1810 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
1811 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) {
1812 if (bta_gattc_cb.clcb[i].in_use &&
1813 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1814 bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
1815 p_clcb = &bta_gattc_cb.clcb[i];
1820 /* send confirmation here if this is an indication, it should always be */
1821 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
1823 /* if connection available, refresh cache by doing discovery now */
1824 if (p_clcb != NULL) {
1825 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1828 /* notify applicationf or service change */
1829 if (p_clrcb->p_cback != NULL) {
1830 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda);
1838 /*******************************************************************************
1840 ** Function bta_gattc_proc_other_indication
1842 ** Description process all non-service change indication/notification.
1846 *******************************************************************************/
1847 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
1848 tGATT_CL_COMPLETE *p_data,
1849 tBTA_GATTC_NOTIFY *p_notify)
1851 APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check p_data->att_value.handle=%d p_data->handle=%d",
1852 p_data->att_value.handle, p_data->handle);
1853 APPL_TRACE_DEBUG("is_notify %d", p_notify->is_notify);
1855 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
1856 p_notify->len = p_data->att_value.len;
1857 bdcpy(p_notify->bda, p_clcb->bda);
1858 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
1859 p_notify->conn_id = p_clcb->bta_conn_id;
1861 if (p_clcb->p_rcb->p_cback) {
1862 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
1866 /*******************************************************************************
1868 ** Function bta_gattc_process_indicate
1870 ** Description process indication/notification.
1874 *******************************************************************************/
1875 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
1877 UINT16 handle = p_data->att_value.handle;
1878 tBTA_GATTC_CLCB *p_clcb ;
1879 tBTA_GATTC_RCB *p_clrcb = NULL;
1880 tBTA_GATTC_SERV *p_srcb = NULL;
1881 tBTA_GATTC_NOTIFY notify;
1883 tBTA_GATTC_IF gatt_if;
1884 tBTA_TRANSPORT transport;
1886 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
1887 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
1888 if (op == GATTC_OPTYPE_INDICATION) {
1889 GATTC_SendHandleValueConfirm(conn_id, handle);
1894 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) {
1895 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
1896 if (op == GATTC_OPTYPE_INDICATION) {
1897 GATTC_SendHandleValueConfirm(conn_id, handle);
1902 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
1903 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore", __func__);
1904 if (op == GATTC_OPTYPE_INDICATION) {
1905 GATTC_SendHandleValueConfirm(conn_id, handle);
1910 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1912 notify.handle = handle;
1913 /* if non-service change indication/notification, forward to application */
1914 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value)) {
1915 /* if app registered for the notification */
1916 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
1917 /* connection not open yet */
1918 if (p_clcb == NULL) {
1919 p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
1921 if (p_clcb == NULL) {
1922 APPL_TRACE_ERROR("No resources");
1926 p_clcb->bta_conn_id = conn_id;
1927 p_clcb->transport = transport;
1929 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
1932 if (p_clcb != NULL) {
1933 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
1935 } else if (op == GATTC_OPTYPE_INDICATION) {
1936 /* no one intersted and need ack? */
1937 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
1938 GATTC_SendHandleValueConfirm(conn_id, handle);
1942 /*******************************************************************************
1944 ** Function bta_gattc_cmpl_cback
1946 ** Description client operation complete callback register with BTE GATT.
1950 *******************************************************************************/
1951 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
1952 tGATT_CL_COMPLETE *p_data)
1954 tBTA_GATTC_CLCB *p_clcb;
1955 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
1956 conn_id, op, status);
1958 /* notification and indication processed right away */
1959 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
1960 bta_gattc_process_indicate(conn_id, op, p_data);
1963 /* for all other operation, not expected if w/o connection */
1964 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) {
1965 APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
1969 /* if over BR_EDR, inform PM for mode change */
1970 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1971 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1972 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1975 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
1978 /*******************************************************************************
1980 ** Function bta_gattc_cmpl_sendmsg
1982 ** Description client operation complete send message
1986 *******************************************************************************/
1987 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
1988 tBTA_GATT_STATUS status,
1989 tGATT_CL_COMPLETE *p_data)
1991 const UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
1992 tBTA_GATTC_OP_CMPL *p_buf = (tBTA_GATTC_OP_CMPL *) osi_malloc(len);
1994 if (p_buf != NULL) {
1995 memset(p_buf, 0, len);
1996 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
1997 p_buf->hdr.layer_specific = conn_id;
1998 p_buf->status = status;
1999 p_buf->op_code = op;
2001 if (p_data != NULL) {
2002 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2003 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2006 bta_sys_sendmsg(p_buf);
2010 /*******************************************************************************
2012 ** Function bta_gattc_cong_cback
2014 ** Description congestion callback for BTA GATT client.
2018 ********************************************************************************/
2019 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2021 tBTA_GATTC_CLCB *p_clcb;
2024 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL) {
2025 if (p_clcb->p_rcb->p_cback) {
2026 cb_data.congest.conn_id = conn_id;
2027 cb_data.congest.congested = congested;
2029 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
2034 #if BLE_INCLUDED == TRUE
2035 /*******************************************************************************
2037 ** Function bta_gattc_init_clcb_conn
2039 ** Description Initaite a BTA CLCB connection
2043 ********************************************************************************/
2044 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2046 tBTA_GATTC_CLCB *p_clcb = NULL;
2047 tBTA_GATTC_DATA gattc_data;
2050 /* should always get the connection ID */
2051 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) {
2052 APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2056 /* initaite a new connection here */
2057 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
2058 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2060 gattc_data.api_conn.client_if = cif;
2061 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2062 gattc_data.api_conn.is_direct = TRUE;
2064 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2066 APPL_TRACE_ERROR("No resources");
2069 /*******************************************************************************
2071 ** Function bta_gattc_process_listen_all
2073 ** Description process listen all, send open callback to application for all
2074 ** connected slave LE link.
2078 ********************************************************************************/
2079 void bta_gattc_process_listen_all(UINT8 cif)
2082 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
2084 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
2085 if (p_conn->in_use ) {
2086 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) {
2087 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2089 /* else already connected */
2093 /*******************************************************************************
2095 ** Function bta_gattc_listen
2097 ** Description Start or stop a listen for connection
2101 ********************************************************************************/
2102 void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2104 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2108 cb_data.reg_oper.status = BTA_GATT_ERROR;
2109 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2111 if (p_clreg == NULL) {
2112 APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2113 p_msg->api_listen.client_if);
2116 /* mark bg conn record */
2117 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2118 (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2119 p_msg->api_listen.start,
2121 if (!GATT_Listen(p_msg->api_listen.client_if,
2122 p_msg->api_listen.start,
2123 p_msg->api_listen.remote_bda)) {
2124 APPL_TRACE_ERROR("Listen failure");
2125 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2127 cb_data.status = BTA_GATT_OK;
2129 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2131 if (p_msg->api_listen.start) {
2132 /* if listen to a specific target */
2133 if (p_msg->api_listen.remote_bda != NULL) {
2135 /* if is a connected remote device */
2136 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2137 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2138 p_msg->api_listen.remote_bda,
2139 BTA_GATT_TRANSPORT_LE) == NULL) {
2141 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2142 p_msg->api_listen.remote_bda);
2145 /* if listen to all */
2147 LOG_DEBUG("Listen For All now");
2148 /* go through all connected device and send
2149 callback for all connected slave connection */
2150 bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2157 /*******************************************************************************
2159 ** Function bta_gattc_broadcast
2161 ** Description Start or stop broadcasting
2165 ********************************************************************************/
2166 void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2168 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2172 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2173 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
2174 //TODO need modify callback if used
2175 if (p_clreg && p_clreg->p_cback) {
2176 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2180 /*******************************************************************************
2182 ** Function bta_gattc_start_service_change_ccc_timer
2184 ** Description start a timer to wait for service change ccc discovered
2188 *******************************************************************************/
2189 void bta_gattc_start_service_change_ccc_timer(UINT16 conn_id, BD_ADDR bda,UINT32 timeout_ms,
2190 UINT8 timer_cnt, UINT8 last_status, TIMER_LIST_ENT *ccc_timer)
2192 tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) osi_malloc(sizeof(tBTA_GATTC_WAIT_CCC_TIMER));
2193 if (p_timer_param != NULL) {
2194 p_timer_param->conn_id = conn_id;
2195 memcpy(p_timer_param->remote_bda, bda, sizeof(BD_ADDR));
2196 p_timer_param->count = timer_cnt;
2197 p_timer_param->last_status = last_status;
2198 ccc_timer->param = (UINT32)p_timer_param;
2199 ccc_timer->p_cback = (TIMER_CBACK *)&bta_gattc_wait4_service_change_ccc_cback;
2200 bta_sys_start_timer(ccc_timer, 0, timeout_ms);
2203 APPL_TRACE_ERROR("%s, allocate p_timer_param failed\n", __func__);
2207 /*******************************************************************************
2209 ** Function bta_gattc_register_service_change_notify
2211 ** Description Find remote device's gatt service change characteristic ccc's handle and write 2 to this
2212 ** this ccc. If not found, start a timer to wait for service discovery finished.
2214 ** Returns Return result of service change ccc service discovery result result and written operate result
2216 *******************************************************************************/
2217 tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda, BOOLEAN *need_timer)
2219 tBTA_GATTC_SERV *p_srcb = NULL;
2220 list_t *p_cache = NULL;
2221 tBTA_GATTC_SERVICE *p_service = NULL;
2222 tBTA_GATTC_CHARACTERISTIC *p_char = NULL;
2223 tBTA_GATTC_DESCRIPTOR *p_desc = NULL;
2224 tGATT_STATUS write_status;
2225 tGATT_VALUE ccc_value;
2226 tBTA_GATTC_FIND_SERVICE_CB result;
2227 BOOLEAN gatt_cache_found = FALSE;
2228 BOOLEAN gatt_service_found = FALSE;
2229 BOOLEAN gatt_service_change_found = FALSE;
2230 BOOLEAN gatt_ccc_found = FALSE;
2231 BOOLEAN start_find_ccc_timer = FALSE;
2233 tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
2234 tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
2235 tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
2237 p_srcb = bta_gattc_find_srcb(remote_bda);
2238 if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
2239 p_cache = p_srcb->p_srvc_cache;
2240 gatt_cache_found = TRUE;
2243 start_find_ccc_timer = TRUE;
2244 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2246 /* start to find gatt service */
2247 if (gatt_cache_found == TRUE) {
2248 for (list_node_t *sn = list_begin(p_cache);
2249 sn != list_end(p_cache); sn = list_next(sn)) {
2250 p_service = list_node(sn);
2251 if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_service->uuid, TRUE)) {
2252 gatt_service_found = TRUE;
2258 start_find_ccc_timer = TRUE;
2259 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2262 /* start to find gatt service change characteristic */
2263 if (gatt_service_found == TRUE) {
2264 if (p_service->characteristics) {
2265 for (list_node_t *cn = list_begin(p_service->characteristics);
2266 cn != list_end(p_service->characteristics); cn = list_next(cn)) {
2267 p_char = list_node(cn);
2268 if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_char->uuid, TRUE)) {
2269 gatt_service_change_found = TRUE;
2275 else if (gatt_cache_found == TRUE) {
2276 /* Gatt service not found, start a timer to wait for service discovery */
2277 start_find_ccc_timer = TRUE;
2278 result = SERVICE_CHANGE_SERVICE_NOT_FOUND;
2280 /* start to find gatt service change characteristic ccc */
2281 if (gatt_service_change_found == TRUE) {
2282 if (p_char->descriptors) {
2283 for (list_node_t *dn = list_begin(p_char->descriptors);
2284 dn != list_end(p_char->descriptors); dn = list_next(dn)) {
2285 p_desc = list_node(dn);
2286 if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_desc->uuid, TRUE)) {
2287 gatt_ccc_found = TRUE;
2293 else if (gatt_service_found ==TRUE) {
2294 /* Gatt service found, but service change char not found,
2295 * Case1: remote device doesn't have service change char, we don't need to start a timer here to
2296 * wait for service discovery
2297 * Case2: remote device exist service change char, we have found gatt service, but have not found
2298 * service change char, we need to start a timer here*/
2299 start_find_ccc_timer = TRUE;
2300 result = SERVICE_CHANGE_CHAR_NOT_FOUND;
2303 if (gatt_ccc_found == TRUE){
2304 ccc_value.handle = p_desc->handle;
2306 ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION;
2307 ccc_value.auth_req = GATT_AUTH_REQ_NONE;
2308 if (gatt_is_clcb_allocated(conn_id)) {
2309 APPL_TRACE_DEBUG("%s, GATTC_Write GATT_BUSY conn_id = %d", __func__, conn_id);
2310 write_status = GATT_BUSY;
2312 write_status = GATTC_Write (conn_id, GATT_WRITE, &ccc_value);
2314 if (write_status != GATT_SUCCESS) {
2315 start_find_ccc_timer = TRUE;
2316 result = SERVICE_CHANGE_WRITE_CCC_FAILED;
2319 start_find_ccc_timer = FALSE;
2320 result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
2323 else if (gatt_service_change_found == TRUE) {
2324 /* Gatt service char found, but service change char ccc not found,
2325 * Case1: remote device doesn't have service change char ccc, we don't need to start a timer here to
2326 * wait for service discovery
2327 * Case2: remote device exist service change char ccc, we have found gatt service change char, but have not found
2328 * service change char ccc, we need to start a timer here */
2329 start_find_ccc_timer = TRUE;
2330 result = SERVICE_CHANGE_CCC_NOT_FOUND;
2333 if (need_timer != NULL) {
2334 *need_timer = start_find_ccc_timer;
2340 /*******************************************************************************
2342 ** Function bta_gattc_wait4_service_change_ccc_cback
2344 ** Description callback function of service_change_ccc_timer
2348 *******************************************************************************/
2349 static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle)
2351 tBTA_GATTC_FIND_SERVICE_CB result;
2352 BOOLEAN start_ccc_timer = FALSE;
2355 assert(bta_gattc_cb.write_ccc_mutex != NULL);
2356 osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
2358 tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) p_tle->param;
2359 p_tle->param = (TIMER_PARAM_TYPE)0;
2360 if (p_timer_param == NULL){
2361 APPL_TRACE_ERROR("p_timer_param is NULL in %s\n", __func__);
2362 osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
2366 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_timer_param->remote_bda);
2367 if (p_conn == NULL){
2368 APPL_TRACE_ERROR("p_conn is NULL in %s\n", __func__);
2369 osi_free(p_timer_param);
2370 osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
2374 result = bta_gattc_register_service_change_notify(p_timer_param->conn_id, p_timer_param->remote_bda, &start_ccc_timer);
2375 /* If return SERVICE_CHANGE_CHAR_NOT_FOUND or SERVICE_CHANGE_CCC_NOT_FOUND twice, means remote device doesn't have
2376 * service change char or ccc, stop timer */
2377 if ((result == p_timer_param->last_status) \
2378 && ((result == SERVICE_CHANGE_CHAR_NOT_FOUND) || (result == SERVICE_CHANGE_CCC_NOT_FOUND))){
2379 start_ccc_timer = FALSE;
2382 if ((start_ccc_timer == TRUE) && (p_timer_param->count < 10)){
2383 TIMER_LIST_ENT *ccc_timer = &(p_conn->service_change_ccc_timer);
2384 if (result == SERVICE_CHANGE_WRITE_CCC_FAILED){
2385 /* retry to write service change ccc, needn't to add counter */
2389 /* retry to find service change ccc */
2391 p_timer_param->count ++;
2393 bta_gattc_start_service_change_ccc_timer(p_timer_param->conn_id, p_timer_param->remote_bda, \
2394 new_timeout, p_timer_param->count, result, ccc_timer);
2397 p_conn->ccc_timer_used = FALSE;
2398 p_conn->service_change_ccc_written = TRUE;
2401 osi_free(p_timer_param);
2402 osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
2406 #endif ///GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE