From 71520d681a51872fe5306a83e92c70d11d1f64d5 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 7 May 2020 15:31:52 +0100 Subject: [PATCH] changes in pucch res allocation api to allow replacing p/scells --- srsenb/hdr/stack/rrc/rrc.h | 4 +- srsenb/hdr/stack/rrc/rrc_cell_cfg.h | 9 +- srsenb/src/enb_cfg_parser.cc | 4 +- srsenb/src/stack/rrc/rrc.cc | 15 ++-- srsenb/src/stack/rrc/rrc_cell_cfg.cc | 124 +++++++++++++++++++++++---- srsenb/src/stack/rrc/rrc_mobility.cc | 2 +- 6 files changed, 129 insertions(+), 29 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 39158a401..afab56d76 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -175,8 +175,8 @@ private: bool select_security_algorithms(); void send_dl_ccch(asn1::rrc::dl_ccch_msg_s* dl_ccch_msg); - void send_dl_dcch(asn1::rrc::dl_dcch_msg_s* dl_dcch_msg, - srslte::unique_byte_buffer_t pdu = srslte::unique_byte_buffer_t()); + bool send_dl_dcch(const asn1::rrc::dl_dcch_msg_s* dl_dcch_msg, + srslte::unique_byte_buffer_t pdu = srslte::unique_byte_buffer_t()); uint16_t rnti = 0; rrc* parent = nullptr; diff --git a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h index 1840ea05b..828bc7623 100644 --- a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h @@ -85,9 +85,8 @@ private: /** Class used to store all the resources specific to a UE's cell */ struct cell_ctxt_dedicated { uint32_t ue_cc_idx; - const cell_info_common& cell_common; + const cell_info_common* cell_common; bool cqi_res_present = false; - bool sr_res_present = false; struct cqi_res_t { uint32_t pmi_idx = 0; uint32_t pucch_res = 0; @@ -95,12 +94,13 @@ struct cell_ctxt_dedicated { uint32_t sf_idx = 0; } cqi_res; - explicit cell_ctxt_dedicated(uint32_t i_, const cell_info_common& c_) : ue_cc_idx(i_), cell_common(c_) {} + explicit cell_ctxt_dedicated(uint32_t i_, const cell_info_common& c_) : ue_cc_idx(i_), cell_common(&c_) {} // forbid copying to not break counting of pucch allocated resources cell_ctxt_dedicated(const cell_ctxt_dedicated&) = delete; cell_ctxt_dedicated(cell_ctxt_dedicated&&) noexcept = default; cell_ctxt_dedicated& operator=(const cell_ctxt_dedicated&) = delete; + cell_ctxt_dedicated& operator=(cell_ctxt_dedicated&&) noexcept = default; }; /** Class used to handle the allocation of a UE's resources across its cells */ @@ -113,6 +113,8 @@ public: ~cell_ctxt_dedicated_list(); cell_ctxt_dedicated* add_cell(uint32_t enb_cc_idx); + bool rem_last_cell(); + bool set_cells(const std::vector& enb_cc_idxs); cell_ctxt_dedicated* get_ue_cc_idx(uint32_t ue_cc_idx) { @@ -138,6 +140,7 @@ public: bool is_pucch_cs_allocated() const { return n_pucch_cs_present; } private: + bool alloc_cell_resources(uint32_t ue_cc_idx); bool alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period); bool dealloc_cqi_resources(uint32_t ue_cc_idx); bool alloc_sr_resources(uint32_t period); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 97c993bd6..86819d1cb 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -897,9 +897,9 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ rrc_cfg_->cell = cell_cfg_; // Set S1AP related params from cell list - args_->stack.s1ap.enb_id = args_->enb.enb_id; + args_->stack.s1ap.enb_id = args_->enb.enb_id; args_->stack.s1ap.cell_id = rrc_cfg_->cell_list.at(0).cell_id; - args_->stack.s1ap.tac = rrc_cfg_->cell_list.at(0).tac; + args_->stack.s1ap.tac = rrc_cfg_->cell_list.at(0).tac; // Create dedicated cell configuration from RRC configuration for (auto& cfg : rrc_cfg_->cell_list) { diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index dc3dc6d84..b62daffcc 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -178,7 +178,7 @@ void rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg) bool rnti_added = true; if (rnti != SRSLTE_MRNTI) { // only non-eMBMS RNTIs are present in user map - auto p = users.insert(std::make_pair(rnti, std::unique_ptr(new ue{this, rnti, sched_ue_cfg}))); + auto p = users.insert(std::make_pair(rnti, std::unique_ptr(new ue{this, rnti, sched_ue_cfg}))); rnti_added = p.second and p.first->second->is_allocated(); } if (rnti_added) { @@ -1244,7 +1244,7 @@ void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte: list.resize(ue_cc_idx + 1); } list[ue_cc_idx].active = true; - list[ue_cc_idx].enb_cc_idx = ue_cell.cell_common.enb_cc_idx; + list[ue_cc_idx].enb_cc_idx = ue_cell.cell_common->enb_cc_idx; } parent->mac->ue_cfg(rnti, ¤t_sched_ue_cfg); @@ -1253,12 +1253,15 @@ void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte: bearer_cfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH; bearer_cfg.group = 0; parent->mac->bearer_ue_cfg(rnti, 2, &bearer_cfg); + current_sched_ue_cfg.ue_bearers[2] = bearer_cfg; + bearer_cfg.group = last_rrc_conn_recfg.crit_exts.c1() .rrc_conn_recfg_r8() .rr_cfg_ded.drb_to_add_mod_list[0] .lc_ch_cfg.ul_specific_params.lc_ch_group; for (const std::pair& erab_pair : erabs) { parent->mac->bearer_ue_cfg(rnti, erab_pair.second.id - 2, &bearer_cfg); + current_sched_ue_cfg.ue_bearers[erab_pair.second.id - 2] = bearer_cfg; } // Acknowledge Dedicated Configuration @@ -1942,7 +1945,7 @@ int rrc::ue::fill_scell_to_addmod_list(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_ continue; } uint32_t scell_idx = p.ue_cc_idx; - const cell_info_common* cc_cfg = &p.cell_common; + const cell_info_common* cc_cfg = p.cell_common; const sib_type1_s& cell_sib1 = cc_cfg->sib1; const sib_type2_s& cell_sib2 = cc_cfg->sib2; @@ -2314,7 +2317,7 @@ void rrc::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) } } -void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffer_t pdu) +bool rrc::ue::send_dl_dcch(const dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffer_t pdu) { if (!pdu) { pdu = srslte::allocate_unique_buffer(*pool); @@ -2323,7 +2326,7 @@ void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffe asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); if (dl_dcch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { parent->rrc_log->error("Failed to encode DL-DCCH-Msg\n"); - return; + return false; } pdu->N_bytes = 1u + (uint32_t)bref.distance_bytes(pdu->msg); @@ -2338,7 +2341,9 @@ void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffe parent->pdcp->write_sdu(rnti, lcid, std::move(pdu)); } else { parent->rrc_log->error("Allocating pdu\n"); + return false; } + return true; } void rrc::ue::apply_setup_phy_common(const asn1::rrc::rr_cfg_common_sib_s& config) diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index 0990d5493..3cdf4b658 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -120,7 +120,7 @@ cell_ctxt_dedicated_list::~cell_ctxt_dedicated_list() cell_ctxt_dedicated* cell_ctxt_dedicated_list::get_enb_cc_idx(uint32_t enb_cc_idx) { auto it = std::find_if(cell_ded_list.begin(), cell_ded_list.end(), [enb_cc_idx](const cell_ctxt_dedicated& c) { - return c.cell_common.enb_cc_idx == enb_cc_idx; + return c.cell_common->enb_cc_idx == enb_cc_idx; }); return it == cell_ded_list.end() ? nullptr : &(*it); } @@ -147,29 +147,121 @@ cell_ctxt_dedicated* cell_ctxt_dedicated_list::add_cell(uint32_t enb_cc_idx) cell_ded_list.emplace_back(cell_ded_list.size(), *cell_common); + // Allocate CQI, SR, and PUCCH CS resources. If failure, do not add new cell + if (not alloc_cell_resources(ue_cc_idx)) { + rem_last_cell(); + return nullptr; + } + + return &cell_ded_list.back(); +} + +bool cell_ctxt_dedicated_list::rem_last_cell() +{ + if (cell_ded_list.empty()) { + return false; + } + uint32_t ue_cc_idx = cell_ded_list.size() - 1; + if (ue_cc_idx == UE_PCELL_CC_IDX) { + dealloc_sr_resources(); + dealloc_pucch_cs_resources(); + } + dealloc_cqi_resources(ue_cc_idx); + cell_ded_list.pop_back(); + return true; +} + +bool cell_ctxt_dedicated_list::alloc_cell_resources(uint32_t ue_cc_idx) +{ // Allocate CQI, SR, and PUCCH CS resources. If failure, do not add new cell if (ue_cc_idx == UE_PCELL_CC_IDX) { if (not alloc_sr_resources(cfg.sr_cfg.period)) { log_h->error("Failed to allocate SR resources for PCell\n"); - cell_ded_list.pop_back(); - return nullptr; + return false; } if (cfg.cell_list.size() == 2) { // Allocate resources for Format1b CS (will be optional PUCCH3/CS) if (not alloc_pucch_cs_resources()) { log_h->error("Error allocating PUCCH Format1b CS resource for SCell\n"); - cell_ded_list.pop_back(); - return nullptr; + return false; } } } if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) { - log_h->error("Failed to allocate CQIresources for cell enb_cc_idx=%d\n", enb_cc_idx); - cell_ded_list.pop_back(); - return nullptr; + log_h->error("Failed to allocate CQIresources for cell ue_cc_idx=%d\n", ue_cc_idx); + return false; } + return true; +} - return &cell_ded_list.back(); +/** + * Set UE Cells. Contrarily to rem_cell/add_cell(), this method avoids unnecessary reallocation of PUCCH resources. + * @param enb_cc_idxs list of cells supported by the UE + * @return true if all cells were allocated + */ +bool cell_ctxt_dedicated_list::set_cells(const std::vector& enb_cc_idxs) +{ + // Remove extra previously allocked cells + while (enb_cc_idxs.size() < cell_ded_list.size()) { + rem_last_cell(); + } + if (cell_ded_list.empty()) { + // There were no previous cells allocated. Just add new ones + for (auto& cc_idx : enb_cc_idxs) { + if (not add_cell(cc_idx)) { + return false; + } + } + return true; + } + + const cell_info_common* prev_pcell = cell_ded_list[UE_PCELL_CC_IDX].cell_common; + const cell_info_common* new_pcell = common_list.get_cc_idx(enb_cc_idxs[0]); + bool pcell_freq_changed = prev_pcell->cell_cfg.dl_earfcn != new_pcell->cell_cfg.dl_earfcn; + + if (pcell_freq_changed) { + // Need to clean all allocated resources if PCell earfcn changes + while (not cell_ded_list.empty()) { + rem_last_cell(); + } + while (cell_ded_list.size() < enb_cc_idxs.size()) { + if (not add_cell(enb_cc_idxs[cell_ded_list.size()])) { + return false; + } + } + return true; + } + + uint32_t ue_cc_idx = 0; + for (; ue_cc_idx < enb_cc_idxs.size(); ++ue_cc_idx) { + uint32_t enb_cc_idx = enb_cc_idxs[ue_cc_idx]; + const cell_info_common* cell_common = common_list.get_cc_idx(enb_cc_idx); + if (cell_common == nullptr) { + log_h->error("cell with enb_cc_idx=%d does not exist.\n", enb_cc_idx); + break; + } + auto* prev_cell_common = cell_ded_list[ue_cc_idx].cell_common; + if (enb_cc_idx == prev_cell_common->enb_cc_idx) { + // Same cell. Do not realloc resources + continue; + } + + dealloc_cqi_resources(ue_cc_idx); + cell_ded_list[ue_cc_idx] = cell_ctxt_dedicated{ue_cc_idx, *cell_common}; + if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) { + log_h->error("Failed to allocate CQI resources for cell ue_cc_idx=%d\n", ue_cc_idx); + break; + } + } + while (ue_cc_idx < cell_ded_list.size()) { + // Remove cells above the one that failed + rem_last_cell(); + } + if (cell_ded_list.empty()) { + // We failed to allocate new PCell. Fallback to old PCell + add_cell(prev_pcell->enb_cc_idx); + } + return ue_cc_idx == enb_cc_idxs.size(); } bool cell_ctxt_dedicated_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) @@ -184,7 +276,7 @@ bool cell_ctxt_dedicated_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t return false; } - const auto& pcell_pucch_cfg = get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common.sib2.rr_cfg_common.pucch_cfg_common; + const auto& pcell_pucch_cfg = get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->sib2.rr_cfg_common.pucch_cfg_common; uint32_t c = SRSLTE_CP_ISNORM(cfg.cell.cp) ? 3 : 2; uint32_t delta_pucch_shift = pcell_pucch_cfg.delta_pucch_shift.to_number(); delta_pucch_shift = SRSLTE_MAX(1, delta_pucch_shift); @@ -285,13 +377,13 @@ bool cell_ctxt_dedicated_list::alloc_sr_resources(uint32_t period) log_h->error("The user cell pcell has not been allocated\n"); return false; } - if (cell->sr_res_present) { + if (sr_res_present) { log_h->error("The user sr resources are already allocated\n"); return false; } uint32_t c = SRSLTE_CP_ISNORM(cfg.cell.cp) ? 3 : 2; - uint32_t delta_pucch_shift = cell->cell_common.sib2.rr_cfg_common.pucch_cfg_common.delta_pucch_shift.to_number(); + uint32_t delta_pucch_shift = cell->cell_common->sib2.rr_cfg_common.pucch_cfg_common.delta_pucch_shift.to_number(); delta_pucch_shift = SRSLTE_MAX(1, delta_pucch_shift); // prevent div by zero uint32_t max_users = 12 * c / delta_pucch_shift; @@ -327,8 +419,8 @@ bool cell_ctxt_dedicated_list::alloc_sr_resources(uint32_t period) // Compute N_pucch_sr sr_res.sr_N_pucch = i_min * max_users + pucch_res->sr_sched.nof_users[i_min][j_min]; - if (cell->cell_common.sib2.rr_cfg_common.pucch_cfg_common.ncs_an) { - sr_res.sr_N_pucch += cell->cell_common.sib2.rr_cfg_common.pucch_cfg_common.ncs_an; + if (cell->cell_common->sib2.rr_cfg_common.pucch_cfg_common.ncs_an) { + sr_res.sr_N_pucch += cell->cell_common->sib2.rr_cfg_common.pucch_cfg_common.ncs_an; } // Allocate user @@ -365,12 +457,12 @@ bool cell_ctxt_dedicated_list::alloc_pucch_cs_resources() log_h->error("The user cell pcell has not been allocated\n"); return false; } - if (cell->sr_res_present) { + if (n_pucch_cs_present) { log_h->error("The user sr resources are already allocated\n"); return false; } - const sib_type2_s& sib2 = cell->cell_common.sib2; + const sib_type2_s& sib2 = cell->cell_common->sib2; const uint16_t N_pucch_1 = sib2.rr_cfg_common.pucch_cfg_common.n1_pucch_an; const uint32_t max_cce = srslte_max_cce(cfg.cell.nof_prb); // Loop through all available resources diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 305547524..6983b1de7 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -466,7 +466,7 @@ void var_meas_cfg_t::compute_diff_cells(const meas_obj_eutra_s& target_it, return; case rrc_details::diff_outcome_t::id_removed: // case "entry with matching cellIndex exists in cellsToRemoveList - Info("UE can now cease to measure activity of cell %s.\n", rrc_details::to_string(*result.target_it).c_str()); + Info("UE can now cease to measure activity of cell %s.\n", rrc_details::to_string(*result.src_it).c_str()); eutra_obj->cells_to_rem_list_present = true; eutra_obj->cells_to_rem_list.push_back(result.src_it->cell_idx); break;