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