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