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