added diff computation for reportconfig and measid. Tests passing

master
Francisco Paisana 5 years ago
parent 1524e28c3a
commit 200e18ee3a

@ -231,6 +231,13 @@ public:
T* data() { return &data_[0]; }
const T* data() const { return &data_[0]; }
T* begin() { return &data_[0]; }
T* end() { return &data_[size()]; }
const T* begin() const { return &data_[0]; }
const T* end() const { return &data_[size()]; }
using iterator = T*;
using const_iterator = const T*;
private:
T data_[MAX_N];
uint32_t current_size;

@ -27,6 +27,8 @@
namespace srsenb {
bool operator==(const asn1::rrc::report_cfg_eutra_s& lhs, const asn1::rrc::report_cfg_eutra_s& rhs);
/**
* This class is responsible for storing the UE Measurement Configuration at the eNB side.
* Has the same fields as asn1::rrc::var_meas_cfg but stored in data structs that are easier to handle
@ -41,16 +43,20 @@ public:
using report_cfg_t = asn1::rrc::report_cfg_to_add_mod_s;
std::tuple<bool, meas_obj_t*, meas_cell_t*> add_cell_cfg(const meas_cell_cfg_t& cellcfg);
uint32_t get_new_obj_id();
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);
void compute_diff_meas_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const;
bool compute_diff_meas_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const;
void compute_diff_meas_objs(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const;
void compute_diff_cells(const asn1::rrc::meas_obj_eutra_s& target_it,
const asn1::rrc::meas_obj_eutra_s& src_it,
asn1::rrc::meas_obj_to_add_mod_s* added_obj) const;
void compute_diff_report_cfgs(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const;
void compute_diff_meas_ids(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const;
// getters
const asn1::rrc::meas_obj_to_add_mod_list_l& meas_objs() const { return var_meas.meas_obj_list; }
const asn1::rrc::meas_obj_to_add_mod_list_l& meas_objs() const { return var_meas.meas_obj_list; }
const asn1::rrc::report_cfg_to_add_mod_list_l& rep_cfgs() const { return var_meas.report_cfg_list; }
private:
asn1::rrc::var_meas_cfg_s var_meas;

@ -75,6 +75,49 @@ bool operator==(const meas_obj_to_add_mod_s& lhs, const meas_obj_to_add_mod_s& r
rhs_eutra.cells_to_add_mod_list.begin(),
cells_are_equal);
}
bool operator==(const report_cfg_eutra_s& lhs, const report_cfg_eutra_s& rhs)
{
if (lhs.ext or rhs.ext) {
printf("[%d] extension of reportCfgToAddMod not supported\n", __LINE__);
return false;
}
if (lhs.trigger_type.type() != rhs.trigger_type.type()) {
return false;
}
if (lhs.trigger_type.type().value == report_cfg_eutra_s::trigger_type_c_::types_opts::event) {
auto &lhs_ev = lhs.trigger_type.event(), &rhs_ev = rhs.trigger_type.event();
if (lhs_ev.hysteresis != rhs_ev.hysteresis or lhs_ev.time_to_trigger != rhs_ev.time_to_trigger or
lhs_ev.event_id.type() != rhs_ev.event_id.type()) {
return false;
}
if (lhs_ev.event_id.type().value != eutra_event_s::event_id_c_::types_opts::event_a3) {
printf("[%d] event type != A3 of reportCfgToAddMod not supported\n", __LINE__);
return false;
}
if (lhs_ev.event_id.event_a3().report_on_leave != rhs_ev.event_id.event_a3().report_on_leave or
lhs_ev.event_id.event_a3().a3_offset != rhs_ev.event_id.event_a3().a3_offset) {
return false;
}
} else {
if (lhs.trigger_type.periodical().purpose != rhs.trigger_type.periodical().purpose) {
return false;
}
}
return lhs.trigger_quant == rhs.trigger_quant and lhs.report_quant == rhs.report_quant and
lhs.max_report_cells == rhs.max_report_cells and lhs.report_interv == rhs.report_interv and
lhs.report_amount == rhs.report_amount;
}
bool operator==(const report_cfg_to_add_mod_s& lhs, const report_cfg_to_add_mod_s& rhs)
{
if (lhs.report_cfg_id != rhs.report_cfg_id or lhs.report_cfg.type() != rhs.report_cfg.type()) {
return false;
}
return lhs.report_cfg.report_cfg_eutra() == rhs.report_cfg.report_cfg_eutra();
}
bool operator==(const meas_id_to_add_mod_s& lhs, const meas_id_to_add_mod_s& rhs)
{
return lhs.meas_id == rhs.meas_id and lhs.meas_obj_id == rhs.meas_obj_id and lhs.report_cfg_id == rhs.report_cfg_id;
}
namespace rrc_details {
@ -85,14 +128,22 @@ uint32_t eci_to_cellid(uint32_t eci)
}
//! convenience function overload to extract Id from MeasObj/MeasId/ReportCfg/Cells
uint8_t get_id(const cells_to_add_mod_s& obj)
constexpr uint8_t get_id(const cells_to_add_mod_s& obj)
{
return obj.cell_idx;
}
uint8_t get_id(const meas_obj_to_add_mod_s& obj)
constexpr uint8_t get_id(const meas_obj_to_add_mod_s& obj)
{
return obj.meas_obj_id;
}
constexpr uint8_t get_id(const report_cfg_to_add_mod_s& obj)
{
return obj.report_cfg_id;
}
constexpr uint8_t get_id(const meas_id_to_add_mod_s& obj)
{
return obj.meas_id;
}
//! convenience function overload to print MeasObj/MeasId/etc. fields
std::string to_string(const cells_to_add_mod_s& obj)
@ -147,30 +198,9 @@ find_cell(meas_obj_to_add_mod_list_l& l, uint32_t earfcn, uint8_t cell_id)
return {obj, it};
}
//! Adds Cell to MeasCfg MeasObjToAddMod field
cells_to_add_mod_s* meascfg_add_cell(meas_obj_eutra_s& eutra_obj, const cells_to_add_mod_s& celltoadd)
{
// create new cell_id in the provided eutra_obj.
// if the cell_id already exists, just update the fields.
eutra_obj.cells_to_add_mod_list_present = true;
// find the cell. Assumes sorted list
auto& l = eutra_obj.cells_to_add_mod_list;
auto found_it = std::lower_bound(l.begin(), l.end(), celltoadd.cell_idx, rrc_details::cell_id_cmp{});
if (found_it == l.end()) {
eutra_obj.cells_to_add_mod_list.push_back({});
found_it = &eutra_obj.cells_to_add_mod_list.back();
}
*found_it = celltoadd;
// cell_obj->cell_idx = (uint8_t)(cell_id % 3); // 0-3 // FIXME: What?
// printf("The added cell has idx=%d, pci=%d\n", cell_obj->cell_idx, cell_obj->pci);
return found_it;
}
/**
* Adds MeasObjtoAddMod to MeasCfg object
* Section 5.5.2.5
* Description: Adds MeasObjtoAddMod to MeasCfg object
*/
meas_obj_to_add_mod_s* meascfg_add_meas_obj(meas_cfg_s* meas_cfg, const meas_obj_to_add_mod_s& meas_obj)
{
@ -194,6 +224,7 @@ meas_obj_to_add_mod_s* meascfg_add_meas_obj(meas_cfg_s* meas_cfg, const meas_obj
target_eutra.allowed_meas_bw = src_eutra.allowed_meas_bw;
target_eutra.presence_ant_port1 = src_eutra.presence_ant_port1;
target_eutra.neigh_cell_cfg = src_eutra.neigh_cell_cfg;
// do not add cellsToAddModList, blacCells, whiteCells, etc. according to (5.5.2.5 1|1|1)
return found_it;
}
@ -245,6 +276,21 @@ private:
const_iterator src_it, src_end, target_it, target_end;
};
template <typename Container, typename IdType = decltype(get_id(*Container{}.begin()))>
IdType find_id_gap(const Container& c)
{
auto prev_it = c.begin();
if (prev_it != c.end() and get_id(*prev_it) == 1) {
auto it = prev_it;
for (++it; it != c.end(); prev_it = it, ++it) {
if (get_id(*it) > get_id(*prev_it) + 1) {
break;
}
}
}
return (prev_it == c.end()) ? 1 : get_id(*prev_it) + 1; // starts at 1.
}
} // namespace rrc_details
/*************************************************************************************************
@ -290,7 +336,7 @@ 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 = get_new_obj_id();
new_obj.meas_obj_id = rrc_details::find_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; // FIXME: What value to add here?
@ -310,37 +356,81 @@ var_meas_cfg_t::add_cell_cfg(const meas_cell_cfg_t& cellcfg)
ret.second = &ret.first->meas_obj.meas_obj_eutra().cells_to_add_mod_list.back();
}
if (inserted_flag) {
var_meas.meas_obj_list_present = true;
}
return {inserted_flag, ret.first, ret.second};
}
//! Find first gap in meas_obj_id and return it
uint32_t var_meas_cfg_t::get_new_obj_id()
report_cfg_to_add_mod_s* var_meas_cfg_t::add_report_cfg(const report_cfg_eutra_s& reportcfg)
{
meas_obj_t* prev_it = var_meas.meas_obj_list.begin();
if (prev_it != var_meas.meas_obj_list.end() and prev_it->meas_obj_id == 1) {
meas_obj_t* it = prev_it;
for (++it; it != var_meas.meas_obj_list.end(); prev_it = it, ++it) {
if (it->meas_obj_id > prev_it->meas_obj_id + 1) {
break;
}
}
rrc_details::field_id_cmp<report_cfg_to_add_mod_s> cmp{};
report_cfg_to_add_mod_s new_rep;
new_rep.report_cfg_id = rrc_details::find_id_gap(var_meas.report_cfg_list);
new_rep.report_cfg.set_report_cfg_eutra() = reportcfg;
var_meas.report_cfg_list_present = true;
var_meas.report_cfg_list.push_back(new_rep);
std::sort(var_meas.report_cfg_list.begin(), var_meas.report_cfg_list.end(), cmp);
return std::lower_bound(var_meas.report_cfg_list.begin(), var_meas.report_cfg_list.end(), new_rep.report_cfg_id, cmp);
}
meas_id_to_add_mod_s* var_meas_cfg_t::add_measid_cfg(uint8_t measobjid, uint8_t measrepid)
{
// ensure MeasObjId and ReportCfgId already exist
auto objit = std::lower_bound(
var_meas.meas_obj_list.begin(), var_meas.meas_obj_list.end(), measobjid, rrc_details::meas_obj_id_cmp{});
if (objit == var_meas.meas_obj_list.end() or objit->meas_obj_id != measobjid) {
ERROR("Failed to add MeasId because MeasObjId=%d is not found.\n", measobjid);
return nullptr;
}
auto repit = std::lower_bound(var_meas.report_cfg_list.begin(),
var_meas.report_cfg_list.end(),
measrepid,
rrc_details::field_id_cmp<report_cfg_to_add_mod_s>{});
if (repit == var_meas.report_cfg_list.end() or repit->report_cfg_id != measrepid) {
ERROR("Failed to add MeasId because ReportCfgId=%d is not found.\n", measrepid);
return nullptr;
}
return (prev_it == var_meas.meas_obj_list.end()) ? 1 : prev_it->meas_obj_id + 1; // starts at 1.
rrc_details::field_id_cmp<meas_id_to_add_mod_s> cmp{};
meas_id_to_add_mod_s new_measid;
new_measid.report_cfg_id = measrepid;
new_measid.meas_obj_id = measobjid;
new_measid.meas_id = rrc_details::find_id_gap(var_meas.meas_id_list);
var_meas.meas_id_list_present = true;
var_meas.meas_id_list.push_back(new_measid);
std::sort(var_meas.meas_id_list.begin(), var_meas.meas_id_list.end(), cmp);
return std::lower_bound(var_meas.meas_id_list.begin(), var_meas.meas_id_list.end(), new_measid.meas_id, cmp);
}
void var_meas_cfg_t::compute_diff_meas_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const
bool var_meas_cfg_t::compute_diff_meas_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const
{
*meas_cfg = {};
// TODO: Create a flag to disable changing the "this" members (useful for transparent container)
// Set a MeasConfig in the RRC Connection Reconfiguration for HO.
compute_diff_meas_objs(target_cfg, meas_cfg);
// deltaconfig_meas_reports(target_cfg, meas_cfg);
// deltaconfig_meas_ids(target_cfg, meas_cfg);
compute_diff_report_cfgs(target_cfg, meas_cfg);
compute_diff_meas_ids(target_cfg, meas_cfg);
// deltaconfig_meas_quantity_config(target_cfg, meas_cfg);
meas_cfg->meas_gap_cfg_present = false; // NOTE: we do not support inter-freq. HO
meas_cfg->s_measure_present = false; // NOTE: We do not support SCells
meas_cfg->pre_regist_info_hrpd_present = false; // NOTE: not supported
meas_cfg->speed_state_pars_present = false; // NOTE: not supported
bool diff = meas_cfg->meas_obj_to_add_mod_list_present;
diff |= meas_cfg->meas_obj_to_rem_list_present;
diff |= meas_cfg->report_cfg_to_add_mod_list_present;
diff |= meas_cfg->report_cfg_to_rem_list_present;
diff |= meas_cfg->meas_id_to_add_mod_list_present;
diff |= meas_cfg->meas_id_to_rem_list_present;
diff |= meas_cfg->quant_cfg_present;
diff |= meas_cfg->meas_gap_cfg_present;
diff |= meas_cfg->s_measure_present;
diff |= meas_cfg->pre_regist_info_hrpd_present;
diff |= meas_cfg->speed_state_pars_present;
return diff;
}
//! adds all the cells that got updated to MeasCfg.
@ -350,37 +440,48 @@ void var_meas_cfg_t::compute_diff_cells(const meas_obj_eutra_s& target_it,
{
rrc_details::compute_diff_generator<cells_to_add_mod_list_l> diffs{src_it.cells_to_add_mod_list,
target_it.cells_to_add_mod_list};
meas_obj_eutra_s* eutra_obj = &added_obj->meas_obj.meas_obj_eutra();
meas_obj_eutra_s* eutra_obj = &added_obj->meas_obj.meas_obj_eutra();
while (true) {
auto result = diffs.next();
switch (result.outcome) {
case rrc_details::diff_outcome_t::complete:
return;
case rrc_details::diff_outcome_t::id_removed:
// case "entry with matching cellIndex exists in cellsToRemoveList
Info("UE can now cease to measure activity of cell %s.\n", rrc_details::to_string(*result.target_it).c_str());
eutra_obj->cells_to_rem_list_present = true;
eutra_obj->cells_to_rem_list.push_back(result.src_it->cell_idx);
break;
case rrc_details::diff_outcome_t::id_added:
// case "entry with matching cellIndex doesn't exist in cellsToAddModList"
Info("UE has now to measure activity of %s.\n", rrc_details::to_string(*result.target_it).c_str());
rrc_details::meascfg_add_cell(*eutra_obj, *result.target_it);
eutra_obj->cells_to_add_mod_list_present = true;
eutra_obj->cells_to_add_mod_list.push_back(*result.target_it);
break;
case rrc_details::diff_outcome_t::same_id:
// check if cells are the same. if not, update.
if (not(*result.src_it == *result.target_it)) {
// case "entry with matching cellIndex exists in cellsToAddModList"
Info("UE has now to measure activity of %s with updated params.\n",
rrc_details::to_string(*result.target_it).c_str());
rrc_details::meascfg_add_cell(*eutra_obj, *result.target_it);
eutra_obj->cells_to_add_mod_list_present = true;
eutra_obj->cells_to_add_mod_list.push_back(*result.target_it);
}
break;
}
}
}
//! compute diff between target_cfg and var_meas -> depending on diff, add/remove/update meas_obj in meas_cfg
/**
* Section 5.5.2.4/5, Measurement Object removal and addition/modification
* Description: compute diff between target_cfg and var_meas -> depending on diff, add/remove/update meas_obj in
* meas_cfg
*/
void var_meas_cfg_t::compute_diff_meas_objs(const var_meas_cfg_t& target_cfg, meas_cfg_s* meas_cfg) const
{
if (not target_cfg.var_meas.meas_obj_list_present) {
return;
}
// TODO: black cells and white cells
rrc_details::compute_diff_generator<meas_obj_to_add_mod_list_l> diffs{var_meas.meas_obj_list,
target_cfg.var_meas.meas_obj_list};
@ -391,22 +492,26 @@ void var_meas_cfg_t::compute_diff_meas_objs(const var_meas_cfg_t& target_cfg, me
case rrc_details::diff_outcome_t::complete:
return;
case rrc_details::diff_outcome_t::id_removed:
// case "entry with matching cellIndex exists in cellsToRemoveList
Info("UE can cease to measure activity in frequency earfcn=%d.\n",
result.src_it->meas_obj.meas_obj_eutra().carrier_freq);
meas_cfg->meas_obj_to_rem_list_present = true;
meas_cfg->meas_obj_to_rem_list.push_back(result.src_it->meas_obj_id);
break;
case rrc_details::diff_outcome_t::id_added: {
// case "entry with matching measObjectId doesn't exist in measObjToAddModList"
Info("HO: UE has now to measure activity of new frequency earfcn=%d.\n",
result.target_it->meas_obj.meas_obj_eutra().carrier_freq);
auto& target_eutra = result.target_it->meas_obj.meas_obj_eutra();
auto& added_eutra = rrc_details::meascfg_add_meas_obj(meas_cfg, *result.target_it)->meas_obj.meas_obj_eutra();
// add all cells in measCfg
for (const cells_to_add_mod_s& cell_it : target_eutra.cells_to_add_mod_list) {
rrc_details::meascfg_add_cell(added_eutra, cell_it);
added_eutra.cells_to_add_mod_list_present = true;
added_eutra.cells_to_add_mod_list.push_back(cell_it);
}
} break;
case rrc_details::diff_outcome_t::same_id:
// case "entry with matching measObjectId exists in measObjToAddModList"
bool are_equal = *result.src_it == *result.target_it;
if (not are_equal) {
// if we found a difference in obj IDs
@ -420,6 +525,71 @@ void var_meas_cfg_t::compute_diff_meas_objs(const var_meas_cfg_t& target_cfg, me
}
}
/**
* Section 5.5.2.6/7 - Reporting configuration removal and addition/modification
*/
void var_meas_cfg_t::compute_diff_report_cfgs(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const
{
if (not target_cfg.var_meas.report_cfg_list_present) {
return;
}
rrc_details::compute_diff_generator<report_cfg_to_add_mod_list_l> diffs{var_meas.report_cfg_list,
target_cfg.var_meas.report_cfg_list};
while (true) {
auto result = diffs.next();
switch (result.outcome) {
case rrc_details::diff_outcome_t::complete:
return;
case rrc_details::diff_outcome_t::id_removed:
meas_cfg->report_cfg_to_rem_list_present = true;
meas_cfg->report_cfg_to_rem_list.push_back(result.src_it->report_cfg_id);
break;
case rrc_details::diff_outcome_t::id_added:
meas_cfg->report_cfg_to_add_mod_list_present = true;
meas_cfg->report_cfg_to_add_mod_list.push_back(*result.target_it);
break;
case rrc_details::diff_outcome_t::same_id:
if (not(*result.src_it == *result.target_it)) {
meas_cfg->report_cfg_to_add_mod_list_present = true;
meas_cfg->report_cfg_to_add_mod_list.push_back(*result.target_it);
}
break;
}
}
}
void var_meas_cfg_t::compute_diff_meas_ids(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const
{
if (not target_cfg.var_meas.meas_id_list_present) {
return;
}
rrc_details::compute_diff_generator<meas_id_to_add_mod_list_l> diffs{var_meas.meas_id_list,
target_cfg.var_meas.meas_id_list};
while (true) {
auto result = diffs.next();
switch (result.outcome) {
case rrc_details::diff_outcome_t::complete:
return;
case rrc_details::diff_outcome_t::id_removed:
meas_cfg->meas_id_to_rem_list_present = true;
meas_cfg->meas_id_to_rem_list.push_back(result.src_it->meas_id);
break;
case rrc_details::diff_outcome_t::id_added:
meas_cfg->meas_id_to_add_mod_list_present = true;
meas_cfg->meas_id_to_add_mod_list.push_back(*result.target_it);
break;
case rrc_details::diff_outcome_t::same_id:
if (not(*result.src_it == *result.target_it)) {
meas_cfg->meas_id_to_add_mod_list_present = true;
meas_cfg->meas_id_to_add_mod_list.push_back(*result.target_it);
}
break;
}
}
}
/*************************************************************************************************
* mobility_cfg class
************************************************************************************************/
@ -428,11 +598,22 @@ rrc::mobility_cfg::mobility_cfg(rrc* outer_rrc) : rrc_enb(outer_rrc)
{
var_meas_cfg_t var_meas{outer_rrc->rrc_log};
// inserts all neighbor cells
if (rrc_enb->cfg.meas_cfg_present) {
// inserts all neighbor cells
for (meas_cell_cfg_t& meascell : rrc_enb->cfg.meas_cfg.meas_cells) {
var_meas.add_cell_cfg(meascell);
}
// insert all report cfgs
for (const report_cfg_eutra_s& reportcfg : rrc_enb->cfg.meas_cfg.meas_reports) {
var_meas.add_report_cfg(reportcfg);
}
// insert all meas ids
// FIXME: add this to the parser
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);
}
}
current_meas_cfg = std::make_shared<var_meas_cfg_t>(var_meas);
@ -452,6 +633,7 @@ rrc::ue::rrc_mobility::rrc_mobility(rrc::ue* outer_ue) :
ue_var_meas = std::make_shared<var_meas_cfg_t>(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)
{
// only reconfigure meas_cfg if no handover is occurring
@ -465,22 +647,11 @@ bool rrc::ue::rrc_mobility::fill_conn_recfg_msg(asn1::rrc::rrc_conn_recfg_r8_ies
}
asn1::rrc::meas_cfg_s* meas_cfg = &conn_recfg->meas_cfg;
ue_var_meas->compute_diff_meas_cfg(*cfg->current_meas_cfg, meas_cfg);
bool updated = ue_var_meas->compute_diff_meas_cfg(*cfg->current_meas_cfg, meas_cfg);
// update ue var meas
ue_var_meas = cfg->current_meas_cfg;
// if there is at least one difference, we tag a new measurement report in conn_reconf.
bool diff = meas_cfg->meas_obj_to_add_mod_list_present;
diff |= meas_cfg->meas_obj_to_rem_list_present;
diff |= meas_cfg->report_cfg_to_add_mod_list_present;
diff |= meas_cfg->report_cfg_to_rem_list_present;
diff |= meas_cfg->meas_id_to_add_mod_list_present;
diff |= meas_cfg->meas_id_to_rem_list_present;
diff |= meas_cfg->quant_cfg_present;
diff |= meas_cfg->meas_gap_cfg_present;
diff |= meas_cfg->s_measure_present;
diff |= meas_cfg->pre_regist_info_hrpd_present;
diff |= meas_cfg->speed_state_pars_present;
if (diff) {
if (updated) {
conn_recfg->meas_cfg_present = true;
return true;
}

@ -46,6 +46,22 @@ meas_cell_cfg_t generate_cell1()
return cell1;
}
report_cfg_eutra_s generate_rep1()
{
report_cfg_eutra_s rep{};
rep.report_amount.value = report_cfg_eutra_s::report_amount_opts::r16;
rep.report_interv.value = report_interv_opts::ms240;
rep.max_report_cells = 2;
rep.report_quant.value = report_cfg_eutra_s::report_quant_opts::both;
rep.trigger_quant.value = report_cfg_eutra_s::trigger_quant_opts::rsrp;
rep.trigger_type.set_event().event_id.set_event_a3();
rep.trigger_type.event().time_to_trigger.value = time_to_trigger_opts::ms100;
rep.trigger_type.event().hysteresis = 0;
rep.trigger_type.event().event_id.event_a3().a3_offset = 5;
rep.trigger_type.event().event_id.event_a3().report_on_leave = true;
return rep;
}
bool is_cell_cfg_equal(const meas_cell_cfg_t& cfg, const cells_to_add_mod_s& cell)
{
return cfg.pci == cell.pci and cell.cell_individual_offset.to_number() == (int8_t)round(cfg.q_offset) and
@ -63,7 +79,9 @@ int test_correct_insertion()
cell4 = cell1;
cell4.q_offset = 1;
// TEST 1: cell insertion in empty varMeasCfg
report_cfg_eutra_s rep1 = generate_rep1();
// TEST 1: cell/rep insertion in empty varMeasCfg
{
var_meas_cfg_t var_cfg(&log_h);
auto ret = var_cfg.add_cell_cfg(cell1);
@ -76,6 +94,10 @@ int test_correct_insertion()
TESTASSERT(eutra.carrier_freq == cell1.earfcn);
TESTASSERT(eutra.cells_to_add_mod_list.size() == 1);
TESTASSERT(is_cell_cfg_equal(cell1, eutra.cells_to_add_mod_list[0]));
auto ret2 = var_cfg.add_report_cfg(rep1);
TESTASSERT(ret2->report_cfg_id == 1);
TESTASSERT(ret2->report_cfg.report_cfg_eutra() == rep1);
}
{
@ -129,12 +151,22 @@ int test_correct_meascfg_calculation()
cell2.pci = 2;
cell2.cell_id = 0x19C02;
report_cfg_eutra_s rep1 = generate_rep1(), rep2{}, rep3{};
rep2 = rep1;
rep2.trigger_quant.value = report_cfg_eutra_s::trigger_quant_opts::rsrq;
rep3 = rep2;
rep3.report_quant.value = report_cfg_eutra_s::report_quant_opts::same_as_trigger_quant;
{
meas_cfg_s result_meascfg;
// TEST: Insertion of two cells in var_meas propagates to the resulting meas_cfg_s cellsToAddMod list
target_var.add_cell_cfg(cell1);
target_var.add_cell_cfg(cell2);
target_var.add_report_cfg(rep1);
target_var.add_report_cfg(rep2);
target_var.add_measid_cfg(1, 1);
target_var.add_measid_cfg(1, 2);
src_var.compute_diff_meas_cfg(target_var, &result_meascfg);
TESTASSERT(result_meascfg.meas_obj_to_add_mod_list_present);
TESTASSERT(not result_meascfg.meas_obj_to_rem_list_present);
@ -149,12 +181,26 @@ int test_correct_meascfg_calculation()
TESTASSERT(is_cell_cfg_equal(cell1, *cell_item));
cell_item++;
TESTASSERT(is_cell_cfg_equal(cell2, *cell_item));
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list_present and not result_meascfg.report_cfg_to_rem_list_present);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list.size() == 2);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list[0].report_cfg_id == 1);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list[0].report_cfg.report_cfg_eutra() == rep1);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list[1].report_cfg_id == 2);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list[1].report_cfg.report_cfg_eutra() == rep2);
TESTASSERT(result_meascfg.meas_id_to_add_mod_list_present and not result_meascfg.meas_id_to_rem_list_present);
TESTASSERT(result_meascfg.meas_id_to_add_mod_list.size() == 2);
auto* measid_item = &result_meascfg.meas_id_to_add_mod_list[0];
TESTASSERT(measid_item->meas_id == 1 and measid_item->meas_obj_id == 1 and measid_item->report_cfg_id == 1);
measid_item++;
TESTASSERT(measid_item->meas_id == 2 and measid_item->meas_obj_id == 1 and measid_item->report_cfg_id == 2);
// TEST: if measCfg is empty if nothing was updated
src_var = target_var;
src_var.compute_diff_meas_cfg(target_var, &result_meascfg);
TESTASSERT(not result_meascfg.meas_obj_to_add_mod_list_present);
TESTASSERT(result_meascfg.meas_obj_to_add_mod_list.size() == 0);
TESTASSERT(not result_meascfg.report_cfg_to_rem_list_present);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list.size() == 0);
// TEST: Cell is added to cellsToAddModList if just a field was updated
cell1.pci = 3;
@ -172,10 +218,12 @@ int test_correct_meascfg_calculation()
cell_item = &eutra.cells_to_add_mod_list[0];
TESTASSERT(is_cell_cfg_equal(cell1, *cell_item));
// TEST: Removal of cell from target propagates to the resulting meas_cfg_s cellsToRemoveList
// TEST: Removal of cell/rep from target propagates to the resulting meas_cfg_s
src_var = target_var;
target_var = var_meas_cfg_t{&log_h};
target_var.add_cell_cfg(cell2);
target_var.add_report_cfg(rep1);
target_var.add_report_cfg(rep3);
src_var.compute_diff_meas_cfg(target_var, &result_meascfg);
TESTASSERT(result_meascfg.meas_obj_to_add_mod_list_present);
TESTASSERT(result_meascfg.meas_obj_to_add_mod_list.size() == 1);
@ -186,6 +234,10 @@ int test_correct_meascfg_calculation()
TESTASSERT(not eutra.cells_to_add_mod_list_present and eutra.cells_to_rem_list_present);
TESTASSERT(eutra.cells_to_rem_list.size() == 1);
TESTASSERT(eutra.cells_to_rem_list[0] == (cell1.cell_id & 0xFFu));
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list_present and not result_meascfg.report_cfg_to_rem_list_present);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list.size() == 1);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list[0].report_cfg_id == 2);
TESTASSERT(result_meascfg.report_cfg_to_add_mod_list[0].report_cfg.report_cfg_eutra() == rep3);
}
return SRSLTE_SUCCESS;

Loading…
Cancel
Save