changes in pucch res allocation api to allow replacing p/scells

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent c892ae56be
commit 71520d681a

@ -175,8 +175,8 @@ private:
bool select_security_algorithms(); bool select_security_algorithms();
void send_dl_ccch(asn1::rrc::dl_ccch_msg_s* dl_ccch_msg); 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, 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()); srslte::unique_byte_buffer_t pdu = srslte::unique_byte_buffer_t());
uint16_t rnti = 0; uint16_t rnti = 0;
rrc* parent = nullptr; rrc* parent = nullptr;

@ -85,9 +85,8 @@ private:
/** Class used to store all the resources specific to a UE's cell */ /** Class used to store all the resources specific to a UE's cell */
struct cell_ctxt_dedicated { struct cell_ctxt_dedicated {
uint32_t ue_cc_idx; uint32_t ue_cc_idx;
const cell_info_common& cell_common; const cell_info_common* cell_common;
bool cqi_res_present = false; bool cqi_res_present = false;
bool sr_res_present = false;
struct cqi_res_t { struct cqi_res_t {
uint32_t pmi_idx = 0; uint32_t pmi_idx = 0;
uint32_t pucch_res = 0; uint32_t pucch_res = 0;
@ -95,12 +94,13 @@ struct cell_ctxt_dedicated {
uint32_t sf_idx = 0; uint32_t sf_idx = 0;
} cqi_res; } 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 // forbid copying to not break counting of pucch allocated resources
cell_ctxt_dedicated(const cell_ctxt_dedicated&) = delete; cell_ctxt_dedicated(const cell_ctxt_dedicated&) = delete;
cell_ctxt_dedicated(cell_ctxt_dedicated&&) noexcept = default; cell_ctxt_dedicated(cell_ctxt_dedicated&&) noexcept = default;
cell_ctxt_dedicated& operator=(const cell_ctxt_dedicated&) = delete; 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 */ /** 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_list();
cell_ctxt_dedicated* add_cell(uint32_t enb_cc_idx); cell_ctxt_dedicated* add_cell(uint32_t enb_cc_idx);
bool rem_last_cell();
bool set_cells(const std::vector<uint32_t>& enb_cc_idxs);
cell_ctxt_dedicated* get_ue_cc_idx(uint32_t ue_cc_idx) 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; } bool is_pucch_cs_allocated() const { return n_pucch_cs_present; }
private: private:
bool alloc_cell_resources(uint32_t ue_cc_idx);
bool alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period); bool alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period);
bool dealloc_cqi_resources(uint32_t ue_cc_idx); bool dealloc_cqi_resources(uint32_t ue_cc_idx);
bool alloc_sr_resources(uint32_t period); bool alloc_sr_resources(uint32_t period);

@ -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_; rrc_cfg_->cell = cell_cfg_;
// Set S1AP related params from cell list // 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.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 // Create dedicated cell configuration from RRC configuration
for (auto& cfg : rrc_cfg_->cell_list) { for (auto& cfg : rrc_cfg_->cell_list) {

@ -178,7 +178,7 @@ void rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg)
bool rnti_added = true; bool rnti_added = true;
if (rnti != SRSLTE_MRNTI) { if (rnti != SRSLTE_MRNTI) {
// only non-eMBMS RNTIs are present in user map // only non-eMBMS RNTIs are present in user map
auto p = users.insert(std::make_pair(rnti, std::unique_ptr<ue>(new ue{this, rnti, sched_ue_cfg}))); auto p = users.insert(std::make_pair(rnti, std::unique_ptr<ue>(new ue{this, rnti, sched_ue_cfg})));
rnti_added = p.second and p.first->second->is_allocated(); rnti_added = p.second and p.first->second->is_allocated();
} }
if (rnti_added) { 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.resize(ue_cc_idx + 1);
} }
list[ue_cc_idx].active = true; 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, &current_sched_ue_cfg); parent->mac->ue_cfg(rnti, &current_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.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH;
bearer_cfg.group = 0; bearer_cfg.group = 0;
parent->mac->bearer_ue_cfg(rnti, 2, &bearer_cfg); 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() bearer_cfg.group = last_rrc_conn_recfg.crit_exts.c1()
.rrc_conn_recfg_r8() .rrc_conn_recfg_r8()
.rr_cfg_ded.drb_to_add_mod_list[0] .rr_cfg_ded.drb_to_add_mod_list[0]
.lc_ch_cfg.ul_specific_params.lc_ch_group; .lc_ch_cfg.ul_specific_params.lc_ch_group;
for (const std::pair<const uint8_t, erab_t>& erab_pair : erabs) { for (const std::pair<const uint8_t, erab_t>& erab_pair : erabs) {
parent->mac->bearer_ue_cfg(rnti, erab_pair.second.id - 2, &bearer_cfg); 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 // 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; continue;
} }
uint32_t scell_idx = p.ue_cc_idx; 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_type1_s& cell_sib1 = cc_cfg->sib1;
const sib_type2_s& cell_sib2 = cc_cfg->sib2; 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) { if (!pdu) {
pdu = srslte::allocate_unique_buffer(*pool); 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()); asn1::bit_ref bref(pdu->msg, pdu->get_tailroom());
if (dl_dcch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { if (dl_dcch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) {
parent->rrc_log->error("Failed to encode DL-DCCH-Msg\n"); 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); 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)); parent->pdcp->write_sdu(rnti, lcid, std::move(pdu));
} else { } else {
parent->rrc_log->error("Allocating pdu\n"); 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) void rrc::ue::apply_setup_phy_common(const asn1::rrc::rr_cfg_common_sib_s& config)

@ -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) 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) { 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); 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); 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 // Allocate CQI, SR, and PUCCH CS resources. If failure, do not add new cell
if (ue_cc_idx == UE_PCELL_CC_IDX) { if (ue_cc_idx == UE_PCELL_CC_IDX) {
if (not alloc_sr_resources(cfg.sr_cfg.period)) { if (not alloc_sr_resources(cfg.sr_cfg.period)) {
log_h->error("Failed to allocate SR resources for PCell\n"); log_h->error("Failed to allocate SR resources for PCell\n");
cell_ded_list.pop_back(); return false;
return nullptr;
} }
if (cfg.cell_list.size() == 2) { if (cfg.cell_list.size() == 2) {
// Allocate resources for Format1b CS (will be optional PUCCH3/CS) // Allocate resources for Format1b CS (will be optional PUCCH3/CS)
if (not alloc_pucch_cs_resources()) { if (not alloc_pucch_cs_resources()) {
log_h->error("Error allocating PUCCH Format1b CS resource for SCell\n"); log_h->error("Error allocating PUCCH Format1b CS resource for SCell\n");
cell_ded_list.pop_back(); return false;
return nullptr;
} }
} }
} }
if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) { 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); log_h->error("Failed to allocate CQIresources for cell ue_cc_idx=%d\n", ue_cc_idx);
cell_ded_list.pop_back(); return false;
return nullptr;
} }
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<uint32_t>& 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) 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; 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 c = SRSLTE_CP_ISNORM(cfg.cell.cp) ? 3 : 2;
uint32_t delta_pucch_shift = pcell_pucch_cfg.delta_pucch_shift.to_number(); uint32_t delta_pucch_shift = pcell_pucch_cfg.delta_pucch_shift.to_number();
delta_pucch_shift = SRSLTE_MAX(1, delta_pucch_shift); 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"); log_h->error("The user cell pcell has not been allocated\n");
return false; return false;
} }
if (cell->sr_res_present) { if (sr_res_present) {
log_h->error("The user sr resources are already allocated\n"); log_h->error("The user sr resources are already allocated\n");
return false; return false;
} }
uint32_t c = SRSLTE_CP_ISNORM(cfg.cell.cp) ? 3 : 2; 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 delta_pucch_shift = SRSLTE_MAX(1, delta_pucch_shift); // prevent div by zero
uint32_t max_users = 12 * c / delta_pucch_shift; 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 // Compute N_pucch_sr
sr_res.sr_N_pucch = i_min * max_users + pucch_res->sr_sched.nof_users[i_min][j_min]; 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) { 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; sr_res.sr_N_pucch += cell->cell_common->sib2.rr_cfg_common.pucch_cfg_common.ncs_an;
} }
// Allocate user // 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"); log_h->error("The user cell pcell has not been allocated\n");
return false; return false;
} }
if (cell->sr_res_present) { if (n_pucch_cs_present) {
log_h->error("The user sr resources are already allocated\n"); log_h->error("The user sr resources are already allocated\n");
return false; 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 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); const uint32_t max_cce = srslte_max_cce(cfg.cell.nof_prb);
// Loop through all available resources // Loop through all available resources

@ -466,7 +466,7 @@ void var_meas_cfg_t::compute_diff_cells(const meas_obj_eutra_s& target_it,
return; return;
case rrc_details::diff_outcome_t::id_removed: case rrc_details::diff_outcome_t::id_removed:
// case "entry with matching cellIndex exists in cellsToRemoveList // 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_present = true;
eutra_obj->cells_to_rem_list.push_back(result.src_it->cell_idx); eutra_obj->cells_to_rem_list.push_back(result.src_it->cell_idx);
break; break;

Loading…
Cancel
Save