bta_gattc_act.c revision f37767a17b2d80828f7ac4fa170859cb9e2f0bc6
1/******************************************************************************
2 *
3 *  Copyright (C) 2003-2012 Broadcom Corporation
4 *
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:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  This file contains the GATT client action functions for the state
22 *  machine.
23 *
24 ******************************************************************************/
25
26#include "bt_target.h"
27
28#include "utl.h"
29#include "gki.h"
30#include "bd.h"
31#include "bta_sys.h"
32
33#include "bta_gattc_int.h"
34#include "l2c_api.h"
35
36#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
37#include "bta_hh_int.h"
38#endif
39
40#include <string.h>
41
42#if BTA_GATT_INCLUDED && BLE_INCLUDED == TRUE
43
44/*****************************************************************************
45**  Constants
46*****************************************************************************/
47static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
48                                 BOOLEAN connected, tGATT_DISCONN_REASON reason,
49                                 tBT_TRANSPORT transport);
50
51static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
52                                  tGATT_CL_COMPLETE *p_data);
53
54static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
55static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
56static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
57
58static tGATT_CBACK bta_gattc_cl_cback =
59{
60    bta_gattc_conn_cback,
61    bta_gattc_cmpl_cback,
62    bta_gattc_disc_res_cback,
63    bta_gattc_disc_cmpl_cback,
64    NULL,
65    bta_gattc_enc_cmpl_cback,
66    bta_gattc_cong_cback
67};
68
69/* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
70static UINT16 bta_gattc_opcode_to_int_evt[] =
71{
72    BTA_GATTC_API_READ_EVT,
73    BTA_GATTC_API_WRITE_EVT,
74    BTA_GATTC_API_EXEC_EVT,
75    BTA_GATTC_API_CFG_MTU_EVT
76};
77
78#if (BT_TRACE_VERBOSE == TRUE)
79static const char *bta_gattc_op_code_name[] =
80{
81    "Unknown",
82    "Discovery",
83    "Read",
84    "Write",
85    "Exec",
86    "Config",
87    "Notification",
88    "Indication"
89};
90#endif
91/*****************************************************************************
92**  Action Functions
93*****************************************************************************/
94
95/*******************************************************************************
96**
97** Function         bta_gattc_enable
98**
99** Description      Enables GATTC module
100**
101**
102** Returns          void
103**
104*******************************************************************************/
105static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
106{
107    APPL_TRACE_DEBUG("bta_gattc_enable");
108
109    if (p_cb->state == BTA_GATTC_STATE_DISABLED)
110    {
111        /* initialize control block */
112        memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
113        p_cb->state = BTA_GATTC_STATE_ENABLED;
114    }
115    else
116    {
117        APPL_TRACE_DEBUG("GATTC is arelady enabled");
118    }
119}
120
121
122/*******************************************************************************
123**
124** Function         bta_gattc_disable
125**
126** Description      Disable GATTC module by cleaning up all active connections
127**                  and deregister all application.
128**
129** Returns          void
130**
131*******************************************************************************/
132void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
133{
134    UINT8           i;
135
136    APPL_TRACE_DEBUG("bta_gattc_disable");
137
138    if (p_cb->state != BTA_GATTC_STATE_ENABLED)
139    {
140        APPL_TRACE_ERROR("not enabled or disable in pogress");
141        return;
142    }
143
144    for (i = 0; i <BTA_GATTC_CL_MAX; i ++)
145    {
146        if (p_cb->cl_rcb[i].in_use)
147        {
148            p_cb->state = BTA_GATTC_STATE_DISABLING;
149            /* don't deregister HH GATT IF */
150            /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
151#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
152            if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) {
153#endif
154                bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
155#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
156            }
157#endif
158        }
159    }
160
161    /* no registered apps, indicate disable completed */
162    if (p_cb->state != BTA_GATTC_STATE_DISABLING)
163    {
164        p_cb->state = BTA_GATTC_STATE_DISABLED;
165        memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
166    }
167}
168
169/*******************************************************************************
170**
171** Function         bta_gattc_register
172**
173** Description      Register a GATT client application with BTA.
174**
175** Returns          void
176**
177*******************************************************************************/
178void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
179{
180    tBTA_GATTC               cb_data;
181    UINT8                    i;
182    tBT_UUID                 *p_app_uuid = &p_data->api_reg.app_uuid;
183    tBTA_GATTC_INT_START_IF  *p_buf;
184    tBTA_GATT_STATUS         status = BTA_GATT_NO_RESOURCES;
185
186
187    APPL_TRACE_DEBUG("bta_gattc_register state %d",p_cb->state);
188    memset(&cb_data, 0, sizeof(cb_data));
189    cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
190
191     /* check if  GATTC module is already enabled . Else enable */
192     if (p_cb->state == BTA_GATTC_STATE_DISABLED)
193     {
194         bta_gattc_enable (p_cb);
195     }
196    /* todo need to check duplicate uuid */
197    for (i = 0; i < BTA_GATTC_CL_MAX; i ++)
198    {
199        if (!p_cb->cl_rcb[i].in_use)
200        {
201            if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0)
202            {
203                APPL_TRACE_ERROR("Register with GATT stack failed.");
204                status = BTA_GATT_ERROR;
205            }
206            else
207            {
208                p_cb->cl_rcb[i].in_use = TRUE;
209                p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
210                memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
211
212                /* BTA use the same client interface as BTE GATT statck */
213                cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
214
215                if ((p_buf = (tBTA_GATTC_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTC_INT_START_IF))) != NULL)
216                {
217                    p_buf->hdr.event    = BTA_GATTC_INT_START_IF_EVT;
218                    p_buf->client_if    = p_cb->cl_rcb[i].client_if;
219
220                    bta_sys_sendmsg(p_buf);
221                    status = BTA_GATT_OK;
222                }
223                else
224                {
225                    GATT_Deregister(p_cb->cl_rcb[i].client_if);
226
227                    status = BTA_GATT_NO_RESOURCES;
228                    memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
229                }
230                break;
231            }
232        }
233    }
234
235    /* callback with register event */
236    if (p_data->api_reg.p_cback)
237    {
238        if (p_app_uuid != NULL)
239            memcpy(&(cb_data.reg_oper.app_uuid),p_app_uuid,sizeof(tBT_UUID));
240
241        cb_data.reg_oper.status = status;
242        (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT,  (tBTA_GATTC *)&cb_data);
243    }
244}
245/*******************************************************************************
246**
247** Function         bta_gattc_start_if
248**
249** Description      start an application interface.
250**
251** Returns          none.
252**
253*******************************************************************************/
254void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
255{
256    UNUSED(p_cb);
257
258    if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) !=NULL )
259    {
260        GATT_StartIf(p_msg->int_start_if.client_if);
261    }
262    else
263    {
264        APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.client_if );
265    }
266}
267/*******************************************************************************
268**
269** Function         bta_gattc_deregister
270**
271** Description      De-Register a GATT client application with BTA.
272**
273** Returns          void
274**
275*******************************************************************************/
276void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB  *p_clreg)
277{
278    UINT8               i;
279    BT_HDR              buf;
280
281    if (p_clreg != NULL)
282    {
283        /* remove bg connection associated with this rcb */
284        for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++)
285        {
286            if (p_cb->bg_track[i].in_use)
287            {
288                if (p_cb->bg_track[i].cif_mask & (1 <<(p_clreg->client_if - 1)))
289                {
290                    bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE);
291                    GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
292                }
293                if (p_cb->bg_track[i].cif_adv_mask & (1 <<(p_clreg->client_if - 1)))
294                {
295                    bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
296                }
297            }
298        }
299
300        if (p_clreg->num_clcb > 0)
301        {
302            /* close all CLCB related to this app */
303            for (i= 0; i < BTA_GATTC_CLCB_MAX; i ++)
304            {
305                if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg))
306                {
307                    p_clreg->dereg_pending = TRUE;
308
309                    buf.event = BTA_GATTC_API_CLOSE_EVT;
310                    buf.layer_specific = p_cb->clcb[i].bta_conn_id;
311                    bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf)  ;
312                }
313            }
314        }
315        else
316            bta_gattc_deregister_cmpl(p_clreg);
317    }
318    else
319    {
320        APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
321    }
322}
323/*******************************************************************************
324**
325** Function         bta_gattc_process_api_open
326**
327** Description      process connect API request.
328**
329** Returns          void
330**
331*******************************************************************************/
332void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
333{
334    UINT16 event = ((BT_HDR *)p_msg)->event;
335    tBTA_GATTC_CLCB *p_clcb = NULL;
336    tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
337    UNUSED(p_cb);
338
339    if (p_clreg != NULL)
340    {
341        if (p_msg->api_conn.is_direct)
342        {
343            if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
344                                                    p_msg->api_conn.remote_bda,
345                                                    p_msg->api_conn.transport)) != NULL)
346            {
347                bta_gattc_sm_execute(p_clcb, event, p_msg);
348            }
349            else
350            {
351                APPL_TRACE_ERROR("No resources to open a new connection.");
352
353                bta_gattc_send_open_cback(p_clreg,
354                                          BTA_GATT_NO_RESOURCES,
355                                          p_msg->api_conn.remote_bda,
356                                          BTA_GATT_INVALID_CONN_ID,
357                                          p_msg->api_conn.transport, 0);
358            }
359        }
360        else
361        {
362            bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
363        }
364    }
365    else
366    {
367        APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
368                        p_msg->api_conn.client_if);
369    }
370}
371/*******************************************************************************
372**
373** Function         bta_gattc_process_api_open_cancel
374**
375** Description      process connect API request.
376**
377** Returns          void
378**
379*******************************************************************************/
380void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
381{
382    UINT16 event = ((BT_HDR *)p_msg)->event;
383    tBTA_GATTC_CLCB *p_clcb = NULL;
384    tBTA_GATTC_RCB *p_clreg;
385    tBTA_GATTC cb_data;
386    UNUSED(p_cb);
387
388    if (p_msg->api_cancel_conn.is_direct)
389    {
390        if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
391                                                 p_msg->api_cancel_conn.remote_bda,
392                                                 BTA_GATT_TRANSPORT_LE)) != NULL)
393        {
394            bta_gattc_sm_execute(p_clcb, event, p_msg);
395        }
396        else
397        {
398            APPL_TRACE_ERROR("No such connection need to be cancelled");
399
400            p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
401
402            if (p_clreg && p_clreg->p_cback)
403            {
404                cb_data.status = BTA_GATT_ERROR;
405                (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
406            }
407        }
408    }
409    else
410    {
411        bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
412
413    }
414}
415
416/*******************************************************************************
417**
418** Function         bta_gattc_process_enc_cmpl
419**
420** Description      process encryption complete message.
421**
422** Returns          void
423**
424*******************************************************************************/
425void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
426{
427    tBTA_GATTC_RCB *p_clreg;
428    tBTA_GATTC cb_data;
429    UNUSED(p_cb);
430
431    p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
432
433    if (p_clreg && p_clreg->p_cback)
434    {
435        memset(&cb_data, 0, sizeof(tBTA_GATTC));
436
437        cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
438        bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
439
440        (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
441    }
442}
443
444/*******************************************************************************
445**
446** Function         bta_gattc_cancel_open_error
447**
448** Description
449**
450** Returns          void
451**
452*******************************************************************************/
453void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
454{
455    tBTA_GATTC cb_data;
456    UNUSED(p_data);
457
458    cb_data.status=BTA_GATT_ERROR;
459
460    if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback )
461        (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
462}
463
464/*******************************************************************************
465**
466** Function         bta_gattc_open_error
467**
468** Description
469**
470** Returns          void
471**
472*******************************************************************************/
473void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
474{
475    UNUSED(p_data);
476
477    APPL_TRACE_ERROR("Connection already opened. wrong state");
478
479    bta_gattc_send_open_cback(p_clcb->p_rcb,
480                              BTA_GATT_OK,
481                              p_clcb->bda,
482                              p_clcb->bta_conn_id,
483                              p_clcb->transport,
484                              0);
485}
486/*******************************************************************************
487**
488** Function         bta_gattc_open_fail
489**
490** Description
491**
492** Returns          void
493**
494*******************************************************************************/
495void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
496{
497    UNUSED(p_data);
498
499    bta_gattc_send_open_cback(p_clcb->p_rcb,
500                              BTA_GATT_ERROR,
501                              p_clcb->bda,
502                              p_clcb->bta_conn_id,
503                              p_clcb->transport,
504                              0);
505    /* open failure, remove clcb */
506    bta_gattc_clcb_dealloc(p_clcb);
507}
508
509/*******************************************************************************
510**
511** Function         bta_gattc_open
512**
513** Description      Process API connection function.
514**
515** Returns          void
516**
517*******************************************************************************/
518void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
519{
520    tBTA_GATTC_DATA gattc_data;
521
522    /* open/hold a connection */
523    if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
524                      TRUE, p_data->api_conn.transport))
525    {
526        APPL_TRACE_ERROR("Connection open failure");
527
528        bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
529    }
530    else
531    {
532        /* a connected remote device */
533        if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
534                                      p_data->api_conn.remote_bda,
535                                      &p_clcb->bta_conn_id,
536                                      p_data->api_conn.transport))
537        {
538            gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
539
540            bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
541        }
542        /* else wait for the callback event */
543    }
544}
545/*******************************************************************************
546**
547** Function         bta_gattc_init_bk_conn
548**
549** Description      Process API Open for a background connection
550**
551** Returns          void
552**
553*******************************************************************************/
554void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
555{
556    tBTA_GATT_STATUS         status = BTA_GATT_NO_RESOURCES;
557    UINT16                   conn_id;
558    tBTA_GATTC_CLCB         *p_clcb;
559    tBTA_GATTC_DATA         gattc_data;
560
561    if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
562    {
563        /* always call open to hold a connection */
564        if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport))
565        {
566            status = BTA_GATT_ERROR;
567            APPL_TRACE_ERROR("bta_gattc_init_bk_conn failed");
568        }
569        else
570        {
571            status = BTA_GATT_OK;
572
573            /* if is a connected remote device */
574            if (GATT_GetConnIdIfConnected(p_data->client_if,
575                                          p_data->remote_bda,
576                                          &conn_id,
577                                          p_data->transport))
578            {
579                if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
580                    BTA_GATT_TRANSPORT_LE)) != NULL)
581                {
582                    gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
583
584                    /* open connection */
585                    bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
586                    status = BTA_GATT_OK;
587                }
588            }
589        }
590    }
591
592    /* open failure, report OPEN_EVT */
593    if (status != BTA_GATT_OK)
594    {
595        bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
596        BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
597    }
598}
599/*******************************************************************************
600**
601** Function         bta_gattc_cancel_bk_conn
602**
603** Description      Process API Cancel Open for a background connection
604**
605** Returns          void
606**
607*******************************************************************************/
608void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
609{
610    tBTA_GATTC_RCB      *p_clreg;
611    tBTA_GATTC          cb_data;
612    cb_data.status = BTA_GATT_ERROR;
613
614    /* remove the device from the bg connection mask */
615    if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE))
616    {
617        if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE))
618        {
619            cb_data.status = BTA_GATT_OK;
620        }
621        else
622        {
623            APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
624        }
625    }
626    p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
627
628    if (p_clreg && p_clreg->p_cback)
629    {
630        (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
631    }
632
633}
634/*******************************************************************************
635**
636** Function         bta_gattc_int_cancel_open_ok
637**
638** Description
639**
640** Returns          void
641**
642*******************************************************************************/
643void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
644{
645    tBTA_GATTC          cb_data;
646    UNUSED(p_data);
647
648    if ( p_clcb->p_rcb->p_cback )
649    {
650        cb_data.status = BTA_GATT_OK;
651        (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
652    }
653
654    bta_gattc_clcb_dealloc(p_clcb);
655}
656/*******************************************************************************
657**
658** Function         bta_gattc_cancel_open
659**
660** Description
661**
662** Returns          void
663**
664*******************************************************************************/
665void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
666{
667    tBTA_GATTC          cb_data;
668
669    if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE))
670    {
671        bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
672    }
673    else
674    {
675        if ( p_clcb->p_rcb->p_cback )
676        {
677            cb_data.status = BTA_GATT_ERROR;
678            (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
679        }
680    }
681}
682/*******************************************************************************
683**
684** Function         bta_gattc_conn
685**
686** Description      receive connection callback from stack
687**
688** Returns          void
689**
690*******************************************************************************/
691void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
692{
693    tBTA_GATTC_IF   gatt_if;
694    APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state);
695
696    if (p_data != NULL)
697    {
698        APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
699        p_clcb->bta_conn_id  = p_data->int_conn.hdr.layer_specific;
700
701        GATT_GetConnectionInfor(p_data->hdr.layer_specific,
702                                &gatt_if, p_clcb->bda, &p_clcb->transport);
703    }
704
705        p_clcb->p_srcb->connected = TRUE;
706
707        if (p_clcb->p_srcb->mtu == 0)
708            p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
709
710        /* start database cache if needed */
711        if (p_clcb->p_srcb->p_srvc_cache == NULL ||
712            p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE)
713        {
714            if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
715            {
716                p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
717                bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL);
718            }
719            else /* cache is building */
720                p_clcb->state = BTA_GATTC_DISCOVER_ST;
721        }
722
723        else
724        {
725            /* a pending service handle change indication */
726            if (p_clcb->p_srcb->srvc_hdl_chg)
727            {
728                p_clcb->p_srcb->srvc_hdl_chg = FALSE;
729                /* start discovery */
730                bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
731            }
732        }
733
734        if (p_clcb->p_rcb)
735        {
736        /* there is no RM for GATT */
737        if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
738            bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
739
740        bta_gattc_send_open_cback(p_clcb->p_rcb,
741                                  BTA_GATT_OK,
742                                  p_clcb->bda,
743                                  p_clcb->bta_conn_id,
744                                  p_clcb->transport,
745                                  p_clcb->p_srcb->mtu);
746        }
747    }
748/*******************************************************************************
749**
750** Function         bta_gattc_close_fail
751**
752** Description      close a  connection.
753**
754** Returns          void
755**
756*******************************************************************************/
757void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
758{
759    tBTA_GATTC           cb_data;
760
761    if ( p_clcb->p_rcb->p_cback )
762    {
763        memset(&cb_data, 0, sizeof(tBTA_GATTC));
764        cb_data.close.client_if = p_clcb->p_rcb->client_if;
765        cb_data.close.conn_id   = p_data->hdr.layer_specific;
766        bdcpy(cb_data.close.remote_bda, p_clcb->bda);
767        cb_data.close.status    = BTA_GATT_ERROR;
768        cb_data.close.reason    = BTA_GATT_CONN_NONE;
769
770
771        (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
772    }
773}
774/*******************************************************************************
775**
776** Function         bta_gattc_api_close
777**
778** Description      close a GATTC connection.
779**
780** Returns          void
781**
782*******************************************************************************/
783void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
784{
785    tBTA_GATTC_CBACK    *p_cback = p_clcb->p_rcb->p_cback;
786    tBTA_GATTC_RCB      *p_clreg = p_clcb->p_rcb;
787    tBTA_GATTC           cb_data;
788
789    APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id);
790
791    cb_data.close.client_if = p_clcb->p_rcb->client_if;
792    cb_data.close.conn_id   = p_clcb->bta_conn_id;
793    cb_data.close.reason    = p_clcb->reason;
794    cb_data.close.status    = p_clcb->status;
795    bdcpy(cb_data.close.remote_bda, p_clcb->bda);
796
797    if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
798        bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda);
799
800    bta_gattc_clcb_dealloc(p_clcb);
801
802    if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
803    {
804        cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
805    }
806    else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT)
807    {
808        cb_data.close.status = p_data->int_conn.reason;
809    }
810
811    if(p_cback)
812        (* p_cback)(BTA_GATTC_CLOSE_EVT,   (tBTA_GATTC *)&cb_data);
813
814    if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending)
815    {
816        bta_gattc_deregister_cmpl(p_clreg);
817    }
818}
819/*******************************************************************************
820**
821** Function         bta_gattc_reset_discover_st
822**
823** Description      when a SRCB finished discovery, tell all related clcb.
824**
825** Returns          None.
826**
827*******************************************************************************/
828void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
829{
830    tBTA_GATTC_CB   *p_cb = &bta_gattc_cb;
831    UINT8 i;
832
833    for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++)
834    {
835        if (p_cb->clcb[i].p_srcb == p_srcb)
836        {
837            p_cb->clcb[i].status = status;
838            bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
839        }
840    }
841}
842/*******************************************************************************
843**
844** Function         bta_gattc_disc_close
845**
846** Description      close a GATTC connection while in discovery state.
847**
848** Returns          void
849**
850*******************************************************************************/
851void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
852{
853    APPL_TRACE_DEBUG("Discovery cancel conn_id=%d",p_clcb->bta_conn_id);
854    if (p_clcb->disc_active)
855        bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
856    else
857        p_clcb->state = BTA_GATTC_CONN_ST;
858}
859/*******************************************************************************
860**
861** Function         bta_gattc_set_discover_st
862**
863** Description      when a SRCB start discovery, tell all related clcb and set
864**                  the state.
865**
866** Returns          None.
867**
868*******************************************************************************/
869void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
870{
871    tBTA_GATTC_CB   *p_cb = &bta_gattc_cb;
872    UINT8   i;
873
874#if BLE_INCLUDED == TRUE
875    L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE);
876#endif
877    for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++)
878    {
879        if (p_cb->clcb[i].p_srcb == p_srcb)
880        {
881            p_cb->clcb[i].status = BTA_GATT_OK;
882            p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
883        }
884    }
885}
886/*******************************************************************************
887**
888** Function         bta_gattc_restart_discover
889**
890** Description      process service change in discovery state, mark up the auto
891**                  update flag and set status to be discovery cancel for current
892**                  discovery.
893**
894** Returns          None.
895**
896*******************************************************************************/
897void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
898{
899    UNUSED(p_data);
900
901    p_clcb->status      = BTA_GATT_CANCEL;
902    p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
903}
904
905/*******************************************************************************
906**
907** Function         bta_gattc_cfg_mtu
908**
909** Description      Configure MTU size on the GATT connection.
910**
911** Returns          None.
912**
913*******************************************************************************/
914void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
915{
916    tBTA_GATTC_OP_CMPL  op_cmpl;
917    tBTA_GATT_STATUS    status;
918
919    if (bta_gattc_enqueue(p_clcb, p_data))
920    {
921        status = GATTC_ConfigureMTU (p_clcb->bta_conn_id, p_data->api_mtu.mtu);
922
923        /* if failed, return callback here */
924        if (status != GATT_SUCCESS && status != GATT_CMD_STARTED)
925        {
926            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
927
928            op_cmpl.status  = status;
929            op_cmpl.op_code = GATTC_OPTYPE_CONFIG;
930            op_cmpl.p_cmpl  = NULL;
931
932            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
933        }
934    }
935}
936/*******************************************************************************
937**
938** Function         bta_gattc_start_discover
939**
940** Description      Start a discovery on server.
941**
942** Returns          None.
943**
944*******************************************************************************/
945void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
946{
947    UNUSED(p_data);
948
949    APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
950        p_clcb->bta_conn_id, p_clcb->p_srcb->state);
951
952    if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
953        p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
954        p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC)
955    /* no pending operation, start discovery right away */
956    {
957        p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
958
959        if (p_clcb->p_srcb != NULL)
960        {
961            /* clear the service change mask */
962            p_clcb->p_srcb->srvc_hdl_chg = FALSE;
963            p_clcb->p_srcb->update_count = 0;
964            p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
965
966            if (p_clcb->transport == BTA_TRANSPORT_LE)
967                L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
968
969            /* set all srcb related clcb into discovery ST */
970            bta_gattc_set_discover_st(p_clcb->p_srcb);
971
972            if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK)
973            {
974                p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
975                                                               p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
976            }
977            if (p_clcb->status != BTA_GATT_OK)
978            {
979                APPL_TRACE_ERROR("discovery on server failed");
980                bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
981            }
982            else
983                p_clcb->disc_active = TRUE;
984        }
985        else
986        {
987            APPL_TRACE_ERROR("unknown device, can not start discovery");
988        }
989    }
990    /* pending operation, wait until it finishes */
991    else
992    {
993        p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
994
995        if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
996            p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
997    }
998
999}
1000/*******************************************************************************
1001**
1002** Function         bta_gattc_disc_cmpl
1003**
1004** Description      discovery on server is finished
1005**
1006** Returns          None.
1007**
1008*******************************************************************************/
1009void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1010{
1011    tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1012    UNUSED(p_data);
1013
1014    APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
1015
1016#if BLE_INCLUDED == TRUE
1017    if(p_clcb->transport == BTA_TRANSPORT_LE)
1018        L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
1019#endif
1020    p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1021    p_clcb->disc_active = FALSE;
1022
1023    if (p_clcb->status != GATT_SUCCESS)
1024    {
1025        /* clean up cache */
1026        if(p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
1027        {
1028            while (p_clcb->p_srcb->cache_buffer.p_first)
1029            {
1030                GKI_freebuf (GKI_dequeue (&p_clcb->p_srcb->cache_buffer));
1031            }
1032            p_clcb->p_srcb->p_srvc_cache = NULL;
1033        }
1034
1035        /* used to reset cache in application */
1036        bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda);
1037    }
1038    /* release pending attribute list buffer */
1039    utl_freebuf((void **)&p_clcb->p_srcb->p_srvc_list);
1040
1041    if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
1042    {
1043        /* start discovery again */
1044        bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1045    }
1046    /* get any queued command to proceed */
1047    else if (p_q_cmd != NULL)
1048    {
1049        p_clcb->p_q_cmd = NULL;
1050
1051        bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1052        /* if the command executed requeued the cmd, we don't
1053         * want to free the underlying buffer that's being
1054         * referenced by p_clcb->p_q_cmd
1055         */
1056        if (p_q_cmd != p_clcb->p_q_cmd) {
1057            utl_freebuf((void **)&p_q_cmd);
1058        }
1059    }
1060}
1061/*******************************************************************************
1062**
1063** Function         bta_gattc_read
1064**
1065** Description      Read an attribute
1066**
1067** Returns          None.
1068**
1069*******************************************************************************/
1070void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1071{
1072    UINT16 handle = 0;
1073    tGATT_READ_PARAM    read_param;
1074    tBTA_GATTC_OP_CMPL  op_cmpl;
1075
1076    memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1077    memset (&op_cmpl, 0 ,sizeof(tBTA_GATTC_OP_CMPL));
1078
1079    if (bta_gattc_enqueue(p_clcb, p_data))
1080    {
1081        if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1082                                          &p_data->api_read.srvc_id,
1083                                          &p_data->api_read.char_id,
1084                                          p_data->api_read.p_descr_type)) == 0)
1085        {
1086            op_cmpl.status = BTA_GATT_ERROR;
1087        }
1088        else
1089        {
1090            read_param.by_handle.handle = handle;
1091            read_param.by_handle.auth_req = p_data->api_read.auth_req;
1092
1093            op_cmpl.status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1094        }
1095
1096        /* read fail */
1097        if (op_cmpl.status != BTA_GATT_OK)
1098        {
1099            op_cmpl.op_code = GATTC_OPTYPE_READ;
1100            op_cmpl.p_cmpl = NULL;
1101
1102            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1103        }
1104    }
1105}
1106/*******************************************************************************
1107**
1108** Function         bta_gattc_read_multi
1109**
1110** Description      read multiple
1111**
1112** Returns          None.
1113*********************************************************************************/
1114void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1115{
1116    UINT16              i, handle;
1117    tBTA_GATT_STATUS    status = BTA_GATT_OK;
1118    tGATT_READ_PARAM    read_param;
1119    tBTA_GATTC_OP_CMPL  op_cmpl;
1120    tBTA_GATTC_ATTR_ID  *p_id;
1121
1122    if (bta_gattc_enqueue(p_clcb, p_data))
1123    {
1124        memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1125
1126        p_id = p_data->api_read_multi.p_id_list;
1127
1128        for (i = 0; i < p_data->api_read_multi.num_attr && p_id; i ++, p_id ++)
1129        {
1130            handle = 0;
1131
1132            if (p_id->id_type == BTA_GATT_TYPE_CHAR)
1133            {
1134                handle = bta_gattc_id2handle(p_clcb->p_srcb,
1135                                     &p_id->id_value.char_id.srvc_id,
1136                                     &p_id->id_value.char_id.char_id,
1137                                     NULL);
1138            }
1139            else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR)
1140            {
1141                handle = bta_gattc_id2handle(p_clcb->p_srcb,
1142                                     &p_id->id_value.char_descr_id.char_id.srvc_id,
1143                                     &p_id->id_value.char_descr_id.char_id.char_id,
1144                                     &p_id->id_value.char_descr_id.descr_id);
1145            }
1146            else
1147            {
1148                APPL_TRACE_ERROR("invalud ID type: %d", p_id->id_type);
1149            }
1150
1151            if (handle == 0)
1152            {
1153                status = BTA_GATT_ERROR;
1154                break;
1155            }
1156        }
1157        if (status == BTA_GATT_OK)
1158        {
1159            read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1160            read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1161
1162            status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1163        }
1164
1165        /* read fail */
1166        if (status != BTA_GATT_OK)
1167        {
1168            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
1169
1170            op_cmpl.status  = status;
1171            op_cmpl.op_code = GATTC_OPTYPE_READ;
1172            op_cmpl.p_cmpl  = NULL;
1173
1174            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1175        }
1176    }
1177}
1178/*******************************************************************************
1179**
1180** Function         bta_gattc_write
1181**
1182** Description      Write an attribute
1183**
1184** Returns          None.
1185**
1186*******************************************************************************/
1187void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1188{
1189    UINT16              handle = 0;
1190    tGATT_VALUE         attr = {0};
1191    tBTA_GATTC_OP_CMPL  op_cmpl;
1192    tBTA_GATT_STATUS    status = BTA_GATT_OK;
1193
1194    if (bta_gattc_enqueue(p_clcb, p_data))
1195    {
1196        if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1197                                          &p_data->api_write.srvc_id,
1198                                          &p_data->api_write.char_id,
1199                                          p_data->api_write.p_descr_type)) == 0)
1200        {
1201            status = BTA_GATT_ERROR;
1202        }
1203        else
1204        {
1205            attr.handle= handle;
1206            attr.offset = p_data->api_write.offset;
1207            attr.len    = p_data->api_write.len;
1208            attr.auth_req = p_data->api_write.auth_req;
1209
1210            if (p_data->api_write.p_value)
1211                memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1212
1213            status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1214        }
1215
1216        /* write fail */
1217        if (status != BTA_GATT_OK)
1218        {
1219            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
1220
1221            op_cmpl.status  = status;
1222            op_cmpl.op_code = GATTC_OPTYPE_WRITE;
1223            op_cmpl.p_cmpl  = NULL;
1224
1225            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1226        }
1227    }
1228}
1229/*******************************************************************************
1230**
1231** Function         bta_gattc_execute
1232**
1233** Description      send execute write
1234**
1235** Returns          None.
1236*********************************************************************************/
1237void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1238{
1239    tBTA_GATTC_OP_CMPL  op_cmpl;
1240    tBTA_GATT_STATUS    status;
1241
1242    if (bta_gattc_enqueue(p_clcb, p_data))
1243    {
1244        status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1245
1246        if (status != BTA_GATT_OK)
1247        {
1248            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
1249
1250            op_cmpl.status  = status;
1251            op_cmpl.op_code = GATTC_OPTYPE_EXE_WRITE;
1252            op_cmpl.p_cmpl  = NULL;
1253
1254            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1255        }
1256    }
1257}
1258/*******************************************************************************
1259**
1260** Function         bta_gattc_confirm
1261**
1262** Description      send handle value confirmation
1263**
1264** Returns          None.
1265**
1266*******************************************************************************/
1267void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1268{
1269    UINT16 handle;
1270
1271    if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1272                                      &p_data->api_confirm.srvc_id,
1273                                      &p_data->api_confirm.char_id,
1274                                      NULL)) == 0)
1275    {
1276        APPL_TRACE_ERROR("Can not map service/char ID into valid handle");
1277    }
1278    else
1279    {
1280        if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1281            != GATT_SUCCESS)
1282        {
1283            APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1284        }
1285        else
1286        {
1287            /* if over BR_EDR, inform PM for mode change */
1288            if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
1289            {
1290                bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1291                bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1292            }
1293        }
1294    }
1295}
1296/*******************************************************************************
1297**
1298** Function         bta_gattc_read_cmpl
1299**
1300** Description      read complete
1301**
1302** Returns          None.
1303**
1304*******************************************************************************/
1305void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1306{
1307    UINT8               event;
1308    tBTA_GATTC          cb_data;
1309    tBTA_GATT_READ_VAL  read_value;
1310
1311    memset(&cb_data, 0, sizeof(tBTA_GATTC));
1312    memset(&read_value, 0, sizeof(tBTA_GATT_READ_VAL));
1313
1314    cb_data.read.status     = p_data->status;
1315
1316    if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK)
1317    {
1318        if (bta_gattc_handle2id(p_clcb->p_srcb,
1319                                p_data->p_cmpl->att_value.handle,
1320                                &cb_data.read.srvc_id,
1321                                &cb_data.read.char_id,
1322                                &cb_data.read.descr_type) == FALSE)
1323        {
1324            cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
1325            APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x",
1326                                p_data->p_cmpl->att_value.handle);
1327        }
1328        else
1329        {
1330            cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb,
1331                                                              &cb_data.read.descr_type.uuid,
1332                                                              &p_data->p_cmpl->att_value,
1333                                                              &read_value);
1334            cb_data.read.p_value = &read_value;
1335        }
1336    }
1337    else
1338    {
1339        cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
1340        cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
1341        if (p_clcb->p_q_cmd->api_read.p_descr_type)
1342            memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type,
1343                   sizeof(tBTA_GATT_ID));
1344    }
1345
1346    event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ?
1347                    BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
1348    cb_data.read.conn_id = p_clcb->bta_conn_id;
1349
1350    utl_freebuf((void **)&p_clcb->p_q_cmd);
1351    /* read complete, callback */
1352    ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1353
1354}
1355/*******************************************************************************
1356**
1357** Function         bta_gattc_write_cmpl
1358**
1359** Description      read complete
1360**
1361** Returns          None.
1362**
1363*******************************************************************************/
1364void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1365{
1366    tBTA_GATTC      cb_data = {0};
1367    UINT8          event;
1368
1369    memset(&cb_data, 0, sizeof(tBTA_GATTC));
1370
1371    cb_data.write.status     = p_data->status;
1372
1373    if (p_data->p_cmpl != NULL)
1374    {
1375        bta_gattc_handle2id(p_clcb->p_srcb, p_data->p_cmpl->handle,
1376                            &cb_data.write.srvc_id, &cb_data.write.char_id,
1377                            &cb_data.write.descr_type);
1378    }
1379    else
1380    {
1381        memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id,
1382                sizeof(tBTA_GATT_SRVC_ID));
1383        memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id,
1384                sizeof(tBTA_GATT_ID));
1385        if (p_clcb->p_q_cmd->api_write.p_descr_type)
1386            memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type,
1387                   sizeof(tBTA_GATT_ID));
1388    }
1389
1390    if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1391        p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE)
1392
1393        event = BTA_GATTC_PREP_WRITE_EVT;
1394
1395    else if (p_clcb->p_q_cmd->api_write.p_descr_type == NULL)
1396
1397        event = BTA_GATTC_WRITE_CHAR_EVT;
1398
1399    else
1400        event = BTA_GATTC_WRITE_DESCR_EVT;
1401
1402    utl_freebuf((void **)&p_clcb->p_q_cmd);
1403    cb_data.write.conn_id = p_clcb->bta_conn_id;
1404    /* write complete, callback */
1405    ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1406
1407}
1408/*******************************************************************************
1409**
1410** Function         bta_gattc_exec_cmpl
1411**
1412** Description      execute write complete
1413**
1414** Returns          None.
1415**
1416*******************************************************************************/
1417void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1418{
1419    tBTA_GATTC          cb_data;
1420
1421    utl_freebuf((void **)&p_clcb->p_q_cmd);
1422
1423    p_clcb->status      = BTA_GATT_OK;
1424
1425    /* execute complete, callback */
1426    cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1427    cb_data.exec_cmpl.status = p_data->status;
1428
1429    ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT,  &cb_data);
1430
1431}
1432
1433/*******************************************************************************
1434**
1435** Function         bta_gattc_cfg_mtu_cmpl
1436**
1437** Description      configure MTU operation complete
1438**
1439** Returns          None.
1440**
1441*******************************************************************************/
1442void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1443{
1444    tBTA_GATTC          cb_data;
1445
1446    utl_freebuf((void **)&p_clcb->p_q_cmd);
1447
1448
1449    if (p_data->p_cmpl  &&  p_data->status == BTA_GATT_OK)
1450        p_clcb->p_srcb->mtu  = p_data->p_cmpl->mtu;
1451
1452    /* configure MTU complete, callback */
1453    p_clcb->status          = p_data->status;
1454    cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1455    cb_data.cfg_mtu.status  = p_data->status;
1456    cb_data.cfg_mtu.mtu     = p_clcb->p_srcb->mtu;
1457
1458    (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT,  &cb_data);
1459
1460}
1461/*******************************************************************************
1462**
1463** Function         bta_gattc_op_cmpl
1464**
1465** Description      operation completed.
1466**
1467** Returns          None.
1468**
1469*******************************************************************************/
1470void  bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1471{
1472    UINT8           op = (UINT8)p_data->op_cmpl.op_code;
1473    UINT8           mapped_op = 0;
1474
1475    APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1476
1477    if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION)
1478    {
1479        APPL_TRACE_ERROR("unexpected operation, ignored");
1480    }
1481    else if (op >= GATTC_OPTYPE_READ)
1482    {
1483        if (p_clcb->p_q_cmd == NULL)
1484        {
1485            APPL_TRACE_ERROR("No pending command");
1486            return;
1487        }
1488        if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ])
1489        {
1490            mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1491            if ( mapped_op > GATTC_OPTYPE_INDICATION)   mapped_op = 0;
1492
1493#if (BT_TRACE_VERBOSE == TRUE)
1494            APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1495                                bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1496                                bta_gattc_op_code_name[op]);
1497#else
1498            APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1499                                mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1500#endif
1501            return;
1502        }
1503
1504        /* discard responses if service change indication is received before operation completed */
1505        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg)
1506        {
1507            APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1508            p_data->op_cmpl.status = GATT_ERROR;
1509        }
1510
1511        /* service handle change void the response, discard it */
1512        if (op == GATTC_OPTYPE_READ)
1513            bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1514
1515        else if (op == GATTC_OPTYPE_WRITE)
1516            bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1517
1518        else if (op == GATTC_OPTYPE_EXE_WRITE)
1519            bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1520
1521        else if (op == GATTC_OPTYPE_CONFIG)
1522            bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1523
1524        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
1525        {
1526            p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1527            bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1528        }
1529    }
1530}
1531/*******************************************************************************
1532**
1533** Function         bta_gattc_op_cmpl
1534**
1535** Description      operation completed.
1536**
1537** Returns          None.
1538**
1539*******************************************************************************/
1540void  bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1541{
1542    UNUSED(p_clcb);
1543
1544    /* receive op complete when discovery is started, ignore the response,
1545        and wait for discovery finish and resent */
1546    APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1547
1548}
1549/*******************************************************************************
1550**
1551** Function         bta_gattc_search
1552**
1553** Description      start a search in the local server cache
1554**
1555** Returns          None.
1556**
1557*******************************************************************************/
1558void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1559{
1560    tBTA_GATT_STATUS    status = GATT_INTERNAL_ERROR;
1561    tBTA_GATTC cb_data;
1562    APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id);
1563    if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
1564    {
1565        status = BTA_GATT_OK;
1566        /* search the local cache of a server device */
1567        bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1568    }
1569    cb_data.search_cmpl.status  = status;
1570    cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1571
1572    /* end of search or no server cache available */
1573    ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT,  &cb_data);
1574}
1575/*******************************************************************************
1576**
1577** Function         bta_gattc_q_cmd
1578**
1579** Description      enqueue a command into control block, usually because discovery
1580**                  operation is busy.
1581**
1582** Returns          None.
1583**
1584*******************************************************************************/
1585void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1586{
1587    bta_gattc_enqueue(p_clcb, p_data);
1588}
1589/*******************************************************************************
1590**
1591** Function         bta_gattc_cache_open
1592**
1593** Description      open a NV cache for loading
1594**
1595** Returns          void
1596**
1597*******************************************************************************/
1598void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1599{
1600    UNUSED(p_data);
1601
1602    bta_gattc_set_discover_st(p_clcb->p_srcb);
1603
1604    APPL_TRACE_DEBUG("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id);
1605    bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,
1606                            p_clcb->bta_conn_id, FALSE);
1607}
1608/*******************************************************************************
1609**
1610** Function         bta_gattc_start_load
1611**
1612** Description      start cache loading by sending callout open cache
1613**
1614** Returns          None.
1615**
1616*******************************************************************************/
1617void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1618{
1619    APPL_TRACE_DEBUG("bta_gattc_ci_open conn_id=%d server state=%d" ,
1620                      p_clcb->bta_conn_id, p_clcb->p_srcb->state);
1621    if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD)
1622    {
1623        if (p_data->ci_open.status == BTA_GATT_OK)
1624        {
1625            p_clcb->p_srcb->attr_index = 0;
1626            bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
1627                                    BTA_GATTC_CI_CACHE_LOAD_EVT,
1628                                    p_clcb->p_srcb->attr_index,
1629                                    p_clcb->bta_conn_id);
1630        }
1631        else
1632        {
1633            p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
1634            /* cache open failure, start discovery */
1635            bta_gattc_start_discover(p_clcb, NULL);
1636        }
1637    }
1638    if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE)
1639    {
1640        if (p_data->ci_open.status == BTA_GATT_OK)
1641        {
1642            if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
1643            {
1644                p_data->ci_open.status = BTA_GATT_ERROR;
1645            }
1646        }
1647        if (p_data->ci_open.status != BTA_GATT_OK)
1648        {
1649            p_clcb->p_srcb->attr_index = 0;
1650            bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id);
1651            bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1652
1653        }
1654    }
1655}
1656/*******************************************************************************
1657**
1658** Function         bta_gattc_ci_load
1659**
1660** Description      cache loading received.
1661**
1662** Returns          None.
1663**
1664*******************************************************************************/
1665void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1666{
1667
1668    APPL_TRACE_DEBUG("bta_gattc_ci_load conn_id=%d load status=%d",
1669                      p_clcb->bta_conn_id, p_data->ci_load.status);
1670
1671    if (p_data->ci_load.status == BTA_GATT_OK ||
1672         p_data->ci_load.status == BTA_GATT_MORE)
1673    {
1674        if (p_data->ci_load.num_attr != 0)
1675            bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr,
1676                                p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
1677
1678        if (p_data->ci_load.status == BTA_GATT_OK)
1679        {
1680            p_clcb->p_srcb->attr_index = 0;
1681            bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
1682            bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1683        }
1684        else /* load more */
1685        {
1686            p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr;
1687
1688            bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
1689                                    BTA_GATTC_CI_CACHE_LOAD_EVT,
1690                                    p_clcb->p_srcb->attr_index,
1691                                    p_clcb->bta_conn_id);
1692        }
1693    }
1694    else
1695    {
1696        bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1697        p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
1698        p_clcb->p_srcb->attr_index = 0;
1699        /* cache load failure, start discovery */
1700        bta_gattc_start_discover(p_clcb, NULL);
1701    }
1702}
1703/*******************************************************************************
1704**
1705** Function         bta_gattc_ci_save
1706**
1707** Description      cache loading received.
1708**
1709** Returns          None.
1710**
1711*******************************************************************************/
1712void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1713{
1714    UNUSED(p_data);
1715
1716    APPL_TRACE_DEBUG("bta_gattc_ci_save conn_id=%d  " ,
1717                      p_clcb->bta_conn_id   );
1718
1719    if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
1720    {
1721        p_clcb->p_srcb->attr_index = 0;
1722        bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1723        bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1724    }
1725}
1726/*******************************************************************************
1727**
1728** Function         bta_gattc_fail
1729**
1730** Description      report API call failure back to apps
1731**
1732** Returns          None.
1733**
1734*******************************************************************************/
1735void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1736{
1737    UNUSED(p_data);
1738
1739    if (p_clcb->status == BTA_GATT_OK)
1740    {
1741        APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1742    }
1743}
1744
1745/*******************************************************************************
1746**
1747** Function         bta_gattc_deregister_cmpl
1748**
1749** Description      De-Register a GATT client application with BTA completed.
1750**
1751** Returns          void
1752**
1753*******************************************************************************/
1754static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1755{
1756    tBTA_GATTC_CB       *p_cb = &bta_gattc_cb;
1757    tBTA_GATTC_IF       client_if = p_clreg->client_if;
1758    tBTA_GATTC          cb_data;
1759    tBTA_GATTC_CBACK    *p_cback = p_clreg->p_cback;
1760
1761    memset(&cb_data, 0, sizeof(tBTA_GATTC));
1762
1763    GATT_Deregister(p_clreg->client_if);
1764    memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1765
1766    cb_data.reg_oper.client_if = client_if;
1767    cb_data.reg_oper.status    = BTA_GATT_OK;
1768
1769    if (p_cback)
1770        /* callback with de-register event */
1771        (*p_cback)(BTA_GATTC_DEREG_EVT,  (tBTA_GATTC *)&cb_data);
1772
1773    if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING)
1774    {
1775        p_cb->state = BTA_GATTC_STATE_DISABLED;
1776    }
1777}
1778/*******************************************************************************
1779**
1780** Function         bta_gattc_conn_cback
1781**                  bta_gattc_cmpl_cback
1782**
1783** Description      callback functions to GATT client stack.
1784**
1785** Returns          void
1786**
1787*******************************************************************************/
1788static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1789                                 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1790                                 tBT_TRANSPORT transport)
1791{
1792    tBTA_GATTC_DATA *p_buf;
1793
1794    if (reason != 0)
1795    {
1796        APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1797                      __FUNCTION__, gattc_if, connected, conn_id, reason);
1798    }
1799
1800    if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
1801    {
1802        memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1803
1804        p_buf->int_conn.hdr.event            = connected ? BTA_GATTC_INT_CONN_EVT:
1805                                                           BTA_GATTC_INT_DISCONN_EVT;
1806        p_buf->int_conn.hdr.layer_specific   = conn_id;
1807        p_buf->int_conn.client_if            = gattc_if;
1808        p_buf->int_conn.role                 = L2CA_GetBleConnRole(bda);
1809        p_buf->int_conn.reason               = reason;
1810        p_buf->int_conn.transport            = transport;
1811        bdcpy(p_buf->int_conn.remote_bda, bda);
1812
1813        bta_sys_sendmsg(p_buf);
1814    }
1815}
1816
1817/*******************************************************************************
1818**
1819** Function         bta_gattc_enc_cmpl_cback
1820**
1821** Description      encryption complete callback function to GATT client stack.
1822**
1823** Returns          void
1824**
1825*******************************************************************************/
1826static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1827{
1828    tBTA_GATTC_DATA *p_buf;
1829    tBTA_GATTC_CLCB *p_clcb = NULL;
1830
1831    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL)
1832    {
1833        return;
1834    }
1835
1836#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1837    /* filter this event just for BTA HH LE GATT client,
1838       In the future, if we want to enable encryption complete event
1839       for all GATT clients, we can remove this code */
1840    if (!bta_hh_le_is_hh_gatt_if(gattc_if))
1841    {
1842        return;
1843    }
1844#endif
1845
1846    APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1847
1848    if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
1849    {
1850        memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1851
1852        p_buf->enc_cmpl.hdr.event            = BTA_GATTC_ENC_CMPL_EVT;
1853        p_buf->enc_cmpl.hdr.layer_specific   = p_clcb->bta_conn_id;
1854        p_buf->enc_cmpl.client_if            = gattc_if;
1855        bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1856
1857        bta_sys_sendmsg(p_buf);
1858    }
1859}
1860
1861/*******************************************************************************
1862**
1863** Function         bta_gattc_process_api_refresh
1864**
1865** Description      process refresh API to delete cache and start a new discovery
1866**                  if currently connected.
1867**
1868** Returns          None.
1869**
1870*******************************************************************************/
1871void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
1872{
1873    tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1874    tBTA_GATTC_CLCB      *p_clcb = &bta_gattc_cb.clcb[0];
1875    BOOLEAN         found = FALSE;
1876    UINT8           i;
1877    UNUSED(p_cb);
1878
1879    if (p_srvc_cb != NULL)
1880    {
1881        /* try to find a CLCB */
1882        if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0)
1883        {
1884            for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++)
1885            {
1886                if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb)
1887                {
1888                    found = TRUE;
1889                    break;
1890                }
1891            }
1892            if (found)
1893            {
1894                bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1895                return;
1896            }
1897        }
1898        /* in all other cases, mark it and delete the cache */
1899        if (p_srvc_cb->p_srvc_cache != NULL)
1900        {
1901            while (p_srvc_cb->cache_buffer.p_first)
1902                GKI_freebuf (GKI_dequeue (&p_srvc_cb->cache_buffer));
1903
1904            p_srvc_cb->p_srvc_cache = NULL;
1905        }
1906    }
1907    /* used to reset cache in application */
1908    bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda);
1909
1910}
1911/*******************************************************************************
1912**
1913** Function         bta_gattc_process_srvc_chg_ind
1914**
1915** Description      process service change indication.
1916**
1917** Returns          None.
1918**
1919*******************************************************************************/
1920BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1921                                       tBTA_GATTC_RCB      *p_clrcb,
1922                                       tBTA_GATTC_SERV     *p_srcb,
1923                                       tBTA_GATTC_CLCB      *p_clcb,
1924                                       tBTA_GATTC_NOTIFY    *p_notify,
1925                                       UINT16 handle)
1926{
1927    tBT_UUID        gattp_uuid, srvc_chg_uuid;
1928    BOOLEAN         processed = FALSE;
1929    UINT8           i;
1930
1931    gattp_uuid.len = 2;
1932    gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1933
1934    srvc_chg_uuid.len = 2;
1935    srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1936
1937    if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) &&
1938        bta_gattc_uuid_compare(&p_notify->char_id.char_id.uuid, &srvc_chg_uuid, TRUE))
1939    {
1940        processed = TRUE;
1941        /* mark service handle change pending */
1942        p_srcb->srvc_hdl_chg = TRUE;
1943        /* clear up all notification/indication registration */
1944        bta_gattc_clear_notif_registration(conn_id);
1945        /* service change indication all received, do discovery update */
1946        if ( ++ p_srcb->update_count == bta_gattc_num_reg_app())
1947        {
1948            /* not an opened connection; or connection busy */
1949            /* search for first available clcb and start discovery */
1950            if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL))
1951            {
1952                for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++)
1953                {
1954                    if (bta_gattc_cb.clcb[i].in_use &&
1955                        bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1956                        bta_gattc_cb.clcb[i].p_q_cmd == NULL)
1957                    {
1958                        p_clcb = &bta_gattc_cb.clcb[i];
1959                        break;
1960                    }
1961                }
1962            }
1963            /* send confirmation here if this is an indication, it should always be */
1964            GATTC_SendHandleValueConfirm(conn_id, handle);
1965
1966            /* if connection available, refresh cache by doing discovery now */
1967            if (p_clcb != NULL)
1968                bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1969        }
1970        /* notify applicationf or service change */
1971        if (p_clrcb->p_cback != NULL)
1972        {
1973           (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda);
1974        }
1975
1976    }
1977
1978    return processed;
1979
1980}
1981/*******************************************************************************
1982**
1983** Function         bta_gattc_proc_other_indication
1984**
1985** Description      process all non-service change indication/notification.
1986**
1987** Returns          None.
1988**
1989*******************************************************************************/
1990void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
1991                                     tGATT_CL_COMPLETE *p_data,
1992                                     tBTA_GATTC_NOTIFY *p_notify)
1993{
1994    APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check \
1995                       p_data->att_value.handle=%d p_data->handle=%d",
1996                       p_data->att_value.handle, p_data->handle);
1997    APPL_TRACE_DEBUG("is_notify", p_notify->is_notify);
1998
1999    p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
2000    p_notify->len = p_data->att_value.len;
2001    bdcpy(p_notify->bda, p_clcb->bda);
2002    memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
2003    p_notify->conn_id = p_clcb->bta_conn_id;
2004
2005    if (p_clcb->p_rcb->p_cback)
2006        (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT,  (tBTA_GATTC *)p_notify);
2007
2008}
2009/*******************************************************************************
2010**
2011** Function         bta_gattc_process_indicate
2012**
2013** Description      process indication/notification.
2014**
2015** Returns          None.
2016**
2017*******************************************************************************/
2018void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
2019{
2020    UINT16              handle = p_data->att_value.handle;
2021    tBTA_GATTC_CLCB     *p_clcb ;
2022    tBTA_GATTC_RCB      *p_clrcb = NULL;
2023    tBTA_GATTC_SERV     *p_srcb = NULL;
2024    tBTA_GATTC_NOTIFY   notify;
2025    BD_ADDR             remote_bda;
2026    tBTA_GATTC_IF       gatt_if;
2027    tBTA_TRANSPORT transport;
2028
2029    if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
2030    {
2031        APPL_TRACE_ERROR("indication/notif for unknown app");
2032        return;
2033    }
2034
2035    if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL)
2036    {
2037        APPL_TRACE_ERROR("indication/notif for unregistered app");
2038        return;
2039    }
2040
2041    if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL)
2042    {
2043        APPL_TRACE_ERROR("indication/notif for unknown device, ignore");
2044        return;
2045    }
2046
2047    p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
2048
2049    if (bta_gattc_handle2id(p_srcb, handle,
2050                            &notify.char_id.srvc_id,
2051                            &notify.char_id.char_id,
2052                            &notify.descr_type))
2053    {
2054        /* if non-service change indication/notification, forward to application */
2055        if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, &notify, handle))
2056        {
2057            /* if app registered for the notification */
2058            if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, &notify))
2059            {
2060                /* connection not open yet */
2061                if (p_clcb == NULL)
2062                {
2063                    if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL)
2064                    {
2065                        p_clcb->bta_conn_id = conn_id;
2066                        p_clcb->transport   = transport;
2067
2068                        bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
2069                    }
2070                    else
2071                    {
2072                        APPL_TRACE_ERROR("No resources");
2073                    }
2074                }
2075
2076                if (p_clcb != NULL)
2077                    bta_gattc_proc_other_indication(p_clcb, op, p_data, &notify);
2078            }
2079            /* no one intersted and need ack? */
2080            else if (op == GATTC_OPTYPE_INDICATION)
2081            {
2082                APPL_TRACE_DEBUG("no one interested, ack now");
2083                GATTC_SendHandleValueConfirm(conn_id, handle);
2084            }
2085        }
2086    }
2087    else
2088    {
2089        APPL_TRACE_ERROR("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.",
2090                          handle);
2091    }
2092}
2093/*******************************************************************************
2094**
2095** Function         bta_gattc_cmpl_cback
2096**
2097** Description      client operation complete callback register with BTE GATT.
2098**
2099** Returns          None.
2100**
2101*******************************************************************************/
2102static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
2103                                  tGATT_CL_COMPLETE *p_data)
2104{
2105    tBTA_GATTC_CLCB     *p_clcb ;
2106    tBTA_GATTC_OP_CMPL  *p_buf;
2107    UINT16              len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
2108
2109    APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
2110                      conn_id, op, status);
2111
2112    /* notification and indication processed right away */
2113    if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION)
2114    {
2115        bta_gattc_process_indicate(conn_id, op, p_data);
2116        return;
2117    }
2118    /* for all other operation, not expected if w/o connection */
2119    else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL)
2120    {
2121        APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id =  %d, ignore data", conn_id);
2122        return;
2123    }
2124
2125    /* if over BR_EDR, inform PM for mode change */
2126    if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
2127    {
2128        bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2129        bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2130    }
2131
2132    if ((p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len)) != NULL)
2133    {
2134        memset(p_buf, 0, len);
2135        p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
2136        p_buf->hdr.layer_specific = conn_id;
2137        p_buf->status = status;
2138        p_buf->op_code = op;
2139
2140        if (p_data != NULL)
2141        {
2142            p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2143            memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2144        }
2145
2146        bta_sys_sendmsg(p_buf);
2147    }
2148
2149    return;
2150}
2151
2152/*******************************************************************************
2153**
2154** Function         bta_gattc_cong_cback
2155**
2156** Description      congestion callback for BTA GATT client.
2157**
2158** Returns          void
2159**
2160********************************************************************************/
2161static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2162{
2163    tBTA_GATTC_CLCB *p_clcb;
2164    tBTA_GATTC cb_data;
2165
2166    if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL)
2167    {
2168        if (p_clcb->p_rcb->p_cback)
2169        {
2170            cb_data.congest.conn_id = conn_id;
2171            cb_data.congest.congested = congested;
2172
2173            (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
2174        }
2175    }
2176}
2177
2178#if BLE_INCLUDED == TRUE
2179/*******************************************************************************
2180**
2181** Function         bta_gattc_init_clcb_conn
2182**
2183** Description      Initaite a BTA CLCB connection
2184**
2185** Returns          void
2186**
2187********************************************************************************/
2188void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2189{
2190    tBTA_GATTC_CLCB     *p_clcb = NULL;
2191    tBTA_GATTC_DATA     gattc_data;
2192    UINT16              conn_id;
2193
2194    /* should always get the connection ID */
2195    if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE)
2196    {
2197        APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2198        return;
2199    }
2200
2201    /* initaite a new connection here */
2202    if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL)
2203    {
2204        gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2205
2206        gattc_data.api_conn.client_if = cif;
2207        memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2208        gattc_data.api_conn.is_direct = TRUE;
2209
2210        bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2211    }
2212    else
2213    {
2214        APPL_TRACE_ERROR("No resources");
2215    }
2216}
2217/*******************************************************************************
2218**
2219** Function         bta_gattc_process_listen_all
2220**
2221** Description      process listen all, send open callback to application for all
2222**                  connected slave LE link.
2223**
2224** Returns          void
2225**
2226********************************************************************************/
2227void bta_gattc_process_listen_all(UINT8 cif)
2228{
2229    UINT8               i_conn = 0;
2230    tBTA_GATTC_CONN     *p_conn = &bta_gattc_cb.conn_track[0];
2231
2232    for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
2233    {
2234        if (p_conn->in_use )
2235        {
2236            if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL)
2237            {
2238                bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2239            }
2240            /* else already connected */
2241        }
2242    }
2243}
2244/*******************************************************************************
2245**
2246** Function         bta_gattc_listen
2247**
2248** Description      Start or stop a listen for connection
2249**
2250** Returns          void
2251**
2252********************************************************************************/
2253void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
2254{
2255    tBTA_GATTC_RCB      *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2256    tBTA_GATTC          cb_data;
2257    UNUSED(p_cb);
2258
2259    cb_data.reg_oper.status = BTA_GATT_ERROR;
2260    cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2261
2262    if (p_clreg == NULL)
2263    {
2264        APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2265                            p_msg->api_listen.client_if);
2266        return;
2267    }
2268    /* mark bg conn record */
2269    if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2270                               (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2271                               p_msg->api_listen.start,
2272                               TRUE))
2273    {
2274        if (!GATT_Listen(p_msg->api_listen.client_if,
2275                         p_msg->api_listen.start,
2276                         p_msg->api_listen.remote_bda))
2277        {
2278            APPL_TRACE_ERROR("Listen failure");
2279            (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2280        }
2281        else
2282        {
2283            cb_data.status = BTA_GATT_OK;
2284
2285            (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2286
2287            if (p_msg->api_listen.start)
2288            {
2289                /* if listen to a specific target */
2290                if (p_msg->api_listen.remote_bda != NULL)
2291                {
2292
2293                    /* if is a connected remote device */
2294                    if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2295                        bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2296                                                   p_msg->api_listen.remote_bda,
2297                                                   BTA_GATT_TRANSPORT_LE) == NULL)
2298                    {
2299
2300                        bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2301                                                p_msg->api_listen.remote_bda);
2302                    }
2303                }
2304                /* if listen to all */
2305                else
2306                {
2307                    APPL_TRACE_ERROR("Listen For All now");
2308                    /* go through all connected device and send
2309                    callback for all connected slave connection */
2310                    bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2311                }
2312            }
2313        }
2314    }
2315}
2316
2317/*******************************************************************************
2318**
2319** Function         bta_gattc_broadcast
2320**
2321** Description      Start or stop broadcasting
2322**
2323** Returns          void
2324**
2325********************************************************************************/
2326void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
2327{
2328    tBTA_GATTC_RCB      *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2329    tBTA_GATTC          cb_data;
2330    UNUSED(p_cb);
2331
2332    cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2333    cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start);
2334
2335    if (p_clreg && p_clreg->p_cback)
2336        (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2337}
2338#endif
2339#endif
2340