/******************************************************************************
 *
 *  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 implementation file for the MCAP Control Channel Action
 *  Functions.
 *
 ******************************************************************************/
#include <string.h>
#include "bt_target.h"
#include "bt_utils.h"
#include "gki.h"
#include "btm_api.h"
#include "mca_api.h"
#include "mca_defs.h"
#include "mca_int.h"


#include  "btu.h"
/*****************************************************************************
** constants
*****************************************************************************/
/*******************************************************************************
**
** Function         mca_ccb_rsp_tout
**
** Description      This function processes the response timeout.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_rsp_tout(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
   tMCA_CTRL   evt_data;
   UNUSED(p_data);

   mca_ccb_report_event(p_ccb, MCA_RSP_TOUT_IND_EVT, &evt_data);
}

/*******************************************************************************
**
** Function         mca_ccb_report_event
**
** Description      This function reports the given event.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_report_event(tMCA_CCB *p_ccb, UINT8 event, tMCA_CTRL *p_data)
{
    if (p_ccb && p_ccb->p_rcb && p_ccb->p_rcb->p_cback)
        (*p_ccb->p_rcb->p_cback)(mca_rcb_to_handle(p_ccb->p_rcb), mca_ccb_to_hdl(p_ccb), event, p_data);
}

/*******************************************************************************
**
** Function         mca_ccb_free_msg
**
** Description      This function frees the received message.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_free_msg(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    UNUSED(p_ccb);

    GKI_freebuf (p_data);
}

/*******************************************************************************
**
** Function         mca_ccb_snd_req
**
** Description      This function builds a request and sends it to the peer.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_snd_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
    BT_HDR  *p_pkt;
    UINT8   *p, *p_start;
    BOOLEAN is_abort = FALSE;
    tMCA_DCB *p_dcb;

    MCA_TRACE_DEBUG ("mca_ccb_snd_req cong=%d req=%d", p_ccb->cong, p_msg->op_code);
    /* check for abort request */
    if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (p_msg->op_code == MCA_OP_MDL_ABORT_REQ))
    {
        p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
        /* the Abort API does not have the associated mdl_id.
         * Get the mdl_id in dcb to compose the request */
        p_msg->mdl_id = p_dcb->mdl_id;
        mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
        mca_free_buf ((void **)&p_ccb->p_tx_req);
        p_ccb->status = MCA_CCB_STAT_NORM;
        is_abort = TRUE;
    }

    /* no pending outgoing messages or it's an abort request for a pending data channel */
    if ((!p_ccb->p_tx_req) || is_abort)
    {
        p_ccb->p_tx_req = p_msg;
        if (!p_ccb->cong)
        {
            p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
            if (p_pkt)
            {
                p_pkt->offset = L2CAP_MIN_OFFSET;
                p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
                *p++ = p_msg->op_code;
                UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
                if (p_msg->op_code == MCA_OP_MDL_CREATE_REQ)
                {
                    *p++ = p_msg->mdep_id;
                    *p++ = p_msg->param;
                }
                p_msg->hdr.layer_specific = TRUE;   /* mark this message as sent */
                p_pkt->len = p - p_start;
                L2CA_DataWrite (p_ccb->lcid, p_pkt);
                p_ccb->timer_entry.param = (TIMER_PARAM_TYPE) p_ccb;
                btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_MCA_CCB_RSP, p_ccb->p_rcb->reg.rsp_tout);
            }
        }
        /* else the L2CAP channel is congested. keep the message to be sent later */
    }
    else
    {
        MCA_TRACE_WARNING ("dropping api req");
        GKI_freebuf (p_data);
    }
}

/*******************************************************************************
**
** Function         mca_ccb_snd_rsp
**
** Description      This function builds a response and sends it to
**                  the peer.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_snd_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
    BT_HDR  *p_pkt;
    UINT8   *p, *p_start;
    BOOLEAN chk_mdl = FALSE;

    MCA_TRACE_DEBUG ("mca_ccb_snd_rsp cong=%d req=%d", p_ccb->cong, p_msg->op_code);
    /* assume that API functions verified the parameters */
    p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
    if (p_pkt)
    {
        p_pkt->offset = L2CAP_MIN_OFFSET;
        p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
        *p++ = p_msg->op_code;
        *p++ = p_msg->rsp_code;
        UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
        if (p_msg->op_code == MCA_OP_MDL_CREATE_RSP)
        {
            *p++ = p_msg->param;
            chk_mdl = TRUE;
        }
        else if (p_msg->op_code == MCA_OP_MDL_RECONNECT_RSP)
                chk_mdl = TRUE;

        if (chk_mdl && p_msg->rsp_code == MCA_RSP_SUCCESS)
        {
            mca_dcb_by_hdl(p_msg->dcb_idx);
            BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
                p_ccb->p_rcb->reg.data_psm, BTM_SEC_PROTO_MCA, p_msg->dcb_idx);
            p_ccb->status = MCA_CCB_STAT_PENDING;
            /* set p_tx_req to block API_REQ/API_RSP before DL is up */
            mca_free_buf ((void **)&p_ccb->p_tx_req);
            p_ccb->p_tx_req = p_ccb->p_rx_msg;
            p_ccb->p_rx_msg = NULL;
            p_ccb->p_tx_req->dcb_idx = p_msg->dcb_idx;
        }
        mca_free_buf ((void **)&p_ccb->p_rx_msg);
        p_pkt->len = p - p_start;
        L2CA_DataWrite (p_ccb->lcid, p_pkt);
    }

}

/*******************************************************************************
**
** Function         mca_ccb_do_disconn
**
** Description      This function closes a control channel.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_do_disconn (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    UNUSED(p_data);

    mca_dcb_close_by_mdl_id (p_ccb, MCA_ALL_MDL_ID);
    L2CA_DisconnectReq(p_ccb->lcid);
}

/*******************************************************************************
**
** Function         mca_ccb_cong
**
** Description      This function sets the congestion state for the CCB.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_cong(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    MCA_TRACE_DEBUG ("mca_ccb_cong cong=%d/%d", p_ccb->cong, p_data->llcong);
    p_ccb->cong = p_data->llcong;
    if (!p_ccb->cong)
    {
        /* if there's a held packet, send it now */
        if (p_ccb->p_tx_req && !p_ccb->p_tx_req->hdr.layer_specific)
        {
            p_data = (tMCA_CCB_EVT *)p_ccb->p_tx_req;
            p_ccb->p_tx_req = NULL;
            mca_ccb_snd_req (p_ccb, p_data);
        }
    }
}

/*******************************************************************************
**
** Function         mca_ccb_hdl_req
**
** Description      This function is called when a MCAP request is received from
**                  the peer. It calls the application callback function to
**                  report the event.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_hdl_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    BT_HDR  *p_pkt = &p_data->hdr;
    BT_HDR  *p_buf;
    UINT8   *p, *p_start;
    tMCA_DCB    *p_dcb;
    tMCA_CTRL       evt_data;
    tMCA_CCB_MSG    *p_rx_msg = NULL;
    UINT8           reject_code = MCA_RSP_NO_RESOURCE;
    BOOLEAN         send_rsp = FALSE;
    BOOLEAN         check_req = FALSE;
    UINT8           reject_opcode;

    MCA_TRACE_DEBUG ("mca_ccb_hdl_req status:%d", p_ccb->status);
    p_rx_msg = (tMCA_CCB_MSG *)p_pkt;
    p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    evt_data.hdr.op_code = *p++;
    BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
    reject_opcode = evt_data.hdr.op_code+1;

    MCA_TRACE_DEBUG ("received mdl id: %d ", evt_data.hdr.mdl_id);
    if (p_ccb->status == MCA_CCB_STAT_PENDING)
    {
        MCA_TRACE_DEBUG ("received req inpending state");
        /* allow abort in pending state */
        if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (evt_data.hdr.op_code == MCA_OP_MDL_ABORT_REQ))
        {
            reject_code = MCA_RSP_SUCCESS;
            send_rsp = TRUE;
            /* clear the pending status */
            p_ccb->status = MCA_CCB_STAT_NORM;
            if (p_ccb->p_tx_req && ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx))!= NULL))
            {
                mca_dcb_dealloc (p_dcb, NULL);
                mca_free_buf ((void **)&p_ccb->p_tx_req);
            }
        }
        else
            reject_code = MCA_RSP_BAD_OP;
    }
    else if (p_ccb->p_rx_msg)
    {
        MCA_TRACE_DEBUG ("still handling prev req");
        /* still holding previous message, reject this new one ?? */

    }
    else if (p_ccb->p_tx_req)
    {
        MCA_TRACE_DEBUG ("still waiting for a response ctrl_vpsm:0x%x", p_ccb->ctrl_vpsm);
        /* sent a request; waiting for response */
        if (p_ccb->ctrl_vpsm == 0)
        {
            MCA_TRACE_DEBUG ("local is ACP. accept the cmd from INT");
            /* local is acceptor, need to handle the request */
            check_req = TRUE;
            reject_code = MCA_RSP_SUCCESS;
            /* drop the previous request */
            if ((p_ccb->p_tx_req->op_code == MCA_OP_MDL_CREATE_REQ) &&
                ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) != NULL))
            {
                mca_dcb_dealloc(p_dcb, NULL);
            }
            mca_free_buf ((void **)&p_ccb->p_tx_req);
            mca_stop_timer(p_ccb);
        }
        else
        {
            /*  local is initiator, ignore the req */
            GKI_freebuf (p_pkt);
            return;
        }
    }
    else if (p_pkt->layer_specific != MCA_RSP_SUCCESS)
    {

        reject_code = (UINT8)p_pkt->layer_specific;
        if (((evt_data.hdr.op_code >= MCA_NUM_STANDARD_OPCODE) &&
            (evt_data.hdr.op_code < MCA_FIRST_SYNC_OP)) ||
            (evt_data.hdr.op_code > MCA_LAST_SYNC_OP))
        {
            /* invalid op code */
            reject_opcode = MCA_OP_ERROR_RSP;
            evt_data.hdr.mdl_id = 0;
        }
    }
    else
    {
        check_req = TRUE;
        reject_code = MCA_RSP_SUCCESS;
    }

    if (check_req)
    {
        if (reject_code == MCA_RSP_SUCCESS)
        {
            reject_code = MCA_RSP_BAD_MDL;
            if (MCA_IS_VALID_MDL_ID(evt_data.hdr.mdl_id) ||
                ((evt_data.hdr.mdl_id == MCA_ALL_MDL_ID) && (evt_data.hdr.op_code == MCA_OP_MDL_DELETE_REQ)))
            {
                reject_code = MCA_RSP_SUCCESS;
                /* mdl_id is valid according to the spec */
                switch (evt_data.hdr.op_code)
                {
                case MCA_OP_MDL_CREATE_REQ:
                    evt_data.create_ind.dep_id = *p++;
                    evt_data.create_ind.cfg = *p++;
                    p_rx_msg->mdep_id = evt_data.create_ind.dep_id;
                    if (!mca_is_valid_dep_id(p_ccb->p_rcb, p_rx_msg->mdep_id))
                    {
                        MCA_TRACE_ERROR ("not a valid local mdep id");
                        reject_code = MCA_RSP_BAD_MDEP;
                    }
                    else if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
                    {
                        MCA_TRACE_DEBUG ("the mdl_id is currently used in the CL(create)");
                        mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
                    }
                    else
                    {
                        /* check if this dep still have MDL available */
                        if (mca_dep_free_mdl(p_ccb, evt_data.create_ind.dep_id) == 0)
                        {
                            MCA_TRACE_ERROR ("the mdep is currently using max_mdl");
                            reject_code = MCA_RSP_MDEP_BUSY;
                        }
                    }
                    break;

                case MCA_OP_MDL_RECONNECT_REQ:
                    if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
                    {
                        MCA_TRACE_ERROR ("the mdl_id is currently used in the CL(reconn)");
                        reject_code = MCA_RSP_MDL_BUSY;
                    }
                    break;

                case MCA_OP_MDL_ABORT_REQ:
                    reject_code = MCA_RSP_BAD_OP;
                    break;

                case MCA_OP_MDL_DELETE_REQ:
                    /* delete the associated mdl */
                    mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
                    send_rsp = TRUE;
                    break;
                }
            }
        }
    }

    if (((reject_code != MCA_RSP_SUCCESS) && (evt_data.hdr.op_code != MCA_OP_SYNC_INFO_IND))
        || send_rsp)
    {
        p_buf = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
        if (p_buf)
        {
            p_buf->offset = L2CAP_MIN_OFFSET;
            p = p_start = (UINT8*)(p_buf + 1) + L2CAP_MIN_OFFSET;
            *p++ = reject_opcode;
            *p++ = reject_code;
            UINT16_TO_BE_STREAM (p, evt_data.hdr.mdl_id);
            /*
            if (((*p_start) == MCA_OP_MDL_CREATE_RSP) && (reject_code == MCA_RSP_SUCCESS))
            {
                *p++ = evt_data.create_ind.cfg;
            }
            */

            p_buf->len = p - p_start;
            L2CA_DataWrite (p_ccb->lcid, p_buf);
        }
    }

    if (reject_code == MCA_RSP_SUCCESS)
    {
        /* use the received GKI buffer to store information to double check response API */
        p_rx_msg->op_code = evt_data.hdr.op_code;
        p_rx_msg->mdl_id = evt_data.hdr.mdl_id;
        p_ccb->p_rx_msg = p_rx_msg;
        if (send_rsp)
        {
            GKI_freebuf (p_pkt);
            p_ccb->p_rx_msg = NULL;
        }
        mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
    }
    else
        GKI_freebuf (p_pkt);
}

/*******************************************************************************
**
** Function         mca_ccb_hdl_rsp
**
** Description      This function is called when a MCAP response is received from
**                  the peer.  It calls the application callback function with
**                  the results.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_hdl_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    BT_HDR  *p_pkt = &p_data->hdr;
    UINT8   *p;
    tMCA_CTRL   evt_data;
    BOOLEAN     chk_mdl = FALSE;
    tMCA_DCB    *p_dcb;
    tMCA_RESULT result = MCA_BAD_HANDLE;
    tMCA_TC_TBL *p_tbl;

    if (p_ccb->p_tx_req)
    {
        /* verify that the received response matches the sent request */
        p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
        evt_data.hdr.op_code = *p++;
        if ((evt_data.hdr.op_code == 0) ||
            ((p_ccb->p_tx_req->op_code + 1) == evt_data.hdr.op_code))
        {
            evt_data.rsp.rsp_code = *p++;
            mca_stop_timer(p_ccb);
            BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
            if (evt_data.hdr.op_code == MCA_OP_MDL_CREATE_RSP)
            {
                evt_data.create_cfm.cfg = *p++;
                chk_mdl = TRUE;
            }
            else if (evt_data.hdr.op_code == MCA_OP_MDL_RECONNECT_RSP)
                    chk_mdl = TRUE;

            if (chk_mdl)
            {
                p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
                if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
                {
                    if (evt_data.hdr.mdl_id != p_dcb->mdl_id)
                    {
                        MCA_TRACE_ERROR ("peer's mdl_id=%d != our mdl_id=%d", evt_data.hdr.mdl_id, p_dcb->mdl_id);
                        /* change the response code to be an error */
                        if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
                        {
                            evt_data.rsp.rsp_code = MCA_RSP_BAD_MDL;
                            /* send Abort */
                            p_ccb->status = MCA_CCB_STAT_PENDING;
                            MCA_Abort(mca_ccb_to_hdl(p_ccb));
                        }
                    }
                    else if (p_dcb->p_chnl_cfg)
                    {
                        /* the data channel configuration is known. Proceed with data channel initiation */
                        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;
                                p_ccb->status = MCA_CCB_STAT_PENDING;
                                result = MCA_SUCCESS;
                            }
                        }
                    }
                    else
                    {
                        /* mark this MCL as pending and wait for MCA_DataChnlCfg */
                        p_ccb->status = MCA_CCB_STAT_PENDING;
                        result = MCA_SUCCESS;
                    }
                }

                if (result != MCA_SUCCESS && p_dcb)
                {
                    mca_dcb_dealloc(p_dcb, NULL);
                }
            } /* end of chk_mdl */

            if (p_ccb->status != MCA_CCB_STAT_PENDING)
                mca_free_buf ((void **)&p_ccb->p_tx_req);
            mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
        }
        /* else a bad response is received */
    }
    else
    {
        /* not expecting any response. drop it */
        MCA_TRACE_WARNING ("dropping received rsp (not expecting a response)");
    }
    GKI_freebuf (p_data);
}

/*******************************************************************************
**
** Function         mca_ccb_ll_open
**
** Description      This function is called to report MCA_CONNECT_IND_EVT event.
**                  It also clears the congestion flag (ccb.cong).
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_ll_open (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    tMCA_CTRL    evt_data;
    p_ccb->cong  = FALSE;
    evt_data.connect_ind.mtu = p_data->open.peer_mtu;
    memcpy (evt_data.connect_ind.bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
    mca_ccb_report_event (p_ccb, MCA_CONNECT_IND_EVT, &evt_data);
}

/*******************************************************************************
**
** Function         mca_ccb_dl_open
**
** Description      This function is called when data channel is open.
**                  It clears p_tx_req to allow other message exchage on this CL.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_dl_open (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    UNUSED(p_data);

    mca_free_buf ((void **)&p_ccb->p_tx_req);
    mca_free_buf ((void **)&p_ccb->p_rx_msg);
    p_ccb->status = MCA_CCB_STAT_NORM;
}

