using new rrc obj id util methods in handover code

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent f43985b6cd
commit e8aff22e1b

@ -158,10 +158,18 @@ bool operator==(const quant_cfg_s& lhs, const quant_cfg_s& rhs);
*************************/ *************************/
uint8_t get_rrc_obj_id(const srb_to_add_mod_s& srb); uint8_t get_rrc_obj_id(const srb_to_add_mod_s& srb);
uint8_t get_rrc_obj_id(const drb_to_add_mod_s& srb); uint8_t get_rrc_obj_id(const drb_to_add_mod_s& drb);
uint8_t get_rrc_obj_id(const cells_to_add_mod_s& obj);
uint8_t get_rrc_obj_id(const meas_obj_to_add_mod_s& obj);
uint8_t get_rrc_obj_id(const report_cfg_to_add_mod_s& obj);
uint8_t get_rrc_obj_id(const meas_id_to_add_mod_s& obj);
void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id); void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id);
void set_rrc_obj_id(drb_to_add_mod_s& srb, uint8_t id); void set_rrc_obj_id(drb_to_add_mod_s& drb, uint8_t id);
void set_rrc_obj_id(cells_to_add_mod_s& obj, uint8_t id);
void set_rrc_obj_id(meas_obj_to_add_mod_s& obj, uint8_t id);
void set_rrc_obj_id(report_cfg_to_add_mod_s& obj, uint8_t id);
void set_rrc_obj_id(meas_id_to_add_mod_s& obj, uint8_t id);
} // namespace rrc } // namespace rrc
} // namespace asn1 } // namespace asn1

@ -347,6 +347,7 @@ public:
virtual void rem_user(uint16_t rnti) = 0; virtual void rem_user(uint16_t rnti) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg) = 0; virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg) = 0;
virtual void add_bearer_mrb(uint16_t rnti, uint32_t lcid) = 0; virtual void add_bearer_mrb(uint16_t rnti, uint32_t lcid) = 0;
virtual void del_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0;
virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0;

@ -24,12 +24,13 @@
#include "srslte/asn1/rrc_asn1_utils.h" #include "srslte/asn1/rrc_asn1_utils.h"
#include <algorithm> #include <algorithm>
#include <cassert>
namespace srslte { namespace srslte {
//! Functor to compare RRC config elements (e.g. SRB/measObj/Rep) based on ID //! Functor to compare RRC config elements (e.g. SRB/measObj/Rep) based on ID
template <typename T> template <typename T>
struct rrb_obj_id_cmp { struct rrc_obj_id_cmp {
bool operator()(const T& lhs, const T& rhs) const bool operator()(const T& lhs, const T& rhs) const
{ {
return asn1::rrc::get_rrc_obj_id(lhs) < asn1::rrc::get_rrc_obj_id(rhs); return asn1::rrc::get_rrc_obj_id(lhs) < asn1::rrc::get_rrc_obj_id(rhs);
@ -46,7 +47,7 @@ struct rrb_obj_id_cmp {
} }
}; };
template <typename Container> template <typename Container>
using rrc_obj_id_list_cmp = rrb_obj_id_cmp<typename Container::value_type>; using rrc_obj_id_list_cmp = rrc_obj_id_cmp<typename Container::value_type>;
template <typename Container, typename IdType> template <typename Container, typename IdType>
typename Container::iterator find_rrc_obj_id(Container& c, IdType id) typename Container::iterator find_rrc_obj_id(Container& c, IdType id)
@ -57,35 +58,74 @@ typename Container::iterator find_rrc_obj_id(Container& c, IdType id)
template <typename Container, typename IdType> template <typename Container, typename IdType>
typename Container::const_iterator find_rrc_obj_id(const Container& c, IdType id) typename Container::const_iterator find_rrc_obj_id(const Container& c, IdType id)
{ {
return std::find_if(c.begin(), c.end(), [id](const typename Container::value_type& e) { return std::find_if(
return asn1::rrc::get_rrc_obj_id(*e) == id; c.begin(), c.end(), [id](const typename Container::value_type& e) { return asn1::rrc::get_rrc_obj_id(e) == id; });
}); }
//! Search of rrc cfg element based on ID. Assumes sorted list.
template <typename Container, typename IdType>
typename Container::iterator sorted_find_rrc_obj_id(Container& c, IdType id)
{
auto it = std::lower_bound(c.begin(), c.end(), id, rrc_obj_id_list_cmp<Container>{});
return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it;
}
template <typename Container, typename IdType>
typename Container::const_iterator sorted_find_rrc_obj_id(const Container& c, IdType id)
{
auto it = std::lower_bound(c.begin(), c.end(), id, rrc_obj_id_list_cmp<Container>{});
return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it;
} }
//! Add Id to List in a sorted manner
template <typename Container, typename IdType> template <typename Container, typename IdType>
typename Container::iterator add_rrc_obj_id(Container& c, IdType id) typename Container::iterator add_rrc_obj_id(Container& c, IdType id)
{ {
auto it = find_rrc_obj_id(c, id); auto it = sorted_find_rrc_obj_id(c, id);
if (it == c.end()) { if (it == c.end()) {
c.push_back({}); c.push_back({});
it = c.end() - 1; it = c.end() - 1;
asn1::rrc::set_rrc_obj_id(*it, id); asn1::rrc::set_rrc_obj_id(*it, id);
std::sort(c.begin(), c.end(), rrc_obj_id_list_cmp<Container>{});
it = sorted_find_rrc_obj_id(c, id);
} }
return it; return it;
} }
//! Search of rrc cfg element based on ID. Assumes sorted list. template <typename Container>
template <typename Container, typename IdType> typename Container::iterator add_rrc_obj(Container& c, const typename Container::value_type& v)
typename Container::iterator binary_find(Container& c, IdType id)
{ {
auto it = std::lower_bound(c.begin(), c.end(), id, rrb_obj_id_cmp<decltype(*c.begin())>{}); auto it = sorted_find_rrc_obj_id(c, asn1::rrc::get_rrc_obj_id(v));
return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it; if (it == c.end()) {
c.push_back(v);
std::sort(c.begin(), c.end(), rrc_obj_id_list_cmp<Container>{});
it = sorted_find_rrc_obj_id(c, asn1::rrc::get_rrc_obj_id(v));
} else {
*it = v;
}
return it;
} }
template <typename Container, typename IdType>
typename Container::const_iterator binary_find(const Container& c, IdType id) /**
* Find rrc obj id gap in list of rrc objs (e.g. {1, 2, 4} -> 3)
* Expects list to be sorted
* @return id value
*/
template <typename Container>
auto find_rrc_obj_id_gap(const Container& c) -> decltype(asn1::rrc::get_rrc_obj_id(c[0]))
{ {
auto it = std::lower_bound(c.begin(), c.end(), id, rrb_obj_id_cmp<decltype(*c.begin())>{}); auto id_cmp_op = rrc_obj_id_list_cmp<Container>{};
return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it; assert(std::is_sorted(c.begin(), c.end(), id_cmp_op));
auto prev_it = c.begin();
if (prev_it != c.end() and asn1::rrc::get_rrc_obj_id(*prev_it) == 1) {
auto it = prev_it;
for (++it; it != c.end(); prev_it = it, ++it) {
if (asn1::rrc::get_rrc_obj_id(*it) > asn1::rrc::get_rrc_obj_id(*prev_it) + 1) {
break;
}
}
}
return (prev_it == c.end()) ? 1 : asn1::rrc::get_rrc_obj_id(*prev_it) + 1; // starts at 1.
} }
/** /**
@ -95,7 +135,7 @@ typename Container::const_iterator binary_find(const Container& c, IdType id)
* @param target_list resulting list. (Can be same as src_list) * @param target_list resulting list. (Can be same as src_list)
*/ */
template <typename AddModList> template <typename AddModList>
void apply_addmodlist_diff(AddModList& src_list, AddModList& add_diff_list, AddModList& target_list) void apply_addmodlist_diff(const AddModList& src_list, const AddModList& add_diff_list, AddModList& target_list)
{ {
// Shortcut for empty case // Shortcut for empty case
if (add_diff_list.size() == 0) { if (add_diff_list.size() == 0) {
@ -104,10 +144,9 @@ void apply_addmodlist_diff(AddModList& src_list, AddModList& add_diff_list, AddM
} }
return; return;
} }
// Sort Lists by ID
auto id_cmp_op = rrc_obj_id_list_cmp<AddModList>{}; auto id_cmp_op = rrc_obj_id_list_cmp<AddModList>{};
std::sort(src_list.begin(), src_list.end(), id_cmp_op); assert(std::is_sorted(src_list.begin(), src_list.end(), id_cmp_op));
std::sort(add_diff_list.begin(), add_diff_list.end(), id_cmp_op); assert(std::is_sorted(add_diff_list.begin(), add_diff_list.end(), id_cmp_op));
AddModList l; AddModList l;
std::set_union( std::set_union(
@ -123,16 +162,21 @@ void apply_addmodlist_diff(AddModList& src_list, AddModList& add_diff_list, AddM
* @param target_list resulting list. (Can be same as src_list) * @param target_list resulting list. (Can be same as src_list)
*/ */
template <typename AddModList, typename RemoveList> template <typename AddModList, typename RemoveList>
void apply_addmodremlist_diff(AddModList& src_list, void apply_addmodremlist_diff(const AddModList& src_list,
AddModList& add_diff_list, const AddModList& add_diff_list,
RemoveList& rm_diff_list, RemoveList& rm_diff_list,
AddModList& target_list) AddModList& target_list)
{ {
// Sort Lists by ID if (add_diff_list.size() == 0 and rm_diff_list.size() == 0) {
if (&target_list != &src_list) {
target_list = src_list;
}
return;
}
auto id_cmp_op = rrc_obj_id_list_cmp<AddModList>{}; auto id_cmp_op = rrc_obj_id_list_cmp<AddModList>{};
std::sort(src_list.begin(), src_list.end(), id_cmp_op); assert(std::is_sorted(src_list.begin(), src_list.end(), id_cmp_op));
std::sort(add_diff_list.begin(), add_diff_list.end(), id_cmp_op); assert(std::is_sorted(add_diff_list.begin(), add_diff_list.end(), id_cmp_op));
std::sort(rm_diff_list.begin(), rm_diff_list.end()); assert(std::is_sorted(rm_diff_list.begin(), rm_diff_list.end()));
AddModList tmp_lst; AddModList tmp_lst;
// apply remove list // apply remove list
@ -155,15 +199,15 @@ void apply_addmodremlist_diff(AddModList& src_list,
//! Update RRC field toAddModList //! Update RRC field toAddModList
template <typename List, typename RemFunctor, typename AddFunctor, typename ModFunctor> template <typename List, typename RemFunctor, typename AddFunctor, typename ModFunctor>
void apply_cfg_list_updates(List& src_list, void compute_cfg_diff(const List& src_list,
List& target_list, const List& target_list,
RemFunctor rem_func, RemFunctor rem_func,
AddFunctor add_func, AddFunctor add_func,
ModFunctor mod_func) ModFunctor mod_func)
{ {
// Sort by ID auto id_cmp_op = rrc_obj_id_list_cmp<List>{};
std::sort(src_list.begin(), src_list.end(), rrb_obj_id_cmp<decltype(*src_list.begin())>{}); assert(std::is_sorted(src_list.begin(), src_list.end(), id_cmp_op));
std::sort(target_list.begin(), target_list.end(), rrb_obj_id_cmp<decltype(*target_list.begin())>{}); assert(std::is_sorted(target_list.begin(), target_list.end(), id_cmp_op));
auto src_it = src_list.begin(); auto src_it = src_list.begin();
auto target_it = target_list.begin(); auto target_it = target_list.begin();
@ -171,10 +215,9 @@ void apply_cfg_list_updates(List& src_list,
bool src_left = src_it != src_list.end(); bool src_left = src_it != src_list.end();
bool target_left = target_it != target_list.end(); bool target_left = target_it != target_list.end();
while (src_left or target_left) { while (src_left or target_left) {
if (not target_left or (src_left and asn1::rrc::get_rrc_obj_id(*src_it) < asn1::rrc::get_rrc_obj_id(*target_it))) { if (not target_left or (src_left and id_cmp_op(*src_it, *target_it))) {
rem_func(src_it++); rem_func(src_it++);
} else if (not src_left or } else if (not src_left or (target_left and id_cmp_op(*target_it, *src_it))) {
(target_left and asn1::rrc::get_rrc_obj_id(*src_it) > asn1::rrc::get_rrc_obj_id(*target_it))) {
// a new object has been added to target // a new object has been added to target
add_func(target_it++); add_func(target_it++);
} else { } else {
@ -185,6 +228,23 @@ void apply_cfg_list_updates(List& src_list,
} }
} }
template <typename toAddModList, typename RemoveList>
void compute_cfg_diff(const toAddModList& src_list,
const toAddModList& target_list,
toAddModList& add_diff_list,
RemoveList& rem_diff_list)
{
using it_t = typename toAddModList::const_iterator;
auto rem_func = [&rem_diff_list](it_t rem_it) { rem_diff_list.push_back(asn1::rrc::get_rrc_obj_id(*rem_it)); };
auto add_func = [&add_diff_list](it_t add_it) { add_diff_list.push_back(*add_it); };
auto mod_func = [&add_diff_list](it_t src_it, it_t target_it) {
if (not(*src_it == *target_it)) {
add_diff_list.push_back(*target_it);
}
};
compute_cfg_diff(src_list, target_list, rem_func, add_func, mod_func);
}
} // namespace srslte } // namespace srslte
#endif // SRSLTE_RRC_CFG_UTILS_H #endif // SRSLTE_RRC_CFG_UTILS_H

@ -596,7 +596,10 @@ void set_phy_cfg_t_common_pdsch(phy_cfg_t* cfg, const asn1::rrc::pdsch_cfg_commo
cfg->dl_cfg.pdsch.p_b = asn1_type.p_b; cfg->dl_cfg.pdsch.p_b = asn1_type.p_b;
} }
void set_phy_cfg_t_enable_64qam(phy_cfg_t* cfg, const bool enabled) { cfg->ul_cfg.pusch.enable_64qam = enabled; } void set_phy_cfg_t_enable_64qam(phy_cfg_t* cfg, const bool enabled)
{
cfg->ul_cfg.pusch.enable_64qam = enabled;
}
void set_phy_cfg_t_common_pusch(phy_cfg_t* cfg, const asn1::rrc::pusch_cfg_common_s& asn1_type) void set_phy_cfg_t_common_pusch(phy_cfg_t* cfg, const asn1::rrc::pusch_cfg_common_s& asn1_type)
{ {
@ -1085,11 +1088,55 @@ bool operator==(const asn1::rrc::quant_cfg_s& lhs, const asn1::rrc::quant_cfg_s&
* RRC Obj Id * RRC Obj Id
*************************/ *************************/
uint8_t get_rrc_obj_id(const srb_to_add_mod_s& srb) { return srb.srb_id; } uint8_t get_rrc_obj_id(const srb_to_add_mod_s& srb)
uint8_t get_rrc_obj_id(const drb_to_add_mod_s& srb) { return srb.drb_id; } {
return srb.srb_id;
}
uint8_t get_rrc_obj_id(const drb_to_add_mod_s& drb)
{
return drb.drb_id;
}
uint8_t get_rrc_obj_id(const cells_to_add_mod_s& obj)
{
return obj.cell_idx;
}
uint8_t get_rrc_obj_id(const meas_obj_to_add_mod_s& obj)
{
return obj.meas_obj_id;
}
uint8_t get_rrc_obj_id(const report_cfg_to_add_mod_s& obj)
{
return obj.report_cfg_id;
}
uint8_t get_rrc_obj_id(const meas_id_to_add_mod_s& obj)
{
return obj.meas_id;
}
void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id) { srb.srb_id = id; } void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id)
void set_rrc_obj_id(drb_to_add_mod_s& srb, uint8_t id) { srb.drb_id = id; } {
srb.srb_id = id;
}
void set_rrc_obj_id(drb_to_add_mod_s& drb, uint8_t id)
{
drb.drb_id = id;
}
void set_rrc_obj_id(cells_to_add_mod_s& obj, uint8_t id)
{
obj.cell_idx = id;
}
void set_rrc_obj_id(meas_obj_to_add_mod_s& obj, uint8_t id)
{
obj.meas_obj_id = id;
}
void set_rrc_obj_id(report_cfg_to_add_mod_s& obj, uint8_t id)
{
obj.report_cfg_id = id;
}
void set_rrc_obj_id(meas_id_to_add_mod_s& obj, uint8_t id)
{
obj.meas_id = id;
}
} // namespace rrc } // namespace rrc
} // namespace asn1 } // namespace asn1

@ -52,6 +52,7 @@ public:
void rem_user(uint16_t rnti); void rem_user(uint16_t rnti);
void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg); void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg);
void add_bearer_mrb(uint16_t rnti, uint32_t lcid); void add_bearer_mrb(uint16_t rnti, uint32_t lcid);
void del_bearer(uint16_t rnti, uint32_t lcid);
bool has_bearer(uint16_t rnti, uint32_t lcid); bool has_bearer(uint16_t rnti, uint32_t lcid);
bool suspend_bearer(uint16_t rnti, uint32_t lcid); bool suspend_bearer(uint16_t rnti, uint32_t lcid);
bool resume_bearer(uint16_t rnti, uint32_t lcid); bool resume_bearer(uint16_t rnti, uint32_t lcid);

@ -121,6 +121,15 @@ bool rlc::has_bearer(uint16_t rnti, uint32_t lcid)
return result; return result;
} }
void rlc::del_bearer(uint16_t rnti, uint32_t lcid)
{
pthread_rwlock_rdlock(&rwlock);
if (users.count(rnti)) {
users[rnti].rlc->del_bearer(lcid);
}
pthread_rwlock_unlock(&rwlock);
}
bool rlc::suspend_bearer(uint16_t rnti, uint32_t lcid) bool rlc::suspend_bearer(uint16_t rnti, uint32_t lcid)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);

@ -52,6 +52,7 @@ public:
void rem_user(uint16_t rnti) override {} void rem_user(uint16_t rnti) override {}
void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg) override {} void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg) override {}
void add_bearer_mrb(uint16_t rnti, uint32_t lcid) override {} void add_bearer_mrb(uint16_t rnti, uint32_t lcid) override {}
void del_bearer(uint16_t rnti, uint32_t lcid) override {}
void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override {} void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override {}
bool has_bearer(uint16_t rnti, uint32_t lcid) override { return false; } bool has_bearer(uint16_t rnti, uint32_t lcid) override { return false; }
bool suspend_bearer(uint16_t rnti, uint32_t lcid) override { return true; } bool suspend_bearer(uint16_t rnti, uint32_t lcid) override { return true; }

@ -187,15 +187,16 @@ int test_correct_meascfg_calculation()
measid_item++; measid_item++;
TESTASSERT(measid_item->meas_id == 2 and measid_item->meas_obj_id == 1 and measid_item->report_cfg_id == 2); 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 // TEST 2: measConfig is empty if nothing was updated
src_var = target_var; src_var = target_var;
src_var.compute_diff_meas_cfg(target_var, &result_meascfg); src_var.compute_diff_meas_cfg(target_var, &result_meascfg);
TESTASSERT(not result_meascfg.meas_obj_to_add_mod_list_present); TESTASSERT(not result_meascfg.meas_obj_to_add_mod_list_present and not result_meascfg.meas_obj_to_rem_list_present);
TESTASSERT(result_meascfg.meas_obj_to_add_mod_list.size() == 0); TESTASSERT(result_meascfg.meas_obj_to_add_mod_list.size() == 0);
TESTASSERT(not result_meascfg.report_cfg_to_rem_list_present); TESTASSERT(not 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() == 0); TESTASSERT(result_meascfg.report_cfg_to_add_mod_list.size() == 0);
// TEST: Cell is added to cellsToAddModList if just a field was updated // TEST 3: Cell is added to cellsToAddModList if just a field was updated
cell1.pci = 3; cell1.pci = 3;
src_var = target_var; src_var = target_var;
target_var.add_cell_cfg(cell1); target_var.add_cell_cfg(cell1);
@ -211,7 +212,7 @@ int test_correct_meascfg_calculation()
cell_item = &eutra.cells_to_add_mod_list[0]; cell_item = &eutra.cells_to_add_mod_list[0];
TESTASSERT(is_cell_cfg_equal(cell1, *cell_item)); TESTASSERT(is_cell_cfg_equal(cell1, *cell_item));
// TEST: Removal of cell/rep from target propagates to the resulting meas_cfg_s // TEST 4: Removal of cell/rep from target propagates to the resulting meas_cfg_s
src_var = target_var; src_var = target_var;
target_var = var_meas_cfg_t{}; target_var = var_meas_cfg_t{};
target_var.add_cell_cfg(cell2); target_var.add_cell_cfg(cell2);

@ -145,6 +145,8 @@ int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args)
args.general.eia_pref_list = "EIA2, EIA1, EIA0"; args.general.eia_pref_list = "EIA2, EIA1, EIA0";
args.general.eea_pref_list = "EEA0, EEA2, EEA1"; args.general.eea_pref_list = "EEA0, EEA2, EEA1";
args.general.rrc_inactivity_timer = 60000;
phy_cfg_t phy_cfg; phy_cfg_t phy_cfg;
return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &phy_cfg); return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &phy_cfg);

Loading…
Cancel
Save