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 19 #include <audio_hal_interface/a2dp_encoding.h> 20 21 #include "btif/include/bta_av_co_peer.h" 22 23 /** 24 * BTA AV codec callouts state. 25 */ 26 class BtaAvCoState { 27 public: 28 BtaAvCoState() = default; 29 30 /** 31 * Set the active peer for the state. 32 * @param peer 33 */ 34 void setActivePeer(BtaAvCoPeer* peer); 35 36 /** 37 * Gets the active peer for the state. 38 * @return pointer to the active peer. 39 */ 40 BtaAvCoPeer* getActivePeer() const; 41 42 /** 43 * Gets the codec config for the state. 44 * @return the active codec config. 45 */ 46 uint8_t* getCodecConfig(); 47 48 /** 49 * Updates the codec config 50 * @param codec_config codec config that needs to be updated. 51 */ 52 void setCodecConfig(const uint8_t* codec_config); 53 54 /** 55 * Clears the codec config. 56 */ 57 void clearCodecConfig(); 58 59 /** 60 * Resets the state. 61 */ 62 void Reset(); 63 virtual ~BtaAvCoState() = default; 64 65 private: 66 // The current active peer 67 BtaAvCoPeer* active_peer_; 68 // Current codec configuration 69 uint8_t codec_config_[AVDT_CODEC_SIZE]; 70 }; 71 72 class BtaAvCo { 73 public: BtaAvCo(bool content_protect_enabled,BtaAvCoPeerCache * bta_av_co_peer_bank)74 BtaAvCo(bool content_protect_enabled, BtaAvCoPeerCache* bta_av_co_peer_bank) 75 : peer_cache_(bta_av_co_peer_bank), 76 content_protect_enabled_(content_protect_enabled), 77 content_protect_flag_(0) { 78 Reset(); 79 } 80 81 virtual ~BtaAvCo() = default; 82 83 /** 84 * Initialize the state. 85 * 86 * @param codec_priorities the codec priorities to use for the initialization 87 * @param supported_codecs return the list of supported codecs 88 */ 89 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities, 90 std::vector<btav_a2dp_codec_info_t>* supported_codecs); 91 92 /** 93 * Checks whether a codec is supported. 94 * 95 * @param codec_index the index of the codec to check 96 * @return true if the codec is supported, otherwise false 97 */ 98 bool IsSupportedCodec(btav_a2dp_codec_index_t codec_index); 99 100 /** 101 * Get the current codec configuration for the active peer. 102 * 103 * @return the current codec configuration if found, otherwise nullptr 104 */ 105 A2dpCodecConfig* GetActivePeerCurrentCodec(); 106 107 /** 108 * Get the current codec configuration for a peer. 109 * 110 * @param peer_address the peer address 111 * @return the current codec configuration if found, otherwise nullptr 112 */ 113 A2dpCodecConfig* GetPeerCurrentCodec(const RawAddress& peer_address); 114 115 /** 116 * Process the AVDTP discovery result: number of Stream End Points (SEP) 117 * found during the AVDTP stream discovery process. 118 * 119 * @param bta_av_handle the BTA AV handle to identify the peer 120 * @param peer_address the peer address 121 * @param num_seps the number of discovered SEPs 122 * @param num_sinks number of discovered Sink SEPs 123 * @param num_sources number of discovered Source SEPs 124 * @param uuid_local local UUID 125 */ 126 void ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, 127 uint8_t num_seps, uint8_t num_sinks, uint8_t num_sources, 128 uint16_t uuid_local); 129 130 /** 131 * Process retrieved codec configuration and content protection from 132 * Peer Sink SEP. 133 * 134 * @param bta_av_handle the BTA AV handle to identify the peer 135 * @param peer_address the peer address 136 * @param p_codec_info the peer sink capability filled-in by the caller. 137 * On success, it will contain the current codec configuration for the peer. 138 * @param p_sep_info_idx the peer SEP index for the corresponding peer 139 * sink capability filled-in by the caller. On success, it will contain 140 * the SEP index for the current codec configuration for the peer. 141 * @param seid the peer SEP index in peer tables 142 * @param p_num_protect the peer SEP number of content protection elements 143 * filled-in by the caller. On success, it will contain the SEP number of 144 * content protection elements for the current codec configuration for the 145 * peer. 146 * @param p_protect_info the peer SEP content protection info filled-in by 147 * the caller. On success, it will contain the SEP content protection info 148 * for the current codec configuration for the peer. 149 * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL 150 */ 151 tA2DP_STATUS ProcessSourceGetConfig(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, 152 uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, 153 uint8_t* p_num_protect, uint8_t* p_protect_info); 154 155 /** 156 * Process retrieved codec configuration and content protection from 157 * Peer Source SEP. 158 * 159 * @param bta_av_handle the BTA AV handle to identify the peer 160 * @param peer_address the peer address 161 * @param p_codec_info the peer source capability filled-in by the caller. 162 * On success, it will contain the current codec configuration for the peer. 163 * @param p_sep_info_idx the peer SEP index for the corresponding peer 164 * source capability filled-in by the caller. On success, it will contain 165 * the SEP index for the current codec configuration for the peer. 166 * @param seid the peer SEP index in peer tables 167 * @param p_num_protect the peer SEP number of content protection elements 168 * filled-in by the caller. On success, it will contain the SEP number of 169 * content protection elements for the current codec configuration for the 170 * peer. 171 * @param p_protect_info the peer SEP content protection info filled-in by 172 * the caller. On success, it will contain the SEP content protection info 173 * for the current codec configuration for the peer. 174 * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL 175 */ 176 tA2DP_STATUS ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, 177 uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, 178 uint8_t* p_num_protect, uint8_t* p_protect_info); 179 180 /** 181 * Process AVDTP Set Config to set the codec and content protection 182 * configuration of the audio stream. 183 * 184 * @param bta_av_handle the BTA AV handle to identify the peer 185 * @param peer_address the peer address 186 * @param p_codec_info the codec configuration to set 187 * @param seid stream endpoint ID of stream initiating the operation 188 * @param peer_address the peer address 189 * @param num_protect the peer SEP number of content protection elements 190 * @param p_protect_info the peer SEP content protection info 191 * @param t_local_sep the local SEP: AVDT_TSEP_SRC or AVDT_TSEP_SNK 192 * @param avdt_handle the AVDTP handle 193 */ 194 void ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, 195 const uint8_t* p_codec_info, uint8_t seid, uint8_t num_protect, 196 const uint8_t* p_protect_info, uint8_t t_local_sep, uint8_t avdt_handle); 197 198 /** 199 * Process AVDTP Open when the stream connection is opened. 200 * 201 * @param bta_av_handle the BTA AV handle to identify the peer 202 * @param peer_address the peer address 203 * @param mtu the MTU of the connection 204 */ 205 void ProcessOpen(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t mtu); 206 207 /** 208 * Process AVDTP Close when the stream connection is closed. 209 * 210 * @param bta_av_handle the BTA AV handle to identify the peer 211 * @param peer_address the peer address 212 */ 213 void ProcessClose(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); 214 215 /** 216 * Process AVDTP Start when the audio data streaming is started. 217 * 218 * @param bta_av_handle the BTA AV handle to identify the peer 219 * @param peer_address the peer address 220 * @param p_codec_info the codec configuration 221 * @param p_no_rtp_header on return, set to true if the audio data packets 222 * should not contain RTP header 223 */ 224 void ProcessStart(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, 225 const uint8_t* p_codec_info, bool* p_no_rtp_header); 226 227 /** 228 * Process AVDTP Stop when the audio data streaming is stopped. 229 * 230 * @param bta_av_handle the BTA AV handle to identify the peer 231 * @param peer_address the peer address 232 */ 233 void ProcessStop(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); 234 235 /** 236 * Get the next encoded audio data packet to send. 237 * 238 * @param p_codec_info the codec configuration 239 * @param p_timestamp on return, set to the timestamp of the data packet 240 * @return the next encoded data packet or nullptr if no encoded data to send 241 */ 242 BT_HDR* GetNextSourceDataPacket(const uint8_t* p_codec_info, uint32_t* p_timestamp); 243 244 /** 245 * An audio packet has been dropped. 246 * This signal can be used by the encoder to reduce the encoder bit rate 247 * setting. 248 * 249 * @param bta_av_handle the BTA AV handle to identify the peer 250 * @param peer_address the peer address 251 */ 252 void DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); 253 254 /** 255 * Process AVDTP Audio Delay when the initial delay report is received by 256 * the Source. 257 * 258 * @param bta_av_handle the BTA AV handle to identify the peer 259 * @param peer_address the peer address 260 * @param delay the reported delay in 1/10th of a millisecond 261 */ 262 void ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, 263 uint16_t delay); 264 265 /** 266 * Update the MTU of the audio data connection. 267 * 268 * @param bta_av_handle the BTA AV handle to identify the peer 269 * @param peer_address the peer address 270 * @param mtu the new MTU of the audio data connection 271 */ 272 void UpdateMtu(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t mtu); 273 274 /** 275 * Set the active peer. 276 * 277 * @param peer_address the peer address 278 * @param t_local_sep update the active peer for the profile type. 279 * @return true on success, otherwise false 280 */ 281 bool SetActivePeer(const RawAddress& peer_address, const uint8_t t_local_sep); 282 283 /** 284 * Save the reconfig codec 285 * 286 * @param peer_address the peer address. 287 * @param new_codec_config the new codec config 288 */ 289 void SaveCodec(const RawAddress& peer_address, const uint8_t* new_codec_config); 290 291 /** 292 * Get the encoder parameters for a peer. 293 * 294 * @param peer_address the peer address 295 * @param p_peer_params on return, set to the peer's encoder parameters 296 */ 297 void GetPeerEncoderParameters(const RawAddress& peer_address, 298 tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params); 299 300 /** 301 * Get the Source encoder interface for the current codec. 302 * 303 * @param peer_address the peer address. 304 * @return the Source encoder interface for the current codec 305 */ 306 const tA2DP_ENCODER_INTERFACE* GetSourceEncoderInterface(const RawAddress& peer_address); 307 308 /** 309 * Set the codec user configuration. 310 * 311 * @param peer_address the peer address 312 * @param codec_user_config the codec user configuration to set 313 * @param p_restart_output if there is a change in the encoder configuration 314 * that requires restarting of the A2DP connection, flag |p_restart_output| 315 * will be set to true. 316 * @return true on success, otherwise false 317 */ 318 bool SetCodecUserConfig(const RawAddress& peer_address, 319 const btav_a2dp_codec_config_t& codec_user_config, 320 bool* p_restart_output); 321 322 /** 323 * Set the codec audio configuration. 324 * 325 * @param codec_audio_config the codec audio configuration to set 326 * @return true on success, otherwise false 327 */ 328 bool SetCodecAudioConfig(const btav_a2dp_codec_config_t& codec_audio_config); 329 330 /** 331 * Get the Source encoder maximum frame size for the current codec. 332 * 333 * @param peer_address the peer address. 334 * @return the effective frame size for the current codec 335 */ 336 int GetSourceEncoderEffectiveFrameSize(const RawAddress& peer_address); 337 338 /** 339 * Get the Source encoder preferred encoding interval. 340 * 341 * @return the preferred encoding interval for the current codec 342 */ 343 int GetSourceEncoderPreferredIntervalUs(); 344 345 /** 346 * Report the source codec state for a peer 347 * 348 * @param p_peer the peer to report 349 * @return true on success, otherwise false 350 */ 351 bool ReportSourceCodecState(BtaAvCoPeer* p_peer); 352 353 /** 354 * Report the sink codec state for a peer 355 * 356 * @param p_peer the peer to report 357 * @return true on success, otherwise false 358 */ 359 bool ReportSinkCodecState(BtaAvCoPeer* p_peer); 360 361 /** 362 * Get the content protection flag. 363 * 364 * @return the content protection flag. It should be one of the following: 365 * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE 366 */ ContentProtectFlag()367 uint8_t ContentProtectFlag() const { return content_protect_flag_; } 368 369 /** 370 * Set the content protection flag. 371 * 372 * @param cp_flag the content protection flag. It should be one of the 373 * following: 374 * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE 375 * NOTE: If Content Protection is not enabled on the system, then 376 * the only acceptable vailue is AVDT_CP_SCMS_COPY_FREE. 377 */ SetContentProtectFlag(uint8_t cp_flag)378 void SetContentProtectFlag(uint8_t cp_flag) { 379 if (!ContentProtectEnabled() && (cp_flag != AVDT_CP_SCMS_COPY_FREE)) { 380 return; 381 } 382 content_protect_flag_ = cp_flag; 383 } 384 385 /** 386 * Dump debug-related information. 387 * 388 * @param fd the file descritor to use for writing the ASCII formatted 389 * information 390 */ 391 void DebugDump(int fd); 392 393 /** 394 * Access peer data via cache. 395 */ 396 BtaAvCoPeerCache* peer_cache_; 397 398 private: 399 /** 400 * Reset the state. 401 */ 402 void Reset(); 403 404 /** 405 * Select the Source codec configuration based on peer codec support. 406 * 407 * Furthermore, the local state for the remaining non-selected codecs is 408 * updated to reflect whether the codec is selectable. 409 * 410 * @param p_peer the peer to use 411 * @return a pointer to the corresponding SEP Sink entry on success, 412 * otherwise nullptr 413 */ 414 const BtaAvCoSep* SelectSourceCodec(BtaAvCoPeer* p_peer); 415 416 /** 417 * Select the Sink codec configuration based on peer codec support. 418 * 419 * Furthermore, the local state for the remaining non-selected codecs is 420 * updated to reflect whether the codec is selectable. 421 * 422 * @param p_peer the peer to use 423 * @return a pointer to the corresponding SEP Source entry on success, 424 * otherwise nullptr 425 */ 426 const BtaAvCoSep* SelectSinkCodec(BtaAvCoPeer* p_peer); 427 428 /** 429 * Save new codec configuration. 430 * 431 * @param p_peer the peer to use 432 * @param new_codec_config the new codec configuration to use 433 * @param num_protect the number of content protection elements 434 * @param p_protect_info the content protection info to use 435 * @param t_local_sep the profile for which the codec config needs to be 436 * saved. 437 */ 438 void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, uint8_t num_protect, 439 const uint8_t* p_protect_info, const uint8_t t_local_sep); 440 441 /** 442 * Set the Over-The-Air preferred codec configuration. 443 * 444 * The OTA preferred codec configuration is ignored if the current 445 * codec configuration contains explicit user configuration, or if the 446 * codec configuration for the same codec contains explicit user 447 * configuration. 448 * 449 * @param p_peer is the peer device that sent the OTA codec configuration 450 * @param p_ota_codec_config contains the received OTA A2DP codec 451 * configuration from the remote peer. Note: this is not the peer codec 452 * capability, but the codec configuration that the peer would like to use. 453 * @param num_protect is the number of content protection methods to use 454 * @param p_protect_info contains the content protection information to use. 455 * @param t_local_sep the profile for which ota config needs to be set. 456 * @return true on success, otherwise false 457 */ 458 tA2DP_STATUS SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, 459 uint8_t num_protect, const uint8_t* p_protect_info, 460 const uint8_t t_local_sep); 461 462 /** 463 * Update all selectable Source codecs with the corresponding codec 464 * information from a Sink peer. 465 * 466 * @param p_peer the peer Sink SEP to use 467 * @return the number of codecs that have been updated 468 */ 469 size_t UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer); 470 471 /** 472 * Update a selectable Source codec with the corresponding codec information 473 * from a Sink peer. 474 * 475 * @param codec_config the codec config info to identify the codec to update 476 * @param p_peer the peer Sink SEP to use 477 * @return true if the codec is updated, otherwise false 478 */ 479 bool UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer); 480 481 /** 482 * Update all selectable Sink codecs with the corresponding codec 483 * information from a Source peer. 484 * 485 * @param p_peer the peer Source SEP to use 486 * @return the number of codecs that have been updated 487 */ 488 size_t UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer); 489 490 /** 491 * Update a selectable Sink codec with the corresponding codec information 492 * from a Source peer. 493 * 494 * @param codec_config the codec config info to identify the codec to update 495 * @param p_peer the peer Source SEP to use 496 * @return true if the codec is updated, otherwise false 497 */ 498 bool UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer); 499 500 /** 501 * Attempt to select Source codec configuration for a Sink peer. 502 * 503 * @param codec_config the codec configuration to use 504 * @param p_peer the Sink peer to use 505 * @return a pointer to the corresponding SEP Sink entry on success, 506 * otnerwise nullptr 507 */ 508 const BtaAvCoSep* AttemptSourceCodecSelection(const A2dpCodecConfig& codec_config, 509 BtaAvCoPeer* p_peer); 510 511 /** 512 * Attempt to select Sink codec configuration for a Source peer. 513 * 514 * @param codec_config the codec configuration to use 515 * @param p_peer the Source peer to use 516 * @return a pointer to the corresponding SEP Source entry on success, 517 * otnerwise nullptr 518 */ 519 const BtaAvCoSep* AttemptSinkCodecSelection(const A2dpCodecConfig& codec_config, 520 BtaAvCoPeer* p_peer); 521 522 /** 523 * Let the HAL offload provider select codec configuration. 524 * 525 * @param p_peer the peer to use 526 * @param configuration configuration from the offload provider 527 */ 528 std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration> 529 GetProviderCodecConfiguration(BtaAvCoPeer* p_peer); 530 531 /** 532 * Select the HAL proposed configuration. 533 */ 534 BtaAvCoSep* SelectProviderCodecConfiguration( 535 BtaAvCoPeer* p_peer, 536 const ::bluetooth::audio::a2dp::provider::a2dp_configuration& provider_codec_config); 537 538 /** 539 * Returns the state that needs to be accessed. 540 * @param p_peer peer address. 541 * @return state of the profile. 542 */ 543 BtaAvCoState* getStateFromPeer(const BtaAvCoPeer* p_peer); 544 545 /** 546 * Returns the state based on the local profile of the stack. 547 * @param t_local_sep local sep type 548 * @return state of the profile. 549 */ 550 BtaAvCoState* getStateFromLocalProfile(const uint8_t t_local_sep); 551 ContentProtectEnabled()552 bool ContentProtectEnabled() const { return content_protect_enabled_; } 553 554 const bool content_protect_enabled_; // True if Content Protect is enabled 555 uint8_t content_protect_flag_; // Content Protect flag 556 BtaAvCoState bta_av_source_state_; // Source profile state 557 BtaAvCoState bta_av_sink_state_; // Sink profile state 558 }; 559