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