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