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