15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35b790feeeb211c42bf78ca3ae9c26aa30e516765Jakub Pawlowski *  Copyright 2003-2016 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 API of the audio/video control transport protocol.
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "avct_api.h"
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
27911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "avct_int.h"
28911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_common.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_types.h"
315cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
32911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btm_api.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2cdefs.h"
35d7ffd64accbd50a27289a388856e56244ccbb5daMyles Watson#include "osi/include/osi.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Control block for AVCT */
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttAVCT_CB avct_cb;
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
41ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
42ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_Register
43ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
44ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This is the system level registration function for the
45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  AVCTP protocol.  This function initializes AVCTP and
46ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  prepares the protocol stack for its use.  This function
47ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  must be called once by the system or platform using AVCTP
48ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  before the other functions of the API an be used.
49ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
50ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
51ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
52ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
53ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid AVCT_Register(uint16_t mtu, UNUSED_ATTR uint16_t mtu_br,
55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   uint8_t sec_mask) {
56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("AVCT_Register");
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* register PSM with L2CAP */
59911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_Register(AVCT_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_appl);
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* set security level */
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0,
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       0);
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0,
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       0);
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* initialize AVCTP data structures */
68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&avct_cb, 0, sizeof(tAVCT_CB));
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Include the browsing channel which uses eFCR */
71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_Register(AVCT_BR_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_br_appl);
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* AVCTP browsing channel uses the same security service as AVCTP control
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * channel */
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_BR_PSM,
76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       0, 0);
77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_BR_PSM,
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       0, 0);
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (mtu_br < AVCT_MIN_BROWSE_MTU) mtu_br = AVCT_MIN_BROWSE_MTU;
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  avct_cb.mtu_br = mtu_br;
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if defined(AVCT_INITIAL_TRACE_LEVEL)
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  avct_cb.trace_level = AVCT_INITIAL_TRACE_LEVEL;
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  avct_cb.trace_level = BT_TRACE_LEVEL_NONE;
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (mtu < AVCT_MIN_CONTROL_MTU) mtu = AVCT_MIN_CONTROL_MTU;
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* store mtu */
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  avct_cb.mtu = mtu;
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
95ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
96ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_Deregister
97ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
98ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to deregister use AVCTP protocol.
99ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  It is called when AVCTP is no longer being used by any
100ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  application in the system.  Before this function can be
101ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  called, all connections must be removed with
102ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  AVCT_RemoveConn().
103ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
104ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
105ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid AVCT_Deregister(void) {
109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("AVCT_Deregister");
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* deregister PSM with L2CAP */
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_Deregister(AVCT_PSM);
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
116ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
117ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_CreateConn
118ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
119ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Create an AVCTP connection.  There are two types of
120ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  connections, initiator and acceptor, as determined by
121ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the p_cc->role parameter.  When this function is called to
122ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  create an initiator connection, an AVCTP connection to
123ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the peer device is initiated if one does not already exist.
124ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  If an acceptor connection is created, the connection waits
1259ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  passively for an incoming AVCTP connection from a peer
1269ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  device.
127ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
128ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
129ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          AVCT_SUCCESS if successful, otherwise error.
130ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
131ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
132903c16685e62e7721d44460b9171e020f38609f5Jakub Pawlowskiuint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc,
133a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski                         const RawAddress& peer_addr) {
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t result = AVCT_SUCCESS;
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_CCB* p_ccb;
136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_LCB* p_lcb;
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("AVCT_CreateConn: %d, control:%d", p_cc->role, p_cc->control);
139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Allocate ccb; if no ccbs, return failure */
141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb = avct_ccb_alloc(p_cc);
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb == NULL) {
143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = AVCT_NO_RESOURCES;
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* get handle */
146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    *p_handle = avct_ccb_to_idx(p_ccb);
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* if initiator connection */
149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cc->role == AVCT_INT) {
150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* find link; if none allocate a new one */
151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_lcb = avct_lcb_by_bd(peer_addr);
152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_lcb == NULL) {
153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_lcb = avct_lcb_alloc(peer_addr);
154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (p_lcb == NULL) {
155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* no link resources; free ccb as well */
156911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          result = AVCT_NO_RESOURCES;
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* check if PID already in use */
161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      else if (avct_lcb_has_pid(p_lcb, p_cc->pid)) {
162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        result = AVCT_PID_IN_USE;
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (result == AVCT_SUCCESS) {
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* bind lcb to ccb */
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_ccb->p_lcb = p_lcb;
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state);
1708d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson        tAVCT_LCB_EVT avct_lcb_evt;
1718d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson        avct_lcb_evt.p_ccb = p_ccb;
1728d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson        avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return result;
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
180ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
181ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_RemoveConn
182ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
183ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Remove an AVCTP connection.  This function is called when
184ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the application is no longer using a connection.  If this
185ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  is the last connection to a peer the L2CAP channel for AVCTP
186ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  will be closed.
187ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
188ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
189ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          AVCT_SUCCESS if successful, otherwise error.
190ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
191ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t AVCT_RemoveConn(uint8_t handle) {
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t result = AVCT_SUCCESS;
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_CCB* p_ccb;
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("AVCT_RemoveConn");
197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* map handle to ccb */
199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb = avct_ccb_by_idx(handle);
200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb == NULL) {
201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = AVCT_BAD_HANDLE;
202911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* if connection not bound to lcb, dealloc */
204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else if (p_ccb->p_lcb == NULL) {
205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* send unbind event to lcb */
208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else {
2098d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson    tAVCT_LCB_EVT avct_lcb_evt;
2108d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson    avct_lcb_evt.p_ccb = p_ccb;
2118d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson    avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return result;
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
217ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
218ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_CreateBrowse
219ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
220ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Create an AVCTP Browse channel.  There are two types of
221ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  connections, initiator and acceptor, as determined by
222ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the role parameter.  When this function is called to
223ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  create an initiator connection, the Browse channel to
224ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the peer device is initiated if one does not already exist.
225ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  If an acceptor connection is created, the connection waits
2269ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  passively for an incoming AVCTP connection from a peer
2279ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  device.
228ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
229ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
230ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          AVCT_SUCCESS if successful, otherwise error.
231ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
232ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) {
234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t result = AVCT_SUCCESS;
235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_CCB* p_ccb;
236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_BCB* p_bcb;
237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  int index;
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("AVCT_CreateBrowse: %d", role);
240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* map handle to ccb */
242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb = avct_ccb_by_idx(handle);
243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb == NULL) {
244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return AVCT_BAD_HANDLE;
245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* mark this CCB as supporting browsing channel */
247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_ccb->allocated |= AVCT_ALOC_BCB;
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* if initiator connection */
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (role == AVCT_INT) {
254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* the link control block must exist before this function is called as INT.
255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     */
256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) {
257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      result = AVCT_NOT_OPEN;
258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* find link; if none allocate a new one */
260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      index = p_ccb->p_lcb->allocated;
261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (index > AVCT_NUM_LINKS) {
262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        result = AVCT_BAD_HANDLE;
263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb = &avct_cb.bcb[index - 1];
265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->allocated = index;
266911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
269911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (result == AVCT_SUCCESS) {
270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* bind bcb to ccb */
271911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_ccb->p_bcb = p_bcb;
272903c16685e62e7721d44460b9171e020f38609f5Jakub Pawlowski      p_bcb->peer_addr = p_ccb->p_lcb->peer_addr;
273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state);
2748d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson      tAVCT_LCB_EVT avct_lcb_evt;
2758d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson      avct_lcb_evt.p_ccb = p_ccb;
2768d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson      avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return result;
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
284ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
285ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_RemoveBrowse
286ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
2879ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      Remove an AVCTP Browse channel.  This function is called
2889ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  when the application is no longer using a connection.  If
2899ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  this is the last connection to a peer the L2CAP channel for
2909ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  AVCTP will be closed.
291ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
292ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
293ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          AVCT_SUCCESS if successful, otherwise error.
294ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
295ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t AVCT_RemoveBrowse(uint8_t handle) {
297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t result = AVCT_SUCCESS;
298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_CCB* p_ccb;
299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("AVCT_RemoveBrowse");
301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* map handle to ccb */
303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb = avct_ccb_by_idx(handle);
304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb == NULL) {
305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = AVCT_BAD_HANDLE;
306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_ccb->p_bcb != NULL)
307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* send unbind event to bcb */
308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  {
3098d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson    tAVCT_LCB_EVT avct_lcb_evt;
3108d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson    avct_lcb_evt.p_ccb = p_ccb;
3118d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson    avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return result;
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
318ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
319ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_GetBrowseMtu
320ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
321ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Get the peer_mtu for the AVCTP Browse channel of the given
322ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  connection.
323ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
324ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          the peer browsing channel MTU.
325ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
326ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
327911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t AVCT_GetBrowseMtu(uint8_t handle) {
328911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t peer_mtu = AVCT_MIN_BROWSE_MTU;
329a408eb7227b7060aaa84b2dada7ddd9b6a955761Avish Shah
330f9c5752344ec459def74765f512d28fa0f402168Marie Janssen  tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle);
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
332f9c5752344ec459def74765f512d28fa0f402168Marie Janssen  if (p_ccb != NULL && p_ccb->p_bcb != NULL) {
333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    peer_mtu = p_ccb->p_bcb->peer_mtu;
334911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
335a408eb7227b7060aaa84b2dada7ddd9b6a955761Avish Shah
336911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return peer_mtu;
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
340ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
341ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_GetPeerMtu
342ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
343ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Get the peer_mtu for the AVCTP channel of the given
344ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  connection.
345ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
346ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          the peer MTU size.
347ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
348ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t AVCT_GetPeerMtu(uint8_t handle) {
350911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t peer_mtu = L2CAP_DEFAULT_MTU;
351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_CCB* p_ccb;
352911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
353911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* map handle to ccb */
354911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb = avct_ccb_by_idx(handle);
355911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb != NULL) {
356911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_ccb->p_lcb) {
357911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      peer_mtu = p_ccb->p_lcb->peer_mtu;
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
359911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
361911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return peer_mtu;
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
365ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
366ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         AVCT_MsgReq
367ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
368ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Send an AVCTP message to a peer device.  In calling
369ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  AVCT_MsgReq(), the application should keep track of the
370ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  congestion state of AVCTP as communicated with events
371ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT.   If the
372ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  application calls AVCT_MsgReq() when AVCTP is congested
373ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the message may be discarded.  The application may make its
374ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  first call to AVCT_MsgReq() after it receives an
3759ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control
3769ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  channel or AVCT_BROWSE_CONN_CFM_EVT or
3779ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  AVCT_BROWSE_CONN_IND_EVT on browsing channel.
378ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
379ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  p_msg->layer_specific must be set to
380ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  AVCT_DATA_CTRL for control channel traffic;
381ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  AVCT_DATA_BROWSE for for browse channel traffic.
382ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
383ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          AVCT_SUCCESS if successful, otherwise error.
384ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
385ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
386911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) {
387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t result = AVCT_SUCCESS;
388911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_CCB* p_ccb;
389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tAVCT_UL_MSG ul_msg;
390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
391911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("%s", __func__);
392911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
393911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* verify p_msg parameter */
394911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_msg == NULL) {
395911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return AVCT_NO_RESOURCES;
396911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
397911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AVCT_TRACE_API("%s len: %d layer_specific: %d", __func__, p_msg->len,
398911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                 p_msg->layer_specific);
399911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
400911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* map handle to ccb */
401911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb = avct_ccb_by_idx(handle);
402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb == NULL) {
403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = AVCT_BAD_HANDLE;
404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_msg);
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
406911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* verify channel is bound to link */
407911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else if (p_ccb->p_lcb == NULL) {
408911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = AVCT_NOT_OPEN;
409911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_msg);
410911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
411911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (result == AVCT_SUCCESS) {
413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ul_msg.p_buf = p_msg;
414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ul_msg.p_ccb = p_ccb;
415911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ul_msg.label = label;
416911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ul_msg.cr = cr;
417911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
418911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* send msg event to bcb */
419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_msg->layer_specific == AVCT_DATA_BROWSE) {
420911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
421911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* BCB channel is not open and not allocated */
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        result = AVCT_BAD_HANDLE;
423cceb430489a70add1b996d54289867c17f4ac0fdPavlin Radoslavov        osi_free(p_msg);
424911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
425911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb);
4268d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson        tAVCT_LCB_EVT avct_lcb_evt;
4278d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson        avct_lcb_evt.ul_msg = ul_msg;
4288d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson        avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* send msg event to lcb */
432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else {
4338d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson      tAVCT_LCB_EVT avct_lcb_evt;
4348d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson      avct_lcb_evt.ul_msg = ul_msg;
4358d749047a084b2d8a18fcaaac5c585e97a16f58dMyles Watson      avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
438911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return result;
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
440