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

Commit 98c539a9 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

btm_iso: Fix race condition

If btm iso is closed when controller is doing some operation for it, the
returning callback will not have valid `this`.
Since we are using single instance of the iso_impl, let introduce guard
which make sure operations are done on valid object.

Bug: 285482385
Test: compile
Tag: #feature
Change-Id: I9afd1ddc125ee2656f2502baa1ce367d3b3c1319
parent 676c4de9
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ static constexpr uint8_t kStateFlagHasDataPathSet = 0x04;
static constexpr uint8_t kStateFlagIsBroadcast = 0x10;

constexpr char kBtmLogTag[] = "ISO";
static bool iso_impl_initialized_ = false;

struct iso_sync_info {
  uint32_t first_sync_ts;
@@ -95,9 +96,10 @@ struct iso_impl {
  iso_impl() {
    iso_credits_ = controller_get_interface()->get_iso_buffer_count();
    iso_buffer_size_ = controller_get_interface()->get_iso_data_size();
    iso_impl_initialized_ = true;
  }

  ~iso_impl() {}
  ~iso_impl() { iso_impl_initialized_ = false; }

  void handle_register_cis_callbacks(CigCallbacks* callbacks) {
    LOG_ASSERT(callbacks != nullptr) << "Invalid CIG callbacks";
@@ -122,6 +124,11 @@ struct iso_impl {
    uint16_t conn_handle;
    cig_create_cmpl_evt evt;

    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }

    LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks";
    LOG_ASSERT(len >= 3) << "Invalid packet length: " << +len;

@@ -215,6 +222,11 @@ struct iso_impl {
  void on_remove_cig(uint8_t* stream, uint16_t len) {
    cig_remove_cmpl_evt evt;

    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }

    LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks";
    LOG_ASSERT(len == 2) << "Invalid packet length: " << +len;

@@ -266,6 +278,11 @@ struct iso_impl {
      uint16_t len) {
    uint8_t status;

    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }

    LOG_ASSERT(len == 2) << "Invalid packet length: " << +len;

    STREAM_TO_UINT16(status, stream);
@@ -336,6 +353,11 @@ struct iso_impl {
    uint8_t status;
    uint16_t conn_handle;

    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }

    STREAM_TO_UINT8(status, stream);
    STREAM_TO_UINT16(conn_handle, stream);

@@ -396,6 +418,11 @@ struct iso_impl {
    STREAM_TO_UINT8(status, stream);
    STREAM_TO_UINT16(conn_handle, stream);

    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }

    iso_base* iso = GetIsoIfKnown(conn_handle);
    if (iso == nullptr) {
      /* That could happen when ACL has been disconnected while removing data
@@ -457,6 +484,10 @@ struct iso_impl {

    STREAM_TO_UINT16(conn_handle, stream);

    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }
    iso_base* iso = GetIsoIfKnown(conn_handle);
    if (iso == nullptr) {
      /* That could happen when ACL has been disconnected while waiting on the
@@ -615,6 +646,11 @@ struct iso_impl {
  }

  void disconnection_complete(uint16_t handle, uint8_t reason) {
    if (!iso_impl_initialized_) {
      LOG_WARN("iso_impl not available anymore");
      return;
    }

    /* Check if this is an ISO handle */
    auto cis = GetCisIfKnown(handle);
    if (cis == nullptr) return;