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