OSDN Git Service

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