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