Home | History | Annotate | Download | only in co
      1 /******************************************************************************
      2  *
      3  *  Copyright 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 <mutex>
     27 
     28 #include <base/bind.h>
     29 #include <base/logging.h>
     30 #include <string.h>
     31 
     32 #include "bt_target.h"
     33 
     34 #include "a2dp_api.h"
     35 #include "a2dp_sbc.h"
     36 #include "bta_av_api.h"
     37 #include "bta_av_ci.h"
     38 #include "bta_av_co.h"
     39 #include "bta_sys.h"
     40 
     41 #include "btif_av.h"
     42 #include "btif_av_co.h"
     43 #include "btif_util.h"
     44 #include "osi/include/osi.h"
     45 #include "osi/include/properties.h"
     46 
     47 // Macro to retrieve the number of elements in a statically allocated array
     48 #define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0]))
     49 
     50 // Macro to convert BTA AV audio handle to index and vice versa
     51 #define BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle) \
     52   (((bta_av_handle) & (~BTA_AV_CHNL_MSK)) - 1)
     53 #define BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(index) \
     54   (((index) + 1) | BTA_AV_CHNL_AUDIO)
     55 
     56 class BtaAvCoSep {
     57  public:
     58   BtaAvCoSep()
     59       : sep_info_idx(0), seid(0), codec_caps{}, num_protect(0), protect_info{} {
     60     Reset();
     61   }
     62 
     63   /**
     64    * Reset the state.
     65    */
     66   void Reset() {
     67     sep_info_idx = 0;
     68     seid = 0;
     69     memset(codec_caps, 0, sizeof(codec_caps));
     70     num_protect = 0;
     71     memset(protect_info, 0, sizeof(protect_info));
     72   }
     73 
     74   uint8_t sep_info_idx;                    // Local SEP index (in BTA tables)
     75   uint8_t seid;                            // Peer SEP index (in peer tables)
     76   uint8_t codec_caps[AVDT_CODEC_SIZE];     // Peer SEP codec capabilities
     77   uint8_t num_protect;                     // Peer SEP number of CP elements
     78   uint8_t protect_info[AVDT_CP_INFO_LEN];  // Peer SEP content protection info
     79 };
     80 
     81 class BtaAvCoPeer {
     82  public:
     83   BtaAvCoPeer()
     84       : addr(RawAddress::kEmpty),
     85         num_sinks(0),
     86         num_sources(0),
     87         num_seps(0),
     88         num_rx_sinks(0),
     89         num_rx_sources(0),
     90         num_sup_sinks(0),
     91         num_sup_sources(0),
     92         p_sink(nullptr),
     93         p_source(nullptr),
     94         codec_config{},
     95         acceptor(false),
     96         reconfig_needed(false),
     97         opened(false),
     98         mtu(0),
     99         uuid_to_connect(0),
    100         bta_av_handle_(0),
    101         codecs_(nullptr),
    102         content_protect_active_(false) {
    103     Reset(0);
    104   }
    105 
    106   /**
    107    * Initialize the state.
    108    *
    109    * @param codec_priorities the codec priorities to use for the initialization
    110    */
    111   void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities);
    112 
    113   /**
    114    * Reset the state.
    115    *
    116    * @param bta_av_handle the BTA AV handle to use
    117    */
    118   void Reset(tBTA_AV_HNDL bta_av_handle);
    119 
    120   /**
    121    * Get the BTA AV handle.
    122    *
    123    * @return the BTA AV handle
    124    */
    125   tBTA_AV_HNDL BtaAvHandle() const { return bta_av_handle_; }
    126 
    127   /**
    128    * Get the A2DP codecs.
    129    *
    130    * @return the A2DP codecs
    131    */
    132   A2dpCodecs* GetCodecs() { return codecs_; }
    133 
    134   bool ContentProtectActive() const { return content_protect_active_; }
    135   void SetContentProtectActive(bool cp_active) {
    136     content_protect_active_ = cp_active;
    137   }
    138 
    139   RawAddress addr;                                // Peer address
    140   BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX];    // Supported sinks
    141   BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX];  // Supported sources
    142   uint8_t num_sinks;                      // Total number of sinks at peer
    143   uint8_t num_sources;                    // Total number of sources at peer
    144   uint8_t num_seps;                       // Total number of SEPs at peer
    145   uint8_t num_rx_sinks;                   // Number of received sinks
    146   uint8_t num_rx_sources;                 // Number of received sources
    147   uint8_t num_sup_sinks;                  // Number of supported sinks
    148   uint8_t num_sup_sources;                // Number of supported sources
    149   const BtaAvCoSep* p_sink;               // Currently selected sink
    150   const BtaAvCoSep* p_source;             // Currently selected source
    151   uint8_t codec_config[AVDT_CODEC_SIZE];  // Current codec configuration
    152   bool acceptor;                          // True if acceptor
    153   bool reconfig_needed;                   // True if reconfiguration is needed
    154   bool opened;                            // True if opened
    155   uint16_t mtu;                           // Maximum Transmit Unit size
    156   uint16_t uuid_to_connect;               // UUID of peer device
    157 
    158  private:
    159   tBTA_AV_HNDL bta_av_handle_;   // BTA AV handle to use
    160   A2dpCodecs* codecs_;           // Locally supported codecs
    161   bool content_protect_active_;  // True if Content Protect is active
    162 };
    163 
    164 class BtaAvCo {
    165  public:
    166   BtaAvCo(bool content_protect_enabled)
    167       : active_peer_(nullptr),
    168         codec_config_{},
    169         content_protect_enabled_(content_protect_enabled),
    170         content_protect_flag_(0) {
    171     Reset();
    172   }
    173 
    174   /**
    175    * Initialize the state.
    176    *
    177    * @param codec_priorities the codec priorities to use for the initialization
    178    */
    179   void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities);
    180 
    181   /**
    182    * Get the current codec configuration for the active peer.
    183    *
    184    * @return the current codec configuration if found, otherwise nullptr
    185    */
    186   A2dpCodecConfig* GetActivePeerCurrentCodec();
    187 
    188   /**
    189    * Get the current codec configuration for a peer.
    190    *
    191    * @param peer_address the peer address
    192    * @return the current codec configuration if found, otherwise nullptr
    193    */
    194   A2dpCodecConfig* GetPeerCurrentCodec(const RawAddress& peer_address);
    195 
    196   /**
    197    * Find the peer UUID for a given BTA AV handle.
    198    *
    199    * @param bta_av_handle the BTA AV handle to use
    200    * @return the peer UUID if found, otherwise 0
    201    */
    202   uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle);
    203 
    204   /**
    205    * Process the AVDTP discovery result: number of Stream End Points (SEP)
    206    * found during the AVDTP stream discovery process.
    207    *
    208    * @param bta_av_handle the BTA AV handle to identify the peer
    209    * @param peer_address the peer address
    210    * @param num_seps the number of discovered SEPs
    211    * @param num_sinks number of discovered Sink SEPs
    212    * @param num_sources number of discovered Source SEPs
    213    * @param uuid_local local UUID
    214    */
    215   void ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
    216                               const RawAddress& peer_address, uint8_t num_seps,
    217                               uint8_t num_sinks, uint8_t num_sources,
    218                               uint16_t uuid_local);
    219 
    220   /**
    221    * Process retrieved codec configuration and content protection from
    222    * Peer Sink SEP.
    223    *
    224    * @param bta_av_handle the BTA AV handle to identify the peer
    225    * @param peer_address the peer address
    226    * @param p_codec_info the peer sink capability filled-in by the caller.
    227    * On success, it will contain the current codec configuration for the peer.
    228    * @param p_sep_info_idx the peer SEP index for the corresponding peer
    229    * sink capability filled-in by the caller. On success, it will contain
    230    * the SEP index for the current codec configuration for the peer.
    231    * @param seid the peer SEP index in peer tables
    232    * @param p_num_protect the peer SEP number of content protection elements
    233    * filled-in by the caller. On success, it will contain the SEP number of
    234    * content protection elements for the current codec configuration for the
    235    * peer.
    236    * @param p_protect_info the peer SEP content protection info filled-in by
    237    * the caller. On success, it will contain the SEP content protection info
    238    * for the current codec configuration for the peer.
    239    * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL
    240    */
    241   tA2DP_STATUS ProcessSourceGetConfig(tBTA_AV_HNDL bta_av_handle,
    242                                       const RawAddress& peer_address,
    243                                       uint8_t* p_codec_info,
    244                                       uint8_t* p_sep_info_idx, uint8_t seid,
    245                                       uint8_t* p_num_protect,
    246                                       uint8_t* p_protect_info);
    247 
    248   /**
    249    * Process retrieved codec configuration and content protection from
    250    * Peer Source SEP.
    251    *
    252    * @param bta_av_handle the BTA AV handle to identify the peer
    253    * @param peer_address the peer address
    254    * @param p_codec_info the peer source capability filled-in by the caller.
    255    * On success, it will contain the current codec configuration for the peer.
    256    * @param p_sep_info_idx the peer SEP index for the corresponding peer
    257    * source capability filled-in by the caller. On success, it will contain
    258    * the SEP index for the current codec configuration for the peer.
    259    * @param seid the peer SEP index in peer tables
    260    * @param p_num_protect the peer SEP number of content protection elements
    261    * filled-in by the caller. On success, it will contain the SEP number of
    262    * content protection elements for the current codec configuration for the
    263    * peer.
    264    * @param p_protect_info the peer SEP content protection info filled-in by
    265    * the caller. On success, it will contain the SEP content protection info
    266    * for the current codec configuration for the peer.
    267    * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL
    268    */
    269   tA2DP_STATUS ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
    270                                     const RawAddress& peer_address,
    271                                     uint8_t* p_codec_info,
    272                                     uint8_t* p_sep_info_idx, uint8_t seid,
    273                                     uint8_t* p_num_protect,
    274                                     uint8_t* p_protect_info);
    275 
    276   /**
    277    * Process AVDTP Set Config to set the codec and content protection
    278    * configuration of the audio stream.
    279    *
    280    * @param bta_av_handle the BTA AV handle to identify the peer
    281    * @param peer_address the peer address
    282    * @param p_codec_info the codec configuration to set
    283    * @param seid stream endpoint ID of stream initiating the operation
    284    * @param peer_address the peer address
    285    * @param num_protect the peer SEP number of content protection elements
    286    * @param p_protect_info the peer SEP conntent protection info
    287    * @param t_local_sep the local SEP: AVDT_TSEP_SRC or AVDT_TSEP_SNK
    288    * @param avdt_handle the AVDTP handle
    289    */
    290   void ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
    291                         const RawAddress& peer_address,
    292                         const uint8_t* p_codec_info, uint8_t seid,
    293                         uint8_t num_protect, const uint8_t* p_protect_info,
    294                         uint8_t t_local_sep, uint8_t avdt_handle);
    295 
    296   /**
    297    * Process AVDTP Open when the stream connection is opened.
    298    *
    299    * @param bta_av_handle the BTA AV handle to identify the peer
    300    * @param peer_address the peer address
    301    * @param mtu the MTU of the connection
    302    */
    303   void ProcessOpen(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
    304                    uint16_t mtu);
    305 
    306   /**
    307    * Process AVDTP Close when the stream connection is closed.
    308    *
    309    * @param bta_av_handle the BTA AV handle to identify the peer
    310    * @param peer_address the peer address
    311    */
    312   void ProcessClose(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address);
    313 
    314   /**
    315    * Process AVDTP Start when the audio data streaming is started.
    316    *
    317    * @param bta_av_handle the BTA AV handle to identify the peer
    318    * @param peer_address the peer address
    319    * @param p_codec_info the codec configuration
    320    * @param p_no_rtp_header on return, set to true if the audio data packets
    321    * should not contain RTP header
    322    */
    323   void ProcessStart(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
    324                     const uint8_t* p_codec_info, bool* p_no_rtp_header);
    325 
    326   /**
    327    * Process AVDTP Stop when the audio data streaming is stopped.
    328    *
    329    * @param bta_av_handle the BTA AV handle to identify the peer
    330    * @param peer_address the peer address
    331    */
    332   void ProcessStop(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address);
    333 
    334   /**
    335    * Get the next encoded audio data packet to send.
    336    *
    337    * @param p_codec_info the codec configuration
    338    * @param p_timestamp on return, set to the timestamp of the data packet
    339    * @return the next encoded data packet or nullptr if no encoded data to send
    340    */
    341   BT_HDR* GetNextSourceDataPacket(const uint8_t* p_codec_info,
    342                                   uint32_t* p_timestamp);
    343 
    344   /**
    345    * An audio packet has been dropped.
    346    * This signal can be used by the encoder to reduce the encoder bit rate
    347    * setting.
    348    *
    349    * @param bta_av_handle the BTA AV handle to identify the peer
    350    * @param peer_address the peer address
    351    */
    352   void DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,
    353                             const RawAddress& peer_address);
    354 
    355   /**
    356    * Process AVDTP Audio Delay when the initial delay report is received by
    357    * the Source.
    358    *
    359    * @param bta_av_handle the BTA AV handle to identify the peer
    360    * @param peer_address the peer address
    361    * @param delay the reported delay in 1/10th of a millisecond
    362    */
    363   void ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,
    364                          const RawAddress& peer_address, uint16_t delay);
    365 
    366   /**
    367    * Update the MTU of the audio data connection.
    368    *
    369    * @param bta_av_handle the BTA AV handle to identify the peer
    370    * @param peer_address the peer address
    371    * @param mtu the new MTU of the audio data connection
    372    */
    373   void UpdateMtu(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
    374                  uint16_t mtu);
    375 
    376   /**
    377    * Set the active peer.
    378    *
    379    * @param peer_address the peer address
    380    * @return true on success, otherwise false
    381    */
    382   bool SetActivePeer(const RawAddress& peer_address);
    383 
    384   /**
    385    * Get the encoder parameters for a peer.
    386    *
    387    * @param peer_address the peer address
    388    * @param p_peer_params on return, set to the peer's encoder parameters
    389    */
    390   void GetPeerEncoderParameters(const RawAddress& peer_address,
    391                                 tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params);
    392 
    393   /**
    394    * Get the Source encoder interface for the current codec.
    395    *
    396    * @return the Source encoder interface for the current codec
    397    */
    398   const tA2DP_ENCODER_INTERFACE* GetSourceEncoderInterface();
    399 
    400   /**
    401    * Get the Sink decoder interface for the current codec.
    402    *
    403    * @return the Sink decoder interface for the current codec
    404    */
    405   const tA2DP_DECODER_INTERFACE* GetSinkDecoderInterface();
    406 
    407   /**
    408    * Set the codec user configuration.
    409    *
    410    * @param peer_address the peer address
    411    * @param codec_user_config the codec user configuration to set
    412    * @return true on success, otherwise false
    413    */
    414   bool SetCodecUserConfig(const RawAddress& peer_address,
    415                           const btav_a2dp_codec_config_t& codec_user_config);
    416 
    417   /**
    418    * Set the codec audio configuration.
    419    *
    420    * @param codec_audio_config the codec audio configuration to set
    421    * @return true on success, otherwise false
    422    */
    423   bool SetCodecAudioConfig(const btav_a2dp_codec_config_t& codec_audio_config);
    424 
    425   /**
    426    * Report the source codec state for a peer
    427    *
    428    * @param p_peer the peer to report
    429    * @return true on success, otherwise false
    430    */
    431   bool ReportSourceCodecState(BtaAvCoPeer* p_peer);
    432 
    433   /**
    434    * Report the sink codec state for a peer
    435    *
    436    * @param p_peer the peer to report
    437    * @return true on success, otherwise false
    438    */
    439   bool ReportSinkCodecState(BtaAvCoPeer* p_peer);
    440 
    441   /**
    442    * Get the content protection flag.
    443    *
    444    * @return the content protection flag. It should be one of the following:
    445    * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE
    446    */
    447   uint8_t ContentProtectFlag() const { return content_protect_flag_; }
    448 
    449   /**
    450    * Set the content protection flag.
    451    *
    452    * @param cp_flag the content protection flag. It should be one of the
    453    * following:
    454    * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE
    455    * NOTE: If Content Protection is not enabled on the system, then
    456    * the only acceptable vailue is AVDT_CP_SCMS_COPY_FREE.
    457    */
    458   void SetContentProtectFlag(uint8_t cp_flag) {
    459     if (!ContentProtectEnabled() && (cp_flag != AVDT_CP_SCMS_COPY_FREE)) {
    460       return;
    461     }
    462     content_protect_flag_ = cp_flag;
    463   }
    464 
    465   /**
    466    * Dump debug-related information.
    467    *
    468    * @param fd the file descritor to use for writing the ASCII formatted
    469    * information
    470    */
    471   void DebugDump(int fd);
    472 
    473   /**
    474    * Find the peer entry for a given peer address.
    475    *
    476    * @param peer_address the peer address to use
    477    * @return the peer entry if found, otherwise nullptr
    478    */
    479   BtaAvCoPeer* FindPeer(const RawAddress& peer_address);
    480 
    481   /**
    482    * Find the peer Sink SEP entry for a given codec index.
    483    *
    484    * @param p_peer the peer to use
    485    * @param codec_index the codec index to use
    486    * @return the peer Sink SEP for the codec index if found, otherwise nullptr
    487    */
    488   BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer,
    489                            btav_a2dp_codec_index_t codec_index);
    490 
    491   /**
    492    * Find the peer Source SEP entry for a given codec index.
    493    *
    494    * @param p_peer the peer to use
    495    * @param codec_config the codec index to use
    496    * @return the peer Source SEP for the codec index if found, otherwise nullptr
    497    */
    498   BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer,
    499                              btav_a2dp_codec_index_t codec_index);
    500 
    501  private:
    502   /**
    503    * Reset the state.
    504    */
    505   void Reset();
    506 
    507   /**
    508    * Find the peer entry for a given BTA AV handle.
    509    *
    510    * @param bta_av_handle the BTA AV handle to use
    511    * @return the peer entry if found, otherwise nullptr
    512    */
    513   BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle);
    514 
    515   /**
    516    * Find the peer entry for a given BTA AV handle and update it with the
    517    * peer address.
    518    *
    519    * @param bta_av_handle the BTA AV handle to use
    520    * @param peer_address the peer address
    521    * @return the peer entry if found, otherwise nullptr
    522    */
    523   BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
    524                                  const RawAddress& peer_address);
    525 
    526   /**
    527    * Select the Source codec configuration based on peer codec support.
    528    *
    529    * Furthermore, the local state for the remaining non-selected codecs is
    530    * updated to reflect whether the codec is selectable.
    531    *
    532    * @param p_peer the peer to use
    533    * @return a pointer to the corresponding SEP Sink entry on success,
    534    * otherwise nullptr
    535    */
    536   const BtaAvCoSep* SelectSourceCodec(BtaAvCoPeer* p_peer);
    537 
    538   /**
    539    * Select the Sink codec configuration based on peer codec support.
    540    *
    541    * Furthermore, the local state for the remaining non-selected codecs is
    542    * updated to reflect whether the codec is selectable.
    543    *
    544    * @param p_peer the peer to use
    545    * @return a pointer to the corresponding SEP Source entry on success,
    546    * otherwise nullptr
    547    */
    548   const BtaAvCoSep* SelectSinkCodec(BtaAvCoPeer* p_peer);
    549 
    550   /**
    551    * Save new codec configuration.
    552    *
    553    * @param p_peer the peer to use
    554    * @param new_codec_config the new codec configuration to use
    555    * @param num_protect the number of content protection elements
    556    * @param p_protect_info the content protection info to use
    557    */
    558   void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config,
    559                           uint8_t num_protect, const uint8_t* p_protect_info);
    560 
    561   /**
    562    * Set the Over-The-Air preferred codec configuration.
    563    *
    564    * The OTA prefered codec configuration is ignored if the current
    565    * codec configuration contains explicit user configuration, or if the
    566    * codec configuration for the same codec contains explicit user
    567    * configuration.
    568    *
    569    * @param p_peer is the peer device that sent the OTA codec configuration
    570    * @param p_ota_codec_config contains the received OTA A2DP codec
    571    * configuration from the remote peer. Note: this is not the peer codec
    572    * capability, but the codec configuration that the peer would like to use.
    573    * @param num_protect is the number of content protection methods to use
    574    * @param p_protect_info contains the content protection information to use.
    575    * @param p_restart_output if there is a change in the encoder configuration
    576    * that requires restarting of the A2DP connection, flag |p_restart_output|
    577    * is set to true.
    578    * @return true on success, otherwise false
    579    */
    580   bool SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config,
    581                          uint8_t num_protect, const uint8_t* p_protect_info,
    582                          bool* p_restart_output);
    583 
    584   /**
    585    * Update all selectable Source codecs with the corresponding codec
    586    * information from a Sink peer.
    587    *
    588    * @param p_peer the peer Sink SEP to use
    589    * @return the number of codecs that have been updated
    590    */
    591   size_t UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer);
    592 
    593   /**
    594    * Update a selectable Source codec with the corresponding codec information
    595    * from a Sink peer.
    596    *
    597    * @param codec_config the codec config info to identify the codec to update
    598    * @param p_peer the peer Sink SEP to use
    599    * @return true if the codec is updated, otherwise false
    600    */
    601   bool UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config,
    602                                    BtaAvCoPeer* p_peer);
    603 
    604   /**
    605    * Update all selectable Sink codecs with the corresponding codec
    606    * information from a Source peer.
    607    *
    608    * @param p_peer the peer Source SEP to use
    609    * @return the number of codecs that have been updated
    610    */
    611   size_t UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer);
    612 
    613   /**
    614    * Update a selectable Sink codec with the corresponding codec information
    615    * from a Source peer.
    616    *
    617    * @param codec_config the codec config info to identify the codec to update
    618    * @param p_peer the peer Source SEP to use
    619    * @return true if the codec is updated, otherwise false
    620    */
    621   bool UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config,
    622                                  BtaAvCoPeer* p_peer);
    623 
    624   /**
    625    * Attempt to select Source codec configuration for a Sink peer.
    626    *
    627    * @param codec_config the codec configuration to use
    628    * @param p_peer the Sink peer to use
    629    * @return a pointer to the corresponding SEP Sink entry on success,
    630    * otnerwise nullptr
    631    */
    632   const BtaAvCoSep* AttemptSourceCodecSelection(
    633       const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer);
    634 
    635   /**
    636    * Attempt to select Sink codec configuration for a Source peer.
    637    *
    638    * @param codec_config the codec configuration to use
    639    * @param p_peer the Source peer to use
    640    * @return a pointer to the corresponding SEP Source entry on success,
    641    * otnerwise nullptr
    642    */
    643   const BtaAvCoSep* AttemptSinkCodecSelection(
    644       const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer);
    645 
    646   /**
    647    * Check if a peer SEP has content protection enabled.
    648    *
    649    * @param p_sep the peer SEP to check
    650    * @return true if the peer SEP has content protection enabled,
    651    * otherwise false
    652    */
    653   bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep);
    654 
    655   /**
    656    * Check if a content protection service is SCMS-T.
    657    *
    658    * @param p_orotect_info the content protection info to check
    659    * @return true if the Contention Protection in @param p_protect_info
    660    * is SCMS-T, otherwise false
    661    */
    662   static bool ContentProtectIsScmst(const uint8_t* p_protect_info);
    663 
    664   /**
    665    * Check if audio protect info contains SCMS-T Content Protection.
    666    *
    667    * @param num_protect number of protect schemes
    668    * @param p_protect_info the protect info to check
    669    * @return true if @param p_protect_info contains SCMS-T, otherwise false
    670    */
    671   static bool AudioProtectHasScmst(uint8_t num_protect,
    672                                    const uint8_t* p_protect_info);
    673 
    674   bool ContentProtectEnabled() const { return content_protect_enabled_; }
    675 
    676   std::recursive_mutex codec_lock_;  // Protect access to the codec state
    677   std::vector<btav_a2dp_codec_config_t> codec_priorities_;  // Configured
    678   BtaAvCoPeer peers_[BTA_AV_NUM_STRS];     // Connected peer information
    679   BtaAvCoPeer* active_peer_;               // The current active peer
    680   uint8_t codec_config_[AVDT_CODEC_SIZE];  // Current codec configuration
    681   const bool content_protect_enabled_;     // True if Content Protect is enabled
    682   uint8_t content_protect_flag_;           // Content Protect flag
    683 };
    684 
    685 // SCMS-T protect info
    686 const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00};
    687 
    688 // Control block instance
    689 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
    690 static const bool kContentProtectEnabled = true;
    691 #else
    692 static const bool kContentProtectEnabled = false;
    693 #endif
    694 static BtaAvCo bta_av_co_cb(kContentProtectEnabled);
    695 
    696 void BtaAvCoPeer::Init(
    697     const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
    698   Reset(bta_av_handle_);
    699   // Reset the current config
    700   codecs_ = new A2dpCodecs(codec_priorities);
    701   codecs_->init();
    702   A2DP_InitDefaultCodec(codec_config);
    703 }
    704 
    705 void BtaAvCoPeer::Reset(tBTA_AV_HNDL bta_av_handle) {
    706   addr = RawAddress::kEmpty;
    707   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sinks); i++) {
    708     BtaAvCoSep& sink = sinks[i];
    709     sink.Reset();
    710   }
    711   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sources); i++) {
    712     BtaAvCoSep& source = sources[i];
    713     source.Reset();
    714   }
    715   num_sinks = 0;
    716   num_sources = 0;
    717   num_seps = 0;
    718   num_rx_sinks = 0;
    719   num_rx_sources = 0;
    720   num_sup_sinks = 0;
    721   num_sup_sources = 0;
    722   p_sink = nullptr;
    723   p_source = nullptr;
    724   memset(codec_config, 0, sizeof(codec_config));
    725   acceptor = false;
    726   reconfig_needed = false;
    727   opened = false;
    728   mtu = 0;
    729   uuid_to_connect = 0;
    730 
    731   bta_av_handle_ = bta_av_handle;
    732   delete codecs_;
    733   codecs_ = nullptr;
    734   content_protect_active_ = false;
    735 }
    736 
    737 void BtaAvCo::Init(
    738     const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
    739   APPL_TRACE_DEBUG("%s", __func__);
    740 
    741   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
    742 
    743   // Reset the control block
    744   Reset();
    745   codec_priorities_ = codec_priorities;
    746 
    747   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
    748     BtaAvCoPeer* p_peer = &peers_[i];
    749     p_peer->Init(codec_priorities);
    750   }
    751 }
    752 
    753 void BtaAvCo::Reset() {
    754   codec_priorities_.clear();
    755   active_peer_ = nullptr;
    756   content_protect_flag_ = 0;
    757   memset(codec_config_, 0, sizeof(codec_config_));
    758 
    759   if (ContentProtectEnabled()) {
    760     SetContentProtectFlag(AVDT_CP_SCMS_COPY_NEVER);
    761   } else {
    762     SetContentProtectFlag(AVDT_CP_SCMS_COPY_FREE);
    763   }
    764 
    765   // Reset the peers and initialize the handles
    766   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
    767     BtaAvCoPeer* p_peer = &peers_[i];
    768     p_peer->Reset(BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(i));
    769   }
    770 }
    771 
    772 A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() {
    773   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
    774 
    775   if (active_peer_ == nullptr || active_peer_->GetCodecs() == nullptr) {
    776     return nullptr;
    777   }
    778   return active_peer_->GetCodecs()->getCurrentCodecConfig();
    779 }
    780 
    781 A2dpCodecConfig* BtaAvCo::GetPeerCurrentCodec(const RawAddress& peer_address) {
    782   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
    783 
    784   BtaAvCoPeer* peer = FindPeer(peer_address);
    785   if (peer == nullptr || peer->GetCodecs() == nullptr) {
    786     return nullptr;
    787   }
    788   return peer->GetCodecs()->getCurrentCodecConfig();
    789 }
    790 
    791 BtaAvCoPeer* BtaAvCo::FindPeer(const RawAddress& peer_address) {
    792   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
    793     BtaAvCoPeer* p_peer = &peers_[i];
    794     if (p_peer->addr == peer_address) {
    795       return p_peer;
    796     }
    797   }
    798   return nullptr;
    799 }
    800 
    801 BtaAvCoPeer* BtaAvCo::FindPeer(tBTA_AV_HNDL bta_av_handle) {
    802   uint8_t index;
    803 
    804   index = BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle);
    805 
    806   APPL_TRACE_DEBUG("%s: bta_av_handle = 0x%x index = %d", __func__,
    807                    bta_av_handle, index);
    808 
    809   // Sanity check
    810   if (index >= BTA_AV_CO_NUM_ELEMENTS(peers_)) {
    811     APPL_TRACE_ERROR(
    812         "%s: peer index %d for BTA AV handle 0x%x is out of bounds", __func__,
    813         index, bta_av_handle);
    814     return nullptr;
    815   }
    816 
    817   return &peers_[index];
    818 }
    819 
    820 BtaAvCoPeer* BtaAvCo::FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
    821                                         const RawAddress& peer_address) {
    822   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle = 0x%x", __func__,
    823                    peer_address.ToString().c_str(), bta_av_handle);
    824 
    825   BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
    826   if (p_peer == nullptr) {
    827     APPL_TRACE_ERROR("%s: peer entry for BTA AV handle 0x%x peer %s not found",
    828                      __func__, bta_av_handle, peer_address.ToString().c_str());
    829     return nullptr;
    830   }
    831 
    832   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle = 0x%x previous address %s",
    833                    __func__, peer_address.ToString().c_str(), bta_av_handle,
    834                    p_peer->addr.ToString().c_str());
    835   p_peer->addr = peer_address;
    836   return p_peer;
    837 }
    838 
    839 uint16_t BtaAvCo::FindPeerUuid(tBTA_AV_HNDL bta_av_handle) {
    840   BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
    841   if (p_peer == nullptr) {
    842     return 0;
    843   }
    844   return p_peer->uuid_to_connect;
    845 }
    846 
    847 void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
    848                                      const RawAddress& peer_address,
    849                                      uint8_t num_seps, uint8_t num_sinks,
    850                                      uint8_t num_sources, uint16_t uuid_local) {
    851   APPL_TRACE_DEBUG(
    852       "%s: peer %s bta_av_handle:0x%x num_seps:%d num_sinks:%d num_sources:%d",
    853       __func__, peer_address.ToString().c_str(), bta_av_handle, num_seps,
    854       num_sinks, num_sources);
    855 
    856   // Find the peer
    857   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
    858   if (p_peer == nullptr) {
    859     APPL_TRACE_ERROR(
    860         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
    861         __func__, bta_av_handle, peer_address.ToString().c_str());
    862     return;
    863   }
    864 
    865   /* Sanity check : this should never happen */
    866   if (p_peer->opened) {
    867     APPL_TRACE_ERROR("%s: peer %s already opened", __func__,
    868                      peer_address.ToString().c_str());
    869   }
    870 
    871   /* Copy the discovery results */
    872   p_peer->addr = peer_address;
    873   p_peer->num_sinks = num_sinks;
    874   p_peer->num_sources = num_sources;
    875   p_peer->num_seps = num_seps;
    876   p_peer->num_rx_sinks = 0;
    877   p_peer->num_rx_sources = 0;
    878   p_peer->num_sup_sinks = 0;
    879   p_peer->num_sup_sources = 0;
    880   if (uuid_local == UUID_SERVCLASS_AUDIO_SINK) {
    881     p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SOURCE;
    882   } else if (uuid_local == UUID_SERVCLASS_AUDIO_SOURCE) {
    883     p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SINK;
    884   }
    885 }
    886 
    887 tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
    888     tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
    889     uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid,
    890     uint8_t* p_num_protect, uint8_t* p_protect_info) {
    891   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle:0x%x codec:%s seid:%d", __func__,
    892                    peer_address.ToString().c_str(), bta_av_handle,
    893                    A2DP_CodecName(p_codec_info), seid);
    894   APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
    895                    __func__, *p_num_protect, p_protect_info[0],
    896                    p_protect_info[1], p_protect_info[2]);
    897   APPL_TRACE_DEBUG("%s: codec: %s", __func__,
    898                    A2DP_CodecInfoString(p_codec_info).c_str());
    899 
    900   // Find the peer
    901   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
    902   if (p_peer == nullptr) {
    903     APPL_TRACE_ERROR(
    904         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
    905         __func__, bta_av_handle, peer_address.ToString().c_str());
    906     return A2DP_FAIL;
    907   }
    908   APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)",
    909                    __func__, p_peer->opened, p_peer->num_sinks,
    910                    p_peer->num_rx_sinks, p_peer->num_sup_sinks);
    911 
    912   p_peer->num_rx_sinks++;
    913 
    914   // Check the peer's Sink codec
    915   if (A2DP_IsPeerSinkCodecValid(p_codec_info)) {
    916     // If there is room for a new one
    917     if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) {
    918       BtaAvCoSep* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++];
    919 
    920       APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
    921                        p_codec_info[1], p_codec_info[2], p_codec_info[3],
    922                        p_codec_info[4], p_codec_info[5], p_codec_info[6]);
    923 
    924       memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
    925       p_sink->sep_info_idx = *p_sep_info_idx;
    926       p_sink->seid = seid;
    927       p_sink->num_protect = *p_num_protect;
    928       memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
    929     } else {
    930       APPL_TRACE_ERROR("%s: peer %s : no more room for Sink info", __func__,
    931                        p_peer->addr.ToString().c_str());
    932     }
    933   }
    934 
    935   // Check if this is the last Sink get capabilities or all supported codec
    936   // capabilities are retrieved.
    937   if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
    938       (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
    939     return A2DP_FAIL;
    940   }
    941   APPL_TRACE_DEBUG("%s: last Sink codec reached for peer %s", __func__,
    942                    p_peer->addr.ToString().c_str());
    943 
    944   // Select the Source codec
    945   const BtaAvCoSep* p_sink = nullptr;
    946   if (p_peer->acceptor) {
    947     UpdateAllSelectableSourceCodecs(p_peer);
    948     if (p_peer->p_sink == nullptr) {
    949       // Update the selected codec
    950       p_peer->p_sink =
    951           FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_peer->codec_config));
    952     }
    953     p_sink = p_peer->p_sink;
    954     if (p_sink == nullptr) {
    955       APPL_TRACE_ERROR("%s: cannot find the selected codec for peer %s",
    956                        __func__, p_peer->addr.ToString().c_str());
    957       return A2DP_FAIL;
    958     }
    959   } else {
    960     p_sink = SelectSourceCodec(p_peer);
    961     if (p_sink == nullptr) {
    962       APPL_TRACE_ERROR("%s: cannot set up codec for peer %s", __func__,
    963                        p_peer->addr.ToString().c_str());
    964       return A2DP_FAIL;
    965     }
    966   }
    967 
    968   // By default, no content protection
    969   *p_num_protect = 0;
    970   if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
    971     *p_num_protect = AVDT_CP_INFO_LEN;
    972     memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
    973   }
    974 
    975   // If acceptor -> reconfig otherwise reply for configuration
    976   *p_sep_info_idx = p_sink->sep_info_idx;
    977   APPL_TRACE_EVENT("%s: peer %s acceptor:%s reconfig_needed:%s", __func__,
    978                    p_peer->addr.ToString().c_str(),
    979                    (p_peer->acceptor) ? "true" : "false",
    980                    (p_peer->reconfig_needed) ? "true" : "false");
    981   if (p_peer->acceptor) {
    982     if (p_peer->reconfig_needed) {
    983       APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x) for peer %s", __func__,
    984                        bta_av_handle, p_peer->addr.ToString().c_str());
    985       BTA_AvReconfig(bta_av_handle, true, p_sink->sep_info_idx,
    986                      p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst);
    987     }
    988   } else {
    989     memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
    990   }
    991 
    992   return A2DP_SUCCESS;
    993 }
    994 
    995 tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
    996                                            const RawAddress& peer_address,
    997                                            uint8_t* p_codec_info,
    998                                            uint8_t* p_sep_info_idx,
    999                                            uint8_t seid, uint8_t* p_num_protect,
   1000                                            uint8_t* p_protect_info) {
   1001   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1002 
   1003   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle:0x%x codec:%s seid:%d", __func__,
   1004                    peer_address.ToString().c_str(), bta_av_handle,
   1005                    A2DP_CodecName(p_codec_info), seid);
   1006   APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
   1007                    __func__, *p_num_protect, p_protect_info[0],
   1008                    p_protect_info[1], p_protect_info[2]);
   1009   APPL_TRACE_DEBUG("%s: codec: %s", __func__,
   1010                    A2DP_CodecInfoString(p_codec_info).c_str());
   1011 
   1012   // Find the peer
   1013   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
   1014   if (p_peer == nullptr) {
   1015     APPL_TRACE_ERROR(
   1016         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
   1017         __func__, bta_av_handle, peer_address.ToString().c_str());
   1018     return A2DP_FAIL;
   1019   }
   1020   APPL_TRACE_DEBUG(
   1021       "%s: peer %s found (o=%d, n_sources=%d, n_rx_sources=%d, "
   1022       "n_sup_sources=%d)",
   1023       __func__, p_peer->addr.ToString().c_str(), p_peer->opened,
   1024       p_peer->num_sources, p_peer->num_rx_sources, p_peer->num_sup_sources);
   1025 
   1026   p_peer->num_rx_sources++;
   1027 
   1028   // Check the peer's Source codec
   1029   if (A2DP_IsPeerSourceCodecValid(p_codec_info)) {
   1030     // If there is room for a new one
   1031     if (p_peer->num_sup_sources < BTA_AV_CO_NUM_ELEMENTS(p_peer->sources)) {
   1032       BtaAvCoSep* p_source = &p_peer->sources[p_peer->num_sup_sources++];
   1033 
   1034       APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
   1035                        p_codec_info[1], p_codec_info[2], p_codec_info[3],
   1036                        p_codec_info[4], p_codec_info[5], p_codec_info[6]);
   1037 
   1038       memcpy(p_source->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
   1039       p_source->sep_info_idx = *p_sep_info_idx;
   1040       p_source->seid = seid;
   1041       p_source->num_protect = *p_num_protect;
   1042       memcpy(p_source->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
   1043     } else {
   1044       APPL_TRACE_ERROR("%s: peer %s : no more room for Source info", __func__,
   1045                        p_peer->addr.ToString().c_str());
   1046     }
   1047   }
   1048 
   1049   // Check if this is the last Source get capabilities or all supported codec
   1050   // capabilities are retrieved.
   1051   if ((p_peer->num_rx_sources != p_peer->num_sources) &&
   1052       (p_peer->num_sup_sources != BTA_AV_CO_NUM_ELEMENTS(p_peer->sources))) {
   1053     return A2DP_FAIL;
   1054   }
   1055   APPL_TRACE_DEBUG("%s: last Source codec reached for peer %s", __func__,
   1056                    p_peer->addr.ToString().c_str());
   1057 
   1058   // Select the Sink codec
   1059   const BtaAvCoSep* p_source = nullptr;
   1060   if (p_peer->acceptor) {
   1061     UpdateAllSelectableSinkCodecs(p_peer);
   1062     if (p_peer->p_source == nullptr) {
   1063       // Update the selected codec
   1064       p_peer->p_source =
   1065           FindPeerSource(p_peer, A2DP_SinkCodecIndex(p_peer->codec_config));
   1066     }
   1067     p_source = p_peer->p_source;
   1068     if (p_source == nullptr) {
   1069       APPL_TRACE_ERROR("%s: cannot find the selected codec for peer %s",
   1070                        __func__, p_peer->addr.ToString().c_str());
   1071       return A2DP_FAIL;
   1072     }
   1073   } else {
   1074     p_source = SelectSinkCodec(p_peer);
   1075     if (p_source == nullptr) {
   1076       APPL_TRACE_ERROR("%s: cannot set up codec for the peer %s", __func__,
   1077                        p_peer->addr.ToString().c_str());
   1078       return A2DP_FAIL;
   1079     }
   1080   }
   1081 
   1082   // By default, no content protection
   1083   *p_num_protect = 0;
   1084   if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
   1085     *p_num_protect = AVDT_CP_INFO_LEN;
   1086     memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
   1087   }
   1088 
   1089   // If acceptor -> reconfig otherwise reply for configuration
   1090   *p_sep_info_idx = p_source->sep_info_idx;
   1091   APPL_TRACE_EVENT("%s: peer %s acceptor:%s reconfig_needed:%s", __func__,
   1092                    p_peer->addr.ToString().c_str(),
   1093                    (p_peer->acceptor) ? "true" : "false",
   1094                    (p_peer->reconfig_needed) ? "true" : "false");
   1095   if (p_peer->acceptor) {
   1096     if (p_peer->reconfig_needed) {
   1097       APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x) for peer %s", __func__,
   1098                        bta_av_handle, p_peer->addr.ToString().c_str());
   1099       BTA_AvReconfig(bta_av_handle, true, p_source->sep_info_idx,
   1100                      p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst);
   1101     }
   1102   } else {
   1103     memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
   1104   }
   1105 
   1106   return A2DP_SUCCESS;
   1107 }
   1108 
   1109 void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
   1110                                UNUSED_ATTR const RawAddress& peer_address,
   1111                                const uint8_t* p_codec_info,
   1112                                UNUSED_ATTR uint8_t seid, uint8_t num_protect,
   1113                                const uint8_t* p_protect_info,
   1114                                uint8_t t_local_sep, uint8_t avdt_handle) {
   1115   tA2DP_STATUS status = A2DP_SUCCESS;
   1116   uint8_t category = A2DP_SUCCESS;
   1117   bool reconfig_needed = false;
   1118 
   1119   APPL_TRACE_DEBUG(
   1120       "%s: bta_av_handle=0x%x peer_address=%s seid=%d "
   1121       "num_protect=%d t_local_sep=%d avdt_handle=%d",
   1122       __func__, bta_av_handle, peer_address.ToString().c_str(), seid,
   1123       num_protect, t_local_sep, avdt_handle);
   1124   APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
   1125                    p_codec_info[1], p_codec_info[2], p_codec_info[3],
   1126                    p_codec_info[4], p_codec_info[5], p_codec_info[6]);
   1127   APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
   1128                    __func__, num_protect, p_protect_info[0], p_protect_info[1],
   1129                    p_protect_info[2]);
   1130   APPL_TRACE_DEBUG("%s: codec: %s", __func__,
   1131                    A2DP_CodecInfoString(p_codec_info).c_str());
   1132 
   1133   // Find the peer
   1134   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
   1135   if (p_peer == nullptr) {
   1136     APPL_TRACE_ERROR(
   1137         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
   1138         __func__, bta_av_handle, peer_address.ToString().c_str());
   1139     // Call call-in rejecting the configuration
   1140     bta_av_ci_setconfig(bta_av_handle, A2DP_BUSY, AVDT_ASC_CODEC, 0, nullptr,
   1141                         false, avdt_handle);
   1142     return;
   1143   }
   1144 
   1145   APPL_TRACE_DEBUG(
   1146       "%s: peer %s found (o=%d, n_sinks=%d, n_rx_sinks=%d, "
   1147       "n_sup_sinks=%d)",
   1148       __func__, p_peer->addr.ToString().c_str(), p_peer->opened,
   1149       p_peer->num_sinks, p_peer->num_rx_sinks, p_peer->num_sup_sinks);
   1150 
   1151   // Sanity check: should not be opened at this point
   1152   if (p_peer->opened) {
   1153     APPL_TRACE_ERROR("%s: peer %s already in use", __func__,
   1154                      p_peer->addr.ToString().c_str());
   1155   }
   1156 
   1157   if (num_protect != 0) {
   1158     if (ContentProtectEnabled()) {
   1159       if ((num_protect != 1) ||
   1160           !BtaAvCo::ContentProtectIsScmst(p_protect_info)) {
   1161         APPL_TRACE_ERROR("%s: wrong CP configuration for peer %s", __func__,
   1162                          p_peer->addr.ToString().c_str());
   1163         status = A2DP_BAD_CP_TYPE;
   1164         category = AVDT_ASC_PROTECT;
   1165       }
   1166     } else {
   1167       // Do not support content protection for the time being
   1168       APPL_TRACE_ERROR("%s: wrong CP configuration for peer %s", __func__,
   1169                        p_peer->addr.ToString().c_str());
   1170       status = A2DP_BAD_CP_TYPE;
   1171       category = AVDT_ASC_PROTECT;
   1172     }
   1173   }
   1174 
   1175   if (status == A2DP_SUCCESS) {
   1176     bool codec_config_supported = false;
   1177 
   1178     if (t_local_sep == AVDT_TSEP_SNK) {
   1179       APPL_TRACE_DEBUG("%s: peer %s is A2DP Source", __func__,
   1180                        p_peer->addr.ToString().c_str());
   1181       codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info);
   1182       if (codec_config_supported) {
   1183         // If Peer is Source, and our config subset matches with what is
   1184         // requested by peer, then just accept what peer wants.
   1185         SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info);
   1186       }
   1187     }
   1188     if (t_local_sep == AVDT_TSEP_SRC) {
   1189       APPL_TRACE_DEBUG("%s: peer %s is A2DP SINK", __func__,
   1190                        p_peer->addr.ToString().c_str());
   1191       // Ignore the restart_output flag: accepting the remote device's
   1192       // codec selection should not trigger codec reconfiguration.
   1193       bool dummy_restart_output = false;
   1194       if ((p_peer->GetCodecs() == nullptr) ||
   1195           !SetCodecOtaConfig(p_peer, p_codec_info, num_protect, p_protect_info,
   1196                              &dummy_restart_output)) {
   1197         APPL_TRACE_ERROR("%s: cannot set source codec %s for peer %s", __func__,
   1198                          A2DP_CodecName(p_codec_info),
   1199                          p_peer->addr.ToString().c_str());
   1200       } else {
   1201         codec_config_supported = true;
   1202         // Check if reconfiguration is needed
   1203         if (((num_protect == 1) && !p_peer->ContentProtectActive())) {
   1204           reconfig_needed = true;
   1205         }
   1206       }
   1207     }
   1208 
   1209     // Check if codec configuration is supported
   1210     if (!codec_config_supported) {
   1211       category = AVDT_ASC_CODEC;
   1212       status = A2DP_WRONG_CODEC;
   1213     }
   1214   }
   1215 
   1216   if (status != A2DP_SUCCESS) {
   1217     APPL_TRACE_DEBUG("%s: peer %s reject s=%d c=%d", __func__,
   1218                      p_peer->addr.ToString().c_str(), status, category);
   1219     // Call call-in rejecting the configuration
   1220     bta_av_ci_setconfig(bta_av_handle, status, category, 0, nullptr, false,
   1221                         avdt_handle);
   1222     return;
   1223   }
   1224 
   1225   // Mark that this is an acceptor peer
   1226   p_peer->acceptor = true;
   1227   p_peer->reconfig_needed = reconfig_needed;
   1228   APPL_TRACE_DEBUG("%s: peer %s accept reconf=%d", __func__,
   1229                    p_peer->addr.ToString().c_str(), reconfig_needed);
   1230   // Call call-in accepting the configuration
   1231   bta_av_ci_setconfig(bta_av_handle, A2DP_SUCCESS, A2DP_SUCCESS, 0, nullptr,
   1232                       reconfig_needed, avdt_handle);
   1233 }
   1234 
   1235 void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle,
   1236                           const RawAddress& peer_address, uint16_t mtu) {
   1237   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x mtu:%d", __func__,
   1238                    peer_address.ToString().c_str(), bta_av_handle, mtu);
   1239 
   1240   // Find the peer
   1241   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
   1242   if (p_peer == nullptr) {
   1243     APPL_TRACE_ERROR(
   1244         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
   1245         __func__, bta_av_handle, peer_address.ToString().c_str());
   1246     return;
   1247   }
   1248   p_peer->opened = true;
   1249   p_peer->mtu = mtu;
   1250 
   1251   // The first connected peer becomes the active peer
   1252   if (active_peer_ == nullptr) {
   1253     active_peer_ = p_peer;
   1254   }
   1255 }
   1256 
   1257 void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle,
   1258                            const RawAddress& peer_address) {
   1259   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
   1260                    peer_address.ToString().c_str(), bta_av_handle);
   1261   btif_av_reset_audio_delay();
   1262 
   1263   // Find the peer
   1264   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
   1265   if (p_peer == nullptr) {
   1266     APPL_TRACE_ERROR(
   1267         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
   1268         __func__, bta_av_handle, peer_address.ToString().c_str());
   1269     return;
   1270   }
   1271   // Reset the active peer
   1272   if (active_peer_ == p_peer) {
   1273     active_peer_ = nullptr;
   1274   }
   1275   // Mark the peer closed and clean the peer info
   1276   p_peer->Init(codec_priorities_);
   1277 }
   1278 
   1279 void BtaAvCo::ProcessStart(tBTA_AV_HNDL bta_av_handle,
   1280                            const RawAddress& peer_address,
   1281                            const uint8_t* p_codec_info, bool* p_no_rtp_header) {
   1282   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
   1283                    peer_address.ToString().c_str(), bta_av_handle);
   1284 
   1285   // Find the peer
   1286   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
   1287   if (p_peer == nullptr) {
   1288     APPL_TRACE_ERROR(
   1289         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
   1290         __func__, bta_av_handle, peer_address.ToString().c_str());
   1291     return;
   1292   }
   1293 
   1294   bool add_rtp_header =
   1295       A2DP_UsesRtpHeader(p_peer->ContentProtectActive(), p_codec_info);
   1296 
   1297   APPL_TRACE_DEBUG("%s: bta_av_handle: 0x%x add_rtp_header: %s", __func__,
   1298                    bta_av_handle, add_rtp_header ? "true" : "false");
   1299   *p_no_rtp_header = !add_rtp_header;
   1300 }
   1301 
   1302 void BtaAvCo::ProcessStop(tBTA_AV_HNDL bta_av_handle,
   1303                           const RawAddress& peer_address) {
   1304   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
   1305                    peer_address.ToString().c_str(), bta_av_handle);
   1306   // Nothing to do
   1307 }
   1308 
   1309 BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info,
   1310                                          uint32_t* p_timestamp) {
   1311   BT_HDR* p_buf;
   1312 
   1313   APPL_TRACE_DEBUG("%s: codec: %s", __func__, A2DP_CodecName(p_codec_info));
   1314 
   1315   p_buf = btif_a2dp_source_audio_readbuf();
   1316   if (p_buf == nullptr) return nullptr;
   1317 
   1318   /*
   1319    * Retrieve the timestamp information from the media packet,
   1320    * and set up the packet header.
   1321    *
   1322    * In media packet, the following information is available:
   1323    * p_buf->layer_specific : number of audio frames in the packet
   1324    * p_buf->word[0] : timestamp
   1325    */
   1326   if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1),
   1327                                p_timestamp) ||
   1328       !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) {
   1329     APPL_TRACE_ERROR("%s: unsupported codec type (%d)", __func__,
   1330                      A2DP_GetCodecType(p_codec_info));
   1331   }
   1332 
   1333   if (ContentProtectEnabled() && (active_peer_ != nullptr) &&
   1334       active_peer_->ContentProtectActive()) {
   1335     p_buf->len++;
   1336     p_buf->offset--;
   1337     uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1338     *p = ContentProtectFlag();
   1339   }
   1340 
   1341   return p_buf;
   1342 }
   1343 
   1344 void BtaAvCo::DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,
   1345                                    const RawAddress& peer_address) {
   1346   APPL_TRACE_ERROR("%s: peer %s dropped audio packet on handle 0x%x", __func__,
   1347                    peer_address.ToString().c_str(), bta_av_handle);
   1348 }
   1349 
   1350 void BtaAvCo::ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,
   1351                                 const RawAddress& peer_address,
   1352                                 uint16_t delay) {
   1353   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x delay:0x%x", __func__,
   1354                    peer_address.ToString().c_str(), bta_av_handle, delay);
   1355 
   1356   btif_av_set_audio_delay(delay);
   1357 }
   1358 
   1359 void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
   1360                         const RawAddress& peer_address, uint16_t mtu) {
   1361   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x mtu: %d", __func__,
   1362                    peer_address.ToString().c_str(), bta_av_handle, mtu);
   1363 
   1364   // Find the peer
   1365   BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
   1366   if (p_peer == nullptr) {
   1367     APPL_TRACE_ERROR(
   1368         "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
   1369         __func__, bta_av_handle, peer_address.ToString().c_str());
   1370     return;
   1371   }
   1372   p_peer->mtu = mtu;
   1373 }
   1374 
   1375 bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {
   1376   APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
   1377                    peer_address.ToString().c_str());
   1378 
   1379   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1380 
   1381   if (peer_address.IsEmpty()) {
   1382     // Reset the active peer;
   1383     active_peer_ = nullptr;
   1384     memset(codec_config_, 0, sizeof(codec_config_));
   1385     return true;
   1386   }
   1387 
   1388   // Find the peer
   1389   BtaAvCoPeer* p_peer = FindPeer(peer_address);
   1390   if (p_peer == nullptr) {
   1391     return false;
   1392   }
   1393 
   1394   active_peer_ = p_peer;
   1395   memcpy(codec_config_, active_peer_->codec_config, AVDT_CODEC_SIZE);
   1396   APPL_TRACE_DEBUG("%s: codec = %s", __func__,
   1397                    A2DP_CodecInfoString(codec_config_).c_str());
   1398   ReportSourceCodecState(active_peer_);
   1399   return true;
   1400 }
   1401 
   1402 void BtaAvCo::GetPeerEncoderParameters(
   1403     const RawAddress& peer_address,
   1404     tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
   1405   uint16_t min_mtu = 0xFFFF;
   1406   CHECK(p_peer_params != nullptr) << "Peer address " << peer_address;
   1407 
   1408   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1409 
   1410   // Compute the MTU
   1411   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
   1412     const BtaAvCoPeer* p_peer = &peers_[i];
   1413     if (!p_peer->opened) continue;
   1414     if (p_peer->addr != peer_address) continue;
   1415     if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu;
   1416   }
   1417   p_peer_params->peer_mtu = min_mtu;
   1418   p_peer_params->is_peer_edr = btif_av_is_peer_edr(peer_address);
   1419   p_peer_params->peer_supports_3mbps =
   1420       btif_av_peer_supports_3mbps(peer_address);
   1421   APPL_TRACE_DEBUG(
   1422       "%s: peer_address=%s peer_mtu=%d is_peer_edr=%s peer_supports_3mbps=%s",
   1423       __func__, peer_address.ToString().c_str(), p_peer_params->peer_mtu,
   1424       logbool(p_peer_params->is_peer_edr).c_str(),
   1425       logbool(p_peer_params->peer_supports_3mbps).c_str());
   1426 }
   1427 
   1428 const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() {
   1429   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1430 
   1431   return A2DP_GetEncoderInterface(codec_config_);
   1432 }
   1433 
   1434 const tA2DP_DECODER_INTERFACE* BtaAvCo::GetSinkDecoderInterface() {
   1435   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1436 
   1437   return A2DP_GetDecoderInterface(codec_config_);
   1438 }
   1439 
   1440 bool BtaAvCo::SetCodecUserConfig(
   1441     const RawAddress& peer_address,
   1442     const btav_a2dp_codec_config_t& codec_user_config) {
   1443   uint8_t result_codec_config[AVDT_CODEC_SIZE];
   1444   const BtaAvCoSep* p_sink = nullptr;
   1445   bool restart_input = false;
   1446   bool restart_output = false;
   1447   bool config_updated = false;
   1448   bool success = true;
   1449 
   1450   APPL_TRACE_DEBUG("%s: peer_address=%s codec_user_config=%s", __func__,
   1451                    peer_address.ToString().c_str(),
   1452                    codec_user_config.ToString().c_str());
   1453 
   1454   BtaAvCoPeer* p_peer = FindPeer(peer_address);
   1455   if (p_peer == nullptr) {
   1456     APPL_TRACE_ERROR("%s: cannot find peer %s to configure", __func__,
   1457                      peer_address.ToString().c_str());
   1458     success = false;
   1459     goto done;
   1460   }
   1461 
   1462   // Find the peer SEP codec to use
   1463   if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
   1464     p_sink = FindPeerSink(p_peer, codec_user_config.codec_type);
   1465   } else {
   1466     // Use the current sink codec
   1467     p_sink = p_peer->p_sink;
   1468   }
   1469   if (p_sink == nullptr) {
   1470     APPL_TRACE_ERROR(
   1471         "%s: peer %s : cannot find peer SEP to configure for codec type %d",
   1472         __func__, p_peer->addr.ToString().c_str(),
   1473         codec_user_config.codec_type);
   1474     success = false;
   1475     goto done;
   1476   }
   1477 
   1478   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
   1479   GetPeerEncoderParameters(p_peer->addr, &peer_params);
   1480   if (!p_peer->GetCodecs()->setCodecUserConfig(
   1481           codec_user_config, &peer_params, p_sink->codec_caps,
   1482           result_codec_config, &restart_input, &restart_output,
   1483           &config_updated)) {
   1484     success = false;
   1485     goto done;
   1486   }
   1487 
   1488   if (restart_output) {
   1489     uint8_t num_protect = 0;
   1490     if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
   1491       num_protect = AVDT_CP_INFO_LEN;
   1492     }
   1493 
   1494     p_sink = SelectSourceCodec(p_peer);
   1495     if (p_sink == nullptr) {
   1496       APPL_TRACE_ERROR("%s: peer %s : cannot set up codec for the peer SINK",
   1497                        __func__, p_peer->addr.ToString().c_str());
   1498       success = false;
   1499       goto done;
   1500     }
   1501     // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
   1502     if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
   1503         (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
   1504       APPL_TRACE_WARNING(
   1505           "%s: peer %s : not all peer's capabilities have been retrieved",
   1506           __func__, p_peer->addr.ToString().c_str());
   1507       success = false;
   1508       goto done;
   1509     }
   1510 
   1511     p_peer->acceptor = false;
   1512     APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x)", __func__,
   1513                      p_peer->BtaAvHandle());
   1514     BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
   1515                    p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
   1516   }
   1517 
   1518 done:
   1519   // NOTE: We unconditionally send the upcall even if there is no change
   1520   // or the user config failed. Thus, the caller would always know whether the
   1521   // request succeeded or failed.
   1522   // NOTE: Currently, the input is restarted by sending an upcall
   1523   // and informing the Media Framework about the change.
   1524   if (p_peer != nullptr) {
   1525     return ReportSourceCodecState(p_peer);
   1526   }
   1527 
   1528   return success;
   1529 }
   1530 
   1531 bool BtaAvCo::SetCodecAudioConfig(
   1532     const btav_a2dp_codec_config_t& codec_audio_config) {
   1533   uint8_t result_codec_config[AVDT_CODEC_SIZE];
   1534   bool restart_output = false;
   1535   bool config_updated = false;
   1536 
   1537   APPL_TRACE_DEBUG("%s: codec_audio_config: %s", __func__,
   1538                    codec_audio_config.ToString().c_str());
   1539 
   1540   // Find the peer that is currently open
   1541   BtaAvCoPeer* p_peer = active_peer_;
   1542   if (p_peer == nullptr) {
   1543     APPL_TRACE_ERROR("%s: no active peer to configure", __func__);
   1544     return false;
   1545   }
   1546 
   1547   // Use the current sink codec
   1548   const BtaAvCoSep* p_sink = p_peer->p_sink;
   1549   if (p_sink == nullptr) {
   1550     APPL_TRACE_ERROR("%s: peer %s : cannot find peer SEP to configure",
   1551                      __func__, p_peer->addr.ToString().c_str());
   1552     return false;
   1553   }
   1554 
   1555   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
   1556   GetPeerEncoderParameters(p_peer->addr, &peer_params);
   1557   if (!p_peer->GetCodecs()->setCodecAudioConfig(
   1558           codec_audio_config, &peer_params, p_sink->codec_caps,
   1559           result_codec_config, &restart_output, &config_updated)) {
   1560     return false;
   1561   }
   1562 
   1563   if (restart_output) {
   1564     uint8_t num_protect = 0;
   1565     if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
   1566       num_protect = AVDT_CP_INFO_LEN;
   1567     }
   1568 
   1569     SaveNewCodecConfig(p_peer, result_codec_config, p_sink->num_protect,
   1570                        p_sink->protect_info);
   1571 
   1572     // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
   1573     if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
   1574         (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
   1575       APPL_TRACE_WARNING(
   1576           "%s: peer %s : not all peer's capabilities have been retrieved",
   1577           __func__, p_peer->addr.ToString().c_str());
   1578     } else {
   1579       p_peer->acceptor = false;
   1580       APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x)", __func__,
   1581                        p_peer->BtaAvHandle());
   1582       BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
   1583                      p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
   1584     }
   1585   }
   1586 
   1587   if (config_updated) {
   1588     // NOTE: Currently, the input is restarted by sending an upcall
   1589     // and informing the Media Framework about the change.
   1590     return ReportSourceCodecState(p_peer);
   1591   }
   1592 
   1593   return true;
   1594 }
   1595 
   1596 bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) {
   1597   btav_a2dp_codec_config_t codec_config;
   1598   std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities;
   1599   std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities;
   1600 
   1601   APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
   1602                    p_peer->addr.ToString().c_str());
   1603   A2dpCodecs* codecs = p_peer->GetCodecs();
   1604   CHECK(codecs != nullptr);
   1605   if (!codecs->getCodecConfigAndCapabilities(&codec_config,
   1606                                              &codecs_local_capabilities,
   1607                                              &codecs_selectable_capabilities)) {
   1608     APPL_TRACE_WARNING(
   1609         "%s: Peer %s : error reporting audio source codec state: "
   1610         "cannot get codec config and capabilities",
   1611         __func__, p_peer->addr.ToString().c_str());
   1612     return false;
   1613   }
   1614   APPL_TRACE_DEBUG("%s: peer %s codec_config=%s", __func__,
   1615                    p_peer->addr.ToString().c_str(),
   1616                    codec_config.ToString().c_str());
   1617   btif_av_report_source_codec_state(p_peer->addr, codec_config,
   1618                                     codecs_local_capabilities,
   1619                                     codecs_selectable_capabilities);
   1620   return true;
   1621 }
   1622 
   1623 bool BtaAvCo::ReportSinkCodecState(BtaAvCoPeer* p_peer) {
   1624   APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
   1625                    p_peer->addr.ToString().c_str());
   1626   // Nothing to do (for now)
   1627   return true;
   1628 }
   1629 void BtaAvCo::DebugDump(int fd) {
   1630   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1631 
   1632   dprintf(fd, "\nA2DP Codecs and Peers State:\n");
   1633   dprintf(fd, "  Active peer: %s\n",
   1634           (active_peer_ != nullptr) ? active_peer_->addr.ToString().c_str()
   1635                                     : "null");
   1636 
   1637   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
   1638     const BtaAvCoPeer& peer = peers_[i];
   1639     dprintf(fd, "  Peer: %s\n", peer.addr.ToString().c_str());
   1640     dprintf(fd, "    Number of sinks: %u\n", peer.num_sinks);
   1641     dprintf(fd, "    Number of sources: %u\n", peer.num_sources);
   1642     dprintf(fd, "    Number of SEPs: %u\n", peer.num_seps);
   1643     dprintf(fd, "    Number of received sinks: %u\n", peer.num_rx_sinks);
   1644     dprintf(fd, "    Number of received sources: %u\n", peer.num_rx_sources);
   1645     dprintf(fd, "    Number of supported sinks: %u\n", peer.num_sup_sinks);
   1646     dprintf(fd, "    Number of supported sources: %u\n", peer.num_sup_sources);
   1647     dprintf(fd, "    Acceptor: %s\n", (peer.acceptor) ? "true" : "false");
   1648     dprintf(fd, "    Reconfig needed: %s\n",
   1649             (peer.reconfig_needed) ? "true" : "false");
   1650     dprintf(fd, "    Opened: %s\n", (peer.opened) ? "true" : "false");
   1651     dprintf(fd, "    MTU: %u\n", peer.mtu);
   1652     dprintf(fd, "    UUID to connect: 0x%x\n", peer.uuid_to_connect);
   1653     dprintf(fd, "    BTA AV handle: %u\n", peer.BtaAvHandle());
   1654   }
   1655 
   1656   //
   1657   // Active peer codec-specific stats
   1658   //
   1659   if (active_peer_ != nullptr) {
   1660     A2dpCodecs* a2dp_codecs = active_peer_->GetCodecs();
   1661     if (a2dp_codecs != nullptr) {
   1662       a2dp_codecs->debug_codec_dump(fd);
   1663     }
   1664   }
   1665 }
   1666 
   1667 bool BtaAvCo::ContentProtectIsScmst(const uint8_t* p_protect_info) {
   1668   APPL_TRACE_DEBUG("%s", __func__);
   1669 
   1670   if (*p_protect_info >= AVDT_CP_LOSC) {
   1671     uint16_t cp_id;
   1672     p_protect_info++;
   1673     STREAM_TO_UINT16(cp_id, p_protect_info);
   1674     if (cp_id == AVDT_CP_SCMS_T_ID) {
   1675       APPL_TRACE_DEBUG("%s: SCMS-T found", __func__);
   1676       return true;
   1677     }
   1678   }
   1679   return false;
   1680 }
   1681 
   1682 bool BtaAvCo::AudioProtectHasScmst(uint8_t num_protect,
   1683                                    const uint8_t* p_protect_info) {
   1684   APPL_TRACE_DEBUG("%s", __func__);
   1685   while (num_protect--) {
   1686     if (BtaAvCo::ContentProtectIsScmst(p_protect_info)) return true;
   1687     // Move to the next Content Protect schema
   1688     p_protect_info += *p_protect_info + 1;
   1689   }
   1690   APPL_TRACE_DEBUG("%s: SCMS-T not found", __func__);
   1691   return false;
   1692 }
   1693 
   1694 bool BtaAvCo::AudioSepHasContentProtection(const BtaAvCoSep* p_sep) {
   1695   APPL_TRACE_DEBUG("%s", __func__);
   1696 
   1697   // Check if content protection is enabled for this stream
   1698   if (ContentProtectFlag() != AVDT_CP_SCMS_COPY_FREE) {
   1699     return BtaAvCo::AudioProtectHasScmst(p_sep->num_protect,
   1700                                          p_sep->protect_info);
   1701   }
   1702 
   1703   APPL_TRACE_DEBUG("%s: not required", __func__);
   1704   return true;
   1705 }
   1706 
   1707 const BtaAvCoSep* BtaAvCo::SelectSourceCodec(BtaAvCoPeer* p_peer) {
   1708   const BtaAvCoSep* p_sink = nullptr;
   1709 
   1710   // Update all selectable codecs.
   1711   // This is needed to update the selectable parameters for each codec.
   1712   // NOTE: The selectable codec info is used only for informational purpose.
   1713   UpdateAllSelectableSourceCodecs(p_peer);
   1714 
   1715   // Select the codec
   1716   for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
   1717     APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
   1718     p_sink = AttemptSourceCodecSelection(*iter, p_peer);
   1719     if (p_sink != nullptr) {
   1720       APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
   1721       break;
   1722     }
   1723     APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
   1724   }
   1725 
   1726   // NOTE: Unconditionally dispatch the event to make sure a callback with
   1727   // the most recent codec info is generated.
   1728   ReportSourceCodecState(p_peer);
   1729 
   1730   return p_sink;
   1731 }
   1732 
   1733 const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) {
   1734   const BtaAvCoSep* p_source = nullptr;
   1735 
   1736   // Update all selectable codecs.
   1737   // This is needed to update the selectable parameters for each codec.
   1738   // NOTE: The selectable codec info is used only for informational purpose.
   1739   UpdateAllSelectableSinkCodecs(p_peer);
   1740 
   1741   // Select the codec
   1742   for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) {
   1743     APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
   1744     p_source = AttemptSinkCodecSelection(*iter, p_peer);
   1745     if (p_source != nullptr) {
   1746       APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
   1747       break;
   1748     }
   1749     APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
   1750   }
   1751 
   1752   // NOTE: Unconditionally dispatch the event to make sure a callback with
   1753   // the most recent codec info is generated.
   1754   ReportSinkCodecState(p_peer);
   1755 
   1756   return p_source;
   1757 }
   1758 
   1759 BtaAvCoSep* BtaAvCo::FindPeerSink(BtaAvCoPeer* p_peer,
   1760                                   btav_a2dp_codec_index_t codec_index) {
   1761   if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
   1762     APPL_TRACE_WARNING("%s: invalid codec index for peer %s", __func__,
   1763                        p_peer->addr.ToString().c_str());
   1764     return nullptr;
   1765   }
   1766 
   1767   // Find the peer Sink for the codec
   1768   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
   1769     BtaAvCoSep* p_sink = &p_peer->sinks[index];
   1770     btav_a2dp_codec_index_t peer_codec_index =
   1771         A2DP_SourceCodecIndex(p_sink->codec_caps);
   1772     if (peer_codec_index != codec_index) {
   1773       continue;
   1774     }
   1775     if (!AudioSepHasContentProtection(p_sink)) {
   1776       APPL_TRACE_DEBUG(
   1777           "%s: peer Sink for codec %s does not support "
   1778           "Content Protection",
   1779           __func__, A2DP_CodecIndexStr(codec_index));
   1780       continue;
   1781     }
   1782     return p_sink;
   1783   }
   1784   return nullptr;
   1785 }
   1786 
   1787 BtaAvCoSep* BtaAvCo::FindPeerSource(BtaAvCoPeer* p_peer,
   1788                                     btav_a2dp_codec_index_t codec_index) {
   1789   if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
   1790     APPL_TRACE_WARNING("%s: invalid codec index for peer %s", __func__,
   1791                        p_peer->addr.ToString().c_str());
   1792     return nullptr;
   1793   }
   1794 
   1795   // Find the peer Source for the codec
   1796   for (size_t index = 0; index < p_peer->num_sup_sources; index++) {
   1797     BtaAvCoSep* p_source = &p_peer->sources[index];
   1798     btav_a2dp_codec_index_t peer_codec_index =
   1799         A2DP_SinkCodecIndex(p_source->codec_caps);
   1800     if (peer_codec_index != codec_index) {
   1801       continue;
   1802     }
   1803     if (!AudioSepHasContentProtection(p_source)) {
   1804       APPL_TRACE_DEBUG(
   1805           "%s: peer Source for codec %s does not support "
   1806           "Content Protection",
   1807           __func__, A2DP_CodecIndexStr(codec_index));
   1808       continue;
   1809     }
   1810     return p_source;
   1811   }
   1812   return nullptr;
   1813 }
   1814 
   1815 const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection(
   1816     const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
   1817   uint8_t new_codec_config[AVDT_CODEC_SIZE];
   1818 
   1819   APPL_TRACE_DEBUG("%s", __func__);
   1820 
   1821   // Find the peer Sink for the codec
   1822   BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex());
   1823   if (p_sink == nullptr) {
   1824     APPL_TRACE_DEBUG("%s: peer Sink for codec %s not found", __func__,
   1825                      codec_config.name().c_str());
   1826     return nullptr;
   1827   }
   1828   if (!p_peer->GetCodecs()->setCodecConfig(
   1829           p_sink->codec_caps, true /* is_capability */, new_codec_config,
   1830           true /* select_current_codec */)) {
   1831     APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__,
   1832                      codec_config.name().c_str());
   1833     return nullptr;
   1834   }
   1835   p_peer->p_sink = p_sink;
   1836 
   1837   SaveNewCodecConfig(p_peer, new_codec_config, p_sink->num_protect,
   1838                      p_sink->protect_info);
   1839 
   1840   return p_sink;
   1841 }
   1842 
   1843 const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection(
   1844     const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
   1845   uint8_t new_codec_config[AVDT_CODEC_SIZE];
   1846 
   1847   APPL_TRACE_DEBUG("%s", __func__);
   1848 
   1849   // Find the peer Source for the codec
   1850   BtaAvCoSep* p_source = FindPeerSource(p_peer, codec_config.codecIndex());
   1851   if (p_source == nullptr) {
   1852     APPL_TRACE_DEBUG("%s: peer Source for codec %s not found", __func__,
   1853                      codec_config.name().c_str());
   1854     return nullptr;
   1855   }
   1856   if (!p_peer->GetCodecs()->setSinkCodecConfig(
   1857           p_source->codec_caps, true /* is_capability */, new_codec_config,
   1858           true /* select_current_codec */)) {
   1859     APPL_TRACE_DEBUG("%s: cannot set sink codec %s", __func__,
   1860                      codec_config.name().c_str());
   1861     return nullptr;
   1862   }
   1863   p_peer->p_source = p_source;
   1864 
   1865   SaveNewCodecConfig(p_peer, new_codec_config, p_source->num_protect,
   1866                      p_source->protect_info);
   1867 
   1868   return p_source;
   1869 }
   1870 
   1871 size_t BtaAvCo::UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer) {
   1872   APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
   1873 
   1874   size_t updated_codecs = 0;
   1875   for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
   1876     APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__,
   1877                      iter->name().c_str());
   1878     if (UpdateSelectableSourceCodec(*iter, p_peer)) {
   1879       updated_codecs++;
   1880     }
   1881   }
   1882   return updated_codecs;
   1883 }
   1884 
   1885 bool BtaAvCo::UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config,
   1886                                           BtaAvCoPeer* p_peer) {
   1887   APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
   1888 
   1889   // Find the peer Sink for the codec
   1890   const BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex());
   1891   if (p_sink == nullptr) {
   1892     // The peer Sink device does not support this codec
   1893     return false;
   1894   }
   1895   if (!p_peer->GetCodecs()->setPeerSinkCodecCapabilities(p_sink->codec_caps)) {
   1896     APPL_TRACE_WARNING("%s: cannot update peer %s codec capabilities for %s",
   1897                        __func__, p_peer->addr.ToString().c_str(),
   1898                        A2DP_CodecName(p_sink->codec_caps));
   1899     return false;
   1900   }
   1901   return true;
   1902 }
   1903 
   1904 size_t BtaAvCo::UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer) {
   1905   APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
   1906 
   1907   size_t updated_codecs = 0;
   1908   for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) {
   1909     APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__,
   1910                      iter->name().c_str());
   1911     if (UpdateSelectableSinkCodec(*iter, p_peer)) {
   1912       updated_codecs++;
   1913     }
   1914   }
   1915   return updated_codecs;
   1916 }
   1917 
   1918 bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config,
   1919                                         BtaAvCoPeer* p_peer) {
   1920   APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
   1921 
   1922   // Find the peer Source for the codec
   1923   const BtaAvCoSep* p_source =
   1924       FindPeerSource(p_peer, codec_config.codecIndex());
   1925   if (p_source == nullptr) {
   1926     // The peer Source device does not support this codec
   1927     return false;
   1928   }
   1929   if (!p_peer->GetCodecs()->setPeerSourceCodecCapabilities(
   1930           p_source->codec_caps)) {
   1931     APPL_TRACE_WARNING("%s: cannot update peer %s codec capabilities for %s",
   1932                        __func__, p_peer->addr.ToString().c_str(),
   1933                        A2DP_CodecName(p_source->codec_caps));
   1934     return false;
   1935   }
   1936   return true;
   1937 }
   1938 
   1939 void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer,
   1940                                  const uint8_t* new_codec_config,
   1941                                  uint8_t num_protect,
   1942                                  const uint8_t* p_protect_info) {
   1943   APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
   1944   APPL_TRACE_DEBUG("%s: codec: %s", __func__,
   1945                    A2DP_CodecInfoString(new_codec_config).c_str());
   1946 
   1947   std::lock_guard<std::recursive_mutex> lock(codec_lock_);
   1948 
   1949   memcpy(codec_config_, new_codec_config, sizeof(codec_config_));
   1950   memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE);
   1951 
   1952   if (ContentProtectEnabled()) {
   1953     // Check if this Sink supports SCMS
   1954     bool cp_active = BtaAvCo::AudioProtectHasScmst(num_protect, p_protect_info);
   1955     p_peer->SetContentProtectActive(cp_active);
   1956   }
   1957 }
   1958 
   1959 bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
   1960                                 const uint8_t* p_ota_codec_config,
   1961                                 uint8_t num_protect,
   1962                                 const uint8_t* p_protect_info,
   1963                                 bool* p_restart_output) {
   1964   uint8_t result_codec_config[AVDT_CODEC_SIZE];
   1965   bool restart_input = false;
   1966   bool restart_output = false;
   1967   bool config_updated = false;
   1968 
   1969   APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
   1970                    p_peer->addr.ToString().c_str());
   1971   APPL_TRACE_DEBUG("%s: codec: %s", __func__,
   1972                    A2DP_CodecInfoString(p_ota_codec_config).c_str());
   1973 
   1974   *p_restart_output = false;
   1975 
   1976   // Find the peer SEP codec to use
   1977   const BtaAvCoSep* p_sink =
   1978       FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_ota_codec_config));
   1979   if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) {
   1980     // There are no peer SEPs if we didn't do the discovery procedure yet.
   1981     // We have all the information we need from the peer, so we can
   1982     // proceed with the OTA codec configuration.
   1983     APPL_TRACE_ERROR("%s: peer %s : cannot find peer SEP to configure",
   1984                      __func__, p_peer->addr.ToString().c_str());
   1985     return false;
   1986   }
   1987 
   1988   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
   1989   GetPeerEncoderParameters(p_peer->addr, &peer_params);
   1990   if (!p_peer->GetCodecs()->setCodecOtaConfig(
   1991           p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
   1992           &restart_output, &config_updated)) {
   1993     APPL_TRACE_ERROR("%s: peer %s : cannot set OTA config", __func__,
   1994                      p_peer->addr.ToString().c_str());
   1995     return false;
   1996   }
   1997 
   1998   if (restart_output) {
   1999     APPL_TRACE_DEBUG("%s: restart output", __func__);
   2000     APPL_TRACE_DEBUG("%s: codec: %s", __func__,
   2001                      A2DP_CodecInfoString(result_codec_config).c_str());
   2002 
   2003     *p_restart_output = true;
   2004     p_peer->p_sink = p_sink;
   2005     SaveNewCodecConfig(p_peer, result_codec_config, num_protect,
   2006                        p_protect_info);
   2007   }
   2008 
   2009   if (restart_input || config_updated) {
   2010     // NOTE: Currently, the input is restarted by sending an upcall
   2011     // and informing the Media Framework about the change.
   2012     ReportSourceCodecState(p_peer);
   2013   }
   2014 
   2015   return true;
   2016 }
   2017 
   2018 void bta_av_co_init(
   2019     const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
   2020   bta_av_co_cb.Init(codec_priorities);
   2021 }
   2022 
   2023 A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) {
   2024   return bta_av_co_cb.GetActivePeerCurrentCodec();
   2025 }
   2026 
   2027 A2dpCodecConfig* bta_av_get_a2dp_peer_current_codec(
   2028     const RawAddress& peer_address) {
   2029   return bta_av_co_cb.GetPeerCurrentCodec(peer_address);
   2030 }
   2031 
   2032 bool bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,
   2033                           AvdtpSepConfig* p_cfg) {
   2034   return A2DP_InitCodecConfig(codec_index, p_cfg);
   2035 }
   2036 
   2037 void bta_av_co_audio_disc_res(tBTA_AV_HNDL bta_av_handle,
   2038                               const RawAddress& peer_address, uint8_t num_seps,
   2039                               uint8_t num_sinks, uint8_t num_sources,
   2040                               uint16_t uuid_local) {
   2041   bta_av_co_cb.ProcessDiscoveryResult(bta_av_handle, peer_address, num_seps,
   2042                                       num_sinks, num_sources, uuid_local);
   2043 }
   2044 
   2045 tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle,
   2046                                        const RawAddress& peer_address,
   2047                                        uint8_t* p_codec_info,
   2048                                        uint8_t* p_sep_info_idx, uint8_t seid,
   2049                                        uint8_t* p_num_protect,
   2050                                        uint8_t* p_protect_info) {
   2051   uint16_t peer_uuid = bta_av_co_cb.FindPeerUuid(bta_av_handle);
   2052 
   2053   APPL_TRACE_DEBUG("%s: peer %s bta_av_handle=0x%x peer_uuid=0x%x", __func__,
   2054                    peer_address.ToString().c_str(), bta_av_handle, peer_uuid);
   2055 
   2056   switch (peer_uuid) {
   2057     case UUID_SERVCLASS_AUDIO_SOURCE:
   2058       return bta_av_co_cb.ProcessSinkGetConfig(
   2059           bta_av_handle, peer_address, p_codec_info, p_sep_info_idx, seid,
   2060           p_num_protect, p_protect_info);
   2061     case UUID_SERVCLASS_AUDIO_SINK:
   2062       return bta_av_co_cb.ProcessSourceGetConfig(
   2063           bta_av_handle, peer_address, p_codec_info, p_sep_info_idx, seid,
   2064           p_num_protect, p_protect_info);
   2065     default:
   2066       break;
   2067   }
   2068   APPL_TRACE_ERROR(
   2069       "%s: peer %s : Invalid peer UUID: 0x%x for bta_av_handle 0x%x",
   2070       peer_address.ToString().c_str(), peer_uuid, bta_av_handle);
   2071   return A2DP_FAIL;
   2072 }
   2073 
   2074 void bta_av_co_audio_setconfig(tBTA_AV_HNDL bta_av_handle,
   2075                                const RawAddress& peer_address,
   2076                                const uint8_t* p_codec_info, uint8_t seid,
   2077                                uint8_t num_protect,
   2078                                const uint8_t* p_protect_info,
   2079                                uint8_t t_local_sep, uint8_t avdt_handle) {
   2080   bta_av_co_cb.ProcessSetConfig(bta_av_handle, peer_address, p_codec_info, seid,
   2081                                 num_protect, p_protect_info, t_local_sep,
   2082                                 avdt_handle);
   2083 }
   2084 
   2085 void bta_av_co_audio_open(tBTA_AV_HNDL bta_av_handle,
   2086                           const RawAddress& peer_address, uint16_t mtu) {
   2087   bta_av_co_cb.ProcessOpen(bta_av_handle, peer_address, mtu);
   2088 }
   2089 
   2090 void bta_av_co_audio_close(tBTA_AV_HNDL bta_av_handle,
   2091                            const RawAddress& peer_address) {
   2092   bta_av_co_cb.ProcessClose(bta_av_handle, peer_address);
   2093 }
   2094 
   2095 void bta_av_co_audio_start(tBTA_AV_HNDL bta_av_handle,
   2096                            const RawAddress& peer_address,
   2097                            const uint8_t* p_codec_info, bool* p_no_rtp_header) {
   2098   bta_av_co_cb.ProcessStart(bta_av_handle, peer_address, p_codec_info,
   2099                             p_no_rtp_header);
   2100 }
   2101 
   2102 void bta_av_co_audio_stop(tBTA_AV_HNDL bta_av_handle,
   2103                           const RawAddress& peer_address) {
   2104   bta_av_co_cb.ProcessStop(bta_av_handle, peer_address);
   2105 }
   2106 
   2107 BT_HDR* bta_av_co_audio_source_data_path(const uint8_t* p_codec_info,
   2108                                          uint32_t* p_timestamp) {
   2109   return bta_av_co_cb.GetNextSourceDataPacket(p_codec_info, p_timestamp);
   2110 }
   2111 
   2112 void bta_av_co_audio_drop(tBTA_AV_HNDL bta_av_handle,
   2113                           const RawAddress& peer_address) {
   2114   bta_av_co_cb.DataPacketWasDropped(bta_av_handle, peer_address);
   2115 }
   2116 
   2117 void bta_av_co_audio_delay(tBTA_AV_HNDL bta_av_handle,
   2118                            const RawAddress& peer_address, uint16_t delay) {
   2119   bta_av_co_cb.ProcessAudioDelay(bta_av_handle, peer_address, delay);
   2120 }
   2121 
   2122 void bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle,
   2123                                 const RawAddress& peer_address, uint16_t mtu) {
   2124   bta_av_co_cb.UpdateMtu(bta_av_handle, peer_address, mtu);
   2125 }
   2126 
   2127 bool bta_av_co_set_active_peer(const RawAddress& peer_address) {
   2128   return bta_av_co_cb.SetActivePeer(peer_address);
   2129 }
   2130 
   2131 void bta_av_co_get_peer_params(const RawAddress& peer_address,
   2132                                tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
   2133   bta_av_co_cb.GetPeerEncoderParameters(peer_address, p_peer_params);
   2134 }
   2135 
   2136 const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) {
   2137   return bta_av_co_cb.GetSourceEncoderInterface();
   2138 }
   2139 
   2140 const tA2DP_DECODER_INTERFACE* bta_av_co_get_decoder_interface(void) {
   2141   return bta_av_co_cb.GetSinkDecoderInterface();
   2142 }
   2143 
   2144 bool bta_av_co_set_codec_user_config(
   2145     const RawAddress& peer_address,
   2146     const btav_a2dp_codec_config_t& codec_user_config) {
   2147   return bta_av_co_cb.SetCodecUserConfig(peer_address, codec_user_config);
   2148 }
   2149 
   2150 bool bta_av_co_set_codec_audio_config(
   2151     const btav_a2dp_codec_config_t& codec_audio_config) {
   2152   return bta_av_co_cb.SetCodecAudioConfig(codec_audio_config);
   2153 }
   2154 
   2155 bool bta_av_co_content_protect_is_active(const RawAddress& peer_address) {
   2156   BtaAvCoPeer* p_peer = bta_av_co_cb.FindPeer(peer_address);
   2157   CHECK(p_peer != nullptr);
   2158   return p_peer->ContentProtectActive();
   2159 }
   2160 
   2161 void btif_a2dp_codec_debug_dump(int fd) { bta_av_co_cb.DebugDump(fd); }
   2162