mirror of https://github.com/PentHertz/srsLTE.git
fix cellsToAddModList handling. Now the eNB always adds PCell+SCells as measObjects in the RRC Reconfiguration messages. It may also further include cellsToAddModList if they are provided in the rr.conf file
This commit is contained in:
parent
8c30822350
commit
da70c0fdaf
|
@ -182,9 +182,6 @@ private:
|
|||
uint32_t nof_si_messages = 0;
|
||||
asn1::rrc::sib_type7_s sib7;
|
||||
|
||||
class enb_mobility_handler;
|
||||
std::unique_ptr<enb_mobility_handler> enb_mobility_cfg;
|
||||
|
||||
void rem_user_thread(uint16_t rnti);
|
||||
|
||||
std::mutex paging_mutex;
|
||||
|
|
|
@ -77,6 +77,8 @@ public:
|
|||
const cell_info_common* get_pci(uint32_t pci) const;
|
||||
size_t nof_cells() const { return cell_list.size(); }
|
||||
|
||||
std::vector<const cell_info_common*> get_potential_cells(uint32_t enb_cc_idx) const;
|
||||
|
||||
private:
|
||||
const rrc_cfg_t& cfg;
|
||||
std::vector<std::unique_ptr<cell_info_common> > cell_list;
|
||||
|
@ -101,6 +103,8 @@ struct cell_ctxt_dedicated {
|
|||
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;
|
||||
|
||||
uint32_t get_dl_earfcn() const { return cell_common->cell_cfg.dl_earfcn; }
|
||||
};
|
||||
|
||||
/** Class used to handle the allocation of a UE's resources across its cells */
|
||||
|
|
|
@ -42,8 +42,9 @@ public:
|
|||
using meas_obj_t = asn1::rrc::meas_obj_to_add_mod_s;
|
||||
using report_cfg_t = asn1::rrc::report_cfg_to_add_mod_s;
|
||||
|
||||
var_meas_cfg_t(uint32_t dl_earfcn_) : dl_earfcn(dl_earfcn_), rrc_log(srslte::logmap::get("RRC")) {}
|
||||
var_meas_cfg_t();
|
||||
std::tuple<bool, meas_obj_t*, meas_cell_t*> add_cell_cfg(const meas_cell_cfg_t& cellcfg);
|
||||
std::pair<bool, meas_obj_t*> add_meas_obj(uint32_t dl_earfcn);
|
||||
report_cfg_t* add_report_cfg(const asn1::rrc::report_cfg_eutra_s& reportcfg);
|
||||
meas_id_t* add_measid_cfg(uint8_t measobjid, uint8_t repid);
|
||||
asn1::rrc::quant_cfg_s* add_quant_cfg(const asn1::rrc::quant_cfg_eutra_s& quantcfg);
|
||||
|
@ -64,40 +65,18 @@ public:
|
|||
asn1::rrc::meas_obj_to_add_mod_list_l& meas_objs() { return var_meas.meas_obj_list; }
|
||||
asn1::rrc::report_cfg_to_add_mod_list_l& rep_cfgs() { return var_meas.report_cfg_list; }
|
||||
asn1::rrc::meas_id_to_add_mod_list_l& meas_ids() { return var_meas.meas_id_list; }
|
||||
uint32_t get_dl_earfcn() const { return dl_earfcn; }
|
||||
std::string to_string() const;
|
||||
|
||||
static var_meas_cfg_t make(uint32_t dl_earfcn, const asn1::rrc::meas_cfg_s& meas_cfg);
|
||||
static var_meas_cfg_t make(const asn1::rrc::meas_cfg_s& meas_cfg);
|
||||
static var_meas_cfg_t make(const rrc_cfg_t& cfg);
|
||||
|
||||
private:
|
||||
uint32_t dl_earfcn;
|
||||
asn1::rrc::var_meas_cfg_s var_meas;
|
||||
srslte::log_ref rrc_log;
|
||||
};
|
||||
|
||||
enum class ho_interface_t { S1, X2, intra_enb };
|
||||
|
||||
class rrc::enb_mobility_handler
|
||||
{
|
||||
public:
|
||||
explicit enb_mobility_handler(rrc* rrc_);
|
||||
|
||||
//! Variable used to store the MeasConfig expected for each cell.
|
||||
// Note: Made const to forbid silent updates and enable comparison based on addr
|
||||
std::vector<var_meas_cfg_t> cell_meas_cfg_list;
|
||||
|
||||
rrc* get_rrc() { return rrc_ptr; }
|
||||
const rrc* get_rrc() const { return rrc_ptr; }
|
||||
|
||||
uint16_t start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg,
|
||||
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container);
|
||||
|
||||
private:
|
||||
// args
|
||||
rrc* rrc_ptr = nullptr;
|
||||
const rrc_cfg_t* cfg = nullptr;
|
||||
};
|
||||
|
||||
class rrc::ue::rrc_mobility : public srslte::fsm_t<rrc::ue::rrc_mobility>
|
||||
{
|
||||
public:
|
||||
|
@ -109,7 +88,8 @@ public:
|
|||
struct ho_cancel_ev {};
|
||||
|
||||
explicit rrc_mobility(srsenb::rrc::ue* outer_ue);
|
||||
bool fill_conn_recfg_msg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg);
|
||||
|
||||
bool fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg);
|
||||
void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg);
|
||||
void handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container);
|
||||
bool is_ho_running() const { return not is_in_state<idle_st>(); }
|
||||
|
@ -118,29 +98,30 @@ public:
|
|||
bool start_s1_tenb_ho(const asn1::s1ap::ho_request_s& msg,
|
||||
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container);
|
||||
|
||||
static uint16_t
|
||||
start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg,
|
||||
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container);
|
||||
|
||||
private:
|
||||
// helper methods
|
||||
bool update_ue_var_meas_cfg(uint32_t src_earfcn,
|
||||
std::vector<const cell_info_common*> target_cells,
|
||||
asn1::rrc::meas_cfg_s* diff_meas_cfg);
|
||||
|
||||
// Handover from source cell
|
||||
bool start_ho_preparation(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available);
|
||||
bool start_enb_status_transfer();
|
||||
|
||||
// Handover to target cell
|
||||
bool update_ue_var_meas_cfg(const asn1::rrc::meas_cfg_s& source_meas_cfg,
|
||||
uint32_t src_dl_earfcn,
|
||||
uint32_t target_enb_cc_idx,
|
||||
asn1::rrc::meas_cfg_s* diff_meas_cfg);
|
||||
bool update_ue_var_meas_cfg(var_meas_cfg_t& source_var_meas_cfg,
|
||||
uint32_t target_enb_cc_idx,
|
||||
asn1::rrc::meas_cfg_s* diff_meas_cfg);
|
||||
void fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s& msg,
|
||||
const cell_info_common& target_cell,
|
||||
uint32_t src_dl_earfcn);
|
||||
bool apply_ho_prep_cfg(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep, const asn1::s1ap::ho_request_s& ho_req_msg);
|
||||
|
||||
rrc::ue* rrc_ue = nullptr;
|
||||
rrc* rrc_enb = nullptr;
|
||||
rrc::enb_mobility_handler* cfg = nullptr;
|
||||
srslte::byte_buffer_pool* pool = nullptr;
|
||||
srslte::log_ref rrc_log;
|
||||
rrc::ue* rrc_ue = nullptr;
|
||||
rrc* rrc_enb = nullptr;
|
||||
srslte::byte_buffer_pool* pool = nullptr;
|
||||
srslte::log_ref rrc_log;
|
||||
|
||||
// vars
|
||||
var_meas_cfg_t ue_var_meas;
|
||||
|
|
|
@ -75,7 +75,6 @@ void rrc::init(const rrc_cfg_t& cfg_,
|
|||
|
||||
nof_si_messages = generate_sibs();
|
||||
config_mac();
|
||||
enb_mobility_cfg.reset(new enb_mobility_handler(this));
|
||||
|
||||
// Check valid inactivity timeout config
|
||||
uint32_t t310 = cfg.sibs[1].sib2().ue_timers_and_consts.t310.to_number();
|
||||
|
@ -462,12 +461,6 @@ void rrc::ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique
|
|||
users.at(rnti)->mobility_handler->handle_ho_preparation_complete(is_success, std::move(rrc_container));
|
||||
}
|
||||
|
||||
uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg,
|
||||
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container)
|
||||
{
|
||||
return enb_mobility_cfg->start_ho_ue_resource_alloc(msg, container);
|
||||
}
|
||||
|
||||
void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs)
|
||||
{
|
||||
auto ue_it = users.find(rnti);
|
||||
|
|
|
@ -95,6 +95,18 @@ const cell_info_common* cell_info_common_list::get_pci(uint32_t pci) const
|
|||
return it == cell_list.end() ? nullptr : it->get();
|
||||
}
|
||||
|
||||
std::vector<const cell_info_common*> cell_info_common_list::get_potential_cells(uint32_t enb_cc_idx) const
|
||||
{
|
||||
const cell_info_common* pcell = get_cc_idx(enb_cc_idx);
|
||||
std::vector<const cell_info_common*> cells(pcell->cell_cfg.scell_list.size() + 1);
|
||||
cells[0] = pcell;
|
||||
for (uint32_t i = 0; i < pcell->cell_cfg.scell_list.size(); ++i) {
|
||||
uint32_t cell_id = pcell->cell_cfg.scell_list[i].cell_id;
|
||||
cells[i + 1] = get_cell_id(cell_id);
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* cell ctxt dedicated
|
||||
************************/
|
||||
|
|
|
@ -187,6 +187,28 @@ meas_obj_to_add_mod_s* meascfg_add_meas_obj(meas_cfg_s* meas_cfg, const meas_obj
|
|||
* var_meas_cfg_t class
|
||||
************************************************************************************************/
|
||||
|
||||
var_meas_cfg_t::var_meas_cfg_t() : rrc_log(srslte::logmap::get("RRC")) {}
|
||||
|
||||
//! Add EARFCN to the varMeasCfg
|
||||
std::pair<bool, var_meas_cfg_t::meas_obj_t*> var_meas_cfg_t::add_meas_obj(uint32_t dl_earfcn)
|
||||
{
|
||||
auto* obj = rrc_details::find_meas_obj(var_meas.meas_obj_list, dl_earfcn);
|
||||
if (obj != nullptr) {
|
||||
return {false, obj};
|
||||
}
|
||||
|
||||
meas_obj_t new_obj;
|
||||
new_obj.meas_obj_id = srslte::find_rrc_obj_id_gap(var_meas.meas_obj_list);
|
||||
asn1::rrc::meas_obj_eutra_s& eutra = new_obj.meas_obj.set_meas_obj_eutra();
|
||||
eutra.carrier_freq = dl_earfcn;
|
||||
eutra.allowed_meas_bw.value = asn1::rrc::allowed_meas_bw_e::mbw6; // TODO: What value to add here?
|
||||
eutra.neigh_cell_cfg.from_number(1); // No MBSFN subframes present in neighbors
|
||||
eutra.offset_freq_present = false; // no offset
|
||||
obj = srslte::add_rrc_obj(var_meas.meas_obj_list, new_obj);
|
||||
var_meas.meas_obj_list_present = true;
|
||||
return {true, obj};
|
||||
}
|
||||
|
||||
//! Add cell parsed in configuration file to the varMeasCfg
|
||||
std::tuple<bool, var_meas_cfg_t::meas_obj_t*, var_meas_cfg_t::meas_cell_t*>
|
||||
var_meas_cfg_t::add_cell_cfg(const meas_cell_cfg_t& cellcfg)
|
||||
|
@ -195,7 +217,7 @@ var_meas_cfg_t::add_cell_cfg(const meas_cell_cfg_t& cellcfg)
|
|||
bool inserted_flag = true;
|
||||
|
||||
q_offset_range_e offset;
|
||||
asn1::number_to_enum(offset, (int8_t)cellcfg.q_offset); // TODO: What's the difference
|
||||
asn1::number_to_enum(offset, (int8_t)cellcfg.q_offset);
|
||||
|
||||
std::pair<meas_obj_t*, meas_cell_t*> ret =
|
||||
rrc_details::find_cell(var_meas.meas_obj_list, cellcfg.earfcn, cellcfg.pci);
|
||||
|
@ -221,19 +243,13 @@ var_meas_cfg_t::add_cell_cfg(const meas_cell_cfg_t& cellcfg)
|
|||
}
|
||||
} else {
|
||||
// no measobj has been found with same earfcn, create a new one
|
||||
meas_obj_t new_obj;
|
||||
new_obj.meas_obj_id = srslte::find_rrc_obj_id_gap(var_meas.meas_obj_list);
|
||||
asn1::rrc::meas_obj_eutra_s& eutra = new_obj.meas_obj.set_meas_obj_eutra();
|
||||
eutra.carrier_freq = cellcfg.earfcn;
|
||||
eutra.allowed_meas_bw.value = asn1::rrc::allowed_meas_bw_e::mbw6; // TODO: What value to add here?
|
||||
eutra.neigh_cell_cfg.from_number(1); // TODO: What value?
|
||||
eutra.offset_freq_present = true;
|
||||
// TODO: Assert that q_offset is in ms
|
||||
asn1::number_to_enum(eutra.offset_freq, cellcfg.q_offset);
|
||||
auto ret2 = add_meas_obj(cellcfg.earfcn);
|
||||
ret.first = ret2.second;
|
||||
|
||||
new_cell.cell_idx = 1;
|
||||
auto& eutra = ret2.second->meas_obj.meas_obj_eutra();
|
||||
eutra.cells_to_add_mod_list_present = true;
|
||||
eutra.cells_to_add_mod_list.push_back(new_cell);
|
||||
ret.first = srslte::add_rrc_obj(var_meas.meas_obj_list, new_obj);
|
||||
ret.second = &ret.first->meas_obj.meas_obj_eutra().cells_to_add_mod_list.back();
|
||||
}
|
||||
|
||||
|
@ -399,9 +415,9 @@ std::string var_meas_cfg_t::to_string() const
|
|||
* @param meas_cfg
|
||||
* @return
|
||||
*/
|
||||
var_meas_cfg_t var_meas_cfg_t::make(uint32_t dl_earfcn, const asn1::rrc::meas_cfg_s& meas_cfg)
|
||||
var_meas_cfg_t var_meas_cfg_t::make(const asn1::rrc::meas_cfg_s& meas_cfg)
|
||||
{
|
||||
var_meas_cfg_t var{dl_earfcn};
|
||||
var_meas_cfg_t var{};
|
||||
if (meas_cfg.meas_id_to_add_mod_list_present) {
|
||||
var.var_meas.meas_id_list_present = true;
|
||||
var.var_meas.meas_id_list = meas_cfg.meas_id_to_add_mod_list;
|
||||
|
@ -437,45 +453,41 @@ var_meas_cfg_t var_meas_cfg_t::make(uint32_t dl_earfcn, const asn1::rrc::meas_cf
|
|||
return var;
|
||||
}
|
||||
|
||||
var_meas_cfg_t var_meas_cfg_t::make(const rrc_cfg_t& cfg)
|
||||
{
|
||||
var_meas_cfg_t var_meas;
|
||||
if (not cfg.meas_cfg_present) {
|
||||
return var_meas;
|
||||
}
|
||||
|
||||
for (const auto& cell_cfg : cfg.cell_list) {
|
||||
// inserts all neighbor cells
|
||||
for (const meas_cell_cfg_t& meascell : cell_cfg.meas_cfg.meas_cells) {
|
||||
var_meas.add_cell_cfg(meascell);
|
||||
}
|
||||
// insert same report cfg for all cells
|
||||
for (const report_cfg_eutra_s& reportcfg : cell_cfg.meas_cfg.meas_reports) {
|
||||
var_meas.add_report_cfg(reportcfg);
|
||||
}
|
||||
// insert quantity config
|
||||
var_meas.add_quant_cfg(cell_cfg.meas_cfg.quant_cfg);
|
||||
}
|
||||
|
||||
// insert all meas ids
|
||||
// TODO: add this to the parser
|
||||
if (var_meas.rep_cfgs().size() > 0) {
|
||||
for (const auto& measobj : var_meas.meas_objs()) {
|
||||
var_meas.add_measid_cfg(measobj.meas_obj_id, var_meas.rep_cfgs().begin()->report_cfg_id);
|
||||
}
|
||||
}
|
||||
|
||||
return var_meas;
|
||||
}
|
||||
|
||||
/*************************************************************************************************
|
||||
* mobility_cfg class
|
||||
************************************************************************************************/
|
||||
|
||||
rrc::enb_mobility_handler::enb_mobility_handler(rrc* rrc_) : rrc_ptr(rrc_), cfg(&rrc_->cfg)
|
||||
{
|
||||
cell_meas_cfg_list.reserve(cfg->cell_list.size());
|
||||
|
||||
/* Create Template Cell VarMeasCfg List for each Cell */
|
||||
|
||||
for (const auto& cell_cfg : cfg->cell_list) {
|
||||
cell_meas_cfg_list.emplace_back(cell_cfg.dl_earfcn);
|
||||
var_meas_cfg_t& var_meas = cell_meas_cfg_list.back();
|
||||
|
||||
if (cfg->meas_cfg_present) {
|
||||
// inserts all neighbor cells
|
||||
for (const meas_cell_cfg_t& meascell : cell_cfg.meas_cfg.meas_cells) {
|
||||
var_meas.add_cell_cfg(meascell);
|
||||
}
|
||||
|
||||
// insert same report cfg for all cells
|
||||
for (const report_cfg_eutra_s& reportcfg : cell_cfg.meas_cfg.meas_reports) {
|
||||
var_meas.add_report_cfg(reportcfg);
|
||||
}
|
||||
|
||||
// insert all meas ids
|
||||
// TODO: add this to the parser
|
||||
if (var_meas.rep_cfgs().size() > 0) {
|
||||
for (const auto& measobj : var_meas.meas_objs()) {
|
||||
var_meas.add_measid_cfg(measobj.meas_obj_id, var_meas.rep_cfgs().begin()->report_cfg_id);
|
||||
}
|
||||
}
|
||||
|
||||
// insert quantity config
|
||||
var_meas.add_quant_cfg(cell_cfg.meas_cfg.quant_cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: Handover Request Handling
|
||||
* - Allocation of RNTI
|
||||
|
@ -485,18 +497,16 @@ rrc::enb_mobility_handler::enb_mobility_handler(rrc* rrc_) : rrc_ptr(rrc_), cfg(
|
|||
* - Response from TeNB on whether it was able to allocate resources for user doing handover
|
||||
* @return rnti of created ue
|
||||
*/
|
||||
uint16_t rrc::enb_mobility_handler::start_ho_ue_resource_alloc(
|
||||
const asn1::s1ap::ho_request_s& msg,
|
||||
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container)
|
||||
uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg,
|
||||
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container)
|
||||
{
|
||||
// TODO: Decision Making on whether the same QoS of the source eNB can be provided by target eNB
|
||||
|
||||
/* Evaluate if cell exists */
|
||||
uint32_t target_eci = container.target_cell_id.cell_id.to_number();
|
||||
const cell_info_common* target_cell = rrc_ptr->cell_common_list->get_cell_id(rrc_details::eci_to_cellid(target_eci));
|
||||
const cell_info_common* target_cell = cell_common_list->get_cell_id(rrc_details::eci_to_cellid(target_eci));
|
||||
if (target_cell == nullptr) {
|
||||
rrc_ptr->rrc_log->error("The S1-handover target cell_id=0x%x does not exist\n",
|
||||
rrc_details::eci_to_cellid(target_eci));
|
||||
rrc_log->error("The S1-handover target cell_id=0x%x does not exist\n", rrc_details::eci_to_cellid(target_eci));
|
||||
return SRSLTE_INVALID_RNTI;
|
||||
}
|
||||
|
||||
|
@ -509,15 +519,15 @@ uint16_t rrc::enb_mobility_handler::start_ho_ue_resource_alloc(
|
|||
ue_cfg.supported_cc_list[0].enb_cc_idx = target_cell->enb_cc_idx;
|
||||
ue_cfg.ue_bearers[0].direction = sched_interface::ue_bearer_cfg_t::BOTH;
|
||||
ue_cfg.supported_cc_list[0].dl_cfg.tm = SRSLTE_TM1;
|
||||
uint16_t rnti = rrc_ptr->mac->reserve_new_crnti(ue_cfg);
|
||||
uint16_t rnti = mac->reserve_new_crnti(ue_cfg);
|
||||
if (rnti == SRSLTE_INVALID_RNTI) {
|
||||
rrc_ptr->rrc_log->error("Failed to allocate C-RNTI resources\n");
|
||||
rrc_log->error("Failed to allocate C-RNTI resources\n");
|
||||
return SRSLTE_INVALID_RNTI;
|
||||
}
|
||||
|
||||
// Register new user in RRC
|
||||
rrc_ptr->add_user(rnti, ue_cfg);
|
||||
auto it = rrc_ptr->users.find(rnti);
|
||||
add_user(rnti, ue_cfg);
|
||||
auto it = users.find(rnti);
|
||||
ue* ue_ptr = it->second.get();
|
||||
// Reset activity timer (Response is not expected)
|
||||
ue_ptr->set_activity_timeout(ue::UE_INACTIVITY_TIMEOUT);
|
||||
|
@ -530,7 +540,7 @@ uint16_t rrc::enb_mobility_handler::start_ho_ue_resource_alloc(
|
|||
// TODO: KeNB derivations
|
||||
|
||||
if (not ue_ptr->mobility_handler->start_s1_tenb_ho(msg, container)) {
|
||||
rrc_ptr->rem_user_thread(rnti);
|
||||
rem_user_thread(rnti);
|
||||
return SRSLTE_INVALID_RNTI;
|
||||
}
|
||||
return rnti;
|
||||
|
@ -544,14 +554,12 @@ rrc::ue::rrc_mobility::rrc_mobility(rrc::ue* outer_ue) :
|
|||
base_t(outer_ue->parent->rrc_log),
|
||||
rrc_ue(outer_ue),
|
||||
rrc_enb(outer_ue->parent),
|
||||
cfg(outer_ue->parent->enb_mobility_cfg.get()),
|
||||
pool(outer_ue->pool),
|
||||
rrc_log(outer_ue->parent->rrc_log),
|
||||
ue_var_meas(outer_ue->cell_ded_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->cell_cfg.dl_earfcn)
|
||||
rrc_log(outer_ue->parent->rrc_log)
|
||||
{}
|
||||
|
||||
//! Method to add Mobility Info to a RRC Connection Reconfiguration Message
|
||||
bool rrc::ue::rrc_mobility::fill_conn_recfg_msg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg)
|
||||
bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg)
|
||||
{
|
||||
// only reconfigure meas_cfg if no handover is occurring.
|
||||
// NOTE: We basically freeze ue_var_meas for the whole duration of the handover procedure
|
||||
|
@ -559,10 +567,11 @@ bool rrc::ue::rrc_mobility::fill_conn_recfg_msg(asn1::rrc::rrc_conn_recfg_r8_ies
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check if there has been any update in ue_var_meas
|
||||
cell_info_common* pcell = rrc_ue->get_ue_cc_cfg(UE_PCELL_CC_IDX);
|
||||
asn1::rrc::meas_cfg_s& meas_cfg = conn_recfg->meas_cfg;
|
||||
conn_recfg->meas_cfg_present = update_ue_var_meas_cfg(ue_var_meas, pcell->enb_cc_idx, &meas_cfg);
|
||||
// Check if there has been any update in ue_var_meas based on UE current cell list
|
||||
cell_ctxt_dedicated* pcell = rrc_ue->cell_ded_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
|
||||
uint32_t src_earfcn = pcell->get_dl_earfcn();
|
||||
auto target_cells = rrc_enb->cell_common_list->get_potential_cells(pcell->cell_common->enb_cc_idx);
|
||||
conn_recfg->meas_cfg_present = update_ue_var_meas_cfg(src_earfcn, target_cells, &conn_recfg->meas_cfg);
|
||||
return conn_recfg->meas_cfg_present;
|
||||
}
|
||||
|
||||
|
@ -693,7 +702,7 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
|
|||
/*** fill AS-Config ***/
|
||||
hoprep_r8.as_cfg_present = true;
|
||||
// NOTE: set source_meas_cnfg equal to the UE's current var_meas_cfg
|
||||
var_meas_cfg_t empty_meascfg{ue_var_meas.get_dl_earfcn()}, &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
|
||||
// meas_obj_to_add_mod_s* obj = rrc_details::binary_find(target_var_meas.meas_objs(), measobj_id);
|
||||
// obj->meas_obj.meas_obj_eutra().cells_to_add_mod_list.resize(0);
|
||||
|
@ -771,32 +780,25 @@ bool rrc::ue::rrc_mobility::start_s1_tenb_ho(
|
|||
return is_in_state<s1_target_ho_st>();
|
||||
}
|
||||
|
||||
bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(const asn1::rrc::meas_cfg_s& source_meas_cfg,
|
||||
uint32_t src_dl_earfcn,
|
||||
uint32_t target_enb_cc_idx,
|
||||
asn1::rrc::meas_cfg_s* diff_meas_cfg)
|
||||
bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(uint32_t src_earfcn,
|
||||
std::vector<const cell_info_common*> target_cells,
|
||||
asn1::rrc::meas_cfg_s* diff_meas_cfg)
|
||||
{
|
||||
// Generate equivalent VarMeasCfg
|
||||
var_meas_cfg_t source_var = var_meas_cfg_t::make(src_dl_earfcn, source_meas_cfg);
|
||||
|
||||
// Compute difference measCfg and update UE VarMeasCfg
|
||||
return update_ue_var_meas_cfg(source_var, target_enb_cc_idx, diff_meas_cfg);
|
||||
}
|
||||
|
||||
bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(var_meas_cfg_t& source_var_meas_cfg,
|
||||
uint32_t target_enb_cc_idx,
|
||||
asn1::rrc::meas_cfg_s* diff_meas_cfg)
|
||||
{
|
||||
// Fetch cell VarMeasCfg
|
||||
const var_meas_cfg_t& target_var_meas = rrc_enb->enb_mobility_cfg->cell_meas_cfg_list[target_enb_cc_idx];
|
||||
// Make UE Target VarMeasCfg based on parsed Config files + target cells
|
||||
var_meas_cfg_t target_var_meas = var_meas_cfg_t::make(rrc_enb->cfg);
|
||||
// Add PCell+Scells as MeasObjs
|
||||
for (const cell_info_common* c : target_cells) {
|
||||
target_var_meas.add_meas_obj(c->cell_cfg.dl_earfcn);
|
||||
}
|
||||
uint32_t target_earfcn = target_cells[0]->cell_cfg.dl_earfcn;
|
||||
|
||||
// Apply TS 36.331 5.5.6.1 - If Source and Target eNB EARFCNs do no match, update SourceVarMeasCfg.MeasIdList
|
||||
if (target_var_meas.get_dl_earfcn() != source_var_meas_cfg.get_dl_earfcn()) {
|
||||
auto& meas_objs = source_var_meas_cfg.meas_objs();
|
||||
meas_obj_to_add_mod_s* found_target_obj = rrc_details::find_meas_obj(meas_objs, target_var_meas.get_dl_earfcn());
|
||||
meas_obj_to_add_mod_s* found_src_obj = rrc_details::find_meas_obj(meas_objs, source_var_meas_cfg.get_dl_earfcn());
|
||||
if (target_earfcn != src_earfcn) {
|
||||
auto& meas_objs = ue_var_meas.meas_objs();
|
||||
meas_obj_to_add_mod_s* found_target_obj = rrc_details::find_meas_obj(meas_objs, target_earfcn);
|
||||
meas_obj_to_add_mod_s* found_src_obj = rrc_details::find_meas_obj(meas_objs, src_earfcn);
|
||||
if (found_target_obj != nullptr and found_src_obj != nullptr) {
|
||||
for (auto& mid : source_var_meas_cfg.meas_ids()) {
|
||||
for (auto& mid : ue_var_meas.meas_ids()) {
|
||||
if (found_target_obj->meas_obj_id == mid.meas_obj_id) {
|
||||
mid.meas_obj_id = found_src_obj->meas_obj_id;
|
||||
} else if (found_src_obj->meas_obj_id == mid.meas_obj_id) {
|
||||
|
@ -804,10 +806,10 @@ bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(var_meas_cfg_t& source
|
|||
}
|
||||
}
|
||||
} else if (found_src_obj != nullptr) {
|
||||
for (auto it = source_var_meas_cfg.meas_ids().begin(); it != source_var_meas_cfg.meas_ids().end();) {
|
||||
for (auto it = ue_var_meas.meas_ids().begin(); it != ue_var_meas.meas_ids().end();) {
|
||||
if (it->meas_obj_id == found_src_obj->meas_obj_id) {
|
||||
auto rit = it++;
|
||||
source_var_meas_cfg.meas_ids().erase(rit);
|
||||
ue_var_meas.meas_ids().erase(rit);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
|
@ -816,10 +818,10 @@ bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(var_meas_cfg_t& source
|
|||
}
|
||||
|
||||
// Calculate difference between source and target VarMeasCfg
|
||||
bool meas_cfg_present = source_var_meas_cfg.compute_diff_meas_cfg(target_var_meas, diff_meas_cfg);
|
||||
bool meas_cfg_present = ue_var_meas.compute_diff_meas_cfg(target_var_meas, diff_meas_cfg);
|
||||
|
||||
// Update user varMeasCfg to target
|
||||
rrc_ue->mobility_handler->ue_var_meas = target_var_meas;
|
||||
ue_var_meas = target_var_meas;
|
||||
rrc_log->debug_long("New rnti=0x%x varMeasConfig: %s", rrc_ue->rnti, ue_var_meas.to_string().c_str());
|
||||
|
||||
return meas_cfg_present;
|
||||
|
@ -906,7 +908,8 @@ void rrc::ue::rrc_mobility::fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s
|
|||
ant_info.ue_tx_ant_sel.set(setup_e::release);
|
||||
|
||||
// Add MeasConfig of target cell
|
||||
recfg_r8.meas_cfg_present = update_ue_var_meas_cfg(ue_var_meas, target_cell.enb_cc_idx, &recfg_r8.meas_cfg);
|
||||
auto target_cells = rrc_enb->cell_common_list->get_potential_cells(target_cell.enb_cc_idx);
|
||||
recfg_r8.meas_cfg_present = update_ue_var_meas_cfg(src_dl_earfcn, target_cells, &recfg_r8.meas_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1211,7 +1214,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho
|
|||
}
|
||||
|
||||
// Save measConfig
|
||||
ue_var_meas = var_meas_cfg_t::make(ho_prep.as_cfg.source_dl_carrier_freq, ho_prep.as_cfg.source_meas_cfg);
|
||||
ue_var_meas = var_meas_cfg_t::make(ho_prep.as_cfg.source_meas_cfg);
|
||||
rrc_log->debug_long("New rnti=0x%x varMeasConfig: %s", rrc_ue->rnti, ue_var_meas.to_string().c_str());
|
||||
|
||||
return true;
|
||||
|
|
|
@ -550,7 +550,7 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu)
|
|||
bearer_list.fill_pending_nas_info(conn_reconf);
|
||||
|
||||
if (mobility_handler != nullptr) {
|
||||
mobility_handler->fill_conn_recfg_msg(conn_reconf);
|
||||
mobility_handler->fill_conn_recfg_no_ho_cmd(conn_reconf);
|
||||
}
|
||||
last_rrc_conn_recfg = dl_dcch_msg.msg.c1().rrc_conn_recfg();
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ int test_correct_insertion()
|
|||
|
||||
// TEST 1: cell/rep insertion in empty varMeasCfg
|
||||
{
|
||||
var_meas_cfg_t var_cfg{3400};
|
||||
var_meas_cfg_t var_cfg{};
|
||||
auto ret = var_cfg.add_cell_cfg(cell1);
|
||||
TESTASSERT(std::get<0>(ret) and std::get<1>(ret) != nullptr);
|
||||
const auto& objs = var_cfg.meas_objs();
|
||||
|
@ -93,7 +93,7 @@ int test_correct_insertion()
|
|||
}
|
||||
|
||||
{
|
||||
var_meas_cfg_t var_cfg{3400};
|
||||
var_meas_cfg_t var_cfg{};
|
||||
const auto& objs = var_cfg.meas_objs();
|
||||
|
||||
// TEST 2: insertion of out-of-order cell ids in same earfcn
|
||||
|
@ -136,7 +136,7 @@ int test_correct_insertion()
|
|||
|
||||
int test_correct_meascfg_calculation()
|
||||
{
|
||||
var_meas_cfg_t src_var{3400}, target_var{3400};
|
||||
var_meas_cfg_t src_var{}, target_var{};
|
||||
|
||||
meas_cell_cfg_t cell1{}, cell2{};
|
||||
cell1.earfcn = 3400;
|
||||
|
@ -219,7 +219,7 @@ int test_correct_meascfg_calculation()
|
|||
src_var = target_var;
|
||||
TESTASSERT(src_var.meas_objs().size() == 1);
|
||||
TESTASSERT(src_var.meas_objs()[0].meas_obj.meas_obj_eutra().cells_to_add_mod_list.size() == 2);
|
||||
target_var = var_meas_cfg_t{3400};
|
||||
target_var = {};
|
||||
target_var.add_cell_cfg(cell2);
|
||||
target_var.add_report_cfg(rep1);
|
||||
target_var.add_report_cfg(rep3);
|
||||
|
|
Loading…
Reference in New Issue