Home | History | Annotate | Download | only in gatt
      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 *****************************************************************************/
     45 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
     46                                  BOOLEAN connected, tGATT_DISCONN_REASON reason);
     47 
     48 static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
     49                                   tGATT_CL_COMPLETE *p_data);
     50 
     51 static 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 */
     61 static 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)
     69 static 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 *******************************************************************************/
     94 void 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 *******************************************************************************/
    159 void 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 *******************************************************************************/
    181 void 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 *******************************************************************************/
    210 void 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 *******************************************************************************/
    238 void 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 *******************************************************************************/
    277 void 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 *******************************************************************************/
    317 void 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 *******************************************************************************/
    362 void 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 *******************************************************************************/
    404 void 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 *******************************************************************************/
    421 void 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 *******************************************************************************/
    439 void 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 *******************************************************************************/
    455 void 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 *******************************************************************************/
    489 void 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 *******************************************************************************/
    540 void 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 *******************************************************************************/
    574 void 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 *******************************************************************************/
    595 void 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 *******************************************************************************/
    620 void 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 *******************************************************************************/
    675 void 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 *******************************************************************************/
    701 void 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 *******************************************************************************/
    749 void 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 *******************************************************************************/
    772 void 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 *******************************************************************************/
    797 void 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 *******************************************************************************/
    843 void 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 *******************************************************************************/
    876 void 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 *********************************************************************************/
    920 void 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 *******************************************************************************/
    995 void 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 *********************************************************************************/
   1045 void 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 *******************************************************************************/
   1076 void 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 *******************************************************************************/
   1106 void 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 *******************************************************************************/
   1161 void 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 *******************************************************************************/
   1208 void 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 *******************************************************************************/
   1234 void  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 *******************************************************************************/
   1298 void  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 *******************************************************************************/
   1314 void 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 *******************************************************************************/
   1341 void 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 *******************************************************************************/
   1354 void 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 *******************************************************************************/
   1371 void 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 *******************************************************************************/
   1418 void 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 *******************************************************************************/
   1463 void 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 *******************************************************************************/
   1485 void 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 *******************************************************************************/
   1502 static 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 *******************************************************************************/
   1574 BOOLEAN 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 *******************************************************************************/
   1645 void 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 *******************************************************************************/
   1673 void 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 *******************************************************************************/
   1759 static 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