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