1 /****************************************************************************** 2 * 3 * Copyright (C) 2004-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 is the advanced audio/video call-out function implementation for 22 * BTIF. 23 * 24 ******************************************************************************/ 25 26 #include "string.h" 27 #include "a2d_api.h" 28 #include "a2d_sbc.h" 29 #include "bta_sys.h" 30 #include "bta_av_api.h" 31 #include "bta_av_co.h" 32 #include "bta_av_ci.h" 33 #include "bta_av_sbc.h" 34 35 #include "btif_media.h" 36 #include "sbc_encoder.h" 37 #include "btif_av_co.h" 38 #include "btif_util.h" 39 #include "osi/include/mutex.h" 40 41 42 /***************************************************************************** 43 ** Constants 44 *****************************************************************************/ 45 46 #define FUNC_TRACE() APPL_TRACE_DEBUG("%s", __FUNCTION__); 47 48 /* Macro to retrieve the number of elements in a statically allocated array */ 49 #define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a)/sizeof((__a)[0])) 50 51 /* MIN and MAX macros */ 52 #define BTA_AV_CO_MIN(X,Y) ((X) < (Y) ? (X) : (Y)) 53 #define BTA_AV_CO_MAX(X,Y) ((X) > (Y) ? (X) : (Y)) 54 55 /* Macro to convert audio handle to index and vice versa */ 56 #define BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl) (((hndl) & (~BTA_AV_CHNL_MSK)) - 1) 57 #define BTA_AV_CO_AUDIO_INDX_TO_HNDL(indx) (((indx) + 1) | BTA_AV_CHNL_AUDIO) 58 59 60 /* Offsets to access codec information in SBC codec */ 61 #define BTA_AV_CO_SBC_FREQ_CHAN_OFF 3 62 #define BTA_AV_CO_SBC_BLOCK_BAND_OFF 4 63 #define BTA_AV_CO_SBC_MIN_BITPOOL_OFF 5 64 #define BTA_AV_CO_SBC_MAX_BITPOOL_OFF 6 65 66 #define BTA_AV_CO_SBC_MAX_BITPOOL 53 67 68 /* SCMS-T protect info */ 69 const UINT8 bta_av_co_cp_scmst[BTA_AV_CP_INFO_LEN] = "\x02\x02\x00"; 70 71 /* SBC SRC codec capabilities */ 72 const tA2D_SBC_CIE bta_av_co_sbc_caps = 73 { 74 (A2D_SBC_IE_SAMP_FREQ_44), /* samp_freq */ 75 (A2D_SBC_IE_CH_MD_JOINT), /* ch_mode */ 76 (A2D_SBC_IE_BLOCKS_16), /* block_len */ 77 (A2D_SBC_IE_SUBBAND_8), /* num_subbands */ 78 (A2D_SBC_IE_ALLOC_MD_L), /* alloc_mthd */ 79 BTA_AV_CO_SBC_MAX_BITPOOL, /* max_bitpool */ 80 A2D_SBC_IE_MIN_BITPOOL /* min_bitpool */ 81 }; 82 83 /* SBC SINK codec capabilities */ 84 const tA2D_SBC_CIE bta_av_co_sbc_sink_caps = 85 { 86 (A2D_SBC_IE_SAMP_FREQ_48 | A2D_SBC_IE_SAMP_FREQ_44), /* samp_freq */ 87 (A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO | A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL), /* ch_mode */ 88 (A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | A2D_SBC_IE_BLOCKS_8 | A2D_SBC_IE_BLOCKS_4), /* block_len */ 89 (A2D_SBC_IE_SUBBAND_4 | A2D_SBC_IE_SUBBAND_8), /* num_subbands */ 90 (A2D_SBC_IE_ALLOC_MD_L | A2D_SBC_IE_ALLOC_MD_S), /* alloc_mthd */ 91 A2D_SBC_IE_MAX_BITPOOL, /* max_bitpool */ 92 A2D_SBC_IE_MIN_BITPOOL /* min_bitpool */ 93 }; 94 95 #if !defined(BTIF_AV_SBC_DEFAULT_SAMP_FREQ) 96 #define BTIF_AV_SBC_DEFAULT_SAMP_FREQ A2D_SBC_IE_SAMP_FREQ_44 97 #endif 98 99 /* Default SBC codec configuration */ 100 const tA2D_SBC_CIE btif_av_sbc_default_config = 101 { 102 BTIF_AV_SBC_DEFAULT_SAMP_FREQ, /* samp_freq */ 103 A2D_SBC_IE_CH_MD_JOINT, /* ch_mode */ 104 A2D_SBC_IE_BLOCKS_16, /* block_len */ 105 A2D_SBC_IE_SUBBAND_8, /* num_subbands */ 106 A2D_SBC_IE_ALLOC_MD_L, /* alloc_mthd */ 107 BTA_AV_CO_SBC_MAX_BITPOOL, /* max_bitpool */ 108 A2D_SBC_IE_MIN_BITPOOL /* min_bitpool */ 109 }; 110 111 112 /***************************************************************************** 113 ** Local data 114 *****************************************************************************/ 115 typedef struct 116 { 117 UINT8 sep_info_idx; /* local SEP index (in BTA tables) */ 118 UINT8 seid; /* peer SEP index (in peer tables) */ 119 UINT8 codec_type; /* peer SEP codec type */ 120 UINT8 codec_caps[AVDT_CODEC_SIZE]; /* peer SEP codec capabilities */ 121 UINT8 num_protect; /* peer SEP number of CP elements */ 122 UINT8 protect_info[BTA_AV_CP_INFO_LEN]; /* peer SEP content protection info */ 123 } tBTA_AV_CO_SINK; 124 125 typedef struct 126 { 127 BD_ADDR addr; /* address of audio/video peer */ 128 tBTA_AV_CO_SINK snks[BTIF_SV_AV_AA_SEP_INDEX]; /* array of supported sinks */ 129 tBTA_AV_CO_SINK srcs[BTIF_SV_AV_AA_SEP_INDEX]; /* array of supported srcs */ 130 UINT8 num_snks; /* total number of sinks at peer */ 131 UINT8 num_srcs; /* total number of srcs at peer */ 132 UINT8 num_seps; /* total number of seids at peer */ 133 UINT8 num_rx_snks; /* number of received sinks */ 134 UINT8 num_rx_srcs; /* number of received srcs */ 135 UINT8 num_sup_snks; /* number of supported sinks in the snks array */ 136 UINT8 num_sup_srcs; /* number of supported srcs in the srcs array */ 137 tBTA_AV_CO_SINK *p_snk; /* currently selected sink */ 138 tBTA_AV_CO_SINK *p_src; /* currently selected src */ 139 UINT8 codec_cfg[AVDT_CODEC_SIZE]; /* current codec configuration */ 140 BOOLEAN cp_active; /* current CP configuration */ 141 BOOLEAN acp; /* acceptor */ 142 BOOLEAN recfg_needed; /* reconfiguration is needed */ 143 BOOLEAN opened; /* opened */ 144 UINT16 mtu; /* maximum transmit unit size */ 145 UINT16 uuid_to_connect; /* uuid of peer device */ 146 } tBTA_AV_CO_PEER; 147 148 typedef struct 149 { 150 BOOLEAN active; 151 UINT8 flag; 152 } tBTA_AV_CO_CP; 153 154 typedef struct 155 { 156 /* Connected peer information */ 157 tBTA_AV_CO_PEER peers[BTA_AV_NUM_STRS]; 158 /* Current codec configuration - access to this variable must be protected */ 159 tBTIF_AV_CODEC_INFO codec_cfg; 160 tBTIF_AV_CODEC_INFO codec_cfg_setconfig; /* remote peer setconfig preference */ 161 162 tBTA_AV_CO_CP cp; 163 } tBTA_AV_CO_CB; 164 165 /* Control block instance */ 166 static tBTA_AV_CO_CB bta_av_co_cb; 167 168 static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg); 169 static void bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER *p_peer); 170 static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo); 171 static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink); 172 static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index); 173 static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg); 174 static BOOLEAN bta_av_co_audio_sink_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg); 175 static BOOLEAN bta_av_co_audio_peer_src_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_src_index); 176 177 178 179 /******************************************************************************* 180 ** 181 ** Function bta_av_co_cp_is_active 182 ** 183 ** Description Get the current configuration of content protection 184 ** 185 ** Returns TRUE if the current streaming has CP, FALSE otherwise 186 ** 187 *******************************************************************************/ 188 BOOLEAN bta_av_co_cp_is_active(void) 189 { 190 FUNC_TRACE(); 191 return bta_av_co_cb.cp.active; 192 } 193 194 /******************************************************************************* 195 ** 196 ** Function bta_av_co_cp_get_flag 197 ** 198 ** Description Get content protection flag 199 ** BTA_AV_CP_SCMS_COPY_NEVER 200 ** BTA_AV_CP_SCMS_COPY_ONCE 201 ** BTA_AV_CP_SCMS_COPY_FREE 202 ** 203 ** Returns The current flag value 204 ** 205 *******************************************************************************/ 206 UINT8 bta_av_co_cp_get_flag(void) 207 { 208 FUNC_TRACE(); 209 return bta_av_co_cb.cp.flag; 210 } 211 212 /******************************************************************************* 213 ** 214 ** Function bta_av_co_cp_set_flag 215 ** 216 ** Description Set content protection flag 217 ** BTA_AV_CP_SCMS_COPY_NEVER 218 ** BTA_AV_CP_SCMS_COPY_ONCE 219 ** BTA_AV_CP_SCMS_COPY_FREE 220 ** 221 ** Returns TRUE if setting the SCMS flag is supported else FALSE 222 ** 223 *******************************************************************************/ 224 BOOLEAN bta_av_co_cp_set_flag(UINT8 cp_flag) 225 { 226 FUNC_TRACE(); 227 228 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 229 #else 230 if (cp_flag != BTA_AV_CP_SCMS_COPY_FREE) 231 { 232 return FALSE; 233 } 234 #endif 235 bta_av_co_cb.cp.flag = cp_flag; 236 return TRUE; 237 } 238 239 /******************************************************************************* 240 ** 241 ** Function bta_av_co_get_peer 242 ** 243 ** Description find the peer entry for a given handle 244 ** 245 ** Returns the control block 246 ** 247 *******************************************************************************/ 248 static tBTA_AV_CO_PEER *bta_av_co_get_peer(tBTA_AV_HNDL hndl) 249 { 250 UINT8 index; 251 FUNC_TRACE(); 252 253 index = BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl); 254 255 /* Sanity check */ 256 if (index >= BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers)) 257 { 258 APPL_TRACE_ERROR("bta_av_co_get_peer peer index out of bounds:%d", index); 259 return NULL; 260 } 261 262 return &bta_av_co_cb.peers[index]; 263 } 264 265 /******************************************************************************* 266 ** 267 ** Function bta_av_co_audio_init 268 ** 269 ** Description This callout function is executed by AV when it is 270 ** started by calling BTA_AvRegister(). This function can be 271 ** used by the phone to initialize audio paths or for other 272 ** initialization purposes. 273 ** 274 ** 275 ** Returns Stream codec and content protection capabilities info. 276 ** 277 *******************************************************************************/ 278 BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_num_protect, 279 UINT8 *p_protect_info, UINT8 index) 280 { 281 FUNC_TRACE(); 282 283 APPL_TRACE_DEBUG("bta_av_co_audio_init: %d", index); 284 285 /* By default - no content protection info */ 286 *p_num_protect = 0; 287 *p_protect_info = 0; 288 289 /* reset remote preference through setconfig */ 290 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE; 291 292 switch (index) 293 { 294 case BTIF_SV_AV_AA_SBC_INDEX: 295 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 296 { 297 UINT8 *p = p_protect_info; 298 299 /* Content protection info - support SCMS-T */ 300 *p_num_protect = 1; 301 *p++ = BTA_AV_CP_LOSC; 302 UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID); 303 304 } 305 #endif 306 /* Set up for SBC codec for SRC*/ 307 *p_codec_type = BTA_AV_CODEC_SBC; 308 309 /* This should not fail because we are using constants for parameters */ 310 A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info); 311 312 /* Codec is valid */ 313 return TRUE; 314 #if (BTA_AV_SINK_INCLUDED == TRUE) 315 case BTIF_SV_AV_AA_SBC_SINK_INDEX: 316 *p_codec_type = BTA_AV_CODEC_SBC; 317 318 /* This should not fail because we are using constants for parameters */ 319 A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_sink_caps, p_codec_info); 320 321 /* Codec is valid */ 322 return TRUE; 323 #endif 324 default: 325 /* Not valid */ 326 return FALSE; 327 } 328 } 329 330 /******************************************************************************* 331 ** 332 ** Function bta_av_co_audio_disc_res 333 ** 334 ** Description This callout function is executed by AV to report the 335 ** number of stream end points (SEP) were found during the 336 ** AVDT stream discovery process. 337 ** 338 ** 339 ** Returns void. 340 ** 341 *******************************************************************************/ 342 void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, UINT8 num_seps, UINT8 num_snk, 343 UINT8 num_src, BD_ADDR addr, UINT16 uuid_local) 344 { 345 tBTA_AV_CO_PEER *p_peer; 346 347 FUNC_TRACE(); 348 349 APPL_TRACE_DEBUG("bta_av_co_audio_disc_res h:x%x num_seps:%d num_snk:%d num_src:%d", 350 hndl, num_seps, num_snk, num_src); 351 352 /* Find the peer info */ 353 p_peer = bta_av_co_get_peer(hndl); 354 if (p_peer == NULL) 355 { 356 APPL_TRACE_ERROR("bta_av_co_audio_disc_res could not find peer entry"); 357 return; 358 } 359 360 /* Sanity check : this should never happen */ 361 if (p_peer->opened) 362 { 363 APPL_TRACE_ERROR("bta_av_co_audio_disc_res peer already opened"); 364 } 365 366 /* Copy the discovery results */ 367 bdcpy(p_peer->addr, addr); 368 p_peer->num_snks = num_snk; 369 p_peer->num_srcs = num_src; 370 p_peer->num_seps = num_seps; 371 p_peer->num_rx_snks = 0; 372 p_peer->num_rx_srcs = 0; 373 p_peer->num_sup_snks = 0; 374 if (uuid_local == UUID_SERVCLASS_AUDIO_SINK) 375 p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SOURCE; 376 else if (uuid_local == UUID_SERVCLASS_AUDIO_SOURCE) 377 p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SINK; 378 } 379 380 /******************************************************************************* 381 ** 382 ** Function bta_av_build_src_cfg 383 ** 384 ** Description This function will build preferred config from src capabilities 385 ** 386 ** 387 ** Returns Pass or Fail for current getconfig. 388 ** 389 *******************************************************************************/ 390 void bta_av_build_src_cfg (UINT8 *p_pref_cfg, UINT8 *p_src_cap) 391 { 392 tA2D_SBC_CIE src_cap; 393 tA2D_SBC_CIE pref_cap; 394 UINT8 status = 0; 395 396 /* initialize it to default SBC configuration */ 397 A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &btif_av_sbc_default_config, p_pref_cfg); 398 /* now try to build a preferred one */ 399 /* parse configuration */ 400 if ((status = A2D_ParsSbcInfo(&src_cap, p_src_cap, TRUE)) != 0) 401 { 402 APPL_TRACE_DEBUG(" Cant parse src cap ret = %d", status); 403 return ; 404 } 405 406 if (src_cap.samp_freq & A2D_SBC_IE_SAMP_FREQ_48) 407 pref_cap.samp_freq = A2D_SBC_IE_SAMP_FREQ_48; 408 else if (src_cap.samp_freq & A2D_SBC_IE_SAMP_FREQ_44) 409 pref_cap.samp_freq = A2D_SBC_IE_SAMP_FREQ_44; 410 411 if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_JOINT) 412 pref_cap.ch_mode = A2D_SBC_IE_CH_MD_JOINT; 413 else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_STEREO) 414 pref_cap.ch_mode = A2D_SBC_IE_CH_MD_STEREO; 415 else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL) 416 pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL; 417 else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_MONO) 418 pref_cap.ch_mode = A2D_SBC_IE_CH_MD_MONO; 419 420 if (src_cap.block_len & A2D_SBC_IE_BLOCKS_16) 421 pref_cap.block_len = A2D_SBC_IE_BLOCKS_16; 422 else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_12) 423 pref_cap.block_len = A2D_SBC_IE_BLOCKS_12; 424 else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_8) 425 pref_cap.block_len = A2D_SBC_IE_BLOCKS_8; 426 else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_4) 427 pref_cap.block_len = A2D_SBC_IE_BLOCKS_4; 428 429 if (src_cap.num_subbands & A2D_SBC_IE_SUBBAND_8) 430 pref_cap.num_subbands = A2D_SBC_IE_SUBBAND_8; 431 else if(src_cap.num_subbands & A2D_SBC_IE_SUBBAND_4) 432 pref_cap.num_subbands = A2D_SBC_IE_SUBBAND_4; 433 434 if (src_cap.alloc_mthd & A2D_SBC_IE_ALLOC_MD_L) 435 pref_cap.alloc_mthd = A2D_SBC_IE_ALLOC_MD_L; 436 else if(src_cap.alloc_mthd & A2D_SBC_IE_ALLOC_MD_S) 437 pref_cap.alloc_mthd = A2D_SBC_IE_ALLOC_MD_S; 438 439 pref_cap.max_bitpool = src_cap.max_bitpool; 440 pref_cap.min_bitpool = src_cap.min_bitpool; 441 442 A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &pref_cap, p_pref_cfg); 443 } 444 445 /******************************************************************************* 446 ** 447 ** Function bta_av_audio_sink_getconfig 448 ** 449 ** Description This callout function is executed by AV to retrieve the 450 ** desired codec and content protection configuration for the 451 ** A2DP Sink audio stream in Initiator. 452 ** 453 ** 454 ** Returns Pass or Fail for current getconfig. 455 ** 456 *******************************************************************************/ 457 UINT8 bta_av_audio_sink_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 458 UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, UINT8 *p_num_protect, 459 UINT8 *p_protect_info) 460 { 461 462 UINT8 result = A2D_FAIL; 463 BOOLEAN supported; 464 tBTA_AV_CO_PEER *p_peer; 465 tBTA_AV_CO_SINK *p_src; 466 UINT8 pref_cfg[AVDT_CODEC_SIZE]; 467 UINT8 index; 468 469 FUNC_TRACE(); 470 471 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig handle:0x%x codec_type:%d seid:%d", 472 hndl, codec_type, seid); 473 APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 474 *p_num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]); 475 476 /* Retrieve the peer info */ 477 p_peer = bta_av_co_get_peer(hndl); 478 if (p_peer == NULL) 479 { 480 APPL_TRACE_ERROR("bta_av_audio_sink_getconfig could not find peer entry"); 481 return A2D_FAIL; 482 } 483 484 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)", 485 p_peer->opened, p_peer->num_srcs, p_peer->num_rx_srcs, p_peer->num_sup_srcs); 486 487 p_peer->num_rx_srcs++; 488 489 /* Check if this is a supported configuration */ 490 supported = FALSE; 491 switch (codec_type) 492 { 493 case BTA_AV_CODEC_SBC: 494 supported = TRUE; 495 break; 496 497 default: 498 break; 499 } 500 501 if (supported) 502 { 503 /* If there is room for a new one */ 504 if (p_peer->num_sup_srcs < BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs)) 505 { 506 p_src = &p_peer->srcs[p_peer->num_sup_srcs++]; 507 508 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig saved caps[%x:%x:%x:%x:%x:%x]", 509 p_codec_info[1], p_codec_info[2], p_codec_info[3], 510 p_codec_info[4], p_codec_info[5], p_codec_info[6]); 511 512 memcpy(p_src->codec_caps, p_codec_info, AVDT_CODEC_SIZE); 513 p_src->codec_type = codec_type; 514 p_src->sep_info_idx = *p_sep_info_idx; 515 p_src->seid = seid; 516 p_src->num_protect = *p_num_protect; 517 memcpy(p_src->protect_info, p_protect_info, BTA_AV_CP_INFO_LEN); 518 } 519 else 520 { 521 APPL_TRACE_ERROR("bta_av_audio_sink_getconfig no more room for SRC info"); 522 } 523 } 524 525 /* If last SNK get capabilities or all supported codec caps retrieved */ 526 if ((p_peer->num_rx_srcs == p_peer->num_srcs) || 527 (p_peer->num_sup_srcs == BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs))) 528 { 529 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig last SRC reached"); 530 531 /* Protect access to bta_av_co_cb.codec_cfg */ 532 mutex_global_lock(); 533 534 /* Find a src that matches the codec config */ 535 if (bta_av_co_audio_peer_src_supports_codec(p_peer, &index)) 536 { 537 APPL_TRACE_DEBUG(" Codec Supported "); 538 p_src = &p_peer->srcs[index]; 539 540 /* Build the codec configuration for this sink */ 541 { 542 /* Save the new configuration */ 543 p_peer->p_src = p_src; 544 /* get preferred config from src_caps */ 545 bta_av_build_src_cfg(pref_cfg, p_src->codec_caps); 546 memcpy(p_peer->codec_cfg, pref_cfg, AVDT_CODEC_SIZE); 547 548 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig p_codec_info[%x:%x:%x:%x:%x:%x]", 549 p_peer->codec_cfg[1], p_peer->codec_cfg[2], p_peer->codec_cfg[3], 550 p_peer->codec_cfg[4], p_peer->codec_cfg[5], p_peer->codec_cfg[6]); 551 /* By default, no content protection */ 552 *p_num_protect = 0; 553 554 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 555 p_peer->cp_active = FALSE; 556 bta_av_co_cb.cp.active = FALSE; 557 #endif 558 559 *p_sep_info_idx = p_src->sep_info_idx; 560 memcpy(p_codec_info, p_peer->codec_cfg, AVDT_CODEC_SIZE); 561 result = A2D_SUCCESS; 562 } 563 } 564 /* Protect access to bta_av_co_cb.codec_cfg */ 565 mutex_global_unlock(); 566 } 567 return result; 568 } 569 /******************************************************************************* 570 ** 571 ** Function bta_av_co_audio_getconfig 572 ** 573 ** Description This callout function is executed by AV to retrieve the 574 ** desired codec and content protection configuration for the 575 ** audio stream. 576 ** 577 ** 578 ** Returns Stream codec and content protection configuration info. 579 ** 580 *******************************************************************************/ 581 UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 582 UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, UINT8 *p_num_protect, 583 UINT8 *p_protect_info) 584 585 { 586 UINT8 result = A2D_FAIL; 587 BOOLEAN supported; 588 tBTA_AV_CO_PEER *p_peer; 589 tBTA_AV_CO_SINK *p_sink; 590 UINT8 codec_cfg[AVDT_CODEC_SIZE]; 591 UINT8 index; 592 593 FUNC_TRACE(); 594 595 /* Retrieve the peer info */ 596 p_peer = bta_av_co_get_peer(hndl); 597 if (p_peer == NULL) 598 { 599 APPL_TRACE_ERROR("bta_av_co_audio_getconfig could not find peer entry"); 600 return A2D_FAIL; 601 } 602 603 if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) 604 { 605 result = bta_av_audio_sink_getconfig(hndl, codec_type, p_codec_info, p_sep_info_idx, 606 seid, p_num_protect, p_protect_info); 607 return result; 608 } 609 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig handle:0x%x codec_type:%d seid:%d", 610 hndl, codec_type, seid); 611 APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 612 *p_num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]); 613 614 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)", 615 p_peer->opened, p_peer->num_snks, p_peer->num_rx_snks, p_peer->num_sup_snks); 616 617 p_peer->num_rx_snks++; 618 619 /* Check if this is a supported configuration */ 620 supported = FALSE; 621 switch (codec_type) 622 { 623 case BTA_AV_CODEC_SBC: 624 supported = TRUE; 625 break; 626 627 default: 628 break; 629 } 630 631 if (supported) 632 { 633 /* If there is room for a new one */ 634 if (p_peer->num_sup_snks < BTA_AV_CO_NUM_ELEMENTS(p_peer->snks)) 635 { 636 p_sink = &p_peer->snks[p_peer->num_sup_snks++]; 637 638 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig saved caps[%x:%x:%x:%x:%x:%x]", 639 p_codec_info[1], p_codec_info[2], p_codec_info[3], 640 p_codec_info[4], p_codec_info[5], p_codec_info[6]); 641 642 memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE); 643 p_sink->codec_type = codec_type; 644 p_sink->sep_info_idx = *p_sep_info_idx; 645 p_sink->seid = seid; 646 p_sink->num_protect = *p_num_protect; 647 memcpy(p_sink->protect_info, p_protect_info, BTA_AV_CP_INFO_LEN); 648 } 649 else 650 { 651 APPL_TRACE_ERROR("bta_av_co_audio_getconfig no more room for SNK info"); 652 } 653 } 654 655 /* If last SNK get capabilities or all supported codec capa retrieved */ 656 if ((p_peer->num_rx_snks == p_peer->num_snks) || 657 (p_peer->num_sup_snks == BTA_AV_CO_NUM_ELEMENTS(p_peer->snks))) 658 { 659 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig last sink reached"); 660 661 /* Protect access to bta_av_co_cb.codec_cfg */ 662 mutex_global_lock(); 663 664 /* Find a sink that matches the codec config */ 665 if (bta_av_co_audio_peer_supports_codec(p_peer, &index)) 666 { 667 /* stop fetching caps once we retrieved a supported codec */ 668 if (p_peer->acp) 669 { 670 *p_sep_info_idx = p_peer->num_seps; 671 APPL_TRACE_EVENT("no need to fetch more SEPs"); 672 } 673 674 p_sink = &p_peer->snks[index]; 675 676 /* Build the codec configuration for this sink */ 677 if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg)) 678 { 679 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig reconfig p_codec_info[%x:%x:%x:%x:%x:%x]", 680 codec_cfg[1], codec_cfg[2], codec_cfg[3], 681 codec_cfg[4], codec_cfg[5], codec_cfg[6]); 682 683 /* Save the new configuration */ 684 p_peer->p_snk = p_sink; 685 memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE); 686 687 /* By default, no content protection */ 688 *p_num_protect = 0; 689 690 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 691 /* Check if this sink supports SCMS */ 692 if (bta_av_co_audio_sink_has_scmst(p_sink)) 693 { 694 p_peer->cp_active = TRUE; 695 bta_av_co_cb.cp.active = TRUE; 696 *p_num_protect = BTA_AV_CP_INFO_LEN; 697 memcpy(p_protect_info, bta_av_co_cp_scmst, BTA_AV_CP_INFO_LEN); 698 } 699 else 700 { 701 p_peer->cp_active = FALSE; 702 bta_av_co_cb.cp.active = FALSE; 703 } 704 #endif 705 706 /* If acceptor -> reconfig otherwise reply for configuration */ 707 if (p_peer->acp) 708 { 709 if (p_peer->recfg_needed) 710 { 711 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig call BTA_AvReconfig(x%x)", hndl); 712 BTA_AvReconfig(hndl, TRUE, p_sink->sep_info_idx, p_peer->codec_cfg, *p_num_protect, (UINT8 *)bta_av_co_cp_scmst); 713 } 714 } 715 else 716 { 717 *p_sep_info_idx = p_sink->sep_info_idx; 718 memcpy(p_codec_info, p_peer->codec_cfg, AVDT_CODEC_SIZE); 719 } 720 result = A2D_SUCCESS; 721 } 722 } 723 /* Protect access to bta_av_co_cb.codec_cfg */ 724 mutex_global_unlock(); 725 } 726 return result; 727 } 728 729 /******************************************************************************* 730 ** 731 ** Function bta_av_co_audio_setconfig 732 ** 733 ** Description This callout function is executed by AV to set the codec and 734 ** content protection configuration of the audio stream. 735 ** 736 ** 737 ** Returns void 738 ** 739 *******************************************************************************/ 740 void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 741 UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, UINT8 num_protect, UINT8 *p_protect_info, 742 UINT8 t_local_sep, UINT8 avdt_handle) 743 { 744 tBTA_AV_CO_PEER *p_peer; 745 UINT8 status = A2D_SUCCESS; 746 UINT8 category = A2D_SUCCESS; 747 BOOLEAN recfg_needed = FALSE; 748 BOOLEAN codec_cfg_supported = FALSE; 749 UNUSED(seid); 750 UNUSED(addr); 751 752 FUNC_TRACE(); 753 754 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig p_codec_info[%x:%x:%x:%x:%x:%x]", 755 p_codec_info[1], p_codec_info[2], p_codec_info[3], 756 p_codec_info[4], p_codec_info[5], p_codec_info[6]); 757 APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 758 num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]); 759 760 /* Retrieve the peer info */ 761 p_peer = bta_av_co_get_peer(hndl); 762 if (p_peer == NULL) 763 { 764 APPL_TRACE_ERROR("bta_av_co_audio_setconfig could not find peer entry"); 765 766 /* Call call-in rejecting the configuration */ 767 bta_av_ci_setconfig(hndl, A2D_BUSY, AVDT_ASC_CODEC, 0, NULL, FALSE, avdt_handle); 768 return; 769 } 770 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)", 771 p_peer->opened, p_peer->num_snks, p_peer->num_rx_snks, p_peer->num_sup_snks); 772 773 /* Sanity check: should not be opened at this point */ 774 if (p_peer->opened) 775 { 776 APPL_TRACE_ERROR("bta_av_co_audio_setconfig peer already in use"); 777 } 778 779 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 780 if (num_protect != 0) 781 { 782 /* If CP is supported */ 783 if ((num_protect != 1) || 784 (bta_av_co_cp_is_scmst(p_protect_info) == FALSE)) 785 { 786 APPL_TRACE_ERROR("bta_av_co_audio_setconfig wrong CP configuration"); 787 status = A2D_BAD_CP_TYPE; 788 category = AVDT_ASC_PROTECT; 789 } 790 } 791 #else 792 /* Do not support content protection for the time being */ 793 if (num_protect != 0) 794 { 795 APPL_TRACE_ERROR("bta_av_co_audio_setconfig wrong CP configuration"); 796 status = A2D_BAD_CP_TYPE; 797 category = AVDT_ASC_PROTECT; 798 } 799 #endif 800 if (status == A2D_SUCCESS) 801 { 802 if(AVDT_TSEP_SNK == t_local_sep) 803 { 804 codec_cfg_supported = bta_av_co_audio_sink_supports_config(codec_type, p_codec_info); 805 APPL_TRACE_DEBUG(" Peer is A2DP SRC "); 806 } 807 if(AVDT_TSEP_SRC == t_local_sep) 808 { 809 codec_cfg_supported = bta_av_co_audio_media_supports_config(codec_type, p_codec_info); 810 APPL_TRACE_DEBUG(" Peer is A2DP SINK "); 811 } 812 /* Check if codec configuration is supported */ 813 if (codec_cfg_supported) 814 { 815 816 /* Protect access to bta_av_co_cb.codec_cfg */ 817 mutex_global_lock(); 818 819 /* Check if the configuration matches the current codec config */ 820 switch (bta_av_co_cb.codec_cfg.id) 821 { 822 case BTIF_AV_CODEC_SBC: 823 if ((codec_type != BTA_AV_CODEC_SBC) || memcmp(p_codec_info, bta_av_co_cb.codec_cfg.info, 5)) 824 { 825 recfg_needed = TRUE; 826 } 827 else if ((num_protect == 1) && (!bta_av_co_cb.cp.active)) 828 { 829 recfg_needed = TRUE; 830 } 831 832 /* if remote side requests a restricted notify sinks preferred bitpool range as all other params are 833 already checked for validify */ 834 APPL_TRACE_EVENT("remote peer setconfig bitpool range [%d:%d]", 835 p_codec_info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 836 p_codec_info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] ); 837 838 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_SBC; 839 memcpy(bta_av_co_cb.codec_cfg_setconfig.info, p_codec_info, AVDT_CODEC_SIZE); 840 if(AVDT_TSEP_SNK == t_local_sep) 841 { 842 /* If Peer is SRC, and our cfg subset matches with what is requested by peer, then 843 just accept what peer wants */ 844 memcpy(bta_av_co_cb.codec_cfg.info, p_codec_info, AVDT_CODEC_SIZE); 845 recfg_needed = FALSE; 846 } 847 break; 848 849 850 default: 851 APPL_TRACE_ERROR("bta_av_co_audio_setconfig unsupported cid %d", bta_av_co_cb.codec_cfg.id); 852 recfg_needed = TRUE; 853 break; 854 } 855 /* Protect access to bta_av_co_cb.codec_cfg */ 856 mutex_global_unlock(); 857 } 858 else 859 { 860 category = AVDT_ASC_CODEC; 861 status = A2D_WRONG_CODEC; 862 } 863 } 864 865 if (status != A2D_SUCCESS) 866 { 867 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig reject s=%d c=%d", status, category); 868 869 /* Call call-in rejecting the configuration */ 870 bta_av_ci_setconfig(hndl, status, category, 0, NULL, FALSE, avdt_handle); 871 } 872 else 873 { 874 /* Mark that this is an acceptor peer */ 875 p_peer->acp = TRUE; 876 p_peer->recfg_needed = recfg_needed; 877 878 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig accept reconf=%d", recfg_needed); 879 880 /* Call call-in accepting the configuration */ 881 bta_av_ci_setconfig(hndl, A2D_SUCCESS, A2D_SUCCESS, 0, NULL, recfg_needed, avdt_handle); 882 } 883 } 884 885 /******************************************************************************* 886 ** 887 ** Function bta_av_co_audio_open 888 ** 889 ** Description This function is called by AV when the audio stream connection 890 ** is opened. 891 ** 892 ** 893 ** Returns void 894 ** 895 *******************************************************************************/ 896 void bta_av_co_audio_open(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, 897 UINT16 mtu) 898 { 899 tBTA_AV_CO_PEER *p_peer; 900 UNUSED(p_codec_info); 901 902 FUNC_TRACE(); 903 904 APPL_TRACE_DEBUG("bta_av_co_audio_open mtu:%d codec_type:%d", mtu, codec_type); 905 906 /* Retrieve the peer info */ 907 p_peer = bta_av_co_get_peer(hndl); 908 if (p_peer == NULL) 909 { 910 APPL_TRACE_ERROR("bta_av_co_audio_setconfig could not find peer entry"); 911 } 912 else 913 { 914 p_peer->opened = TRUE; 915 p_peer->mtu = mtu; 916 } 917 } 918 919 /******************************************************************************* 920 ** 921 ** Function bta_av_co_audio_close 922 ** 923 ** Description This function is called by AV when the audio stream connection 924 ** is closed. 925 ** 926 ** 927 ** Returns void 928 ** 929 *******************************************************************************/ 930 void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu) 931 932 { 933 tBTA_AV_CO_PEER *p_peer; 934 UNUSED(codec_type); 935 UNUSED(mtu); 936 937 FUNC_TRACE(); 938 939 APPL_TRACE_DEBUG("bta_av_co_audio_close"); 940 941 /* Retrieve the peer info */ 942 p_peer = bta_av_co_get_peer(hndl); 943 if (p_peer) 944 { 945 /* Mark the peer closed and clean the peer info */ 946 memset(p_peer, 0, sizeof(*p_peer)); 947 } 948 else 949 { 950 APPL_TRACE_ERROR("bta_av_co_audio_close could not find peer entry"); 951 } 952 953 /* reset remote preference through setconfig */ 954 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE; 955 } 956 957 /******************************************************************************* 958 ** 959 ** Function bta_av_co_audio_start 960 ** 961 ** Description This function is called by AV when the audio streaming data 962 ** transfer is started. 963 ** 964 ** 965 ** Returns void 966 ** 967 *******************************************************************************/ 968 void bta_av_co_audio_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 969 UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr) 970 { 971 UNUSED(hndl); 972 UNUSED(codec_type); 973 UNUSED(p_codec_info); 974 UNUSED(p_no_rtp_hdr); 975 976 FUNC_TRACE(); 977 978 APPL_TRACE_DEBUG("bta_av_co_audio_start"); 979 980 } 981 982 /******************************************************************************* 983 ** 984 ** Function bta_av_co_audio_stop 985 ** 986 ** Description This function is called by AV when the audio streaming data 987 ** transfer is stopped. 988 ** 989 ** 990 ** Returns void 991 ** 992 *******************************************************************************/ 993 extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type) 994 { 995 UNUSED(hndl); 996 UNUSED(codec_type); 997 998 FUNC_TRACE(); 999 1000 APPL_TRACE_DEBUG("bta_av_co_audio_stop"); 1001 } 1002 1003 /******************************************************************************* 1004 ** 1005 ** Function bta_av_co_audio_src_data_path 1006 ** 1007 ** Description This function is called to manage data transfer from 1008 ** the audio codec to AVDTP. 1009 ** 1010 ** Returns Pointer to the GKI buffer to send, NULL if no buffer to send 1011 ** 1012 *******************************************************************************/ 1013 void * bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, UINT32 *p_len, 1014 UINT32 *p_timestamp) 1015 { 1016 BT_HDR *p_buf; 1017 UNUSED(p_len); 1018 1019 FUNC_TRACE(); 1020 1021 p_buf = btif_media_aa_readbuf(); 1022 if (p_buf != NULL) 1023 { 1024 switch (codec_type) 1025 { 1026 case BTA_AV_CODEC_SBC: 1027 /* In media packet SBC, the following information is available: 1028 * p_buf->layer_specific : number of SBC frames in the packet 1029 * p_buf->word[0] : timestamp 1030 */ 1031 /* Retrieve the timestamp information from the media packet */ 1032 *p_timestamp = *((UINT32 *) (p_buf + 1)); 1033 1034 /* Set up packet header */ 1035 bta_av_sbc_bld_hdr(p_buf, p_buf->layer_specific); 1036 break; 1037 1038 1039 default: 1040 APPL_TRACE_ERROR("bta_av_co_audio_src_data_path Unsupported codec type (%d)", codec_type); 1041 break; 1042 } 1043 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1044 { 1045 UINT8 *p; 1046 if (bta_av_co_cp_is_active()) 1047 { 1048 p_buf->len++; 1049 p_buf->offset--; 1050 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 1051 *p = bta_av_co_cp_get_flag(); 1052 } 1053 } 1054 #endif 1055 } 1056 return p_buf; 1057 } 1058 1059 /******************************************************************************* 1060 ** 1061 ** Function bta_av_co_audio_drop 1062 ** 1063 ** Description An Audio packet is dropped. . 1064 ** It's very likely that the connected headset with this handle 1065 ** is moved far away. The implementation may want to reduce 1066 ** the encoder bit rate setting to reduce the packet size. 1067 ** 1068 ** Returns void 1069 ** 1070 *******************************************************************************/ 1071 void bta_av_co_audio_drop(tBTA_AV_HNDL hndl) 1072 { 1073 FUNC_TRACE(); 1074 1075 APPL_TRACE_ERROR("bta_av_co_audio_drop dropped: x%x", hndl); 1076 } 1077 1078 /******************************************************************************* 1079 ** 1080 ** Function bta_av_co_audio_delay 1081 ** 1082 ** Description This function is called by AV when the audio stream connection 1083 ** needs to send the initial delay report to the connected SRC. 1084 ** 1085 ** 1086 ** Returns void 1087 ** 1088 *******************************************************************************/ 1089 void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay) 1090 { 1091 FUNC_TRACE(); 1092 1093 APPL_TRACE_ERROR("bta_av_co_audio_delay handle: x%x, delay:0x%x", hndl, delay); 1094 } 1095 1096 1097 1098 /******************************************************************************* 1099 ** 1100 ** Function bta_av_co_audio_codec_build_config 1101 ** 1102 ** Description Build the codec configuration 1103 ** 1104 ** Returns TRUE if the codec was built successfully, FALSE otherwise 1105 ** 1106 *******************************************************************************/ 1107 static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg) 1108 { 1109 FUNC_TRACE(); 1110 1111 memset(p_codec_cfg, 0, AVDT_CODEC_SIZE); 1112 1113 switch (bta_av_co_cb.codec_cfg.id) 1114 { 1115 case BTIF_AV_CODEC_SBC: 1116 /* only copy the relevant portions for this codec to avoid issues when 1117 comparing codec configs covering larger codec sets than SBC (7 bytes) */ 1118 memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg.info, BTA_AV_CO_SBC_MAX_BITPOOL_OFF+1); 1119 1120 /* Update the bit pool boundaries with the codec capabilities */ 1121 p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF]; 1122 p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]; 1123 1124 APPL_TRACE_EVENT("bta_av_co_audio_codec_build_config : bitpool min %d, max %d", 1125 p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1126 p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]); 1127 break; 1128 default: 1129 APPL_TRACE_ERROR("bta_av_co_audio_codec_build_config: unsupported codec id %d", bta_av_co_cb.codec_cfg.id); 1130 return FALSE; 1131 break; 1132 } 1133 return TRUE; 1134 } 1135 1136 /******************************************************************************* 1137 ** 1138 ** Function bta_av_co_audio_codec_cfg_matches_caps 1139 ** 1140 ** Description Check if a codec config matches a codec capabilities 1141 ** 1142 ** Returns TRUE if it codec config is supported, FALSE otherwise 1143 ** 1144 *******************************************************************************/ 1145 static BOOLEAN bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id, const UINT8 *p_codec_caps, const UINT8 *p_codec_cfg) 1146 { 1147 FUNC_TRACE(); 1148 1149 switch(codec_id) 1150 { 1151 case BTIF_AV_CODEC_SBC: 1152 1153 APPL_TRACE_EVENT("bta_av_co_audio_codec_cfg_matches_caps : min %d/%d max %d/%d", 1154 p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1155 p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1156 p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF], 1157 p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]); 1158 1159 /* Must match all items exactly except bitpool boundaries which can be adjusted */ 1160 if (!((p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF] & p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF]) && 1161 (p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF] & p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]))) 1162 { 1163 APPL_TRACE_EVENT("FALSE %x %x %x %x", 1164 p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF], 1165 p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF], 1166 p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF], 1167 p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]); 1168 return FALSE; 1169 } 1170 break; 1171 1172 1173 default: 1174 APPL_TRACE_ERROR("bta_av_co_audio_codec_cfg_matches_caps: unsupported codec id %d", codec_id); 1175 return FALSE; 1176 break; 1177 } 1178 APPL_TRACE_EVENT("TRUE"); 1179 1180 return TRUE; 1181 } 1182 1183 /******************************************************************************* 1184 ** 1185 ** Function bta_av_co_audio_codec_match 1186 ** 1187 ** Description Check if a codec capabilities supports the codec config 1188 ** 1189 ** Returns TRUE if the connection supports this codec, FALSE otherwise 1190 ** 1191 *******************************************************************************/ 1192 static BOOLEAN bta_av_co_audio_codec_match(const UINT8 *p_codec_caps) 1193 { 1194 FUNC_TRACE(); 1195 1196 return bta_av_co_audio_codec_cfg_matches_caps(bta_av_co_cb.codec_cfg.id, p_codec_caps, bta_av_co_cb.codec_cfg.info); 1197 } 1198 1199 /******************************************************************************* 1200 ** 1201 ** Function bta_av_co_audio_peer_reset_config 1202 ** 1203 ** Description Reset the peer codec configuration 1204 ** 1205 ** Returns Nothing 1206 ** 1207 *******************************************************************************/ 1208 static void bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER *p_peer) 1209 { 1210 FUNC_TRACE(); 1211 1212 /* Indicate that there is no currently selected sink */ 1213 p_peer->p_snk = NULL; 1214 } 1215 1216 /******************************************************************************* 1217 ** 1218 ** Function bta_av_co_cp_is_scmst 1219 ** 1220 ** Description Check if a content protection service is SCMS-T 1221 ** 1222 ** Returns TRUE if this CP is SCMS-T, FALSE otherwise 1223 ** 1224 *******************************************************************************/ 1225 static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo) 1226 { 1227 UINT16 cp_id; 1228 FUNC_TRACE(); 1229 1230 if (*p_protectinfo >= BTA_AV_CP_LOSC) 1231 { 1232 p_protectinfo++; 1233 STREAM_TO_UINT16(cp_id, p_protectinfo); 1234 if (cp_id == BTA_AV_CP_SCMS_T_ID) 1235 { 1236 APPL_TRACE_DEBUG("bta_av_co_cp_is_scmst: SCMS-T found"); 1237 return TRUE; 1238 } 1239 } 1240 1241 return FALSE; 1242 } 1243 1244 /******************************************************************************* 1245 ** 1246 ** Function bta_av_co_audio_sink_has_scmst 1247 ** 1248 ** Description Check if a sink supports SCMS-T 1249 ** 1250 ** Returns TRUE if the sink supports this CP, FALSE otherwise 1251 ** 1252 *******************************************************************************/ 1253 static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink) 1254 { 1255 UINT8 index; 1256 const UINT8 *p; 1257 FUNC_TRACE(); 1258 1259 /* Check if sink supports SCMS-T */ 1260 index = p_sink->num_protect; 1261 p = &p_sink->protect_info[0]; 1262 1263 while (index) 1264 { 1265 if (bta_av_co_cp_is_scmst(p)) 1266 { 1267 return TRUE; 1268 } 1269 /* Move to the next SC */ 1270 p += *p + 1; 1271 /* Decrement the SC counter */ 1272 index--; 1273 } 1274 APPL_TRACE_DEBUG("bta_av_co_audio_sink_has_scmst: SCMS-T not found"); 1275 return FALSE; 1276 } 1277 1278 /******************************************************************************* 1279 ** 1280 ** Function bta_av_co_audio_sink_supports_cp 1281 ** 1282 ** Description Check if a sink supports the current content protection 1283 ** 1284 ** Returns TRUE if the sink supports this CP, FALSE otherwise 1285 ** 1286 *******************************************************************************/ 1287 static BOOLEAN bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK *p_sink) 1288 { 1289 FUNC_TRACE(); 1290 1291 /* Check if content protection is enabled for this stream */ 1292 if (bta_av_co_cp_get_flag() != BTA_AV_CP_SCMS_COPY_FREE) 1293 { 1294 return bta_av_co_audio_sink_has_scmst(p_sink); 1295 } 1296 else 1297 { 1298 APPL_TRACE_DEBUG("bta_av_co_audio_sink_supports_cp: not required"); 1299 return TRUE; 1300 } 1301 } 1302 1303 /******************************************************************************* 1304 ** 1305 ** Function bta_av_co_audio_peer_supports_codec 1306 ** 1307 ** Description Check if a connection supports the codec config 1308 ** 1309 ** Returns TRUE if the connection supports this codec, FALSE otherwise 1310 ** 1311 *******************************************************************************/ 1312 static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index) 1313 { 1314 int index; 1315 UINT8 codec_type; 1316 FUNC_TRACE(); 1317 1318 /* Configure the codec type to look for */ 1319 codec_type = bta_av_co_cb.codec_cfg.id; 1320 1321 1322 for (index = 0; index < p_peer->num_sup_snks; index++) 1323 { 1324 if (p_peer->snks[index].codec_type == codec_type) 1325 { 1326 switch (bta_av_co_cb.codec_cfg.id) 1327 { 1328 case BTIF_AV_CODEC_SBC: 1329 if (p_snk_index) *p_snk_index = index; 1330 return bta_av_co_audio_codec_match(p_peer->snks[index].codec_caps); 1331 break; 1332 1333 1334 default: 1335 APPL_TRACE_ERROR("bta_av_co_audio_peer_supports_codec: unsupported codec id %d", bta_av_co_cb.codec_cfg.id); 1336 return FALSE; 1337 break; 1338 } 1339 } 1340 } 1341 return FALSE; 1342 } 1343 1344 /******************************************************************************* 1345 ** 1346 ** Function bta_av_co_audio_peer_src_supports_codec 1347 ** 1348 ** Description Check if a peer acting as src supports codec config 1349 ** 1350 ** Returns TRUE if the connection supports this codec, FALSE otherwise 1351 ** 1352 *******************************************************************************/ 1353 static BOOLEAN bta_av_co_audio_peer_src_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_src_index) 1354 { 1355 int index; 1356 UINT8 codec_type; 1357 FUNC_TRACE(); 1358 1359 /* Configure the codec type to look for */ 1360 codec_type = bta_av_co_cb.codec_cfg.id; 1361 1362 1363 for (index = 0; index < p_peer->num_sup_srcs; index++) 1364 { 1365 if (p_peer->srcs[index].codec_type == codec_type) 1366 { 1367 switch (bta_av_co_cb.codec_cfg.id) 1368 { 1369 case BTIF_AV_CODEC_SBC: 1370 if (p_src_index) *p_src_index = index; 1371 if (0 == bta_av_sbc_cfg_matches_cap((UINT8 *)p_peer->srcs[index].codec_caps, 1372 (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps)) 1373 { 1374 return TRUE; 1375 } 1376 break; 1377 1378 default: 1379 APPL_TRACE_ERROR("peer_src_supports_codec: unsupported codec id %d", 1380 bta_av_co_cb.codec_cfg.id); 1381 return FALSE; 1382 break; 1383 } 1384 } 1385 } 1386 return FALSE; 1387 } 1388 1389 /******************************************************************************* 1390 ** 1391 ** Function bta_av_co_audio_sink_supports_config 1392 ** 1393 ** Description Check if the media source supports a given configuration 1394 ** 1395 ** Returns TRUE if the media source supports this config, FALSE otherwise 1396 ** 1397 *******************************************************************************/ 1398 static BOOLEAN bta_av_co_audio_sink_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg) 1399 { 1400 FUNC_TRACE(); 1401 1402 switch (codec_type) 1403 { 1404 case BTA_AV_CODEC_SBC: 1405 if (bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps)) 1406 { 1407 return FALSE; 1408 } 1409 break; 1410 1411 1412 default: 1413 APPL_TRACE_ERROR("bta_av_co_audio_media_supports_config unsupported codec type %d", codec_type); 1414 return FALSE; 1415 break; 1416 } 1417 return TRUE; 1418 } 1419 1420 /******************************************************************************* 1421 ** 1422 ** Function bta_av_co_audio_media_supports_config 1423 ** 1424 ** Description Check if the media sink supports a given configuration 1425 ** 1426 ** Returns TRUE if the media source supports this config, FALSE otherwise 1427 ** 1428 *******************************************************************************/ 1429 static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg) 1430 { 1431 FUNC_TRACE(); 1432 1433 switch (codec_type) 1434 { 1435 case BTA_AV_CODEC_SBC: 1436 if (bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_caps)) 1437 { 1438 return FALSE; 1439 } 1440 break; 1441 1442 1443 default: 1444 APPL_TRACE_ERROR("bta_av_co_audio_media_supports_config unsupported codec type %d", codec_type); 1445 return FALSE; 1446 break; 1447 } 1448 return TRUE; 1449 } 1450 1451 /******************************************************************************* 1452 ** 1453 ** Function bta_av_co_audio_codec_supported 1454 ** 1455 ** Description Check if all opened connections are compatible with a codec 1456 ** configuration and content protection 1457 ** 1458 ** Returns TRUE if all opened devices support this codec, FALSE otherwise 1459 ** 1460 *******************************************************************************/ 1461 BOOLEAN bta_av_co_audio_codec_supported(tBTIF_STATUS *p_status) 1462 { 1463 UINT8 index; 1464 UINT8 snk_index; 1465 tBTA_AV_CO_PEER *p_peer; 1466 tBTA_AV_CO_SINK *p_sink; 1467 UINT8 codec_cfg[AVDT_CODEC_SIZE]; 1468 UINT8 num_protect = 0; 1469 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1470 BOOLEAN cp_active; 1471 #endif 1472 1473 FUNC_TRACE(); 1474 1475 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported"); 1476 1477 /* Check AV feeding is supported */ 1478 *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED; 1479 1480 for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++) 1481 { 1482 p_peer = &bta_av_co_cb.peers[index]; 1483 if (p_peer->opened) 1484 { 1485 if (bta_av_co_audio_peer_supports_codec(p_peer, &snk_index)) 1486 { 1487 p_sink = &p_peer->snks[snk_index]; 1488 1489 /* Check that this sink is compatible with the CP */ 1490 if (!bta_av_co_audio_sink_supports_cp(p_sink)) 1491 { 1492 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported sink %d of peer %d doesn't support cp", 1493 snk_index, index); 1494 *p_status = BTIF_ERROR_SRV_AV_CP_NOT_SUPPORTED; 1495 return FALSE; 1496 } 1497 1498 /* Build the codec configuration for this sink */ 1499 if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg)) 1500 { 1501 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1502 /* Check if this sink supports SCMS */ 1503 cp_active = bta_av_co_audio_sink_has_scmst(p_sink); 1504 #endif 1505 /* Check if this is a new configuration (new sink or new config) */ 1506 if ((p_sink != p_peer->p_snk) || 1507 (memcmp(codec_cfg, p_peer->codec_cfg, AVDT_CODEC_SIZE)) 1508 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1509 || (p_peer->cp_active != cp_active) 1510 #endif 1511 ) 1512 { 1513 /* Save the new configuration */ 1514 p_peer->p_snk = p_sink; 1515 memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE); 1516 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1517 p_peer->cp_active = cp_active; 1518 if (p_peer->cp_active) 1519 { 1520 bta_av_co_cb.cp.active = TRUE; 1521 num_protect = BTA_AV_CP_INFO_LEN; 1522 } 1523 else 1524 { 1525 bta_av_co_cb.cp.active = FALSE; 1526 } 1527 #endif 1528 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported call BTA_AvReconfig(x%x)", BTA_AV_CO_AUDIO_INDX_TO_HNDL(index)); 1529 BTA_AvReconfig(BTA_AV_CO_AUDIO_INDX_TO_HNDL(index), TRUE, p_sink->sep_info_idx, 1530 p_peer->codec_cfg, num_protect, (UINT8 *)bta_av_co_cp_scmst); 1531 } 1532 } 1533 } 1534 else 1535 { 1536 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported index %d doesn't support codec", index); 1537 return FALSE; 1538 } 1539 } 1540 } 1541 1542 *p_status = BTIF_SUCCESS; 1543 return TRUE; 1544 } 1545 1546 /******************************************************************************* 1547 ** 1548 ** Function bta_av_co_audio_codec_reset 1549 ** 1550 ** Description Reset the current codec configuration 1551 ** 1552 ** Returns void 1553 ** 1554 *******************************************************************************/ 1555 void bta_av_co_audio_codec_reset(void) 1556 { 1557 mutex_global_lock(); 1558 FUNC_TRACE(); 1559 1560 /* Reset the current configuration to SBC */ 1561 bta_av_co_cb.codec_cfg.id = BTIF_AV_CODEC_SBC; 1562 1563 if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_SBC_CIE *)&btif_av_sbc_default_config, bta_av_co_cb.codec_cfg.info) != A2D_SUCCESS) 1564 { 1565 APPL_TRACE_ERROR("bta_av_co_audio_codec_reset A2D_BldSbcInfo failed"); 1566 } 1567 1568 mutex_global_unlock(); 1569 } 1570 1571 /******************************************************************************* 1572 ** 1573 ** Function bta_av_co_audio_set_codec 1574 ** 1575 ** Description Set the current codec configuration from the feeding type. 1576 ** This function is starting to modify the configuration, it 1577 ** should be protected. 1578 ** 1579 ** Returns TRUE if successful, FALSE otherwise 1580 ** 1581 *******************************************************************************/ 1582 BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTIF_STATUS *p_status) 1583 { 1584 tA2D_SBC_CIE sbc_config; 1585 tBTIF_AV_CODEC_INFO new_cfg; 1586 1587 FUNC_TRACE(); 1588 1589 /* Check AV feeding is supported */ 1590 *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED; 1591 1592 APPL_TRACE_DEBUG("bta_av_co_audio_set_codec cid=%d", p_feeding->format); 1593 1594 /* Supported codecs */ 1595 switch (p_feeding->format) 1596 { 1597 case BTIF_AV_CODEC_PCM: 1598 new_cfg.id = BTIF_AV_CODEC_SBC; 1599 1600 sbc_config = btif_av_sbc_default_config; 1601 if ((p_feeding->cfg.pcm.num_channel != 1) && 1602 (p_feeding->cfg.pcm.num_channel != 2)) 1603 { 1604 APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM channel number unsupported"); 1605 return FALSE; 1606 } 1607 if ((p_feeding->cfg.pcm.bit_per_sample != 8) && 1608 (p_feeding->cfg.pcm.bit_per_sample != 16)) 1609 { 1610 APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM sample size unsupported"); 1611 return FALSE; 1612 } 1613 switch (p_feeding->cfg.pcm.sampling_freq) 1614 { 1615 case 8000: 1616 case 12000: 1617 case 16000: 1618 case 24000: 1619 case 32000: 1620 case 48000: 1621 sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_48; 1622 break; 1623 1624 case 11025: 1625 case 22050: 1626 case 44100: 1627 sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_44; 1628 break; 1629 default: 1630 APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM sampling frequency unsupported"); 1631 return FALSE; 1632 break; 1633 } 1634 /* Build the codec config */ 1635 if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, &sbc_config, new_cfg.info) != A2D_SUCCESS) 1636 { 1637 APPL_TRACE_ERROR("bta_av_co_audio_set_codec A2D_BldSbcInfo failed"); 1638 return FALSE; 1639 } 1640 break; 1641 1642 1643 default: 1644 APPL_TRACE_ERROR("bta_av_co_audio_set_codec Feeding format unsupported"); 1645 return FALSE; 1646 break; 1647 } 1648 1649 /* The new config was correctly built */ 1650 bta_av_co_cb.codec_cfg = new_cfg; 1651 1652 1653 /* Check all devices support it */ 1654 *p_status = BTIF_SUCCESS; 1655 return bta_av_co_audio_codec_supported(p_status); 1656 } 1657 1658 /******************************************************************************* 1659 ** 1660 ** Function bta_av_co_audio_get_sbc_config 1661 ** 1662 ** Description Retrieves the SBC codec configuration. If the codec in use 1663 ** is not SBC, return the default SBC codec configuration. 1664 ** 1665 ** Returns TRUE if codec is SBC, FALSE otherwise 1666 ** 1667 *******************************************************************************/ 1668 BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu) 1669 { 1670 BOOLEAN result = FALSE; 1671 UINT8 index, jndex; 1672 tBTA_AV_CO_PEER *p_peer; 1673 tBTA_AV_CO_SINK *p_sink; 1674 1675 APPL_TRACE_EVENT("bta_av_co_cb.codec_cfg.id : codec 0x%x", bta_av_co_cb.codec_cfg.id); 1676 1677 /* Minimum MTU is by default very large */ 1678 *p_minmtu = 0xFFFF; 1679 1680 mutex_global_lock(); 1681 if (bta_av_co_cb.codec_cfg.id == BTIF_AV_CODEC_SBC) 1682 { 1683 if (A2D_ParsSbcInfo(p_sbc_config, bta_av_co_cb.codec_cfg.info, FALSE) == A2D_SUCCESS) 1684 { 1685 for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++) 1686 { 1687 p_peer = &bta_av_co_cb.peers[index]; 1688 if (p_peer->opened) 1689 { 1690 if (p_peer->mtu < *p_minmtu) 1691 { 1692 *p_minmtu = p_peer->mtu; 1693 } 1694 for (jndex = 0; jndex < p_peer->num_sup_snks; jndex++) 1695 { 1696 p_sink = &p_peer->snks[jndex]; 1697 if (p_sink->codec_type == A2D_MEDIA_CT_SBC) 1698 { 1699 /* Update the bitpool boundaries of the current config */ 1700 p_sbc_config->min_bitpool = 1701 BTA_AV_CO_MAX(p_sink->codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1702 p_sbc_config->min_bitpool); 1703 p_sbc_config->max_bitpool = 1704 BTA_AV_CO_MIN(p_sink->codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF], 1705 p_sbc_config->max_bitpool); 1706 APPL_TRACE_EVENT("bta_av_co_audio_get_sbc_config : sink bitpool min %d, max %d", 1707 p_sbc_config->min_bitpool, p_sbc_config->max_bitpool); 1708 break; 1709 } 1710 } 1711 } 1712 } 1713 result = TRUE; 1714 } 1715 } 1716 1717 if (!result) 1718 { 1719 /* Not SBC, still return the default values */ 1720 *p_sbc_config = btif_av_sbc_default_config; 1721 } 1722 mutex_global_unlock(); 1723 1724 return result; 1725 } 1726 1727 /******************************************************************************* 1728 ** 1729 ** Function bta_av_co_audio_discard_config 1730 ** 1731 ** Description Discard the codec configuration of a connection 1732 ** 1733 ** Returns Nothing 1734 ** 1735 *******************************************************************************/ 1736 void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl) 1737 { 1738 tBTA_AV_CO_PEER *p_peer; 1739 1740 FUNC_TRACE(); 1741 1742 /* Find the peer info */ 1743 p_peer = bta_av_co_get_peer(hndl); 1744 if (p_peer == NULL) 1745 { 1746 APPL_TRACE_ERROR("bta_av_co_audio_discard_config could not find peer entry"); 1747 return; 1748 } 1749 1750 /* Reset the peer codec configuration */ 1751 bta_av_co_audio_peer_reset_config(p_peer); 1752 } 1753 1754 /******************************************************************************* 1755 ** 1756 ** Function bta_av_co_init 1757 ** 1758 ** Description Initialization 1759 ** 1760 ** Returns Nothing 1761 ** 1762 *******************************************************************************/ 1763 void bta_av_co_init(void) 1764 { 1765 FUNC_TRACE(); 1766 1767 /* Reset the control block */ 1768 memset(&bta_av_co_cb, 0, sizeof(bta_av_co_cb)); 1769 1770 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE; 1771 1772 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1773 bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_NEVER); 1774 #else 1775 bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_FREE); 1776 #endif 1777 1778 /* Reset the current config */ 1779 bta_av_co_audio_codec_reset(); 1780 } 1781 1782 1783 /******************************************************************************* 1784 ** 1785 ** Function bta_av_co_peer_cp_supported 1786 ** 1787 ** Description Checks if the peer supports CP 1788 ** 1789 ** Returns TRUE if the peer supports CP 1790 ** 1791 *******************************************************************************/ 1792 BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl) 1793 { 1794 tBTA_AV_CO_PEER *p_peer; 1795 tBTA_AV_CO_SINK *p_sink; 1796 UINT8 index; 1797 1798 FUNC_TRACE(); 1799 1800 /* Find the peer info */ 1801 p_peer = bta_av_co_get_peer(hndl); 1802 if (p_peer == NULL) 1803 { 1804 APPL_TRACE_ERROR("bta_av_co_peer_cp_supported could not find peer entry"); 1805 return FALSE; 1806 } 1807 1808 for (index = 0; index < p_peer->num_sup_snks; index++) 1809 { 1810 p_sink = &p_peer->snks[index]; 1811 if (p_sink->codec_type == A2D_MEDIA_CT_SBC) 1812 { 1813 return bta_av_co_audio_sink_has_scmst(p_sink); 1814 } 1815 } 1816 APPL_TRACE_ERROR("bta_av_co_peer_cp_supported did not find SBC sink"); 1817 return FALSE; 1818 } 1819 1820 1821 /******************************************************************************* 1822 ** 1823 ** Function bta_av_co_get_remote_bitpool_pref 1824 ** 1825 ** Description Check if remote side did a setconfig within the limits 1826 ** of our exported bitpool range. If set we will set the 1827 ** remote preference. 1828 ** 1829 ** Returns TRUE if config set, FALSE otherwize 1830 ** 1831 *******************************************************************************/ 1832 1833 BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max) 1834 { 1835 /* check if remote peer did a set config */ 1836 if (bta_av_co_cb.codec_cfg_setconfig.id == BTIF_AV_CODEC_NONE) 1837 return FALSE; 1838 1839 *min = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF]; 1840 *max = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]; 1841 1842 return TRUE; 1843 } 1844