Home | History | Annotate | Download | only in co
      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