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() 29 : sep_info_idx(0), seid(0), codec_caps{}, num_protect(0), protect_info{} { 30 Reset(); 31 } 32 33 /** 34 * Reset the state. 35 */ Reset()36 void Reset() { 37 sep_info_idx = 0; 38 seid = 0; 39 memset(codec_caps, 0, sizeof(codec_caps)); 40 num_protect = 0; 41 memset(protect_info, 0, sizeof(protect_info)); 42 } 43 44 uint8_t sep_info_idx; // Local SEP index (in BTA tables) 45 uint8_t seid; // Peer SEP index (in peer tables) 46 uint8_t codec_caps[AVDT_CODEC_SIZE]; // Peer SEP codec capabilities 47 uint8_t num_protect; // Peer SEP number of CP elements 48 uint8_t protect_info[AVDT_CP_INFO_LEN]; // Peer SEP content protection info 49 }; 50 51 class BtaAvCoPeer { 52 public: 53 /** 54 * Default constructor to initialize the state of the member variables. 55 */ 56 BtaAvCoPeer(); 57 58 /** 59 * Initialize the state. 60 * 61 * @param codec_priorities the codec priorities to use for the initialization 62 */ 63 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities); 64 65 /** 66 * Reset the state. 67 * 68 * @param bta_av_handle the BTA AV handle to use 69 */ 70 void Reset(tBTA_AV_HNDL bta_av_handle); 71 72 /** 73 * Get the BTA AV handle. 74 * 75 * @return the BTA AV handle 76 */ BtaAvHandle()77 tBTA_AV_HNDL BtaAvHandle() const { return bta_av_handle_; } 78 79 /** 80 * Get the A2DP codecs. 81 * 82 * @return the A2DP codecs 83 */ GetCodecs()84 A2dpCodecs* GetCodecs() const { return codecs_; } 85 ContentProtectActive()86 bool ContentProtectActive() const { return content_protect_active_; } SetContentProtectActive(bool cp_active)87 void SetContentProtectActive(bool cp_active) { 88 content_protect_active_ = cp_active; 89 } 90 91 RawAddress addr; // Peer address 92 BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sinks 93 BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sources 94 uint8_t num_sinks; // Total number of sinks at peer 95 uint8_t num_sources; // Total number of sources at peer 96 uint8_t num_seps; // Total number of SEPs at peer 97 uint8_t num_rx_sinks; // Number of received sinks 98 uint8_t num_rx_sources; // Number of received sources 99 uint8_t num_sup_sinks; // Number of supported sinks 100 uint8_t num_sup_sources; // Number of supported sources 101 const BtaAvCoSep* p_sink; // Currently selected sink 102 const BtaAvCoSep* p_source; // Currently selected source 103 uint8_t codec_config[AVDT_CODEC_SIZE]; // Current codec configuration 104 bool acceptor; // True if acceptor 105 bool reconfig_needed; // True if reconfiguration is needed 106 bool opened; // True if opened 107 uint16_t mtu; // Maximum Transmit Unit size 108 uint16_t uuid_to_connect; // UUID of peer device 109 110 private: 111 tBTA_AV_HNDL bta_av_handle_; // BTA AV handle to use 112 A2dpCodecs* codecs_; // Locally supported codecs 113 bool content_protect_active_; // True if Content Protect is active 114 }; 115 116 /** 117 * Cache to store all the peer and codec information. 118 * It provides different APIs to retrieve the peer and update the peer data. 119 */ 120 class BtaAvCoPeerCache { 121 public: 122 BtaAvCoPeerCache() = default; 123 std::recursive_mutex codec_lock_; // Protect access to the codec state 124 std::vector<btav_a2dp_codec_config_t> codec_priorities_; // Configured 125 BtaAvCoPeer peers_[BTA_AV_NUM_STRS]; // Connected peer information 126 127 /** 128 * Inits the cache with the appropriate data. 129 * @param codec_priorities codec priorities. 130 * @param supported_codecs supported codecs by the stack. 131 */ 132 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities, 133 std::vector<btav_a2dp_codec_info_t>* supported_codecs); 134 135 /** 136 * Resets the cache and the peer data. 137 */ 138 void Reset(); 139 140 /** 141 * Find the peer entry for a given peer address. 142 * 143 * @param peer_address the peer address to use 144 * @return the peer entry if found, otherwise nullptr 145 */ 146 BtaAvCoPeer* FindPeer(const RawAddress& peer_address); 147 148 /** 149 * Find the peer Source SEP entry for a given codec index. 150 * 151 * @param p_peer the peer to use 152 * @param codec_config the codec index to use 153 * @return the peer Source SEP for the codec index if found, otherwise nullptr 154 */ 155 BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer, 156 btav_a2dp_codec_index_t codec_index, 157 const uint8_t content_protect_flag); 158 159 /** 160 * Find the peer Sink SEP entry for a given codec index. 161 * 162 * @param p_peer the peer to use 163 * @param codec_index the codec index to use 164 * @return the peer Sink SEP for the codec index if found, otherwise nullptr 165 */ 166 BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer, 167 btav_a2dp_codec_index_t codec_index, 168 const uint8_t content_protect_flag); 169 170 /** 171 * Find the peer entry for a given BTA AV handle. 172 * 173 * @param bta_av_handle the BTA AV handle to use 174 * @return the peer entry if found, otherwise nullptr 175 */ 176 BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle); 177 178 /** 179 * Find the peer entry for a given BTA AV handle and update it with the 180 * peer address. 181 * 182 * @param bta_av_handle the BTA AV handle to use 183 * @param peer_address the peer address 184 * @return the peer entry if found, otherwise nullptr 185 */ 186 BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle, 187 const RawAddress& peer_address); 188 189 /** 190 * Find the peer UUID for a given BTA AV handle. 191 * 192 * @param bta_av_handle the BTA AV handle to use 193 * @return the peer UUID if found, otherwise 0 194 */ 195 uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle); 196 }; 197 198 /** 199 * Check if a content protection service is SCMS-T. 200 * 201 * @param p_orotect_info the content protection info to check 202 * @return true if the Contention Protection in @param p_protect_info 203 * is SCMS-T, otherwise false 204 */ 205 bool ContentProtectIsScmst(const uint8_t* p_protect_info); 206 207 /** 208 * Check if audio protect info contains SCMS-T Content Protection. 209 * 210 * @param num_protect number of protect schemes 211 * @param p_protect_info the protect info to check 212 * @return true if @param p_protect_info contains SCMS-T, otherwise false 213 */ 214 bool AudioProtectHasScmst(uint8_t num_protect, const uint8_t* p_protect_info); 215 216 /** 217 * Check if a peer SEP has content protection enabled. 218 * 219 * @param p_sep the peer SEP to check 220 * @param content_protect_flag flag to check if content protect is enabled or 221 * not. 222 * @return true if the peer SEP has content protection enabled, 223 * otherwise false 224 */ 225 bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep, 226 const uint8_t content_protect_flag); 227