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: public:
bit_ref_impl() = default; bit_ref_impl() = default;
bit_ref_impl(Ptr start_ptr_, uint32_t max_size_) : bit_ref_impl(Ptr start_ptr_, uint32_t max_size_) :
ptr(start_ptr_), ptr(start_ptr_), start_ptr(start_ptr_), max_ptr(max_size_ + start_ptr_)
start_ptr(start_ptr_),
max_ptr(max_size_ + start_ptr_)
{} {}
int distance(const bit_ref_impl<Ptr>& other) const; int distance(const bit_ref_impl<Ptr>& other) const;
@ -1123,6 +1121,7 @@ class copy_ptr
public: public:
copy_ptr() : ptr(nullptr) {} copy_ptr() : ptr(nullptr) {}
explicit copy_ptr(T* ptr_) : ptr(ptr_) {} 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(const copy_ptr<T>& other) { ptr = (other.ptr == nullptr) ? nullptr : new T(*other.ptr); }
~copy_ptr() { destroy_(); } ~copy_ptr() { destroy_(); }
copy_ptr<T>& operator=(const copy_ptr<T>& other) copy_ptr<T>& operator=(const copy_ptr<T>& other)
@ -1132,6 +1131,14 @@ public:
} }
return *this; 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; } bool operator==(const copy_ptr<T>& other) const { return *ptr == *other; }
T* operator->() { return ptr; } T* operator->() { return ptr; }
const T* operator->() const { 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<meas_cell_cfg_t> meas_cells;
std::vector<asn1::rrc::report_cfg_eutra_s> meas_reports; std::vector<asn1::rrc::report_cfg_eutra_s> meas_reports;
asn1::rrc::quant_cfg_eutra_s quant_cfg; asn1::rrc::quant_cfg_eutra_s quant_cfg;
// TODO: Add blacklist cells uint32_t meas_gap_period;
// TODO: Add multiple meas configs
}; };
// Cell/Sector configuration // Cell/Sector configuration

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

@ -27,18 +27,20 @@
namespace srsenb { namespace srsenb {
class pucch_res_common class cell_res_common
{ {
public: public:
struct pucch_idx_sched_t { struct pucch_idx_sched_t {
uint32_t nof_users[100][80]; 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_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; 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 = {}; uint32_t next_measgap_offset = 0;
std::array<bool, N_PUCCH_MAX_RES> n_pucch_cs_used = {}; 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 */ /** Storage of CQI/SR/PUCCH CS resources across multiple frequencies and for multiple users */
@ -47,11 +49,11 @@ class freq_res_common_list
public: public:
explicit freq_res_common_list(const rrc_cfg_t& cfg_); 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: private:
const rrc_cfg_t& cfg; const rrc_cfg_t& cfg;
std::map<uint32_t, pucch_res_common> pucch_res_list; std::map<uint32_t, cell_res_common> pucch_res_list;
}; };
/** Storage of cell-specific eNB config and derived params */ /** Storage of cell-specific eNB config and derived params */
@ -99,6 +101,8 @@ struct cell_ctxt_dedicated {
uint32_t prb_idx = 0; uint32_t prb_idx = 0;
uint32_t sf_idx = 0; uint32_t sf_idx = 0;
} cqi_res; } 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_) {} 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: public:
explicit cell_ctxt_dedicated_list(const rrc_cfg_t& cfg_, 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); const cell_info_common_list& enb_common_list);
~cell_ctxt_dedicated_list(); ~cell_ctxt_dedicated_list();
@ -163,9 +167,9 @@ private:
srslte::log_ref log_h{"RRC"}; srslte::log_ref log_h{"RRC"};
const rrc_cfg_t& cfg; const rrc_cfg_t& cfg;
const cell_info_common_list& common_list; 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; std::vector<cell_ctxt_dedicated> cell_ded_list;
bool sr_res_present = false; bool sr_res_present = false;
bool n_pucch_cs_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::sib_info_item_c sibs[ASN1_RRC_MAX_SIB];
asn1::rrc::mac_main_cfg_s mac_cnfg; asn1::rrc::mac_main_cfg_s mac_cnfg;
asn1::rrc::pusch_cfg_ded_s pusch_cfg; asn1::rrc::pusch_cfg_ded_s pusch_cfg;
asn1::rrc::ant_info_ded_s antenna_info; asn1::rrc::ant_info_ded_s antenna_info;
asn1::rrc::pdsch_cfg_ded_s::p_a_e_ pdsch_cfg; asn1::rrc::pdsch_cfg_ded_s::p_a_e_ pdsch_cfg;
rrc_cfg_sr_t sr_cfg; rrc_cfg_sr_t sr_cfg;
rrc_cfg_cqi_t cqi_cfg; rrc_cfg_cqi_t cqi_cfg;
rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI]; rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI];
bool enable_mbsfn; bool enable_mbsfn;
uint16_t mbms_mcs; uint16_t mbms_mcs;
uint32_t inactivity_timeout_ms; uint32_t inactivity_timeout_ms;
std::array<srslte::CIPHERING_ALGORITHM_ID_ENUM, srslte::CIPHERING_ALGORITHM_ID_N_ITEMS> eea_preference_list; 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; std::array<srslte::INTEGRITY_ALGORITHM_ID_ENUM, srslte::INTEGRITY_ALGORITHM_ID_N_ITEMS> eia_preference_list;
bool meas_cfg_present = false; bool meas_cfg_present = false;
srslte_cell_t cell; srslte_cell_t cell;
cell_list_t cell_list; cell_list_t cell_list;
}; };
constexpr uint32_t UE_PCELL_CC_IDX = 0; 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 } // namespace srsenb
#endif // SRSLTE_RRC_CONFIG_H #endif // SRSLTE_RRC_CONFIG_H

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

@ -52,6 +52,7 @@ namespace srsenb {
struct rrc_cfg_t; struct rrc_cfg_t;
class cell_ctxt_dedicated_list; class cell_ctxt_dedicated_list;
class bearer_cfg_handler; class bearer_cfg_handler;
struct ue_var_cfg_t;
/// Fill RadioResourceConfigDedicated with data known at the RRCSetup/Reestablishment stage /// Fill RadioResourceConfigDedicated with data known at the RRCSetup/Reestablishment stage
void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, 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); const cell_ctxt_dedicated_list& ue_cell_list);
/// Apply Reconf updates and update current state /// Apply Reconf updates and update current state
void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
asn1::rrc::rr_cfg_ded_s& current_rr_cfg, ue_var_cfg_t& current_ue_cfg,
asn1::rrc::scell_to_add_mod_list_r10_l& current_scells, const rrc_cfg_t& enb_cfg,
const rrc_cfg_t& enb_cfg, const cell_ctxt_dedicated_list& ue_cell_list,
const cell_ctxt_dedicated_list& ue_cell_list, bearer_cfg_handler& bearers,
bearer_cfg_handler& bearers, const srslte::rrc_ue_capabilities_t& ue_caps,
const srslte::rrc_ue_capabilities_t& ue_caps, bool phy_cfg_updated);
bool phy_cfg_updated);
/// Apply radioResourceConfigDedicated updates to the current UE RRC configuration /// 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, 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); 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 /// 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, 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); const asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8);

@ -61,6 +61,7 @@ cell_list =
dl_earfcn = 3350; dl_earfcn = 3350;
//ul_earfcn = 21400; //ul_earfcn = 21400;
ho_active = false; ho_active = false;
//meas_gap_period = 0;
// CA cells // CA cells
scell_list = ( 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( 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); 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.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"]) { if (cellroot.exists("ho_active") and cellroot["ho_active"]) {
HANDLEPARSERCODE(parse_meas_cell_list(&cell_cfg.meas_cfg, cellroot["meas_cell_list"])); 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: case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp0:
ue_cfg.measgap_period = 40; ue_cfg.measgap_period = 40;
ue_cfg.measgap_offset = setup.gap_offset.gp0(); ue_cfg.measgap_offset = setup.gap_offset.gp0();
break;
case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp1: case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp1:
ue_cfg.measgap_period = 80; ue_cfg.measgap_period = 80;
ue_cfg.measgap_offset = setup.gap_offset.gp1(); ue_cfg.measgap_offset = setup.gap_offset.gp1();
break;
default: default:
srslte::logmap::get("RRC")->warning("Invalid measGap configuration\n"); srslte::logmap::get("RRC")->warning("Invalid measGap configuration\n");
ue_cfg.measgap_period = 0; 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()); 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 // Loads the PRACH root sequence
cfg.sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx = cfg.cell_list[0].root_seq_idx; 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_) 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); auto it = pucch_res_list.find(c.dl_earfcn);
if (it == pucch_res_list.end()) { if (it == pucch_res_list.end()) {
pucch_res_list[c.dl_earfcn] = {}; 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); auto it = pucch_res_list.find(earfcn);
return (it == pucch_res_list.end()) ? nullptr : &(it->second); 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_, 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) : const cell_info_common_list& enb_common_list) :
cfg(cfg_), cfg(cfg_), cell_res_list(cell_res_list_), common_list(enb_common_list)
pucch_res_list(pucch_res_list_),
common_list(enb_common_list)
{ {
cell_ded_list.reserve(common_list.nof_cells()); 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) { if (ue_cc_idx == UE_PCELL_CC_IDX) {
// Fetch PUCCH resources if it's pcell // 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); 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; 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)) { 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); log_h->error("Failed to allocate CQIresources for cell ue_cc_idx=%d\n", ue_cc_idx);
return false; return false;
} }
return true; 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 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
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)) { if (!pucch_res->n_pucch_cs_used[i] && (i <= N_pucch_1 && i != sr_res.sr_N_pucch)) {
// Allocate resource // Allocate resource
pucch_res->n_pucch_cs_used[i] = true; 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 ***/ /*** fill AS-Config ***/
hoprep_r8.as_cfg_present = true; hoprep_r8.as_cfg_present = true;
hoprep_r8.as_cfg.source_rr_cfg = rrc_ue->current_rr_cfg; 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_scells}); 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 // 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; 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 // // 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.key_change_ind = false;
intralte.next_hop_chaining_count = rrc_ue->ue_security_cfg.get_ncc(); 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, apply_reconf_updates(recfg_r8,
rrc_ue->current_rr_cfg, rrc_ue->current_ue_cfg,
rrc_ue->current_scells,
rrc_enb->cfg, rrc_enb->cfg,
rrc_ue->cell_ded_list, rrc_ue->cell_ded_list,
rrc_ue->bearer_list, rrc_ue->bearer_list,
rrc_ue->ue_capabilities, rrc_ue->ue_capabilities,
true); 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 */ /* Configure remaining layers based on pending changes */
// Update RLC + PDCP SRBs (no DRBs until MME Status Transfer) // Update RLC + PDCP SRBs (no DRBs until MME Status Transfer)
rrc_ue->apply_pdcp_srb_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_rr_cfg); rrc_ue->apply_rlc_rb_updates(rrc_ue->current_ue_cfg.rr_cfg);
// Update MAC // Update MAC
rrc_ue->mac_ctrl->handle_target_enb_ho_cmd(recfg_r8, rrc_ue->ue_capabilities); rrc_ue->mac_ctrl->handle_target_enb_ho_cmd(recfg_r8, rrc_ue->ue_capabilities);
// Apply PHY updates // 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(); rrc_ue->update_scells();
// Save source eNB UE RR cfg as a starting point // 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 // Save source UE MAC configuration as a base
rrc_ue->mac_ctrl->handle_ho_prep(ho_prep); 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) void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const status_transfer_ev& erabs)
{ {
// Establish DRBs // 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 // Set DRBs SNs
for (const auto& erab : erabs) { 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_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->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_srb_updates(rrc_ue->current_ue_cfg.rr_cfg);
rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_rr_cfg); rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_ue_cfg.rr_cfg);
} else { } else {
rrc_log->info("Received duplicate C-RNTI CE during rnti=0x%x handover.\n", rrc_ue->rnti); 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_), rnti(rnti_),
pool(srslte::byte_buffer_pool::get_instance()), pool(srslte::byte_buffer_pool::get_instance()),
phy_rrc_dedicated_list(sched_ue_cfg.supported_cc_list.size()), 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), bearer_list(rnti_, parent->cfg),
ue_security_cfg(parent->cfg) ue_security_cfg(parent->cfg)
{ {
@ -273,7 +273,7 @@ void rrc::ue::send_connection_setup()
send_dl_ccch(&dl_ccch_msg); 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) 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); 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) 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.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(); 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 // Fill RR Config Ded and SCells
apply_reconf_updates(recfg_r8, apply_reconf_updates(recfg_r8,
current_rr_cfg, current_ue_cfg,
current_scells,
parent->cfg, parent->cfg,
cell_ded_list, cell_ded_list,
bearer_list, bearer_list,
ue_capabilities, ue_capabilities,
phy_cfg_updated); 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 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 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)) { 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 { namespace srsenb {
srslte::log_ref log_h = srslte::logmap::get("RRC");
/****************************** /******************************
* SRBs / DRBs * 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) 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) { 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; return nullptr;
} }
@ -114,7 +116,7 @@ int16_t get_ri(uint32_t m_ri)
ri_idx = 805 - N_offset_ri; ri_idx = 805 - N_offset_ri;
break; break;
default: 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; return -1;
} }
@ -146,7 +148,7 @@ int fill_cqi_report_setup(cqi_report_cfg_s& cqi_rep,
if (cqi_rep.cqi_report_periodic_present) { if (cqi_rep.cqi_report_periodic_present) {
const cell_ctxt_dedicated* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); 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) { 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; return SRSLTE_ERROR;
} }
auto& cqi_periodic = cqi_rep.cqi_report_periodic.setup(); 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_present = true;
cqi_setup.ri_cfg_idx = ri_idx; cqi_setup.ri_cfg_idx = ri_idx;
} else { } 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, 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 scell_to_add_mod_list_r10_l& current_scells,
const rrc_cfg_t& enb_cfg, 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; 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.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); 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.phich_cfg_r10 = scell_cfg.mib.phich_cfg;
nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common; nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common;
// RadioResourceConfigCommonSCell-r10::ul-Configuration-r10 // RadioResourceConfigCommonSCell-r10::ul-Configuration-r10
asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true; asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true;
auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10; 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 #if SRS_ENABLED
ul_cfg_ded.srs_ul_cfg_ded_r10_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(); 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_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.srs_hop_bw.value = srs_ul_cfg_ded_c::setup_s_::srs_hop_bw_opts::hbw0;
srs_setup.freq_domain_position = 0; srs_setup.freq_domain_position = 0;
srs_setup.dur = true; srs_setup.dur = true;
srs_setup.srs_cfg_idx = 167; srs_setup.srs_cfg_idx = 167;
srs_setup.tx_comb = 0; srs_setup.tx_comb = 0;
srs_setup.cyclic_shift.value = srs_ul_cfg_ded_c::setup_s_::cyclic_shift_opts::cs0; 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_v1020_present = true;
asn1::number_to_enum(ul_cfg_ded.srs_ul_cfg_ded_v1020.srs_ant_port_r10, enb_cfg.cell.nof_ports); 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); ul_cfg_ded.srs_ul_cfg_ded_aperiodic_r10.set(setup_opts::release);
#endif // SRS_ENABLED #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 /// Apply Reconf updates and update current state
void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8,
asn1::rrc::rr_cfg_ded_s& current_rr_cfg, ue_var_cfg_t& current_ue_cfg,
asn1::rrc::scell_to_add_mod_list_r10_l& current_scells, const rrc_cfg_t& enb_cfg,
const rrc_cfg_t& enb_cfg, const cell_ctxt_dedicated_list& ue_cell_list,
const cell_ctxt_dedicated_list& ue_cell_list, bearer_cfg_handler& bearers,
bearer_cfg_handler& bearers, const srslte::rrc_ue_capabilities_t& ue_caps,
const srslte::rrc_ue_capabilities_t& ue_caps, bool phy_cfg_updated)
bool phy_cfg_updated)
{ {
// Compute pending updates and fill reconf msg // Compute pending updates and fill reconf msg
recfg_r8.rr_cfg_ded_present = true; 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_rr_cfg_ded_reconf(
fill_scells_reconf(recfg_r8, current_scells, enb_cfg, ue_cell_list, ue_caps); 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 // Add pending NAS info
bearers.fill_pending_nas_info(&recfg_r8); bearers.fill_pending_nas_info(&recfg_r8);
// Update current rr_cfg_ded and scells state // Update current rr_cfg_ded and scells state
apply_rr_cfg_ded_diff(current_rr_cfg, recfg_r8.rr_cfg_ded); apply_rr_cfg_ded_diff(current_ue_cfg.rr_cfg, recfg_r8.rr_cfg_ded);
apply_scells_to_add_diff(current_scells, recfg_r8); apply_scells_to_add_diff(current_ue_cfg.scells, recfg_r8);
} }
} // namespace srsenb } // namespace srsenb

@ -21,7 +21,6 @@
#include "srsenb/hdr/enb.h" #include "srsenb/hdr/enb.h"
#include "srsenb/hdr/stack/rrc/rrc_mobility.h" #include "srsenb/hdr/stack/rrc/rrc_mobility.h"
#include "srsenb/src/enb_cfg_parser.h"
#include "srsenb/test/common/dummy_classes.h" #include "srsenb/test/common/dummy_classes.h"
#include "srslte/asn1/rrc_utils.h" #include "srslte/asn1/rrc_utils.h"
#include "srslte/common/test_common.h" #include "srslte/common/test_common.h"
@ -29,6 +28,8 @@
#include <iostream> #include <iostream>
#include <srslte/common/log_filter.h> #include <srslte/common/log_filter.h>
using namespace asn1::rrc;
meas_cell_cfg_t generate_cell1() meas_cell_cfg_t generate_cell1()
{ {
meas_cell_cfg_t cell1{}; meas_cell_cfg_t cell1{};
@ -378,6 +379,7 @@ struct s1ap_mobility_tester : public mobility_tester {
{ {
TESTASSERT(generate_rrc_cfg_common() == SRSLTE_SUCCESS); 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_cells[0].eci = 0x19C02;
cfg.cell_list[0].meas_cfg.meas_gap_period = 40;
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
}; };
@ -388,12 +390,14 @@ struct intraenb_mobility_tester : public mobility_tester {
{ {
TESTASSERT(generate_rrc_cfg_common() == SRSLTE_SUCCESS); 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_cells[0].eci = 0x19B02;
cfg.cell_list[0].meas_cfg.meas_gap_period = 40;
cell_cfg_t cell2 = cfg.cell_list[0]; cell_cfg_t cell2 = cfg.cell_list[0];
cell2.pci = 2; cell2.pci = 2;
cell2.cell_id = 2; cell2.cell_id = 2;
cell2.meas_cfg.meas_cells[0].pci = 1; cell2.meas_cfg.meas_cells[0].pci = 1;
cell2.meas_cfg.meas_cells[0].eci = 0x19B01; cell2.meas_cfg.meas_cells[0].eci = 0x19B01;
cell2.meas_cfg.meas_gap_period = 80;
cfg.cell_list.push_back(cell2); cfg.cell_list.push_back(cell2);
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -411,6 +415,15 @@ int test_s1ap_mobility(mobility_test_params test_params)
TESTASSERT(tester.run_preamble() == SRSLTE_SUCCESS); TESTASSERT(tester.run_preamble() == SRSLTE_SUCCESS);
test_dummies::s1ap_mobility_dummy& s1ap = tester.s1ap; 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) */ /* Receive MeasReport from UE (correct if PCI=2) */
if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) { 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 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); TESTASSERT(tester.rrc_log->error_counter == 0);
asn1::rrc::dl_dcch_msg_s ho_cmd; asn1::rrc::dl_dcch_msg_s ho_cmd;
TESTASSERT(test_helpers::unpack_asn1(ho_cmd, srslte::make_span(tester.pdcp.last_sdu.sdu))); 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_present);
return SRSLTE_SUCCESS; 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.generate_rrc_cfg() == SRSLTE_SUCCESS);
TESTASSERT(tester.setup_rrc() == SRSLTE_SUCCESS); TESTASSERT(tester.setup_rrc() == SRSLTE_SUCCESS);
TESTASSERT(tester.run_preamble() == 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.pdcp.last_sdu.sdu = nullptr;
tester.rlc.test_reset_all(); tester.rlc.test_reset_all();
tester.phy.phy_cfg_set = false; 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 TESTASSERT(tester.pdcp.last_sdu.lcid == 1); // SRB1
asn1::rrc::dl_dcch_msg_s ho_cmd; asn1::rrc::dl_dcch_msg_s ho_cmd;
TESTASSERT(test_helpers::unpack_asn1(ho_cmd, srslte::make_span(tester.pdcp.last_sdu.sdu))); 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_present);
TESTASSERT(recfg_r8.mob_ctrl_info.new_ue_id.to_number() == tester.rnti); TESTASSERT(recfg_r8.mob_ctrl_info.new_ue_id.to_number() == tester.rnti);
TESTASSERT(recfg_r8.mob_ctrl_info.target_pci == 2); 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); TESTASSERT(phy_cfg_ded.cqi_report_cfg_present);
// PHY should not be updated until the UE handovers to the new cell // PHY should not be updated until the UE handovers to the new cell
TESTASSERT(not tester.phy.phy_cfg_set); 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 */ /* Test Case: The UE sends a C-RNTI CE. Bearers are reestablished, PHY is configured */
tester.pdcp.last_sdu.sdu = nullptr; tester.pdcp.last_sdu.sdu = nullptr;

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

Loading…
Cancel
Save