15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2009-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  This is the implementation file for the MCAP Control Channel Action
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Functions.
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
275cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "mca_api.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "mca_defs.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "mca_int.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include  "btu.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** constants
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_rsp_tout
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function processes the response timeout.
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_rsp_tout(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   tMCA_CTRL   evt_data;
515cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen   UNUSED(p_data);
525cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   mca_ccb_report_event(p_ccb, MCA_RSP_TOUT_IND_EVT, &evt_data);
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_report_event
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function reports the given event.
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_report_event(tMCA_CCB *p_ccb, UINT8 event, tMCA_CTRL *p_data)
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb && p_ccb->p_rcb && p_ccb->p_rcb->p_cback)
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_ccb->p_rcb->p_cback)(mca_rcb_to_handle(p_ccb->p_rcb), mca_ccb_to_hdl(p_ccb), event, p_data);
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_free_msg
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function frees the received message.
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_free_msg(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
825cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_ccb);
835cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_freebuf (p_data);
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_snd_req
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function builds a request and sends it to the peer.
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_snd_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_pkt;
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p, *p_start;
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN is_abort = FALSE;
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_DCB *p_dcb;
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
104b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    MCA_TRACE_DEBUG ("mca_ccb_snd_req cong=%d req=%d", p_ccb->cong, p_msg->op_code);
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* check for abort request */
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (p_msg->op_code == MCA_OP_MDL_ABORT_REQ))
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* the Abort API does not have the associated mdl_id.
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         * Get the mdl_id in dcb to compose the request */
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_msg->mdl_id = p_dcb->mdl_id;
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        mca_free_buf ((void **)&p_ccb->p_tx_req);
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->status = MCA_CCB_STAT_NORM;
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        is_abort = TRUE;
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* no pending outgoing messages or it's an abort request for a pending data channel */
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((!p_ccb->p_tx_req) || is_abort)
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_tx_req = p_msg;
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb->cong)
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_pkt)
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_pkt->offset = L2CAP_MIN_OFFSET;
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p++ = p_msg->op_code;
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_msg->op_code == MCA_OP_MDL_CREATE_REQ)
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *p++ = p_msg->mdep_id;
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *p++ = p_msg->param;
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_msg->hdr.layer_specific = TRUE;   /* mark this message as sent */
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_pkt->len = p - p_start;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CA_DataWrite (p_ccb->lcid, p_pkt);
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->timer_entry.param = (TIMER_PARAM_TYPE) p_ccb;
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_MCA_CCB_RSP, p_ccb->p_rcb->reg.rsp_tout);
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* else the L2CAP channel is congested. keep the message to be sent later */
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
147b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        MCA_TRACE_WARNING ("dropping api req");
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_data);
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_snd_rsp
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function builds a response and sends it to
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the peer.
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_snd_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_pkt;
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p, *p_start;
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN chk_mdl = FALSE;
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
169b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    MCA_TRACE_DEBUG ("mca_ccb_snd_rsp cong=%d req=%d", p_ccb->cong, p_msg->op_code);
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* assume that API functions verified the parameters */
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_pkt)
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_pkt->offset = L2CAP_MIN_OFFSET;
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p++ = p_msg->op_code;
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p++ = p_msg->rsp_code;
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_msg->op_code == MCA_OP_MDL_CREATE_RSP)
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p++ = p_msg->param;
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            chk_mdl = TRUE;
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (p_msg->op_code == MCA_OP_MDL_RECONNECT_RSP)
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                chk_mdl = TRUE;
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (chk_mdl && p_msg->rsp_code == MCA_RSP_SUCCESS)
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
189f1c764fab01c929f71e185b97433bf40938026d3Sharvil Nanavati            mca_dcb_by_hdl(p_msg->dcb_idx);
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_rcb->reg.data_psm, BTM_SEC_PROTO_MCA, p_msg->dcb_idx);
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->status = MCA_CCB_STAT_PENDING;
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* set p_tx_req to block API_REQ/API_RSP before DL is up */
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mca_free_buf ((void **)&p_ccb->p_tx_req);
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_tx_req = p_ccb->p_rx_msg;
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_rx_msg = NULL;
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_tx_req->dcb_idx = p_msg->dcb_idx;
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        mca_free_buf ((void **)&p_ccb->p_rx_msg);
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_pkt->len = p - p_start;
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_DataWrite (p_ccb->lcid, p_pkt);
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_do_disconn
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function closes a control channel.
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_do_disconn (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2175cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_data);
2185cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    mca_dcb_close_by_mdl_id (p_ccb, MCA_ALL_MDL_ID);
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_DisconnectReq(p_ccb->lcid);
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_cong
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sets the congestion state for the CCB.
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_cong(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
234b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    MCA_TRACE_DEBUG ("mca_ccb_cong cong=%d/%d", p_ccb->cong, p_data->llcong);
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->cong = p_data->llcong;
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_ccb->cong)
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if there's a held packet, send it now */
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_tx_req && !p_ccb->p_tx_req->hdr.layer_specific)
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data = (tMCA_CCB_EVT *)p_ccb->p_tx_req;
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_tx_req = NULL;
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mca_ccb_snd_req (p_ccb, p_data);
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_hdl_req
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when a MCAP request is received from
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the peer. It calls the application callback function to
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  report the event.
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_hdl_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_pkt = &p_data->hdr;
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p, *p_start;
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_DCB    *p_dcb;
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_CTRL       evt_data;
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_CCB_MSG    *p_rx_msg = NULL;
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           reject_code = MCA_RSP_NO_RESOURCE;
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN         send_rsp = FALSE;
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN         check_req = FALSE;
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           reject_opcode;
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
272b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    MCA_TRACE_DEBUG ("mca_ccb_hdl_req status:%d", p_ccb->status);
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rx_msg = (tMCA_CCB_MSG *)p_pkt;
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    evt_data.hdr.op_code = *p++;
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    reject_opcode = evt_data.hdr.op_code+1;
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
279b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    MCA_TRACE_DEBUG ("received mdl id: %d ", evt_data.hdr.mdl_id);
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->status == MCA_CCB_STAT_PENDING)
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
282b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        MCA_TRACE_DEBUG ("received req inpending state");
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* allow abort in pending state */
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (evt_data.hdr.op_code == MCA_OP_MDL_ABORT_REQ))
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            reject_code = MCA_RSP_SUCCESS;
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            send_rsp = TRUE;
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* clear the pending status */
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->status = MCA_CCB_STAT_NORM;
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->p_tx_req && ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx))!= NULL))
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                mca_dcb_dealloc (p_dcb, NULL);
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                mca_free_buf ((void **)&p_ccb->p_tx_req);
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            reject_code = MCA_RSP_BAD_OP;
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->p_rx_msg)
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
301b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        MCA_TRACE_DEBUG ("still handling prev req");
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* still holding previous message, reject this new one ?? */
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->p_tx_req)
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
307b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        MCA_TRACE_DEBUG ("still waiting for a response ctrl_vpsm:0x%x", p_ccb->ctrl_vpsm);
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* sent a request; waiting for response */
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->ctrl_vpsm == 0)
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
311b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            MCA_TRACE_DEBUG ("local is ACP. accept the cmd from INT");
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* local is acceptor, need to handle the request */
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            check_req = TRUE;
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            reject_code = MCA_RSP_SUCCESS;
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* drop the previous request */
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->p_tx_req->op_code == MCA_OP_MDL_CREATE_REQ) &&
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) != NULL))
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                mca_dcb_dealloc(p_dcb, NULL);
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mca_free_buf ((void **)&p_ccb->p_tx_req);
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mca_stop_timer(p_ccb);
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*  local is initiator, ignore the req */
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GKI_freebuf (p_pkt);
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return;
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_pkt->layer_specific != MCA_RSP_SUCCESS)
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        reject_code = (UINT8)p_pkt->layer_specific;
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (((evt_data.hdr.op_code >= MCA_NUM_STANDARD_OPCODE) &&
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (evt_data.hdr.op_code < MCA_FIRST_SYNC_OP)) ||
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (evt_data.hdr.op_code > MCA_LAST_SYNC_OP))
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* invalid op code */
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            reject_opcode = MCA_OP_ERROR_RSP;
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            evt_data.hdr.mdl_id = 0;
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        check_req = TRUE;
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        reject_code = MCA_RSP_SUCCESS;
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (check_req)
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (reject_code == MCA_RSP_SUCCESS)
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            reject_code = MCA_RSP_BAD_MDL;
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (MCA_IS_VALID_MDL_ID(evt_data.hdr.mdl_id) ||
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((evt_data.hdr.mdl_id == MCA_ALL_MDL_ID) && (evt_data.hdr.op_code == MCA_OP_MDL_DELETE_REQ)))
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                reject_code = MCA_RSP_SUCCESS;
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* mdl_id is valid according to the spec */
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                switch (evt_data.hdr.op_code)
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                case MCA_OP_MDL_CREATE_REQ:
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    evt_data.create_ind.dep_id = *p++;
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    evt_data.create_ind.cfg = *p++;
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_rx_msg->mdep_id = evt_data.create_ind.dep_id;
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (!mca_is_valid_dep_id(p_ccb->p_rcb, p_rx_msg->mdep_id))
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
368b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                        MCA_TRACE_ERROR ("not a valid local mdep id");
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        reject_code = MCA_RSP_BAD_MDEP;
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
373b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                        MCA_TRACE_DEBUG ("the mdl_id is currently used in the CL(create)");
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        /* check if this dep still have MDL available */
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if (mca_dep_free_mdl(p_ccb, evt_data.create_ind.dep_id) == 0)
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
381b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                            MCA_TRACE_ERROR ("the mdep is currently using max_mdl");
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            reject_code = MCA_RSP_MDEP_BUSY;
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                case MCA_OP_MDL_RECONNECT_REQ:
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
390b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                        MCA_TRACE_ERROR ("the mdl_id is currently used in the CL(reconn)");
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        reject_code = MCA_RSP_MDL_BUSY;
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                case MCA_OP_MDL_ABORT_REQ:
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    reject_code = MCA_RSP_BAD_OP;
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                case MCA_OP_MDL_DELETE_REQ:
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* delete the associated mdl */
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    send_rsp = TRUE;
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (((reject_code != MCA_RSP_SUCCESS) && (evt_data.hdr.op_code != MCA_OP_SYNC_INFO_IND))
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        || send_rsp)
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf)
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset = L2CAP_MIN_OFFSET;
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p = p_start = (UINT8*)(p_buf + 1) + L2CAP_MIN_OFFSET;
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p++ = reject_opcode;
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p++ = reject_code;
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_BE_STREAM (p, evt_data.hdr.mdl_id);
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (((*p_start) == MCA_OP_MDL_CREATE_RSP) && (reject_code == MCA_RSP_SUCCESS))
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p++ = evt_data.create_ind.cfg;
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            */
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->len = p - p_start;
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CA_DataWrite (p_ccb->lcid, p_buf);
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (reject_code == MCA_RSP_SUCCESS)
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* use the received GKI buffer to store information to double check response API */
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_msg->op_code = evt_data.hdr.op_code;
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_msg->mdl_id = evt_data.hdr.mdl_id;
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_rx_msg = p_rx_msg;
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (send_rsp)
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GKI_freebuf (p_pkt);
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_rx_msg = NULL;
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_pkt);
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_hdl_rsp
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when a MCAP response is received from
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the peer.  It calls the application callback function with
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the results.
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_hdl_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_pkt = &p_data->hdr;
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_CTRL   evt_data;
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     chk_mdl = FALSE;
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_DCB    *p_dcb;
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_RESULT result = MCA_BAD_HANDLE;
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_TC_TBL *p_tbl;
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_tx_req)
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* verify that the received response matches the sent request */
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        evt_data.hdr.op_code = *p++;
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((evt_data.hdr.op_code == 0) ||
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ((p_ccb->p_tx_req->op_code + 1) == evt_data.hdr.op_code))
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            evt_data.rsp.rsp_code = *p++;
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mca_stop_timer(p_ccb);
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (evt_data.hdr.op_code == MCA_OP_MDL_CREATE_RSP)
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                evt_data.create_cfm.cfg = *p++;
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                chk_mdl = TRUE;
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if (evt_data.hdr.op_code == MCA_OP_MDL_RECONNECT_RSP)
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    chk_mdl = TRUE;
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (chk_mdl)
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (evt_data.hdr.mdl_id != p_dcb->mdl_id)
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
496b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                        MCA_TRACE_ERROR ("peer's mdl_id=%d != our mdl_id=%d", evt_data.hdr.mdl_id, p_dcb->mdl_id);
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        /* change the response code to be an error */
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            evt_data.rsp.rsp_code = MCA_RSP_BAD_MDL;
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            /* send Abort */
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->status = MCA_CCB_STAT_PENDING;
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            MCA_Abort(mca_ccb_to_hdl(p_ccb));
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else if (p_dcb->p_chnl_cfg)
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        /* the data channel configuration is known. Proceed with data channel initiation */
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->data_vpsm, BTM_SEC_PROTO_MCA, p_ccb->p_tx_req->dcb_idx);
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_dcb->lcid = mca_l2c_open_req(p_ccb->peer_addr, p_ccb->data_vpsm, p_dcb->p_chnl_cfg);
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if (p_dcb->lcid)
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_tbl = mca_tc_tbl_dalloc(p_dcb);
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            if (p_tbl)
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            {
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                p_tbl->state = MCA_TC_ST_CONN;
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                p_ccb->status = MCA_CCB_STAT_PENDING;
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                result = MCA_SUCCESS;
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            }
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        /* mark this MCL as pending and wait for MCA_DataChnlCfg */
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->status = MCA_CCB_STAT_PENDING;
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        result = MCA_SUCCESS;
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (result != MCA_SUCCESS && p_dcb)
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    mca_dcb_dealloc(p_dcb, NULL);
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            } /* end of chk_mdl */
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->status != MCA_CCB_STAT_PENDING)
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                mca_free_buf ((void **)&p_ccb->p_tx_req);
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* else a bad response is received */
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* not expecting any response. drop it */
546b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        MCA_TRACE_WARNING ("dropping received rsp (not expecting a response)");
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_freebuf (p_data);
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_ll_open
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to report MCA_CONNECT_IND_EVT event.
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  It also clears the congestion flag (ccb.cong).
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_ll_open (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tMCA_CTRL    evt_data;
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->cong  = FALSE;
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    evt_data.connect_ind.mtu = p_data->open.peer_mtu;
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memcpy (evt_data.connect_ind.bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    mca_ccb_report_event (p_ccb, MCA_CONNECT_IND_EVT, &evt_data);
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         mca_ccb_dl_open
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when data channel is open.
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  It clears p_tx_req to allow other message exchage on this CL.
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid mca_ccb_dl_open (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5825cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_data);
5835cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    mca_free_buf ((void **)&p_ccb->p_tx_req);
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    mca_free_buf ((void **)&p_ccb->p_rx_msg);
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->status = MCA_CCB_STAT_NORM;
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
589