/******************************************************************************
 *
 *  Copyright (C) 2009-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 is the API implementation file for the Multi-Channel Adaptation
 *  Protocol (MCAP).
 *
 ******************************************************************************/
#include <assert.h>
#include <string.h>

#include "bt_target.h"
#include "btm_api.h"
#include "btm_int.h"
#include "mca_api.h"
#include "mca_defs.h"
#include "mca_int.h"

#include "btu.h"


/*******************************************************************************
**
** Function         mca_process_timeout
**
** Description      This function is called by BTU when an MCA timer
**                  expires.
**
**                  This function is for use internal to the stack only.
**
** Returns          void
**
*******************************************************************************/
void mca_ccb_timer_timeout(void *data)
{
    tMCA_CCB *p_ccb = (tMCA_CCB *)data;

    mca_ccb_event(p_ccb, MCA_CCB_RSP_TOUT_EVT, NULL);
}

/*******************************************************************************
**
** Function         MCA_Init
**
** Description      Initialize MCAP main control block.
**                  This function is called at stack start up.
**
** Returns          void
**
*******************************************************************************/
void MCA_Init(void)
{
    memset(&mca_cb, 0, sizeof(tMCA_CB));

#if defined(MCA_INITIAL_TRACE_LEVEL)
    mca_cb.trace_level = MCA_INITIAL_TRACE_LEVEL;
#else
    mca_cb.trace_level = BT_TRACE_LEVEL_NONE;
#endif
}

/*******************************************************************************
**
** Function         MCA_SetTraceLevel
**
** Description      This function sets the debug trace level for MCA.
**                  If 0xff is passed, the current trace level is returned.
**
**                  Input Parameters:
**                      level:  The level to set the MCA tracing to:
**                      0xff-returns the current setting.
**                      0-turns off tracing.
**                      >= 1-Errors.
**                      >= 2-Warnings.
**                      >= 3-APIs.
**                      >= 4-Events.
**                      >= 5-Debug.
**
** Returns          The new trace level or current trace level if
**                  the input parameter is 0xff.
**
*******************************************************************************/
UINT8 MCA_SetTraceLevel (UINT8 level)
{
    if (level != 0xFF)
        mca_cb.trace_level = level;

    return (mca_cb.trace_level);
}

/*******************************************************************************
**
** Function         MCA_Register
**
** Description      This function registers an MCAP implementation.
**                  It is assumed that the control channel PSM and data channel
**                  PSM are not used by any other instances of the stack.
**                  If the given p_reg->ctrl_psm is 0, this handle is INT only.
**
** Returns          0, if failed. Otherwise, the MCA handle.
**
*******************************************************************************/
tMCA_HANDLE MCA_Register(tMCA_REG *p_reg, tMCA_CTRL_CBACK *p_cback)
{
    tMCA_RCB    *p_rcb;
    tMCA_HANDLE handle = 0;
    tL2CAP_APPL_INFO l2c_cacp_appl;
    tL2CAP_APPL_INFO l2c_dacp_appl;

    assert(p_reg != NULL );
    assert(p_cback != NULL );

    MCA_TRACE_API ("MCA_Register: ctrl_psm:0x%x, data_psm:0x%x", p_reg->ctrl_psm, p_reg->data_psm);

    if ( (p_rcb = mca_rcb_alloc (p_reg)) != NULL)
    {
        if (p_reg->ctrl_psm)
        {
            if (L2C_INVALID_PSM(p_reg->ctrl_psm) || L2C_INVALID_PSM(p_reg->data_psm))
            {
                MCA_TRACE_ERROR ("INVALID_PSM");
                return 0;
            }

            l2c_cacp_appl = *(tL2CAP_APPL_INFO *)&mca_l2c_int_appl;
            l2c_cacp_appl.pL2CA_ConnectCfm_Cb = NULL;
            l2c_dacp_appl = *(tL2CAP_APPL_INFO *)&l2c_cacp_appl;
            l2c_cacp_appl.pL2CA_ConnectInd_Cb = mca_l2c_cconn_ind_cback;
            l2c_dacp_appl.pL2CA_ConnectInd_Cb = mca_l2c_dconn_ind_cback;
            if (L2CA_Register(p_reg->ctrl_psm, (tL2CAP_APPL_INFO *) &l2c_cacp_appl) &&
                L2CA_Register(p_reg->data_psm, (tL2CAP_APPL_INFO *) &l2c_dacp_appl))
            {
                /* set security level */
                BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_CTRL, p_reg->sec_mask,
                    p_reg->ctrl_psm, BTM_SEC_PROTO_MCA, MCA_CTRL_TCID);

                /* in theory, we do not need this one for data_psm
                 * If we don't, L2CAP rejects with security block (3),
                 * which is different reject code from what MCAP spec suggests.
                 * we set this one, so mca_l2c_dconn_ind_cback can reject /w no resources (4) */
                BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_DATA, p_reg->sec_mask,
                    p_reg->data_psm, BTM_SEC_PROTO_MCA, MCA_CTRL_TCID);
            }
            else
            {
                MCA_TRACE_ERROR ("Failed to register to L2CAP");
                return 0;
            }
        }
        else
            p_rcb->reg.data_psm = 0;
        handle = mca_rcb_to_handle (p_rcb);
        p_rcb->p_cback = p_cback;
        p_rcb->reg.rsp_tout = p_reg->rsp_tout;
    }
    return handle;
}


/*******************************************************************************
**
** Function         MCA_Deregister
**
** Description      This function is called to deregister an MCAP implementation.
**                  Before this function can be called, all control and data
**                  channels must be removed with MCA_DisconnectReq and MCA_CloseReq.
**
** Returns          void
**
*******************************************************************************/
void MCA_Deregister(tMCA_HANDLE handle)
{
    tMCA_RCB *p_rcb = mca_rcb_by_handle(handle);

    MCA_TRACE_API ("MCA_Deregister: %d", handle);
    if (p_rcb && p_rcb->reg.ctrl_psm)
    {
        L2CA_Deregister(p_rcb->reg.ctrl_psm);
        L2CA_Deregister(p_rcb->reg.data_psm);
        btm_sec_clr_service_by_psm (p_rcb->reg.ctrl_psm);
        btm_sec_clr_service_by_psm (p_rcb->reg.data_psm);
    }
    mca_rcb_dealloc(handle);
}


/*******************************************************************************
**
** Function         MCA_CreateDep
**
** Description      Create a data endpoint.  If the MDEP is created successfully,
**                  the MDEP ID is returned in *p_dep. After a data endpoint is
**                  created, an application can initiate a connection between this
**                  endpoint and an endpoint on a peer device.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_CreateDep(tMCA_HANDLE handle, tMCA_DEP *p_dep, tMCA_CS *p_cs)
{
    tMCA_RESULT result = MCA_BAD_HANDLE;
    int       i;
    tMCA_RCB *p_rcb = mca_rcb_by_handle(handle);
    tMCA_CS  *p_depcs;

    assert(p_dep != NULL );
    assert(p_cs != NULL );
    assert(p_cs->p_data_cback != NULL );

    MCA_TRACE_API ("MCA_CreateDep: %d", handle);
    if (p_rcb)
    {
        if (p_cs->max_mdl > MCA_NUM_MDLS)
        {
            MCA_TRACE_ERROR ("max_mdl: %d is too big", p_cs->max_mdl );
            result = MCA_BAD_PARAMS;
        }
        else
        {
            p_depcs = p_rcb->dep;
            if (p_cs->type == MCA_TDEP_ECHO)
            {
                if (p_depcs->p_data_cback)
                {
                    MCA_TRACE_ERROR ("Already has ECHO MDEP");
                    return MCA_NO_RESOURCES;
                }
                memcpy (p_depcs, p_cs, sizeof (tMCA_CS));
                *p_dep = 0;
                result = MCA_SUCCESS;
            }
            else
            {
                result = MCA_NO_RESOURCES;
                /* non-echo MDEP starts from 1 */
                p_depcs++;
                for (i=1; i<MCA_NUM_DEPS; i++, p_depcs++)
                {
                    if (p_depcs->p_data_cback == NULL)
                    {
                        memcpy (p_depcs, p_cs, sizeof (tMCA_CS));
                        /* internally use type as the mdep id */
                        p_depcs->type = i;
                        *p_dep = i;
                        result = MCA_SUCCESS;
                        break;
                    }
                }
            }
        }
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_DeleteDep
**
** Description      Delete a data endpoint.  This function is called when
**                  the implementation is no longer using a data endpoint.
**                  If this function is called when the endpoint is connected
**                  the connection is closed and the data endpoint
**                  is removed.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_DeleteDep(tMCA_HANDLE handle, tMCA_DEP dep)
{
    tMCA_RESULT result = MCA_BAD_HANDLE;
    tMCA_RCB *p_rcb = mca_rcb_by_handle(handle);
    tMCA_DCB *p_dcb;
    int      i, max;
    tMCA_CS  *p_depcs;

    MCA_TRACE_API ("MCA_DeleteDep: %d dep:%d", handle, dep);
    if (p_rcb)
    {
        if (dep < MCA_NUM_DEPS && p_rcb->dep[dep].p_data_cback)
        {
            result = MCA_SUCCESS;
            p_rcb->dep[dep].p_data_cback = NULL;
            p_depcs = &(p_rcb->dep[dep]);
            i = handle - 1;
            max = MCA_NUM_MDLS*MCA_NUM_LINKS;
            p_dcb = &mca_cb.dcb[i*max];
            /* make sure no MDL exists for this MDEP */
            for (i=0; i<max; i++, p_dcb++)
            {
                if (p_dcb->state && p_dcb->p_cs == p_depcs)
                {
                    mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
                }
            }
        }
    }
    return result;
}

/*******************************************************************************
**
** Function         MCA_ConnectReq
**
** Description      This function initiates an MCAP control channel connection
**                  to the peer device.  When the connection is completed, an
**                  MCA_CONNECT_IND_EVT is reported to the application via its
**                  control callback function.
**                  This control channel is identified by the tMCA_CL.
**                  If the connection attempt fails, an MCA_DISCONNECT_IND_EVT is
**                  reported. The security mask parameter overrides the outgoing
**                  security mask set in MCA_Register().
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_ConnectReq(tMCA_HANDLE handle, BD_ADDR bd_addr,
                           UINT16 ctrl_psm, UINT16 sec_mask)
{
    tMCA_RESULT result = MCA_BAD_HANDLE;
    tMCA_CCB    *p_ccb;
    tMCA_TC_TBL *p_tbl;

    MCA_TRACE_API ("MCA_ConnectReq: %d psm:0x%x", handle, ctrl_psm);
    if ((p_ccb = mca_ccb_by_bd(handle, bd_addr)) == NULL)
        p_ccb = mca_ccb_alloc(handle, bd_addr);
    else
    {
        MCA_TRACE_ERROR ("control channel already exists");
        return MCA_BUSY;
    }

    if (p_ccb)
    {
        p_ccb->ctrl_vpsm = L2CA_Register (ctrl_psm, (tL2CAP_APPL_INFO *)&mca_l2c_int_appl);
        result = MCA_NO_RESOURCES;
        if (p_ccb->ctrl_vpsm)
        {
            BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_MCAP_CTRL, sec_mask,
                p_ccb->ctrl_vpsm, BTM_SEC_PROTO_MCA, MCA_CTRL_TCID);
            p_ccb->lcid = mca_l2c_open_req(bd_addr, p_ccb->ctrl_vpsm, NULL);
            if (p_ccb->lcid)
            {
                p_tbl = mca_tc_tbl_calloc(p_ccb);
                if (p_tbl)
                {
                    p_tbl->state = MCA_TC_ST_CONN;
                    p_ccb->sec_mask = sec_mask;
                    result = MCA_SUCCESS;
                }
            }
        }
        if (result != MCA_SUCCESS)
            mca_ccb_dealloc (p_ccb, NULL);
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_DisconnectReq
**
** Description      This function disconnect an MCAP control channel
**                  to the peer device.
**                  If associated data channel exists, they are disconnected.
**                  When the MCL is disconnected an MCA_DISCONNECT_IND_EVT is
**                  reported to the application via its control callback function.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_DisconnectReq(tMCA_CL mcl)
{
    tMCA_RESULT result = MCA_BAD_HANDLE;
    tMCA_CCB *p_ccb = mca_ccb_by_hdl(mcl);

    MCA_TRACE_API ("MCA_DisconnectReq: %d ", mcl);
    if (p_ccb)
    {
        result = MCA_SUCCESS;
        mca_ccb_event (p_ccb, MCA_CCB_API_DISCONNECT_EVT, NULL);
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_CreateMdl
**
** Description      This function sends a CREATE_MDL request to the peer device.
**                  When the response is received, a MCA_CREATE_CFM_EVT is reported
**                  with the given MDL ID.
**                  If the response is successful, a data channel is open
**                  with the given p_chnl_cfg
**                  If p_chnl_cfg is NULL, the data channel is not initiated until
**                  MCA_DataChnlCfg is called to provide the p_chnl_cfg.
**                  When the data channel is open successfully, a MCA_OPEN_CFM_EVT
**                  is reported. This data channel is identified as tMCA_DL.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_CreateMdl(tMCA_CL mcl, tMCA_DEP dep, UINT16 data_psm,
                                         UINT16 mdl_id, UINT8 peer_dep_id,
                                         UINT8 cfg, const tMCA_CHNL_CFG *p_chnl_cfg)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);
    tMCA_DCB        *p_dcb;

    MCA_TRACE_API ("MCA_CreateMdl: %d dep=%d mdl_id=%d peer_dep_id=%d", mcl, dep, mdl_id, peer_dep_id);
    if (p_ccb)
    {
        if (p_ccb->p_tx_req || p_ccb->p_rx_msg || p_ccb->cong)
        {
            MCA_TRACE_ERROR ("pending req");
            return MCA_BUSY;
        }

        if ((peer_dep_id > MCA_MAX_MDEP_ID) || (!MCA_IS_VALID_MDL_ID(mdl_id)))
        {
            MCA_TRACE_ERROR ("bad peer dep id:%d or bad mdl id: %d ", peer_dep_id, mdl_id);
            return MCA_BAD_PARAMS;
        }

        if (mca_ccb_uses_mdl_id(p_ccb, mdl_id))
        {
            MCA_TRACE_ERROR ("mdl id: %d is used in the control link", mdl_id);
            return MCA_BAD_MDL_ID;
        }

        p_dcb = mca_dcb_alloc(p_ccb, dep);
        result = MCA_NO_RESOURCES;
        if (p_dcb)
        {
            /* save the info required by dcb connection */
            p_dcb->p_chnl_cfg       = p_chnl_cfg;
            p_dcb->mdl_id           = mdl_id;
            tMCA_CCB_MSG *p_evt_data =
                (tMCA_CCB_MSG *)osi_malloc(sizeof(tMCA_CCB_MSG));
            if (!p_ccb->data_vpsm)
                p_ccb->data_vpsm = L2CA_Register (data_psm, (tL2CAP_APPL_INFO *)&mca_l2c_int_appl);
            if (p_ccb->data_vpsm) {
                p_evt_data->dcb_idx     = mca_dcb_to_hdl (p_dcb);
                p_evt_data->mdep_id     = peer_dep_id;
                p_evt_data->mdl_id      = mdl_id;
                p_evt_data->param       = cfg;
                p_evt_data->op_code     = MCA_OP_MDL_CREATE_REQ;
                p_evt_data->hdr.event   = MCA_CCB_API_REQ_EVT;
                p_evt_data->hdr.layer_specific   = FALSE;
                mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT *)p_evt_data);
                return MCA_SUCCESS;
            } else {
                osi_free(p_evt_data);
            }

            mca_dcb_dealloc(p_dcb, NULL);
        }
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_CreateMdlRsp
**
** Description      This function sends a CREATE_MDL response to the peer device
**                  in response to a received MCA_CREATE_IND_EVT.
**                  If the rsp_code is successful, a data channel is open
**                  with the given p_chnl_cfg
**                  When the data channel is open successfully, a MCA_OPEN_IND_EVT
**                  is reported. This data channel is identified as tMCA_DL.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_CreateMdlRsp(tMCA_CL mcl, tMCA_DEP dep,
                                            UINT16 mdl_id, UINT8 cfg, UINT8 rsp_code,
                                            const tMCA_CHNL_CFG *p_chnl_cfg)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);
    tMCA_CCB_MSG    evt_data;
    tMCA_DCB        *p_dcb;

    MCA_TRACE_API ("MCA_CreateMdlRsp: %d dep=%d mdl_id=%d cfg=%d rsp_code=%d", mcl, dep, mdl_id, cfg, rsp_code);
    assert(p_chnl_cfg != NULL );
    if (p_ccb)
    {
        if (p_ccb->cong)
        {
            MCA_TRACE_ERROR ("congested");
            return MCA_BUSY;
        }
        if (p_ccb->p_rx_msg && (p_ccb->p_rx_msg->mdep_id == dep )
            && (p_ccb->p_rx_msg->mdl_id == mdl_id) && (p_ccb->p_rx_msg->op_code == MCA_OP_MDL_CREATE_REQ))
        {
            result = MCA_SUCCESS;
            evt_data.dcb_idx    = 0;
            if (rsp_code == MCA_RSP_SUCCESS)
            {
                p_dcb = mca_dcb_alloc(p_ccb, dep);
                if (p_dcb)
                {
                    evt_data.dcb_idx    = mca_dcb_to_hdl(p_dcb);
                    p_dcb->p_chnl_cfg   = p_chnl_cfg;
                    p_dcb->mdl_id       = mdl_id;
                }
                else
                {
                    rsp_code = MCA_RSP_MDEP_BUSY;
                    result = MCA_NO_RESOURCES;
                }
            }

            if (result == MCA_SUCCESS)
            {
                evt_data.mdl_id     = mdl_id;
                evt_data.param      = cfg;
                evt_data.rsp_code   = rsp_code;
                evt_data.op_code    = MCA_OP_MDL_CREATE_RSP;
                mca_ccb_event(p_ccb, MCA_CCB_API_RSP_EVT, (tMCA_CCB_EVT *)&evt_data);
            }
        }
        else
        {
            MCA_TRACE_ERROR ("The given MCL is not expecting a MCA_CreateMdlRsp with the given parameters" );
            result = MCA_BAD_PARAMS;
        }
    }
    return result;
}

/*******************************************************************************
**
** Function         MCA_CloseReq
**
** Description      Close a data channel.  When the channel is closed, an
**                  MCA_CLOSE_CFM_EVT is sent to the application via the
**                  control callback function for this handle.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_CloseReq(tMCA_DL mdl)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_DCB *p_dcb = mca_dcb_by_hdl(mdl);

    MCA_TRACE_API ("MCA_CloseReq: %d ", mdl);
    if (p_dcb)
    {
        result = MCA_SUCCESS;
        mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_ReconnectMdl
**
** Description      This function sends a RECONNECT_MDL request to the peer device.
**                  When the response is received, a MCA_RECONNECT_CFM_EVT is reported.
**                  If p_chnl_cfg is NULL, the data channel is not initiated until
**                  MCA_DataChnlCfg is called to provide the p_chnl_cfg.
**                  If the response is successful, a data channel is open.
**                  When the data channel is open successfully, a MCA_OPEN_CFM_EVT
**                  is reported.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_ReconnectMdl(tMCA_CL mcl, tMCA_DEP dep, UINT16 data_psm,
                                            UINT16 mdl_id, const tMCA_CHNL_CFG *p_chnl_cfg)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);
    tMCA_DCB        *p_dcb;

    MCA_TRACE_API ("MCA_ReconnectMdl: %d ", mcl);
    assert(p_chnl_cfg != NULL );
    if (p_ccb)
    {
        if (p_ccb->p_tx_req || p_ccb->p_rx_msg || p_ccb->cong)
        {
            MCA_TRACE_ERROR ("pending req");
            return MCA_BUSY;
        }

        if (!MCA_IS_VALID_MDL_ID(mdl_id))
        {
            MCA_TRACE_ERROR ("bad mdl id: %d ", mdl_id);
            return MCA_BAD_PARAMS;
        }

        if (mca_ccb_uses_mdl_id(p_ccb, mdl_id))
        {
            MCA_TRACE_ERROR ("mdl id: %d is used in the control link", mdl_id);
            return MCA_BAD_MDL_ID;
        }

        p_dcb = mca_dcb_alloc(p_ccb, dep);
        result = MCA_NO_RESOURCES;
        if (p_dcb) {
            tMCA_CCB_MSG *p_evt_data =
                (tMCA_CCB_MSG *)osi_malloc(sizeof(tMCA_CCB_MSG));

            p_dcb->p_chnl_cfg       = p_chnl_cfg;
            p_dcb->mdl_id           = mdl_id;
            if (!p_ccb->data_vpsm)
                p_ccb->data_vpsm = L2CA_Register (data_psm, (tL2CAP_APPL_INFO *)&mca_l2c_int_appl);
            p_evt_data->dcb_idx     = mca_dcb_to_hdl(p_dcb);
            p_evt_data->mdl_id      = mdl_id;
            p_evt_data->op_code     = MCA_OP_MDL_RECONNECT_REQ;
            p_evt_data->hdr.event   = MCA_CCB_API_REQ_EVT;
            mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT *)p_evt_data);
            return MCA_SUCCESS;
        }
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_ReconnectMdlRsp
**
** Description      This function sends a RECONNECT_MDL response to the peer device
**                  in response to a MCA_RECONNECT_IND_EVT event.
**                  If the response is successful, a data channel is open.
**                  When the data channel is open successfully, a MCA_OPEN_IND_EVT
**                  is reported.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_ReconnectMdlRsp(tMCA_CL mcl, tMCA_DEP dep,
                                               UINT16 mdl_id, UINT8 rsp_code,
                                               const tMCA_CHNL_CFG *p_chnl_cfg)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);
    tMCA_CCB_MSG    evt_data;
    tMCA_DCB        *p_dcb;

    MCA_TRACE_API ("MCA_ReconnectMdlRsp: %d ", mcl);
    assert(p_chnl_cfg != NULL );
    if (p_ccb)
    {
        if (p_ccb->cong)
        {
            MCA_TRACE_ERROR ("congested");
            return MCA_BUSY;
        }
        if (p_ccb->p_rx_msg && (p_ccb->p_rx_msg->mdl_id == mdl_id) &&
            (p_ccb->p_rx_msg->op_code == MCA_OP_MDL_RECONNECT_REQ))
        {
            result = MCA_SUCCESS;
            evt_data.dcb_idx    = 0;
            if (rsp_code == MCA_RSP_SUCCESS)
            {
                p_dcb = mca_dcb_alloc(p_ccb, dep);
                if (p_dcb)
                {
                    evt_data.dcb_idx    = mca_dcb_to_hdl(p_dcb);
                    p_dcb->p_chnl_cfg   = p_chnl_cfg;
                    p_dcb->mdl_id       = mdl_id;
                }
                else
                {
                    MCA_TRACE_ERROR ("Out of MDL for this MDEP");
                    rsp_code = MCA_RSP_MDEP_BUSY;
                    result = MCA_NO_RESOURCES;
                }
            }

            evt_data.mdl_id     = mdl_id;
            evt_data.rsp_code   = rsp_code;
            evt_data.op_code    = MCA_OP_MDL_RECONNECT_RSP;
            mca_ccb_event(p_ccb, MCA_CCB_API_RSP_EVT, (tMCA_CCB_EVT *)&evt_data);
        }
        else
        {
            MCA_TRACE_ERROR ("The given MCL is not expecting a MCA_ReconnectMdlRsp with the given parameters" );
            result = MCA_BAD_PARAMS;
        }
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_DataChnlCfg
**
** Description      This function initiates a data channel connection toward the
**                  connected peer device.
**                  When the data channel is open successfully, a MCA_OPEN_CFM_EVT
**                  is reported. This data channel is identified as tMCA_DL.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_DataChnlCfg(tMCA_CL mcl, const tMCA_CHNL_CFG *p_chnl_cfg)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);
    tMCA_DCB        *p_dcb;
    tMCA_TC_TBL *p_tbl;

    MCA_TRACE_API ("MCA_DataChnlCfg: %d ", mcl);
    assert(p_chnl_cfg != NULL );
    if (p_ccb)
    {
        result = MCA_NO_RESOURCES;
        if ((p_ccb->p_tx_req == NULL) || (p_ccb->status != MCA_CCB_STAT_PENDING) ||
            ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) == NULL))
        {
            MCA_TRACE_ERROR ("The given MCL is not expecting this API:%d", p_ccb->status);
            return result;
        }

        p_dcb->p_chnl_cfg       = p_chnl_cfg;
        BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
            p_ccb->data_vpsm, BTM_SEC_PROTO_MCA, p_ccb->p_tx_req->dcb_idx);
        p_dcb->lcid = mca_l2c_open_req(p_ccb->peer_addr, p_ccb->data_vpsm, p_dcb->p_chnl_cfg);
        if (p_dcb->lcid)
        {
            p_tbl = mca_tc_tbl_dalloc(p_dcb);
            if (p_tbl)
            {
                p_tbl->state = MCA_TC_ST_CONN;
                result = MCA_SUCCESS;
            }
        }
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_Abort
**
** Description      This function sends a ABORT_MDL request to the peer device.
**                  When the response is received, a MCA_ABORT_CFM_EVT is reported.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_Abort(tMCA_CL mcl)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);
    tMCA_DCB        *p_dcb;

    MCA_TRACE_API ("MCA_Abort: %d", mcl);
    if (p_ccb)
    {
        result = MCA_NO_RESOURCES;
        /* verify that we are waiting for data channel to come up with the given mdl */
        if ((p_ccb->p_tx_req == NULL) || (p_ccb->status != MCA_CCB_STAT_PENDING) ||
            ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) == NULL))
        {
            MCA_TRACE_ERROR ("The given MCL is not expecting this API:%d", p_ccb->status);
            return result;
        }

        if (p_ccb->cong)
        {
            MCA_TRACE_ERROR ("congested");
            return MCA_BUSY;
        }

        tMCA_CCB_MSG *p_evt_data =
            (tMCA_CCB_MSG *)osi_malloc(sizeof(tMCA_CCB_MSG));
        result = MCA_SUCCESS;
        p_evt_data->op_code     = MCA_OP_MDL_ABORT_REQ;
        p_evt_data->hdr.event   = MCA_CCB_API_REQ_EVT;
        mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT *)p_evt_data);
    }
    return result;
}


/*******************************************************************************
**
** Function         MCA_Delete
**
** Description      This function sends a DELETE_MDL request to the peer device.
**                  When the response is received, a MCA_DELETE_CFM_EVT is reported.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_Delete(tMCA_CL mcl, UINT16 mdl_id)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_CCB        *p_ccb = mca_ccb_by_hdl(mcl);

    MCA_TRACE_API ("MCA_Delete: %d ", mcl);
    if (p_ccb)
    {
        if (p_ccb->cong)
        {
            MCA_TRACE_ERROR ("congested");
            return MCA_BUSY;
        }
        if (!MCA_IS_VALID_MDL_ID(mdl_id) && (mdl_id != MCA_ALL_MDL_ID))
        {
            MCA_TRACE_ERROR ("bad mdl id: %d ", mdl_id);
            return MCA_BAD_PARAMS;
        }

        tMCA_CCB_MSG *p_evt_data = (tMCA_CCB_MSG *)osi_malloc(sizeof(tMCA_CCB_MSG));
        result = MCA_SUCCESS;
        p_evt_data->mdl_id      = mdl_id;
        p_evt_data->op_code     = MCA_OP_MDL_DELETE_REQ;
        p_evt_data->hdr.event   = MCA_CCB_API_REQ_EVT;
        mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT *)p_evt_data);
    }
    return result;
}

/*******************************************************************************
**
** Function         MCA_WriteReq
**
** Description      Send a data packet to the peer device.
**
**                  The application passes the packet using the BT_HDR structure.
**                  The offset field must be equal to or greater than L2CAP_MIN_OFFSET.
**                  This allows enough space in the buffer for the L2CAP header.
**
**                  The memory pointed to by p_pkt must be a GKI buffer
**                  allocated by the application.  This buffer will be freed
**                  by the protocol stack; the application must not free
**                  this buffer.
**
** Returns          MCA_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
tMCA_RESULT MCA_WriteReq(tMCA_DL mdl, BT_HDR *p_pkt)
{
    tMCA_RESULT     result = MCA_BAD_HANDLE;
    tMCA_DCB *p_dcb = mca_dcb_by_hdl(mdl);
    tMCA_DCB_EVT    evt_data;

    MCA_TRACE_API ("MCA_WriteReq: %d ", mdl);
    if (p_dcb)
    {
        if (p_dcb->cong)
        {
            result = MCA_BUSY;
        }
        else
        {
            evt_data.p_pkt  = p_pkt;
            result = MCA_SUCCESS;
            mca_dcb_event(p_dcb, MCA_DCB_API_WRITE_EVT, &evt_data);
        }
    }
    return result;
}

/*******************************************************************************
**
** Function         MCA_GetL2CapChannel
**
** Description      Get the L2CAP CID used by the given data channel handle.
**
** Returns          L2CAP channel ID if successful, otherwise 0.
**
*******************************************************************************/
UINT16 MCA_GetL2CapChannel (tMCA_DL mdl)
{
    UINT16  lcid = 0;
    tMCA_DCB *p_dcb = mca_dcb_by_hdl(mdl);

    MCA_TRACE_API ("MCA_GetL2CapChannel: %d ", mdl);
    if (p_dcb)
        lcid = p_dcb->lcid;
    return lcid;
}

