Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2b5669e authored by Rongxuan Liu's avatar Rongxuan Liu
Browse files

le_audio: Check iso state upon starting broadcast

In handling call during broadcast, broadcast will be paused and resumed
when call ends.
If the unicast iso is still active, we might encounter the issue that
BIG create command is rejected by controller.
Add the queue mechanism to handle this case, similar to the create broadcast request.
And move the iso state out of the broadcast request.

Test: atest bluetooth_test_broadcaster
Test: manually test with calling during broadcast and check the handover
Bug: 305943737
Bug: 308171251
Change-Id: Id8f7dbcdee58d1ffe1cc8fb05e354232fed0a282
parent 1a30ed09
Loading
Loading
Loading
Loading
+74 −35
Original line number Diff line number Diff line
@@ -126,6 +126,9 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    LOG_INFO("Broadcaster");
    broadcasts_.clear();
    callbacks_ = nullptr;
    is_iso_running_ = false;
    queued_start_broadcast_request_.ClearQueuedBroadcast();
    queued_create_broadcast_request_.ClearQueuedBroadcast();

    if (le_audio_source_hal_client_) {
      le_audio_source_hal_client_->Stop();
@@ -374,14 +377,14 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    LeAudioLtvMap public_ltv;
    std::vector<LeAudioLtvMap> subgroup_ltvs;

    if (queued_broadcast_.IsQueuedBroadcast()) {
    if (queued_create_broadcast_request_.IsQueuedBroadcast()) {
      LOG_ERROR("Not processed yet queued broadcast");
      return;
    }

    if (!queued_broadcast_.CanCreateBroadcast()) {
      queued_broadcast_.SetQueuedBroadcast(is_public, broadcast_name,
                                           broadcast_code, public_metadata,
    if (is_iso_running_) {
      queued_create_broadcast_request_.SetCreateBroadcastRequest(
          is_public, broadcast_name, broadcast_code, public_metadata,
          subgroup_quality, subgroup_metadata);
      return;
    }
@@ -574,6 +577,16 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
  void StartAudioBroadcast(uint32_t broadcast_id) override {
    LOG_INFO("Starting broadcast_id=%d", broadcast_id);

    if (queued_start_broadcast_request_.IsQueuedBroadcast()) {
      LOG_ERROR("Not processed yet start broadcast request");
      return;
    }

    if (is_iso_running_) {
      queued_start_broadcast_request_.SetStartBroadcastRequest(broadcast_id);
      return;
    }

    if (IsAnyoneStreaming()) {
      LOG_ERROR("Stop the other broadcast first!");
      return;
@@ -745,14 +758,17 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
  }

  void IsoTrafficEventCb(bool is_active) {
    if (is_active) {
      queued_broadcast_.SetIsoTrafficFlag();
    } else {
      queued_broadcast_.ResetIsoTrafficFlag();
    is_iso_running_ = is_active;
    LOG_INFO("is_iso_running: %d", is_iso_running_);

      if (!queued_broadcast_.IsQueuedBroadcast()) return;
    if (!is_iso_running_) {
      if (queued_start_broadcast_request_.IsQueuedBroadcast()) {
        queued_start_broadcast_request_.StartAudioBroadcast();
      }

      queued_broadcast_.CreateAudioBroadcast();
      if (queued_create_broadcast_request_.IsQueuedBroadcast()) {
        queued_create_broadcast_request_.CreateAudioBroadcast();
      }
    }
  }

@@ -1104,15 +1120,21 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    std::vector<std::unique_ptr<le_audio::CodecInterface>> sw_enc_;
  } audio_receiver_;

  static class QueuedBroadcast {
  static class QueuedCreateBroadcastRequest {
   public:
    bool IsQueuedBroadcast() {
      LOG_INFO("");
      LOG_INFO();

      return is_queued_;
    }

    void SetQueuedBroadcast(
    void ClearQueuedBroadcast() {
      LOG_INFO();

      is_queued_ = false;
    }

    void SetCreateBroadcastRequest(
        bool is_public, const std::string& broadcast_name,
        const std::optional<bluetooth::le_audio::BroadcastCode>& broadcast_code,
        const std::vector<uint8_t>& public_metadata,
@@ -1131,7 +1153,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
    }

    void CreateAudioBroadcast() {
      if (!instance || !CanCreateBroadcast()) return;
      if (!instance) return;

      LOG_INFO("Create queued broadcast");

@@ -1142,42 +1164,54 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
                                     subgroup_quality_, subgroup_metadata_);
    }

    void ClearQueuedBroadcast() {
   private:
    /* Queued broadcast data */
    bool is_queued_;
    bool is_public_;
    std::string broadcast_name_;
    std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code_;
    std::vector<uint8_t> public_metadata_;
    std::vector<uint8_t> subgroup_quality_;
    std::vector<std::vector<uint8_t>> subgroup_metadata_;
  } queued_create_broadcast_request_;

  static class QueuedStartBroadcastRequest {
   public:
    bool IsQueuedBroadcast() {
      LOG_INFO();

      is_queued_ = false;
      return is_queued_;
    }

    void SetIsoTrafficFlag() {
    void ClearQueuedBroadcast() {
      LOG_INFO();

      is_iso_running_ = true;
      is_queued_ = false;
    }

    void ResetIsoTrafficFlag() {
    void SetStartBroadcastRequest(uint32_t broadcast_id) {
      LOG_INFO();

      is_iso_running_ = false;
      broadcast_id_ = broadcast_id;

      is_queued_ = true;
    }

    bool CanCreateBroadcast() {
      LOG_INFO("%d", is_iso_running_ == false);
    void StartAudioBroadcast() {
      if (!instance) return;

      LOG_INFO("Start queued broadcast");

      is_queued_ = false;

      return is_iso_running_ == false;
      instance->StartAudioBroadcast(broadcast_id_);
    }

   private:
    /* Queued broadcast data */
    bool is_public_;
    std::string broadcast_name_;
    std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code_;
    std::vector<uint8_t> public_metadata_;
    std::vector<uint8_t> subgroup_quality_;
    std::vector<std::vector<uint8_t>> subgroup_metadata_;

    bool is_iso_running_;
    bool is_queued_;
  } queued_broadcast_;
    uint32_t broadcast_id_;
  } queued_start_broadcast_request_;

  bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_;
  std::map<uint32_t, std::unique_ptr<BroadcastStateMachine>> broadcasts_;
@@ -1188,6 +1222,9 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
  AudioDataPathState audio_data_path_state_;
  std::unique_ptr<LeAudioSourceAudioHalClient> le_audio_source_hal_client_;
  std::vector<BroadcastId> available_broadcast_ids_;

  // Flag to track iso state
  bool is_iso_running_ = false;
};

/* Static members definitions */
@@ -1197,8 +1234,10 @@ LeAudioBroadcasterImpl::LeAudioSourceCallbacksImpl
    LeAudioBroadcasterImpl::audio_receiver_;
LeAudioBroadcasterImpl::BroadcastAdvertisingCallbacks
    LeAudioBroadcasterImpl::state_machine_adv_callbacks_;
LeAudioBroadcasterImpl::QueuedBroadcast
    LeAudioBroadcasterImpl::queued_broadcast_;
LeAudioBroadcasterImpl::QueuedCreateBroadcastRequest
    LeAudioBroadcasterImpl::queued_create_broadcast_request_;
LeAudioBroadcasterImpl::QueuedStartBroadcastRequest
    LeAudioBroadcasterImpl::queued_start_broadcast_request_;
} /* namespace */

void LeAudioBroadcaster::Initialize(