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   BD_ADDR 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,BD_ADDR 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, BD_ADDR addr,
243                               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   bdcpy(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 
399   /* Retrieve the peer info */
400   p_peer = bta_av_co_get_peer(hndl);
401   if (p_peer == NULL) {
402     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
403     return A2DP_FAIL;
404   }
405 
406   if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) {
407     return bta_av_audio_sink_getconfig(hndl, p_codec_info, p_sep_info_idx, seid,
408                                        p_num_protect, p_protect_info);
409   }
410   APPL_TRACE_DEBUG("%s: handle:0x%x codec:%s seid:%d", __func__, hndl,
411                    A2DP_CodecName(p_codec_info), seid);
412   APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
413                    __func__, *p_num_protect, p_protect_info[0],
414                    p_protect_info[1], p_protect_info[2]);
415   APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)",
416                    __func__, p_peer->opened, p_peer->num_sinks,
417                    p_peer->num_rx_sinks, p_peer->num_sup_sinks);
418 
419   p_peer->num_rx_sinks++;
420 
421   /* Check the peer's SINK codec */
422   if (A2DP_IsPeerSinkCodecValid(p_codec_info)) {
423     /* If there is room for a new one */
424     if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) {
425       tBTA_AV_CO_SINK* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++];
426 
427       APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
428                        p_codec_info[1], p_codec_info[2], p_codec_info[3],
429                        p_codec_info[4], p_codec_info[5], p_codec_info[6]);
430 
431       memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
432       p_sink->sep_info_idx = *p_sep_info_idx;
433       p_sink->seid = seid;
434       p_sink->num_protect = *p_num_protect;
435       memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
436     } else {
437       APPL_TRACE_ERROR("%s: no more room for SINK info", __func__);
438     }
439   }
440 
441   // Check if this is the last SINK get capabilities or all supported codec
442   // capabilities are retrieved.
443   if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
444       (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
445     return A2DP_FAIL;
446   }
447   APPL_TRACE_DEBUG("%s: last sink reached", __func__);
448 
449   const tBTA_AV_CO_SINK* p_sink = bta_av_co_audio_set_codec(p_peer);
450   if (p_sink == NULL) {
451     APPL_TRACE_ERROR("%s: cannot set up codec for the peer SINK", __func__);
452     return A2DP_FAIL;
453   }
454 
455   // By default, no content protection
456   *p_num_protect = 0;
457 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
458   if (p_peer->cp_active) {
459     *p_num_protect = AVDT_CP_INFO_LEN;
460     memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
461   }
462 #endif
463 
464   // If acceptor -> reconfig otherwise reply for configuration.
465   if (p_peer->acp) {
466     // Stop fetching caps once we retrieved a supported codec.
467     APPL_TRACE_EVENT("%s: no need to fetch more SEPs", __func__);
468     *p_sep_info_idx = p_peer->num_seps;
469     if (p_peer->reconfig_needed) {
470       APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, hndl);
471       BTA_AvReconfig(hndl, true, p_sink->sep_info_idx, p_peer->codec_config,
472                      *p_num_protect, bta_av_co_cp_scmst);
473     }
474   } else {
475     *p_sep_info_idx = p_sink->sep_info_idx;
476     memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
477   }
478 
479   return A2DP_SUCCESS;
480 }
481 
482 /*******************************************************************************
483  **
484  ** Function         bta_av_co_audio_setconfig
485  **
486  ** Description      This callout function is executed by AV to set the codec
487  **                  and content protection configuration of the audio stream.
488  **
489  **
490  ** Returns          void
491  **
492  ******************************************************************************/
bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl,const uint8_t * p_codec_info,UNUSED_ATTR uint8_t seid,UNUSED_ATTR BD_ADDR addr,uint8_t num_protect,const uint8_t * p_protect_info,uint8_t t_local_sep,uint8_t avdt_handle)493 void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, const uint8_t* p_codec_info,
494                                UNUSED_ATTR uint8_t seid,
495                                UNUSED_ATTR BD_ADDR addr, uint8_t num_protect,
496                                const uint8_t* p_protect_info,
497                                uint8_t t_local_sep, uint8_t avdt_handle) {
498   tBTA_AV_CO_PEER* p_peer;
499   tA2DP_STATUS status = A2DP_SUCCESS;
500   uint8_t category = A2DP_SUCCESS;
501   bool reconfig_needed = false;
502 
503   APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
504                    p_codec_info[1], p_codec_info[2], p_codec_info[3],
505                    p_codec_info[4], p_codec_info[5], p_codec_info[6]);
506   APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x",
507                    num_protect, p_protect_info[0], p_protect_info[1],
508                    p_protect_info[2]);
509 
510   /* Retrieve the peer info */
511   p_peer = bta_av_co_get_peer(hndl);
512   if (p_peer == NULL) {
513     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
514     /* Call call-in rejecting the configuration */
515     bta_av_ci_setconfig(hndl, A2DP_BUSY, AVDT_ASC_CODEC, 0, NULL, false,
516                         avdt_handle);
517     return;
518   }
519 
520   APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)",
521                    __func__, p_peer->opened, p_peer->num_sinks,
522                    p_peer->num_rx_sinks, p_peer->num_sup_sinks);
523 
524   /* Sanity check: should not be opened at this point */
525   if (p_peer->opened) {
526     APPL_TRACE_ERROR("%s: peer already in use", __func__);
527   }
528 
529   if (num_protect != 0) {
530 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
531     /* If CP is supported */
532     if ((num_protect != 1) ||
533         (bta_av_co_cp_is_scmst(p_protect_info) == false)) {
534       APPL_TRACE_ERROR("%s: wrong CP configuration", __func__);
535       status = A2DP_BAD_CP_TYPE;
536       category = AVDT_ASC_PROTECT;
537     }
538 #else
539     /* Do not support content protection for the time being */
540     APPL_TRACE_ERROR("%s: wrong CP configuration", __func__);
541     status = A2DP_BAD_CP_TYPE;
542     category = AVDT_ASC_PROTECT;
543 #endif
544   }
545 
546   if (status == A2DP_SUCCESS) {
547     bool codec_config_supported = false;
548 
549     if (t_local_sep == AVDT_TSEP_SNK) {
550       APPL_TRACE_DEBUG("%s: peer is A2DP SRC", __func__);
551       codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info);
552       if (codec_config_supported) {
553         // If Peer is SRC, and our config subset matches with what is
554         // requested by peer, then just accept what peer wants.
555         bta_av_co_save_new_codec_config(p_peer, p_codec_info, num_protect,
556                                         p_protect_info);
557       }
558     }
559     if (t_local_sep == AVDT_TSEP_SRC) {
560       APPL_TRACE_DEBUG("%s: peer is A2DP SINK", __func__);
561       bool restart_output = false;
562       if ((bta_av_co_cb.codecs == nullptr) ||
563           !bta_av_co_set_codec_ota_config(p_peer, p_codec_info, num_protect,
564                                           p_protect_info, &restart_output)) {
565         APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__,
566                          A2DP_CodecName(p_codec_info));
567       } else {
568         codec_config_supported = true;
569         // Check if reconfiguration is needed
570         if (restart_output ||
571             ((num_protect == 1) && (!bta_av_co_cb.cp.active))) {
572           reconfig_needed = true;
573         }
574       }
575     }
576 
577     /* Check if codec configuration is supported */
578     if (!codec_config_supported) {
579       category = AVDT_ASC_CODEC;
580       status = A2DP_WRONG_CODEC;
581     }
582   }
583 
584   if (status != A2DP_SUCCESS) {
585     APPL_TRACE_DEBUG("%s: reject s=%d c=%d", __func__, status, category);
586     /* Call call-in rejecting the configuration */
587     bta_av_ci_setconfig(hndl, status, category, 0, NULL, false, avdt_handle);
588     return;
589   }
590 
591   /* Mark that this is an acceptor peer */
592   p_peer->acp = true;
593   p_peer->reconfig_needed = reconfig_needed;
594   APPL_TRACE_DEBUG("%s: accept reconf=%d", __func__, reconfig_needed);
595   /* Call call-in accepting the configuration */
596   bta_av_ci_setconfig(hndl, A2DP_SUCCESS, A2DP_SUCCESS, 0, NULL,
597                       reconfig_needed, avdt_handle);
598 }
599 
600 /*******************************************************************************
601  **
602  ** Function         bta_av_co_audio_open
603  **
604  ** Description      This function is called by AV when the audio stream
605  **                  connection is opened.
606  **
607  **
608  ** Returns          void
609  **
610  ******************************************************************************/
bta_av_co_audio_open(tBTA_AV_HNDL hndl,uint16_t mtu)611 void bta_av_co_audio_open(tBTA_AV_HNDL hndl, uint16_t mtu) {
612   tBTA_AV_CO_PEER* p_peer;
613 
614   APPL_TRACE_DEBUG("%s: handle: %d mtu:%d", __func__, hndl, mtu);
615 
616   /* Retrieve the peer info */
617   p_peer = bta_av_co_get_peer(hndl);
618   if (p_peer == NULL) {
619     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
620   } else {
621     p_peer->opened = true;
622     p_peer->mtu = mtu;
623   }
624 }
625 
626 /*******************************************************************************
627  **
628  ** Function         bta_av_co_audio_close
629  **
630  ** Description      This function is called by AV when the audio stream
631  **                  connection is closed.
632  **
633  **
634  ** Returns          void
635  **
636  ******************************************************************************/
bta_av_co_audio_close(tBTA_AV_HNDL hndl)637 void bta_av_co_audio_close(tBTA_AV_HNDL hndl) {
638   tBTA_AV_CO_PEER* p_peer;
639 
640   APPL_TRACE_DEBUG("%s", __func__);
641 
642   /* Retrieve the peer info */
643   p_peer = bta_av_co_get_peer(hndl);
644   if (p_peer) {
645     /* Mark the peer closed and clean the peer info */
646     memset(p_peer, 0, sizeof(*p_peer));
647   } else {
648     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
649   }
650 }
651 
652 /*******************************************************************************
653  **
654  ** Function         bta_av_co_audio_start
655  **
656  ** Description      This function is called by AV when the audio streaming data
657  **                  transfer is started.
658  **
659  **
660  ** Returns          void
661  **
662  ******************************************************************************/
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)663 void bta_av_co_audio_start(UNUSED_ATTR tBTA_AV_HNDL hndl,
664                            UNUSED_ATTR uint8_t* p_codec_info,
665                            UNUSED_ATTR bool* p_no_rtp_hdr) {
666   APPL_TRACE_DEBUG("%s", __func__);
667 }
668 
669 /*******************************************************************************
670  **
671  ** Function         bta_av_co_audio_stop
672  **
673  ** Description      This function is called by AV when the audio streaming data
674  **                  transfer is stopped.
675  **
676  **
677  ** Returns          void
678  **
679  ******************************************************************************/
bta_av_co_audio_stop(UNUSED_ATTR tBTA_AV_HNDL hndl)680 void bta_av_co_audio_stop(UNUSED_ATTR tBTA_AV_HNDL hndl) {
681   APPL_TRACE_DEBUG("%s", __func__);
682 }
683 
684 /*******************************************************************************
685  **
686  ** Function         bta_av_co_audio_src_data_path
687  **
688  ** Description      This function is called to manage data transfer from
689  **                  the audio codec to AVDTP.
690  **
691  ** Returns          Pointer to the GKI buffer to send, NULL if no buffer to
692  **                  send
693  **
694  ******************************************************************************/
bta_av_co_audio_src_data_path(const uint8_t * p_codec_info,uint32_t * p_timestamp)695 void* bta_av_co_audio_src_data_path(const uint8_t* p_codec_info,
696                                     uint32_t* p_timestamp) {
697   BT_HDR* p_buf;
698 
699   APPL_TRACE_DEBUG("%s: codec: %s", __func__, A2DP_CodecName(p_codec_info));
700 
701   p_buf = btif_a2dp_source_audio_readbuf();
702   if (p_buf == NULL) return NULL;
703 
704   /*
705    * Retrieve the timestamp information from the media packet,
706    * and set up the packet header.
707    *
708    * In media packet, the following information is available:
709    * p_buf->layer_specific : number of audio frames in the packet
710    * p_buf->word[0] : timestamp
711    */
712   if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1),
713                                p_timestamp) ||
714       !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) {
715     APPL_TRACE_ERROR("%s: unsupported codec type (%d)", __func__,
716                      A2DP_GetCodecType(p_codec_info));
717   }
718 
719 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
720   if (bta_av_co_cb.cp.active) {
721     p_buf->len++;
722     p_buf->offset--;
723     uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
724     *p = bta_av_co_cp_get_flag();
725   }
726 #endif
727 
728   return p_buf;
729 }
730 
731 /*******************************************************************************
732  **
733  ** Function         bta_av_co_audio_drop
734  **
735  ** Description      An Audio packet is dropped. .
736  **                  It's very likely that the connected headset with this
737  **                  handle is moved far away. The implementation may want to
738  **                  reduce the encoder bit rate setting to reduce the packet
739  **                  size.
740  **
741  ** Returns          void
742  **
743  ******************************************************************************/
bta_av_co_audio_drop(tBTA_AV_HNDL hndl)744 void bta_av_co_audio_drop(tBTA_AV_HNDL hndl) {
745   APPL_TRACE_ERROR("%s: dropped audio packet on handle 0x%x", __func__, hndl);
746 }
747 
748 /*******************************************************************************
749  **
750  ** Function         bta_av_co_audio_delay
751  **
752  ** Description      This function is called by AV when the audio stream
753  **                  connection needs to send the initial delay report to the
754  **                  connected SRC.
755  **
756  **
757  ** Returns          void
758  **
759  ******************************************************************************/
bta_av_co_audio_delay(tBTA_AV_HNDL hndl,uint16_t delay)760 void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, uint16_t delay) {
761   APPL_TRACE_ERROR("%s: handle: x%x, delay:0x%x", __func__, hndl, delay);
762 }
763 
bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl,uint16_t mtu)764 void bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl, uint16_t mtu) {
765   tBTA_AV_CO_PEER* p_peer;
766 
767   APPL_TRACE_DEBUG("%s: handle: %d mtu: %d", __func__, hndl, mtu);
768 
769   /* Retrieve the peer info */
770   p_peer = bta_av_co_get_peer(hndl);
771   if (p_peer == NULL) {
772     APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
773     return;
774   }
775   p_peer->mtu = mtu;
776 }
777 
778 /*******************************************************************************
779  **
780  ** Function         bta_av_co_cp_is_scmst
781  **
782  ** Description      Check if a content protection service is SCMS-T
783  **
784  ** Returns          true if this CP is SCMS-T, false otherwise
785  **
786  ******************************************************************************/
bta_av_co_cp_is_scmst(const uint8_t * p_protect_info)787 static bool bta_av_co_cp_is_scmst(const uint8_t* p_protect_info) {
788   APPL_TRACE_DEBUG("%s", __func__);
789 
790   if (*p_protect_info >= AVDT_CP_LOSC) {
791     uint16_t cp_id;
792 
793     p_protect_info++;
794     STREAM_TO_UINT16(cp_id, p_protect_info);
795     if (cp_id == AVDT_CP_SCMS_T_ID) {
796       APPL_TRACE_DEBUG("%s: SCMS-T found", __func__);
797       return true;
798     }
799   }
800 
801   return false;
802 }
803 
804 // Check if audio protect info contains SCMS-T Copy Protection
805 // 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)806 static bool bta_av_co_audio_protect_has_scmst(uint8_t num_protect,
807                                               const uint8_t* p_protect_info) {
808   APPL_TRACE_DEBUG("%s", __func__);
809 
810   while (num_protect--) {
811     if (bta_av_co_cp_is_scmst(p_protect_info)) return true;
812     /* Move to the next SC */
813     p_protect_info += *p_protect_info + 1;
814   }
815   APPL_TRACE_DEBUG("%s: SCMS-T not found", __func__);
816   return false;
817 }
818 
819 /*******************************************************************************
820  **
821  ** Function         bta_av_co_audio_sink_supports_cp
822  **
823  ** Description      Check if a sink supports the current content protection
824  **
825  ** Returns          true if the sink supports this CP, false otherwise
826  **
827  ******************************************************************************/
bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK * p_sink)828 static bool bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK* p_sink) {
829   APPL_TRACE_DEBUG("%s", __func__);
830 
831   /* Check if content protection is enabled for this stream */
832   if (bta_av_co_cp_get_flag() != AVDT_CP_SCMS_COPY_FREE) {
833     return bta_av_co_audio_protect_has_scmst(p_sink->num_protect,
834                                              p_sink->protect_info);
835   }
836 
837   APPL_TRACE_DEBUG("%s: not required", __func__);
838   return true;
839 }
840 
841 /*******************************************************************************
842  **
843  ** Function         bta_av_co_find_peer_src_supports_codec
844  **
845  ** Description      Find a peer acting as src that supports codec config
846  **
847  ** Returns          The peer source that supports the codec, otherwise NULL.
848  **
849  ******************************************************************************/
bta_av_co_find_peer_src_supports_codec(const tBTA_AV_CO_PEER * p_peer)850 static const tBTA_AV_CO_SINK* bta_av_co_find_peer_src_supports_codec(
851     const tBTA_AV_CO_PEER* p_peer) {
852   APPL_TRACE_DEBUG("%s: peer num_sup_srcs = %d", __func__,
853                    p_peer->num_sup_srcs);
854 
855   for (size_t index = 0; index < p_peer->num_sup_srcs; index++) {
856     const uint8_t* p_codec_caps = p_peer->srcs[index].codec_caps;
857     if (A2DP_CodecTypeEquals(bta_av_co_cb.codec_config, p_codec_caps) &&
858         A2DP_IsPeerSourceCodecSupported(p_codec_caps)) {
859       return &p_peer->srcs[index];
860     }
861   }
862   return NULL;
863 }
864 
865 //
866 // Select the current codec configuration based on peer codec support.
867 // Furthermore, the local state for the remaining non-selected codecs is
868 // updated to reflect whether the codec is selectable.
869 // Return a pointer to the corresponding |tBTA_AV_CO_SINK| sink entry
870 // on success, otherwise NULL.
871 //
bta_av_co_audio_set_codec(tBTA_AV_CO_PEER * p_peer)872 static tBTA_AV_CO_SINK* bta_av_co_audio_set_codec(tBTA_AV_CO_PEER* p_peer) {
873   tBTA_AV_CO_SINK* p_sink = NULL;
874 
875   // Update all selectable codecs.
876   // This is needed to update the selectable parameters for each codec.
877   // NOTE: The selectable codec info is used only for informational purpose.
878   for (const auto& iter : bta_av_co_cb.codecs->orderedSourceCodecs()) {
879     APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__,
880                      iter->name().c_str());
881     bta_av_co_audio_update_selectable_codec(*iter, p_peer);
882   }
883 
884   // Select the codec
885   for (const auto& iter : bta_av_co_cb.codecs->orderedSourceCodecs()) {
886     APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
887     p_sink = bta_av_co_audio_codec_selected(*iter, p_peer);
888     if (p_sink != NULL) {
889       APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
890       break;
891     }
892     APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
893   }
894 
895   // NOTE: Unconditionally dispatch the event to make sure a callback with
896   // the most recent codec info is generated.
897   btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
898 
899   return p_sink;
900 }
901 
902 // Select an open device for the preferred codec specified by |codec_config|.
903 // 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)904 static tBTA_AV_CO_SINK* bta_av_co_audio_codec_selected(
905     A2dpCodecConfig& codec_config, tBTA_AV_CO_PEER* p_peer) {
906   uint8_t new_codec_config[AVDT_CODEC_SIZE];
907 
908   APPL_TRACE_DEBUG("%s", __func__);
909 
910   // Find the peer sink for the codec
911   tBTA_AV_CO_SINK* p_sink = NULL;
912   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
913     btav_a2dp_codec_index_t peer_codec_index =
914         A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
915     if (peer_codec_index != codec_config.codecIndex()) {
916       continue;
917     }
918     if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) {
919       APPL_TRACE_DEBUG(
920           "%s: peer sink for codec %s does not support "
921           "Copy Protection",
922           __func__, codec_config.name().c_str());
923       continue;
924     }
925     p_sink = &p_peer->sinks[index];
926     break;
927   }
928   if (p_sink == NULL) {
929     APPL_TRACE_DEBUG("%s: peer sink for codec %s not found", __func__,
930                      codec_config.name().c_str());
931     return NULL;
932   }
933   if (!bta_av_co_cb.codecs->setCodecConfig(
934           p_sink->codec_caps, true /* is_capability */, new_codec_config,
935           true /* select_current_codec */)) {
936     APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__,
937                      codec_config.name().c_str());
938     return NULL;
939   }
940   p_peer->p_sink = p_sink;
941 
942   bta_av_co_save_new_codec_config(p_peer, new_codec_config, p_sink->num_protect,
943                                   p_sink->protect_info);
944   // NOTE: Event BTIF_AV_SOURCE_CONFIG_UPDATED_EVT is dispatched by the caller
945 
946   return p_sink;
947 }
948 
949 // Update a selectable codec |codec_config| with the corresponding codec
950 // information from a peer device |p_peer|.
951 // 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)952 static bool bta_av_co_audio_update_selectable_codec(
953     A2dpCodecConfig& codec_config, const tBTA_AV_CO_PEER* p_peer) {
954   uint8_t new_codec_config[AVDT_CODEC_SIZE];
955 
956   APPL_TRACE_DEBUG("%s", __func__);
957 
958   // Find the peer sink for the codec
959   const tBTA_AV_CO_SINK* p_sink = NULL;
960   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
961     btav_a2dp_codec_index_t peer_codec_index =
962         A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
963     if (peer_codec_index != codec_config.codecIndex()) {
964       continue;
965     }
966     if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) {
967       APPL_TRACE_DEBUG(
968           "%s: peer sink for codec %s does not support "
969           "Copy Protection",
970           __func__, codec_config.name().c_str());
971       continue;
972     }
973     p_sink = &p_peer->sinks[index];
974     break;
975   }
976   if (p_sink == NULL) {
977     // The peer sink device does not support this codec
978     return false;
979   }
980   if (!bta_av_co_cb.codecs->setCodecConfig(
981           p_sink->codec_caps, true /* is_capability */, new_codec_config,
982           false /* select_current_codec */)) {
983     APPL_TRACE_DEBUG("%s: cannot update source codec %s", __func__,
984                      codec_config.name().c_str());
985     return false;
986   }
987   return true;
988 }
989 
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)990 static void bta_av_co_save_new_codec_config(tBTA_AV_CO_PEER* p_peer,
991                                             const uint8_t* new_codec_config,
992                                             uint8_t num_protect,
993                                             const uint8_t* p_protect_info) {
994   // Protect access to bta_av_co_cb.codec_config
995   mutex_global_lock();
996 
997   memcpy(bta_av_co_cb.codec_config, new_codec_config,
998          sizeof(bta_av_co_cb.codec_config));
999   memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE);
1000 
1001 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1002   /* Check if this sink supports SCMS */
1003   bool cp_active =
1004       bta_av_co_audio_protect_has_scmst(num_protect, p_protect_info);
1005   bta_av_co_cb.cp.active = cp_active;
1006   p_peer->cp_active = cp_active;
1007 #endif
1008 
1009   // Protect access to bta_av_co_cb.codec_config
1010   mutex_global_unlock();
1011 }
1012 
bta_av_co_get_peer_params(tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params)1013 void bta_av_co_get_peer_params(tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
1014   uint16_t min_mtu = 0xFFFF;
1015 
1016   APPL_TRACE_DEBUG("%s", __func__);
1017   CHECK(p_peer_params != nullptr);
1018 
1019   /* Protect access to bta_av_co_cb.codec_config */
1020   mutex_global_lock();
1021 
1022   /* Compute the MTU */
1023   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
1024     const tBTA_AV_CO_PEER* p_peer = &bta_av_co_cb.peers[i];
1025     if (!p_peer->opened) continue;
1026     if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu;
1027   }
1028   p_peer_params->peer_mtu = min_mtu;
1029   p_peer_params->is_peer_edr = btif_av_is_peer_edr();
1030   p_peer_params->peer_supports_3mbps = btif_av_peer_supports_3mbps();
1031 
1032   /* Protect access to bta_av_co_cb.codec_config */
1033   mutex_global_unlock();
1034 }
1035 
bta_av_co_get_encoder_interface(void)1036 const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) {
1037   /* Protect access to bta_av_co_cb.codec_config */
1038   mutex_global_lock();
1039 
1040   const tA2DP_ENCODER_INTERFACE* encoder_interface =
1041       A2DP_GetEncoderInterface(bta_av_co_cb.codec_config);
1042 
1043   /* Protect access to bta_av_co_cb.codec_config */
1044   mutex_global_unlock();
1045 
1046   return encoder_interface;
1047 }
1048 
bta_av_co_set_codec_user_config(const btav_a2dp_codec_config_t & codec_user_config)1049 bool bta_av_co_set_codec_user_config(
1050     const btav_a2dp_codec_config_t& codec_user_config) {
1051   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1052   const tBTA_AV_CO_SINK* p_sink = nullptr;
1053   bool restart_input = false;
1054   bool restart_output = false;
1055   bool config_updated = false;
1056   bool success = true;
1057 
1058   // Find the peer that is currently open
1059   tBTA_AV_CO_PEER* p_peer = nullptr;
1060   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
1061     tBTA_AV_CO_PEER* p_peer_tmp = &bta_av_co_cb.peers[i];
1062     if (p_peer_tmp->opened) {
1063       p_peer = p_peer_tmp;
1064       break;
1065     }
1066   }
1067   if (p_peer == nullptr) {
1068     APPL_TRACE_ERROR("%s: no open peer to configure", __func__);
1069     success = false;
1070     goto done;
1071   }
1072 
1073   // Find the peer SEP codec to use
1074   if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
1075     for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
1076       btav_a2dp_codec_index_t peer_codec_index =
1077           A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
1078       if (peer_codec_index != codec_user_config.codec_type) continue;
1079       if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) continue;
1080       p_sink = &p_peer->sinks[index];
1081       break;
1082     }
1083   } else {
1084     // Use the current sink codec
1085     p_sink = p_peer->p_sink;
1086   }
1087   if (p_sink == nullptr) {
1088     APPL_TRACE_ERROR("%s: cannot find peer SEP to configure for codec type %d",
1089                      __func__, codec_user_config.codec_type);
1090     success = false;
1091     goto done;
1092   }
1093 
1094   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1095   bta_av_co_get_peer_params(&peer_params);
1096   if (!bta_av_co_cb.codecs->setCodecUserConfig(
1097           codec_user_config, &peer_params, p_sink->codec_caps,
1098           result_codec_config, &restart_input, &restart_output,
1099           &config_updated)) {
1100     success = false;
1101     goto done;
1102   }
1103 
1104   if (restart_output) {
1105     uint8_t num_protect = 0;
1106 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1107     if (p_peer->cp_active) num_protect = AVDT_CP_INFO_LEN;
1108 #endif
1109 
1110     p_sink = bta_av_co_audio_set_codec(p_peer);
1111     if (p_sink == NULL) {
1112       APPL_TRACE_ERROR("%s: cannot set up codec for the peer SINK", __func__);
1113       success = false;
1114       goto done;
1115     }
1116     APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, p_peer->handle);
1117     BTA_AvReconfig(p_peer->handle, true, p_sink->sep_info_idx,
1118                    p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
1119   }
1120 
1121 done:
1122   // NOTE: We uncoditionally send the upcall even if there is no change
1123   // or the user config failed. Thus, the caller would always know whether the
1124   // request succeeded or failed.
1125   // NOTE: Currently, the input is restarted by sending an upcall
1126   // and informing the Media Framework about the change.
1127   btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1128 
1129   return success;
1130 }
1131 
1132 // Sets the Over-The-Air preferred codec configuration.
1133 // The OTA prefered codec configuration is ignored if the current
1134 // codec configuration contains explicit user configuration, or if the
1135 // codec configuration for the same codec contains explicit user
1136 // configuration.
1137 // |p_peer| is the peer device that sent the OTA codec configuration.
1138 // |p_ota_codec_config| contains the received OTA A2DP codec configuration
1139 // from the remote peer. Note: this is not the peer codec capability,
1140 // but the codec configuration that the peer would like to use.
1141 // |num_protect| is the number of content protection methods to use.
1142 // |p_protect_info| contains the content protection information to use.
1143 // If there is a change in the encoder configuration tht requires restarting
1144 // of the A2DP connection, flag |p_restart_output| is set to true.
1145 // 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)1146 static bool bta_av_co_set_codec_ota_config(tBTA_AV_CO_PEER* p_peer,
1147                                            const uint8_t* p_ota_codec_config,
1148                                            uint8_t num_protect,
1149                                            const uint8_t* p_protect_info,
1150                                            bool* p_restart_output) {
1151   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1152   bool restart_input = false;
1153   bool restart_output = false;
1154   bool config_updated = false;
1155 
1156   *p_restart_output = false;
1157 
1158   // Find the peer SEP codec to use
1159   btav_a2dp_codec_index_t ota_codec_index =
1160       A2DP_SourceCodecIndex(p_ota_codec_config);
1161   if (ota_codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
1162     APPL_TRACE_WARNING("%s: invalid peer codec config", __func__);
1163     return false;
1164   }
1165   const tBTA_AV_CO_SINK* p_sink = nullptr;
1166   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
1167     btav_a2dp_codec_index_t peer_codec_index =
1168         A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps);
1169     if (peer_codec_index != ota_codec_index) continue;
1170     if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) continue;
1171     p_sink = &p_peer->sinks[index];
1172     break;
1173   }
1174   if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) {
1175     // There are no peer SEPs if we didn't do the discovery procedure yet.
1176     // We have all the information we need from the peer, so we can
1177     // proceed with the OTA codec configuration.
1178     APPL_TRACE_ERROR("%s: cannot find peer SEP to configure", __func__);
1179     return false;
1180   }
1181 
1182   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1183   bta_av_co_get_peer_params(&peer_params);
1184   if (!bta_av_co_cb.codecs->setCodecOtaConfig(
1185           p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
1186           &restart_output, &config_updated)) {
1187     APPL_TRACE_ERROR("%s: cannot set OTA config", __func__);
1188     return false;
1189   }
1190 
1191   if (restart_output) {
1192     *p_restart_output = true;
1193     p_peer->p_sink = p_sink;
1194     bta_av_co_save_new_codec_config(p_peer, result_codec_config, num_protect,
1195                                     p_protect_info);
1196   }
1197 
1198   if (restart_input || config_updated) {
1199     // NOTE: Currently, the input is restarted by sending an upcall
1200     // and informing the Media Framework about the change.
1201     btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1202   }
1203 
1204   return true;
1205 }
1206 
bta_av_co_set_codec_audio_config(const btav_a2dp_codec_config_t & codec_audio_config)1207 bool bta_av_co_set_codec_audio_config(
1208     const btav_a2dp_codec_config_t& codec_audio_config) {
1209   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1210   bool restart_output = false;
1211   bool config_updated = false;
1212 
1213   // Find the peer that is currently open
1214   tBTA_AV_CO_PEER* p_peer = nullptr;
1215   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
1216     tBTA_AV_CO_PEER* p_peer_tmp = &bta_av_co_cb.peers[i];
1217     if (p_peer_tmp->opened) {
1218       p_peer = p_peer_tmp;
1219       break;
1220     }
1221   }
1222   if (p_peer == nullptr) {
1223     APPL_TRACE_ERROR("%s: no open peer to configure", __func__);
1224     return false;
1225   }
1226 
1227   // Use the current sink codec
1228   const tBTA_AV_CO_SINK* p_sink = p_peer->p_sink;
1229   if (p_sink == nullptr) {
1230     APPL_TRACE_ERROR("%s: cannot find peer SEP to configure", __func__);
1231     return false;
1232   }
1233 
1234   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1235   bta_av_co_get_peer_params(&peer_params);
1236   if (!bta_av_co_cb.codecs->setCodecAudioConfig(
1237           codec_audio_config, &peer_params, p_sink->codec_caps,
1238           result_codec_config, &restart_output, &config_updated)) {
1239     return false;
1240   }
1241 
1242   if (restart_output) {
1243     uint8_t num_protect = 0;
1244 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1245     if (p_peer->cp_active) num_protect = AVDT_CP_INFO_LEN;
1246 #endif
1247 
1248     bta_av_co_save_new_codec_config(p_peer, result_codec_config,
1249                                     p_sink->num_protect, p_sink->protect_info);
1250 
1251     APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, p_peer->handle);
1252     BTA_AvReconfig(p_peer->handle, true, p_sink->sep_info_idx,
1253                    p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
1254   }
1255 
1256   if (config_updated) {
1257     // NOTE: Currently, the input is restarted by sending an upcall
1258     // and informing the Media Framework about the change.
1259     btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1260   }
1261 
1262   return true;
1263 }
1264 
bta_av_get_a2dp_codecs(void)1265 A2dpCodecs* bta_av_get_a2dp_codecs(void) { return bta_av_co_cb.codecs; }
1266 
bta_av_get_a2dp_current_codec(void)1267 A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) {
1268   A2dpCodecConfig* current_codec;
1269 
1270   mutex_global_lock();
1271   if (bta_av_co_cb.codecs == nullptr) {
1272     mutex_global_unlock();
1273     return nullptr;
1274   }
1275   current_codec = bta_av_co_cb.codecs->getCurrentCodecConfig();
1276   mutex_global_unlock();
1277 
1278   return current_codec;
1279 }
1280 
bta_av_co_init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)1281 void bta_av_co_init(
1282     const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
1283   APPL_TRACE_DEBUG("%s", __func__);
1284 
1285   /* Reset the control block */
1286   bta_av_co_cb.reset();
1287 
1288 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
1289   bta_av_co_cp_set_flag(AVDT_CP_SCMS_COPY_NEVER);
1290 #else
1291   bta_av_co_cp_set_flag(AVDT_CP_SCMS_COPY_FREE);
1292 #endif
1293 
1294   /* Reset the current config */
1295   /* Protect access to bta_av_co_cb.codec_config */
1296   mutex_global_lock();
1297   bta_av_co_cb.codecs = new A2dpCodecs(codec_priorities);
1298   bta_av_co_cb.codecs->init();
1299   A2DP_InitDefaultCodec(bta_av_co_cb.codec_config);
1300   mutex_global_unlock();
1301 
1302   // NOTE: Unconditionally dispatch the event to make sure a callback with
1303   // the most recent codec info is generated.
1304   btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0);
1305 }
1306