• 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 
39 
40 /*****************************************************************************
41  **  Constants
42  *****************************************************************************/
43 
44 #define FUNC_TRACE()     APPL_TRACE_DEBUG1("%s", __FUNCTION__);
45 
46 /* Macro to retrieve the number of elements in a statically allocated array */
47 #define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a)/sizeof((__a)[0]))
48 
49 /* MIN and MAX macros */
50 #define BTA_AV_CO_MIN(X,Y) ((X) < (Y) ? (X) : (Y))
51 #define BTA_AV_CO_MAX(X,Y) ((X) > (Y) ? (X) : (Y))
52 
53 /* Macro to convert audio handle to index and vice versa */
54 #define BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl) (((hndl) & (~BTA_AV_CHNL_MSK)) - 1)
55 #define BTA_AV_CO_AUDIO_INDX_TO_HNDL(indx) (((indx) + 1) | BTA_AV_CHNL_AUDIO)
56 
57 
58 /* Offsets to access codec information in SBC codec */
59 #define BTA_AV_CO_SBC_FREQ_CHAN_OFF    3
60 #define BTA_AV_CO_SBC_BLOCK_BAND_OFF   4
61 #define BTA_AV_CO_SBC_MIN_BITPOOL_OFF  5
62 #define BTA_AV_CO_SBC_MAX_BITPOOL_OFF  6
63 
64 #define BTA_AV_CO_SBC_MAX_BITPOOL  53
65 
66 /* SCMS-T protect info */
67 const UINT8 bta_av_co_cp_scmst[BTA_AV_CP_INFO_LEN] = "\x02\x02\x00";
68 
69 /* SBC codec capabilities */
70 const tA2D_SBC_CIE bta_av_co_sbc_caps =
71 {
72     (A2D_SBC_IE_SAMP_FREQ_44), /* samp_freq */
73     (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 */
74     (A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | A2D_SBC_IE_BLOCKS_8 | A2D_SBC_IE_BLOCKS_4), /* block_len */
75     (A2D_SBC_IE_SUBBAND_4 | A2D_SBC_IE_SUBBAND_8), /* num_subbands */
76     (A2D_SBC_IE_ALLOC_MD_L | A2D_SBC_IE_ALLOC_MD_S), /* alloc_mthd */
77     BTA_AV_CO_SBC_MAX_BITPOOL, /* max_bitpool */
78     A2D_SBC_IE_MIN_BITPOOL /* min_bitpool */
79 };
80 
81 #if !defined(BTIF_AV_SBC_DEFAULT_SAMP_FREQ)
82 #define BTIF_AV_SBC_DEFAULT_SAMP_FREQ A2D_SBC_IE_SAMP_FREQ_44
83 #endif
84 
85 /* Default SBC codec configuration */
86 const tA2D_SBC_CIE btif_av_sbc_default_config =
87 {
88     BTIF_AV_SBC_DEFAULT_SAMP_FREQ,   /* samp_freq */
89     A2D_SBC_IE_CH_MD_JOINT,         /* ch_mode */
90     A2D_SBC_IE_BLOCKS_16,           /* block_len */
91     A2D_SBC_IE_SUBBAND_8,           /* num_subbands */
92     A2D_SBC_IE_ALLOC_MD_L,          /* alloc_mthd */
93     BTA_AV_CO_SBC_MAX_BITPOOL,      /* max_bitpool */
94     A2D_SBC_IE_MIN_BITPOOL          /* min_bitpool */
95 };
96 
97 
98 /*****************************************************************************
99 **  Local data
100 *****************************************************************************/
101 typedef struct
102 {
103     UINT8 sep_info_idx;                 /* local SEP index (in BTA tables) */
104     UINT8 seid;                         /* peer SEP index (in peer tables) */
105     UINT8 codec_type;                   /* peer SEP codec type */
106     UINT8 codec_caps[AVDT_CODEC_SIZE];  /* peer SEP codec capabilities */
107     UINT8 num_protect;                  /* peer SEP number of CP elements */
108     UINT8 protect_info[BTA_AV_CP_INFO_LEN];  /* peer SEP content protection info */
109 } tBTA_AV_CO_SINK;
110 
111 typedef struct
112 {
113     BD_ADDR         addr;               /* address of audio/video peer */
114     tBTA_AV_CO_SINK snks[BTIF_SV_AV_AA_SEP_INDEX]; /* array of supported sinks */
115     UINT8           num_snks;           /* total number of sinks at peer */
116     UINT8           num_seps;           /* total number of seids at peer */
117     UINT8           num_rx_snks;        /* number of received sinks */
118     UINT8           num_sup_snks;       /* number of supported sinks in the snks array */
119     tBTA_AV_CO_SINK *p_snk;             /* currently selected sink */
120     UINT8           codec_cfg[AVDT_CODEC_SIZE]; /* current codec configuration */
121     BOOLEAN         cp_active;          /* current CP configuration */
122     BOOLEAN         acp;                /* acceptor */
123     BOOLEAN         recfg_needed;       /* reconfiguration is needed */
124     BOOLEAN         opened;             /* opened */
125     UINT16          mtu;                /* maximum transmit unit size */
126 } tBTA_AV_CO_PEER;
127 
128 typedef struct
129 {
130     BOOLEAN active;
131     UINT8 flag;
132 } tBTA_AV_CO_CP;
133 
134 typedef struct
135 {
136     /* Connected peer information */
137     tBTA_AV_CO_PEER peers[BTA_AV_NUM_STRS];
138     /* Current codec configuration - access to this variable must be protected */
139     tBTIF_AV_CODEC_INFO codec_cfg;
140     tBTIF_AV_CODEC_INFO codec_cfg_setconfig; /* remote peer setconfig preference */
141 
142     tBTA_AV_CO_CP cp;
143 } tBTA_AV_CO_CB;
144 
145 /* Control block instance */
146 static tBTA_AV_CO_CB bta_av_co_cb;
147 
148 static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg);
149 static void bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER *p_peer);
150 static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo);
151 static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink);
152 static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index);
153 static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg);
154 
155 
156 
157 
158 /*******************************************************************************
159  **
160  ** Function         bta_av_co_cp_is_active
161  **
162  ** Description      Get the current configuration of content protection
163  **
164  ** Returns          TRUE if the current streaming has CP, FALSE otherwise
165  **
166  *******************************************************************************/
bta_av_co_cp_is_active(void)167 BOOLEAN bta_av_co_cp_is_active(void)
168 {
169     FUNC_TRACE();
170     return bta_av_co_cb.cp.active;
171 }
172 
173 /*******************************************************************************
174  **
175  ** Function         bta_av_co_cp_get_flag
176  **
177  ** Description      Get content protection flag
178  **                  BTA_AV_CP_SCMS_COPY_NEVER
179  **                  BTA_AV_CP_SCMS_COPY_ONCE
180  **                  BTA_AV_CP_SCMS_COPY_FREE
181  **
182  ** Returns          The current flag value
183  **
184  *******************************************************************************/
bta_av_co_cp_get_flag(void)185 UINT8 bta_av_co_cp_get_flag(void)
186 {
187     FUNC_TRACE();
188     return bta_av_co_cb.cp.flag;
189 }
190 
191 /*******************************************************************************
192  **
193  ** Function         bta_av_co_cp_set_flag
194  **
195  ** Description      Set content protection flag
196  **                  BTA_AV_CP_SCMS_COPY_NEVER
197  **                  BTA_AV_CP_SCMS_COPY_ONCE
198  **                  BTA_AV_CP_SCMS_COPY_FREE
199  **
200  ** Returns          TRUE if setting the SCMS flag is supported else FALSE
201  **
202  *******************************************************************************/
bta_av_co_cp_set_flag(UINT8 cp_flag)203 BOOLEAN bta_av_co_cp_set_flag(UINT8 cp_flag)
204 {
205     FUNC_TRACE();
206 
207 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
208 #else
209     if (cp_flag != BTA_AV_CP_SCMS_COPY_FREE)
210     {
211         return FALSE;
212     }
213 #endif
214     bta_av_co_cb.cp.flag = cp_flag;
215     return TRUE;
216 }
217 
218 /*******************************************************************************
219  **
220  ** Function         bta_av_co_get_peer
221  **
222  ** Description      find the peer entry for a given handle
223  **
224  ** Returns          the control block
225  **
226  *******************************************************************************/
bta_av_co_get_peer(tBTA_AV_HNDL hndl)227 static tBTA_AV_CO_PEER *bta_av_co_get_peer(tBTA_AV_HNDL hndl)
228 {
229     UINT8 index;
230     FUNC_TRACE();
231 
232     index = BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl);
233 
234     /* Sanity check */
235     if (index >= BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers))
236     {
237         APPL_TRACE_ERROR1("bta_av_co_get_peer peer index out of bounds:%d", index);
238         return NULL;
239     }
240 
241     return &bta_av_co_cb.peers[index];
242 }
243 
244 /*******************************************************************************
245  **
246  ** Function         bta_av_co_audio_init
247  **
248  ** Description      This callout function is executed by AV when it is
249  **                  started by calling BTA_AvRegister().  This function can be
250  **                  used by the phone to initialize audio paths or for other
251  **                  initialization purposes.
252  **
253  **
254  ** Returns          Stream codec and content protection capabilities info.
255  **
256  *******************************************************************************/
bta_av_co_audio_init(UINT8 * p_codec_type,UINT8 * p_codec_info,UINT8 * p_num_protect,UINT8 * p_protect_info,UINT8 index)257 BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_num_protect,
258         UINT8 *p_protect_info, UINT8 index)
259 {
260     FUNC_TRACE();
261 
262     APPL_TRACE_DEBUG1("bta_av_co_audio_init: %d", index);
263 
264 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
265     {
266         UINT8 *p = p_protect_info;
267 
268         /* Content protection info - support SCMS-T */
269         *p_num_protect = 1;
270         *p++ = BTA_AV_CP_LOSC;
271         UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID);
272 
273     }
274 #else
275     /* By default - no content protection info */
276     *p_num_protect = 0;
277     *p_protect_info = 0;
278 #endif
279 
280     /* reset remote preference through setconfig */
281     bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE;
282 
283     switch (index)
284     {
285     case BTIF_SV_AV_AA_SBC_INDEX:
286         /* Set up for SBC codec */
287         *p_codec_type = BTA_AV_CODEC_SBC;
288 
289         /* This should not fail because we are using constants for parameters */
290         A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info);
291 
292         /* Codec is valid */
293         return TRUE;
294 
295 
296     default:
297         /* Not valid */
298         return FALSE;
299     }
300 }
301 
302 /*******************************************************************************
303  **
304  ** Function         bta_av_co_audio_disc_res
305  **
306  ** Description      This callout function is executed by AV to report the
307  **                  number of stream end points (SEP) were found during the
308  **                  AVDT stream discovery process.
309  **
310  **
311  ** Returns          void.
312  **
313  *******************************************************************************/
bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl,UINT8 num_seps,UINT8 num_snk,BD_ADDR addr)314 BTA_API void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, UINT8 num_seps, UINT8 num_snk,
315         BD_ADDR addr)
316 {
317     tBTA_AV_CO_PEER *p_peer;
318 
319     FUNC_TRACE();
320 
321     APPL_TRACE_DEBUG3("bta_av_co_audio_disc_res h:x%x num_seps:%d num_snk:%d",
322             hndl, num_seps, num_snk);
323 
324     /* Find the peer info */
325     p_peer = bta_av_co_get_peer(hndl);
326     if (p_peer == NULL)
327     {
328         APPL_TRACE_ERROR0("bta_av_co_audio_disc_res could not find peer entry");
329         return;
330     }
331 
332     /* Sanity check : this should never happen */
333     if (p_peer->opened)
334     {
335         APPL_TRACE_ERROR0("bta_av_co_audio_disc_res peer already opened");
336     }
337 
338     /* Copy the discovery results */
339     bdcpy(p_peer->addr, addr);
340     p_peer->num_snks = num_snk;
341     p_peer->num_seps = num_seps;
342     p_peer->num_rx_snks = 0;
343     p_peer->num_sup_snks = 0;
344 }
345 
346 /*******************************************************************************
347  **
348  ** Function         bta_av_co_audio_getconfig
349  **
350  ** Description      This callout function is executed by AV to retrieve the
351  **                  desired codec and content protection configuration for the
352  **                  audio stream.
353  **
354  **
355  ** Returns          Stream codec and content protection configuration info.
356  **
357  *******************************************************************************/
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)358 BTA_API UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
359         UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, UINT8 *p_num_protect,
360         UINT8 *p_protect_info)
361 
362 {
363     UINT8 result = A2D_FAIL;
364     BOOLEAN supported;
365     tBTA_AV_CO_PEER *p_peer;
366     tBTA_AV_CO_SINK *p_sink;
367     UINT8 codec_cfg[AVDT_CODEC_SIZE];
368     UINT8 index;
369 
370     FUNC_TRACE();
371 
372     APPL_TRACE_DEBUG3("bta_av_co_audio_getconfig handle:0x%x codec_type:%d seid:%d", hndl, codec_type, seid);
373     APPL_TRACE_DEBUG4("num_protect:0x%02x protect_info:0x%02x%02x%02x",
374         *p_num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]);
375 
376     /* Retrieve the peer info */
377     p_peer = bta_av_co_get_peer(hndl);
378     if (p_peer == NULL)
379     {
380         APPL_TRACE_ERROR0("bta_av_co_audio_getconfig could not find peer entry");
381         return A2D_FAIL;
382     }
383 
384     APPL_TRACE_DEBUG4("bta_av_co_audio_getconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)",
385             p_peer->opened, p_peer->num_snks, p_peer->num_rx_snks, p_peer->num_sup_snks);
386 
387     /* Increment the number of received sinks capabilities */
388     p_peer->num_rx_snks++;
389 
390     /* Check if this is a supported configuration */
391     supported = FALSE;
392     switch (codec_type)
393     {
394     case BTA_AV_CODEC_SBC:
395         supported = TRUE;
396         break;
397 
398     default:
399         break;
400     }
401 
402     if (supported)
403     {
404         /* If there is room for a new one */
405         if (p_peer->num_sup_snks < BTA_AV_CO_NUM_ELEMENTS(p_peer->snks))
406         {
407             p_sink = &p_peer->snks[p_peer->num_sup_snks++];
408 
409             APPL_TRACE_DEBUG6("bta_av_co_audio_getconfig saved caps[%x:%x:%x:%x:%x:%x]",
410                     p_codec_info[1], p_codec_info[2], p_codec_info[3],
411                     p_codec_info[4], p_codec_info[5], p_codec_info[6]);
412 
413             memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
414             p_sink->codec_type = codec_type;
415             p_sink->sep_info_idx = *p_sep_info_idx;
416             p_sink->seid = seid;
417             p_sink->num_protect = *p_num_protect;
418             memcpy(p_sink->protect_info, p_protect_info, BTA_AV_CP_INFO_LEN);
419         }
420         else
421         {
422             APPL_TRACE_ERROR0("bta_av_co_audio_getconfig no more room for SNK info");
423         }
424     }
425 
426     /* If last SNK get capabilities or all supported codec capa retrieved */
427     if ((p_peer->num_rx_snks == p_peer->num_snks) ||
428         (p_peer->num_sup_snks == BTA_AV_CO_NUM_ELEMENTS(p_peer->snks)))
429     {
430         APPL_TRACE_DEBUG0("bta_av_co_audio_getconfig last sink reached");
431 
432         /* Protect access to bta_av_co_cb.codec_cfg */
433         GKI_disable();
434 
435         /* Find a sink that matches the codec config */
436         if (bta_av_co_audio_peer_supports_codec(p_peer, &index))
437         {
438             /* stop fetching caps once we retrieved a supported codec */
439             if (p_peer->acp)
440             {
441                 *p_sep_info_idx = p_peer->num_seps;
442                 APPL_TRACE_EVENT0("no need to fetch more SEPs");
443             }
444 
445             p_sink = &p_peer->snks[index];
446 
447             /* Build the codec configuration for this sink */
448             if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg))
449             {
450                 APPL_TRACE_DEBUG6("bta_av_co_audio_getconfig reconfig p_codec_info[%x:%x:%x:%x:%x:%x]",
451                         codec_cfg[1], codec_cfg[2], codec_cfg[3],
452                         codec_cfg[4], codec_cfg[5], codec_cfg[6]);
453 
454                 /* Save the new configuration */
455                 p_peer->p_snk = p_sink;
456                 memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE);
457 
458                 /* By default, no content protection */
459                 *p_num_protect = 0;
460 
461 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
462                 /* Check if this sink supports SCMS */
463                 if (bta_av_co_audio_sink_has_scmst(p_sink))
464                 {
465                     p_peer->cp_active = TRUE;
466                     bta_av_co_cb.cp.active = TRUE;
467                     *p_num_protect = BTA_AV_CP_INFO_LEN;
468                     memcpy(p_protect_info, bta_av_co_cp_scmst, BTA_AV_CP_INFO_LEN);
469                 }
470                 else
471                 {
472                     p_peer->cp_active = FALSE;
473                     bta_av_co_cb.cp.active = FALSE;
474                 }
475 #endif
476 
477                 /* If acceptor -> reconfig otherwise reply for configuration */
478                 if (p_peer->acp)
479                 {
480                     if (p_peer->recfg_needed)
481                     {
482                         APPL_TRACE_DEBUG1("bta_av_co_audio_getconfig call BTA_AvReconfig(x%x)", hndl);
483                         BTA_AvReconfig(hndl, TRUE, p_sink->sep_info_idx, p_peer->codec_cfg, *p_num_protect, (UINT8 *)bta_av_co_cp_scmst);
484                     }
485                 }
486                 else
487                 {
488                     *p_sep_info_idx = p_sink->sep_info_idx;
489                     memcpy(p_codec_info, p_peer->codec_cfg, AVDT_CODEC_SIZE);
490                 }
491                 result =  A2D_SUCCESS;
492             }
493         }
494         /* Protect access to bta_av_co_cb.codec_cfg */
495         GKI_enable();
496     }
497     return result;
498 }
499 
500 /*******************************************************************************
501  **
502  ** Function         bta_av_co_audio_setconfig
503  **
504  ** Description      This callout function is executed by AV to set the codec and
505  **                  content protection configuration of the audio stream.
506  **
507  **
508  ** Returns          void
509  **
510  *******************************************************************************/
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)511 BTA_API void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
512         UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, UINT8 num_protect, UINT8 *p_protect_info)
513 
514 {
515     tBTA_AV_CO_PEER *p_peer;
516     UINT8 status = A2D_SUCCESS;
517     UINT8 category = A2D_SUCCESS;
518     BOOLEAN recfg_needed = FALSE;
519 
520     FUNC_TRACE();
521 
522     APPL_TRACE_DEBUG6("bta_av_co_audio_setconfig p_codec_info[%x:%x:%x:%x:%x:%x]",
523             p_codec_info[1], p_codec_info[2], p_codec_info[3],
524             p_codec_info[4], p_codec_info[5], p_codec_info[6]);
525     APPL_TRACE_DEBUG4("num_protect:0x%02x protect_info:0x%02x%02x%02x",
526         num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]);
527 
528     /* Retrieve the peer info */
529     p_peer = bta_av_co_get_peer(hndl);
530     if (p_peer == NULL)
531     {
532         APPL_TRACE_ERROR0("bta_av_co_audio_setconfig could not find peer entry");
533 
534         /* Call call-in rejecting the configuration */
535         bta_av_ci_setconfig(hndl, A2D_BUSY, AVDT_ASC_CODEC, 0, NULL, FALSE);
536         return;
537     }
538 
539     /* Sanity check: should not be opened at this point */
540     if (p_peer->opened)
541     {
542         APPL_TRACE_ERROR0("bta_av_co_audio_setconfig peer already in use");
543     }
544 
545 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
546     if (num_protect != 0)
547     {
548         /* If CP is supported */
549         if ((num_protect != 1) ||
550             (bta_av_co_cp_is_scmst(p_protect_info) == FALSE))
551         {
552             APPL_TRACE_ERROR0("bta_av_co_audio_setconfig wrong CP configuration");
553             status = A2D_BAD_CP_TYPE;
554             category = AVDT_ASC_PROTECT;
555         }
556     }
557 #else
558     /* Do not support content protection for the time being */
559     if (num_protect != 0)
560     {
561         APPL_TRACE_ERROR0("bta_av_co_audio_setconfig wrong CP configuration");
562         status = A2D_BAD_CP_TYPE;
563         category = AVDT_ASC_PROTECT;
564     }
565 #endif
566     if (status == A2D_SUCCESS)
567     {
568         /* Check if codec configuration is supported */
569         if (bta_av_co_audio_media_supports_config(codec_type, p_codec_info))
570         {
571             /* Protect access to bta_av_co_cb.codec_cfg */
572             GKI_disable();
573 
574             /* Check if the configuration matches the current codec config */
575             switch (bta_av_co_cb.codec_cfg.id)
576             {
577             case BTIF_AV_CODEC_SBC:
578                 if ((codec_type != BTA_AV_CODEC_SBC) || memcmp(p_codec_info, bta_av_co_cb.codec_cfg.info, 5))
579                 {
580                     recfg_needed = TRUE;
581                 }
582                 else if ((num_protect == 1) && (!bta_av_co_cb.cp.active))
583                 {
584                     recfg_needed = TRUE;
585                 }
586 
587                 /* if remote side requests a restricted notify sinks preferred bitpool range as all other params are
588                    already checked for validify */
589                 APPL_TRACE_EVENT2("remote peer setconfig bitpool range [%d:%d]",
590                    p_codec_info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
591                    p_codec_info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] );
592 
593                 bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_SBC;
594                 memcpy(bta_av_co_cb.codec_cfg_setconfig.info, p_codec_info, AVDT_CODEC_SIZE);
595                 break;
596 
597 
598             default:
599                 APPL_TRACE_ERROR1("bta_av_co_audio_setconfig unsupported cid %d", bta_av_co_cb.codec_cfg.id);
600                 recfg_needed = TRUE;
601                 break;
602             }
603             /* Protect access to bta_av_co_cb.codec_cfg */
604             GKI_enable();
605         }
606         else
607         {
608             category = AVDT_ASC_CODEC;
609             status = A2D_WRONG_CODEC;
610         }
611     }
612 
613     if (status != A2D_SUCCESS)
614     {
615         APPL_TRACE_DEBUG2("bta_av_co_audio_setconfig reject s=%d c=%d", status, category);
616 
617         /* Call call-in rejecting the configuration */
618         bta_av_ci_setconfig(hndl, status, category, 0, NULL, FALSE);
619     }
620     else
621     {
622         /* Mark that this is an acceptor peer */
623         p_peer->acp = TRUE;
624         p_peer->recfg_needed = recfg_needed;
625 
626         APPL_TRACE_DEBUG1("bta_av_co_audio_setconfig accept reconf=%d", recfg_needed);
627 
628         /* Call call-in accepting the configuration */
629         bta_av_ci_setconfig(hndl, A2D_SUCCESS, A2D_SUCCESS, 0, NULL, recfg_needed);
630     }
631 }
632 
633 /*******************************************************************************
634  **
635  ** Function         bta_av_co_audio_open
636  **
637  ** Description      This function is called by AV when the audio stream connection
638  **                  is opened.
639  **
640  **
641  ** Returns          void
642  **
643  *******************************************************************************/
bta_av_co_audio_open(tBTA_AV_HNDL hndl,tBTA_AV_CODEC codec_type,UINT8 * p_codec_info,UINT16 mtu)644 BTA_API void bta_av_co_audio_open(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
645         UINT16 mtu)
646 {
647     tBTA_AV_CO_PEER *p_peer;
648 
649     FUNC_TRACE();
650 
651     APPL_TRACE_DEBUG2("bta_av_co_audio_open mtu:%d codec_type:%d", mtu, codec_type);
652 
653     /* Retrieve the peer info */
654     p_peer = bta_av_co_get_peer(hndl);
655     if (p_peer == NULL)
656     {
657         APPL_TRACE_ERROR0("bta_av_co_audio_setconfig could not find peer entry");
658     }
659     else
660     {
661         p_peer->opened = TRUE;
662         p_peer->mtu = mtu;
663     }
664 }
665 
666 /*******************************************************************************
667  **
668  ** Function         bta_av_co_audio_close
669  **
670  ** Description      This function is called by AV when the audio stream connection
671  **                  is closed.
672  **
673  **
674  ** Returns          void
675  **
676  *******************************************************************************/
bta_av_co_audio_close(tBTA_AV_HNDL hndl,tBTA_AV_CODEC codec_type,UINT16 mtu)677 BTA_API void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu)
678 
679 {
680     tBTA_AV_CO_PEER *p_peer;
681 
682     FUNC_TRACE();
683 
684     APPL_TRACE_DEBUG0("bta_av_co_audio_close");
685 
686     /* Retrieve the peer info */
687     p_peer = bta_av_co_get_peer(hndl);
688     if (p_peer)
689     {
690         /* Mark the peer closed and clean the peer info */
691         memset(p_peer, 0, sizeof(*p_peer));
692     }
693     else
694     {
695         APPL_TRACE_ERROR0("bta_av_co_audio_close could not find peer entry");
696     }
697 
698     /* reset remote preference through setconfig */
699     bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE;
700 }
701 
702 /*******************************************************************************
703  **
704  ** Function         bta_av_co_audio_start
705  **
706  ** Description      This function is called by AV when the audio streaming data
707  **                  transfer is started.
708  **
709  **
710  ** Returns          void
711  **
712  *******************************************************************************/
bta_av_co_audio_start(tBTA_AV_HNDL hndl,tBTA_AV_CODEC codec_type,UINT8 * p_codec_info,BOOLEAN * p_no_rtp_hdr)713 BTA_API void bta_av_co_audio_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
714         UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr)
715 {
716     FUNC_TRACE();
717 
718     APPL_TRACE_DEBUG0("bta_av_co_audio_start");
719 
720 }
721 
722 /*******************************************************************************
723  **
724  ** Function         bta_av_co_audio_stop
725  **
726  ** Description      This function is called by AV when the audio streaming data
727  **                  transfer is stopped.
728  **
729  **
730  ** Returns          void
731  **
732  *******************************************************************************/
bta_av_co_audio_stop(tBTA_AV_HNDL hndl,tBTA_AV_CODEC codec_type)733 BTA_API extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type)
734 {
735     FUNC_TRACE();
736 
737     APPL_TRACE_DEBUG0("bta_av_co_audio_stop");
738 }
739 
740 /*******************************************************************************
741  **
742  ** Function         bta_av_co_audio_src_data_path
743  **
744  ** Description      This function is called to manage data transfer from
745  **                  the audio codec to AVDTP.
746  **
747  ** Returns          Pointer to the GKI buffer to send, NULL if no buffer to send
748  **
749  *******************************************************************************/
bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type,UINT32 * p_len,UINT32 * p_timestamp)750 BTA_API void * bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, UINT32 *p_len,
751         UINT32 *p_timestamp)
752 {
753     BT_HDR *p_buf;
754     FUNC_TRACE();
755 
756     p_buf = btif_media_aa_readbuf();
757     if (p_buf != NULL)
758     {
759         switch (codec_type)
760         {
761         case BTA_AV_CODEC_SBC:
762             /* In media packet SBC, the following information is available:
763              * p_buf->layer_specific : number of SBC frames in the packet
764              * p_buf->word[0] : timestamp
765              */
766             /* Retrieve the timestamp information from the media packet */
767             *p_timestamp = *((UINT32 *) (p_buf + 1));
768 
769             /* Set up packet header */
770             bta_av_sbc_bld_hdr(p_buf, p_buf->layer_specific);
771             break;
772 
773 
774         default:
775             APPL_TRACE_ERROR1("bta_av_co_audio_src_data_path Unsupported codec type (%d)", codec_type);
776             break;
777         }
778 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
779         {
780             UINT8 *p;
781             if (bta_av_co_cp_is_active())
782             {
783                 p_buf->len++;
784                 p_buf->offset--;
785                 p = (UINT8 *)(p_buf + 1) + p_buf->offset;
786                 *p = bta_av_co_cp_get_flag();
787             }
788         }
789 #endif
790     }
791     return p_buf;
792 }
793 
794 /*******************************************************************************
795  **
796  ** Function         bta_av_co_audio_drop
797  **
798  ** Description      An Audio packet is dropped. .
799  **                  It's very likely that the connected headset with this handle
800  **                  is moved far away. The implementation may want to reduce
801  **                  the encoder bit rate setting to reduce the packet size.
802  **
803  ** Returns          void
804  **
805  *******************************************************************************/
bta_av_co_audio_drop(tBTA_AV_HNDL hndl)806 void bta_av_co_audio_drop(tBTA_AV_HNDL hndl)
807 {
808     FUNC_TRACE();
809 
810     APPL_TRACE_ERROR1("bta_av_co_audio_drop dropped: x%x", hndl);
811 }
812 
813 /*******************************************************************************
814  **
815  ** Function         bta_av_co_audio_delay
816  **
817  ** Description      This function is called by AV when the audio stream connection
818  **                  needs to send the initial delay report to the connected SRC.
819  **
820  **
821  ** Returns          void
822  **
823  *******************************************************************************/
bta_av_co_audio_delay(tBTA_AV_HNDL hndl,UINT16 delay)824 void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay)
825 {
826     FUNC_TRACE();
827 
828     APPL_TRACE_ERROR2("bta_av_co_audio_delay handle: x%x, delay:0x%x", hndl, delay);
829 }
830 
831 
832 
833 /*******************************************************************************
834  **
835  ** Function         bta_av_co_audio_codec_build_config
836  **
837  ** Description      Build the codec configuration
838  **
839  ** Returns          TRUE if the codec was built successfully, FALSE otherwise
840  **
841  *******************************************************************************/
bta_av_co_audio_codec_build_config(const UINT8 * p_codec_caps,UINT8 * p_codec_cfg)842 static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg)
843 {
844     FUNC_TRACE();
845 
846     memset(p_codec_cfg, 0, AVDT_CODEC_SIZE);
847 
848     switch (bta_av_co_cb.codec_cfg.id)
849     {
850     case BTIF_AV_CODEC_SBC:
851         /*  only copy the relevant portions for this codec to avoid issues when
852             comparing codec configs covering larger codec sets than SBC (7 bytes) */
853         memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg.info, BTA_AV_CO_SBC_MAX_BITPOOL_OFF+1);
854 
855         /* Update the bit pool boundaries with the codec capabilities */
856         p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF];
857         p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF];
858 
859         APPL_TRACE_EVENT2("bta_av_co_audio_codec_build_config : bitpool min %d, max %d",
860                     p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
861                     p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
862         break;
863     default:
864         APPL_TRACE_ERROR1("bta_av_co_audio_codec_build_config: unsupported codec id %d", bta_av_co_cb.codec_cfg.id);
865         return FALSE;
866         break;
867     }
868     return TRUE;
869 }
870 
871 /*******************************************************************************
872  **
873  ** Function         bta_av_co_audio_codec_cfg_matches_caps
874  **
875  ** Description      Check if a codec config matches a codec capabilities
876  **
877  ** Returns          TRUE if it codec config is supported, FALSE otherwise
878  **
879  *******************************************************************************/
bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id,const UINT8 * p_codec_caps,const UINT8 * p_codec_cfg)880 static BOOLEAN bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id, const UINT8 *p_codec_caps, const UINT8 *p_codec_cfg)
881 {
882     FUNC_TRACE();
883 
884     switch(codec_id)
885     {
886     case BTIF_AV_CODEC_SBC:
887 
888         APPL_TRACE_EVENT4("bta_av_co_audio_codec_cfg_matches_caps : min %d/%d max %d/%d",
889            p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
890            p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
891            p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF],
892            p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
893 
894         /* Must match all items exactly except bitpool boundaries which can be adjusted */
895         if (!((p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF] & p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF]) &&
896               (p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF] & p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF])))
897         {
898             APPL_TRACE_EVENT4("FALSE %x %x %x %x",
899                     p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF],
900                     p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF],
901                     p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF],
902                     p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]);
903             return FALSE;
904         }
905         break;
906 
907 
908     default:
909         APPL_TRACE_ERROR1("bta_av_co_audio_codec_cfg_matches_caps: unsupported codec id %d", codec_id);
910         return FALSE;
911         break;
912     }
913     APPL_TRACE_EVENT0("TRUE");
914 
915     return TRUE;
916 }
917 
918 /*******************************************************************************
919  **
920  ** Function         bta_av_co_audio_codec_match
921  **
922  ** Description      Check if a codec capabilities supports the codec config
923  **
924  ** Returns          TRUE if the connection supports this codec, FALSE otherwise
925  **
926  *******************************************************************************/
bta_av_co_audio_codec_match(const UINT8 * p_codec_caps)927 static BOOLEAN bta_av_co_audio_codec_match(const UINT8 *p_codec_caps)
928 {
929     FUNC_TRACE();
930 
931     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);
932 }
933 
934 /*******************************************************************************
935  **
936  ** Function         bta_av_co_audio_peer_reset_config
937  **
938  ** Description      Reset the peer codec configuration
939  **
940  ** Returns          Nothing
941  **
942  *******************************************************************************/
bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER * p_peer)943 static void bta_av_co_audio_peer_reset_config(tBTA_AV_CO_PEER *p_peer)
944 {
945     FUNC_TRACE();
946 
947     /* Indicate that there is no currently selected sink */
948     p_peer->p_snk = NULL;
949 }
950 
951 /*******************************************************************************
952  **
953  ** Function         bta_av_co_cp_is_scmst
954  **
955  ** Description      Check if a content protection service is SCMS-T
956  **
957  ** Returns          TRUE if this CP is SCMS-T, FALSE otherwise
958  **
959  *******************************************************************************/
bta_av_co_cp_is_scmst(const UINT8 * p_protectinfo)960 static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo)
961 {
962     UINT16 cp_id;
963     FUNC_TRACE();
964 
965     if (*p_protectinfo >= BTA_AV_CP_LOSC)
966     {
967         p_protectinfo++;
968         STREAM_TO_UINT16(cp_id, p_protectinfo);
969         if (cp_id == BTA_AV_CP_SCMS_T_ID)
970         {
971             APPL_TRACE_DEBUG0("bta_av_co_cp_is_scmst: SCMS-T found");
972             return TRUE;
973         }
974     }
975 
976     return FALSE;
977 }
978 
979 /*******************************************************************************
980  **
981  ** Function         bta_av_co_audio_sink_has_scmst
982  **
983  ** Description      Check if a sink supports SCMS-T
984  **
985  ** Returns          TRUE if the sink supports this CP, FALSE otherwise
986  **
987  *******************************************************************************/
bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK * p_sink)988 static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink)
989 {
990     UINT8 index;
991     const UINT8 *p;
992     FUNC_TRACE();
993 
994     /* Check if sink supports SCMS-T */
995     index = p_sink->num_protect;
996     p = &p_sink->protect_info[0];
997 
998     while (index)
999     {
1000         if (bta_av_co_cp_is_scmst(p))
1001         {
1002             return TRUE;
1003         }
1004         /* Move to the next SC */
1005         p += *p + 1;
1006         /* Decrement the SC counter */
1007         index--;
1008     }
1009     APPL_TRACE_DEBUG0("bta_av_co_audio_sink_has_scmst: SCMS-T not found");
1010     return FALSE;
1011 }
1012 
1013 /*******************************************************************************
1014  **
1015  ** Function         bta_av_co_audio_sink_supports_cp
1016  **
1017  ** Description      Check if a sink supports the current content protection
1018  **
1019  ** Returns          TRUE if the sink supports this CP, FALSE otherwise
1020  **
1021  *******************************************************************************/
bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK * p_sink)1022 static BOOLEAN bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK *p_sink)
1023 {
1024     FUNC_TRACE();
1025 
1026     /* Check if content protection is enabled for this stream */
1027     if (bta_av_co_cp_get_flag() != BTA_AV_CP_SCMS_COPY_FREE)
1028     {
1029         return bta_av_co_audio_sink_has_scmst(p_sink);
1030     }
1031     else
1032     {
1033         APPL_TRACE_DEBUG0("bta_av_co_audio_sink_supports_cp: not required");
1034         return TRUE;
1035     }
1036 }
1037 
1038 /*******************************************************************************
1039  **
1040  ** Function         bta_av_co_audio_peer_supports_codec
1041  **
1042  ** Description      Check if a connection supports the codec config
1043  **
1044  ** Returns          TRUE if the connection supports this codec, FALSE otherwise
1045  **
1046  *******************************************************************************/
bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER * p_peer,UINT8 * p_snk_index)1047 static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index)
1048 {
1049     int index;
1050     UINT8 codec_type;
1051     FUNC_TRACE();
1052 
1053     /* Configure the codec type to look for */
1054     codec_type = bta_av_co_cb.codec_cfg.id;
1055 
1056 
1057     for (index = 0; index < p_peer->num_sup_snks; index++)
1058     {
1059         if (p_peer->snks[index].codec_type == codec_type)
1060         {
1061             switch (bta_av_co_cb.codec_cfg.id)
1062             {
1063             case BTIF_AV_CODEC_SBC:
1064                 if (p_snk_index) *p_snk_index = index;
1065                 return bta_av_co_audio_codec_match(p_peer->snks[index].codec_caps);
1066                 break;
1067 
1068 
1069             default:
1070                 APPL_TRACE_ERROR1("bta_av_co_audio_peer_supports_codec: unsupported codec id %d", bta_av_co_cb.codec_cfg.id);
1071                 return FALSE;
1072                 break;
1073             }
1074         }
1075     }
1076     return FALSE;
1077 }
1078 
1079 /*******************************************************************************
1080  **
1081  ** Function         bta_av_co_audio_media_supports_config
1082  **
1083  ** Description      Check if the media source supports a given configuration
1084  **
1085  ** Returns          TRUE if the media source supports this config, FALSE otherwise
1086  **
1087  *******************************************************************************/
bta_av_co_audio_media_supports_config(UINT8 codec_type,const UINT8 * p_codec_cfg)1088 static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg)
1089 {
1090     FUNC_TRACE();
1091 
1092     switch (codec_type)
1093     {
1094     case BTA_AV_CODEC_SBC:
1095         if (bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_caps))
1096         {
1097             return FALSE;
1098         }
1099         break;
1100 
1101 
1102     default:
1103         APPL_TRACE_ERROR1("bta_av_co_audio_media_supports_config unsupported codec type %d", codec_type);
1104         return FALSE;
1105         break;
1106     }
1107     return TRUE;
1108 }
1109 
1110 /*******************************************************************************
1111  **
1112  ** Function         bta_av_co_audio_codec_supported
1113  **
1114  ** Description      Check if all opened connections are compatible with a codec
1115  **                  configuration and content protection
1116  **
1117  ** Returns          TRUE if all opened devices support this codec, FALSE otherwise
1118  **
1119  *******************************************************************************/
bta_av_co_audio_codec_supported(tBTIF_STATUS * p_status)1120 BOOLEAN bta_av_co_audio_codec_supported(tBTIF_STATUS *p_status)
1121 {
1122     UINT8 index;
1123     UINT8 snk_index;
1124     tBTA_AV_CO_PEER *p_peer;
1125     tBTA_AV_CO_SINK *p_sink;
1126     UINT8 codec_cfg[AVDT_CODEC_SIZE];
1127     UINT8 num_protect = 0;
1128 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
1129     BOOLEAN cp_active;
1130 #endif
1131 
1132     FUNC_TRACE();
1133 
1134     APPL_TRACE_DEBUG0("bta_av_co_audio_codec_supported");
1135 
1136     /* Check AV feeding is supported */
1137     *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED;
1138 
1139     for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++)
1140     {
1141         p_peer = &bta_av_co_cb.peers[index];
1142         if (p_peer->opened)
1143         {
1144             if (bta_av_co_audio_peer_supports_codec(p_peer, &snk_index))
1145             {
1146                 p_sink = &p_peer->snks[snk_index];
1147 
1148                 /* Check that this sink is compatible with the CP */
1149                 if (!bta_av_co_audio_sink_supports_cp(p_sink))
1150                 {
1151                     APPL_TRACE_DEBUG2("bta_av_co_audio_codec_supported sink %d of peer %d doesn't support cp",
1152                             snk_index, index);
1153                     *p_status = BTIF_ERROR_SRV_AV_CP_NOT_SUPPORTED;
1154                     return FALSE;
1155                 }
1156 
1157                 /* Build the codec configuration for this sink */
1158                 if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg))
1159                 {
1160 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
1161                     /* Check if this sink supports SCMS */
1162                     cp_active = bta_av_co_audio_sink_has_scmst(p_sink);
1163 #endif
1164                     /* Check if this is a new configuration (new sink or new config) */
1165                     if ((p_sink != p_peer->p_snk) ||
1166                         (memcmp(codec_cfg, p_peer->codec_cfg, AVDT_CODEC_SIZE))
1167 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
1168                         || (p_peer->cp_active != cp_active)
1169 #endif
1170                         )
1171                     {
1172                         /* Save the new configuration */
1173                         p_peer->p_snk = p_sink;
1174                         memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE);
1175 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
1176                         p_peer->cp_active = cp_active;
1177                         if (p_peer->cp_active)
1178                         {
1179                             bta_av_co_cb.cp.active = TRUE;
1180                             num_protect = BTA_AV_CP_INFO_LEN;
1181                         }
1182                         else
1183                         {
1184                             bta_av_co_cb.cp.active = FALSE;
1185                         }
1186 #endif
1187                         APPL_TRACE_DEBUG1("bta_av_co_audio_codec_supported call BTA_AvReconfig(x%x)", BTA_AV_CO_AUDIO_INDX_TO_HNDL(index));
1188                         BTA_AvReconfig(BTA_AV_CO_AUDIO_INDX_TO_HNDL(index), TRUE, p_sink->sep_info_idx,
1189                                 p_peer->codec_cfg, num_protect, (UINT8 *)bta_av_co_cp_scmst);
1190                     }
1191                 }
1192             }
1193             else
1194             {
1195                 APPL_TRACE_DEBUG1("bta_av_co_audio_codec_supported index %d doesn't support codec", index);
1196                 return FALSE;
1197             }
1198         }
1199     }
1200 
1201     *p_status = BTIF_SUCCESS;
1202     return TRUE;
1203 }
1204 
1205 /*******************************************************************************
1206  **
1207  ** Function         bta_av_co_audio_codec_reset
1208  **
1209  ** Description      Reset the current codec configuration
1210  **
1211  ** Returns          void
1212  **
1213  *******************************************************************************/
bta_av_co_audio_codec_reset(void)1214 void bta_av_co_audio_codec_reset(void)
1215 {
1216     GKI_disable();
1217     FUNC_TRACE();
1218 
1219     /* Reset the current configuration to SBC */
1220     bta_av_co_cb.codec_cfg.id = BTIF_AV_CODEC_SBC;
1221 
1222     if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_SBC_CIE *)&btif_av_sbc_default_config, bta_av_co_cb.codec_cfg.info) != A2D_SUCCESS)
1223     {
1224         APPL_TRACE_ERROR0("bta_av_co_audio_codec_reset A2D_BldSbcInfo failed");
1225     }
1226 
1227     GKI_enable();
1228 }
1229 
1230 /*******************************************************************************
1231  **
1232  ** Function         bta_av_co_audio_set_codec
1233  **
1234  ** Description      Set the current codec configuration from the feeding type.
1235  **                  This function is starting to modify the configuration, it
1236  **                  should be protected.
1237  **
1238  ** Returns          TRUE if successful, FALSE otherwise
1239  **
1240  *******************************************************************************/
bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS * p_feeding,tBTIF_STATUS * p_status)1241 BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTIF_STATUS *p_status)
1242 {
1243     tA2D_SBC_CIE sbc_config;
1244     tBTIF_AV_CODEC_INFO new_cfg;
1245 
1246     FUNC_TRACE();
1247 
1248     /* Check AV feeding is supported */
1249     *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED;
1250 
1251     APPL_TRACE_DEBUG1("bta_av_co_audio_set_codec cid=%d", p_feeding->format);
1252 
1253     /* Supported codecs */
1254     switch (p_feeding->format)
1255     {
1256     case BTIF_AV_CODEC_PCM:
1257         new_cfg.id = BTIF_AV_CODEC_SBC;
1258 
1259         sbc_config = btif_av_sbc_default_config;
1260         if ((p_feeding->cfg.pcm.num_channel != 1) &&
1261             (p_feeding->cfg.pcm.num_channel != 2))
1262         {
1263             APPL_TRACE_ERROR0("bta_av_co_audio_set_codec PCM channel number unsupported");
1264             return FALSE;
1265         }
1266         if ((p_feeding->cfg.pcm.bit_per_sample != 8) &&
1267             (p_feeding->cfg.pcm.bit_per_sample != 16))
1268         {
1269             APPL_TRACE_ERROR0("bta_av_co_audio_set_codec PCM sample size unsupported");
1270             return FALSE;
1271         }
1272         switch (p_feeding->cfg.pcm.sampling_freq)
1273         {
1274         case 8000:
1275         case 12000:
1276         case 16000:
1277         case 24000:
1278         case 32000:
1279         case 48000:
1280             sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_48;
1281             break;
1282 
1283         case 11025:
1284         case 22050:
1285         case 44100:
1286             sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_44;
1287             break;
1288         default:
1289             APPL_TRACE_ERROR0("bta_av_co_audio_set_codec PCM sampling frequency unsupported");
1290             return FALSE;
1291             break;
1292         }
1293         /* Build the codec config */
1294         if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, &sbc_config, new_cfg.info) != A2D_SUCCESS)
1295         {
1296             APPL_TRACE_ERROR0("bta_av_co_audio_set_codec A2D_BldSbcInfo failed");
1297             return FALSE;
1298         }
1299         break;
1300 
1301 
1302     default:
1303         APPL_TRACE_ERROR0("bta_av_co_audio_set_codec Feeding format unsupported");
1304         return FALSE;
1305         break;
1306     }
1307 
1308     /* The new config was correctly built */
1309     bta_av_co_cb.codec_cfg = new_cfg;
1310 
1311 
1312     /* Check all devices support it */
1313     *p_status = BTIF_SUCCESS;
1314     return bta_av_co_audio_codec_supported(p_status);
1315 }
1316 
1317 /*******************************************************************************
1318  **
1319  ** Function         bta_av_co_audio_get_sbc_config
1320  **
1321  ** Description      Retrieves the SBC codec configuration.  If the codec in use
1322  **                  is not SBC, return the default SBC codec configuration.
1323  **
1324  ** Returns          TRUE if codec is SBC, FALSE otherwise
1325  **
1326  *******************************************************************************/
bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE * p_sbc_config,UINT16 * p_minmtu)1327 BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu)
1328 {
1329     BOOLEAN result = FALSE;
1330     UINT8 index, jndex;
1331     tBTA_AV_CO_PEER *p_peer;
1332     tBTA_AV_CO_SINK *p_sink;
1333 
1334     APPL_TRACE_EVENT1("bta_av_co_cb.codec_cfg.id : codec 0x%x", bta_av_co_cb.codec_cfg.id);
1335 
1336     /* Minimum MTU is by default very large */
1337     *p_minmtu = 0xFFFF;
1338 
1339     GKI_disable();
1340     if (bta_av_co_cb.codec_cfg.id == BTIF_AV_CODEC_SBC)
1341     {
1342         if (A2D_ParsSbcInfo(p_sbc_config, bta_av_co_cb.codec_cfg.info, FALSE) == A2D_SUCCESS)
1343         {
1344             for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++)
1345             {
1346                 p_peer = &bta_av_co_cb.peers[index];
1347                 if (p_peer->opened)
1348                 {
1349                     if (p_peer->mtu < *p_minmtu)
1350                     {
1351                         *p_minmtu = p_peer->mtu;
1352                     }
1353                     for (jndex = 0; jndex < p_peer->num_sup_snks; jndex++)
1354                     {
1355                         p_sink = &p_peer->snks[jndex];
1356                         if (p_sink->codec_type == A2D_MEDIA_CT_SBC)
1357                         {
1358                             /* Update the bitpool boundaries of the current config */
1359                             p_sbc_config->min_bitpool =
1360                                BTA_AV_CO_MAX(p_sink->codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
1361                                              p_sbc_config->min_bitpool);
1362                             p_sbc_config->max_bitpool =
1363                                BTA_AV_CO_MIN(p_sink->codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF],
1364                                              p_sbc_config->max_bitpool);
1365                             APPL_TRACE_EVENT2("bta_av_co_audio_get_sbc_config : sink bitpool min %d, max %d",
1366                                  p_sbc_config->min_bitpool, p_sbc_config->max_bitpool);
1367                             break;
1368                         }
1369                     }
1370                 }
1371             }
1372             result = TRUE;
1373         }
1374     }
1375 
1376     if (!result)
1377     {
1378         /* Not SBC, still return the default values */
1379         *p_sbc_config = btif_av_sbc_default_config;
1380     }
1381     GKI_enable();
1382 
1383     return result;
1384 }
1385 
1386 /*******************************************************************************
1387  **
1388  ** Function         bta_av_co_audio_discard_config
1389  **
1390  ** Description      Discard the codec configuration of a connection
1391  **
1392  ** Returns          Nothing
1393  **
1394  *******************************************************************************/
bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl)1395 void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl)
1396 {
1397     tBTA_AV_CO_PEER *p_peer;
1398 
1399     FUNC_TRACE();
1400 
1401     /* Find the peer info */
1402     p_peer = bta_av_co_get_peer(hndl);
1403     if (p_peer == NULL)
1404     {
1405         APPL_TRACE_ERROR0("bta_av_co_audio_discard_config could not find peer entry");
1406         return;
1407     }
1408 
1409     /* Reset the peer codec configuration */
1410     bta_av_co_audio_peer_reset_config(p_peer);
1411 }
1412 
1413 /*******************************************************************************
1414  **
1415  ** Function         bta_av_co_init
1416  **
1417  ** Description      Initialization
1418  **
1419  ** Returns          Nothing
1420  **
1421  *******************************************************************************/
bta_av_co_init(void)1422 void bta_av_co_init(void)
1423 {
1424     FUNC_TRACE();
1425 
1426     /* Reset the control block */
1427     memset(&bta_av_co_cb, 0, sizeof(bta_av_co_cb));
1428 
1429     bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE;
1430 
1431 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
1432     bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_NEVER);
1433 #else
1434     bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_FREE);
1435 #endif
1436 
1437     /* Reset the current config */
1438     bta_av_co_audio_codec_reset();
1439 }
1440 
1441 
1442 /*******************************************************************************
1443  **
1444  ** Function         bta_av_co_peer_cp_supported
1445  **
1446  ** Description      Checks if the peer supports CP
1447  **
1448  ** Returns          TRUE if the peer supports CP
1449  **
1450  *******************************************************************************/
bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl)1451 BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl)
1452 {
1453     tBTA_AV_CO_PEER *p_peer;
1454     tBTA_AV_CO_SINK *p_sink;
1455     UINT8 index;
1456 
1457     FUNC_TRACE();
1458 
1459     /* Find the peer info */
1460     p_peer = bta_av_co_get_peer(hndl);
1461     if (p_peer == NULL)
1462     {
1463         APPL_TRACE_ERROR0("bta_av_co_peer_cp_supported could not find peer entry");
1464         return FALSE;
1465     }
1466 
1467     for (index = 0; index < p_peer->num_sup_snks; index++)
1468     {
1469         p_sink = &p_peer->snks[index];
1470         if (p_sink->codec_type == A2D_MEDIA_CT_SBC)
1471         {
1472             return bta_av_co_audio_sink_has_scmst(p_sink);
1473         }
1474     }
1475     APPL_TRACE_ERROR0("bta_av_co_peer_cp_supported did not find SBC sink");
1476     return FALSE;
1477 }
1478 
1479 
1480 /*******************************************************************************
1481  **
1482  ** Function         bta_av_co_get_remote_bitpool_pref
1483  **
1484  ** Description      Check if remote side did a setconfig within the limits
1485  **                  of our exported bitpool range. If set we will set the
1486  **                  remote preference.
1487  **
1488  ** Returns          TRUE if config set, FALSE otherwize
1489  **
1490  *******************************************************************************/
1491 
bta_av_co_get_remote_bitpool_pref(UINT8 * min,UINT8 * max)1492 BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max)
1493 {
1494     /* check if remote peer did a set config */
1495     if (bta_av_co_cb.codec_cfg_setconfig.id == BTIF_AV_CODEC_NONE)
1496         return FALSE;
1497 
1498     *min = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF];
1499     *max = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF];
1500 
1501     return TRUE;
1502 }
1503 
1504 
1505