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

Commit e6b96cde authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "btm_iso: Fix returning credits on iso disconnection"

parents d1a2be60 889d447e
Loading
Loading
Loading
Loading
+44 −17
Original line number Diff line number Diff line
@@ -60,8 +60,9 @@ struct iso_base {
  };

  struct iso_sync_info sync_info;
  uint8_t state_flags;
  std::atomic_uint8_t state_flags;
  uint32_t sdu_itv;
  std::atomic_uint16_t used_credits;
};

typedef iso_base iso_cis;
@@ -121,11 +122,14 @@ struct iso_impl {
        STREAM_TO_UINT16(conn_handle, stream);

        evt.conn_handles.push_back(conn_handle);
        conn_hdl_to_cis_map_[conn_handle] = std::unique_ptr<iso_cis>(
            new iso_cis({.sync_info = {.first_sync_ts = 0, .seq_nb = 0},
                         .cig_id = cig_id,
                         .state_flags = kStateFlagsNone,
                         .sdu_itv = sdu_itv_mtos}));

        auto cis = std::unique_ptr<iso_cis>(new iso_cis());
        cis->cig_id = cig_id;
        cis->sdu_itv = sdu_itv_mtos;
        cis->sync_info = {.first_sync_ts = 0, .seq_nb = 0};
        cis->used_credits = 0;
        cis->state_flags = kStateFlagsNone;
        conn_hdl_to_cis_map_[conn_handle] = std::move(cis);
      }
    }

@@ -434,6 +438,7 @@ struct iso_impl {
    }

    iso_credits_--;
    iso->used_credits++;

    BT_HDR* packet =
        prepare_ts_hci_packet(iso_handle, ts, iso->sync_info.seq_nb, data_len);
@@ -495,6 +500,11 @@ struct iso_impl {

      cig_callbacks_->OnCisEvent(kIsoEventCisDisconnected, &evt);
      cis->state_flags &= ~kStateFlagIsConnected;

      /* return used credits */
      iso_credits_ += cis->used_credits;
      cis->used_credits = 0;

      /* Data path is considered still valid, but can be reconfigured only once
       * CIS is reestablished.
       */
@@ -514,21 +524,36 @@ struct iso_impl {
      STREAM_TO_UINT16(handle, p);
      STREAM_TO_UINT16(num_sent, p);

      if ((conn_hdl_to_cis_map_.find(handle) == conn_hdl_to_cis_map_.end()) &&
          (conn_hdl_to_bis_map_.find(handle) == conn_hdl_to_bis_map_.end()))
      auto iter = conn_hdl_to_cis_map_.find(handle);
      if (iter != conn_hdl_to_cis_map_.end()) {
        iter->second->used_credits -= num_sent;
        iso_credits_ += num_sent;
        continue;
      }

      iter = conn_hdl_to_bis_map_.find(handle);
      if (iter != conn_hdl_to_bis_map_.end()) {
        iter->second->used_credits -= num_sent;
        iso_credits_ += num_sent;
        continue;
      }
    }
  }

  void handle_gd_num_completed_pkts(uint16_t handle, uint16_t credits) {
    if ((conn_hdl_to_cis_map_.find(handle) == conn_hdl_to_cis_map_.end()) &&
        (conn_hdl_to_bis_map_.find(handle) == conn_hdl_to_bis_map_.end()))
    auto iter = conn_hdl_to_cis_map_.find(handle);
    if (iter != conn_hdl_to_cis_map_.end()) {
      iter->second->used_credits -= credits;
      iso_credits_ += credits;
      return;
    }

    iter = conn_hdl_to_bis_map_.find(handle);
    if (iter != conn_hdl_to_bis_map_.end()) {
      iter->second->used_credits -= credits;
      iso_credits_ += credits;
    }
  }

  void process_create_big_cmpl_pkt(uint8_t len, uint8_t* data) {
    struct big_create_cmpl_evt evt;
@@ -563,11 +588,13 @@ struct iso_impl {
      LOG_INFO(" received BIS conn_hdl %d", +conn_handle);

      if (evt.status == HCI_SUCCESS) {
        conn_hdl_to_bis_map_[conn_handle] = std::unique_ptr<iso_bis>(
            new iso_bis({.sync_info = {.first_sync_ts = ts, .seq_nb = 0},
                         .big_handle = evt.big_id,
                         .state_flags = kStateFlagIsBroadcast,
                         .sdu_itv = last_big_create_req_sdu_itv_}));
        auto bis = std::unique_ptr<iso_bis>(new iso_bis());
        bis->big_handle = evt.big_id;
        bis->sdu_itv = last_big_create_req_sdu_itv_;
        bis->sync_info = {.first_sync_ts = ts, .seq_nb = 0};
        bis->used_credits = 0;
        bis->state_flags = kStateFlagIsBroadcast;
        conn_hdl_to_bis_map_[conn_handle] = std::move(bis);
      }
    }

+40 −0
Original line number Diff line number Diff line
@@ -2059,6 +2059,46 @@ TEST_F(IsoManagerTest, SendIsoDataCreditsReturned) {
  }
}

TEST_F(IsoManagerTest, SendIsoDataCreditsReturnedByDisconnection) {
  uint8_t num_buffers = controller_interface_.GetIsoBufferCount();
  std::vector<uint8_t> data_vec(108, 0);

  // Check on CIG
  IsoManager::GetInstance()->CreateCig(
      volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);

  bluetooth::hci::iso_manager::cis_establish_params params;
  for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
    params.conn_pairs.push_back({handle, 1});
  }
  IsoManager::GetInstance()->EstablishCis(params);

  for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
    IsoManager::GetInstance()->SetupIsoDataPath(handle,
                                                kDefaultIsoDataPathParams);
  }

  /* Sending lot of ISO data to first ISO and getting all the credits */
  EXPECT_CALL(bte_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
  for (uint8_t i = 0; i < num_buffers; i++) {
    IsoManager::GetInstance()->SendIsoData(
        volatile_test_cig_create_cmpl_evt_.conn_handles[0], data_vec.data(),
        data_vec.size());
  }

  /* Return all credits by disconnecting CIS */
  IsoManager::GetInstance()->HandleDisconnect(
      volatile_test_cig_create_cmpl_evt_.conn_handles[0], 16);

  /* Try to send ISO data on the second ISO. Expect credits being available.*/
  EXPECT_CALL(bte_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
  for (uint8_t i = 0; i < num_buffers; i++) {
    IsoManager::GetInstance()->SendIsoData(
        volatile_test_cig_create_cmpl_evt_.conn_handles[1], data_vec.data(),
        data_vec.size());
  }
}

TEST_F(IsoManagerDeathTest, SendIsoDataWithNoDataPath) {
  std::vector<uint8_t> data_vec(108, 0);