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