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