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 ******************************************************************************/
26 #define LOG_TAG "bt_bta_gattc"
30 #include "bt_target.h"
31 #include "bta_gattc_int.h"
33 #include "btif/include/btif_debug_conn.h"
34 #include "bt_common.h"
36 #include "osi/include/log.h"
37 #include "stack/l2cap/l2c_int.h"
40 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
41 #include "bta_hh_int.h"
44 #if BTA_GATT_INCLUDED && BLE_INCLUDED == TRUE
46 /*****************************************************************************
48 *****************************************************************************/
49 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
50 BOOLEAN connected, tGATT_DISCONN_REASON reason,
51 tBT_TRANSPORT transport);
53 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
54 tGATT_CL_COMPLETE *p_data);
55 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
56 tBTA_GATT_STATUS status,
57 tGATT_CL_COMPLETE *p_data);
59 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
60 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
61 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
63 static tGATT_CBACK bta_gattc_cl_cback =
67 bta_gattc_disc_res_cback,
68 bta_gattc_disc_cmpl_cback,
70 bta_gattc_enc_cmpl_cback,
74 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
75 static UINT16 bta_gattc_opcode_to_int_evt[] =
77 BTA_GATTC_API_READ_EVT,
78 BTA_GATTC_API_WRITE_EVT,
79 BTA_GATTC_API_EXEC_EVT,
80 BTA_GATTC_API_CFG_MTU_EVT
83 #if (BT_TRACE_VERBOSE == TRUE)
84 static const char *bta_gattc_op_code_name[] =
96 /*****************************************************************************
98 *****************************************************************************/
100 /*******************************************************************************
102 ** Function bta_gattc_enable
104 ** Description Enables GATTC module
109 *******************************************************************************/
110 static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
112 APPL_TRACE_DEBUG("bta_gattc_enable");
114 if (p_cb->state == BTA_GATTC_STATE_DISABLED)
116 /* initialize control block */
117 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
118 p_cb->state = BTA_GATTC_STATE_ENABLED;
122 APPL_TRACE_DEBUG("GATTC is arelady enabled");
126 /*******************************************************************************
128 ** Function bta_gattc_disable
130 ** Description Disable GATTC module by cleaning up all active connections
131 ** and deregister all application.
135 *******************************************************************************/
136 void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
140 APPL_TRACE_DEBUG("bta_gattc_disable");
142 if (p_cb->state != BTA_GATTC_STATE_ENABLED)
144 APPL_TRACE_ERROR("not enabled or disable in pogress");
148 for (i = 0; i <BTA_GATTC_CL_MAX; i ++)
150 if (p_cb->cl_rcb[i].in_use)
152 p_cb->state = BTA_GATTC_STATE_DISABLING;
153 /* don't deregister HH GATT IF */
154 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
155 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
156 if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) {
158 bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
159 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
165 /* no registered apps, indicate disable completed */
166 if (p_cb->state != BTA_GATTC_STATE_DISABLING)
168 p_cb->state = BTA_GATTC_STATE_DISABLED;
169 memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
173 /*******************************************************************************
175 ** Function bta_gattc_register
177 ** Description Register a GATT client application with BTA.
181 *******************************************************************************/
182 void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
186 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
187 tBTA_GATTC_INT_START_IF *p_buf;
188 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
190 APPL_TRACE_DEBUG("bta_gattc_register state %d",p_cb->state);
191 memset(&cb_data, 0, sizeof(cb_data));
192 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
194 /* check if GATTC module is already enabled . Else enable */
195 if (p_cb->state == BTA_GATTC_STATE_DISABLED)
197 bta_gattc_enable (p_cb);
199 /* todo need to check duplicate uuid */
200 for (i = 0; i < BTA_GATTC_CL_MAX; i ++)
202 if (!p_cb->cl_rcb[i].in_use)
204 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0)
206 APPL_TRACE_ERROR("Register with GATT stack failed.");
207 status = BTA_GATT_ERROR;
211 p_cb->cl_rcb[i].in_use = TRUE;
212 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
213 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
215 /* BTA use the same client interface as BTE GATT statck */
216 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
218 if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_getbuf(sizeof(tBTA_GATTC_INT_START_IF))) != NULL)
220 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
221 p_buf->client_if = p_cb->cl_rcb[i].client_if;
223 bta_sys_sendmsg(p_buf);
224 status = BTA_GATT_OK;
228 GATT_Deregister(p_cb->cl_rcb[i].client_if);
230 status = BTA_GATT_NO_RESOURCES;
231 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
238 /* callback with register event */
239 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 )
263 GATT_StartIf(p_msg->int_start_if.client_if);
267 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)
286 /* remove bg connection associated with this rcb */
287 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++)
289 if (p_cb->bg_track[i].in_use)
291 if (p_cb->bg_track[i].cif_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, FALSE);
294 GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
296 if (p_cb->bg_track[i].cif_adv_mask & (1 <<(p_clreg->client_if - 1)))
298 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
303 if (p_clreg->num_clcb > 0)
305 /* close all CLCB related to this app */
306 for (i= 0; i < BTA_GATTC_CLCB_MAX; i ++)
308 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg))
310 p_clreg->dereg_pending = TRUE;
312 buf.event = BTA_GATTC_API_CLOSE_EVT;
313 buf.layer_specific = p_cb->clcb[i].bta_conn_id;
314 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ;
319 bta_gattc_deregister_cmpl(p_clreg);
323 APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
326 /*******************************************************************************
328 ** Function bta_gattc_process_api_open
330 ** Description process connect API request.
334 *******************************************************************************/
335 void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
337 UINT16 event = ((BT_HDR *)p_msg)->event;
338 tBTA_GATTC_CLCB *p_clcb = NULL;
339 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
344 if (p_msg->api_conn.is_direct)
346 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
347 p_msg->api_conn.remote_bda,
348 p_msg->api_conn.transport)) != NULL)
350 bta_gattc_sm_execute(p_clcb, event, p_msg);
354 APPL_TRACE_ERROR("No resources to open a new connection.");
356 bta_gattc_send_open_cback(p_clreg,
357 BTA_GATT_NO_RESOURCES,
358 p_msg->api_conn.remote_bda,
359 BTA_GATT_INVALID_CONN_ID,
360 p_msg->api_conn.transport, 0);
365 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
370 APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
371 p_msg->api_conn.client_if);
374 /*******************************************************************************
376 ** Function bta_gattc_process_api_open_cancel
378 ** Description process connect API request.
382 *******************************************************************************/
383 void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
385 UINT16 event = ((BT_HDR *)p_msg)->event;
386 tBTA_GATTC_CLCB *p_clcb = NULL;
387 tBTA_GATTC_RCB *p_clreg;
391 if (p_msg->api_cancel_conn.is_direct)
393 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
394 p_msg->api_cancel_conn.remote_bda,
395 BTA_GATT_TRANSPORT_LE)) != NULL)
397 bta_gattc_sm_execute(p_clcb, event, p_msg);
401 APPL_TRACE_ERROR("No such connection need to be cancelled");
403 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
405 if (p_clreg && p_clreg->p_cback)
407 cb_data.status = BTA_GATT_ERROR;
408 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
414 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
419 /*******************************************************************************
421 ** Function bta_gattc_process_enc_cmpl
423 ** Description process encryption complete message.
427 *******************************************************************************/
428 void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
430 tBTA_GATTC_RCB *p_clreg;
434 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
436 if (p_clreg && p_clreg->p_cback)
438 memset(&cb_data, 0, sizeof(tBTA_GATTC));
440 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
441 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
443 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
447 /*******************************************************************************
449 ** Function bta_gattc_cancel_open_error
455 *******************************************************************************/
456 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
461 cb_data.status=BTA_GATT_ERROR;
463 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback )
464 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
467 /*******************************************************************************
469 ** Function bta_gattc_open_error
475 *******************************************************************************/
476 void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
480 APPL_TRACE_ERROR("Connection already opened. wrong state");
482 bta_gattc_send_open_cback(p_clcb->p_rcb,
489 /*******************************************************************************
491 ** Function bta_gattc_open_fail
497 *******************************************************************************/
498 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
502 bta_gattc_send_open_cback(p_clcb->p_rcb,
508 /* open failure, remove clcb */
509 bta_gattc_clcb_dealloc(p_clcb);
512 /*******************************************************************************
514 ** Function bta_gattc_open
516 ** Description Process API connection function.
520 *******************************************************************************/
521 void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
523 tBTA_GATTC_DATA gattc_data;
525 /* open/hold a connection */
526 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
527 TRUE, p_data->api_conn.transport))
529 APPL_TRACE_ERROR("Connection open failure");
531 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
535 /* a connected remote device */
536 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
537 p_data->api_conn.remote_bda,
538 &p_clcb->bta_conn_id,
539 p_data->api_conn.transport))
541 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
543 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
545 /* else wait for the callback event */
548 /*******************************************************************************
550 ** Function bta_gattc_init_bk_conn
552 ** Description Process API Open for a background connection
556 *******************************************************************************/
557 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
559 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
561 tBTA_GATTC_CLCB *p_clcb;
562 tBTA_GATTC_DATA gattc_data;
564 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
566 /* always call open to hold a connection */
567 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport))
569 uint8_t *bda = (uint8_t *)p_data->remote_bda;
570 status = BTA_GATT_ERROR;
571 APPL_TRACE_ERROR("%s unable to connect to remote bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
572 __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
577 status = BTA_GATT_OK;
579 /* if is a connected remote device */
580 if (GATT_GetConnIdIfConnected(p_data->client_if,
585 if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
586 BTA_GATT_TRANSPORT_LE)) != NULL)
588 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
590 /* open connection */
591 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
592 status = BTA_GATT_OK;
598 /* open failure, report OPEN_EVT */
599 if (status != BTA_GATT_OK)
601 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
602 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
605 /*******************************************************************************
607 ** Function bta_gattc_cancel_bk_conn
609 ** Description Process API Cancel Open for a background connection
613 *******************************************************************************/
614 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
616 tBTA_GATTC_RCB *p_clreg;
618 cb_data.status = BTA_GATT_ERROR;
620 /* remove the device from the bg connection mask */
621 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE))
623 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE))
625 cb_data.status = BTA_GATT_OK;
629 APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
632 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
634 if (p_clreg && p_clreg->p_cback)
636 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
640 /*******************************************************************************
642 ** Function bta_gattc_int_cancel_open_ok
648 *******************************************************************************/
649 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
654 if ( p_clcb->p_rcb->p_cback )
656 cb_data.status = BTA_GATT_OK;
657 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
660 bta_gattc_clcb_dealloc(p_clcb);
662 /*******************************************************************************
664 ** Function bta_gattc_cancel_open
670 *******************************************************************************/
671 void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
675 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE))
677 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
681 if ( p_clcb->p_rcb->p_cback )
683 cb_data.status = BTA_GATT_ERROR;
684 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
688 /*******************************************************************************
690 ** Function bta_gattc_conn
692 ** Description receive connection callback from stack
696 *******************************************************************************/
697 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
699 tBTA_GATTC_IF gatt_if;
700 APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state);
704 APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
705 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
707 GATT_GetConnectionInfor(p_data->hdr.layer_specific,
708 &gatt_if, p_clcb->bda, &p_clcb->transport);
711 p_clcb->p_srcb->connected = TRUE;
713 if (p_clcb->p_srcb->mtu == 0)
714 p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
716 /* start database cache if needed */
717 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
718 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE)
720 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
722 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
723 bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL);
725 else /* cache is building */
726 p_clcb->state = BTA_GATTC_DISCOVER_ST;
731 /* a pending service handle change indication */
732 if (p_clcb->p_srcb->srvc_hdl_chg)
734 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
735 /* start discovery */
736 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
742 /* there is no RM for GATT */
743 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
744 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
746 bta_gattc_send_open_cback(p_clcb->p_rcb,
751 p_clcb->p_srcb->mtu);
754 /*******************************************************************************
756 ** Function bta_gattc_close_fail
758 ** Description close a connection.
762 *******************************************************************************/
763 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
767 if ( p_clcb->p_rcb->p_cback )
769 memset(&cb_data, 0, sizeof(tBTA_GATTC));
770 cb_data.close.client_if = p_clcb->p_rcb->client_if;
771 cb_data.close.conn_id = p_data->hdr.layer_specific;
772 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
773 cb_data.close.status = BTA_GATT_ERROR;
774 cb_data.close.reason = BTA_GATT_CONN_NONE;
776 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
779 /*******************************************************************************
781 ** Function bta_gattc_api_close
783 ** Description close a GATTC connection.
787 *******************************************************************************/
788 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
790 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
791 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
794 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id);
796 cb_data.close.client_if = p_clcb->p_rcb->client_if;
797 cb_data.close.conn_id = p_clcb->bta_conn_id;
798 cb_data.close.reason = p_clcb->reason;
799 cb_data.close.status = p_clcb->status;
800 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
802 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
803 bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda);
805 bta_gattc_clcb_dealloc(p_clcb);
807 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
809 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
811 else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT)
813 cb_data.close.status = p_data->int_conn.reason;
814 cb_data.close.reason = p_data->int_conn.reason;
818 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
820 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending)
822 bta_gattc_deregister_cmpl(p_clreg);
825 /*******************************************************************************
827 ** Function bta_gattc_reset_discover_st
829 ** Description when a SRCB finished discovery, tell all related clcb.
833 *******************************************************************************/
834 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
836 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
839 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++)
841 if (p_cb->clcb[i].p_srcb == p_srcb)
843 p_cb->clcb[i].status = status;
844 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
848 /*******************************************************************************
850 ** Function bta_gattc_disc_close
852 ** Description close a GATTC connection while in discovery state.
856 *******************************************************************************/
857 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
859 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
860 p_clcb->bta_conn_id);
862 if (p_clcb->disc_active)
863 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
865 p_clcb->state = BTA_GATTC_CONN_ST;
867 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
868 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
869 // connection itself still needs to be closed to resolve the original event.
870 if (p_clcb->state == BTA_GATTC_CONN_ST)
872 APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
873 "Trigger connection close");
874 bta_gattc_close(p_clcb, p_data);
877 /*******************************************************************************
879 ** Function bta_gattc_set_discover_st
881 ** Description when a SRCB start discovery, tell all related clcb and set
886 *******************************************************************************/
887 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
889 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
892 #if BLE_INCLUDED == TRUE
893 L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE);
895 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++)
897 if (p_cb->clcb[i].p_srcb == p_srcb)
899 p_cb->clcb[i].status = BTA_GATT_OK;
900 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
904 /*******************************************************************************
906 ** Function bta_gattc_restart_discover
908 ** Description process service change in discovery state, mark up the auto
909 ** update flag and set status to be discovery cancel for current
914 *******************************************************************************/
915 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
919 p_clcb->status = BTA_GATT_CANCEL;
920 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
923 /*******************************************************************************
925 ** Function bta_gattc_cfg_mtu
927 ** Description Configure MTU size on the GATT connection.
931 *******************************************************************************/
932 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
934 tBTA_GATT_STATUS status;
936 if (bta_gattc_enqueue(p_clcb, p_data))
938 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id, p_data->api_mtu.mtu);
940 /* if failed, return callback here */
941 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED)
943 /* Dequeue the data, if it was enqueued */
944 if (p_clcb->p_q_cmd == p_data)
945 p_clcb->p_q_cmd = NULL;
947 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
951 /*******************************************************************************
953 ** Function bta_gattc_start_discover
955 ** Description Start a discovery on server.
959 *******************************************************************************/
960 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
964 APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
965 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
967 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
968 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
969 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC)
970 /* no pending operation, start discovery right away */
972 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
974 if (p_clcb->p_srcb != NULL)
976 /* clear the service change mask */
977 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
978 p_clcb->p_srcb->update_count = 0;
979 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
981 if (p_clcb->transport == BTA_TRANSPORT_LE)
982 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
984 /* set all srcb related clcb into discovery ST */
985 bta_gattc_set_discover_st(p_clcb->p_srcb);
987 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK)
989 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
990 p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
992 if (p_clcb->status != BTA_GATT_OK)
994 APPL_TRACE_ERROR("discovery on server failed");
995 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
998 p_clcb->disc_active = TRUE;
1002 APPL_TRACE_ERROR("unknown device, can not start discovery");
1005 /* pending operation, wait until it finishes */
1008 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
1010 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
1011 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
1015 /*******************************************************************************
1017 ** Function bta_gattc_disc_cmpl
1019 ** Description discovery on server is finished
1023 *******************************************************************************/
1024 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1026 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1029 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
1031 #if BLE_INCLUDED == TRUE
1032 if(p_clcb->transport == BTA_TRANSPORT_LE)
1033 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
1035 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1036 p_clcb->disc_active = FALSE;
1038 if (p_clcb->status != GATT_SUCCESS)
1040 /* clean up cache */
1041 if(p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
1043 while (! fixed_queue_is_empty(p_clcb->p_srcb->cache_buffer))
1045 osi_freebuf(fixed_queue_try_dequeue(p_clcb->p_srcb->cache_buffer));
1047 p_clcb->p_srcb->p_srvc_cache = NULL;
1050 /* used to reset cache in application */
1051 bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda);
1053 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
1054 /* release pending attribute list buffer */
1055 osi_freebuf_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
1058 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
1060 /* start discovery again */
1061 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1063 /* get any queued command to proceed */
1064 else if (p_q_cmd != NULL)
1066 p_clcb->p_q_cmd = NULL;
1067 /* execute pending operation of link block still present */
1068 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1069 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1071 /* if the command executed requeued the cmd, we don't
1072 * want to free the underlying buffer that's being
1073 * referenced by p_clcb->p_q_cmd
1075 if (p_q_cmd != p_clcb->p_q_cmd)
1076 osi_freebuf_and_reset((void **)&p_q_cmd);
1079 /*******************************************************************************
1081 ** Function bta_gattc_read
1083 ** Description Read an attribute
1087 *******************************************************************************/
1088 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1091 tGATT_READ_PARAM read_param;
1092 tBTA_GATT_STATUS status;
1094 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1096 if (bta_gattc_enqueue(p_clcb, p_data))
1098 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1099 &p_data->api_read.srvc_id,
1100 &p_data->api_read.char_id,
1101 p_data->api_read.p_descr_type)) == 0)
1103 status = BTA_GATT_ERROR;
1107 read_param.by_handle.handle = handle;
1108 read_param.by_handle.auth_req = p_data->api_read.auth_req;
1110 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1114 if (status != BTA_GATT_OK)
1116 /* Dequeue the data, if it was enqueued */
1117 if (p_clcb->p_q_cmd == p_data)
1118 p_clcb->p_q_cmd = NULL;
1120 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1124 /*******************************************************************************
1126 ** Function bta_gattc_read_multi
1128 ** Description read multiple
1131 *********************************************************************************/
1132 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1135 tBTA_GATT_STATUS status = BTA_GATT_OK;
1136 tGATT_READ_PARAM read_param;
1137 tBTA_GATTC_ATTR_ID *p_id;
1139 if (bta_gattc_enqueue(p_clcb, p_data))
1141 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1143 p_id = p_data->api_read_multi.p_id_list;
1145 for (i = 0; i < p_data->api_read_multi.num_attr && p_id; i ++, p_id ++)
1149 if (p_id->id_type == BTA_GATT_TYPE_CHAR)
1151 handle = bta_gattc_id2handle(p_clcb->p_srcb,
1152 &p_id->id_value.char_id.srvc_id,
1153 &p_id->id_value.char_id.char_id,
1156 else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR)
1158 handle = bta_gattc_id2handle(p_clcb->p_srcb,
1159 &p_id->id_value.char_descr_id.char_id.srvc_id,
1160 &p_id->id_value.char_descr_id.char_id.char_id,
1161 &p_id->id_value.char_descr_id.descr_id);
1165 APPL_TRACE_ERROR("invalud ID type: %d", p_id->id_type);
1170 status = BTA_GATT_ERROR;
1174 if (status == BTA_GATT_OK)
1176 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1177 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1179 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1183 if (status != BTA_GATT_OK)
1185 /* Dequeue the data, if it was enqueued */
1186 if (p_clcb->p_q_cmd == p_data)
1187 p_clcb->p_q_cmd = NULL;
1189 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1193 /*******************************************************************************
1195 ** Function bta_gattc_write
1197 ** Description Write an attribute
1201 *******************************************************************************/
1202 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1205 tGATT_VALUE attr = {0};
1206 tBTA_GATT_STATUS status = BTA_GATT_OK;
1208 if (bta_gattc_enqueue(p_clcb, p_data))
1210 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1211 &p_data->api_write.srvc_id,
1212 &p_data->api_write.char_id,
1213 p_data->api_write.p_descr_type)) == 0)
1215 status = BTA_GATT_ERROR;
1219 attr.handle= handle;
1220 attr.offset = p_data->api_write.offset;
1221 attr.len = p_data->api_write.len;
1222 attr.auth_req = p_data->api_write.auth_req;
1224 if (p_data->api_write.p_value)
1225 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1227 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1231 if (status != BTA_GATT_OK)
1233 /* Dequeue the data, if it was enqueued */
1234 if (p_clcb->p_q_cmd == p_data)
1235 p_clcb->p_q_cmd = NULL;
1237 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
1241 /*******************************************************************************
1243 ** Function bta_gattc_execute
1245 ** Description send execute write
1248 *********************************************************************************/
1249 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1251 tBTA_GATT_STATUS status;
1253 if (bta_gattc_enqueue(p_clcb, p_data))
1255 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1257 if (status != BTA_GATT_OK)
1259 /* Dequeue the data, if it was enqueued */
1260 if (p_clcb->p_q_cmd == p_data)
1261 p_clcb->p_q_cmd = NULL;
1263 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
1267 /*******************************************************************************
1269 ** Function bta_gattc_confirm
1271 ** Description send handle value confirmation
1275 *******************************************************************************/
1276 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1280 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1281 &p_data->api_confirm.srvc_id,
1282 &p_data->api_confirm.char_id,
1285 APPL_TRACE_ERROR("Can not map service/char ID into valid handle");
1289 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1292 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1296 /* if over BR_EDR, inform PM for mode change */
1297 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
1299 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1300 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1305 /*******************************************************************************
1307 ** Function bta_gattc_read_cmpl
1309 ** Description read complete
1313 *******************************************************************************/
1314 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1318 tBTA_GATT_READ_VAL read_value;
1320 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1321 memset(&read_value, 0, sizeof(tBTA_GATT_READ_VAL));
1323 cb_data.read.status = p_data->status;
1325 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK)
1327 if (bta_gattc_handle2id(p_clcb->p_srcb,
1328 p_data->p_cmpl->att_value.handle,
1329 &cb_data.read.srvc_id,
1330 &cb_data.read.char_id,
1331 &cb_data.read.descr_type) == FALSE)
1333 cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
1334 APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x",
1335 p_data->p_cmpl->att_value.handle);
1339 cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb,
1340 &cb_data.read.descr_type.uuid,
1341 &p_data->p_cmpl->att_value,
1343 cb_data.read.p_value = &read_value;
1348 cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
1349 cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
1350 if (p_clcb->p_q_cmd->api_read.p_descr_type)
1351 memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type,
1352 sizeof(tBTA_GATT_ID));
1355 event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ?
1356 BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
1357 cb_data.read.conn_id = p_clcb->bta_conn_id;
1359 osi_freebuf_and_reset((void **)&p_clcb->p_q_cmd);
1360 /* read complete, callback */
1361 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1364 /*******************************************************************************
1366 ** Function bta_gattc_write_cmpl
1368 ** Description write complete
1372 *******************************************************************************/
1373 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1375 tBTA_GATTC cb_data = {0};
1378 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1380 cb_data.write.status = p_data->status;
1382 if (p_data->p_cmpl != NULL)
1384 bta_gattc_handle2id(p_clcb->p_srcb, p_data->p_cmpl->att_value.handle,
1385 &cb_data.write.srvc_id, &cb_data.write.char_id,
1386 &cb_data.write.descr_type);
1390 memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id,
1391 sizeof(tBTA_GATT_SRVC_ID));
1392 memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id,
1393 sizeof(tBTA_GATT_ID));
1394 if (p_clcb->p_q_cmd->api_write.p_descr_type)
1395 memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type,
1396 sizeof(tBTA_GATT_ID));
1399 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1400 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE)
1402 event = BTA_GATTC_PREP_WRITE_EVT;
1404 else if (p_clcb->p_q_cmd->api_write.p_descr_type == NULL)
1406 event = BTA_GATTC_WRITE_CHAR_EVT;
1409 event = BTA_GATTC_WRITE_DESCR_EVT;
1411 osi_freebuf_and_reset((void **)&p_clcb->p_q_cmd);
1412 cb_data.write.conn_id = p_clcb->bta_conn_id;
1413 /* write complete, callback */
1414 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1417 /*******************************************************************************
1419 ** Function bta_gattc_exec_cmpl
1421 ** Description execute write complete
1425 *******************************************************************************/
1426 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1430 osi_freebuf_and_reset((void **)&p_clcb->p_q_cmd);
1431 p_clcb->status = BTA_GATT_OK;
1433 /* execute complete, callback */
1434 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1435 cb_data.exec_cmpl.status = p_data->status;
1437 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1441 /*******************************************************************************
1443 ** Function bta_gattc_cfg_mtu_cmpl
1445 ** Description configure MTU operation complete
1449 *******************************************************************************/
1450 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1454 osi_freebuf_and_reset((void **)&p_clcb->p_q_cmd);
1456 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK)
1457 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1459 /* configure MTU complete, callback */
1460 p_clcb->status = p_data->status;
1461 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1462 cb_data.cfg_mtu.status = p_data->status;
1463 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1465 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data);
1468 /*******************************************************************************
1470 ** Function bta_gattc_op_cmpl
1472 ** Description operation completed.
1476 *******************************************************************************/
1477 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1479 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1480 UINT8 mapped_op = 0;
1482 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1484 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION)
1486 APPL_TRACE_ERROR("unexpected operation, ignored");
1488 else if (op >= GATTC_OPTYPE_READ)
1490 if (p_clcb->p_q_cmd == NULL)
1492 APPL_TRACE_ERROR("No pending command");
1495 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ])
1497 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1498 if ( mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0;
1500 #if (BT_TRACE_VERBOSE == TRUE)
1501 APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1502 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1503 bta_gattc_op_code_name[op]);
1505 APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1506 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1511 /* discard responses if service change indication is received before operation completed */
1512 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg)
1514 APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1515 p_data->op_cmpl.status = GATT_ERROR;
1518 /* service handle change void the response, discard it */
1519 if (op == GATTC_OPTYPE_READ)
1520 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1522 else if (op == GATTC_OPTYPE_WRITE)
1523 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1525 else if (op == GATTC_OPTYPE_EXE_WRITE)
1526 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1528 else if (op == GATTC_OPTYPE_CONFIG)
1529 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1531 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
1533 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1534 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1538 /*******************************************************************************
1540 ** Function bta_gattc_op_cmpl
1542 ** Description operation completed.
1546 *******************************************************************************/
1547 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1551 /* receive op complete when discovery is started, ignore the response,
1552 and wait for discovery finish and resent */
1553 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1556 /*******************************************************************************
1558 ** Function bta_gattc_search
1560 ** Description start a search in the local server cache
1564 *******************************************************************************/
1565 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1567 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1569 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id);
1570 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
1572 status = BTA_GATT_OK;
1573 /* search the local cache of a server device */
1574 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1576 cb_data.search_cmpl.status = status;
1577 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1579 /* end of search or no server cache available */
1580 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1582 /*******************************************************************************
1584 ** Function bta_gattc_q_cmd
1586 ** Description enqueue a command into control block, usually because discovery
1587 ** operation is busy.
1591 *******************************************************************************/
1592 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1594 bta_gattc_enqueue(p_clcb, p_data);
1596 /*******************************************************************************
1598 ** Function bta_gattc_cache_open
1600 ** Description open a NV cache for loading
1604 *******************************************************************************/
1605 void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1609 bta_gattc_set_discover_st(p_clcb->p_srcb);
1611 APPL_TRACE_DEBUG("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id);
1612 bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,
1613 p_clcb->bta_conn_id, FALSE);
1615 /*******************************************************************************
1617 ** Function bta_gattc_start_load
1619 ** Description start cache loading by sending callout open cache
1623 *******************************************************************************/
1624 void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1626 APPL_TRACE_DEBUG("bta_gattc_ci_open conn_id=%d server state=%d" ,
1627 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
1628 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD)
1630 if (p_data->ci_open.status == BTA_GATT_OK)
1632 p_clcb->p_srcb->attr_index = 0;
1633 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
1634 BTA_GATTC_CI_CACHE_LOAD_EVT,
1635 p_clcb->p_srcb->attr_index,
1636 p_clcb->bta_conn_id);
1640 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
1641 /* cache open failure, start discovery */
1642 bta_gattc_start_discover(p_clcb, NULL);
1645 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE)
1647 if (p_data->ci_open.status == BTA_GATT_OK)
1649 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
1651 p_data->ci_open.status = BTA_GATT_ERROR;
1654 if (p_data->ci_open.status != BTA_GATT_OK)
1656 p_clcb->p_srcb->attr_index = 0;
1657 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id);
1658 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1663 /*******************************************************************************
1665 ** Function bta_gattc_ci_load
1667 ** Description cache loading received.
1671 *******************************************************************************/
1672 void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1675 APPL_TRACE_DEBUG("bta_gattc_ci_load conn_id=%d load status=%d",
1676 p_clcb->bta_conn_id, p_data->ci_load.status);
1678 if (p_data->ci_load.status == BTA_GATT_OK ||
1679 p_data->ci_load.status == BTA_GATT_MORE)
1681 if (p_data->ci_load.num_attr != 0)
1682 bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr,
1683 p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
1685 if (p_data->ci_load.status == BTA_GATT_OK)
1687 p_clcb->p_srcb->attr_index = 0;
1688 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
1689 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1691 else /* load more */
1693 p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr;
1695 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
1696 BTA_GATTC_CI_CACHE_LOAD_EVT,
1697 p_clcb->p_srcb->attr_index,
1698 p_clcb->bta_conn_id);
1703 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1704 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
1705 p_clcb->p_srcb->attr_index = 0;
1706 /* cache load failure, start discovery */
1707 bta_gattc_start_discover(p_clcb, NULL);
1710 /*******************************************************************************
1712 ** Function bta_gattc_ci_save
1714 ** Description cache loading received.
1718 *******************************************************************************/
1719 void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1723 APPL_TRACE_DEBUG("bta_gattc_ci_save conn_id=%d " ,
1724 p_clcb->bta_conn_id );
1726 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
1728 p_clcb->p_srcb->attr_index = 0;
1729 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1730 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1733 /*******************************************************************************
1735 ** Function bta_gattc_fail
1737 ** Description report API call failure back to apps
1741 *******************************************************************************/
1742 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1746 if (p_clcb->status == BTA_GATT_OK)
1748 APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1752 /*******************************************************************************
1754 ** Function bta_gattc_deregister_cmpl
1756 ** Description De-Register a GATT client application with BTA completed.
1760 *******************************************************************************/
1761 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1763 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
1764 tBTA_GATTC_IF client_if = p_clreg->client_if;
1766 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
1768 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1770 GATT_Deregister(p_clreg->client_if);
1771 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1773 cb_data.reg_oper.client_if = client_if;
1774 cb_data.reg_oper.status = BTA_GATT_OK;
1777 /* callback with de-register event */
1778 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
1780 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING)
1782 p_cb->state = BTA_GATTC_STATE_DISABLED;
1785 /*******************************************************************************
1787 ** Function bta_gattc_conn_cback
1789 ** Description callback functions to GATT client stack.
1793 *******************************************************************************/
1794 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1795 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1796 tBT_TRANSPORT transport)
1798 tBTA_GATTC_DATA *p_buf;
1802 APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1803 __FUNCTION__, gattc_if, connected, conn_id, reason);
1807 bdcpy(bdaddr.address, bda);
1809 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
1811 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
1813 if ((p_buf = (tBTA_GATTC_DATA *) osi_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
1815 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1817 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT:
1818 BTA_GATTC_INT_DISCONN_EVT;
1819 p_buf->int_conn.hdr.layer_specific = conn_id;
1820 p_buf->int_conn.client_if = gattc_if;
1821 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1822 p_buf->int_conn.reason = reason;
1823 p_buf->int_conn.transport = transport;
1824 bdcpy(p_buf->int_conn.remote_bda, bda);
1826 bta_sys_sendmsg(p_buf);
1830 /*******************************************************************************
1832 ** Function bta_gattc_enc_cmpl_cback
1834 ** Description encryption complete callback function to GATT client stack.
1838 *******************************************************************************/
1839 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1841 tBTA_GATTC_DATA *p_buf;
1842 tBTA_GATTC_CLCB *p_clcb = NULL;
1844 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL)
1849 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1850 /* filter this event just for BTA HH LE GATT client,
1851 In the future, if we want to enable encryption complete event
1852 for all GATT clients, we can remove this code */
1853 if (!bta_hh_le_is_hh_gatt_if(gattc_if))
1859 APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1861 if ((p_buf = (tBTA_GATTC_DATA *) osi_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
1863 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1865 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1866 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1867 p_buf->enc_cmpl.client_if = gattc_if;
1868 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1870 bta_sys_sendmsg(p_buf);
1874 /*******************************************************************************
1876 ** Function bta_gattc_process_api_refresh
1878 ** Description process refresh API to delete cache and start a new discovery
1879 ** if currently connected.
1883 *******************************************************************************/
1884 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
1886 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1887 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1888 BOOLEAN found = FALSE;
1892 if (p_srvc_cb != NULL)
1894 /* try to find a CLCB */
1895 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0)
1897 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++)
1899 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb)
1907 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1911 /* in all other cases, mark it and delete the cache */
1912 if (p_srvc_cb->p_srvc_cache != NULL)
1914 while (! fixed_queue_is_empty(p_srvc_cb->cache_buffer))
1915 osi_freebuf(fixed_queue_try_dequeue(p_srvc_cb->cache_buffer));
1917 p_srvc_cb->p_srvc_cache = NULL;
1920 /* used to reset cache in application */
1921 bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda);
1924 /*******************************************************************************
1926 ** Function bta_gattc_process_srvc_chg_ind
1928 ** Description process service change indication.
1932 *******************************************************************************/
1933 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1934 tBTA_GATTC_RCB *p_clrcb,
1935 tBTA_GATTC_SERV *p_srcb,
1936 tBTA_GATTC_CLCB *p_clcb,
1937 tBTA_GATTC_NOTIFY *p_notify,
1938 tGATT_VALUE *att_value)
1940 tBT_UUID gattp_uuid, srvc_chg_uuid;
1941 BOOLEAN processed = FALSE;
1945 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1947 srvc_chg_uuid.len = 2;
1948 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1950 if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) &&
1951 bta_gattc_uuid_compare(&p_notify->char_id.char_id.uuid, &srvc_chg_uuid, TRUE))
1953 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
1954 APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
1958 UINT8 *p = att_value->value;
1959 UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
1960 UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
1962 APPL_TRACE_ERROR("%s: service changed s_handle:0x%04x e_handle:0x%04x",
1963 __func__, s_handle, e_handle);
1966 /* mark service handle change pending */
1967 p_srcb->srvc_hdl_chg = TRUE;
1968 /* clear up all notification/indication registration */
1969 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
1970 /* service change indication all received, do discovery update */
1971 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app())
1973 /* not an opened connection; or connection busy */
1974 /* search for first available clcb and start discovery */
1975 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL))
1977 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++)
1979 if (bta_gattc_cb.clcb[i].in_use &&
1980 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1981 bta_gattc_cb.clcb[i].p_q_cmd == NULL)
1983 p_clcb = &bta_gattc_cb.clcb[i];
1988 /* send confirmation here if this is an indication, it should always be */
1989 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
1991 /* if connection available, refresh cache by doing discovery now */
1993 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1995 /* notify applicationf or service change */
1996 if (p_clrcb->p_cback != NULL)
1998 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda);
2006 /*******************************************************************************
2008 ** Function bta_gattc_proc_other_indication
2010 ** Description process all non-service change indication/notification.
2014 *******************************************************************************/
2015 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
2016 tGATT_CL_COMPLETE *p_data,
2017 tBTA_GATTC_NOTIFY *p_notify)
2019 APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check \
2020 p_data->att_value.handle=%d p_data->handle=%d",
2021 p_data->att_value.handle, p_data->handle);
2022 APPL_TRACE_DEBUG("is_notify", p_notify->is_notify);
2024 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
2025 p_notify->len = p_data->att_value.len;
2026 bdcpy(p_notify->bda, p_clcb->bda);
2027 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
2028 p_notify->conn_id = p_clcb->bta_conn_id;
2030 if (p_clcb->p_rcb->p_cback)
2031 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
2034 /*******************************************************************************
2036 ** Function bta_gattc_process_indicate
2038 ** Description process indication/notification.
2042 *******************************************************************************/
2043 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
2045 UINT16 handle = p_data->att_value.handle;
2046 tBTA_GATTC_CLCB *p_clcb ;
2047 tBTA_GATTC_RCB *p_clrcb = NULL;
2048 tBTA_GATTC_SERV *p_srcb = NULL;
2049 tBTA_GATTC_NOTIFY notify;
2051 tBTA_GATTC_IF gatt_if;
2052 tBTA_TRANSPORT transport;
2054 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
2056 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
2057 if (op == GATTC_OPTYPE_INDICATION)
2058 GATTC_SendHandleValueConfirm(conn_id, handle);
2062 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL)
2064 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
2065 if (op == GATTC_OPTYPE_INDICATION)
2066 GATTC_SendHandleValueConfirm(conn_id, handle);
2070 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL)
2072 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore", __func__);
2073 if (op == GATTC_OPTYPE_INDICATION)
2074 GATTC_SendHandleValueConfirm(conn_id, handle);
2078 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
2080 if (bta_gattc_handle2id(p_srcb, handle,
2081 ¬ify.char_id.srvc_id,
2082 ¬ify.char_id.char_id,
2083 ¬ify.descr_type))
2085 /* if non-service change indication/notification, forward to application */
2086 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value))
2088 /* if app registered for the notification */
2089 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify))
2091 /* connection not open yet */
2094 if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL)
2096 p_clcb->bta_conn_id = conn_id;
2097 p_clcb->transport = transport;
2099 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
2103 APPL_TRACE_ERROR("No resources");
2108 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
2110 /* no one intersted and need ack? */
2111 else if (op == GATTC_OPTYPE_INDICATION)
2113 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
2114 GATTC_SendHandleValueConfirm(conn_id, handle);
2120 APPL_TRACE_ERROR("%s Indi/Notif for Unknown handle[0x%04x], can not find in local cache.",
2122 if (op == GATTC_OPTYPE_INDICATION)
2123 GATTC_SendHandleValueConfirm(conn_id, handle);
2126 /*******************************************************************************
2128 ** Function bta_gattc_cmpl_cback
2130 ** Description client operation complete callback register with BTE GATT.
2134 *******************************************************************************/
2135 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
2136 tGATT_CL_COMPLETE *p_data)
2138 tBTA_GATTC_CLCB *p_clcb;
2139 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
2140 conn_id, op, status);
2142 /* notification and indication processed right away */
2143 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION)
2145 bta_gattc_process_indicate(conn_id, op, p_data);
2148 /* for all other operation, not expected if w/o connection */
2149 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL)
2151 APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
2155 /* if over BR_EDR, inform PM for mode change */
2156 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
2158 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2159 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2162 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
2165 /*******************************************************************************
2167 ** Function bta_gattc_cmpl_sendmsg
2169 ** Description client operation complete send message
2173 *******************************************************************************/
2174 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
2175 tBTA_GATT_STATUS status,
2176 tGATT_CL_COMPLETE *p_data)
2178 const UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
2179 tBTA_GATTC_OP_CMPL *p_buf = (tBTA_GATTC_OP_CMPL *) osi_getbuf(len);
2183 memset(p_buf, 0, len);
2184 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
2185 p_buf->hdr.layer_specific = conn_id;
2186 p_buf->status = status;
2187 p_buf->op_code = op;
2191 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2192 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2195 bta_sys_sendmsg(p_buf);
2199 /*******************************************************************************
2201 ** Function bta_gattc_cong_cback
2203 ** Description congestion callback for BTA GATT client.
2207 ********************************************************************************/
2208 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2210 tBTA_GATTC_CLCB *p_clcb;
2213 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL)
2215 if (p_clcb->p_rcb->p_cback)
2217 cb_data.congest.conn_id = conn_id;
2218 cb_data.congest.congested = congested;
2220 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
2225 #if BLE_INCLUDED == TRUE
2226 /*******************************************************************************
2228 ** Function bta_gattc_init_clcb_conn
2230 ** Description Initaite a BTA CLCB connection
2234 ********************************************************************************/
2235 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2237 tBTA_GATTC_CLCB *p_clcb = NULL;
2238 tBTA_GATTC_DATA gattc_data;
2241 /* should always get the connection ID */
2242 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE)
2244 APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2248 /* initaite a new connection here */
2249 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL)
2251 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2253 gattc_data.api_conn.client_if = cif;
2254 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2255 gattc_data.api_conn.is_direct = TRUE;
2257 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2261 APPL_TRACE_ERROR("No resources");
2264 /*******************************************************************************
2266 ** Function bta_gattc_process_listen_all
2268 ** Description process listen all, send open callback to application for all
2269 ** connected slave LE link.
2273 ********************************************************************************/
2274 void bta_gattc_process_listen_all(UINT8 cif)
2277 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
2279 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
2281 if (p_conn->in_use )
2283 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL)
2285 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2287 /* else already connected */
2291 /*******************************************************************************
2293 ** Function bta_gattc_listen
2295 ** Description Start or stop a listen for connection
2299 ********************************************************************************/
2300 void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
2302 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2306 cb_data.reg_oper.status = BTA_GATT_ERROR;
2307 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2309 if (p_clreg == NULL)
2311 APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2312 p_msg->api_listen.client_if);
2315 /* mark bg conn record */
2316 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2317 (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2318 p_msg->api_listen.start,
2321 if (!GATT_Listen(p_msg->api_listen.client_if,
2322 p_msg->api_listen.start,
2323 p_msg->api_listen.remote_bda))
2325 APPL_TRACE_ERROR("Listen failure");
2326 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2330 cb_data.status = BTA_GATT_OK;
2332 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2334 if (p_msg->api_listen.start)
2336 /* if listen to a specific target */
2337 if (p_msg->api_listen.remote_bda != NULL)
2340 /* if is a connected remote device */
2341 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2342 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2343 p_msg->api_listen.remote_bda,
2344 BTA_GATT_TRANSPORT_LE) == NULL)
2347 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2348 p_msg->api_listen.remote_bda);
2351 /* if listen to all */
2354 LOG_DEBUG(LOG_TAG, "Listen For All now");
2355 /* go through all connected device and send
2356 callback for all connected slave connection */
2357 bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2364 /*******************************************************************************
2366 ** Function bta_gattc_broadcast
2368 ** Description Start or stop broadcasting
2372 ********************************************************************************/
2373 void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
2375 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2379 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2380 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start);
2382 if (p_clreg && p_clreg->p_cback)
2383 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);