• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2004-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This is the advanced audio/video call-out function implementation for
22  *  BTIF.
23  *
24  ******************************************************************************/
25 
26 #include "bta_av_co.h"
27 #include <base/logging.h>
28 #include <string.h>
29 #include "a2dp_api.h"
30 #include "a2dp_sbc.h"
31 #include "bt_target.h"
32 #include "bta_av_api.h"
33 #include "bta_av_ci.h"
34 #include "bta_sys.h"
35 
36 #include "btif_av.h"
37 #include "btif_av_co.h"
38 #include "btif_util.h"
39 #include "osi/include/mutex.h"
40 #include "osi/include/osi.h"
41 
42 /*****************************************************************************
43  **  Constants
44  *****************************************************************************/
45 
46 /* Macro to retrieve the number of elements in a statically allocated array */
47 #define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0]))
48 
49 /* Macro to convert audio handle to index and vice versa */
50 #define BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl) (((hndl) & (~BTA_AV_CHNL_MSK)) - 1)
51 #define BTA_AV_CO_AUDIO_INDX_TO_HNDL(indx) (((indx) + 1) | BTA_AV_CHNL_AUDIO)
52 
53 /* SCMS-T protect info */
54 const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00};
55 
56 /*****************************************************************************
57  *  Local data
58  ****************************************************************************/
59 typedef struct {
60   uint8_t sep_info_idx;                   /* local SEP index (in BTA tables) */
61   uint8_t seid;                           /* peer SEP index (in peer tables) */
62   uint8_t codec_caps[AVDT_CODEC_SIZE];    /* peer SEP codec capabilities */
63   uint8_t num_protect;                    /* peer SEP number of CP elements */
64   uint8_t protect_info[AVDT_CP_INFO_LEN]; /* peer SEP content protection info */
65 } tBTA_AV_CO_SINK;
66 
67 typedef struct {
68   RawAddress addr; /* address of audio/video peer */
69   tBTA_AV_CO_SINK
70       sinks[BTAV_A2DP_CODEC_INDEX_MAX]; /* array of supported sinks */
71   tBTA_AV_CO_SINK srcs[BTAV_A2DP_CODEC_INDEX_MAX]; /* array of supported srcs */
72   uint8_t num_sinks;     /* total number of sinks at peer */
73   uint8_t num_srcs;      /* total number of srcs at peer */
74   uint8_t num_seps;      /* total number of seids at peer */
75   uint8_t num_rx_sinks;  /* number of received sinks */
76   uint8_t num_rx_srcs;   /* number of received srcs */
77   uint8_t num_sup_sinks; /* number of supported sinks in the sinks array */
78   uint8_t num_sup_srcs;  /* number of supported srcs in the srcs array */
79   const tBTA_AV_CO_SINK* p_sink;         /* currently selected sink */
80   const tBTA_AV_CO_SINK* p_src;          /* currently selected src */
81   uint8_t codec_config[AVDT_CODEC_SIZE]; /* current codec configuration */
82   bool cp_active;                        /* current CP configuration */
83   bool acp;                              /* acceptor */
84   bool reconfig_needed;                  /* reconfiguration is needed */
85   bool opened;                           /* opened */
86   uint16_t mtu;                          /* maximum transmit unit size */
87   uint16_t uuid_to_connect;              /* uuid of peer device */
88   tBTA_AV_HNDL handle;                   /* handle to use */
89 } tBTA_AV_CO_PEER;
90 
91 typedef struct {
92   bool active;
93   uint8_t flag;
94 } tBTA_AV_CO_CP;
95 
96 class BtaAvCoCb {
97  public:
BtaAvCoCb()98   BtaAvCoCb() : codecs(nullptr) { reset(); }
99 
100   /* Connected peer information */
101   tBTA_AV_CO_PEER peers[BTA_AV_NUM_STRS];
102   /* Current codec configuration - access to this variable must be protected */
103   uint8_t codec_config[AVDT_CODEC_SIZE];
104   A2dpCodecs* codecs; /* Locally supported codecs */
105   tBTA_AV_CO_CP cp;
106 
reset()107   void reset() {
108     delete codecs;
109     codecs = nullptr;
110     // TODO: Ugly leftover reset from the original C code. Should go away once
111     // the rest of the code in this file migrates to C++.
112     memset(peers, 0, sizeof(peers));
113     memset(codec_config, 0, sizeof(codec_config));
114     memset(&cp, 0, sizeof(cp));
115 
116     // Initialize the handles
117     for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers); i++) {
118       tBTA_AV_CO_PEER* p_peer = &peers[i];
119       p_peer->handle = BTA_AV_CO_AUDIO_INDX_TO_HNDL(i);
120     }
121   }
122 };
123 
124 /* Control block instance */
125 static BtaAvCoCb bta_av_co_cb;
126 
127 static bool bta_av_co_cp_is_scmst(const uint8_t* p_protect_info);
128 static bool bta_av_co_audio_protect_has_scmst(uint8_t num_protect,
129                                               const uint8_t* p_protect_info);
130 static const tBTA_AV_CO_SINK* bta_av_co_find_peer_src_supports_codec(
131     const tBTA_AV_CO_PEER* p_peer);
132 static tBTA_AV_CO_SINK* bta_av_co_audio_set_codec(tBTA_AV_CO_PEER* p_peer);
133 static tBTA_AV_CO_SINK* bta_av_co_audio_codec_selected(
134     A2dpCodecConfig& codec_config, tBTA_AV_CO_PEER* p_peer);
135 static bool bta_av_co_audio_update_selectable_codec(
136     A2dpCodecConfig& codec_config, const tBTA_AV_CO_PEER* p_peer);
137 static void bta_av_co_save_new_codec_config(tBTA_AV_CO_PEER* p_peer,
138                                             const uint8_t* new_codec_config,
139                                             uint8_t num_protect,
140                                             const uint8_t* p_protect_info);
141 static bool bta_av_co_set_codec_ota_config(tBTA_AV_CO_PEER* p_peer,
142                                            const uint8_t* p_ota_codec_config,
143                                            uint8_t num_protect,
144                                            const uint8_t* p_protect_info,
145                                            bool* p_restart_output);
146 
147 /*******************************************************************************
148  **
149  ** Function         bta_av_co_cp_get_flag
150  **
151  ** Description      Get content protection flag
152  **                  AVDT_CP_SCMS_COPY_NEVER
153  **                  AVDT_CP_SCMS_COPY_ONCE
154  **                  AVDT_CP_SCMS_COPY_FREE
155  **
156  ** Returns          The current flag value
157  **
158  ******************************************************************************/
bta_av_co_cp_get_flag(void)159 static uint8_t bta_av_co_cp_get_flag(void) { return bta_av_co_cb.cp.flag; }
160 
161 /*******************************************************************************
162  **
163  ** Function         bta_av_co_cp_set_flag
164  **
165  ** Description      Set content protection flag
166  **                  AVDT_CP_SCMS_COPY_NEVER
167  **                  AVDT_CP_SCMS_COPY_ONCE
168  **                  AVDT_CP_SCMS_COPY_FREE
169  **
170  ** Returns          true if setting the SCMS flag is supported else false
171  **
172  ******************************************************************************/
bta_av_co_cp_set_flag(uint8_t cp_flag)173 static bool bta_av_co_cp_set_flag(uint8_t cp_flag) {
174   APPL_TRACE_DEBUG("%s: cp_flag = %d", __func__, cp_flag);
175 
176 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
177 #else
178   if (cp_flag != AVDT_CP_SCMS_COPY_FREE) {
179     return false;
180   }
181 #endif
182   bta_av_co_cb.cp.flag = cp_flag;
183   return true;
184 }
185 
186 /*******************************************************************************
187  **
188  ** Function         bta_av_co_get_peer
189  **
190  ** Description      find the peer entry for a given handle
191  **
192  ** Returns          the control block
193  **
194  ******************************************************************************/
bta_av_co_get_peer(tBTA_AV_HNDL hndl)195 static tBTA_AV_CO_PEER* bta_av_co_get_peer(tBTA_AV_HNDL hndl) {
196   uint8_t index;
197 
198   index = BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl);
199 
200   APPL_TRACE_DEBUG("%s: handle = %d index = %d", __func__, hndl, index);
201 
202   /* Sanity check */
203   if (index >= BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers)) {
204     APPL_TRACE_ERROR("%s: peer index out of bounds: %d", __func__, index);
205     return NULL;
206   }
207 
208   return &bta_av_co_cb.peers[index];
209 }
210 
211 /*******************************************************************************
212  **
213  ** Function         bta_av_co_audio_init
214  **
215  ** Description      This callout function is executed by AV when it is
216  **                  started by calling BTA_AvRegister().  This function can be
217  **                  used by the phone to initialize audio paths or for other
218  **                  initialization purposes.
219  **
220  **
221  ** Returns          Stream codec and content protection capabilities info.
222  **
223  ******************************************************************************/
bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,tAVDT_CFG * p_cfg)224 bool bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,
225                           tAVDT_CFG* p_cfg) {
226   return A2DP_InitCodecConfig(codec_index, p_cfg);
227 }
228 
229 /*******************************************************************************
230  **
231  ** Function         bta_av_co_audio_disc_res
232  **
233  ** Description      This callout function is executed by AV to report the
234  **                  number of stream end points (SEP) were found during the
235  **                  AVDT stream discovery process.
236  **
237  **
238  ** Returns          void.
239  **
240  ******************************************************************************/
bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl,uint8_t num_seps,uint8_t num_sink,uint8_t num_src,const RawAddress & addr,uint16_t uuid_local)241 void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, uint8_t num_seps,
242                               uint8_t num_sink, uint8_t num_src,
243                               const RawAddress& addr, uint16_t uuid_local) {
244   tBTA_AV_CO_PEER* p_peer;
245 
246   APPL_TRACE_DEBUG("%s: h:x%x num_seps:%d num_sink:%d num_src:%d", __func__,
247                    hndl, num_seps, num_sink, num_src);
248 
249   /* Find the peer info */
250   p_peer = bta_av_co_get_peer(hndl);
251   if (p_peer == NULL) {
252     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
253     return;
254   }
255 
256   /* Sanity check : this should never happen */
257   if (p_peer->opened) {
258     APPL_TRACE_ERROR("%s: peer already opened", __func__);
259   }
260 
261   /* Copy the discovery results */
262   p_peer->addr = addr;
263   p_peer->num_sinks = num_sink;
264   p_peer->num_srcs = num_src;
265   p_peer->num_seps = num_seps;
266   p_peer->num_rx_sinks = 0;
267   p_peer->num_rx_srcs = 0;
268   p_peer->num_sup_sinks = 0;
269   if (uuid_local == UUID_SERVCLASS_AUDIO_SINK)
270     p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SOURCE;
271   else if (uuid_local == UUID_SERVCLASS_AUDIO_SOURCE)
272     p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SINK;
273 }
274 
275 /*******************************************************************************
276  **
277  ** Function         bta_av_audio_sink_getconfig
278  **
279  ** Description      This callout function is executed by AV to retrieve the
280  **                  desired codec and content protection configuration for the
281  **                  A2DP Sink audio stream in Initiator.
282  **
283  **
284  ** Returns          Pass or Fail for current getconfig.
285  **
286  ******************************************************************************/
bta_av_audio_sink_getconfig(tBTA_AV_HNDL hndl,uint8_t * p_codec_info,uint8_t * p_sep_info_idx,uint8_t seid,uint8_t * p_num_protect,uint8_t * p_protect_info)287 static tA2DP_STATUS bta_av_audio_sink_getconfig(
288     tBTA_AV_HNDL hndl, uint8_t* p_codec_info, uint8_t* p_sep_info_idx,
289     uint8_t seid, uint8_t* p_num_protect, uint8_t* p_protect_info) {
290   tA2DP_STATUS result = A2DP_FAIL;
291   tBTA_AV_CO_PEER* p_peer;
292 
293   APPL_TRACE_DEBUG("%s: handle:0x%x codec:%s seid:%d", __func__, hndl,
294                    A2DP_CodecName(p_codec_info), seid);
295   APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
296                    __func__, *p_num_protect, p_protect_info[0],
297                    p_protect_info[1], p_protect_info[2]);
298 
299   /* Retrieve the peer info */
300   p_peer = bta_av_co_get_peer(hndl);
301   if (p_peer == NULL) {
302     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
303     return A2DP_FAIL;
304   }
305 
306   APPL_TRACE_DEBUG("%s: peer(o=%d,n_sinks=%d,n_rx_sinks=%d,n_sup_sinks=%d)",
307                    __func__, p_peer->opened, p_peer->num_srcs,
308                    p_peer->num_rx_srcs, p_peer->num_sup_srcs);
309 
310   p_peer->num_rx_srcs++;
311 
312   /* Check the peer's SOURCE codec */
313   if (A2DP_IsPeerSourceCodecValid(p_codec_info)) {
314     /* If there is room for a new one */
315     if (p_peer->num_sup_srcs < BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs)) {
316       tBTA_AV_CO_SINK* p_src = &p_peer->srcs[p_peer->num_sup_srcs++];
317 
318       APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
319                        p_codec_info[1], p_codec_info[2], p_codec_info[3],
320                        p_codec_info[4], p_codec_info[5], p_codec_info[6]);
321 
322       memcpy(p_src->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
323       p_src->sep_info_idx = *p_sep_info_idx;
324       p_src->seid = seid;
325       p_src->num_protect = *p_num_protect;
326       memcpy(p_src->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
327     } else {
328       APPL_TRACE_ERROR("%s: no more room for SRC info", __func__);
329     }
330   }
331 
332   /* If last SINK get capabilities or all supported codec caps retrieved */
333   if ((p_peer->num_rx_srcs == p_peer->num_srcs) ||
334       (p_peer->num_sup_srcs == BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs))) {
335     APPL_TRACE_DEBUG("%s: last SRC reached", __func__);
336 
337     /* Protect access to bta_av_co_cb.codec_config */
338     mutex_global_lock();
339 
340     /* Find a src that matches the codec config */
341     const tBTA_AV_CO_SINK* p_src =
342         bta_av_co_find_peer_src_supports_codec(p_peer);
343     if (p_src != NULL) {
344       uint8_t pref_config[AVDT_CODEC_SIZE];
345       APPL_TRACE_DEBUG("%s: codec supported", __func__);
346 
347       /* Build the codec configuration for this sink */
348       /* Save the new configuration */
349       p_peer->p_src = p_src;
350       /* get preferred config from src_caps */
351       if (A2DP_BuildSrc2SinkConfig(p_src->codec_caps, pref_config) !=
352           A2DP_SUCCESS) {
353         mutex_global_unlock();
354         return A2DP_FAIL;
355       }
356       memcpy(p_peer->codec_config, pref_config, AVDT_CODEC_SIZE);
357 
358       APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
359                        p_peer->codec_config[1], p_peer->codec_config[2],
360                        p_peer->codec_config[3], p_peer->codec_config[4],
361                        p_peer->codec_config[5], p_peer->codec_config[6]);
362       /* By default, no content protection */
363       *p_num_protect = 0;
364 
365 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
366       p_peer->cp_active = false;
367       bta_av_co_cb.cp.active = false;
368 #endif
369 
370       *p_sep_info_idx = p_src->sep_info_idx;
371       memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
372       result = A2DP_SUCCESS;
373     }
374     /* Protect access to bta_av_co_cb.codec_config */
375     mutex_global_unlock();
376   }
377   return result;
378 }
379 /*******************************************************************************
380  **
381  ** Function         bta_av_co_audio_getconfig
382  **
383  ** Description      This callout function is executed by AV to retrieve the
384  **                  desired codec and content protection configuration for the
385  **                  audio stream.
386  **
387  **
388  ** Returns          Stream codec and content protection configuration info.
389  **
390  ******************************************************************************/
bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl,uint8_t * p_codec_info,uint8_t * p_sep_info_idx,uint8_t seid,uint8_t * p_num_protect,uint8_t * p_protect_info)391 tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, uint8_t* p_codec_info,
392                                        uint8_t* p_sep_info_idx, uint8_t seid,
393                                        uint8_t* p_num_protect,
394                                        uint8_t* p_protect_info) {
395   tBTA_AV_CO_PEER* p_peer;
396 
397   APPL_TRACE_DEBUG("%s", __func__);
398   A2DP_DumpCodecInfo(p_codec_info);
399 
400   /* Retrieve the peer info */
401   p_peer = bta_av_co_get_peer(hndl);
402   if (p_peer == NULL) {
403     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
404     return A2DP_FAIL;
405   }
406 
407   if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) {
408     return bta_av_audio_sink_getconfig(hndl, p_codec_info, p_sep_info_idx, seid,
409                                        p_num_protect, p_protect_info);
410   }
411   APPL_TRACE_DEBUG("%s: handle:0x%x codec:%s seid:%d", __func__, hndl,
412                    A2DP_CodecName(p_codec_info), seid);
413   APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
414                    __func__, *p_num_protect, p_protect_info[0],
415                    p_protect_info[1], p_protect_info[2]);
416   APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)",
417                    __func__, p_peer->opened, p_peer->num_sinks,
418                    p_peer->num_rx_sinks, p_peer->num_sup_sinks);
419 
420   p_peer->num_rx_sinks++;
421 
422   /* Check the peer's SINK codec */
423   if (A2DP_IsPeerSinkCodecValid(p_codec_info)) {
424     /* If there is room for a new one */
425     if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) {
426       tBTA_AV_CO_SINK* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++];
427 
428       APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
429                        p_codec_info[1], p_codec_info[2], p_codec_info[3],
430                        p_codec_info[4], p_codec_info[5], p_codec_info[6]);
431 
432       memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
433       p_sink->sep_info_idx = *p_sep_info_idx;
434       p_sink->seid = seid;
435       p_sink->num_protect = *p_num_protect;
436       memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
437     } else {
438       APPL_TRACE_ERROR("%s: no more room for SINK info", __func__);
439     }
440   }
441 
442   // Check if this is the last SINK get capabilities or all supported codec
443   // capabilities are retrieved.
444   if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
445       (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
446     return A2DP_FAIL;
447   }
448   APPL_TRACE_DEBUG("%s: last sink reached", __func__);
449 
450   const tBTA_AV_CO_SINK* p_sink = bta_av_co_audio_set_codec(p_peer);
451   if (p_sink == NULL) {
452     APPL_TRACE_ERROR("%s: cannot set up codec for the peer SINK", __func__);
453     return A2DP_FAIL;
454   }
455 
456   // By default, no content protection
457   *p_num_protect = 0;
458 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
459   if (p_peer->cp_active) {
460     *p_num_protect = AVDT_CP_INFO_LEN;
461     memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
462   }
463 #endif
464 
465   // If acceptor -> reconfig otherwise reply for configuration.
466   if (p_peer->acp) {
467     // Stop fetching caps once we retrieved a supported codec.
468     APPL_TRACE_EVENT("%s: no need to fetch more SEPs", __func__);
469     *p_sep_info_idx = p_peer->num_seps;
470     if (p_peer->reconfig_needed) {
471       APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, hndl);
472       BTA_AvReconfig(hndl, true, p_sink->sep_info_idx, p_peer->codec_config,
473                      *p_num_protect, bta_av_co_cp_scmst);
474     }
475   } else {
476     *p_sep_info_idx = p_sink->sep_info_idx;
477     memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
478   }
479 
480   return A2DP_SUCCESS;
481 }
482 
483 /*******************************************************************************
484  **
485  ** Function         bta_av_co_audio_setconfig
486  **
487  ** Description      This callout function is executed by AV to set the codec
488  **                  and content protection configuration of the audio stream.
489  **
490  **
491  ** Returns          void
492  **
493  ******************************************************************************/
bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl,const uint8_t * p_codec_info,UNUSED_ATTR uint8_t seid,UNUSED_ATTR const RawAddress & addr,uint8_t num_protect,const uint8_t * p_protect_info,uint8_t t_local_sep,uint8_t avdt_handle)494 void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, const uint8_t* p_codec_info,
495                                UNUSED_ATTR uint8_t seid,
496                                UNUSED_ATTR const RawAddress& addr,
497                                uint8_t num_protect,
498                                const uint8_t* p_protect_info,
499                                uint8_t t_local_sep, uint8_t avdt_handle) {
500   tBTA_AV_CO_PEER* p_peer;
501   tA2DP_STATUS status = A2DP_SUCCESS;
502   uint8_t category = A2DP_SUCCESS;
503   bool reconfig_needed = false;
504 
505   APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
506                    p_codec_info[1], p_codec_info[2], p_codec_info[3],
507                    p_codec_info[4], p_codec_info[5], p_codec_info[6]);
508   APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x",
509                    num_protect, p_protect_info[0], p_protect_info[1],
510                    p_protect_info[2]);
511   A2DP_DumpCodecInfo(p_codec_info);
512 
513   /* Retrieve the peer info */
514   p_peer = bta_av_co_get_peer(hndl);
515   if (p_peer == NULL) {
516     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
517     /* Call call-in rejecting the configuration */
518     bta_av_ci_setconfig(hndl, A2DP_BUSY, AVDT_ASC_CODEC, 0, NULL, false,
519                         avdt_handle);
520     return;
521   }
522 
523   APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)",
524                    __func__, p_peer->opened, p_peer->num_sinks,
525                    p_peer->num_rx_sinks, p_peer->num_sup_sinks);
526 
527   /* Sanity check: should not be opened at this point */
528   if (p_peer->opened) {
529     APPL_TRACE_ERROR("%s: peer already in use", __func__);
530   }
531 
532   if (num_protect != 0) {
533 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
534     /* If CP is supported */
535     if ((num_protect != 1) ||
536         (bta_av_co_cp_is_scmst(p_protect_info) == false)) {
537       APPL_TRACE_ERROR("%s: wrong CP configuration", __func__);
538       status = A2DP_BAD_CP_TYPE;
539       category = AVDT_ASC_PROTECT;
540     }
541 #else
542     /* Do not support content protection for the time being */
543     APPL_TRACE_ERROR("%s: wrong CP configuration", __func__);
544     status = A2DP_BAD_CP_TYPE;
545     category = AVDT_ASC_PROTECT;
546 #endif
547   }
548 
549   if (status == A2DP_SUCCESS) {
550     bool codec_config_supported = false;
551 
552     if (t_local_sep == AVDT_TSEP_SNK) {
553       APPL_TRACE_DEBUG("%s: peer is A2DP SRC", __func__);
554       codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info);
555       if (codec_config_supported) {
556         // If Peer is SRC, and our config subset matches with what is
557         // requested by peer, then just accept what peer wants.
558         bta_av_co_save_new_codec_config(p_peer, p_codec_info, num_protect,
559                                         p_protect_info);
560       }
561     }
562     if (t_local_sep == AVDT_TSEP_SRC) {
563       APPL_TRACE_DEBUG("%s: peer is A2DP SINK", __func__);
564       bool restart_output = false;
565       if ((bta_av_co_cb.codecs == nullptr) ||
566           !bta_av_co_set_codec_ota_config(p_peer, p_codec_info, num_protect,
567                                           p_protect_info, &restart_output)) {
568         APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__,
569                          A2DP_CodecName(p_codec_info));
570       } else {
571         codec_config_supported = true;
572         // Check if reconfiguration is needed
573         if (restart_output ||
574             ((num_protect == 1) && (!bta_av_co_cb.cp.active))) {
575           reconfig_needed = true;
576         }
577       }
578     }
579 
580     /* Check if codec configuration is supported */
581     if (!codec_config_supported) {
582       category = AVDT_ASC_CODEC;
583       status = A2DP_WRONG_CODEC;
584     }
585   }
586 
587   if (status != A2DP_SUCCESS) {
588     APPL_TRACE_DEBUG("%s: reject s=%d c=%d", __func__, status, category);
589     /* Call call-in rejecting the configuration */
590     bta_av_ci_setconfig(hndl, status, category, 0, NULL, false, avdt_handle);
591     return;
592   }
593 
594   /* Mark that this is an acceptor peer */
595   p_peer->acp = true;
596   p_peer->reconfig_needed = reconfig_needed;
597   APPL_TRACE_DEBUG("%s: accept reconf=%d", __func__, reconfig_needed);
598   /* Call call-in accepting the configuration */
599   bta_av_ci_setconfig(hndl, A2DP_SUCCESS, A2DP_SUCCESS, 0, NULL,
600                       reconfig_needed, avdt_handle);
601 }
602 
603 /*******************************************************************************
604  **
605  ** Function         bta_av_co_audio_open
606  **
607  ** Description      This function is called by AV when the audio stream
608  **                  connection is opened.
609  **
610  **
611  ** Returns          void
612  **
613  ******************************************************************************/
bta_av_co_audio_open(tBTA_AV_HNDL hndl,uint16_t mtu)614 void bta_av_co_audio_open(tBTA_AV_HNDL hndl, uint16_t mtu) {
615   tBTA_AV_CO_PEER* p_peer;
616 
617   APPL_TRACE_DEBUG("%s: handle: %d mtu:%d", __func__, hndl, mtu);
618 
619   /* Retrieve the peer info */
620   p_peer = bta_av_co_get_peer(hndl);
621   if (p_peer == NULL) {
622     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
623   } else {
624     p_peer->opened = true;
625     p_peer->mtu = mtu;
626   }
627 }
628 
629 /*******************************************************************************
630  **
631  ** Function         bta_av_co_audio_close
632  **
633  ** Description      This function is called by AV when the audio stream
634  **                  connection is closed.
635  **
636  **
637  ** Returns          void
638  **
639  ******************************************************************************/
bta_av_co_audio_close(tBTA_AV_HNDL hndl)640 void bta_av_co_audio_close(tBTA_AV_HNDL hndl) {
641   tBTA_AV_CO_PEER* p_peer;
642 
643   APPL_TRACE_DEBUG("%s", __func__);
644 
645   /* Retrieve the peer info */
646   p_peer = bta_av_co_get_peer(hndl);
647   if (p_peer) {
648     /* Mark the peer closed and clean the peer info */
649     memset(p_peer, 0, sizeof(*p_peer));
650   } else {
651     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
652   }
653 }
654 
655 /*******************************************************************************
656  **
657  ** Function         bta_av_co_audio_start
658  **
659  ** Description      This function is called by AV when the audio streaming data
660  **                  transfer is started.
661  **
662  **
663  ** Returns          void
664  **
665  ******************************************************************************/
bta_av_co_audio_start(UNUSED_ATTR tBTA_AV_HNDL hndl,UNUSED_ATTR uint8_t * p_codec_info,UNUSED_ATTR bool * p_no_rtp_hdr)666 void bta_av_co_audio_start(UNUSED_ATTR tBTA_AV_HNDL hndl,
667                            UNUSED_ATTR uint8_t* p_codec_info,
668                            UNUSED_ATTR bool* p_no_rtp_hdr) {
669   APPL_TRACE_DEBUG("%s", __func__);
670 }
671 
672 /*******************************************************************************
673  **
674  ** Function         bta_av_co_audio_stop
675  **
676  ** Description      This function is called by AV when the audio streaming data
677  **                  transfer is stopped.
678  **
679  **
680  ** Returns          void
681  **
682  ******************************************************************************/
bta_av_co_audio_stop(UNUSED_ATTR tBTA_AV_HNDL hndl)683 void bta_av_co_audio_stop(UNUSED_ATTR tBTA_AV_HNDL hndl) {
684   APPL_TRACE_DEBUG("%s", __func__);
685 }
686 
687 /*******************************************************************************
688  **
689  ** Function         bta_av_co_audio_src_data_path
690  **
691  ** Description      This function is called to manage data transfer from
692  **                  the audio codec to AVDTP.
693  **
694  ** Returns          Pointer to the GKI buffer to send, NULL if no buffer to
695  **                  send
696  **
697  ******************************************************************************/
bta_av_co_audio_src_data_path(const uint8_t * p_codec_info,uint32_t * p_timestamp)698 void* bta_av_co_audio_src_data_path(const uint8_t* p_codec_info,
699                                     uint32_t* p_timestamp) {
700   BT_HDR* p_buf;
701 
702   APPL_TRACE_DEBUG("%s: codec: %s", __func__, A2DP_CodecName(p_codec_info));
703 
704   p_buf = btif_a2dp_source_audio_readbuf();
705   if (p_buf == NULL) return NULL;
706 
707   /*
708    * Retrieve the timestamp information from the media packet,
709    * and set up the packet header.
710    *
711    * In media packet, the following information is available:
712    * p_buf->layer_specific : number of audio frames in the packet
713    * p_buf->word[0] : timestamp
714    */
715   if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1),
716                                p_timestamp) ||
717       !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) {
718     APPL_TRACE_ERROR("%s: unsupported codec type (%d)", __func__,
719                      A2DP_GetCodecType(p_codec_info));
720   }
721 
722 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
723   if (bta_av_co_cb.cp.active) {
724     p_buf->len++;
725     p_buf->offset--;
726     uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
727     *p = bta_av_co_cp_get_flag();
728   }
729 #endif
730 
731   return p_buf;
732 }
733 
734 /*******************************************************************************
735  **
736  ** Function         bta_av_co_audio_drop
737  **
738  ** Description      An Audio packet is dropped. .
739  **                  It's very likely that the connected headset with this
740  **                  handle is moved far away. The implementation may want to
741  **                  reduce the encoder bit rate setting to reduce the packet
742  **                  size.
743  **
744  ** Returns          void
745  **
746  ******************************************************************************/
bta_av_co_audio_drop(tBTA_AV_HNDL hndl)747 void bta_av_co_audio_drop(tBTA_AV_HNDL hndl) {
748   APPL_TRACE_ERROR("%s: dropped audio packet on handle 0x%x", __func__, hndl);
749 }
750 
751 /*******************************************************************************
752  **
753  ** Function         bta_av_co_audio_delay
754  **
755  ** Description      This function is called by AV when the audio stream
756  **                  connection needs to send the initial delay report to the
757  **                  connected SRC.
758  **
759  **
760  ** Returns          void
761  **
762  ******************************************************************************/
bta_av_co_audio_delay(tBTA_AV_HNDL hndl,uint16_t delay)763 void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, uint16_t delay) {
764   APPL_TRACE_ERROR("%s: handle: x%x, delay:0x%x", __func__, hndl, delay);
765 }
766 
bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl,uint16_t mtu)767 void bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl, uint16_t mtu) {
768   tBTA_AV_CO_PEER* p_peer;
769 
770   APPL_TRACE_DEBUG("%s: handle: %d mtu: %d", __func__, hndl, mtu);
771 
772   /* Retrieve the peer info */
773   p_peer = bta_av_co_get_peer(hndl);
774   if (p_peer == NULL) {
775     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
776     return;
777   }
778   p_peer->mtu = mtu;
779 }
780 
781 /*******************************************************************************
782  **
783  ** Function         bta_av_co_cp_is_scmst
784  **
785  ** Description      Check if a content protection service is SCMS-T
786  **
787  ** Returns          true if this CP is SCMS-T, false otherwise
788  **
789  ******************************************************************************/
bta_av_co_cp_is_scmst(const uint8_t * p_protect_info)790 static bool bta_av_co_cp_is_scmst(const uint8_t* p_protect_info) {
791   APPL_TRACE_DEBUG("%s", __func__);
792 
793   if (*p_protect_info >= AVDT_CP_LOSC) {
794     uint16_t cp_id;
795 
796     p_protect_info++;
797     STREAM_TO_UINT16(cp_id, p_protect_info);
798     if (cp_id == AVDT_CP_SCMS_T_ID) {
799       APPL_TRACE_DEBUG("%s: SCMS-T found", __func__);
800       return true;
801     }
802   }
803 
804   return false;
805 }
806 
807 // Check if audio protect info contains SCMS-T Copy Protection
808 // Returns true if |p_protect_info| contains SCMS-T, otherwise false.
bta_av_co_audio_protect_has_scmst(uint8_t num_protect,const uint8_t * p_protect_info)809 static bool bta_av_co_audio_protect_has_scmst(uint8_t num_protect,
810                                               const uint8_t* p_protect_info) {
811   APPL_TRACE_DEBUG("%s", __func__);
812 
813   while (num_protect--) {
814     if (bta_av_co_cp_is_scmst(p_protect_info)) return true;
815     /* Move to the next SC */
816     p_protect_info += *p_protect_info + 1;
817   }
818   APPL_TRACE_DEBUG("%s: SCMS-T not found", __func__);
819   return false;
820 }
821 
822 /*******************************************************************************
823  **
824  ** Function         bta_av_co_audio_sink_supports_cp
825  **
826  ** Description      Check if a sink supports the current content protection
827  **
828  ** Returns          true if the sink supports this CP, false otherwise
829  **
830  ******************************************************************************/
bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK * p_sink)831 static bool bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK* p_sink) {
832   APPL_TRACE_DEBUG("%s", __func__);
833 
834   /* Check if content protection is enabled for this stream */
835   if (bta_av_co_cp_get_flag() != AVDT_CP_SCMS_COPY_FREE) {
836     return bta_av_co_audio_protect_has_scmst(p_sink->num_protect,
837                                              p_sink->protect_info);
838   }
839 
840   APPL_TRACE_DEBUG("%s: not required", __func__);
841   return true;
842 }
843 
844 /*******************************************************************************
845  **
846  ** Function         bta_av_co_find_peer_src_supports_codec
847  **
848  ** Description      Find a peer acting as src that supports codec config
849  **
850  ** Returns          The peer source that supports the codec, otherwise NULL.
851  **
852  ******************************************************************************/
bta_av_co_find_peer_src_supports_codec(const tBTA_AV_CO_PEER * p_peer)853 static const tBTA_AV_CO_SINK* bta_av_co_find_peer_src_supports_codec(
854     const tBTA_AV_CO_PEER* p_peer) {
855   APPL_TRACE_DEBUG("%s: peer num_sup_srcs = %d", __func__,
856                    p_peer->num_sup_srcs);
857 
858   for (size_t index = 0; index < p_peer->num_sup_srcs; index++) {
859     const uint8_t* p_codec_caps = p_peer->srcs[index].codec_caps;
860     if (A2DP_CodecTypeEquals(bta_av_co_cb.codec_config, p_codec_caps) &&
861         A2DP_IsPeerSourceCodecSupported(p_codec_caps)) {
862       return &p_peer->srcs[index];
863     }
864   }
865   return NULL;
866 }
867 
868 //
869 // Select the current codec configuration based on peer codec support.
870 // Furthermore, the local state for the remaining non-selected codecs is
871 // updated to reflect whether the codec is selectable.
872 // Return a pointer to the corresponding |tBTA_AV_CO_SINK| sink entry
873 // on success, otherwise NULL.
874 //
bta_av_co_audio_set_codec(tBTA_AV_CO_PEER * p_peer)875 static tBTA_AV_CO_SINK* bta_av_co_audio_set_codec(tBTA_AV_CO_PEER* p_peer) {
876   tBTA_AV_CO_SINK* p_sink = NULL;
877 
878   // Update all selectable codecs.
879   // This is needed to update the selectable parameters for each codec.
880   // NOTE: The selectable codec info is used only for informational purpose.
881   for (const auto& iter : bta_av_co_cb.codecs->orderedSourceCodecs()) {
882     APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__,
883                      iter->name().c_str());
884     bta_av_co_audio_update_selectable_codec(*iter, p_peer);
885   }
886 
887   // Select the codec
888   for (const auto& iter : bta_av_co_cb.codecs->orderedSourceCodecs()) {
889     APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
890     p_sink = bta_av_co_audio_codec_selected(*iter, p_peer);
891     if (p_sink != NULL) {
892       APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
893       break;
894     }
895     APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
896   }
897 
898   // NOTE: Unconditionally dispatch the event to make sure a callback with
899   // the most recent codec info is generated.
900   btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
901 
902   return p_sink;
903 }
904 
905 // Select an open device for the preferred codec specified by |codec_config|.
906 // Return the corresponding peer that supports the codec, otherwise NULL.
bta_av_co_audio_codec_selected(A2dpCodecConfig & codec_config,tBTA_AV_CO_PEER * p_peer)907 static tBTA_AV_CO_SINK* bta_av_co_audio_codec_selected(
908     A2dpCodecConfig& codec_config, tBTA_AV_CO_PEER* p_peer) {
909   uint8_t new_codec_config[AVDT_CODEC_SIZE];
910 
911   APPL_TRACE_DEBUG("%s", __func__);
912 
913   // Find the peer sink for the codec
914   tBTA_AV_CO_SINK* p_sink = NULL;
915   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
916     btav_a2dp_codec_index_t peer_codec_index =
917         A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
918     if (peer_codec_index != codec_config.codecIndex()) {
919       continue;
920     }
921     if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) {
922       APPL_TRACE_DEBUG(
923           "%s: peer sink for codec %s does not support "
924           "Copy Protection",
925           __func__, codec_config.name().c_str());
926       continue;
927     }
928     p_sink = &p_peer->sinks[index];
929     break;
930   }
931   if (p_sink == NULL) {
932     APPL_TRACE_DEBUG("%s: peer sink for codec %s not found", __func__,
933                      codec_config.name().c_str());
934     return NULL;
935   }
936   if (!bta_av_co_cb.codecs->setCodecConfig(
937           p_sink->codec_caps, true /* is_capability */, new_codec_config,
938           true /* select_current_codec */)) {
939     APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__,
940                      codec_config.name().c_str());
941     return NULL;
942   }
943   p_peer->p_sink = p_sink;
944 
945   bta_av_co_save_new_codec_config(p_peer, new_codec_config, p_sink->num_protect,
946                                   p_sink->protect_info);
947   // NOTE: Event BTIF_AV_SOURCE_CONFIG_UPDATED_EVT is dispatched by the caller
948 
949   return p_sink;
950 }
951 
952 // Update a selectable codec |codec_config| with the corresponding codec
953 // information from a peer device |p_peer|.
954 // Returns true if the codec is updated, otherwise false.
bta_av_co_audio_update_selectable_codec(A2dpCodecConfig & codec_config,const tBTA_AV_CO_PEER * p_peer)955 static bool bta_av_co_audio_update_selectable_codec(
956     A2dpCodecConfig& codec_config, const tBTA_AV_CO_PEER* p_peer) {
957   uint8_t new_codec_config[AVDT_CODEC_SIZE];
958 
959   APPL_TRACE_DEBUG("%s", __func__);
960 
961   // Find the peer sink for the codec
962   const tBTA_AV_CO_SINK* p_sink = NULL;
963   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
964     btav_a2dp_codec_index_t peer_codec_index =
965         A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
966     if (peer_codec_index != codec_config.codecIndex()) {
967       continue;
968     }
969     if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) {
970       APPL_TRACE_DEBUG(
971           "%s: peer sink for codec %s does not support "
972           "Copy Protection",
973           __func__, codec_config.name().c_str());
974       continue;
975     }
976     p_sink = &p_peer->sinks[index];
977     break;
978   }
979   if (p_sink == NULL) {
980     // The peer sink device does not support this codec
981     return false;
982   }
983   if (!bta_av_co_cb.codecs->setCodecConfig(
984           p_sink->codec_caps, true /* is_capability */, new_codec_config,
985           false /* select_current_codec */)) {
986     APPL_TRACE_DEBUG("%s: cannot update source codec %s", __func__,
987                      codec_config.name().c_str());
988     return false;
989   }
990   return true;
991 }
992 
bta_av_co_save_new_codec_config(tBTA_AV_CO_PEER * p_peer,const uint8_t * new_codec_config,uint8_t num_protect,const uint8_t * p_protect_info)993 static void bta_av_co_save_new_codec_config(tBTA_AV_CO_PEER* p_peer,
994                                             const uint8_t* new_codec_config,
995                                             uint8_t num_protect,
996                                             const uint8_t* p_protect_info) {
997   APPL_TRACE_DEBUG("%s", __func__);
998   A2DP_DumpCodecInfo(new_codec_config);
999 
1000   // Protect access to bta_av_co_cb.codec_config
1001   mutex_global_lock();
1002 
1003   memcpy(bta_av_co_cb.codec_config, new_codec_config,
1004          sizeof(bta_av_co_cb.codec_config));
1005   memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE);
1006 
1007 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1008   /* Check if this sink supports SCMS */
1009   bool cp_active =
1010       bta_av_co_audio_protect_has_scmst(num_protect, p_protect_info);
1011   bta_av_co_cb.cp.active = cp_active;
1012   p_peer->cp_active = cp_active;
1013 #endif
1014 
1015   // Protect access to bta_av_co_cb.codec_config
1016   mutex_global_unlock();
1017 }
1018 
bta_av_co_get_peer_params(tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params)1019 void bta_av_co_get_peer_params(tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
1020   uint16_t min_mtu = 0xFFFF;
1021 
1022   APPL_TRACE_DEBUG("%s", __func__);
1023   CHECK(p_peer_params != nullptr);
1024 
1025   /* Protect access to bta_av_co_cb.codec_config */
1026   mutex_global_lock();
1027 
1028   /* Compute the MTU */
1029   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
1030     const tBTA_AV_CO_PEER* p_peer = &bta_av_co_cb.peers[i];
1031     if (!p_peer->opened) continue;
1032     if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu;
1033   }
1034   p_peer_params->peer_mtu = min_mtu;
1035   p_peer_params->is_peer_edr = btif_av_is_peer_edr();
1036   p_peer_params->peer_supports_3mbps = btif_av_peer_supports_3mbps();
1037 
1038   /* Protect access to bta_av_co_cb.codec_config */
1039   mutex_global_unlock();
1040 }
1041 
bta_av_co_get_encoder_interface(void)1042 const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) {
1043   /* Protect access to bta_av_co_cb.codec_config */
1044   mutex_global_lock();
1045 
1046   const tA2DP_ENCODER_INTERFACE* encoder_interface =
1047       A2DP_GetEncoderInterface(bta_av_co_cb.codec_config);
1048 
1049   /* Protect access to bta_av_co_cb.codec_config */
1050   mutex_global_unlock();
1051 
1052   return encoder_interface;
1053 }
1054 
bta_av_co_set_codec_user_config(const btav_a2dp_codec_config_t & codec_user_config)1055 bool bta_av_co_set_codec_user_config(
1056     const btav_a2dp_codec_config_t& codec_user_config) {
1057   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1058   const tBTA_AV_CO_SINK* p_sink = nullptr;
1059   bool restart_input = false;
1060   bool restart_output = false;
1061   bool config_updated = false;
1062   bool success = true;
1063 
1064   // Find the peer that is currently open
1065   tBTA_AV_CO_PEER* p_peer = nullptr;
1066   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
1067     tBTA_AV_CO_PEER* p_peer_tmp = &bta_av_co_cb.peers[i];
1068     if (p_peer_tmp->opened) {
1069       p_peer = p_peer_tmp;
1070       break;
1071     }
1072   }
1073   if (p_peer == nullptr) {
1074     APPL_TRACE_ERROR("%s: no open peer to configure", __func__);
1075     success = false;
1076     goto done;
1077   }
1078 
1079   // Find the peer SEP codec to use
1080   if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
1081     for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
1082       btav_a2dp_codec_index_t peer_codec_index =
1083           A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
1084       if (peer_codec_index != codec_user_config.codec_type) continue;
1085       if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) continue;
1086       p_sink = &p_peer->sinks[index];
1087       break;
1088     }
1089   } else {
1090     // Use the current sink codec
1091     p_sink = p_peer->p_sink;
1092   }
1093   if (p_sink == nullptr) {
1094     APPL_TRACE_ERROR("%s: cannot find peer SEP to configure for codec type %d",
1095                      __func__, codec_user_config.codec_type);
1096     success = false;
1097     goto done;
1098   }
1099 
1100   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1101   bta_av_co_get_peer_params(&peer_params);
1102   if (!bta_av_co_cb.codecs->setCodecUserConfig(
1103           codec_user_config, &peer_params, p_sink->codec_caps,
1104           result_codec_config, &restart_input, &restart_output,
1105           &config_updated)) {
1106     success = false;
1107     goto done;
1108   }
1109 
1110   if (restart_output) {
1111     uint8_t num_protect = 0;
1112 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1113     if (p_peer->cp_active) num_protect = AVDT_CP_INFO_LEN;
1114 #endif
1115 
1116     p_sink = bta_av_co_audio_set_codec(p_peer);
1117     if (p_sink == NULL) {
1118       APPL_TRACE_ERROR("%s: cannot set up codec for the peer SINK", __func__);
1119       success = false;
1120       goto done;
1121     }
1122     // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
1123     if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
1124         (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
1125       APPL_TRACE_WARNING("%s: not all peer's capabilities have been retrieved",
1126                          __func__);
1127       success = false;
1128       goto done;
1129     }
1130 
1131     APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, p_peer->handle);
1132     BTA_AvReconfig(p_peer->handle, true, p_sink->sep_info_idx,
1133                    p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
1134   }
1135 
1136 done:
1137   // NOTE: We uncoditionally send the upcall even if there is no change
1138   // or the user config failed. Thus, the caller would always know whether the
1139   // request succeeded or failed.
1140   // NOTE: Currently, the input is restarted by sending an upcall
1141   // and informing the Media Framework about the change.
1142   btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1143 
1144   return success;
1145 }
1146 
1147 // Sets the Over-The-Air preferred codec configuration.
1148 // The OTA prefered codec configuration is ignored if the current
1149 // codec configuration contains explicit user configuration, or if the
1150 // codec configuration for the same codec contains explicit user
1151 // configuration.
1152 // |p_peer| is the peer device that sent the OTA codec configuration.
1153 // |p_ota_codec_config| contains the received OTA A2DP codec configuration
1154 // from the remote peer. Note: this is not the peer codec capability,
1155 // but the codec configuration that the peer would like to use.
1156 // |num_protect| is the number of content protection methods to use.
1157 // |p_protect_info| contains the content protection information to use.
1158 // If there is a change in the encoder configuration tht requires restarting
1159 // of the A2DP connection, flag |p_restart_output| is set to true.
1160 // Returns true on success, otherwise false.
bta_av_co_set_codec_ota_config(tBTA_AV_CO_PEER * p_peer,const uint8_t * p_ota_codec_config,uint8_t num_protect,const uint8_t * p_protect_info,bool * p_restart_output)1161 static bool bta_av_co_set_codec_ota_config(tBTA_AV_CO_PEER* p_peer,
1162                                            const uint8_t* p_ota_codec_config,
1163                                            uint8_t num_protect,
1164                                            const uint8_t* p_protect_info,
1165                                            bool* p_restart_output) {
1166   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1167   bool restart_input = false;
1168   bool restart_output = false;
1169   bool config_updated = false;
1170 
1171   APPL_TRACE_DEBUG("%s", __func__);
1172   A2DP_DumpCodecInfo(p_ota_codec_config);
1173 
1174   *p_restart_output = false;
1175 
1176   // Find the peer SEP codec to use
1177   btav_a2dp_codec_index_t ota_codec_index =
1178       A2DP_SourceCodecIndex(p_ota_codec_config);
1179   if (ota_codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
1180     APPL_TRACE_WARNING("%s: invalid peer codec config", __func__);
1181     return false;
1182   }
1183   const tBTA_AV_CO_SINK* p_sink = nullptr;
1184   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
1185     btav_a2dp_codec_index_t peer_codec_index =
1186         A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
1187     if (peer_codec_index != ota_codec_index) continue;
1188     if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) continue;
1189     p_sink = &p_peer->sinks[index];
1190     break;
1191   }
1192   if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) {
1193     // There are no peer SEPs if we didn't do the discovery procedure yet.
1194     // We have all the information we need from the peer, so we can
1195     // proceed with the OTA codec configuration.
1196     APPL_TRACE_ERROR("%s: cannot find peer SEP to configure", __func__);
1197     return false;
1198   }
1199 
1200   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1201   bta_av_co_get_peer_params(&peer_params);
1202   if (!bta_av_co_cb.codecs->setCodecOtaConfig(
1203           p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
1204           &restart_output, &config_updated)) {
1205     APPL_TRACE_ERROR("%s: cannot set OTA config", __func__);
1206     return false;
1207   }
1208 
1209   if (restart_output) {
1210     APPL_TRACE_DEBUG("%s: restart output", __func__);
1211     A2DP_DumpCodecInfo(result_codec_config);
1212 
1213     *p_restart_output = true;
1214     p_peer->p_sink = p_sink;
1215     bta_av_co_save_new_codec_config(p_peer, result_codec_config, num_protect,
1216                                     p_protect_info);
1217   }
1218 
1219   if (restart_input || config_updated) {
1220     // NOTE: Currently, the input is restarted by sending an upcall
1221     // and informing the Media Framework about the change.
1222     btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1223   }
1224 
1225   return true;
1226 }
1227 
bta_av_co_set_codec_audio_config(const btav_a2dp_codec_config_t & codec_audio_config)1228 bool bta_av_co_set_codec_audio_config(
1229     const btav_a2dp_codec_config_t& codec_audio_config) {
1230   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1231   bool restart_output = false;
1232   bool config_updated = false;
1233 
1234   // Find the peer that is currently open
1235   tBTA_AV_CO_PEER* p_peer = nullptr;
1236   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
1237     tBTA_AV_CO_PEER* p_peer_tmp = &bta_av_co_cb.peers[i];
1238     if (p_peer_tmp->opened) {
1239       p_peer = p_peer_tmp;
1240       break;
1241     }
1242   }
1243   if (p_peer == nullptr) {
1244     APPL_TRACE_ERROR("%s: no open peer to configure", __func__);
1245     return false;
1246   }
1247 
1248   // Use the current sink codec
1249   const tBTA_AV_CO_SINK* p_sink = p_peer->p_sink;
1250   if (p_sink == nullptr) {
1251     APPL_TRACE_ERROR("%s: cannot find peer SEP to configure", __func__);
1252     return false;
1253   }
1254 
1255   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1256   bta_av_co_get_peer_params(&peer_params);
1257   if (!bta_av_co_cb.codecs->setCodecAudioConfig(
1258           codec_audio_config, &peer_params, p_sink->codec_caps,
1259           result_codec_config, &restart_output, &config_updated)) {
1260     return false;
1261   }
1262 
1263   if (restart_output) {
1264     uint8_t num_protect = 0;
1265 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1266     if (p_peer->cp_active) num_protect = AVDT_CP_INFO_LEN;
1267 #endif
1268 
1269     bta_av_co_save_new_codec_config(p_peer, result_codec_config,
1270                                     p_sink->num_protect, p_sink->protect_info);
1271 
1272     // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
1273     if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
1274         (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
1275       APPL_TRACE_WARNING("%s: not all peer's capabilities have been retrieved",
1276                          __func__);
1277     } else {
1278       APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__,
1279                        p_peer->handle);
1280       BTA_AvReconfig(p_peer->handle, true, p_sink->sep_info_idx,
1281                      p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
1282     }
1283   }
1284 
1285   if (config_updated) {
1286     // NOTE: Currently, the input is restarted by sending an upcall
1287     // and informing the Media Framework about the change.
1288     btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1289   }
1290 
1291   return true;
1292 }
1293 
bta_av_get_a2dp_codecs(void)1294 A2dpCodecs* bta_av_get_a2dp_codecs(void) { return bta_av_co_cb.codecs; }
1295 
bta_av_get_a2dp_current_codec(void)1296 A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) {
1297   A2dpCodecConfig* current_codec;
1298 
1299   mutex_global_lock();
1300   if (bta_av_co_cb.codecs == nullptr) {
1301     mutex_global_unlock();
1302     return nullptr;
1303   }
1304   current_codec = bta_av_co_cb.codecs->getCurrentCodecConfig();
1305   mutex_global_unlock();
1306 
1307   return current_codec;
1308 }
1309 
bta_av_co_init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)1310 void bta_av_co_init(
1311     const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
1312   APPL_TRACE_DEBUG("%s", __func__);
1313 
1314   /* Reset the control block */
1315   bta_av_co_cb.reset();
1316 
1317 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1318   bta_av_co_cp_set_flag(AVDT_CP_SCMS_COPY_NEVER);
1319 #else
1320   bta_av_co_cp_set_flag(AVDT_CP_SCMS_COPY_FREE);
1321 #endif
1322 
1323   /* Reset the current config */
1324   /* Protect access to bta_av_co_cb.codec_config */
1325   mutex_global_lock();
1326   bta_av_co_cb.codecs = new A2dpCodecs(codec_priorities);
1327   bta_av_co_cb.codecs->init();
1328   A2DP_InitDefaultCodec(bta_av_co_cb.codec_config);
1329   mutex_global_unlock();
1330 
1331   // NOTE: Unconditionally dispatch the event to make sure a callback with
1332   // the most recent codec info is generated.
1333   btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1334 }
1335