Refactor eutra reporting code and add report triggers for inter rat measurements

master
David Rupprecht 4 years ago committed by Andre Puschmann
parent e4e67eebce
commit 0e4d77da76

@ -51,6 +51,8 @@ private:
float rsrq;
} phy_quant_t;
typedef enum { eutra, inter_rat } report_type_t;
class var_meas_cfg;
class var_meas_report_list
@ -66,6 +68,12 @@ private:
const uint32_t carrier_freq,
const report_cfg_eutra_s& report_cfg,
const cell_triggered_t& cell_triggered_list);
void set_measId(const uint32_t measId,
const uint32_t carrier_freq,
const report_cfg_inter_rat_s& report_cfg,
const cell_triggered_t& cell_triggered_list);
void upd_measId(const uint32_t measId, const cell_triggered_t& cell_triggered_list);
cell_triggered_t get_measId_cells(const uint32_t measId);
@ -73,10 +81,12 @@ private:
class var_meas_report
{
public:
report_type_t report_type = eutra;
uint32_t carrier_freq = 0;
uint8_t nof_reports_sent = 0;
cell_triggered_t cell_triggered_list = {};
report_cfg_eutra_s report_cfg = {};
report_cfg_eutra_s report_cfg_eutra = {};
report_cfg_inter_rat_s report_cfg_inter = {};
srslte::timer_handler::unique_timer periodic_timer = {};
};
var_meas_cfg* meas_cfg = nullptr;
@ -134,6 +144,17 @@ private:
void report_triggers_eutra(uint32_t meas_id, report_cfg_eutra_s& report_cfg, meas_obj_eutra_s& meas_obj);
void report_triggers_interrat_nr(uint32_t meas_id, report_cfg_inter_rat_s& report_cfg, meas_obj_nr_r15_s& meas_obj);
void report_triggers_eutra_check_new(int32_t meas_id, report_cfg_eutra_s& report_cfg, meas_obj_eutra_s& meas_obj);
void
report_triggers_eutra_check_leaving(int32_t meas_id, report_cfg_eutra_s& report_cfg);
void report_triggers_eutra_removing_trigger(int32_t meas_id);
void report_triggers_interrat_check_new(int32_t meas_id,
report_cfg_inter_rat_s& report_cfg,
meas_obj_nr_r15_s& meas_obj);
void report_triggers_interrat_check_leaving(int32_t meas_id, report_cfg_inter_rat_s& report_cfg);
void report_triggers_interrat_removing_trigger(int32_t meas_id);
class cell_trigger_state
{
public:

@ -271,6 +271,8 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId)
meas_result_list_eutra_l& neigh_list = report->meas_result_neigh_cells.set_meas_result_list_eutra();
var_meas_report& var_meas = varMeasReportList.at(measId);
// Todo generate report depending on the type
// sort cells by RSRP
std::sort(
var_meas.cell_triggered_list.begin(), var_meas.cell_triggered_list.end(), [this](phy_cell_t a, phy_cell_t b) {
@ -290,19 +292,19 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId)
rrc_ptr->get_cell_rsrq(var_meas.carrier_freq, cell.pci));
continue;
}
if (neigh_list.size() <= var_meas.report_cfg.max_report_cells) {
if (neigh_list.size() <= var_meas.report_cfg_eutra.max_report_cells) {
float rsrp_value = rrc_ptr->get_cell_rsrp(var_meas.carrier_freq, cell.pci);
float rsrq_value = rrc_ptr->get_cell_rsrq(var_meas.carrier_freq, cell.pci);
meas_result_eutra_s rc = {};
// Set quantity to report
switch (var_meas.report_cfg.report_quant.value) {
switch (var_meas.report_cfg_eutra.report_quant.value) {
case report_cfg_eutra_s::report_quant_opts::both:
rc.meas_result.rsrp_result_present = true;
rc.meas_result.rsrq_result_present = true;
break;
case report_cfg_eutra_s::report_quant_opts::same_as_trigger_quant:
switch (var_meas.report_cfg.trigger_quant.value) {
switch (var_meas.report_cfg_eutra.trigger_quant.value) {
case report_cfg_eutra_s::trigger_quant_opts::rsrp:
rc.meas_result.rsrp_result_present = true;
break;
@ -340,8 +342,8 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId)
// if the numberOfReportsSent as defined within the VarMeasReportList for this measId is less than the
// reportAmount as defined within the corresponding reportConfig for this measId (also includes case where amount is
// infinity)
if (var_meas.nof_reports_sent < var_meas.report_cfg.report_amount.to_number() ||
var_meas.report_cfg.report_amount.to_number() == -1) {
if (var_meas.nof_reports_sent < var_meas.report_cfg_eutra.report_amount.to_number() ||
var_meas.report_cfg_eutra.report_amount.to_number() == -1) {
// start the periodical reporting timer with the value of reportInterval as defined within the corresponding
// reportConfig for this measId
if (var_meas.periodic_timer.is_valid()) {
@ -352,7 +354,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId)
var_meas.periodic_timer.clear();
}
// else if the triggerType is set to periodical:
if (var_meas.report_cfg.trigger_type.type().value == report_cfg_eutra_s::trigger_type_c_::types::periodical) {
if (var_meas.report_cfg_eutra.trigger_type.type().value == report_cfg_eutra_s::trigger_type_c_::types::periodical) {
// remove the entry within the VarMeasReportList for this measId
remove_varmeas_report(measId);
meas_cfg->remove_measId(measId);
@ -402,7 +404,31 @@ void rrc::rrc_meas::var_meas_report_list::set_measId(const uint32_t m
varMeasReportList.at(measId).periodic_timer = rrc_ptr->task_sched.get_unique_timer();
varMeasReportList.at(measId).periodic_timer.set(report_cfg.report_interv.to_number());
}
varMeasReportList.at(measId).report_cfg = std::move(report_cfg);
varMeasReportList.at(measId).report_cfg_eutra = std::move(report_cfg);
varMeasReportList.at(measId).carrier_freq = carrier_freq;
varMeasReportList.at(measId).nof_reports_sent = 0;
upd_measId(measId, cell_triggered_list);
}
void rrc::rrc_meas::var_meas_report_list::set_measId(const uint32_t measId,
const uint32_t carrier_freq,
const report_cfg_inter_rat_s& report_cfg,
const cell_triggered_t& cell_triggered_list)
{
// Create entry if it doesn't exist.
if (!varMeasReportList.count(measId)) {
varMeasReportList[measId].nof_reports_sent = 0;
}
// The ReportInterval is applicable if the UE performs periodical reporting (i.e. when reportAmount exceeds 1), for
// triggerType event as well as for triggerType periodical
if (!varMeasReportList.at(measId).periodic_timer.is_valid() &&
(report_cfg.report_amount.to_number() > 1 || report_cfg.report_amount.to_number() == -1)) {
varMeasReportList.at(measId).periodic_timer = rrc_ptr->task_sched.get_unique_timer();
varMeasReportList.at(measId).periodic_timer.set(report_cfg.report_interv.to_number());
}
varMeasReportList.at(measId).report_type = inter_rat;
varMeasReportList.at(measId).report_cfg_inter = std::move(report_cfg);
varMeasReportList.at(measId).carrier_freq = carrier_freq;
varMeasReportList.at(measId).nof_reports_sent = 0;
upd_measId(measId, cell_triggered_list);
@ -424,98 +450,148 @@ cell_triggered_t rrc::rrc_meas::var_meas_report_list::get_measId_cells(const uin
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra(uint32_t meas_id,
report_cfg_eutra_s& report_cfg,
meas_obj_eutra_s& meas_obj)
void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra_check_new(int32_t meas_id,
report_cfg_eutra_s& report_cfg,
meas_obj_eutra_s& meas_obj)
{
if (report_cfg.trigger_type.type() == report_cfg_eutra_s::trigger_type_c_::types::event) {
// if the triggerType is set to event and if the entry condition applicable for this event,
{
bool new_cell_trigger = false;
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
for (auto& cell : trigger_state[meas_id]) {
if (cell.second.is_enter_equal(report_cfg.trigger_type.event().time_to_trigger.to_number())) {
// Do not add if already exists
if (std::find_if(cells_triggered_list.begin(), cells_triggered_list.end(), [&cell](const phy_cell_t& c) {
return cell.first == c.pci;
}) == cells_triggered_list.end()) {
cells_triggered_list.push_back({cell.first, meas_obj.carrier_freq});
new_cell_trigger = true;
}
}
bool new_cell_trigger = false;
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
for (auto& cell : trigger_state[meas_id]) {
if (cell.second.is_enter_equal(report_cfg.trigger_type.event().time_to_trigger.to_number())) {
// Do not add if already exists
if (std::find_if(cells_triggered_list.begin(), cells_triggered_list.end(), [&cell](const phy_cell_t& c) {
return cell.first == c.pci;
}) == cells_triggered_list.end()) {
cells_triggered_list.push_back({cell.first, meas_obj.carrier_freq});
new_cell_trigger = true;
}
}
}
if (new_cell_trigger) {
if (new_cell_trigger) {
// include a measurement reporting entry within the VarMeasReportList for this measId (nof_reports reset
// inside) include the concerned cell(s) in the cellsTriggeredList defined within the VarMeasReportList
meas_report->set_measId(meas_id, meas_obj.carrier_freq, report_cfg, cells_triggered_list);
// include a measurement reporting entry within the VarMeasReportList for this measId (nof_reports reset
// inside) include the concerned cell(s) in the cellsTriggeredList defined within the VarMeasReportList
meas_report->set_measId(meas_id, meas_obj.carrier_freq, report_cfg, cells_triggered_list);
// initiate the measurement reporting procedure, as specified in 5.5.5;
meas_report->generate_report(meas_id);
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra_check_leaving(int32_t meas_id, report_cfg_eutra_s& report_cfg)
{
// if the triggerType is set to event and if the leaving condition applicable for this event is fulfilled ...
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
// remove the concerned cell(s) in the cellsTriggeredList defined within the VarMeasReportList
auto it = cells_triggered_list.begin();
while (it != cells_triggered_list.end()) {
if (trigger_state[meas_id][it->pci].is_exit_equal(report_cfg.trigger_type.event().time_to_trigger.to_number())) {
it = cells_triggered_list.erase(it);
meas_report->upd_measId(meas_id, cells_triggered_list);
// if reportOnLeave is set to TRUE for the corresponding reporting configuration
if (report_cfg.trigger_type.event().event_id.type() == eutra_event_s::event_id_c_::types::event_a3 &&
report_cfg.trigger_type.event().event_id.event_a3().report_on_leave) {
// initiate the measurement reporting procedure, as specified in 5.5.5;
meas_report->generate_report(meas_id);
}
}
{
// if the triggerType is set to event and if the leaving condition applicable for this event is fulfilled ...
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
// remove the concerned cell(s) in the cellsTriggeredList defined within the VarMeasReportList
auto it = cells_triggered_list.begin();
while (it != cells_triggered_list.end()) {
if (trigger_state[meas_id][it->pci].is_exit_equal(
report_cfg.trigger_type.event().time_to_trigger.to_number())) {
it = cells_triggered_list.erase(it);
meas_report->upd_measId(meas_id, cells_triggered_list);
// if reportOnLeave is set to TRUE for the corresponding reporting configuration
if (report_cfg.trigger_type.event().event_id.type() == eutra_event_s::event_id_c_::types::event_a3 &&
report_cfg.trigger_type.event().event_id.event_a3().report_on_leave) {
// initiate the measurement reporting procedure, as specified in 5.5.5;
meas_report->generate_report(meas_id);
}
// if the cellsTriggeredList defined within the VarMeasReportList for this measId is empty:
if (cells_triggered_list.empty()) {
remove_varmeas_report(meas_id);
}
} else {
it++;
}
// if the cellsTriggeredList defined within the VarMeasReportList for this measId is empty:
if (cells_triggered_list.empty()) {
remove_varmeas_report(meas_id);
}
} else {
it++;
}
{
meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell();
if (serv_cell == nullptr) {
log_h->warning("MEAS: Serving cell not set when reporting triggers\n");
return;
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra_removing_trigger(int32_t meas_id)
{
meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell();
if (serv_cell == nullptr) {
log_h->warning("MEAS: Serving cell not set when reporting triggers\n");
return;
}
uint32_t serving_pci = serv_cell->get_pci();
// remove all cells in the cellsTriggeredList that are no neighbor cells anymore
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
auto it = cells_triggered_list.begin();
while (it != cells_triggered_list.end()) {
if (not rrc_ptr->has_neighbour_cell(it->earfcn, it->pci) and it->pci != serving_pci) {
log_h->debug("MEAS: Removing unknown PCI=%d from event trigger list\n", it->pci);
it = cells_triggered_list.erase(it);
meas_report->upd_measId(meas_id, cells_triggered_list);
// if the cellsTriggeredList defined within the VarMeasReportList for this measId is empty:
if (cells_triggered_list.empty()) {
remove_varmeas_report(meas_id);
}
uint32_t serving_pci = serv_cell->get_pci();
// remove all cells in the cellsTriggeredList that are no neighbor cells anymore
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
auto it = cells_triggered_list.begin();
while (it != cells_triggered_list.end()) {
if (not rrc_ptr->has_neighbour_cell(it->earfcn, it->pci) and it->pci != serving_pci) {
log_h->debug("MEAS: Removing unknown PCI=%d from event trigger list\n", it->pci);
it = cells_triggered_list.erase(it);
meas_report->upd_measId(meas_id, cells_triggered_list);
// if the cellsTriggeredList defined within the VarMeasReportList for this measId is empty:
if (cells_triggered_list.empty()) {
remove_varmeas_report(meas_id);
}
} else {
it++;
}
} else {
it++;
}
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra(uint32_t meas_id,
report_cfg_eutra_s& report_cfg,
meas_obj_eutra_s& meas_obj)
{
if (report_cfg.trigger_type.type() == report_cfg_eutra_s::trigger_type_c_::types::event) {
// if the triggerType is set to event and if the entry condition applicable for this event,
report_triggers_eutra_check_new(meas_id, report_cfg, meas_obj);
report_triggers_eutra_check_leaving(meas_id, report_cfg);
report_triggers_eutra_removing_trigger(meas_id);
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_check_new(int32_t meas_id,
report_cfg_inter_rat_s& report_cfg,
meas_obj_nr_r15_s& meas_obj)
{
bool new_cell_trigger = false;
cell_triggered_t cells_triggered_list = meas_report->get_measId_cells(meas_id);
for (auto& cell : trigger_state[meas_id]) {
if (cell.second.is_enter_equal(report_cfg.trigger_type.event().time_to_trigger.to_number())) {
// Do not add if already exists
if (std::find_if(cells_triggered_list.begin(), cells_triggered_list.end(), [&cell](const phy_cell_t& c) {
return cell.first == c.pci;
}) == cells_triggered_list.end()) {
cells_triggered_list.push_back({cell.first, meas_obj.carrier_freq_r15});
new_cell_trigger = true;
}
}
}
if (new_cell_trigger) {
// include a measurement reporting entry within the VarMeasReportList for this measId (nof_reports reset
// inside) include the concerned cell(s) in the cellsTriggeredList defined within the VarMeasReportList
meas_report->set_measId(meas_id, meas_obj.carrier_freq_r15, report_cfg, cells_triggered_list);
// initiate the measurement reporting procedure, as specified in 5.5.5;
meas_report->generate_report(meas_id);
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_check_leaving(int32_t meas_id,
report_cfg_inter_rat_s& report_cfg)
{}
void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_removing_trigger(int32_t meas_id) {}
void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_nr(uint32_t meas_id,
report_cfg_inter_rat_s& report_cfg,
meas_obj_nr_r15_s& meas_obj)
{}
{
if (report_cfg.trigger_type.type() == report_cfg_inter_rat_s::trigger_type_c_::types::event) {
// if the triggerType is set to event and if the entry condition applicable for this event,
report_triggers_interrat_check_new(meas_id, report_cfg, meas_obj);
report_triggers_interrat_check_leaving(meas_id, report_cfg);
report_triggers_interrat_removing_trigger(meas_id);
}
}
void rrc::rrc_meas::var_meas_cfg::report_triggers()
{

Loading…
Cancel
Save