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