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 Server action functions for the state
     22  *  machine.
     23  *
     24  ******************************************************************************/
     25 
     26 
     27 #include "bt_target.h"
     28 
     29 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
     30 
     31 #include "utl.h"
     32 #include "gki.h"
     33 #include "bta_sys.h"
     34 #include "bta_gatts_int.h"
     35 #include "bta_gatts_co.h"
     36 #include "btm_ble_api.h"
     37 #include "btif/include/btif_debug_conn.h"
     38 #include <string.h>
     39 
     40 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
     41 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
     42                                                 tGATTS_SRV_CHG_RSP *p_rsp);
     43 
     44 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
     45                                       BOOLEAN connected, tGATT_DISCONN_REASON reason,
     46                                       tGATT_TRANSPORT transport);
     47 static void bta_gatts_send_request_cback (UINT16 conn_id,
     48                                           UINT32 trans_id,
     49                                           tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
     50 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
     51 
     52 static tGATT_CBACK bta_gatts_cback =
     53 {
     54     bta_gatts_conn_cback,
     55     NULL,
     56     NULL,
     57     NULL,
     58     bta_gatts_send_request_cback,
     59     NULL,
     60     bta_gatts_cong_cback
     61 };
     62 
     63 tGATT_APPL_INFO bta_gatts_nv_cback =
     64 {
     65     bta_gatts_nv_save_cback,
     66     bta_gatts_nv_srv_chg_cback
     67 };
     68 
     69 /*******************************************************************************
     70 **
     71 ** Function         bta_gatts_nv_save_cback
     72 **
     73 ** Description      NV save callback function.
     74 **
     75 ** Parameter        is_add: true is to add a handle range; otherwise is to delete.
     76 ** Returns          none.
     77 **
     78 *******************************************************************************/
     79 static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
     80 {
     81     bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
     82 }
     83 
     84 
     85 /*******************************************************************************
     86 **
     87 ** Function         bta_gatts_nv_srv_chg_cback
     88 **
     89 ** Description      NV save callback function.
     90 **
     91 ** Parameter        is_add: true is to add a handle range; otherwise is to delete.
     92 ** Returns          none.
     93 **
     94 *******************************************************************************/
     95 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
     96                                               tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
     97 {
     98     return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
     99                                 (tBTA_GATTS_SRV_CHG_REQ *) p_req,
    100                                 (tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
    101 }
    102 
    103 
    104 /*******************************************************************************
    105 **
    106 ** Function         bta_gatts_enable
    107 **
    108 ** Description      enable BTA GATTS module.
    109 **
    110 ** Returns          none.
    111 **
    112 *******************************************************************************/
    113 void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
    114 {
    115     UINT8 index=0;
    116     tBTA_GATTS_HNDL_RANGE handle_range;
    117 
    118     if (p_cb->enabled)
    119     {
    120         APPL_TRACE_DEBUG("GATTS already enabled.");
    121     }
    122     else
    123     {
    124         memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
    125 
    126         p_cb->enabled = TRUE;
    127 
    128         while ( bta_gatts_co_load_handle_range(index, &handle_range))
    129         {
    130             GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
    131             memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
    132             index++;
    133         }
    134 
    135         APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
    136 
    137         if (!GATTS_NVRegister(&bta_gatts_nv_cback))
    138         {
    139             APPL_TRACE_ERROR("BTA GATTS NV register failed.");
    140         }
    141     }
    142 }
    143 
    144 /*******************************************************************************
    145 **
    146 ** Function         bta_gatts_api_disable
    147 **
    148 ** Description      disable BTA GATTS module.
    149 **
    150 ** Returns          none.
    151 **
    152 *******************************************************************************/
    153 void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
    154 {
    155     UINT8 i;
    156 
    157     if (p_cb->enabled)
    158     {
    159         for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
    160         {
    161             if (p_cb->rcb[i].in_use)
    162             {
    163                 GATT_Deregister(p_cb->rcb[i].gatt_if);
    164             }
    165         }
    166         memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
    167     }
    168     else
    169     {
    170         APPL_TRACE_ERROR("GATTS not enabled");
    171     }
    172 }
    173 
    174 /*******************************************************************************
    175 **
    176 ** Function         bta_gatts_register
    177 **
    178 ** Description      register an application.
    179 **
    180 ** Returns          none.
    181 **
    182 *******************************************************************************/
    183 void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
    184 {
    185     tBTA_GATTS_INT_START_IF  *p_buf;
    186     tBTA_GATTS               cb_data;
    187     tBTA_GATT_STATUS         status = BTA_GATT_OK;
    188     UINT8                    i, first_unuse = 0xff;
    189 
    190     if (p_cb->enabled == FALSE)
    191     {
    192         bta_gatts_enable(p_cb);
    193     }
    194 
    195     for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
    196     {
    197         if (p_cb->rcb[i].in_use)
    198         {
    199             if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
    200             {
    201                 APPL_TRACE_ERROR("application already registered.");
    202                 status = BTA_GATT_DUP_REG;
    203                 break;
    204             }
    205         }
    206     }
    207 
    208     if (status == BTA_GATT_OK)
    209     {
    210         for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
    211         {
    212             if (first_unuse == 0xff && !p_cb->rcb[i].in_use)
    213             {
    214                 first_unuse = i;
    215                 break;
    216             }
    217         }
    218 
    219         cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
    220 // btla-specific ++
    221         memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
    222 // btla-specific --
    223         if (first_unuse != 0xff)
    224         {
    225             APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);
    226 
    227             p_cb->rcb[first_unuse].in_use = TRUE;
    228             p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
    229             memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
    230             cb_data.reg_oper.server_if      =
    231             p_cb->rcb[first_unuse].gatt_if  =
    232             GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
    233             if ( !p_cb->rcb[first_unuse].gatt_if)
    234             {
    235                 status = BTA_GATT_NO_RESOURCES;
    236             }
    237             else
    238             {
    239                 if ((p_buf =
    240                   (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
    241                 {
    242                     p_buf->hdr.event    = BTA_GATTS_INT_START_IF_EVT;
    243                     p_buf->server_if    = p_cb->rcb[first_unuse].gatt_if;
    244 
    245                     bta_sys_sendmsg(p_buf);
    246                 }
    247                 else
    248                 {
    249                     status = BTA_GATT_NO_RESOURCES;
    250                     memset( &p_cb->rcb[first_unuse], 0 , sizeof(tBTA_GATTS_RCB));
    251                 }
    252             }
    253         }
    254         else
    255         {
    256             status = BTA_GATT_NO_RESOURCES;
    257         }
    258 
    259     }
    260     cb_data.reg_oper.status = status;
    261     if (p_msg->api_reg.p_cback)
    262         (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
    263 }
    264 
    265 
    266 /*******************************************************************************
    267 **
    268 ** Function         bta_gatts_start_if
    269 **
    270 ** Description      start an application interface.
    271 **
    272 ** Returns          none.
    273 **
    274 *******************************************************************************/
    275 void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
    276 {
    277     UNUSED(p_cb);
    278 
    279     if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if))
    280     {
    281         GATT_StartIf(p_msg->int_start_if.server_if);
    282     }
    283     else
    284     {
    285         APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
    286             p_msg->int_start_if.server_if );
    287     }
    288 }
    289 /*******************************************************************************
    290 **
    291 ** Function         bta_gatts_deregister
    292 **
    293 ** Description      deregister an application.
    294 **
    295 ** Returns          none.
    296 **
    297 *******************************************************************************/
    298 void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
    299 {
    300     tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
    301     tBTA_GATTS_CBACK    *p_cback = NULL;
    302     UINT8               i;
    303     tBTA_GATTS          cb_data;
    304 
    305     cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
    306     cb_data.reg_oper.status = status;
    307 
    308     for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
    309     {
    310         if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if)
    311         {
    312             p_cback = p_cb->rcb[i].p_cback;
    313             status = BTA_GATT_OK;
    314 
    315             /* deregister the app */
    316             GATT_Deregister(p_cb->rcb[i].gatt_if);
    317 
    318             /* reset cb */
    319             memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
    320             cb_data.reg_oper.status = status;
    321             break;
    322         }
    323     }
    324 
    325     if (p_cback)
    326     {
    327         (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
    328     }
    329     else
    330     {
    331         APPL_TRACE_ERROR("application not registered.");
    332     }
    333 }
    334 /*******************************************************************************
    335 **
    336 ** Function         bta_gatts_create_srvc
    337 **
    338 ** Description      action function to create a service.
    339 **
    340 ** Returns          none.
    341 **
    342 *******************************************************************************/
    343 void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    344 {
    345     UINT8               rcb_idx;
    346     tBTA_GATTS          cb_data;
    347     UINT8               srvc_idx;
    348     UINT16              service_id = 0;
    349 
    350     cb_data.create.status = BTA_GATT_ERROR;
    351 
    352     rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
    353 
    354     APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);
    355 
    356     if (rcb_idx != BTA_GATTS_INVALID_APP)
    357     {
    358         if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP)
    359         {
    360             /* create the service now */
    361             service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
    362                                               &p_msg->api_create_svc.service_uuid,
    363                                               p_msg->api_create_svc.inst,
    364                                               p_msg->api_create_svc.num_handle,
    365                                               p_msg->api_create_svc.is_pri);
    366 
    367             if (service_id != 0)
    368             {
    369                 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
    370                     &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
    371                 p_cb->srvc_cb[srvc_idx].service_id   = service_id;
    372                 p_cb->srvc_cb[srvc_idx].inst_num     = p_msg->api_create_svc.inst;
    373                 p_cb->srvc_cb[srvc_idx].idx          = srvc_idx;
    374 
    375                 cb_data.create.status      = BTA_GATT_OK;
    376                 cb_data.create.service_id  = service_id;
    377 // btla-specific ++
    378                 cb_data.create.is_primary  = p_msg->api_create_svc.is_pri;
    379 // btla-specific --
    380                 cb_data.create.server_if   = p_cb->rcb[rcb_idx].gatt_if;
    381             }
    382             else
    383             {
    384                 cb_data.status  = BTA_GATT_ERROR;
    385                 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
    386                 APPL_TRACE_ERROR("service creation failed.");
    387             }
    388 // btla-specific ++
    389             memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
    390             cb_data.create.svc_instance= p_msg->api_create_svc.inst;
    391 // btla-specific --
    392         }
    393         if (p_cb->rcb[rcb_idx].p_cback)
    394             (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
    395     }
    396     else /* application not registered */
    397     {
    398         APPL_TRACE_ERROR("Application not registered");
    399     }
    400 }
    401 /*******************************************************************************
    402 **
    403 ** Function         bta_gatts_add_include_srvc
    404 **
    405 ** Description      action function to add an included service.
    406 **
    407 ** Returns          none.
    408 **
    409 *******************************************************************************/
    410 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg)
    411 {
    412     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    413     UINT16          attr_id = 0;
    414     tBTA_GATTS      cb_data;
    415 
    416     attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
    417                                       p_msg->api_add_incl_srvc.included_service_id);
    418 
    419     cb_data.add_result.server_if = p_rcb->gatt_if;
    420     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    421     cb_data.add_result.attr_id = attr_id;
    422 
    423     if (attr_id)
    424     {
    425         cb_data.add_result.status = BTA_GATT_OK;
    426     }
    427     else
    428     {
    429         cb_data.add_result.status = BTA_GATT_ERROR;
    430     }
    431 
    432     if (p_rcb->p_cback)
    433         (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
    434 }
    435 /*******************************************************************************
    436 **
    437 ** Function         bta_gatts_add_char
    438 **
    439 ** Description      action function to add characteristic.
    440 **
    441 ** Returns          none.
    442 **
    443 *******************************************************************************/
    444 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
    445 {
    446     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    447     UINT16          attr_id = 0;
    448     tBTA_GATTS      cb_data;
    449 
    450     attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
    451                                       &p_msg->api_add_char.char_uuid,
    452                                       p_msg->api_add_char.perm,
    453                                       p_msg->api_add_char.property);
    454     cb_data.add_result.server_if = p_rcb->gatt_if;
    455     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    456     cb_data.add_result.attr_id = attr_id;
    457 // btla-specific ++
    458     memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
    459 // btla-specific --
    460 
    461     if (attr_id)
    462     {
    463         cb_data.add_result.status = BTA_GATT_OK;
    464     }
    465     else
    466     {
    467         cb_data.add_result.status = BTA_GATT_ERROR;
    468     }
    469 
    470     if (p_rcb->p_cback)
    471         (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
    472 }
    473 /*******************************************************************************
    474 **
    475 ** Function         bta_gatts_add_char_descr
    476 **
    477 ** Description      action function to add characteristic descriptor.
    478 **
    479 ** Returns          none.
    480 **
    481 *******************************************************************************/
    482 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
    483 {
    484     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    485     UINT16          attr_id = 0;
    486     tBTA_GATTS      cb_data;
    487 
    488     attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
    489                                        p_msg->api_add_char_descr.perm,
    490                                        &p_msg->api_add_char_descr.descr_uuid);
    491 
    492     cb_data.add_result.server_if = p_rcb->gatt_if;
    493     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    494     cb_data.add_result.attr_id = attr_id;
    495 // btla-specific ++
    496     memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
    497 // btla-specific --
    498 
    499     if (attr_id)
    500     {
    501         cb_data.add_result.status = BTA_GATT_OK;
    502     }
    503     else
    504     {
    505         cb_data.add_result.status = BTA_GATT_ERROR;
    506     }
    507 
    508     if (p_rcb->p_cback)
    509         (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
    510 
    511 }
    512 /*******************************************************************************
    513 **
    514 ** Function         bta_gatts_delete_service
    515 **
    516 ** Description      action function to delete a service.
    517 **
    518 ** Returns          none.
    519 **
    520 *******************************************************************************/
    521 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
    522 {
    523     tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    524     tBTA_GATTS      cb_data;
    525 
    526     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
    527     cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    528 
    529     if (GATTS_DeleteService(p_rcb->gatt_if,
    530                             &p_srvc_cb->service_uuid,
    531                             p_srvc_cb->inst_num))
    532     {
    533         cb_data.srvc_oper.status = BTA_GATT_OK;
    534         memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
    535     }
    536     else
    537     {
    538         cb_data.srvc_oper.status = BTA_GATT_ERROR;
    539     }
    540 
    541     if (p_rcb->p_cback)
    542         (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
    543 
    544 }
    545 /*******************************************************************************
    546 **
    547 ** Function         bta_gatts_start_service
    548 **
    549 ** Description      action function to start a service.
    550 **
    551 ** Returns          none.
    552 **
    553 *******************************************************************************/
    554 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
    555 {
    556     tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    557     tBTA_GATTS      cb_data;
    558 
    559     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
    560     cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    561 
    562     if (GATTS_StartService(p_rcb->gatt_if,
    563                            p_srvc_cb->service_id,
    564                            p_msg->api_start.transport) ==  GATT_SUCCESS)
    565     {
    566         APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
    567         cb_data.srvc_oper.status = BTA_GATT_OK;
    568     }
    569     else
    570     {
    571         cb_data.srvc_oper.status = BTA_GATT_ERROR;
    572     }
    573 
    574     if (p_rcb->p_cback)
    575         (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
    576 
    577 }
    578 /*******************************************************************************
    579 **
    580 ** Function         bta_gatts_stop_service
    581 **
    582 ** Description      action function to stop a service.
    583 **
    584 ** Returns          none.
    585 **
    586 *******************************************************************************/
    587 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
    588 {
    589     tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    590     tBTA_GATTS      cb_data;
    591     UNUSED(p_msg);
    592 
    593     GATTS_StopService(p_srvc_cb->service_id);
    594     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
    595     cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
    596     cb_data.srvc_oper.status = BTA_GATT_OK;
    597     APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
    598 
    599     if (p_rcb->p_cback)
    600         (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
    601 
    602 }
    603 /*******************************************************************************
    604 **
    605 ** Function         bta_gatts_send_rsp
    606 **
    607 ** Description      GATTS send response.
    608 **
    609 ** Returns          none.
    610 **
    611 *******************************************************************************/
    612 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    613 {
    614     UNUSED(p_cb);
    615 
    616     if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
    617                         p_msg->api_rsp.trans_id,
    618                         p_msg->api_rsp.status,
    619                         (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
    620     {
    621         APPL_TRACE_ERROR("Sending response failed");
    622     }
    623 
    624 }
    625 /*******************************************************************************
    626 **
    627 ** Function         bta_gatts_indicate_handle
    628 **
    629 ** Description      GATTS send handle value indication or notification.
    630 **
    631 ** Returns          none.
    632 **
    633 *******************************************************************************/
    634 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    635 {
    636     tBTA_GATTS_SRVC_CB  *p_srvc_cb;
    637     tBTA_GATTS_RCB      *p_rcb = NULL;
    638     tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
    639     tGATT_IF            gatt_if;
    640     BD_ADDR             remote_bda;
    641     tBTA_TRANSPORT transport;
    642     tBTA_GATTS          cb_data;
    643 
    644     p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
    645 
    646     if (p_srvc_cb )
    647     {
    648         if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
    649             &gatt_if, remote_bda, &transport))
    650         {
    651             p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
    652 
    653             if (p_msg->api_indicate.need_confirm)
    654 
    655                 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
    656                                                       p_msg->api_indicate.attr_id,
    657                                                       p_msg->api_indicate.len,
    658                                                       p_msg->api_indicate.value);
    659             else
    660                 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
    661                                                         p_msg->api_indicate.attr_id,
    662                                                         p_msg->api_indicate.len,
    663                                                         p_msg->api_indicate.value);
    664 
    665             /* if over BR_EDR, inform PM for mode change */
    666             if (transport == BTA_TRANSPORT_BR_EDR)
    667             {
    668                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
    669                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
    670             }
    671         }
    672         else
    673         {
    674             APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
    675                               p_msg->api_indicate.hdr.layer_specific);
    676         }
    677 
    678         if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
    679             p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
    680         {
    681             cb_data.req_data.status = status;
    682             cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
    683 
    684             (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
    685         }
    686     }
    687     else
    688     {
    689         APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
    690                           p_msg->api_indicate.attr_id);
    691     }
    692 }
    693 
    694 
    695 /*******************************************************************************
    696 **
    697 ** Function         bta_gatts_open
    698 **
    699 ** Description
    700 **
    701 ** Returns          none.
    702 **
    703 *******************************************************************************/
    704 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    705 {
    706     tBTA_GATTS_RCB      *p_rcb=NULL;
    707     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
    708     UINT16              conn_id;
    709     UNUSED(p_cb);
    710 
    711     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
    712     {
    713         /* should always get the connection ID */
    714         if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
    715                         p_msg->api_open.is_direct, p_msg->api_open.transport))
    716         {
    717             status = BTA_GATT_OK;
    718 
    719             if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
    720                                             &conn_id, p_msg->api_open.transport))
    721             {
    722                 status = BTA_GATT_ALREADY_OPEN;
    723             }
    724         }
    725     }
    726     else
    727     {
    728         APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
    729     }
    730 
    731     if (p_rcb && p_rcb->p_cback)
    732         (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT,  (tBTA_GATTS *)&status);
    733 
    734 }
    735 /*******************************************************************************
    736 **
    737 ** Function         bta_gatts_cancel_open
    738 **
    739 ** Description
    740 **
    741 ** Returns          none.
    742 **
    743 *******************************************************************************/
    744 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    745 {
    746     tBTA_GATTS_RCB      *p_rcb;
    747     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
    748     UNUSED(p_cb);
    749 
    750     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
    751     {
    752         if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
    753                                 p_msg->api_cancel_open.is_direct))
    754         {
    755             APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
    756         }
    757         else
    758         {
    759             status= BTA_GATT_OK;
    760         }
    761     }
    762     else
    763     {
    764         APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
    765     }
    766 
    767     if (p_rcb && p_rcb->p_cback)
    768         (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT,  (tBTA_GATTS *)&status);
    769 }
    770 /*******************************************************************************
    771 **
    772 ** Function         bta_gatts_close
    773 **
    774 ** Description
    775 **
    776 ** Returns          none.
    777 **
    778 *******************************************************************************/
    779 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    780 {
    781     tBTA_GATTS_RCB     *p_rcb;
    782     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
    783     tGATT_IF            gatt_if;
    784     BD_ADDR             remote_bda;
    785     tBTA_GATT_TRANSPORT transport;
    786 
    787     UNUSED(p_cb);
    788 
    789     if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
    790     {
    791         if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
    792         {
    793             APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
    794         }
    795         else
    796         {
    797             status= BTA_GATT_OK;
    798         }
    799 
    800         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
    801 
    802         if (p_rcb && p_rcb->p_cback)
    803         {
    804             if (transport == BTA_TRANSPORT_BR_EDR)
    805                 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
    806 
    807             (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT,  (tBTA_GATTS *)&status);
    808         }
    809     }
    810     else
    811     {
    812         APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
    813     }
    814 
    815 }
    816 /*******************************************************************************
    817 **
    818 ** Function         bta_gatts_listen
    819 **
    820 ** Description      Start or stop listening for LE connection on a GATT server
    821 **
    822 ** Returns          none.
    823 **
    824 *******************************************************************************/
    825 void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
    826 {
    827     tBTA_GATTS_RCB     *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
    828     tBTA_GATTS          cb_data;
    829     UNUSED(p_cb);
    830 
    831     cb_data.reg_oper.status = BTA_GATT_OK;
    832     cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
    833 
    834     if (p_rcb == NULL)
    835     {
    836         APPL_TRACE_ERROR("Unknown GATTS application");
    837         return;
    838     }
    839 
    840     if (!GATT_Listen(p_msg->api_listen.server_if,
    841                      p_msg->api_listen.start,
    842                      p_msg->api_listen.remote_bda))
    843     {
    844         cb_data.status = BTA_GATT_ERROR;
    845         APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
    846     }
    847 
    848     if (p_rcb->p_cback)
    849         (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
    850 }
    851 
    852 /*******************************************************************************
    853 **
    854 ** Function         bta_gatts_request_cback
    855 **
    856 ** Description      GATTS attribute request callback.
    857 **
    858 ** Returns          none.
    859 **
    860 *******************************************************************************/
    861 static void bta_gatts_send_request_cback (UINT16 conn_id,
    862                                           UINT32 trans_id,
    863                                           tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
    864 {
    865     tBTA_GATTS          cb_data;
    866     tBTA_GATTS_RCB     *p_rcb;
    867     tGATT_IF            gatt_if;
    868     tBTA_GATT_TRANSPORT transport;
    869 
    870     memset(&cb_data, 0 , sizeof(tBTA_GATTS));
    871 
    872     if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
    873     {
    874         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
    875 
    876         APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
    877                             conn_id, trans_id, req_type);
    878 
    879         if (p_rcb && p_rcb->p_cback)
    880         {
    881             /* if over BR_EDR, inform PM for mode change */
    882             if (transport == BTA_TRANSPORT_BR_EDR)
    883             {
    884                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
    885                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
    886             }
    887 
    888             cb_data.req_data.conn_id    = conn_id;
    889             cb_data.req_data.trans_id   = trans_id;
    890             cb_data.req_data.p_data     = (tBTA_GATTS_REQ_DATA *)p_data;
    891 
    892             (*p_rcb->p_cback)(req_type,  &cb_data);
    893         }
    894         else
    895         {
    896             APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
    897         }
    898     }
    899     else
    900     {
    901         APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
    902     }
    903 }
    904 
    905 /*******************************************************************************
    906 **
    907 ** Function         bta_gatts_conn_cback
    908 **
    909 ** Description      connection callback.
    910 **
    911 ** Returns          none.
    912 **
    913 *******************************************************************************/
    914 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
    915                                   BOOLEAN connected, tGATT_DISCONN_REASON reason,
    916                                   tGATT_TRANSPORT transport)
    917 {
    918     tBTA_GATTS      cb_data;
    919     UINT8           evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
    920     tBTA_GATTS_RCB  *p_reg;
    921 
    922     APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
    923                         gatt_if, conn_id, connected, reason);
    924     APPL_TRACE_DEBUG("bta_gatts_conn_cback  bda :%02x-%02x-%02x-%02x-%02x-%02x ",
    925                       bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
    926 
    927     bt_bdaddr_t bdaddr;
    928     bdcpy(bdaddr.address, bda);
    929     if (connected)
    930         btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
    931     else
    932         btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
    933 
    934     p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
    935 
    936     if (p_reg && p_reg->p_cback)
    937     {
    938         /* there is no RM for GATT */
    939         if (transport == BTA_TRANSPORT_BR_EDR)
    940         {
    941             if (connected)
    942                 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
    943             else
    944                 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
    945         }
    946 
    947         cb_data.conn.conn_id = conn_id;
    948         cb_data.conn.server_if = gatt_if;
    949         cb_data.conn.reason = reason;
    950         cb_data.conn.transport = transport;
    951         memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
    952         (*p_reg->p_cback)(evt, &cb_data);
    953     }
    954     else
    955     {
    956         APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
    957     }
    958 }
    959 
    960 /*******************************************************************************
    961 **
    962 ** Function         bta_gatts_cong_cback
    963 **
    964 ** Description      congestion callback.
    965 **
    966 ** Returns          none.
    967 **
    968 *******************************************************************************/
    969 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
    970 {
    971     tBTA_GATTS_RCB *p_rcb;
    972     tGATT_IF gatt_if;
    973     tBTA_GATT_TRANSPORT transport;
    974     tBTA_GATTS cb_data;
    975 
    976     if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
    977     {
    978         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
    979 
    980         if (p_rcb && p_rcb->p_cback)
    981         {
    982             cb_data.congest.conn_id = conn_id;
    983             cb_data.congest.congested = congested;
    984 
    985             (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
    986         }
    987     }
    988 }
    989 #endif /* BTA_GATT_INCLUDED */
    990