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