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