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