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