1 /****************************************************************************** 2 * 3 * Copyright 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 */ 38 tAVCT_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 ******************************************************************************/ 54 void 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 ******************************************************************************/ 108 void 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 ******************************************************************************/ 132 uint16_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 tAVCT_LCB_EVT avct_lcb_evt; 171 avct_lcb_evt.p_ccb = p_ccb; 172 avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt); 173 } 174 } 175 } 176 return result; 177 } 178 179 /******************************************************************************* 180 * 181 * Function AVCT_RemoveConn 182 * 183 * Description Remove an AVCTP connection. This function is called when 184 * the application is no longer using a connection. If this 185 * is the last connection to a peer the L2CAP channel for AVCTP 186 * will be closed. 187 * 188 * 189 * Returns AVCT_SUCCESS if successful, otherwise error. 190 * 191 ******************************************************************************/ 192 uint16_t AVCT_RemoveConn(uint8_t handle) { 193 uint16_t result = AVCT_SUCCESS; 194 tAVCT_CCB* p_ccb; 195 196 AVCT_TRACE_API("AVCT_RemoveConn"); 197 198 /* map handle to ccb */ 199 p_ccb = avct_ccb_by_idx(handle); 200 if (p_ccb == NULL) { 201 result = AVCT_BAD_HANDLE; 202 } 203 /* if connection not bound to lcb, dealloc */ 204 else if (p_ccb->p_lcb == NULL) { 205 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL); 206 } 207 /* send unbind event to lcb */ 208 else { 209 tAVCT_LCB_EVT avct_lcb_evt; 210 avct_lcb_evt.p_ccb = p_ccb; 211 avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt); 212 } 213 return result; 214 } 215 216 /******************************************************************************* 217 * 218 * Function AVCT_CreateBrowse 219 * 220 * Description Create an AVCTP Browse channel. There are two types of 221 * connections, initiator and acceptor, as determined by 222 * the role parameter. When this function is called to 223 * create an initiator connection, the Browse channel to 224 * the peer device is initiated if one does not already exist. 225 * If an acceptor connection is created, the connection waits 226 * passively for an incoming AVCTP connection from a peer 227 * device. 228 * 229 * 230 * Returns AVCT_SUCCESS if successful, otherwise error. 231 * 232 ******************************************************************************/ 233 uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) { 234 uint16_t result = AVCT_SUCCESS; 235 tAVCT_CCB* p_ccb; 236 tAVCT_BCB* p_bcb; 237 int index; 238 239 AVCT_TRACE_API("AVCT_CreateBrowse: %d", role); 240 241 /* map handle to ccb */ 242 p_ccb = avct_ccb_by_idx(handle); 243 if (p_ccb == NULL) { 244 return AVCT_BAD_HANDLE; 245 } else { 246 /* mark this CCB as supporting browsing channel */ 247 if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) { 248 p_ccb->allocated |= AVCT_ALOC_BCB; 249 } 250 } 251 252 /* if initiator connection */ 253 if (role == AVCT_INT) { 254 /* the link control block must exist before this function is called as INT. 255 */ 256 if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) { 257 result = AVCT_NOT_OPEN; 258 } else { 259 /* find link; if none allocate a new one */ 260 index = p_ccb->p_lcb->allocated; 261 if (index > AVCT_NUM_LINKS) { 262 result = AVCT_BAD_HANDLE; 263 } else { 264 p_bcb = &avct_cb.bcb[index - 1]; 265 p_bcb->allocated = index; 266 } 267 } 268 269 if (result == AVCT_SUCCESS) { 270 /* bind bcb to ccb */ 271 p_ccb->p_bcb = p_bcb; 272 p_bcb->peer_addr = p_ccb->p_lcb->peer_addr; 273 AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state); 274 tAVCT_LCB_EVT avct_lcb_evt; 275 avct_lcb_evt.p_ccb = p_ccb; 276 avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt); 277 } 278 } 279 280 return result; 281 } 282 283 /******************************************************************************* 284 * 285 * Function AVCT_RemoveBrowse 286 * 287 * Description Remove an AVCTP Browse channel. This function is called 288 * when the application is no longer using a connection. If 289 * this is the last connection to a peer the L2CAP channel for 290 * AVCTP will be closed. 291 * 292 * 293 * Returns AVCT_SUCCESS if successful, otherwise error. 294 * 295 ******************************************************************************/ 296 uint16_t AVCT_RemoveBrowse(uint8_t handle) { 297 uint16_t result = AVCT_SUCCESS; 298 tAVCT_CCB* p_ccb; 299 300 AVCT_TRACE_API("AVCT_RemoveBrowse"); 301 302 /* map handle to ccb */ 303 p_ccb = avct_ccb_by_idx(handle); 304 if (p_ccb == NULL) { 305 result = AVCT_BAD_HANDLE; 306 } else if (p_ccb->p_bcb != NULL) 307 /* send unbind event to bcb */ 308 { 309 tAVCT_LCB_EVT avct_lcb_evt; 310 avct_lcb_evt.p_ccb = p_ccb; 311 avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt); 312 } 313 314 return result; 315 } 316 317 /******************************************************************************* 318 * 319 * Function AVCT_GetBrowseMtu 320 * 321 * Description Get the peer_mtu for the AVCTP Browse channel of the given 322 * connection. 323 * 324 * Returns the peer browsing channel MTU. 325 * 326 ******************************************************************************/ 327 uint16_t AVCT_GetBrowseMtu(uint8_t handle) { 328 uint16_t peer_mtu = AVCT_MIN_BROWSE_MTU; 329 330 tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle); 331 332 if (p_ccb != NULL && p_ccb->p_bcb != NULL) { 333 peer_mtu = p_ccb->p_bcb->peer_mtu; 334 } 335 336 return peer_mtu; 337 } 338 339 /******************************************************************************* 340 * 341 * Function AVCT_GetPeerMtu 342 * 343 * Description Get the peer_mtu for the AVCTP channel of the given 344 * connection. 345 * 346 * Returns the peer MTU size. 347 * 348 ******************************************************************************/ 349 uint16_t AVCT_GetPeerMtu(uint8_t handle) { 350 uint16_t peer_mtu = L2CAP_DEFAULT_MTU; 351 tAVCT_CCB* p_ccb; 352 353 /* map handle to ccb */ 354 p_ccb = avct_ccb_by_idx(handle); 355 if (p_ccb != NULL) { 356 if (p_ccb->p_lcb) { 357 peer_mtu = p_ccb->p_lcb->peer_mtu; 358 } 359 } 360 361 return peer_mtu; 362 } 363 364 /******************************************************************************* 365 * 366 * Function AVCT_MsgReq 367 * 368 * Description Send an AVCTP message to a peer device. In calling 369 * AVCT_MsgReq(), the application should keep track of the 370 * congestion state of AVCTP as communicated with events 371 * AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT. If the 372 * application calls AVCT_MsgReq() when AVCTP is congested 373 * the message may be discarded. The application may make its 374 * first call to AVCT_MsgReq() after it receives an 375 * AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control 376 * channel or AVCT_BROWSE_CONN_CFM_EVT or 377 * AVCT_BROWSE_CONN_IND_EVT on browsing channel. 378 * 379 * p_msg->layer_specific must be set to 380 * AVCT_DATA_CTRL for control channel traffic; 381 * AVCT_DATA_BROWSE for for browse channel traffic. 382 * 383 * Returns AVCT_SUCCESS if successful, otherwise error. 384 * 385 ******************************************************************************/ 386 uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) { 387 uint16_t result = AVCT_SUCCESS; 388 tAVCT_CCB* p_ccb; 389 tAVCT_UL_MSG ul_msg; 390 391 AVCT_TRACE_API("%s", __func__); 392 393 /* verify p_msg parameter */ 394 if (p_msg == NULL) { 395 return AVCT_NO_RESOURCES; 396 } 397 AVCT_TRACE_API("%s len: %d layer_specific: %d", __func__, p_msg->len, 398 p_msg->layer_specific); 399 400 /* map handle to ccb */ 401 p_ccb = avct_ccb_by_idx(handle); 402 if (p_ccb == NULL) { 403 result = AVCT_BAD_HANDLE; 404 osi_free(p_msg); 405 } 406 /* verify channel is bound to link */ 407 else if (p_ccb->p_lcb == NULL) { 408 result = AVCT_NOT_OPEN; 409 osi_free(p_msg); 410 } 411 412 if (result == AVCT_SUCCESS) { 413 ul_msg.p_buf = p_msg; 414 ul_msg.p_ccb = p_ccb; 415 ul_msg.label = label; 416 ul_msg.cr = cr; 417 418 /* send msg event to bcb */ 419 if (p_msg->layer_specific == AVCT_DATA_BROWSE) { 420 if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) { 421 /* BCB channel is not open and not allocated */ 422 result = AVCT_BAD_HANDLE; 423 osi_free(p_msg); 424 } else { 425 p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb); 426 tAVCT_LCB_EVT avct_lcb_evt; 427 avct_lcb_evt.ul_msg = ul_msg; 428 avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt); 429 } 430 } 431 /* send msg event to lcb */ 432 else { 433 tAVCT_LCB_EVT avct_lcb_evt; 434 avct_lcb_evt.ul_msg = ul_msg; 435 avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt); 436 } 437 } 438 return result; 439 } 440