1 /* 2 * Copyright 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 #include "bta/include/bta_av_api.h" 19 #include "stack/include/a2dp_codec_api.h" 20 #include "stack/include/bt_types.h" 21 #include "types/raw_address.h" 22 23 // Macro to retrieve the number of elements in a statically allocated array 24 #define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0])) 25 26 class BtaAvCoSep { 27 public: BtaAvCoSep()28 BtaAvCoSep() : sep_info_idx(0), seid(0), codec_caps{}, num_protect(0), protect_info{} { Reset(); } 29 30 /** 31 * Reset the state. 32 */ Reset()33 void Reset() { 34 sep_info_idx = 0; 35 seid = 0; 36 memset(codec_caps, 0, sizeof(codec_caps)); 37 num_protect = 0; 38 memset(protect_info, 0, sizeof(protect_info)); 39 } 40 41 uint8_t sep_info_idx; // Local SEP index (in BTA tables) 42 uint8_t seid; // Peer SEP index (in peer tables) 43 uint8_t codec_caps[AVDT_CODEC_SIZE]; // Peer SEP codec capabilities 44 uint8_t num_protect; // Peer SEP number of CP elements 45 uint8_t protect_info[AVDT_CP_INFO_LEN]; // Peer SEP content protection info 46 }; 47 48 class BtaAvCoPeer { 49 public: 50 /** 51 * Default constructor to initialize the state of the member variables. 52 */ 53 BtaAvCoPeer(); 54 55 /** 56 * Initialize the state. 57 * 58 * @param codec_priorities the codec priorities to use for the initialization 59 */ 60 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities); 61 62 /** 63 * Reset the state. 64 * 65 * @param bta_av_handle the BTA AV handle to use 66 */ 67 void Reset(tBTA_AV_HNDL bta_av_handle); 68 69 /** 70 * Get the BTA AV handle. 71 * 72 * @return the BTA AV handle 73 */ BtaAvHandle()74 tBTA_AV_HNDL BtaAvHandle() const { return bta_av_handle_; } 75 76 /** 77 * Get the A2DP codecs. 78 * 79 * @return the A2DP codecs 80 */ GetCodecs()81 A2dpCodecs* GetCodecs() const { return codecs_; } 82 ContentProtectActive()83 bool ContentProtectActive() const { return content_protect_active_; } SetContentProtectActive(bool cp_active)84 void SetContentProtectActive(bool cp_active) { content_protect_active_ = cp_active; } 85 86 /** 87 * Gets the codec config for the state. 88 * @return the active codec config. 89 */ 90 uint8_t* getCodecConfig(); 91 92 /** 93 * Updates the codec config 94 * @param new_codec_config codec config that needs to be updated. 95 */ 96 void setCodecConfig(const uint8_t* new_codec_config); 97 98 RawAddress addr; // Peer address 99 BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sinks 100 BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sources 101 uint8_t num_sinks; // Total number of sinks at peer 102 uint8_t num_sources; // Total number of sources at peer 103 uint8_t num_seps; // Total number of SEPs at peer 104 uint8_t num_rx_sinks; // Number of received sinks 105 uint8_t num_rx_sources; // Number of received sources 106 uint8_t num_sup_sinks; // Number of supported sinks 107 uint8_t num_sup_sources; // Number of supported sources 108 const BtaAvCoSep* p_sink; // Currently selected sink 109 const BtaAvCoSep* p_source; // Currently selected source 110 uint8_t codec_config[AVDT_CODEC_SIZE]; // Current codec configuration 111 bool acceptor; // True if acceptor 112 bool reconfig_needed; // True if reconfiguration is needed 113 bool opened; // True if opened 114 uint16_t mtu; // Maximum Transmit Unit size 115 uint16_t uuid_to_connect; // UUID of peer device 116 117 private: 118 tBTA_AV_HNDL bta_av_handle_; // BTA AV handle to use 119 A2dpCodecs* codecs_; // Locally supported codecs 120 bool content_protect_active_; // True if Content Protect is active 121 }; 122 123 /** 124 * Cache to store all the peer and codec information. 125 * It provides different APIs to retrieve the peer and update the peer data. 126 */ 127 class BtaAvCoPeerCache { 128 public: 129 BtaAvCoPeerCache() = default; 130 std::recursive_mutex codec_lock_; // Protect access to the codec state 131 std::vector<btav_a2dp_codec_config_t> codec_priorities_; // Configured 132 BtaAvCoPeer peers_[BTA_AV_NUM_STRS]; // Connected peer information 133 134 /** 135 * Inits the cache with the appropriate data. 136 * @param codec_priorities codec priorities. 137 */ 138 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities); 139 140 /** 141 * Resets the cache and the peer data. 142 */ 143 void Reset(); 144 145 /** 146 * Find the peer entry for a given peer address. 147 * 148 * @param peer_address the peer address to use 149 * @return the peer entry if found, otherwise nullptr 150 */ 151 BtaAvCoPeer* FindPeer(const RawAddress& peer_address); 152 153 /** 154 * Find the peer Source SEP entry for a given codec index. 155 * 156 * @param p_peer the peer to use 157 * @param codec_config the codec index to use 158 * @return the peer Source SEP for the codec index if found, otherwise nullptr 159 */ 160 BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer, btav_a2dp_codec_index_t codec_index, 161 const uint8_t content_protect_flag); 162 163 /** 164 * Find the peer Sink SEP entry for a given codec index. 165 * 166 * @param p_peer the peer to use 167 * @param codec_index the codec index to use 168 * @return the peer Sink SEP for the codec index if found, otherwise nullptr 169 */ 170 BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer, btav_a2dp_codec_index_t codec_index, 171 const uint8_t content_protect_flag); 172 173 /** 174 * Find the peer entry for a given BTA AV handle. 175 * 176 * @param bta_av_handle the BTA AV handle to use 177 * @return the peer entry if found, otherwise nullptr 178 */ 179 BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle); 180 181 /** 182 * Find the peer entry for a given BTA AV handle and update it with the 183 * peer address. 184 * 185 * @param bta_av_handle the BTA AV handle to use 186 * @param peer_address the peer address 187 * @return the peer entry if found, otherwise nullptr 188 */ 189 BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); 190 191 /** 192 * Find the peer UUID for a given BTA AV handle. 193 * 194 * @param bta_av_handle the BTA AV handle to use 195 * @return the peer UUID if found, otherwise 0 196 */ 197 uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle); 198 }; 199 200 /** 201 * Check if a content protection service is SCMS-T. 202 * 203 * @param p_orotect_info the content protection info to check 204 * @return true if the Contention Protection in @param p_protect_info 205 * is SCMS-T, otherwise false 206 */ 207 bool ContentProtectIsScmst(const uint8_t* p_protect_info); 208 209 /** 210 * Check if audio protect info contains SCMS-T Content Protection. 211 * 212 * @param num_protect number of protect schemes 213 * @param p_protect_info the protect info to check 214 * @return true if @param p_protect_info contains SCMS-T, otherwise false 215 */ 216 bool AudioProtectHasScmst(uint8_t num_protect, const uint8_t* p_protect_info); 217 218 /** 219 * Check if a peer SEP has content protection enabled. 220 * 221 * @param p_sep the peer SEP to check 222 * @param content_protect_flag flag to check if content protect is enabled or 223 * not. 224 * @return true if the peer SEP has content protection enabled, 225 * otherwise false 226 */ 227 bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep, const uint8_t content_protect_flag); 228