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