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