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