1/******************************************************************************
2 *
3 *  Copyright (C) 2003-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  This module contains functions which operate on the AVCTP connection
22 *  control block.
23 *
24 ******************************************************************************/
25
26#include <string.h>
27#include "data_types.h"
28#include "bt_target.h"
29#include "avct_api.h"
30#include "avct_int.h"
31
32/*******************************************************************************
33**
34** Function         avct_ccb_alloc
35**
36** Description      Allocate a connection control block; copy parameters to ccb.
37**
38**
39** Returns          pointer to the ccb, or NULL if none could be allocated.
40**
41*******************************************************************************/
42tAVCT_CCB *avct_ccb_alloc(tAVCT_CC *p_cc)
43{
44    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
45    int         i;
46
47    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
48    {
49        if (!p_ccb->allocated)
50        {
51            p_ccb->allocated = AVCT_ALOC_LCB;
52            memcpy(&p_ccb->cc, p_cc, sizeof(tAVCT_CC));
53            AVCT_TRACE_DEBUG1("avct_ccb_alloc %d", i);
54            break;
55        }
56    }
57
58    if (i == AVCT_NUM_CONN)
59    {
60        /* out of ccbs */
61        p_ccb = NULL;
62        AVCT_TRACE_WARNING0("Out of ccbs");
63    }
64    return p_ccb;
65}
66
67/*******************************************************************************
68**
69** Function         avct_ccb_dealloc
70**
71** Description      Deallocate a connection control block and call application
72**                  callback.
73**
74**
75** Returns          void.
76**
77*******************************************************************************/
78void avct_ccb_dealloc(tAVCT_CCB *p_ccb, UINT8 event, UINT16 result, BD_ADDR bd_addr)
79{
80    tAVCT_CTRL_CBACK    *p_cback = p_ccb->cc.p_ctrl_cback;
81
82    AVCT_TRACE_DEBUG1("avct_ccb_dealloc %d", avct_ccb_to_idx(p_ccb));
83#if (AVCT_BROWSE_INCLUDED == TRUE)
84    if(p_ccb->p_bcb == NULL)
85        memset(p_ccb, 0, sizeof(tAVCT_CCB));
86    else
87    {
88        /* control channel is down, but the browsing channel is still connected 0 disconnect it now */
89        avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
90        p_ccb->p_lcb = NULL;
91    }
92#else
93    memset(p_ccb, 0, sizeof(tAVCT_CCB));
94#endif
95
96    if (event != AVCT_NO_EVT)
97    {
98        (*p_cback)(avct_ccb_to_idx(p_ccb), event, result, bd_addr);
99    }
100}
101
102/*******************************************************************************
103**
104** Function         avct_ccb_to_idx
105**
106** Description      Given a pointer to an ccb, return its index.
107**
108**
109** Returns          Index of ccb.
110**
111*******************************************************************************/
112UINT8 avct_ccb_to_idx(tAVCT_CCB *p_ccb)
113{
114    /* use array arithmetic to determine index */
115    return (UINT8) (p_ccb - avct_cb.ccb);
116}
117
118/*******************************************************************************
119**
120** Function         avct_ccb_by_idx
121**
122** Description      Return ccb pointer based on ccb index (or handle).
123**
124**
125** Returns          pointer to the ccb, or NULL if none found.
126**
127*******************************************************************************/
128tAVCT_CCB *avct_ccb_by_idx(UINT8 idx)
129{
130    tAVCT_CCB   *p_ccb;
131
132    /* verify index */
133    if (idx < AVCT_NUM_CONN)
134    {
135        p_ccb = &avct_cb.ccb[idx];
136
137        /* verify ccb is allocated */
138        if (!p_ccb->allocated)
139        {
140            p_ccb = NULL;
141            AVCT_TRACE_WARNING1("ccb %d not allocated", idx);
142        }
143    }
144    else
145    {
146        p_ccb = NULL;
147        AVCT_TRACE_WARNING1("No ccb for idx %d", idx);
148    }
149    return p_ccb;
150}
151