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

Commit 3cd4a2bc authored by Himanshu Rawat's avatar Himanshu Rawat Committed by Automerger Merge Worker
Browse files

Merge changes from topic "bt-le-audio-dsa" into main am: fb94ddfd

parents b6a5ad04 fb94ddfd
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -32,6 +32,9 @@ class LeAudioHalVerifier {
  static bool SupportsStreamActiveApi();
  static bool SupportsStreamActiveApi();
};
};


typedef bool(LeAudioIsoDataCallback)(const RawAddress& address,
                                     uint16_t cis_conn_hdl, uint8_t* data,
                                     uint16_t size, uint32_t timestamp);
/* Interface class */
/* Interface class */
class LeAudioClient {
class LeAudioClient {
 public:
 public:
@@ -75,6 +78,9 @@ class LeAudioClient {
  virtual bool isOutputPreferenceLeAudio(const RawAddress& address) = 0;
  virtual bool isOutputPreferenceLeAudio(const RawAddress& address) = 0;
  virtual bool isDuplexPreferenceLeAudio(const RawAddress& address) = 0;
  virtual bool isDuplexPreferenceLeAudio(const RawAddress& address) = 0;
  virtual std::vector<RawAddress> GetGroupDevices(const int group_id) = 0;
  virtual std::vector<RawAddress> GetGroupDevices(const int group_id) = 0;

  static bool RegisterIsoDataConsumer(LeAudioIsoDataCallback callback);

  static void AddFromStorage(const RawAddress& addr, bool autoconnect,
  static void AddFromStorage(const RawAddress& addr, bool autoconnect,
                             int sink_audio_location, int source_audio_location,
                             int sink_audio_location, int source_audio_location,
                             int sink_supported_context_types,
                             int sink_supported_context_types,
+49 −0
Original line number Original line Diff line number Diff line
@@ -180,6 +180,7 @@ LeAudioSinkAudioHalClient::Callbacks* audioSourceReceiver;
CigCallbacks* stateMachineHciCallbacks;
CigCallbacks* stateMachineHciCallbacks;
LeAudioGroupStateMachine::Callbacks* stateMachineCallbacks;
LeAudioGroupStateMachine::Callbacks* stateMachineCallbacks;
DeviceGroupsCallbacks* device_group_callbacks;
DeviceGroupsCallbacks* device_group_callbacks;
LeAudioIsoDataCallback* iso_data_callback;


/*
/*
 * Coordinatet Set Identification Profile (CSIP) based on CSIP 1.0
 * Coordinatet Set Identification Profile (CSIP) based on CSIP 1.0
@@ -3436,6 +3437,10 @@ class LeAudioClientImpl : public LeAudioClient {
      return;
      return;
    }
    }


    if (DsaDataConsume(group, cis_conn_hdl, data, size, timestamp)) {
      return;
    }

    uint16_t left_cis_handle = 0;
    uint16_t left_cis_handle = 0;
    uint16_t right_cis_handle = 0;
    uint16_t right_cis_handle = 0;
    for (auto [cis_handle, audio_location] :
    for (auto [cis_handle, audio_location] :
@@ -5798,6 +5803,41 @@ class LeAudioClientImpl : public LeAudioClient {


    le_audio::MetricsCollector::Get()->OnStreamEnded(active_group_id_);
    le_audio::MetricsCollector::Get()->OnStreamEnded(active_group_id_);
  }
  }

  bool DsaDataConsume(LeAudioDeviceGroup* group, uint16_t cis_conn_hdl,
                      uint8_t* data, uint16_t size, uint32_t timestamp) {
    if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
      return false;
    }

    if (iso_data_callback == nullptr || !group->dsa_.active ||
        group->dsa_.mode != DsaMode::ISO_SW) {
      return false;
    }

    // Find LE Audio device
    LeAudioDevice* leAudioDevice = group->GetFirstDevice();
    while (leAudioDevice != nullptr) {
      if (leAudioDevice->GetDsaCisHandle() == cis_conn_hdl &&
          leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURED) {
        break;
      }
      leAudioDevice = group->GetNextDevice(leAudioDevice);
    }
    if (leAudioDevice == nullptr) {
      LOG_WARN("No LE Audio device found for CIS handle: %d", cis_conn_hdl);
      return false;
    }

    bool consumed = iso_data_callback(leAudioDevice->address_, cis_conn_hdl,
                                      data, size, timestamp);
    if (consumed) {
      return true;
    } else {
      LOG_VERBOSE("ISO data consumer not ready to accept data");
      return false;
    }
  }
};
};


static void le_audio_health_status_callback(const RawAddress& addr,
static void le_audio_health_status_callback(const RawAddress& addr,
@@ -6151,3 +6191,12 @@ void LeAudioClient::Cleanup(void) {
  IsoManager::GetInstance()->Stop();
  IsoManager::GetInstance()->Stop();
  le_audio::MetricsCollector::Get()->Flush();
  le_audio::MetricsCollector::Get()->Flush();
}
}

bool LeAudioClient::RegisterIsoDataConsumer(LeAudioIsoDataCallback callback) {
  if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
    return false;
  }

  iso_data_callback = callback;
  return true;
}
+18 −3
Original line number Original line Diff line number Diff line
@@ -356,7 +356,7 @@ void LeAudioDevice::RegisterPACs(
    pac_db->clear();
    pac_db->clear();
  }
  }


  dsa_modes_ = {DsaMode::DISABLED};
  dsa_.modes = {DsaMode::DISABLED};


  /* TODO wrap this logging part with debug flag */
  /* TODO wrap this logging part with debug flag */
  for (const struct types::acs_ac_record& pac : *pac_recs) {
  for (const struct types::acs_ac_record& pac : *pac_recs) {
@@ -375,7 +375,7 @@ void LeAudioDevice::RegisterPACs(
      if (pac.codec_id == types::kLeAudioCodecHeadtracking) {
      if (pac.codec_id == types::kLeAudioCodecHeadtracking) {
        LOG(INFO) << __func__ << ": Headtracking supported";
        LOG(INFO) << __func__ << ": Headtracking supported";
        /* Todo: Set DSA modes according to the codec configuration */
        /* Todo: Set DSA modes according to the codec configuration */
        dsa_modes_ = {
        dsa_.modes = {
            DsaMode::DISABLED,
            DsaMode::DISABLED,
            DsaMode::ISO_SW,
            DsaMode::ISO_SW,
            DsaMode::ISO_HW,
            DsaMode::ISO_HW,
@@ -1024,7 +1024,22 @@ void LeAudioDevice::UpdateDeviceAllowlistFlag(void) {
    }
    }
  }
  }
}
}
DsaModes LeAudioDevice::GetDsaModes(void) { return dsa_modes_; }

DsaModes LeAudioDevice::GetDsaModes(void) { return dsa_.modes; }

types::DataPathState LeAudioDevice::GetDsaDataPathState(void) {
  return dsa_.state;
}

void LeAudioDevice::SetDsaDataPathState(types::DataPathState state) {
  dsa_.state = state;
}

uint16_t LeAudioDevice::GetDsaCisHandle(void) { return dsa_.cis_handle; }

void LeAudioDevice::SetDsaCisHandle(uint16_t cis_handle) {
  dsa_.cis_handle = cis_handle;
}


/* LeAudioDevices Class methods implementation */
/* LeAudioDevices Class methods implementation */
void LeAudioDevices::Add(const RawAddress& address, DeviceConnectState state,
void LeAudioDevices::Add(const RawAddress& address, DeviceConnectState state,
+13 −5
Original line number Original line Diff line number Diff line
@@ -141,8 +141,9 @@ class LeAudioDevice {
        model_name_(""),
        model_name_(""),
        allowlist_flag_(false),
        allowlist_flag_(false),
        link_quality_timer(nullptr),
        link_quality_timer(nullptr),
        dsa_state_(types::DataPathState::IDLE),
        dsa_({{DsaMode::DISABLED},
        dsa_modes_({DsaMode::DISABLED}) {}
              types::DataPathState::IDLE,
              GATT_INVALID_CONN_ID}) {}
  ~LeAudioDevice(void);
  ~LeAudioDevice(void);


  void SetConnectionState(DeviceConnectState state);
  void SetConnectionState(DeviceConnectState state);
@@ -251,13 +252,20 @@ class LeAudioDevice {
  void GetDeviceModelName(void);
  void GetDeviceModelName(void);
  void UpdateDeviceAllowlistFlag(void);
  void UpdateDeviceAllowlistFlag(void);
  DsaModes GetDsaModes(void);
  DsaModes GetDsaModes(void);

  types::DataPathState GetDsaDataPathState(void);
  types::DataPathState dsa_state_;
  void SetDsaDataPathState(types::DataPathState state);
  uint16_t GetDsaCisHandle(void);
  void SetDsaCisHandle(uint16_t cis_handle);


 private:
 private:
  types::BidirectionalPair<types::AudioContexts> avail_contexts_;
  types::BidirectionalPair<types::AudioContexts> avail_contexts_;
  types::BidirectionalPair<types::AudioContexts> supp_contexts_;
  types::BidirectionalPair<types::AudioContexts> supp_contexts_;
  DsaModes dsa_modes_;
  struct {
    DsaModes modes;
    types::DataPathState state;
    uint16_t cis_handle;
  } dsa_;

  static constexpr char kLeAudioDeviceAllowListProp[] =
  static constexpr char kLeAudioDeviceAllowListProp[] =
      "persist.bluetooth.leaudio.allow_list";
      "persist.bluetooth.leaudio.allow_list";


+9 −7
Original line number Original line Diff line number Diff line
@@ -613,9 +613,9 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
      if (group->dsa_.active &&
      if (group->dsa_.active &&
          (group->dsa_.mode == DsaMode::ISO_SW ||
          (group->dsa_.mode == DsaMode::ISO_SW ||
           group->dsa_.mode == DsaMode::ISO_HW) &&
           group->dsa_.mode == DsaMode::ISO_HW) &&
          leAudioDevice->dsa_state_ == DataPathState::CONFIGURING) {
          leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURING) {
        LOG_INFO("Datapath configured for headtracking");
        LOG_INFO("Datapath configured for headtracking");
        leAudioDevice->dsa_state_ = DataPathState::CONFIGURED;
        leAudioDevice->SetDsaDataPathState(DataPathState::CONFIGURED);
        return;
        return;
      }
      }
    }
    }
@@ -699,9 +699,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
      }
      }
    } else if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
    } else if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
      if (group->dsa_.active &&
      if (group->dsa_.active &&
          leAudioDevice->dsa_state_ == DataPathState::REMOVING) {
          leAudioDevice->GetDsaDataPathState() == DataPathState::REMOVING) {
        LOG_INFO("DSA data path removed");
        LOG_INFO("DSA data path removed");
        leAudioDevice->dsa_state_ = DataPathState::IDLE;
        leAudioDevice->SetDsaDataPathState(DataPathState::IDLE);
        leAudioDevice->SetDsaCisHandle(GATT_INVALID_CONN_ID);
      }
      }
    }
    }


@@ -908,7 +909,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        return;
        return;
    }
    }


    leAudioDevice->dsa_state_ = DataPathState::CONFIGURING;
    leAudioDevice->SetDsaDataPathState(DataPathState::CONFIGURING);
    leAudioDevice->SetDsaCisHandle(conn_hdl);


    LOG_VERBOSE(
    LOG_VERBOSE(
        "DSA mode supported on this LE Audio device: %s, apply data path: %d",
        "DSA mode supported on this LE Audio device: %s, apply data path: %d",
@@ -1088,10 +1090,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
      ases_pair.source->data_path_state = DataPathState::REMOVING;
      ases_pair.source->data_path_state = DataPathState::REMOVING;
    } else {
    } else {
      if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
      if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
        if (leAudioDevice->dsa_state_ == DataPathState::CONFIGURED) {
        if (leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURED) {
          value |=
          value |=
              bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput;
              bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput;
          leAudioDevice->dsa_state_ = DataPathState::REMOVING;
          leAudioDevice->SetDsaDataPathState(DataPathState::REMOVING);
        }
        }
      }
      }
    }
    }
Loading