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