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