Home | History | Annotate | Download | only in co
      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:
     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 
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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 
    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  ******************************************************************************/
    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.
    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  ******************************************************************************/
    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  ******************************************************************************/
    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 //
    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.
    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.
    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 
    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 
   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 
   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 
   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.
   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 
   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 
   1265 A2dpCodecs* bta_av_get_a2dp_codecs(void) { return bta_av_co_cb.codecs; }
   1266 
   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 
   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