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 */ 68 const UINT8 bta_av_co_cp_scmst[BTA_AV_CP_INFO_LEN] = "\x02\x02\x00"; 69 70 /* SBC SRC codec capabilities */ 71 const 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 */ 83 const 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 */ 99 const 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 *****************************************************************************/ 114 typedef 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 124 typedef 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 147 typedef struct 148 { 149 BOOLEAN active; 150 UINT8 flag; 151 } tBTA_AV_CO_CP; 152 153 typedef 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 */ 165 static tBTA_AV_CO_CB bta_av_co_cb; 166 167 static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg); 168 static void bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER *p_peer); 169 static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo); 170 static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink); 171 static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index); 172 static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg); 173 static BOOLEAN bta_av_co_audio_sink_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg); 174 static 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 *******************************************************************************/ 187 BOOLEAN 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 *******************************************************************************/ 205 UINT8 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 *******************************************************************************/ 223 BOOLEAN 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 *******************************************************************************/ 247 static 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 *******************************************************************************/ 277 BOOLEAN 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 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 285 { 286 UINT8 *p = p_protect_info; 287 288 /* Content protection info - support SCMS-T */ 289 *p_num_protect = 1; 290 *p++ = BTA_AV_CP_LOSC; 291 UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID); 292 293 } 294 #else 295 /* By default - no content protection info */ 296 *p_num_protect = 0; 297 *p_protect_info = 0; 298 #endif 299 300 /* reset remote preference through setconfig */ 301 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE; 302 303 switch (index) 304 { 305 case BTIF_SV_AV_AA_SBC_INDEX: 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 BTA_API 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 codec_cfg[AVDT_CODEC_SIZE]; 467 UINT8 pref_cfg[AVDT_CODEC_SIZE]; 468 UINT8 index; 469 470 FUNC_TRACE(); 471 472 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig handle:0x%x codec_type:%d seid:%d", 473 hndl, codec_type, seid); 474 APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 475 *p_num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]); 476 477 /* Retrieve the peer info */ 478 p_peer = bta_av_co_get_peer(hndl); 479 if (p_peer == NULL) 480 { 481 APPL_TRACE_ERROR("bta_av_audio_sink_getconfig could not find peer entry"); 482 return A2D_FAIL; 483 } 484 485 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)", 486 p_peer->opened, p_peer->num_srcs, p_peer->num_rx_srcs, p_peer->num_sup_srcs); 487 488 p_peer->num_rx_srcs++; 489 490 /* Check if this is a supported configuration */ 491 supported = FALSE; 492 switch (codec_type) 493 { 494 case BTA_AV_CODEC_SBC: 495 supported = TRUE; 496 break; 497 498 default: 499 break; 500 } 501 502 if (supported) 503 { 504 /* If there is room for a new one */ 505 if (p_peer->num_sup_srcs < BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs)) 506 { 507 p_src = &p_peer->srcs[p_peer->num_sup_srcs++]; 508 509 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig saved caps[%x:%x:%x:%x:%x:%x]", 510 p_codec_info[1], p_codec_info[2], p_codec_info[3], 511 p_codec_info[4], p_codec_info[5], p_codec_info[6]); 512 513 memcpy(p_src->codec_caps, p_codec_info, AVDT_CODEC_SIZE); 514 p_src->codec_type = codec_type; 515 p_src->sep_info_idx = *p_sep_info_idx; 516 p_src->seid = seid; 517 p_src->num_protect = *p_num_protect; 518 memcpy(p_src->protect_info, p_protect_info, BTA_AV_CP_INFO_LEN); 519 } 520 else 521 { 522 APPL_TRACE_ERROR("bta_av_audio_sink_getconfig no more room for SRC info"); 523 } 524 } 525 526 /* If last SNK get capabilities or all supported codec caps retrieved */ 527 if ((p_peer->num_rx_srcs == p_peer->num_srcs) || 528 (p_peer->num_sup_srcs == BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs))) 529 { 530 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig last SRC reached"); 531 532 /* Protect access to bta_av_co_cb.codec_cfg */ 533 GKI_disable(); 534 535 /* Find a src that matches the codec config */ 536 if (bta_av_co_audio_peer_src_supports_codec(p_peer, &index)) 537 { 538 APPL_TRACE_DEBUG(" Codec Supported "); 539 p_src = &p_peer->srcs[index]; 540 541 /* Build the codec configuration for this sink */ 542 { 543 /* Save the new configuration */ 544 p_peer->p_src = p_src; 545 /* get preferred config from src_caps */ 546 bta_av_build_src_cfg(pref_cfg, p_src->codec_caps); 547 memcpy(p_peer->codec_cfg, pref_cfg, AVDT_CODEC_SIZE); 548 549 APPL_TRACE_DEBUG("bta_av_audio_sink_getconfig p_codec_info[%x:%x:%x:%x:%x:%x]", 550 p_peer->codec_cfg[1], p_peer->codec_cfg[2], p_peer->codec_cfg[3], 551 p_peer->codec_cfg[4], p_peer->codec_cfg[5], p_peer->codec_cfg[6]); 552 /* By default, no content protection */ 553 *p_num_protect = 0; 554 555 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 556 /* Check if this sink supports SCMS */ 557 if (bta_av_co_audio_sink_has_scmst(p_sink)) 558 { 559 p_peer->cp_active = TRUE; 560 bta_av_co_cb.cp.active = TRUE; 561 *p_num_protect = BTA_AV_CP_INFO_LEN; 562 memcpy(p_protect_info, bta_av_co_cp_scmst, BTA_AV_CP_INFO_LEN); 563 } 564 else 565 { 566 p_peer->cp_active = FALSE; 567 bta_av_co_cb.cp.active = FALSE; 568 } 569 #endif 570 571 *p_sep_info_idx = p_src->sep_info_idx; 572 memcpy(p_codec_info, p_peer->codec_cfg, AVDT_CODEC_SIZE); 573 result = A2D_SUCCESS; 574 } 575 } 576 /* Protect access to bta_av_co_cb.codec_cfg */ 577 GKI_enable(); 578 } 579 return result; 580 } 581 /******************************************************************************* 582 ** 583 ** Function bta_av_co_audio_getconfig 584 ** 585 ** Description This callout function is executed by AV to retrieve the 586 ** desired codec and content protection configuration for the 587 ** audio stream. 588 ** 589 ** 590 ** Returns Stream codec and content protection configuration info. 591 ** 592 *******************************************************************************/ 593 BTA_API UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 594 UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, UINT8 *p_num_protect, 595 UINT8 *p_protect_info) 596 597 { 598 UINT8 result = A2D_FAIL; 599 BOOLEAN supported; 600 tBTA_AV_CO_PEER *p_peer; 601 tBTA_AV_CO_SINK *p_sink; 602 UINT8 codec_cfg[AVDT_CODEC_SIZE]; 603 UINT8 index; 604 605 FUNC_TRACE(); 606 607 /* Retrieve the peer info */ 608 p_peer = bta_av_co_get_peer(hndl); 609 if (p_peer == NULL) 610 { 611 APPL_TRACE_ERROR("bta_av_co_audio_getconfig could not find peer entry"); 612 return A2D_FAIL; 613 } 614 615 if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) 616 { 617 result = bta_av_audio_sink_getconfig(hndl, codec_type, p_codec_info, p_sep_info_idx, 618 seid, p_num_protect, p_protect_info); 619 return result; 620 } 621 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig handle:0x%x codec_type:%d seid:%d", 622 hndl, codec_type, seid); 623 APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 624 *p_num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]); 625 626 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)", 627 p_peer->opened, p_peer->num_snks, p_peer->num_rx_snks, p_peer->num_sup_snks); 628 629 p_peer->num_rx_snks++; 630 631 /* Check if this is a supported configuration */ 632 supported = FALSE; 633 switch (codec_type) 634 { 635 case BTA_AV_CODEC_SBC: 636 supported = TRUE; 637 break; 638 639 default: 640 break; 641 } 642 643 if (supported) 644 { 645 /* If there is room for a new one */ 646 if (p_peer->num_sup_snks < BTA_AV_CO_NUM_ELEMENTS(p_peer->snks)) 647 { 648 p_sink = &p_peer->snks[p_peer->num_sup_snks++]; 649 650 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig saved caps[%x:%x:%x:%x:%x:%x]", 651 p_codec_info[1], p_codec_info[2], p_codec_info[3], 652 p_codec_info[4], p_codec_info[5], p_codec_info[6]); 653 654 memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE); 655 p_sink->codec_type = codec_type; 656 p_sink->sep_info_idx = *p_sep_info_idx; 657 p_sink->seid = seid; 658 p_sink->num_protect = *p_num_protect; 659 memcpy(p_sink->protect_info, p_protect_info, BTA_AV_CP_INFO_LEN); 660 } 661 else 662 { 663 APPL_TRACE_ERROR("bta_av_co_audio_getconfig no more room for SNK info"); 664 } 665 } 666 667 /* If last SNK get capabilities or all supported codec capa retrieved */ 668 if ((p_peer->num_rx_snks == p_peer->num_snks) || 669 (p_peer->num_sup_snks == BTA_AV_CO_NUM_ELEMENTS(p_peer->snks))) 670 { 671 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig last sink reached"); 672 673 /* Protect access to bta_av_co_cb.codec_cfg */ 674 GKI_disable(); 675 676 /* Find a sink that matches the codec config */ 677 if (bta_av_co_audio_peer_supports_codec(p_peer, &index)) 678 { 679 /* stop fetching caps once we retrieved a supported codec */ 680 if (p_peer->acp) 681 { 682 *p_sep_info_idx = p_peer->num_seps; 683 APPL_TRACE_EVENT("no need to fetch more SEPs"); 684 } 685 686 p_sink = &p_peer->snks[index]; 687 688 /* Build the codec configuration for this sink */ 689 if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg)) 690 { 691 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig reconfig p_codec_info[%x:%x:%x:%x:%x:%x]", 692 codec_cfg[1], codec_cfg[2], codec_cfg[3], 693 codec_cfg[4], codec_cfg[5], codec_cfg[6]); 694 695 /* Save the new configuration */ 696 p_peer->p_snk = p_sink; 697 memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE); 698 699 /* By default, no content protection */ 700 *p_num_protect = 0; 701 702 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 703 /* Check if this sink supports SCMS */ 704 if (bta_av_co_audio_sink_has_scmst(p_sink)) 705 { 706 p_peer->cp_active = TRUE; 707 bta_av_co_cb.cp.active = TRUE; 708 *p_num_protect = BTA_AV_CP_INFO_LEN; 709 memcpy(p_protect_info, bta_av_co_cp_scmst, BTA_AV_CP_INFO_LEN); 710 } 711 else 712 { 713 p_peer->cp_active = FALSE; 714 bta_av_co_cb.cp.active = FALSE; 715 } 716 #endif 717 718 /* If acceptor -> reconfig otherwise reply for configuration */ 719 if (p_peer->acp) 720 { 721 if (p_peer->recfg_needed) 722 { 723 APPL_TRACE_DEBUG("bta_av_co_audio_getconfig call BTA_AvReconfig(x%x)", hndl); 724 BTA_AvReconfig(hndl, TRUE, p_sink->sep_info_idx, p_peer->codec_cfg, *p_num_protect, (UINT8 *)bta_av_co_cp_scmst); 725 } 726 } 727 else 728 { 729 *p_sep_info_idx = p_sink->sep_info_idx; 730 memcpy(p_codec_info, p_peer->codec_cfg, AVDT_CODEC_SIZE); 731 } 732 result = A2D_SUCCESS; 733 } 734 } 735 /* Protect access to bta_av_co_cb.codec_cfg */ 736 GKI_enable(); 737 } 738 return result; 739 } 740 741 /******************************************************************************* 742 ** 743 ** Function bta_av_co_audio_setconfig 744 ** 745 ** Description This callout function is executed by AV to set the codec and 746 ** content protection configuration of the audio stream. 747 ** 748 ** 749 ** Returns void 750 ** 751 *******************************************************************************/ 752 BTA_API void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 753 UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, UINT8 num_protect, UINT8 *p_protect_info, 754 UINT8 t_local_sep, UINT8 avdt_handle) 755 756 { 757 tBTA_AV_CO_PEER *p_peer; 758 UINT8 status = A2D_SUCCESS; 759 UINT8 category = A2D_SUCCESS; 760 BOOLEAN recfg_needed = FALSE; 761 BOOLEAN codec_cfg_supported = FALSE; 762 UNUSED(seid); 763 UNUSED(addr); 764 765 FUNC_TRACE(); 766 767 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig p_codec_info[%x:%x:%x:%x:%x:%x]", 768 p_codec_info[1], p_codec_info[2], p_codec_info[3], 769 p_codec_info[4], p_codec_info[5], p_codec_info[6]); 770 APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 771 num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]); 772 773 /* Retrieve the peer info */ 774 p_peer = bta_av_co_get_peer(hndl); 775 if (p_peer == NULL) 776 { 777 APPL_TRACE_ERROR("bta_av_co_audio_setconfig could not find peer entry"); 778 779 /* Call call-in rejecting the configuration */ 780 bta_av_ci_setconfig(hndl, A2D_BUSY, AVDT_ASC_CODEC, 0, NULL, FALSE, avdt_handle); 781 return; 782 } 783 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)", 784 p_peer->opened, p_peer->num_snks, p_peer->num_rx_snks, p_peer->num_sup_snks); 785 786 /* Sanity check: should not be opened at this point */ 787 if (p_peer->opened) 788 { 789 APPL_TRACE_ERROR("bta_av_co_audio_setconfig peer already in use"); 790 } 791 792 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 793 if (num_protect != 0) 794 { 795 /* If CP is supported */ 796 if ((num_protect != 1) || 797 (bta_av_co_cp_is_scmst(p_protect_info) == FALSE)) 798 { 799 APPL_TRACE_ERROR("bta_av_co_audio_setconfig wrong CP configuration"); 800 status = A2D_BAD_CP_TYPE; 801 category = AVDT_ASC_PROTECT; 802 } 803 } 804 #else 805 /* Do not support content protection for the time being */ 806 if (num_protect != 0) 807 { 808 APPL_TRACE_ERROR("bta_av_co_audio_setconfig wrong CP configuration"); 809 status = A2D_BAD_CP_TYPE; 810 category = AVDT_ASC_PROTECT; 811 } 812 #endif 813 if (status == A2D_SUCCESS) 814 { 815 if(AVDT_TSEP_SNK == t_local_sep) 816 { 817 codec_cfg_supported = bta_av_co_audio_sink_supports_config(codec_type, p_codec_info); 818 APPL_TRACE_DEBUG(" Peer is A2DP SRC "); 819 } 820 if(AVDT_TSEP_SRC == t_local_sep) 821 { 822 codec_cfg_supported = bta_av_co_audio_media_supports_config(codec_type, p_codec_info); 823 APPL_TRACE_DEBUG(" Peer is A2DP SINK "); 824 } 825 /* Check if codec configuration is supported */ 826 if (codec_cfg_supported) 827 { 828 829 /* Protect access to bta_av_co_cb.codec_cfg */ 830 GKI_disable(); 831 832 /* Check if the configuration matches the current codec config */ 833 switch (bta_av_co_cb.codec_cfg.id) 834 { 835 case BTIF_AV_CODEC_SBC: 836 if ((codec_type != BTA_AV_CODEC_SBC) || memcmp(p_codec_info, bta_av_co_cb.codec_cfg.info, 5)) 837 { 838 recfg_needed = TRUE; 839 } 840 else if ((num_protect == 1) && (!bta_av_co_cb.cp.active)) 841 { 842 recfg_needed = TRUE; 843 } 844 845 /* if remote side requests a restricted notify sinks preferred bitpool range as all other params are 846 already checked for validify */ 847 APPL_TRACE_EVENT("remote peer setconfig bitpool range [%d:%d]", 848 p_codec_info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 849 p_codec_info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] ); 850 851 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_SBC; 852 memcpy(bta_av_co_cb.codec_cfg_setconfig.info, p_codec_info, AVDT_CODEC_SIZE); 853 if(AVDT_TSEP_SNK == t_local_sep) 854 { 855 /* If Peer is SRC, and our cfg subset matches with what is requested by peer, then 856 just accept what peer wants */ 857 memcpy(bta_av_co_cb.codec_cfg.info, p_codec_info, AVDT_CODEC_SIZE); 858 recfg_needed = FALSE; 859 } 860 break; 861 862 863 default: 864 APPL_TRACE_ERROR("bta_av_co_audio_setconfig unsupported cid %d", bta_av_co_cb.codec_cfg.id); 865 recfg_needed = TRUE; 866 break; 867 } 868 /* Protect access to bta_av_co_cb.codec_cfg */ 869 GKI_enable(); 870 } 871 else 872 { 873 category = AVDT_ASC_CODEC; 874 status = A2D_WRONG_CODEC; 875 } 876 } 877 878 if (status != A2D_SUCCESS) 879 { 880 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig reject s=%d c=%d", status, category); 881 882 /* Call call-in rejecting the configuration */ 883 bta_av_ci_setconfig(hndl, status, category, 0, NULL, FALSE, avdt_handle); 884 } 885 else 886 { 887 /* Mark that this is an acceptor peer */ 888 p_peer->acp = TRUE; 889 p_peer->recfg_needed = recfg_needed; 890 891 APPL_TRACE_DEBUG("bta_av_co_audio_setconfig accept reconf=%d", recfg_needed); 892 893 /* Call call-in accepting the configuration */ 894 bta_av_ci_setconfig(hndl, A2D_SUCCESS, A2D_SUCCESS, 0, NULL, recfg_needed, avdt_handle); 895 } 896 } 897 898 /******************************************************************************* 899 ** 900 ** Function bta_av_co_audio_open 901 ** 902 ** Description This function is called by AV when the audio stream connection 903 ** is opened. 904 ** 905 ** 906 ** Returns void 907 ** 908 *******************************************************************************/ 909 BTA_API void bta_av_co_audio_open(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, 910 UINT16 mtu) 911 { 912 tBTA_AV_CO_PEER *p_peer; 913 UNUSED(p_codec_info); 914 915 FUNC_TRACE(); 916 917 APPL_TRACE_DEBUG("bta_av_co_audio_open mtu:%d codec_type:%d", mtu, codec_type); 918 919 /* Retrieve the peer info */ 920 p_peer = bta_av_co_get_peer(hndl); 921 if (p_peer == NULL) 922 { 923 APPL_TRACE_ERROR("bta_av_co_audio_setconfig could not find peer entry"); 924 } 925 else 926 { 927 p_peer->opened = TRUE; 928 p_peer->mtu = mtu; 929 } 930 } 931 932 /******************************************************************************* 933 ** 934 ** Function bta_av_co_audio_close 935 ** 936 ** Description This function is called by AV when the audio stream connection 937 ** is closed. 938 ** 939 ** 940 ** Returns void 941 ** 942 *******************************************************************************/ 943 BTA_API void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu) 944 945 { 946 tBTA_AV_CO_PEER *p_peer; 947 UNUSED(codec_type); 948 UNUSED(mtu); 949 950 FUNC_TRACE(); 951 952 APPL_TRACE_DEBUG("bta_av_co_audio_close"); 953 954 /* Retrieve the peer info */ 955 p_peer = bta_av_co_get_peer(hndl); 956 if (p_peer) 957 { 958 /* Mark the peer closed and clean the peer info */ 959 memset(p_peer, 0, sizeof(*p_peer)); 960 } 961 else 962 { 963 APPL_TRACE_ERROR("bta_av_co_audio_close could not find peer entry"); 964 } 965 966 /* reset remote preference through setconfig */ 967 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE; 968 } 969 970 /******************************************************************************* 971 ** 972 ** Function bta_av_co_audio_start 973 ** 974 ** Description This function is called by AV when the audio streaming data 975 ** transfer is started. 976 ** 977 ** 978 ** Returns void 979 ** 980 *******************************************************************************/ 981 BTA_API void bta_av_co_audio_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, 982 UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr) 983 { 984 UNUSED(hndl); 985 UNUSED(codec_type); 986 UNUSED(p_codec_info); 987 UNUSED(p_no_rtp_hdr); 988 989 FUNC_TRACE(); 990 991 APPL_TRACE_DEBUG("bta_av_co_audio_start"); 992 993 } 994 995 /******************************************************************************* 996 ** 997 ** Function bta_av_co_audio_stop 998 ** 999 ** Description This function is called by AV when the audio streaming data 1000 ** transfer is stopped. 1001 ** 1002 ** 1003 ** Returns void 1004 ** 1005 *******************************************************************************/ 1006 BTA_API extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type) 1007 { 1008 UNUSED(hndl); 1009 UNUSED(codec_type); 1010 1011 FUNC_TRACE(); 1012 1013 APPL_TRACE_DEBUG("bta_av_co_audio_stop"); 1014 } 1015 1016 /******************************************************************************* 1017 ** 1018 ** Function bta_av_co_audio_src_data_path 1019 ** 1020 ** Description This function is called to manage data transfer from 1021 ** the audio codec to AVDTP. 1022 ** 1023 ** Returns Pointer to the GKI buffer to send, NULL if no buffer to send 1024 ** 1025 *******************************************************************************/ 1026 BTA_API void * bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, UINT32 *p_len, 1027 UINT32 *p_timestamp) 1028 { 1029 BT_HDR *p_buf; 1030 UNUSED(p_len); 1031 1032 FUNC_TRACE(); 1033 1034 p_buf = btif_media_aa_readbuf(); 1035 if (p_buf != NULL) 1036 { 1037 switch (codec_type) 1038 { 1039 case BTA_AV_CODEC_SBC: 1040 /* In media packet SBC, the following information is available: 1041 * p_buf->layer_specific : number of SBC frames in the packet 1042 * p_buf->word[0] : timestamp 1043 */ 1044 /* Retrieve the timestamp information from the media packet */ 1045 *p_timestamp = *((UINT32 *) (p_buf + 1)); 1046 1047 /* Set up packet header */ 1048 bta_av_sbc_bld_hdr(p_buf, p_buf->layer_specific); 1049 break; 1050 1051 1052 default: 1053 APPL_TRACE_ERROR("bta_av_co_audio_src_data_path Unsupported codec type (%d)", codec_type); 1054 break; 1055 } 1056 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1057 { 1058 UINT8 *p; 1059 if (bta_av_co_cp_is_active()) 1060 { 1061 p_buf->len++; 1062 p_buf->offset--; 1063 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 1064 *p = bta_av_co_cp_get_flag(); 1065 } 1066 } 1067 #endif 1068 } 1069 return p_buf; 1070 } 1071 1072 /******************************************************************************* 1073 ** 1074 ** Function bta_av_co_audio_drop 1075 ** 1076 ** Description An Audio packet is dropped. . 1077 ** It's very likely that the connected headset with this handle 1078 ** is moved far away. The implementation may want to reduce 1079 ** the encoder bit rate setting to reduce the packet size. 1080 ** 1081 ** Returns void 1082 ** 1083 *******************************************************************************/ 1084 void bta_av_co_audio_drop(tBTA_AV_HNDL hndl) 1085 { 1086 FUNC_TRACE(); 1087 1088 APPL_TRACE_ERROR("bta_av_co_audio_drop dropped: x%x", hndl); 1089 } 1090 1091 /******************************************************************************* 1092 ** 1093 ** Function bta_av_co_audio_delay 1094 ** 1095 ** Description This function is called by AV when the audio stream connection 1096 ** needs to send the initial delay report to the connected SRC. 1097 ** 1098 ** 1099 ** Returns void 1100 ** 1101 *******************************************************************************/ 1102 void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay) 1103 { 1104 FUNC_TRACE(); 1105 1106 APPL_TRACE_ERROR("bta_av_co_audio_delay handle: x%x, delay:0x%x", hndl, delay); 1107 } 1108 1109 1110 1111 /******************************************************************************* 1112 ** 1113 ** Function bta_av_co_audio_codec_build_config 1114 ** 1115 ** Description Build the codec configuration 1116 ** 1117 ** Returns TRUE if the codec was built successfully, FALSE otherwise 1118 ** 1119 *******************************************************************************/ 1120 static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg) 1121 { 1122 FUNC_TRACE(); 1123 1124 memset(p_codec_cfg, 0, AVDT_CODEC_SIZE); 1125 1126 switch (bta_av_co_cb.codec_cfg.id) 1127 { 1128 case BTIF_AV_CODEC_SBC: 1129 /* only copy the relevant portions for this codec to avoid issues when 1130 comparing codec configs covering larger codec sets than SBC (7 bytes) */ 1131 memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg.info, BTA_AV_CO_SBC_MAX_BITPOOL_OFF+1); 1132 1133 /* Update the bit pool boundaries with the codec capabilities */ 1134 p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF]; 1135 p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]; 1136 1137 APPL_TRACE_EVENT("bta_av_co_audio_codec_build_config : bitpool min %d, max %d", 1138 p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1139 p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]); 1140 break; 1141 default: 1142 APPL_TRACE_ERROR("bta_av_co_audio_codec_build_config: unsupported codec id %d", bta_av_co_cb.codec_cfg.id); 1143 return FALSE; 1144 break; 1145 } 1146 return TRUE; 1147 } 1148 1149 /******************************************************************************* 1150 ** 1151 ** Function bta_av_co_audio_codec_cfg_matches_caps 1152 ** 1153 ** Description Check if a codec config matches a codec capabilities 1154 ** 1155 ** Returns TRUE if it codec config is supported, FALSE otherwise 1156 ** 1157 *******************************************************************************/ 1158 static BOOLEAN bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id, const UINT8 *p_codec_caps, const UINT8 *p_codec_cfg) 1159 { 1160 FUNC_TRACE(); 1161 1162 switch(codec_id) 1163 { 1164 case BTIF_AV_CODEC_SBC: 1165 1166 APPL_TRACE_EVENT("bta_av_co_audio_codec_cfg_matches_caps : min %d/%d max %d/%d", 1167 p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1168 p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1169 p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF], 1170 p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]); 1171 1172 /* Must match all items exactly except bitpool boundaries which can be adjusted */ 1173 if (!((p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF] & p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF]) && 1174 (p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF] & p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]))) 1175 { 1176 APPL_TRACE_EVENT("FALSE %x %x %x %x", 1177 p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF], 1178 p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF], 1179 p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF], 1180 p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]); 1181 return FALSE; 1182 } 1183 break; 1184 1185 1186 default: 1187 APPL_TRACE_ERROR("bta_av_co_audio_codec_cfg_matches_caps: unsupported codec id %d", codec_id); 1188 return FALSE; 1189 break; 1190 } 1191 APPL_TRACE_EVENT("TRUE"); 1192 1193 return TRUE; 1194 } 1195 1196 /******************************************************************************* 1197 ** 1198 ** Function bta_av_co_audio_codec_match 1199 ** 1200 ** Description Check if a codec capabilities supports the codec config 1201 ** 1202 ** Returns TRUE if the connection supports this codec, FALSE otherwise 1203 ** 1204 *******************************************************************************/ 1205 static BOOLEAN bta_av_co_audio_codec_match(const UINT8 *p_codec_caps) 1206 { 1207 FUNC_TRACE(); 1208 1209 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); 1210 } 1211 1212 /******************************************************************************* 1213 ** 1214 ** Function bta_av_co_audio_peer_reset_config 1215 ** 1216 ** Description Reset the peer codec configuration 1217 ** 1218 ** Returns Nothing 1219 ** 1220 *******************************************************************************/ 1221 static void bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER *p_peer) 1222 { 1223 FUNC_TRACE(); 1224 1225 /* Indicate that there is no currently selected sink */ 1226 p_peer->p_snk = NULL; 1227 } 1228 1229 /******************************************************************************* 1230 ** 1231 ** Function bta_av_co_cp_is_scmst 1232 ** 1233 ** Description Check if a content protection service is SCMS-T 1234 ** 1235 ** Returns TRUE if this CP is SCMS-T, FALSE otherwise 1236 ** 1237 *******************************************************************************/ 1238 static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo) 1239 { 1240 UINT16 cp_id; 1241 FUNC_TRACE(); 1242 1243 if (*p_protectinfo >= BTA_AV_CP_LOSC) 1244 { 1245 p_protectinfo++; 1246 STREAM_TO_UINT16(cp_id, p_protectinfo); 1247 if (cp_id == BTA_AV_CP_SCMS_T_ID) 1248 { 1249 APPL_TRACE_DEBUG("bta_av_co_cp_is_scmst: SCMS-T found"); 1250 return TRUE; 1251 } 1252 } 1253 1254 return FALSE; 1255 } 1256 1257 /******************************************************************************* 1258 ** 1259 ** Function bta_av_co_audio_sink_has_scmst 1260 ** 1261 ** Description Check if a sink supports SCMS-T 1262 ** 1263 ** Returns TRUE if the sink supports this CP, FALSE otherwise 1264 ** 1265 *******************************************************************************/ 1266 static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink) 1267 { 1268 UINT8 index; 1269 const UINT8 *p; 1270 FUNC_TRACE(); 1271 1272 /* Check if sink supports SCMS-T */ 1273 index = p_sink->num_protect; 1274 p = &p_sink->protect_info[0]; 1275 1276 while (index) 1277 { 1278 if (bta_av_co_cp_is_scmst(p)) 1279 { 1280 return TRUE; 1281 } 1282 /* Move to the next SC */ 1283 p += *p + 1; 1284 /* Decrement the SC counter */ 1285 index--; 1286 } 1287 APPL_TRACE_DEBUG("bta_av_co_audio_sink_has_scmst: SCMS-T not found"); 1288 return FALSE; 1289 } 1290 1291 /******************************************************************************* 1292 ** 1293 ** Function bta_av_co_audio_sink_supports_cp 1294 ** 1295 ** Description Check if a sink supports the current content protection 1296 ** 1297 ** Returns TRUE if the sink supports this CP, FALSE otherwise 1298 ** 1299 *******************************************************************************/ 1300 static BOOLEAN bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK *p_sink) 1301 { 1302 FUNC_TRACE(); 1303 1304 /* Check if content protection is enabled for this stream */ 1305 if (bta_av_co_cp_get_flag() != BTA_AV_CP_SCMS_COPY_FREE) 1306 { 1307 return bta_av_co_audio_sink_has_scmst(p_sink); 1308 } 1309 else 1310 { 1311 APPL_TRACE_DEBUG("bta_av_co_audio_sink_supports_cp: not required"); 1312 return TRUE; 1313 } 1314 } 1315 1316 /******************************************************************************* 1317 ** 1318 ** Function bta_av_co_audio_peer_supports_codec 1319 ** 1320 ** Description Check if a connection supports the codec config 1321 ** 1322 ** Returns TRUE if the connection supports this codec, FALSE otherwise 1323 ** 1324 *******************************************************************************/ 1325 static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index) 1326 { 1327 int index; 1328 UINT8 codec_type; 1329 FUNC_TRACE(); 1330 1331 /* Configure the codec type to look for */ 1332 codec_type = bta_av_co_cb.codec_cfg.id; 1333 1334 1335 for (index = 0; index < p_peer->num_sup_snks; index++) 1336 { 1337 if (p_peer->snks[index].codec_type == codec_type) 1338 { 1339 switch (bta_av_co_cb.codec_cfg.id) 1340 { 1341 case BTIF_AV_CODEC_SBC: 1342 if (p_snk_index) *p_snk_index = index; 1343 return bta_av_co_audio_codec_match(p_peer->snks[index].codec_caps); 1344 break; 1345 1346 1347 default: 1348 APPL_TRACE_ERROR("bta_av_co_audio_peer_supports_codec: unsupported codec id %d", bta_av_co_cb.codec_cfg.id); 1349 return FALSE; 1350 break; 1351 } 1352 } 1353 } 1354 return FALSE; 1355 } 1356 1357 /******************************************************************************* 1358 ** 1359 ** Function bta_av_co_audio_peer_src_supports_codec 1360 ** 1361 ** Description Check if a peer acting as src supports codec config 1362 ** 1363 ** Returns TRUE if the connection supports this codec, FALSE otherwise 1364 ** 1365 *******************************************************************************/ 1366 static BOOLEAN bta_av_co_audio_peer_src_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_src_index) 1367 { 1368 int index; 1369 UINT8 codec_type; 1370 FUNC_TRACE(); 1371 1372 /* Configure the codec type to look for */ 1373 codec_type = bta_av_co_cb.codec_cfg.id; 1374 1375 1376 for (index = 0; index < p_peer->num_sup_srcs; index++) 1377 { 1378 if (p_peer->srcs[index].codec_type == codec_type) 1379 { 1380 switch (bta_av_co_cb.codec_cfg.id) 1381 { 1382 case BTIF_AV_CODEC_SBC: 1383 if (p_src_index) *p_src_index = index; 1384 if (0 == bta_av_sbc_cfg_matches_cap((UINT8 *)p_peer->srcs[index].codec_caps, 1385 (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps)) 1386 { 1387 return TRUE; 1388 } 1389 break; 1390 1391 default: 1392 APPL_TRACE_ERROR("peer_src_supports_codec: unsupported codec id %d", 1393 bta_av_co_cb.codec_cfg.id); 1394 return FALSE; 1395 break; 1396 } 1397 } 1398 } 1399 return FALSE; 1400 } 1401 1402 /******************************************************************************* 1403 ** 1404 ** Function bta_av_co_audio_sink_supports_config 1405 ** 1406 ** Description Check if the media source supports a given configuration 1407 ** 1408 ** Returns TRUE if the media source supports this config, FALSE otherwise 1409 ** 1410 *******************************************************************************/ 1411 static BOOLEAN bta_av_co_audio_sink_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg) 1412 { 1413 FUNC_TRACE(); 1414 1415 switch (codec_type) 1416 { 1417 case BTA_AV_CODEC_SBC: 1418 if (bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps)) 1419 { 1420 return FALSE; 1421 } 1422 break; 1423 1424 1425 default: 1426 APPL_TRACE_ERROR("bta_av_co_audio_media_supports_config unsupported codec type %d", codec_type); 1427 return FALSE; 1428 break; 1429 } 1430 return TRUE; 1431 } 1432 1433 /******************************************************************************* 1434 ** 1435 ** Function bta_av_co_audio_media_supports_config 1436 ** 1437 ** Description Check if the media sink supports a given configuration 1438 ** 1439 ** Returns TRUE if the media source supports this config, FALSE otherwise 1440 ** 1441 *******************************************************************************/ 1442 static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg) 1443 { 1444 FUNC_TRACE(); 1445 1446 switch (codec_type) 1447 { 1448 case BTA_AV_CODEC_SBC: 1449 if (bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_caps)) 1450 { 1451 return FALSE; 1452 } 1453 break; 1454 1455 1456 default: 1457 APPL_TRACE_ERROR("bta_av_co_audio_media_supports_config unsupported codec type %d", codec_type); 1458 return FALSE; 1459 break; 1460 } 1461 return TRUE; 1462 } 1463 1464 /******************************************************************************* 1465 ** 1466 ** Function bta_av_co_audio_codec_supported 1467 ** 1468 ** Description Check if all opened connections are compatible with a codec 1469 ** configuration and content protection 1470 ** 1471 ** Returns TRUE if all opened devices support this codec, FALSE otherwise 1472 ** 1473 *******************************************************************************/ 1474 BOOLEAN bta_av_co_audio_codec_supported(tBTIF_STATUS *p_status) 1475 { 1476 UINT8 index; 1477 UINT8 snk_index; 1478 tBTA_AV_CO_PEER *p_peer; 1479 tBTA_AV_CO_SINK *p_sink; 1480 UINT8 codec_cfg[AVDT_CODEC_SIZE]; 1481 UINT8 num_protect = 0; 1482 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1483 BOOLEAN cp_active; 1484 #endif 1485 1486 FUNC_TRACE(); 1487 1488 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported"); 1489 1490 /* Check AV feeding is supported */ 1491 *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED; 1492 1493 for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++) 1494 { 1495 p_peer = &bta_av_co_cb.peers[index]; 1496 if (p_peer->opened) 1497 { 1498 if (bta_av_co_audio_peer_supports_codec(p_peer, &snk_index)) 1499 { 1500 p_sink = &p_peer->snks[snk_index]; 1501 1502 /* Check that this sink is compatible with the CP */ 1503 if (!bta_av_co_audio_sink_supports_cp(p_sink)) 1504 { 1505 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported sink %d of peer %d doesn't support cp", 1506 snk_index, index); 1507 *p_status = BTIF_ERROR_SRV_AV_CP_NOT_SUPPORTED; 1508 return FALSE; 1509 } 1510 1511 /* Build the codec configuration for this sink */ 1512 if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg)) 1513 { 1514 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1515 /* Check if this sink supports SCMS */ 1516 cp_active = bta_av_co_audio_sink_has_scmst(p_sink); 1517 #endif 1518 /* Check if this is a new configuration (new sink or new config) */ 1519 if ((p_sink != p_peer->p_snk) || 1520 (memcmp(codec_cfg, p_peer->codec_cfg, AVDT_CODEC_SIZE)) 1521 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1522 || (p_peer->cp_active != cp_active) 1523 #endif 1524 ) 1525 { 1526 /* Save the new configuration */ 1527 p_peer->p_snk = p_sink; 1528 memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE); 1529 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1530 p_peer->cp_active = cp_active; 1531 if (p_peer->cp_active) 1532 { 1533 bta_av_co_cb.cp.active = TRUE; 1534 num_protect = BTA_AV_CP_INFO_LEN; 1535 } 1536 else 1537 { 1538 bta_av_co_cb.cp.active = FALSE; 1539 } 1540 #endif 1541 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported call BTA_AvReconfig(x%x)", BTA_AV_CO_AUDIO_INDX_TO_HNDL(index)); 1542 BTA_AvReconfig(BTA_AV_CO_AUDIO_INDX_TO_HNDL(index), TRUE, p_sink->sep_info_idx, 1543 p_peer->codec_cfg, num_protect, (UINT8 *)bta_av_co_cp_scmst); 1544 } 1545 } 1546 } 1547 else 1548 { 1549 APPL_TRACE_DEBUG("bta_av_co_audio_codec_supported index %d doesn't support codec", index); 1550 return FALSE; 1551 } 1552 } 1553 } 1554 1555 *p_status = BTIF_SUCCESS; 1556 return TRUE; 1557 } 1558 1559 /******************************************************************************* 1560 ** 1561 ** Function bta_av_co_audio_codec_reset 1562 ** 1563 ** Description Reset the current codec configuration 1564 ** 1565 ** Returns void 1566 ** 1567 *******************************************************************************/ 1568 void bta_av_co_audio_codec_reset(void) 1569 { 1570 GKI_disable(); 1571 FUNC_TRACE(); 1572 1573 /* Reset the current configuration to SBC */ 1574 bta_av_co_cb.codec_cfg.id = BTIF_AV_CODEC_SBC; 1575 1576 if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_SBC_CIE *)&btif_av_sbc_default_config, bta_av_co_cb.codec_cfg.info) != A2D_SUCCESS) 1577 { 1578 APPL_TRACE_ERROR("bta_av_co_audio_codec_reset A2D_BldSbcInfo failed"); 1579 } 1580 1581 GKI_enable(); 1582 } 1583 1584 /******************************************************************************* 1585 ** 1586 ** Function bta_av_co_audio_set_codec 1587 ** 1588 ** Description Set the current codec configuration from the feeding type. 1589 ** This function is starting to modify the configuration, it 1590 ** should be protected. 1591 ** 1592 ** Returns TRUE if successful, FALSE otherwise 1593 ** 1594 *******************************************************************************/ 1595 BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTIF_STATUS *p_status) 1596 { 1597 tA2D_SBC_CIE sbc_config; 1598 tBTIF_AV_CODEC_INFO new_cfg; 1599 1600 FUNC_TRACE(); 1601 1602 /* Check AV feeding is supported */ 1603 *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED; 1604 1605 APPL_TRACE_DEBUG("bta_av_co_audio_set_codec cid=%d", p_feeding->format); 1606 1607 /* Supported codecs */ 1608 switch (p_feeding->format) 1609 { 1610 case BTIF_AV_CODEC_PCM: 1611 new_cfg.id = BTIF_AV_CODEC_SBC; 1612 1613 sbc_config = btif_av_sbc_default_config; 1614 if ((p_feeding->cfg.pcm.num_channel != 1) && 1615 (p_feeding->cfg.pcm.num_channel != 2)) 1616 { 1617 APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM channel number unsupported"); 1618 return FALSE; 1619 } 1620 if ((p_feeding->cfg.pcm.bit_per_sample != 8) && 1621 (p_feeding->cfg.pcm.bit_per_sample != 16)) 1622 { 1623 APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM sample size unsupported"); 1624 return FALSE; 1625 } 1626 switch (p_feeding->cfg.pcm.sampling_freq) 1627 { 1628 case 8000: 1629 case 12000: 1630 case 16000: 1631 case 24000: 1632 case 32000: 1633 case 48000: 1634 sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_48; 1635 break; 1636 1637 case 11025: 1638 case 22050: 1639 case 44100: 1640 sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_44; 1641 break; 1642 default: 1643 APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM sampling frequency unsupported"); 1644 return FALSE; 1645 break; 1646 } 1647 /* Build the codec config */ 1648 if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, &sbc_config, new_cfg.info) != A2D_SUCCESS) 1649 { 1650 APPL_TRACE_ERROR("bta_av_co_audio_set_codec A2D_BldSbcInfo failed"); 1651 return FALSE; 1652 } 1653 break; 1654 1655 1656 default: 1657 APPL_TRACE_ERROR("bta_av_co_audio_set_codec Feeding format unsupported"); 1658 return FALSE; 1659 break; 1660 } 1661 1662 /* The new config was correctly built */ 1663 bta_av_co_cb.codec_cfg = new_cfg; 1664 1665 1666 /* Check all devices support it */ 1667 *p_status = BTIF_SUCCESS; 1668 return bta_av_co_audio_codec_supported(p_status); 1669 } 1670 1671 /******************************************************************************* 1672 ** 1673 ** Function bta_av_co_audio_get_sbc_config 1674 ** 1675 ** Description Retrieves the SBC codec configuration. If the codec in use 1676 ** is not SBC, return the default SBC codec configuration. 1677 ** 1678 ** Returns TRUE if codec is SBC, FALSE otherwise 1679 ** 1680 *******************************************************************************/ 1681 BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu) 1682 { 1683 BOOLEAN result = FALSE; 1684 UINT8 index, jndex; 1685 tBTA_AV_CO_PEER *p_peer; 1686 tBTA_AV_CO_SINK *p_sink; 1687 1688 APPL_TRACE_EVENT("bta_av_co_cb.codec_cfg.id : codec 0x%x", bta_av_co_cb.codec_cfg.id); 1689 1690 /* Minimum MTU is by default very large */ 1691 *p_minmtu = 0xFFFF; 1692 1693 GKI_disable(); 1694 if (bta_av_co_cb.codec_cfg.id == BTIF_AV_CODEC_SBC) 1695 { 1696 if (A2D_ParsSbcInfo(p_sbc_config, bta_av_co_cb.codec_cfg.info, FALSE) == A2D_SUCCESS) 1697 { 1698 for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++) 1699 { 1700 p_peer = &bta_av_co_cb.peers[index]; 1701 if (p_peer->opened) 1702 { 1703 if (p_peer->mtu < *p_minmtu) 1704 { 1705 *p_minmtu = p_peer->mtu; 1706 } 1707 for (jndex = 0; jndex < p_peer->num_sup_snks; jndex++) 1708 { 1709 p_sink = &p_peer->snks[jndex]; 1710 if (p_sink->codec_type == A2D_MEDIA_CT_SBC) 1711 { 1712 /* Update the bitpool boundaries of the current config */ 1713 p_sbc_config->min_bitpool = 1714 BTA_AV_CO_MAX(p_sink->codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], 1715 p_sbc_config->min_bitpool); 1716 p_sbc_config->max_bitpool = 1717 BTA_AV_CO_MIN(p_sink->codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF], 1718 p_sbc_config->max_bitpool); 1719 APPL_TRACE_EVENT("bta_av_co_audio_get_sbc_config : sink bitpool min %d, max %d", 1720 p_sbc_config->min_bitpool, p_sbc_config->max_bitpool); 1721 break; 1722 } 1723 } 1724 } 1725 } 1726 result = TRUE; 1727 } 1728 } 1729 1730 if (!result) 1731 { 1732 /* Not SBC, still return the default values */ 1733 *p_sbc_config = btif_av_sbc_default_config; 1734 } 1735 GKI_enable(); 1736 1737 return result; 1738 } 1739 1740 /******************************************************************************* 1741 ** 1742 ** Function bta_av_co_audio_discard_config 1743 ** 1744 ** Description Discard the codec configuration of a connection 1745 ** 1746 ** Returns Nothing 1747 ** 1748 *******************************************************************************/ 1749 void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl) 1750 { 1751 tBTA_AV_CO_PEER *p_peer; 1752 1753 FUNC_TRACE(); 1754 1755 /* Find the peer info */ 1756 p_peer = bta_av_co_get_peer(hndl); 1757 if (p_peer == NULL) 1758 { 1759 APPL_TRACE_ERROR("bta_av_co_audio_discard_config could not find peer entry"); 1760 return; 1761 } 1762 1763 /* Reset the peer codec configuration */ 1764 bta_av_co_audio_peer_reset_config(p_peer); 1765 } 1766 1767 /******************************************************************************* 1768 ** 1769 ** Function bta_av_co_init 1770 ** 1771 ** Description Initialization 1772 ** 1773 ** Returns Nothing 1774 ** 1775 *******************************************************************************/ 1776 void bta_av_co_init(void) 1777 { 1778 FUNC_TRACE(); 1779 1780 /* Reset the control block */ 1781 memset(&bta_av_co_cb, 0, sizeof(bta_av_co_cb)); 1782 1783 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE; 1784 1785 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) 1786 bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_NEVER); 1787 #else 1788 bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_FREE); 1789 #endif 1790 1791 /* Reset the current config */ 1792 bta_av_co_audio_codec_reset(); 1793 } 1794 1795 1796 /******************************************************************************* 1797 ** 1798 ** Function bta_av_co_peer_cp_supported 1799 ** 1800 ** Description Checks if the peer supports CP 1801 ** 1802 ** Returns TRUE if the peer supports CP 1803 ** 1804 *******************************************************************************/ 1805 BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl) 1806 { 1807 tBTA_AV_CO_PEER *p_peer; 1808 tBTA_AV_CO_SINK *p_sink; 1809 UINT8 index; 1810 1811 FUNC_TRACE(); 1812 1813 /* Find the peer info */ 1814 p_peer = bta_av_co_get_peer(hndl); 1815 if (p_peer == NULL) 1816 { 1817 APPL_TRACE_ERROR("bta_av_co_peer_cp_supported could not find peer entry"); 1818 return FALSE; 1819 } 1820 1821 for (index = 0; index < p_peer->num_sup_snks; index++) 1822 { 1823 p_sink = &p_peer->snks[index]; 1824 if (p_sink->codec_type == A2D_MEDIA_CT_SBC) 1825 { 1826 return bta_av_co_audio_sink_has_scmst(p_sink); 1827 } 1828 } 1829 APPL_TRACE_ERROR("bta_av_co_peer_cp_supported did not find SBC sink"); 1830 return FALSE; 1831 } 1832 1833 1834 /******************************************************************************* 1835 ** 1836 ** Function bta_av_co_get_remote_bitpool_pref 1837 ** 1838 ** Description Check if remote side did a setconfig within the limits 1839 ** of our exported bitpool range. If set we will set the 1840 ** remote preference. 1841 ** 1842 ** Returns TRUE if config set, FALSE otherwize 1843 ** 1844 *******************************************************************************/ 1845 1846 BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max) 1847 { 1848 /* check if remote peer did a set config */ 1849 if (bta_av_co_cb.codec_cfg_setconfig.id == BTIF_AV_CODEC_NONE) 1850 return FALSE; 1851 1852 *min = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF]; 1853 *max = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]; 1854 1855 return TRUE; 1856 } 1857 1858 1859