15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2003-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 module contains action functions of the link control state machine.
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
2683e2c342e8b40009f3509425722d309c0b8189b9Chris Manton#include "bt_types.h"
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
285cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avct_api.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avct_int.h"
31258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* packet header length lookup table */
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectconst UINT8 avct_lcb_pkt_type_len[] = {
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVCT_HDR_LEN_SINGLE,
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVCT_HDR_LEN_START,
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVCT_HDR_LEN_CONT,
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVCT_HDR_LEN_END
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project};
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_msg_asmbl
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Reassemble incoming message.
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to reassembled message;  NULL if no message
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  available.
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BT_HDR *avct_lcb_msg_asmbl(tAVCT_LCB *p_lcb, BT_HDR *p_buf)
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   pkt_type;
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_ret;
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* parse the message header */
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + p_buf->offset;
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVCT_PRS_PKT_TYPE(p, pkt_type);
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* quick sanity check on length */
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf->len < avct_lcb_pkt_type_len[pkt_type])
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
66abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_buf);
67158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati        AVCT_TRACE_WARNING("Bad length during reassembly");
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ret = NULL;
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* single packet */
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (pkt_type == AVCT_PKT_TYPE_SINGLE)
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if reassembly in progress drop message and process new single */
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->p_rx_msg != NULL)
75158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati            AVCT_TRACE_WARNING("Got single during reassembly");
76ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov
77abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free_and_reset((void **)&p_lcb->p_rx_msg);
78ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ret = p_buf;
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* start packet */
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (pkt_type == AVCT_PKT_TYPE_START)
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if reassembly in progress drop message and process new start */
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->p_rx_msg != NULL)
86158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati            AVCT_TRACE_WARNING("Got start during reassembly");
8720524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov
88abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_lcb->p_rx_msg);
8920524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov
90ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        /*
91ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov         * Allocate bigger buffer for reassembly. As lower layers are
92ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov         * not aware of possible packet size after reassembly, they
930d65d4cdafc165484dfc8d1c5af4ac1cb7453fd7Mallikarjuna GB         * would have allocated smaller buffer.
940d65d4cdafc165484dfc8d1c5af4ac1cb7453fd7Mallikarjuna GB         */
95abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        p_lcb->p_rx_msg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
96ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        memcpy(p_lcb->p_rx_msg, p_buf,
97ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov               sizeof(BT_HDR) + p_buf->offset + p_buf->len);
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
99ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        /* Free original buffer */
100abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_buf);
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
102ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        /* update p to point to new buffer */
103ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        p = (UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset;
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
105ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        /* copy first header byte over nosp */
106ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        *(p + 1) = *p;
107ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov
108ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        /* set offset to point to where to copy next */
109ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len;
110ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov
111ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        /* adjust length for packet header */
112ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov        p_lcb->p_rx_msg->len -= 1;
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ret = NULL;
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* continue or end */
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if no reassembly in progress drop message */
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->p_rx_msg == NULL)
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
122abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            osi_free(p_buf);
123158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati            AVCT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ret = NULL;
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* get size of buffer holding assembled message */
129ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov            /*
130ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov             * NOTE: The buffer is allocated above at the beginning of the
131ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov             * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
132ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov             */
133ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov            UINT16 buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* adjust offset and len of fragment for header byte */
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset += AVCT_HDR_LEN_CONT;
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->len -= AVCT_HDR_LEN_CONT;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* verify length */
140ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov            if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) {
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* won't fit; free everything */
142ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                AVCT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
143abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free_and_reset((void **)&p_lcb->p_rx_msg);
144abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free(p_buf);
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ret = NULL;
146ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov            } else {
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* copy contents of p_buf to p_rx_msg */
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memcpy((UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset,
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (pkt_type == AVCT_PKT_TYPE_END)
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_rx_msg->offset -= p_lcb->p_rx_msg->len;
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_rx_msg->len += p_buf->len;
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_ret = p_lcb->p_rx_msg;
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_rx_msg = NULL;
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_rx_msg->offset += p_buf->len;
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_rx_msg->len += p_buf->len;
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_ret = NULL;
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
164abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free(p_buf);
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_ret;
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_chnl_open
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Open L2CAP channel to peer
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_chnl_open(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 result = AVCT_RESULT_FAIL;
1855cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_data);
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BTM_SetOutService(p_lcb->peer_addr, BTM_SEC_SERVICE_AVCTP, 0);
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* call l2cap connect req */
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->ch_state = AVCT_CH_CONN;
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb->ch_lcid = L2CA_ConnectReq(AVCT_PSM, p_lcb->peer_addr)) == 0)
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if connect req failed, send ourselves close event */
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT *) &result);
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_unbind_disc
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Deallocate ccb and call callback with disconnect event.
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_unbind_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2095cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_lcb);
2105cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    avct_ccb_dealloc(p_data->p_ccb, AVCT_DISCONNECT_CFM_EVT, 0, NULL);
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_open_ind
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Handle an LL_OPEN event.  For each allocated ccb already
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  bound to this lcb, send a connect event.  For each
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  unbound ccb with a new PID, bind that ccb to this lcb and
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  send a connect event.
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_open_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         i;
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     bind = FALSE;
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if ccb allocated and */
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->allocated)
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if bound to this lcb send connect confirm event */
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->p_lcb == p_lcb)
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                bind = TRUE;
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT,
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                       0, p_lcb->peer_addr);
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if unbound acceptor and lcb doesn't already have a ccb for this PID */
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     (avct_lcb_has_pid(p_lcb, p_ccb->cc.pid) == NULL))
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* bind ccb to lcb and send connect ind event */
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                bind = TRUE;
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb = p_lcb;
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT,
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    0, p_lcb->peer_addr);
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* if no ccbs bound to this lcb, disconnect */
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (bind == FALSE)
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_open_fail
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      L2CAP channel open attempt failed.  Deallocate any ccbs
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on this lcb and send connect confirm event with failure.
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_open_fail(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CCB           *p_ccb = &avct_cb.ccb[0];
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int                 i;
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb))
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            avct_ccb_dealloc(p_ccb, AVCT_CONNECT_CFM_EVT,
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_data->result, p_lcb->peer_addr);
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_close_ind
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      L2CAP channel closed by peer.  Deallocate any initiator
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  ccbs on this lcb and send disconnect ind event.
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_close_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CCB           *p_ccb = &avct_cb.ccb[0];
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int                 i;
3085cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_data);
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb))
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->cc.role == AVCT_INT)
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT,
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 0, p_lcb->peer_addr);
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb = NULL;
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), AVCT_DISCONNECT_IND_EVT,
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          0, p_lcb->peer_addr);
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_close_cfm
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      L2CAP channel closed by us.  Deallocate any initiator
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  ccbs on this lcb and send disconnect ind or cfm event.
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_close_cfm(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CCB           *p_ccb = &avct_cb.ccb[0];
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int                 i;
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               event;
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb))
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if this ccb initiated close send disconnect cfm otherwise ind */
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->ch_close)
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->ch_close = FALSE;
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                event = AVCT_DISCONNECT_CFM_EVT;
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                event = AVCT_DISCONNECT_IND_EVT;
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->cc.role == AVCT_INT)
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                avct_ccb_dealloc(p_ccb, event, p_data->result, p_lcb->peer_addr);
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb = NULL;
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event,
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                       p_data->result, p_lcb->peer_addr);
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_bind_conn
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Bind ccb to lcb and send connect cfm event.
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_bind_conn(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data->p_ccb->p_lcb = p_lcb;
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      AVCT_CONNECT_CFM_EVT, 0, p_lcb->peer_addr);
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_chk_disc
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      A ccb wants to close; if it is the last ccb on this lcb,
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  close channel.  Otherwise just deallocate and call
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  callback.
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_chk_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
406158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati    AVCT_TRACE_WARNING("avct_lcb_chk_disc");
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (AVCT_BROWSE_INCLUDED == TRUE)
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    avct_close_bcb(p_lcb, p_data);
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (avct_lcb_last_ccb(p_lcb, p_data->p_ccb))
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
412158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati        AVCT_TRACE_WARNING("closing");
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data->p_ccb->ch_close = TRUE;
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
418158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati        AVCT_TRACE_WARNING("dealloc ccb");
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        avct_lcb_unbind_disc(p_lcb, p_data);
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_chnl_disc
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Disconnect L2CAP channel.
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_chnl_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4355cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_data);
4365cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_DisconnectReq(p_lcb->ch_lcid);
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_bind_fail
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Deallocate ccb and call callback with connect event
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  with failure result.
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_bind_fail(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4535cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_lcb);
4545cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    avct_ccb_dealloc(p_data->p_ccb, AVCT_CONNECT_CFM_EVT, AVCT_RESULT_FAIL, NULL);
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_cong_ind
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Handle congestion indication from L2CAP.
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_cong_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CCB           *p_ccb = &avct_cb.ccb[0];
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int                 i;
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               event;
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR          *p_buf;
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* set event */
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    event = (p_data->cong) ? AVCT_CONG_IND_EVT : AVCT_UNCONG_IND_EVT;
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->cong = p_data->cong;
4781a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    if (p_lcb->cong == FALSE && !fixed_queue_is_empty(p_lcb->tx_q))
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4801a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        while (!p_lcb->cong &&
4811a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov               (p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_lcb->tx_q)) != NULL)
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED)
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->cong = TRUE;
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* send event to all ccbs on this lcb */
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb))
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0, p_lcb->peer_addr);
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_discard_msg
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Discard a message sent in from the API.
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_discard_msg(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5125cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_lcb);
5135cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
51420524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov    AVCT_TRACE_WARNING("Dropping message");
515abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov    osi_free_and_reset((void **)&p_data->ul_msg.p_buf);
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_send_msg
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an AVCTP message.
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_send_msg(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          curr_msg_len;
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           pkt_type;
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           hdr_len;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           *p;
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           nosp = 0;       /* number of subsequent packets */
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          temp;
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          buf_size = p_lcb->peer_mtu + L2CAP_MIN_OFFSET + BT_HDR_SIZE;
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* store msg len */
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    curr_msg_len = p_data->ul_msg.p_buf->len;
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* initialize packet type and other stuff */
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (curr_msg_len <= (p_lcb->peer_mtu - AVCT_HDR_LEN_SINGLE))
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        pkt_type = AVCT_PKT_TYPE_SINGLE;
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        pkt_type = AVCT_PKT_TYPE_START;
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        temp = (curr_msg_len + AVCT_HDR_LEN_START - p_lcb->peer_mtu);
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        nosp = temp / (p_lcb->peer_mtu - 1) + 1;
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (temp % (p_lcb->peer_mtu - 1)) != 0)
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            nosp++;
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* while we haven't sent all packets */
5575fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    while (curr_msg_len != 0) {
5585fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        BT_HDR *p_buf;
5595fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* set header len */
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hdr_len = avct_lcb_pkt_type_len[pkt_type];
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if remaining msg must be fragmented */
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_data->ul_msg.p_buf->len > (p_lcb->peer_mtu - hdr_len))
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* get a new buffer for fragment we are sending */
567abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            p_buf = (BT_HDR *)osi_malloc(buf_size);
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* copy portion of data from current message to new buffer */
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->len = p_lcb->peer_mtu - hdr_len;
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy((UINT8 *)(p_buf + 1) + p_buf->offset,
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   (UINT8 *)(p_data->ul_msg.p_buf + 1) + p_data->ul_msg.p_buf->offset, p_buf->len);
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data->ul_msg.p_buf->offset += p_buf->len;
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data->ul_msg.p_buf->len -= p_buf->len;
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf = p_data->ul_msg.p_buf;
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        curr_msg_len -= p_buf->len;
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* set up to build header */
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len += hdr_len;
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset -= hdr_len;
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p = (UINT8 *)(p_buf + 1) + p_buf->offset;
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* build header */
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        AVCT_BLD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (pkt_type == AVCT_PKT_TYPE_START)
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT8_TO_STREAM(p, nosp);
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((pkt_type == AVCT_PKT_TYPE_START) || (pkt_type == AVCT_PKT_TYPE_SINGLE))
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->cong == TRUE)
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6041a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            fixed_queue_enqueue(p_lcb->tx_q, p_buf);
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* send message to L2CAP */
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED)
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->cong = TRUE;
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* update pkt type for next packet */
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (curr_msg_len > (p_lcb->peer_mtu - AVCT_HDR_LEN_END))
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            pkt_type = AVCT_PKT_TYPE_CONT;
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            pkt_type = AVCT_PKT_TYPE_END;
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6261a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    AVCT_TRACE_DEBUG ("avct_lcb_send_msg tx_q_count:%d",
6271a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                      fixed_queue_length(p_lcb->tx_q));
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return;
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_free_msg_ind
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Discard an incoming AVCTP message.
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_free_msg_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6435cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_lcb);
6445cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
64520524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov    if (p_data == NULL)
64620524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov        return;
64720524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov
648abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov    osi_free_and_reset((void **)&p_data->p_buf);
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avct_lcb_msg_ind
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Handle an incoming AVCTP message.
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid avct_lcb_msg_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p;
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       label, type, cr_ipid;
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      pid;
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CCB   *p_ccb;
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* this p_buf is to be reported through p_msg_cback. The layer_specific
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * needs to be set properly to indicate that it is received through
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * control channel */
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data->p_buf->layer_specific = AVCT_DATA_CTRL;
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* reassemble message; if no message available (we received a fragment) return */
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_data->p_buf = avct_lcb_msg_asmbl(p_lcb, p_data->p_buf)) == NULL)
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_data->p_buf + 1) + p_data->p_buf->offset;
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* parse header byte */
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVCT_PRS_HDR(p, label, type, cr_ipid);
683f1c764fab01c929f71e185b97433bf40938026d3Sharvil Nanavati    UNUSED(type);
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* check for invalid cr_ipid */
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cr_ipid == AVCT_CR_IPID_INVALID)
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
688158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati        AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid);
689abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free_and_reset((void **)&p_data->p_buf);
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* parse and lookup PID */
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BE_STREAM_TO_UINT16(pid, p);
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_ccb = avct_lcb_has_pid(p_lcb, pid)) != NULL)
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* PID found; send msg up, adjust bt hdr and call msg callback */
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid, p_data->p_buf);
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* PID not found; drop message */
705158084e065230a10ffeba6b24ab2fd22b422baedSharvil Nanavati        AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
706abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free_and_reset((void **)&p_data->p_buf);
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if command send reject */
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (cr_ipid == AVCT_CMD)
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
7115fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            BT_HDR *p_buf = (BT_HDR *)osi_malloc(AVCT_CMD_BUF_SIZE);
7125fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            p_buf->len = AVCT_HDR_LEN_SINGLE;
7135fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
7145fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            p = (UINT8 *)(p_buf + 1) + p_buf->offset;
7155fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            AVCT_BLD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
7165fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            UINT16_TO_BE_STREAM(p, pid);
7175fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            L2CA_DataWrite(p_lcb->ch_lcid, p_buf);
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
721