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