enable meas gaps in RRC and enb parser

master
Francisco 4 years ago committed by Andre Puschmann
parent c2bc042713
commit 1cb65f07f1

@ -117,9 +117,7 @@ class bit_ref_impl
public:
bit_ref_impl() = default;
bit_ref_impl(Ptr start_ptr_, uint32_t max_size_) :
ptr(start_ptr_),
start_ptr(start_ptr_),
max_ptr(max_size_ + start_ptr_)
ptr(start_ptr_), start_ptr(start_ptr_), max_ptr(max_size_ + start_ptr_)
{}
int distance(const bit_ref_impl<Ptr>& other) const;
@ -1123,6 +1121,7 @@ class copy_ptr
public:
copy_ptr() : ptr(nullptr) {}
explicit copy_ptr(T* ptr_) : ptr(ptr_) {}
copy_ptr(copy_ptr<T>&& other) noexcept : ptr(other.ptr) { other.ptr = nullptr; }
copy_ptr(const copy_ptr<T>& other) { ptr = (other.ptr == nullptr) ? nullptr : new T(*other.ptr); }
~copy_ptr() { destroy_(); }
copy_ptr<T>& operator=(const copy_ptr<T>& other)
@ -1132,6 +1131,14 @@ public:
}
return *this;
}
copy_ptr<T>& operator=(copy_ptr<T>&& other) noexcept
{
if (this != &other) {
ptr = other.ptr;
other.ptr = nullptr;
}
return *this;
}
bool operator==(const copy_ptr<T>& other) const { return *ptr == *other; }
T* operator->() { return ptr; }
const T* operator->() const { return ptr; }

@ -47,8 +47,7 @@ struct rrc_meas_cfg_t {
std::vector<meas_cell_cfg_t> meas_cells;
std::vector<asn1::rrc::report_cfg_eutra_s> meas_reports;
asn1::rrc::quant_cfg_eutra_s quant_cfg;
// TODO: Add blacklist cells
// TODO: Add multiple meas configs
uint32_t meas_gap_period;
};
// Cell/Sector configuration

@ -145,7 +145,7 @@ private:
std::unique_ptr<cell_info_common_list> cell_common_list;
// state
std::unique_ptr<freq_res_common_list> pucch_res_list;
std::unique_ptr<freq_res_common_list> cell_res_list;
std::map<uint16_t, std::unique_ptr<ue> > users; // NOTE: has to have fixed addr
std::map<uint32_t, asn1::rrc::paging_record_s> pending_paging;

@ -27,18 +27,20 @@
namespace srsenb {
class pucch_res_common
class cell_res_common
{
public:
struct pucch_idx_sched_t {
uint32_t nof_users[100][80];
};
const static uint32_t N_PUCCH_MAX_PRB = 4; // Maximum number of PRB to use for PUCCH ACK/NACK in CS mode
const static uint32_t N_PUCCH_MAX_RES = 3 * SRSLTE_NRE * N_PUCCH_MAX_PRB;
pucch_idx_sched_t sr_sched = {};
pucch_idx_sched_t cqi_sched = {};
std::array<bool, N_PUCCH_MAX_RES> n_pucch_cs_used = {};
const static uint32_t N_PUCCH_MAX_PRB = 4; // Maximum number of PRB to use for PUCCH ACK/NACK in CS mode
const static uint32_t N_PUCCH_MAX_RES = 3 * SRSLTE_NRE * N_PUCCH_MAX_PRB;
uint32_t next_measgap_offset = 0;
pucch_idx_sched_t sr_sched = {};
pucch_idx_sched_t cqi_sched = {};
std::array<bool, N_PUCCH_MAX_RES> n_pucch_cs_used = {};
};
/** Storage of CQI/SR/PUCCH CS resources across multiple frequencies and for multiple users */
@ -47,11 +49,11 @@ class freq_res_common_list
public:
explicit freq_res_common_list(const rrc_cfg_t& cfg_);
pucch_res_common* get_earfcn(uint32_t earfcn);
cell_res_common* get_earfcn(uint32_t earfcn);
private:
const rrc_cfg_t& cfg;
std::map<uint32_t, pucch_res_common> pucch_res_list;
const rrc_cfg_t& cfg;
std::map<uint32_t, cell_res_common> pucch_res_list;
};
/** Storage of cell-specific eNB config and derived params */
@ -99,6 +101,8 @@ struct cell_ctxt_dedicated {
uint32_t prb_idx = 0;
uint32_t sf_idx = 0;
} cqi_res;
uint32_t meas_gap_period = 0;
uint32_t meas_gap_offset = 0;
explicit cell_ctxt_dedicated(uint32_t i_, const cell_info_common& c_) : ue_cc_idx(i_), cell_common(&c_) {}
@ -116,7 +120,7 @@ class cell_ctxt_dedicated_list
{
public:
explicit cell_ctxt_dedicated_list(const rrc_cfg_t& cfg_,
freq_res_common_list& pucch_res_list_,
freq_res_common_list& cell_res_list_,
const cell_info_common_list& enb_common_list);
~cell_ctxt_dedicated_list();
@ -163,9 +167,9 @@ private:
srslte::log_ref log_h{"RRC"};
const rrc_cfg_t& cfg;
const cell_info_common_list& common_list;
freq_res_common_list& pucch_res_list;
freq_res_common_list& cell_res_list;
pucch_res_common* pucch_res = nullptr;
cell_res_common* pucch_res = nullptr;
std::vector<cell_ctxt_dedicated> cell_ded_list;
bool sr_res_present = false;
bool n_pucch_cs_present = false;

@ -54,24 +54,30 @@ struct rrc_cfg_t {
asn1::rrc::sib_info_item_c sibs[ASN1_RRC_MAX_SIB];
asn1::rrc::mac_main_cfg_s mac_cnfg;
asn1::rrc::pusch_cfg_ded_s pusch_cfg;
asn1::rrc::ant_info_ded_s antenna_info;
asn1::rrc::pdsch_cfg_ded_s::p_a_e_ pdsch_cfg;
rrc_cfg_sr_t sr_cfg;
rrc_cfg_cqi_t cqi_cfg;
rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI];
bool enable_mbsfn;
uint16_t mbms_mcs;
uint32_t inactivity_timeout_ms;
asn1::rrc::pusch_cfg_ded_s pusch_cfg;
asn1::rrc::ant_info_ded_s antenna_info;
asn1::rrc::pdsch_cfg_ded_s::p_a_e_ pdsch_cfg;
rrc_cfg_sr_t sr_cfg;
rrc_cfg_cqi_t cqi_cfg;
rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI];
bool enable_mbsfn;
uint16_t mbms_mcs;
uint32_t inactivity_timeout_ms;
std::array<srslte::CIPHERING_ALGORITHM_ID_ENUM, srslte::CIPHERING_ALGORITHM_ID_N_ITEMS> eea_preference_list;
std::array<srslte::INTEGRITY_ALGORITHM_ID_ENUM, srslte::INTEGRITY_ALGORITHM_ID_N_ITEMS> eia_preference_list;
bool meas_cfg_present = false;
srslte_cell_t cell;
cell_list_t cell_list;
bool meas_cfg_present = false;
srslte_cell_t cell;
cell_list_t cell_list;
};
constexpr uint32_t UE_PCELL_CC_IDX = 0;
struct ue_var_cfg_t {
asn1::rrc::rr_cfg_ded_s rr_cfg;
asn1::rrc::meas_gap_cfg_c meas_gaps;
asn1::rrc::scell_to_add_mod_list_r10_l scells;
};
} // namespace srsenb
#endif // SRSLTE_RRC_CONFIG_H

@ -104,8 +104,7 @@ private:
srslte::timer_handler::unique_timer activity_timer;
/// cached ASN1 fields for RRC config update checking, and ease of context transfer during HO
asn1::rrc::rr_cfg_ded_s current_rr_cfg;
asn1::rrc::scell_to_add_mod_list_r10_l current_scells;
ue_var_cfg_t current_ue_cfg;
asn1::rrc::establishment_cause_e establishment_cause;

@ -52,6 +52,7 @@ namespace srsenb {
struct rrc_cfg_t;
class cell_ctxt_dedicated_list;
class bearer_cfg_handler;
struct ue_var_cfg_t;
/// Fill RadioResourceConfigDedicated with data known at the RRCSetup/Reestablishment stage
void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg,
@ -59,26 +60,18 @@ void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg,
const cell_ctxt_dedicated_list& ue_cell_list);
/// Apply Reconf updates and update current state
void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
asn1::rrc::rr_cfg_ded_s& current_rr_cfg,
asn1::rrc::scell_to_add_mod_list_r10_l& current_scells,
const rrc_cfg_t& enb_cfg,
const cell_ctxt_dedicated_list& ue_cell_list,
bearer_cfg_handler& bearers,
const srslte::rrc_ue_capabilities_t& ue_caps,
bool phy_cfg_updated);
void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
ue_var_cfg_t& current_ue_cfg,
const rrc_cfg_t& enb_cfg,
const cell_ctxt_dedicated_list& ue_cell_list,
bearer_cfg_handler& bearers,
const srslte::rrc_ue_capabilities_t& ue_caps,
bool phy_cfg_updated);
/// Apply radioResourceConfigDedicated updates to the current UE RRC configuration
void apply_rr_cfg_ded_diff(asn1::rrc::rr_cfg_ded_s& current_rr_cfg_ded,
const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg_ded);
/// Fill rrcConnectionReconfiguration with SCells that were added/mod/removed since last RRC config update
void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
const asn1::rrc::scell_to_add_mod_list_r10_l& current_scells,
const rrc_cfg_t& enb_cfg,
const cell_ctxt_dedicated_list& ue_cell_list,
const srslte::rrc_ue_capabilities_t& ue_caps);
/// Apply Scell updates to the current UE RRC configuration
void apply_scells_to_add_diff(asn1::rrc::scell_to_add_mod_list_r10_l& current_scells,
const asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8);

@ -61,6 +61,7 @@ cell_list =
dl_earfcn = 3350;
//ul_earfcn = 21400;
ho_active = false;
//meas_gap_period = 0;
// CA cells
scell_list = (

@ -743,6 +743,7 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root)
parse_default_field(
cell_cfg.root_seq_idx, cellroot, "root_seq_idx", rrc_cfg->sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx);
parse_default_field(cell_cfg.initial_dl_cqi, cellroot, "initial_dl_cqi", 5u);
parse_default_field(cell_cfg.meas_cfg.meas_gap_period, cellroot, "meas_gap_period", 0u);
if (cellroot.exists("ho_active") and cellroot["ho_active"]) {
HANDLEPARSERCODE(parse_meas_cell_list(&cell_cfg.meas_cfg, cellroot["meas_cell_list"]));

@ -470,9 +470,11 @@ void ue_cfg_apply_meas_cfg(ue_cfg_t& ue_cfg, const meas_cfg_s& meas_cfg, const r
case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp0:
ue_cfg.measgap_period = 40;
ue_cfg.measgap_offset = setup.gap_offset.gp0();
break;
case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp1:
ue_cfg.measgap_period = 80;
ue_cfg.measgap_offset = setup.gap_offset.gp1();
break;
default:
srslte::logmap::get("RRC")->warning("Invalid measGap configuration\n");
ue_cfg.measgap_period = 0;

@ -68,7 +68,7 @@ void rrc::init(const rrc_cfg_t& cfg_,
configure_mbsfn_sibs(&cfg.sibs[1].sib2(), &cfg.sibs[12].sib13_v920());
}
pucch_res_list.reset(new freq_res_common_list{cfg});
cell_res_list.reset(new freq_res_common_list{cfg});
// Loads the PRACH root sequence
cfg.sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx = cfg.cell_list[0].root_seq_idx;

@ -27,7 +27,7 @@ namespace srsenb {
freq_res_common_list::freq_res_common_list(const rrc_cfg_t& cfg_) : cfg(cfg_)
{
for (auto& c : cfg.cell_list) {
for (const auto& c : cfg.cell_list) {
auto it = pucch_res_list.find(c.dl_earfcn);
if (it == pucch_res_list.end()) {
pucch_res_list[c.dl_earfcn] = {};
@ -35,7 +35,7 @@ freq_res_common_list::freq_res_common_list(const rrc_cfg_t& cfg_) : cfg(cfg_)
}
}
pucch_res_common* freq_res_common_list::get_earfcn(uint32_t earfcn)
cell_res_common* freq_res_common_list::get_earfcn(uint32_t earfcn)
{
auto it = pucch_res_list.find(earfcn);
return (it == pucch_res_list.end()) ? nullptr : &(it->second);
@ -143,11 +143,9 @@ std::vector<uint32_t> get_measobj_earfcns(const cell_info_common& pcell)
************************/
cell_ctxt_dedicated_list::cell_ctxt_dedicated_list(const rrc_cfg_t& cfg_,
freq_res_common_list& pucch_res_list_,
freq_res_common_list& cell_res_list_,
const cell_info_common_list& enb_common_list) :
cfg(cfg_),
pucch_res_list(pucch_res_list_),
common_list(enb_common_list)
cfg(cfg_), cell_res_list(cell_res_list_), common_list(enb_common_list)
{
cell_ded_list.reserve(common_list.nof_cells());
}
@ -186,7 +184,7 @@ cell_ctxt_dedicated* cell_ctxt_dedicated_list::add_cell(uint32_t enb_cc_idx)
if (ue_cc_idx == UE_PCELL_CC_IDX) {
// Fetch PUCCH resources if it's pcell
pucch_res = pucch_res_list.get_earfcn(cell_common->cell_cfg.dl_earfcn);
pucch_res = cell_res_list.get_earfcn(cell_common->cell_cfg.dl_earfcn);
}
cell_ded_list.emplace_back(cell_ded_list.size(), *cell_common);
@ -230,11 +228,17 @@ bool cell_ctxt_dedicated_list::alloc_cell_resources(uint32_t ue_cc_idx)
return false;
}
}
cell_ctxt_dedicated* cell = get_ue_cc_idx(UE_PCELL_CC_IDX);
cell->meas_gap_period = cell->cell_common->cell_cfg.meas_cfg.meas_gap_period;
cell->meas_gap_offset = pucch_res->next_measgap_offset;
pucch_res->next_measgap_offset += 6;
}
if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) {
log_h->error("Failed to allocate CQIresources for cell ue_cc_idx=%d\n", ue_cc_idx);
return false;
}
return true;
}
@ -520,7 +524,7 @@ bool cell_ctxt_dedicated_list::alloc_pucch_cs_resources()
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
for (uint32_t i = 0; i < pucch_res_common::N_PUCCH_MAX_RES; i++) {
for (uint32_t i = 0; i < cell_res_common::N_PUCCH_MAX_RES; i++) {
if (!pucch_res->n_pucch_cs_used[i] && (i <= N_pucch_1 && i != sr_res.sr_N_pucch)) {
// Allocate resource
pucch_res->n_pucch_cs_used[i] = true;

@ -711,8 +711,8 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
}
/*** fill AS-Config ***/
hoprep_r8.as_cfg_present = true;
hoprep_r8.as_cfg.source_rr_cfg = rrc_ue->current_rr_cfg;
hoprep_r8.as_cfg.source_scell_cfg_list_r10.reset(new scell_to_add_mod_list_r10_l{rrc_ue->current_scells});
hoprep_r8.as_cfg.source_rr_cfg = rrc_ue->current_ue_cfg.rr_cfg;
hoprep_r8.as_cfg.source_scell_cfg_list_r10.reset(new scell_to_add_mod_list_r10_l{rrc_ue->current_ue_cfg.scells});
// NOTE: set source_meas_cnfg equal to the UE's current var_meas_cfg
var_meas_cfg_t empty_meascfg{}, &target_var_meas = ue_var_meas;
// // however, reset the MeasObjToAdd Cells, so that the UE does not measure again the target eNB
@ -890,17 +890,16 @@ void rrc::ue::rrc_mobility::fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s
intralte.key_change_ind = false;
intralte.next_hop_chaining_count = rrc_ue->ue_security_cfg.get_ncc();
// Add MeasConfig of target cell
recfg_r8.meas_cfg_present = update_ue_var_meas_cfg(src_dl_earfcn, target_cell, &recfg_r8.meas_cfg);
apply_reconf_updates(recfg_r8,
rrc_ue->current_rr_cfg,
rrc_ue->current_scells,
rrc_ue->current_ue_cfg,
rrc_enb->cfg,
rrc_ue->cell_ded_list,
rrc_ue->bearer_list,
rrc_ue->ue_capabilities,
true);
// Add MeasConfig of target cell
recfg_r8.meas_cfg_present = update_ue_var_meas_cfg(src_dl_earfcn, target_cell, &recfg_r8.meas_cfg);
}
/**
@ -1102,8 +1101,8 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req
/* Configure remaining layers based on pending changes */
// Update RLC + PDCP SRBs (no DRBs until MME Status Transfer)
rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_rlc_rb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_ue_cfg.rr_cfg);
rrc_ue->apply_rlc_rb_updates(rrc_ue->current_ue_cfg.rr_cfg);
// Update MAC
rrc_ue->mac_ctrl->handle_target_enb_ho_cmd(recfg_r8, rrc_ue->ue_capabilities);
// Apply PHY updates
@ -1181,7 +1180,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho
rrc_ue->update_scells();
// Save source eNB UE RR cfg as a starting point
apply_rr_cfg_ded_diff(rrc_ue->current_rr_cfg, ho_prep.as_cfg.source_rr_cfg);
apply_rr_cfg_ded_diff(rrc_ue->current_ue_cfg.rr_cfg, ho_prep.as_cfg.source_rr_cfg);
// Save source UE MAC configuration as a base
rrc_ue->mac_ctrl->handle_ho_prep(ho_prep);
@ -1207,7 +1206,7 @@ void rrc::ue::rrc_mobility::handle_recfg_complete(wait_recfg_comp& s, const recf
void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const status_transfer_ev& erabs)
{
// Establish DRBs
rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_ue_cfg.rr_cfg);
// Set DRBs SNs
for (const auto& erab : erabs) {
@ -1316,8 +1315,8 @@ void rrc::ue::rrc_mobility::handle_crnti_ce(intraenb_ho_st& s, const user_crnti_
rrc_enb->phy->set_config(rrc_ue->rnti, rrc_ue->phy_rrc_dedicated_list);
rrc_ue->ue_security_cfg.regenerate_keys_handover(s.target_cell->cell_cfg.pci, s.target_cell->cell_cfg.dl_earfcn);
rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_ue_cfg.rr_cfg);
rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_ue_cfg.rr_cfg);
} else {
rrc_log->info("Received duplicate C-RNTI CE during rnti=0x%x handover.\n", rrc_ue->rnti);
}

@ -42,7 +42,7 @@ rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sch
rnti(rnti_),
pool(srslte::byte_buffer_pool::get_instance()),
phy_rrc_dedicated_list(sched_ue_cfg.supported_cc_list.size()),
cell_ded_list(parent->cfg, *outer_rrc->pucch_res_list, *outer_rrc->cell_common_list),
cell_ded_list(parent->cfg, *outer_rrc->cell_res_list, *outer_rrc->cell_common_list),
bearer_list(rnti_, parent->cfg),
ue_security_cfg(parent->cfg)
{
@ -273,7 +273,7 @@ void rrc::ue::send_connection_setup()
send_dl_ccch(&dl_ccch_msg);
apply_rr_cfg_ded_diff(current_rr_cfg, rr_cfg);
apply_rr_cfg_ded_diff(current_ue_cfg.rr_cfg, rr_cfg);
}
void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srslte::unique_byte_buffer_t pdu)
@ -414,7 +414,7 @@ void rrc::ue::send_connection_reest(uint8_t ncc)
send_dl_ccch(&dl_ccch_msg);
apply_rr_cfg_ded_diff(current_rr_cfg, rr_cfg);
apply_rr_cfg_ded_diff(current_ue_cfg.rr_cfg, rr_cfg);
}
void rrc::ue::handle_rrc_con_reest_complete(rrc_conn_reest_complete_s* msg, srslte::unique_byte_buffer_t pdu)
@ -476,21 +476,20 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, bool phy_
rrc_conn_recfg.rrc_transaction_id = (uint8_t)((transaction_id++) % 4);
rrc_conn_recfg_r8_ies_s& recfg_r8 = rrc_conn_recfg.crit_exts.set_c1().set_rrc_conn_recfg_r8();
// Add measConfig
if (mobility_handler != nullptr) {
mobility_handler->fill_conn_recfg_no_ho_cmd(&recfg_r8);
}
// Fill RR Config Ded and SCells
apply_reconf_updates(recfg_r8,
current_rr_cfg,
current_scells,
current_ue_cfg,
parent->cfg,
cell_ded_list,
bearer_list,
ue_capabilities,
phy_cfg_updated);
// Add measConfig
if (mobility_handler != nullptr) {
mobility_handler->fill_conn_recfg_no_ho_cmd(&recfg_r8);
}
// if no updates were detected, skip rrc reconfiguration
if (not(recfg_r8.rr_cfg_ded_present or recfg_r8.meas_cfg_present or recfg_r8.mob_ctrl_info_present or
recfg_r8.ded_info_nas_list_present or recfg_r8.security_cfg_ho_present or recfg_r8.non_crit_ext_present)) {

@ -38,6 +38,8 @@ using namespace asn1::rrc;
namespace srsenb {
srslte::log_ref log_h = srslte::logmap::get("RRC");
/******************************
* SRBs / DRBs
*****************************/
@ -45,7 +47,7 @@ namespace srsenb {
srb_to_add_mod_s* add_srb(srb_to_add_mod_list_l& srbs, uint8_t srb_id)
{
if (srb_id > 2 or srb_id == 0) {
srslte::logmap::get("RRC")->error("Invalid SRB id=%d\n", srb_id);
log_h->error("Invalid SRB id=%d\n", srb_id);
return nullptr;
}
@ -114,7 +116,7 @@ int16_t get_ri(uint32_t m_ri)
ri_idx = 805 - N_offset_ri;
break;
default:
srslte::logmap::get("RRC")->error("Allocating RI: invalid m_ri=%d\n", m_ri);
log_h->error("Allocating RI: invalid m_ri=%d\n", m_ri);
return -1;
}
@ -146,7 +148,7 @@ int fill_cqi_report_setup(cqi_report_cfg_s& cqi_rep,
if (cqi_rep.cqi_report_periodic_present) {
const cell_ctxt_dedicated* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
if (pcell == nullptr or not pcell->cqi_res_present) {
srslte::logmap::get("RRC")->warning("PCell CQI resources haven\'t been allocated yet\n");
log_h->warning("PCell CQI resources haven\'t been allocated yet\n");
return SRSLTE_ERROR;
}
auto& cqi_periodic = cqi_rep.cqi_report_periodic.setup();
@ -186,7 +188,7 @@ void fill_cqi_report_reconf(cqi_report_cfg_s& cqi_rep,
cqi_setup.ri_cfg_idx_present = true;
cqi_setup.ri_cfg_idx = ri_idx;
} else {
srslte::logmap::get("RRC")->warning("Warning: Configured wrong M_ri parameter.\n");
log_h->warning("Warning: Configured wrong M_ri parameter.\n");
}
}
}
@ -394,6 +396,7 @@ void apply_rr_cfg_ded_diff(rr_cfg_ded_s& current_rr_cfg_ded, const rr_cfg_ded_s&
}
}
/// Fill rrcConnectionReconfiguration with SCells that were added/mod/removed since last RRC config update
void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
const scell_to_add_mod_list_r10_l& current_scells,
const rrc_cfg_t& enb_cfg,
@ -435,8 +438,8 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
auto& nonul_cfg = asn1cell.rr_cfg_common_scell_r10.non_ul_cfg_r10;
asn1::number_to_enum(nonul_cfg.dl_bw_r10, enb_cfg.cell.nof_prb);
asn1::number_to_enum(nonul_cfg.ant_info_common_r10.ant_ports_count, enb_cfg.cell.nof_ports);
nonul_cfg.phich_cfg_r10 = scell_cfg.mib.phich_cfg;
nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common;
nonul_cfg.phich_cfg_r10 = scell_cfg.mib.phich_cfg;
nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common;
// RadioResourceConfigCommonSCell-r10::ul-Configuration-r10
asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true;
auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10;
@ -498,18 +501,18 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
}
#if SRS_ENABLED
ul_cfg_ded.srs_ul_cfg_ded_r10_present = true;
auto& srs_setup = ul_cfg_ded.srs_ul_cfg_ded_r10.set_setup();
srs_setup.srs_bw.value = srs_ul_cfg_ded_c::setup_s_::srs_bw_opts::bw0;
srs_setup.srs_hop_bw.value = srs_ul_cfg_ded_c::setup_s_::srs_hop_bw_opts::hbw0;
srs_setup.freq_domain_position = 0;
srs_setup.dur = true;
srs_setup.srs_cfg_idx = 167;
srs_setup.tx_comb = 0;
srs_setup.cyclic_shift.value = srs_ul_cfg_ded_c::setup_s_::cyclic_shift_opts::cs0;
ul_cfg_ded.srs_ul_cfg_ded_v1020_present = true;
ul_cfg_ded.srs_ul_cfg_ded_r10_present = true;
auto& srs_setup = ul_cfg_ded.srs_ul_cfg_ded_r10.set_setup();
srs_setup.srs_bw.value = srs_ul_cfg_ded_c::setup_s_::srs_bw_opts::bw0;
srs_setup.srs_hop_bw.value = srs_ul_cfg_ded_c::setup_s_::srs_hop_bw_opts::hbw0;
srs_setup.freq_domain_position = 0;
srs_setup.dur = true;
srs_setup.srs_cfg_idx = 167;
srs_setup.tx_comb = 0;
srs_setup.cyclic_shift.value = srs_ul_cfg_ded_c::setup_s_::cyclic_shift_opts::cs0;
ul_cfg_ded.srs_ul_cfg_ded_v1020_present = true;
asn1::number_to_enum(ul_cfg_ded.srs_ul_cfg_ded_v1020.srs_ant_port_r10, enb_cfg.cell.nof_ports);
ul_cfg_ded.srs_ul_cfg_ded_aperiodic_r10_present = true;
ul_cfg_ded.srs_ul_cfg_ded_aperiodic_r10_present = true;
ul_cfg_ded.srs_ul_cfg_ded_aperiodic_r10.set(setup_opts::release);
#endif // SRS_ENABLED
}
@ -563,27 +566,70 @@ void apply_scells_to_add_diff(asn1::rrc::scell_to_add_mod_list_r10_l& current_sc
}
}
bool apply_measgap_updates(meas_gap_cfg_c& meas_gaps,
meas_gap_cfg_c& current_meas_gaps,
const cell_ctxt_dedicated_list& ue_cell_list)
{
bool flag_set = false;
const cell_ctxt_dedicated* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
meas_gap_cfg_c target_meas_gap;
switch (pcell->cell_common->cell_cfg.meas_cfg.meas_gap_period) {
case 40:
target_meas_gap.set_setup().gap_offset.set_gp0() = pcell->meas_gap_offset;
break;
case 80:
target_meas_gap.set_setup().gap_offset.set_gp1() = pcell->meas_gap_offset;
break;
case 0: // no meas gaps
break;
default:
log_h->error("Error setting measurement gaps\n");
}
bool is_current_setup = current_meas_gaps.type().value == setup_opts::setup;
bool is_target_setup = target_meas_gap.type().value == setup_opts::setup;
if (is_target_setup) {
if (not is_current_setup or
current_meas_gaps.setup().gap_offset.type() != target_meas_gap.setup().gap_offset.type()) {
meas_gaps = target_meas_gap;
flag_set = true;
}
} else if (is_current_setup) {
meas_gaps.set(setup_opts::release);
flag_set = true;
}
// update meas gaps
current_meas_gaps = target_meas_gap;
return flag_set;
}
/// Apply Reconf updates and update current state
void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
asn1::rrc::rr_cfg_ded_s& current_rr_cfg,
asn1::rrc::scell_to_add_mod_list_r10_l& current_scells,
const rrc_cfg_t& enb_cfg,
const cell_ctxt_dedicated_list& ue_cell_list,
bearer_cfg_handler& bearers,
const srslte::rrc_ue_capabilities_t& ue_caps,
bool phy_cfg_updated)
void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
ue_var_cfg_t& current_ue_cfg,
const rrc_cfg_t& enb_cfg,
const cell_ctxt_dedicated_list& ue_cell_list,
bearer_cfg_handler& bearers,
const srslte::rrc_ue_capabilities_t& ue_caps,
bool phy_cfg_updated)
{
// Compute pending updates and fill reconf msg
recfg_r8.rr_cfg_ded_present = true;
fill_rr_cfg_ded_reconf(recfg_r8.rr_cfg_ded, current_rr_cfg, enb_cfg, ue_cell_list, bearers, ue_caps, phy_cfg_updated);
fill_scells_reconf(recfg_r8, current_scells, enb_cfg, ue_cell_list, ue_caps);
fill_rr_cfg_ded_reconf(
recfg_r8.rr_cfg_ded, current_ue_cfg.rr_cfg, enb_cfg, ue_cell_list, bearers, ue_caps, phy_cfg_updated);
fill_scells_reconf(recfg_r8, current_ue_cfg.scells, enb_cfg, ue_cell_list, ue_caps);
recfg_r8.meas_cfg.meas_gap_cfg_present =
apply_measgap_updates(recfg_r8.meas_cfg.meas_gap_cfg, current_ue_cfg.meas_gaps, ue_cell_list);
recfg_r8.meas_cfg_present |= recfg_r8.meas_cfg.meas_gap_cfg_present;
// Add pending NAS info
bearers.fill_pending_nas_info(&recfg_r8);
// Update current rr_cfg_ded and scells state
apply_rr_cfg_ded_diff(current_rr_cfg, recfg_r8.rr_cfg_ded);
apply_scells_to_add_diff(current_scells, recfg_r8);
apply_rr_cfg_ded_diff(current_ue_cfg.rr_cfg, recfg_r8.rr_cfg_ded);
apply_scells_to_add_diff(current_ue_cfg.scells, recfg_r8);
}
} // namespace srsenb

@ -21,7 +21,6 @@
#include "srsenb/hdr/enb.h"
#include "srsenb/hdr/stack/rrc/rrc_mobility.h"
#include "srsenb/src/enb_cfg_parser.h"
#include "srsenb/test/common/dummy_classes.h"
#include "srslte/asn1/rrc_utils.h"
#include "srslte/common/test_common.h"
@ -29,6 +28,8 @@
#include <iostream>
#include <srslte/common/log_filter.h>
using namespace asn1::rrc;
meas_cell_cfg_t generate_cell1()
{
meas_cell_cfg_t cell1{};
@ -378,6 +379,7 @@ struct s1ap_mobility_tester : public mobility_tester {
{
TESTASSERT(generate_rrc_cfg_common() == SRSLTE_SUCCESS);
cfg.cell_list[0].meas_cfg.meas_cells[0].eci = 0x19C02;
cfg.cell_list[0].meas_cfg.meas_gap_period = 40;
return SRSLTE_SUCCESS;
}
};
@ -388,12 +390,14 @@ struct intraenb_mobility_tester : public mobility_tester {
{
TESTASSERT(generate_rrc_cfg_common() == SRSLTE_SUCCESS);
cfg.cell_list[0].meas_cfg.meas_cells[0].eci = 0x19B02;
cfg.cell_list[0].meas_cfg.meas_gap_period = 40;
cell_cfg_t cell2 = cfg.cell_list[0];
cell2.pci = 2;
cell2.cell_id = 2;
cell2.meas_cfg.meas_cells[0].pci = 1;
cell2.meas_cfg.meas_cells[0].eci = 0x19B01;
cell2.meas_cfg.meas_gap_period = 80;
cfg.cell_list.push_back(cell2);
return SRSLTE_SUCCESS;
@ -411,6 +415,15 @@ int test_s1ap_mobility(mobility_test_params test_params)
TESTASSERT(tester.run_preamble() == SRSLTE_SUCCESS);
test_dummies::s1ap_mobility_dummy& s1ap = tester.s1ap;
/* Receive correct measConfig */
dl_dcch_msg_s dl_dcch_msg;
TESTASSERT(test_helpers::unpack_asn1(dl_dcch_msg, srslte::make_span(tester.pdcp.last_sdu.sdu)));
rrc_conn_recfg_r8_ies_s& recfg_r8 = dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
TESTASSERT(recfg_r8.meas_cfg_present and recfg_r8.meas_cfg.meas_gap_cfg_present);
TESTASSERT(recfg_r8.meas_cfg.meas_gap_cfg.type().value == setup_opts::setup);
TESTASSERT((1 + recfg_r8.meas_cfg.meas_gap_cfg.setup().gap_offset.type().value) * 40u ==
tester.cfg.cell_list[0].meas_cfg.meas_gap_period);
/* Receive MeasReport from UE (correct if PCI=2) */
if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) {
uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x0D, 0xBC, 0x80}; // PCI == 3
@ -479,7 +492,7 @@ int test_s1ap_mobility(mobility_test_params test_params)
TESTASSERT(tester.rrc_log->error_counter == 0);
asn1::rrc::dl_dcch_msg_s ho_cmd;
TESTASSERT(test_helpers::unpack_asn1(ho_cmd, srslte::make_span(tester.pdcp.last_sdu.sdu)));
auto& recfg_r8 = ho_cmd.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
recfg_r8 = ho_cmd.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
TESTASSERT(recfg_r8.mob_ctrl_info_present);
return SRSLTE_SUCCESS;
@ -605,6 +618,16 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(tester.generate_rrc_cfg() == SRSLTE_SUCCESS);
TESTASSERT(tester.setup_rrc() == SRSLTE_SUCCESS);
TESTASSERT(tester.run_preamble() == SRSLTE_SUCCESS);
/* Receive correct measConfig */
dl_dcch_msg_s dl_dcch_msg;
TESTASSERT(test_helpers::unpack_asn1(dl_dcch_msg, srslte::make_span(tester.pdcp.last_sdu.sdu)));
rrc_conn_recfg_r8_ies_s& recfg_r8 = dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
TESTASSERT(recfg_r8.meas_cfg_present and recfg_r8.meas_cfg.meas_gap_cfg_present);
TESTASSERT(recfg_r8.meas_cfg.meas_gap_cfg.type().value == setup_opts::setup);
TESTASSERT((1 + recfg_r8.meas_cfg.meas_gap_cfg.setup().gap_offset.type().value) * 40u ==
tester.cfg.cell_list[0].meas_cfg.meas_gap_period);
tester.pdcp.last_sdu.sdu = nullptr;
tester.rlc.test_reset_all();
tester.phy.phy_cfg_set = false;
@ -648,7 +671,7 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(tester.pdcp.last_sdu.lcid == 1); // SRB1
asn1::rrc::dl_dcch_msg_s ho_cmd;
TESTASSERT(test_helpers::unpack_asn1(ho_cmd, srslte::make_span(tester.pdcp.last_sdu.sdu)));
auto& recfg_r8 = ho_cmd.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
recfg_r8 = ho_cmd.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
TESTASSERT(recfg_r8.mob_ctrl_info_present);
TESTASSERT(recfg_r8.mob_ctrl_info.new_ue_id.to_number() == tester.rnti);
TESTASSERT(recfg_r8.mob_ctrl_info.target_pci == 2);
@ -659,6 +682,11 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(phy_cfg_ded.cqi_report_cfg_present);
// PHY should not be updated until the UE handovers to the new cell
TESTASSERT(not tester.phy.phy_cfg_set);
// Correct measConfig
TESTASSERT(recfg_r8.meas_cfg_present and recfg_r8.meas_cfg.meas_gap_cfg_present);
TESTASSERT(recfg_r8.meas_cfg.meas_gap_cfg.type().value == setup_opts::setup);
TESTASSERT((1 + recfg_r8.meas_cfg.meas_gap_cfg.setup().gap_offset.type().value) * 40u ==
tester.cfg.cell_list[1].meas_cfg.meas_gap_period);
/* Test Case: The UE sends a C-RNTI CE. Bearers are reestablished, PHY is configured */
tester.pdcp.last_sdu.sdu = nullptr;

@ -25,6 +25,7 @@
#include "srsenb/test/common/dummy_classes.h"
#include "srslte/adt/span.h"
#include "srslte/common/log_filter.h"
#include "srsenb/src/enb_cfg_parser.h"
using namespace srsenb;
using namespace asn1::rrc;

Loading…
Cancel
Save