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