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