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