/******************************************************************************
 *
 *  Copyright (C) 2003-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This file contains the GATT Server action functions for the state
 *  machine.
 *
 ******************************************************************************/


#include "bt_target.h"

#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)

#include "utl.h"
#include "bt_common.h"
#include "bta_sys.h"
#include "bta_gatts_int.h"
#include "bta_gatts_co.h"
#include "btm_ble_api.h"
#include "btif/include/btif_debug_conn.h"
#include <string.h>

static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
                                                tGATTS_SRV_CHG_RSP *p_rsp);

static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
                                      BOOLEAN connected, tGATT_DISCONN_REASON reason,
                                      tGATT_TRANSPORT transport);
static void bta_gatts_send_request_cback (UINT16 conn_id,
                                          UINT32 trans_id,
                                          tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);

static tGATT_CBACK bta_gatts_cback =
{
    bta_gatts_conn_cback,
    NULL,
    NULL,
    NULL,
    bta_gatts_send_request_cback,
    NULL,
    bta_gatts_cong_cback
};

tGATT_APPL_INFO bta_gatts_nv_cback =
{
    bta_gatts_nv_save_cback,
    bta_gatts_nv_srv_chg_cback
};

/*******************************************************************************
**
** Function         bta_gatts_nv_save_cback
**
** Description      NV save callback function.
**
** Parameter        is_add: true is to add a handle range; otherwise is to delete.
** Returns          none.
**
*******************************************************************************/
static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
{
    bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
}


/*******************************************************************************
**
** Function         bta_gatts_nv_srv_chg_cback
**
** Description      NV save callback function.
**
** Parameter        is_add: true is to add a handle range; otherwise is to delete.
** Returns          none.
**
*******************************************************************************/
static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
                                              tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
{
    return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
                                (tBTA_GATTS_SRV_CHG_REQ *) p_req,
                                (tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
}


/*******************************************************************************
**
** Function         bta_gatts_enable
**
** Description      enable BTA GATTS module.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
{
    UINT8 index=0;
    tBTA_GATTS_HNDL_RANGE handle_range;

    if (p_cb->enabled)
    {
        APPL_TRACE_DEBUG("GATTS already enabled.");
    }
    else
    {
        memset(p_cb, 0, sizeof(tBTA_GATTS_CB));

        p_cb->enabled = TRUE;

        while ( bta_gatts_co_load_handle_range(index, &handle_range))
        {
            GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
            memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
            index++;
        }

        APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);

        if (!GATTS_NVRegister(&bta_gatts_nv_cback))
        {
            APPL_TRACE_ERROR("BTA GATTS NV register failed.");
        }
    }
}

/*******************************************************************************
**
** Function         bta_gatts_api_disable
**
** Description      disable BTA GATTS module.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
{
    UINT8 i;

    if (p_cb->enabled)
    {
        for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
        {
            if (p_cb->rcb[i].in_use)
            {
                GATT_Deregister(p_cb->rcb[i].gatt_if);
            }
        }
        memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
    }
    else
    {
        APPL_TRACE_ERROR("GATTS not enabled");
    }
}

/*******************************************************************************
**
** Function         bta_gatts_register
**
** Description      register an application.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
{
    tBTA_GATTS               cb_data;
    tBTA_GATT_STATUS         status = BTA_GATT_OK;
    UINT8                    i, first_unuse = 0xff;

    if (p_cb->enabled == FALSE)
    {
        bta_gatts_enable(p_cb);
    }

    for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
    {
        if (p_cb->rcb[i].in_use)
        {
            if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
            {
                APPL_TRACE_ERROR("application already registered.");
                status = BTA_GATT_DUP_REG;
                break;
            }
        }
    }

    if (status == BTA_GATT_OK)
    {
        for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
        {
            if (first_unuse == 0xff && !p_cb->rcb[i].in_use)
            {
                first_unuse = i;
                break;
            }
        }

        cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
        memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
        if (first_unuse != 0xff)
        {
            APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);

            p_cb->rcb[first_unuse].in_use = TRUE;
            p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
            memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
            cb_data.reg_oper.server_if      =
            p_cb->rcb[first_unuse].gatt_if  =
            GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
            if ( !p_cb->rcb[first_unuse].gatt_if) {
                status = BTA_GATT_NO_RESOURCES;
            } else {
              tBTA_GATTS_INT_START_IF *p_buf =
                  (tBTA_GATTS_INT_START_IF *)osi_malloc(sizeof(tBTA_GATTS_INT_START_IF));
                p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
                p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;

                bta_sys_sendmsg(p_buf);
            }
        } else {
            status = BTA_GATT_NO_RESOURCES;
        }

    }
    cb_data.reg_oper.status = status;
    if (p_msg->api_reg.p_cback)
        (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
}


/*******************************************************************************
**
** Function         bta_gatts_start_if
**
** Description      start an application interface.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
{
    UNUSED(p_cb);

    if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if))
    {
        GATT_StartIf(p_msg->int_start_if.server_if);
    }
    else
    {
        APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
            p_msg->int_start_if.server_if );
    }
}
/*******************************************************************************
**
** Function         bta_gatts_deregister
**
** Description      deregister an application.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
{
    tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
    tBTA_GATTS_CBACK    *p_cback = NULL;
    UINT8               i;
    tBTA_GATTS          cb_data;

    cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
    cb_data.reg_oper.status = status;

    for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
    {
        if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if)
        {
            p_cback = p_cb->rcb[i].p_cback;
            status = BTA_GATT_OK;

            /* deregister the app */
            GATT_Deregister(p_cb->rcb[i].gatt_if);

            /* reset cb */
            memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
            cb_data.reg_oper.status = status;
            break;
        }
    }

    if (p_cback)
    {
        (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
    }
    else
    {
        APPL_TRACE_ERROR("application not registered.");
    }
}
/*******************************************************************************
**
** Function         bta_gatts_create_srvc
**
** Description      action function to create a service.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    UINT8               rcb_idx;
    tBTA_GATTS          cb_data;
    UINT8               srvc_idx;
    UINT16              service_id = 0;

    cb_data.create.status = BTA_GATT_ERROR;

    rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);

    APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);

    if (rcb_idx != BTA_GATTS_INVALID_APP)
    {
        if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP)
        {
            /* create the service now */
            service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
                                              &p_msg->api_create_svc.service_uuid,
                                              p_msg->api_create_svc.inst,
                                              p_msg->api_create_svc.num_handle,
                                              p_msg->api_create_svc.is_pri);

            if (service_id != 0)
            {
                memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
                    &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
                p_cb->srvc_cb[srvc_idx].service_id   = service_id;
                p_cb->srvc_cb[srvc_idx].inst_num     = p_msg->api_create_svc.inst;
                p_cb->srvc_cb[srvc_idx].idx          = srvc_idx;

                cb_data.create.status      = BTA_GATT_OK;
                cb_data.create.service_id  = service_id;
                cb_data.create.is_primary  = p_msg->api_create_svc.is_pri;
                cb_data.create.server_if   = p_cb->rcb[rcb_idx].gatt_if;
            }
            else
            {
                cb_data.status  = BTA_GATT_ERROR;
                memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
                APPL_TRACE_ERROR("service creation failed.");
            }
            memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
            cb_data.create.svc_instance= p_msg->api_create_svc.inst;
        }
        if (p_cb->rcb[rcb_idx].p_cback)
            (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
    }
    else /* application not registered */
    {
        APPL_TRACE_ERROR("Application not registered");
    }
}
/*******************************************************************************
**
** Function         bta_gatts_add_include_srvc
**
** Description      action function to add an included service.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    UINT16          attr_id = 0;
    tBTA_GATTS      cb_data;

    attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
                                      p_msg->api_add_incl_srvc.included_service_id);

    cb_data.add_result.server_if = p_rcb->gatt_if;
    cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    cb_data.add_result.attr_id = attr_id;

    if (attr_id)
    {
        cb_data.add_result.status = BTA_GATT_OK;
    }
    else
    {
        cb_data.add_result.status = BTA_GATT_ERROR;
    }

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
}
/*******************************************************************************
**
** Function         bta_gatts_add_char
**
** Description      action function to add characteristic.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    UINT16          attr_id = 0;
    tBTA_GATTS      cb_data;

    attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
                                      &p_msg->api_add_char.char_uuid,
                                      p_msg->api_add_char.perm,
                                      p_msg->api_add_char.property);
    cb_data.add_result.server_if = p_rcb->gatt_if;
    cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    cb_data.add_result.attr_id = attr_id;
    memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));

    if (attr_id)
    {
        cb_data.add_result.status = BTA_GATT_OK;
    }
    else
    {
        cb_data.add_result.status = BTA_GATT_ERROR;
    }

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
}
/*******************************************************************************
**
** Function         bta_gatts_add_char_descr
**
** Description      action function to add characteristic descriptor.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    UINT16          attr_id = 0;
    tBTA_GATTS      cb_data;

    attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
                                       p_msg->api_add_char_descr.perm,
                                       &p_msg->api_add_char_descr.descr_uuid);

    cb_data.add_result.server_if = p_rcb->gatt_if;
    cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
    cb_data.add_result.attr_id = attr_id;
    memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));

    if (attr_id)
    {
        cb_data.add_result.status = BTA_GATT_OK;
    }
    else
    {
        cb_data.add_result.status = BTA_GATT_ERROR;
    }

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);

}
/*******************************************************************************
**
** Function         bta_gatts_delete_service
**
** Description      action function to delete a service.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    tBTA_GATTS      cb_data;

    cb_data.srvc_oper.server_if = p_rcb->gatt_if;
    cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;

    if (GATTS_DeleteService(p_rcb->gatt_if,
                            &p_srvc_cb->service_uuid,
                            p_srvc_cb->inst_num))
    {
        cb_data.srvc_oper.status = BTA_GATT_OK;
        memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
    }
    else
    {
        cb_data.srvc_oper.status = BTA_GATT_ERROR;
    }

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);

}
/*******************************************************************************
**
** Function         bta_gatts_start_service
**
** Description      action function to start a service.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    tBTA_GATTS      cb_data;

    cb_data.srvc_oper.server_if = p_rcb->gatt_if;
    cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;

    if (GATTS_StartService(p_rcb->gatt_if,
                           p_srvc_cb->service_id,
                           p_msg->api_start.transport) ==  GATT_SUCCESS)
    {
        APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
        cb_data.srvc_oper.status = BTA_GATT_OK;
    }
    else
    {
        cb_data.srvc_oper.status = BTA_GATT_ERROR;
    }

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);

}
/*******************************************************************************
**
** Function         bta_gatts_stop_service
**
** Description      action function to stop a service.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
    tBTA_GATTS      cb_data;
    UNUSED(p_msg);

    GATTS_StopService(p_srvc_cb->service_id);
    cb_data.srvc_oper.server_if = p_rcb->gatt_if;
    cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
    cb_data.srvc_oper.status = BTA_GATT_OK;
    APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);

}
/*******************************************************************************
**
** Function         bta_gatts_send_rsp
**
** Description      GATTS send response.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    UNUSED(p_cb);

    if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
                        p_msg->api_rsp.trans_id,
                        p_msg->api_rsp.status,
                        (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
    {
        APPL_TRACE_ERROR("Sending response failed");
    }

}
/*******************************************************************************
**
** Function         bta_gatts_indicate_handle
**
** Description      GATTS send handle value indication or notification.
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_SRVC_CB  *p_srvc_cb;
    tBTA_GATTS_RCB      *p_rcb = NULL;
    tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
    tGATT_IF            gatt_if;
    BD_ADDR             remote_bda;
    tBTA_TRANSPORT transport;
    tBTA_GATTS          cb_data;

    p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);

    if (p_srvc_cb )
    {
        if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
            &gatt_if, remote_bda, &transport))
        {
            p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);

            if (p_msg->api_indicate.need_confirm)

                status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
                                                      p_msg->api_indicate.attr_id,
                                                      p_msg->api_indicate.len,
                                                      p_msg->api_indicate.value);
            else
                status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
                                                        p_msg->api_indicate.attr_id,
                                                        p_msg->api_indicate.len,
                                                        p_msg->api_indicate.value);

            /* if over BR_EDR, inform PM for mode change */
            if (transport == BTA_TRANSPORT_BR_EDR)
            {
                bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
                bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
            }
        }
        else
        {
            APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
                              p_msg->api_indicate.hdr.layer_specific);
        }

        if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
            p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
        {
            cb_data.req_data.status = status;
            cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;

            (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
        }
    }
    else
    {
        APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
                          p_msg->api_indicate.attr_id);
    }
}


/*******************************************************************************
**
** Function         bta_gatts_open
**
** Description
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB      *p_rcb=NULL;
    tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
    UINT16              conn_id;
    UNUSED(p_cb);

    if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
    {
        /* should always get the connection ID */
        if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
                        p_msg->api_open.is_direct, p_msg->api_open.transport))
        {
            status = BTA_GATT_OK;

            if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
                                            &conn_id, p_msg->api_open.transport))
            {
                status = BTA_GATT_ALREADY_OPEN;
            }
        }
    }
    else
    {
        APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
    }

    if (p_rcb && p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT,  (tBTA_GATTS *)&status);

}
/*******************************************************************************
**
** Function         bta_gatts_cancel_open
**
** Description
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB      *p_rcb;
    tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
    UNUSED(p_cb);

    if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
    {
        if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
                                p_msg->api_cancel_open.is_direct))
        {
            APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
        }
        else
        {
            status= BTA_GATT_OK;
        }
    }
    else
    {
        APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
    }

    if (p_rcb && p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT,  (tBTA_GATTS *)&status);
}
/*******************************************************************************
**
** Function         bta_gatts_close
**
** Description
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB     *p_rcb;
    tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
    tGATT_IF            gatt_if;
    BD_ADDR             remote_bda;
    tBTA_GATT_TRANSPORT transport;

    UNUSED(p_cb);

    if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
    {
        if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
        {
            APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
        }
        else
        {
            status= BTA_GATT_OK;
        }

        p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);

        if (p_rcb && p_rcb->p_cback)
        {
            if (transport == BTA_TRANSPORT_BR_EDR)
                bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);

            (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT,  (tBTA_GATTS *)&status);
        }
    }
    else
    {
        APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
    }

}
/*******************************************************************************
**
** Function         bta_gatts_listen
**
** Description      Start or stop listening for LE connection on a GATT server
**
** Returns          none.
**
*******************************************************************************/
void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
{
    tBTA_GATTS_RCB     *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
    tBTA_GATTS          cb_data;
    UNUSED(p_cb);

    cb_data.reg_oper.status = BTA_GATT_OK;
    cb_data.reg_oper.server_if = p_msg->api_listen.server_if;

    if (p_rcb == NULL)
    {
        APPL_TRACE_ERROR("Unknown GATTS application");
        return;
    }

    if (!GATT_Listen(p_msg->api_listen.server_if,
                     p_msg->api_listen.start,
                     p_msg->api_listen.remote_bda))
    {
        cb_data.status = BTA_GATT_ERROR;
        APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
    }

    if (p_rcb->p_cback)
        (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
}

/*******************************************************************************
**
** Function         bta_gatts_request_cback
**
** Description      GATTS attribute request callback.
**
** Returns          none.
**
*******************************************************************************/
static void bta_gatts_send_request_cback (UINT16 conn_id,
                                          UINT32 trans_id,
                                          tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
{
    tBTA_GATTS          cb_data;
    tBTA_GATTS_RCB     *p_rcb;
    tGATT_IF            gatt_if;
    tBTA_GATT_TRANSPORT transport;

    memset(&cb_data, 0 , sizeof(tBTA_GATTS));

    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
    {
        p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);

        APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
                            conn_id, trans_id, req_type);

        if (p_rcb && p_rcb->p_cback)
        {
            /* if over BR_EDR, inform PM for mode change */
            if (transport == BTA_TRANSPORT_BR_EDR)
            {
                bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
                bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
            }

            cb_data.req_data.conn_id    = conn_id;
            cb_data.req_data.trans_id   = trans_id;
            cb_data.req_data.p_data     = (tBTA_GATTS_REQ_DATA *)p_data;

            (*p_rcb->p_cback)(req_type,  &cb_data);
        }
        else
        {
            APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
        }
    }
    else
    {
        APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
    }
}

/*******************************************************************************
**
** Function         bta_gatts_conn_cback
**
** Description      connection callback.
**
** Returns          none.
**
*******************************************************************************/
static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
                                  BOOLEAN connected, tGATT_DISCONN_REASON reason,
                                  tGATT_TRANSPORT transport)
{
    tBTA_GATTS      cb_data;
    UINT8           evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
    tBTA_GATTS_RCB  *p_reg;

    APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
                        gatt_if, conn_id, connected, reason);
    APPL_TRACE_DEBUG("bta_gatts_conn_cback  bda :%02x-%02x-%02x-%02x-%02x-%02x ",
                      bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);

    bt_bdaddr_t bdaddr;
    bdcpy(bdaddr.address, bda);
    if (connected)
        btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
    else
        btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);

    p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);

    if (p_reg && p_reg->p_cback)
    {
        /* there is no RM for GATT */
        if (transport == BTA_TRANSPORT_BR_EDR)
        {
            if (connected)
                bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
            else
                bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
        }

        cb_data.conn.conn_id = conn_id;
        cb_data.conn.server_if = gatt_if;
        cb_data.conn.reason = reason;
        cb_data.conn.transport = transport;
        memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
        (*p_reg->p_cback)(evt, &cb_data);
    }
    else
    {
        APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
    }
}

/*******************************************************************************
**
** Function         bta_gatts_cong_cback
**
** Description      congestion callback.
**
** Returns          none.
**
*******************************************************************************/
static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
{
    tBTA_GATTS_RCB *p_rcb;
    tGATT_IF gatt_if;
    tBTA_GATT_TRANSPORT transport;
    tBTA_GATTS cb_data;

    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
    {
        p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);

        if (p_rcb && p_rcb->p_cback)
        {
            cb_data.congest.conn_id = conn_id;
            cb_data.congest.congested = congested;

            (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
        }
    }
}
#endif /* BTA_GATT_INCLUDED */
