avct_api.cc revision a484a888196ddf8bcbf1ad3226d6451bc735a94b
1/****************************************************************************** 2 * 3 * Copyright (C) 2003-2016 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 API of the audio/video control transport protocol. 22 * 23 ******************************************************************************/ 24 25#include "avct_api.h" 26#include <string.h> 27#include "avct_int.h" 28#include "bt_common.h" 29#include "bt_target.h" 30#include "bt_types.h" 31#include "bt_utils.h" 32#include "btm_api.h" 33#include "l2c_api.h" 34#include "l2cdefs.h" 35#include "osi/include/osi.h" 36 37/* Control block for AVCT */ 38tAVCT_CB avct_cb; 39 40/******************************************************************************* 41 * 42 * Function AVCT_Register 43 * 44 * Description This is the system level registration function for the 45 * AVCTP protocol. This function initializes AVCTP and 46 * prepares the protocol stack for its use. This function 47 * must be called once by the system or platform using AVCTP 48 * before the other functions of the API an be used. 49 * 50 * 51 * Returns void 52 * 53 ******************************************************************************/ 54void AVCT_Register(uint16_t mtu, UNUSED_ATTR uint16_t mtu_br, 55 uint8_t sec_mask) { 56 AVCT_TRACE_API("AVCT_Register"); 57 58 /* register PSM with L2CAP */ 59 L2CA_Register(AVCT_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_appl); 60 61 /* set security level */ 62 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0, 63 0); 64 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0, 65 0); 66 67 /* initialize AVCTP data structures */ 68 memset(&avct_cb, 0, sizeof(tAVCT_CB)); 69 70 /* Include the browsing channel which uses eFCR */ 71 L2CA_Register(AVCT_BR_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_br_appl); 72 73 /* AVCTP browsing channel uses the same security service as AVCTP control 74 * channel */ 75 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_BR_PSM, 76 0, 0); 77 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_BR_PSM, 78 0, 0); 79 80 if (mtu_br < AVCT_MIN_BROWSE_MTU) mtu_br = AVCT_MIN_BROWSE_MTU; 81 avct_cb.mtu_br = mtu_br; 82 83#if defined(AVCT_INITIAL_TRACE_LEVEL) 84 avct_cb.trace_level = AVCT_INITIAL_TRACE_LEVEL; 85#else 86 avct_cb.trace_level = BT_TRACE_LEVEL_NONE; 87#endif 88 89 if (mtu < AVCT_MIN_CONTROL_MTU) mtu = AVCT_MIN_CONTROL_MTU; 90 /* store mtu */ 91 avct_cb.mtu = mtu; 92} 93 94/******************************************************************************* 95 * 96 * Function AVCT_Deregister 97 * 98 * Description This function is called to deregister use AVCTP protocol. 99 * It is called when AVCTP is no longer being used by any 100 * application in the system. Before this function can be 101 * called, all connections must be removed with 102 * AVCT_RemoveConn(). 103 * 104 * 105 * Returns void 106 * 107 ******************************************************************************/ 108void AVCT_Deregister(void) { 109 AVCT_TRACE_API("AVCT_Deregister"); 110 111 /* deregister PSM with L2CAP */ 112 L2CA_Deregister(AVCT_PSM); 113} 114 115/******************************************************************************* 116 * 117 * Function AVCT_CreateConn 118 * 119 * Description Create an AVCTP connection. There are two types of 120 * connections, initiator and acceptor, as determined by 121 * the p_cc->role parameter. When this function is called to 122 * create an initiator connection, an AVCTP connection to 123 * the peer device is initiated if one does not already exist. 124 * If an acceptor connection is created, the connection waits 125 * passively for an incoming AVCTP connection from a peer 126 * device. 127 * 128 * 129 * Returns AVCT_SUCCESS if successful, otherwise error. 130 * 131 ******************************************************************************/ 132uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, 133 const RawAddress& peer_addr) { 134 uint16_t result = AVCT_SUCCESS; 135 tAVCT_CCB* p_ccb; 136 tAVCT_LCB* p_lcb; 137 138 AVCT_TRACE_API("AVCT_CreateConn: %d, control:%d", p_cc->role, p_cc->control); 139 140 /* Allocate ccb; if no ccbs, return failure */ 141 p_ccb = avct_ccb_alloc(p_cc); 142 if (p_ccb == NULL) { 143 result = AVCT_NO_RESOURCES; 144 } else { 145 /* get handle */ 146 *p_handle = avct_ccb_to_idx(p_ccb); 147 148 /* if initiator connection */ 149 if (p_cc->role == AVCT_INT) { 150 /* find link; if none allocate a new one */ 151 p_lcb = avct_lcb_by_bd(peer_addr); 152 if (p_lcb == NULL) { 153 p_lcb = avct_lcb_alloc(peer_addr); 154 if (p_lcb == NULL) { 155 /* no link resources; free ccb as well */ 156 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL); 157 result = AVCT_NO_RESOURCES; 158 } 159 } 160 /* check if PID already in use */ 161 else if (avct_lcb_has_pid(p_lcb, p_cc->pid)) { 162 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL); 163 result = AVCT_PID_IN_USE; 164 } 165 166 if (result == AVCT_SUCCESS) { 167 /* bind lcb to ccb */ 168 p_ccb->p_lcb = p_lcb; 169 AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state); 170 avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT*)&p_ccb); 171 } 172 } 173 } 174 return result; 175} 176 177/******************************************************************************* 178 * 179 * Function AVCT_RemoveConn 180 * 181 * Description Remove an AVCTP connection. This function is called when 182 * the application is no longer using a connection. If this 183 * is the last connection to a peer the L2CAP channel for AVCTP 184 * will be closed. 185 * 186 * 187 * Returns AVCT_SUCCESS if successful, otherwise error. 188 * 189 ******************************************************************************/ 190uint16_t AVCT_RemoveConn(uint8_t handle) { 191 uint16_t result = AVCT_SUCCESS; 192 tAVCT_CCB* p_ccb; 193 194 AVCT_TRACE_API("AVCT_RemoveConn"); 195 196 /* map handle to ccb */ 197 p_ccb = avct_ccb_by_idx(handle); 198 if (p_ccb == NULL) { 199 result = AVCT_BAD_HANDLE; 200 } 201 /* if connection not bound to lcb, dealloc */ 202 else if (p_ccb->p_lcb == NULL) { 203 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL); 204 } 205 /* send unbind event to lcb */ 206 else { 207 avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, 208 (tAVCT_LCB_EVT*)&p_ccb); 209 } 210 return result; 211} 212 213/******************************************************************************* 214 * 215 * Function AVCT_CreateBrowse 216 * 217 * Description Create an AVCTP Browse channel. There are two types of 218 * connections, initiator and acceptor, as determined by 219 * the role parameter. When this function is called to 220 * create an initiator connection, the Browse channel to 221 * the peer device is initiated if one does not already exist. 222 * If an acceptor connection is created, the connection waits 223 * passively for an incoming AVCTP connection from a peer 224 * device. 225 * 226 * 227 * Returns AVCT_SUCCESS if successful, otherwise error. 228 * 229 ******************************************************************************/ 230uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) { 231 uint16_t result = AVCT_SUCCESS; 232 tAVCT_CCB* p_ccb; 233 tAVCT_BCB* p_bcb; 234 int index; 235 236 AVCT_TRACE_API("AVCT_CreateBrowse: %d", role); 237 238 /* map handle to ccb */ 239 p_ccb = avct_ccb_by_idx(handle); 240 if (p_ccb == NULL) { 241 return AVCT_BAD_HANDLE; 242 } else { 243 /* mark this CCB as supporting browsing channel */ 244 if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) { 245 p_ccb->allocated |= AVCT_ALOC_BCB; 246 } 247 } 248 249 /* if initiator connection */ 250 if (role == AVCT_INT) { 251 /* the link control block must exist before this function is called as INT. 252 */ 253 if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) { 254 result = AVCT_NOT_OPEN; 255 } else { 256 /* find link; if none allocate a new one */ 257 index = p_ccb->p_lcb->allocated; 258 if (index > AVCT_NUM_LINKS) { 259 result = AVCT_BAD_HANDLE; 260 } else { 261 p_bcb = &avct_cb.bcb[index - 1]; 262 p_bcb->allocated = index; 263 } 264 } 265 266 if (result == AVCT_SUCCESS) { 267 /* bind bcb to ccb */ 268 p_ccb->p_bcb = p_bcb; 269 p_bcb->peer_addr = p_ccb->p_lcb->peer_addr; 270 AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state); 271 avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT*)&p_ccb); 272 } 273 } 274 275 return result; 276} 277 278/******************************************************************************* 279 * 280 * Function AVCT_RemoveBrowse 281 * 282 * Description Remove an AVCTP Browse channel. This function is called 283 * when the application is no longer using a connection. If 284 * this is the last connection to a peer the L2CAP channel for 285 * AVCTP will be closed. 286 * 287 * 288 * Returns AVCT_SUCCESS if successful, otherwise error. 289 * 290 ******************************************************************************/ 291uint16_t AVCT_RemoveBrowse(uint8_t handle) { 292 uint16_t result = AVCT_SUCCESS; 293 tAVCT_CCB* p_ccb; 294 295 AVCT_TRACE_API("AVCT_RemoveBrowse"); 296 297 /* map handle to ccb */ 298 p_ccb = avct_ccb_by_idx(handle); 299 if (p_ccb == NULL) { 300 result = AVCT_BAD_HANDLE; 301 } else if (p_ccb->p_bcb != NULL) 302 /* send unbind event to bcb */ 303 { 304 avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, 305 (tAVCT_LCB_EVT*)&p_ccb); 306 } 307 308 return result; 309} 310 311/******************************************************************************* 312 * 313 * Function AVCT_GetBrowseMtu 314 * 315 * Description Get the peer_mtu for the AVCTP Browse channel of the given 316 * connection. 317 * 318 * Returns the peer browsing channel MTU. 319 * 320 ******************************************************************************/ 321uint16_t AVCT_GetBrowseMtu(uint8_t handle) { 322 uint16_t peer_mtu = AVCT_MIN_BROWSE_MTU; 323 324 tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle); 325 326 if (p_ccb != NULL && p_ccb->p_bcb != NULL) { 327 peer_mtu = p_ccb->p_bcb->peer_mtu; 328 } 329 330 return peer_mtu; 331} 332 333/******************************************************************************* 334 * 335 * Function AVCT_GetPeerMtu 336 * 337 * Description Get the peer_mtu for the AVCTP channel of the given 338 * connection. 339 * 340 * Returns the peer MTU size. 341 * 342 ******************************************************************************/ 343uint16_t AVCT_GetPeerMtu(uint8_t handle) { 344 uint16_t peer_mtu = L2CAP_DEFAULT_MTU; 345 tAVCT_CCB* p_ccb; 346 347 /* map handle to ccb */ 348 p_ccb = avct_ccb_by_idx(handle); 349 if (p_ccb != NULL) { 350 if (p_ccb->p_lcb) { 351 peer_mtu = p_ccb->p_lcb->peer_mtu; 352 } 353 } 354 355 return peer_mtu; 356} 357 358/******************************************************************************* 359 * 360 * Function AVCT_MsgReq 361 * 362 * Description Send an AVCTP message to a peer device. In calling 363 * AVCT_MsgReq(), the application should keep track of the 364 * congestion state of AVCTP as communicated with events 365 * AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT. If the 366 * application calls AVCT_MsgReq() when AVCTP is congested 367 * the message may be discarded. The application may make its 368 * first call to AVCT_MsgReq() after it receives an 369 * AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control 370 * channel or AVCT_BROWSE_CONN_CFM_EVT or 371 * AVCT_BROWSE_CONN_IND_EVT on browsing channel. 372 * 373 * p_msg->layer_specific must be set to 374 * AVCT_DATA_CTRL for control channel traffic; 375 * AVCT_DATA_BROWSE for for browse channel traffic. 376 * 377 * Returns AVCT_SUCCESS if successful, otherwise error. 378 * 379 ******************************************************************************/ 380uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) { 381 uint16_t result = AVCT_SUCCESS; 382 tAVCT_CCB* p_ccb; 383 tAVCT_UL_MSG ul_msg; 384 385 AVCT_TRACE_API("%s", __func__); 386 387 /* verify p_msg parameter */ 388 if (p_msg == NULL) { 389 return AVCT_NO_RESOURCES; 390 } 391 AVCT_TRACE_API("%s len: %d layer_specific: %d", __func__, p_msg->len, 392 p_msg->layer_specific); 393 394 /* map handle to ccb */ 395 p_ccb = avct_ccb_by_idx(handle); 396 if (p_ccb == NULL) { 397 result = AVCT_BAD_HANDLE; 398 osi_free(p_msg); 399 } 400 /* verify channel is bound to link */ 401 else if (p_ccb->p_lcb == NULL) { 402 result = AVCT_NOT_OPEN; 403 osi_free(p_msg); 404 } 405 406 if (result == AVCT_SUCCESS) { 407 ul_msg.p_buf = p_msg; 408 ul_msg.p_ccb = p_ccb; 409 ul_msg.label = label; 410 ul_msg.cr = cr; 411 412 /* send msg event to bcb */ 413 if (p_msg->layer_specific == AVCT_DATA_BROWSE) { 414 if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) { 415 /* BCB channel is not open and not allocated */ 416 result = AVCT_BAD_HANDLE; 417 osi_free(p_msg); 418 } else { 419 p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb); 420 avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, 421 (tAVCT_LCB_EVT*)&ul_msg); 422 } 423 } 424 /* send msg event to lcb */ 425 else { 426 avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, 427 (tAVCT_LCB_EVT*)&ul_msg); 428 } 429 } 430 return result; 431} 432