created generic methods to apply toaddmodlist and removelists.

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent c65c081b51
commit ca0db7fffe

@ -12,7 +12,7 @@ AllowAllParametersOfDeclarationOnNextLine: false # Changed
#AllowAllArgumentsOnNextLine: false # Changed
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline #Changed
AllowShortFunctionsOnASingleLine: All #Changed
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None

@ -143,7 +143,7 @@ template <class T>
class dyn_array
{
public:
typedef T item_type;
typedef T value_type;
using iterator = T*;
using const_iterator = const T*;
@ -209,6 +209,7 @@ public:
resize(size() + 1, size() * 2);
data_[size() - 1] = elem;
}
void clear() { resize(0); }
T& back() { return data_[size() - 1]; }
const T& back() const { return data_[size() - 1]; }
T* data() { return &data_[0]; }

@ -39,6 +39,7 @@ struct s_tmsi_s;
struct rlc_cfg_c;
struct pdcp_cfg_s;
struct srb_to_add_mod_s;
struct drb_to_add_mod_s;
// mac
struct sched_request_cfg_c;
struct mac_main_cfg_s;
@ -145,12 +146,22 @@ namespace rrc {
/***************************
* MeasConfig
**************************/
bool operator==(const asn1::rrc::cells_to_add_mod_s& lhs, const asn1::rrc::cells_to_add_mod_s& rhs);
bool operator==(const asn1::rrc::meas_obj_to_add_mod_s& lhs, const asn1::rrc::meas_obj_to_add_mod_s& rhs);
bool operator==(const asn1::rrc::report_cfg_eutra_s& lhs, const asn1::rrc::report_cfg_eutra_s& rhs);
bool operator==(const asn1::rrc::report_cfg_to_add_mod_s& lhs, const asn1::rrc::report_cfg_to_add_mod_s& rhs);
bool operator==(const asn1::rrc::meas_id_to_add_mod_s& lhs, const asn1::rrc::meas_id_to_add_mod_s& rhs);
bool operator==(const asn1::rrc::quant_cfg_s& lhs, const asn1::rrc::quant_cfg_s& rhs);
bool operator==(const cells_to_add_mod_s& lhs, const cells_to_add_mod_s& rhs);
bool operator==(const meas_obj_to_add_mod_s& lhs, const meas_obj_to_add_mod_s& rhs);
bool operator==(const report_cfg_eutra_s& lhs, const report_cfg_eutra_s& rhs);
bool operator==(const report_cfg_to_add_mod_s& lhs, const report_cfg_to_add_mod_s& rhs);
bool operator==(const meas_id_to_add_mod_s& lhs, const meas_id_to_add_mod_s& rhs);
bool operator==(const quant_cfg_s& lhs, const quant_cfg_s& rhs);
/**************************
* RRC Obj 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);
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);
} // namespace rrc
} // namespace asn1

@ -0,0 +1,56 @@
/*
* Copyright 2013-2020 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_BEARER_CFG_H
#define SRSLTE_BEARER_CFG_H
#include "rrc_cfg_utils.h"
#include "srslte/asn1/rrc_asn1.h"
namespace srslte {
//! Apply toAddModList/toRelease diffs to SRBs
void apply_srb_diff(asn1::rrc::srb_to_add_mod_list_l& src,
asn1::rrc::rr_cfg_ded_s& diff,
asn1::rrc::srb_to_add_mod_list_l& target)
{
if (diff.srb_to_add_mod_list_present) {
apply_addmodlist_diff(src, diff.srb_to_add_mod_list, target);
} else if (&target != &src) {
target = src;
}
}
//! Apply toAddModList/toRelease diffs to SRBs
void apply_drb_diff(asn1::rrc::drb_to_add_mod_list_l& src,
asn1::rrc::rr_cfg_ded_s& diff,
asn1::rrc::drb_to_add_mod_list_l& target)
{
if (diff.drb_to_add_mod_list_present) {
apply_addmodremlist_diff(src, diff.drb_to_add_mod_list, diff.drb_to_release_list, target);
} else if (&target != &src) {
target = src;
}
}
} // namespace srslte
#endif // SRSLTE_BEARER_CFG_H

@ -22,50 +22,138 @@
#ifndef SRSLTE_RRC_CFG_UTILS_H
#define SRSLTE_RRC_CFG_UTILS_H
#include "srslte/asn1/rrc_asn1.h"
#include "srslte/asn1/rrc_asn1_utils.h"
#include <algorithm>
namespace srslte {
//! convenience function overload to extract rrc fields Id
constexpr uint8_t get_id(const asn1::rrc::srb_to_add_mod_s& obj)
{
return obj.srb_id;
}
constexpr uint8_t get_id(const asn1::rrc::drb_to_add_mod_s& obj)
{
return obj.drb_id;
}
//! Functor to compare RRC config elements (e.g. SRB/measObj/Rep) based on ID
template <typename T>
struct field_id_cmp {
bool operator()(const T& lhs, const T& rhs) const { return get_id(lhs) < get_id(rhs); }
struct rrb_obj_id_cmp {
bool operator()(const T& lhs, const T& rhs) const
{
return asn1::rrc::get_rrc_obj_id(lhs) < asn1::rrc::get_rrc_obj_id(rhs);
}
template <typename IdType>
bool operator()(const T& lhs, IdType id) const
{
return get_id(lhs) < id;
return asn1::rrc::get_rrc_obj_id(lhs) < id;
}
template <typename IdType>
bool operator()(IdType id, const T& rhs) const
{
return id < get_id(rhs);
return id < asn1::rrc::get_rrc_obj_id(rhs);
}
};
using srb_id_cmp = field_id_cmp<asn1::rrc::srb_to_add_mod_s>;
using drb_id_cmp = field_id_cmp<asn1::rrc::drb_to_add_mod_s>;
template <typename Container>
using rrc_obj_id_list_cmp = rrb_obj_id_cmp<typename Container::value_type>;
template <typename Container, typename IdType>
typename Container::iterator find_rrc_obj_id(Container& c, IdType id)
{
return std::find_if(
c.begin(), c.end(), [id](const typename Container::value_type& e) { return asn1::rrc::get_rrc_obj_id(e) == id; });
}
template <typename Container, typename IdType>
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 asn1::rrc::get_rrc_obj_id(*e) == id;
});
}
template <typename Container, typename IdType>
typename Container::iterator add_rrc_obj_id(Container& c, IdType id)
{
auto it = find_rrc_obj_id(c, id);
if (it == c.end()) {
c.push_back({});
it = c.end() - 1;
asn1::rrc::set_rrc_obj_id(*it, id);
}
return it;
}
//! Search of rrc cfg element based on ID. Assumes sorted list.
template <typename Container, typename IdType>
typename Container::iterator binary_find(Container& c, IdType id)
{
auto it = std::lower_bound(c.begin(), c.end(), id, field_id_cmp<decltype(*c.begin())>{});
return (it == c.end() or get_id(*it) != id) ? c.end() : it;
auto it = std::lower_bound(c.begin(), c.end(), id, rrb_obj_id_cmp<decltype(*c.begin())>{});
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 binary_find(const Container& c, IdType id)
{
auto it = std::lower_bound(c.begin(), c.end(), id, field_id_cmp<decltype(*c.begin())>{});
return (it == c.end() or get_id(*it) != id) ? c.end() : it;
auto it = std::lower_bound(c.begin(), c.end(), id, rrb_obj_id_cmp<decltype(*c.begin())>{});
return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it;
}
/**
* Apply toAddModList/toRemoveList changes
* @param src_list original list of rrc fields
* @param add_diff_list added/modified elements
* @param rm_diff_list removed elements
* @param target_list resulting list. (Can be same as src_list)
*/
template <typename AddModList, typename RemoveList>
void apply_addmodremlist_diff(AddModList& src_list,
AddModList& add_diff_list,
RemoveList& rm_diff_list,
AddModList& target_list)
{
// Sort Lists by ID
auto id_cmp_op = rrc_obj_id_list_cmp<AddModList>{};
std::sort(src_list.begin(), src_list.end(), id_cmp_op);
std::sort(add_diff_list.begin(), add_diff_list.end(), id_cmp_op);
std::sort(rm_diff_list.begin(), rm_diff_list.end());
AddModList tmp_lst;
// apply remove list
std::set_difference(src_list.begin(),
src_list.end(),
rm_diff_list.begin(),
rm_diff_list.end(),
std::back_inserter(tmp_lst),
id_cmp_op);
// apply toaddmodlist
target_list.clear();
std::set_union(add_diff_list.begin(),
add_diff_list.end(),
tmp_lst.begin(),
tmp_lst.end(),
std::back_inserter(target_list),
id_cmp_op);
}
/**
* Apply toAddModList changes
* @param src_list original list of rrc fields
* @param add_diff_list added/modified elements
* @param target_list resulting list. (Can be same as src_list)
*/
template <typename AddModList>
void apply_addmodlist_diff(AddModList& src_list, AddModList& add_diff_list, AddModList& target_list)
{
// Sort Lists by ID
auto id_cmp_op = rrc_obj_id_list_cmp<AddModList>{};
std::sort(src_list.begin(), src_list.end(), id_cmp_op);
std::sort(add_diff_list.begin(), add_diff_list.end(), id_cmp_op);
if (&target_list != &src_list) {
target_list.resize(0);
std::set_union(add_diff_list.begin(),
add_diff_list.end(),
src_list.begin(),
src_list.end(),
std::back_inserter(target_list),
id_cmp_op);
} else {
AddModList l;
std::set_union(
add_diff_list.begin(), add_diff_list.end(), src_list.begin(), src_list.end(), std::back_inserter(l), id_cmp_op);
target_list = l;
}
}
//! Update RRC field toAddModList
@ -77,8 +165,8 @@ void apply_cfg_list_updates(List& src_list,
ModFunctor mod_func)
{
// Sort by ID
std::sort(src_list.begin(), src_list.end(), field_id_cmp<decltype(*src_list.begin())>{});
std::sort(target_list.begin(), target_list.end(), field_id_cmp<decltype(*target_list.begin())>{});
std::sort(src_list.begin(), src_list.end(), rrb_obj_id_cmp<decltype(*src_list.begin())>{});
std::sort(target_list.begin(), target_list.end(), rrb_obj_id_cmp<decltype(*target_list.begin())>{});
auto src_it = src_list.begin();
auto target_it = target_list.begin();
@ -86,9 +174,10 @@ void apply_cfg_list_updates(List& src_list,
bool src_left = src_it != src_list.end();
bool target_left = target_it != target_list.end();
while (src_left or target_left) {
if (not target_left or (src_left and get_id(*src_it) < get_id(*target_it))) {
if (not target_left or (src_left and asn1::rrc::get_rrc_obj_id(*src_it) < asn1::rrc::get_rrc_obj_id(*target_it))) {
rem_func(src_it++);
} else if (not src_left or (target_left and get_id(*src_it) > get_id(*target_it))) {
} else if (not src_left or
(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
add_func(target_it++);
} else {

@ -214,8 +214,8 @@ srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue
srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const asn1::rrc::pdcp_cfg_s& pdcp_cfg)
{
// TODO: complete config processing
pdcp_discard_timer_t discard_timer = pdcp_discard_timer_t::infinity;
// TODO: complete config processing
pdcp_discard_timer_t discard_timer = pdcp_discard_timer_t::infinity;
if (pdcp_cfg.discard_timer_present) {
switch (pdcp_cfg.discard_timer.to_number()) {
case 10:
@ -596,10 +596,7 @@ 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;
}
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)
{
@ -1084,5 +1081,15 @@ bool operator==(const asn1::rrc::quant_cfg_s& lhs, const asn1::rrc::quant_cfg_s&
lhs.quant_cfg_eutra.filt_coef_rsrq == rhs.quant_cfg_eutra.filt_coef_rsrq;
}
/**************************
* 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 drb_to_add_mod_s& srb) { return srb.drb_id; }
void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id) { srb.srb_id = id; }
void set_rrc_obj_id(drb_to_add_mod_s& srb, uint8_t id) { srb.drb_id = id; }
} // namespace rrc
} // namespace asn1

@ -26,7 +26,6 @@
#include "srslte/common/logmap.h"
#include "srslte/interfaces/enb_interfaces.h"
#include "srslte/interfaces/enb_rrc_interface_types.h"
#include <set>
namespace srsenb {
@ -58,9 +57,7 @@ public:
void fill_rrc_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg);
private:
bool fill_srb_to_add_mod_list(asn1::rrc::rr_cfg_ded_s* msg);
bool fill_drb_to_add_mod_list(asn1::rrc::rr_cfg_ded_s* msg);
void apply_bearer_updates(const asn1::rrc::rr_cfg_ded_s& msg);
void fill_and_apply_bearer_updates(asn1::rrc::rr_cfg_ded_s& msg);
void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg);
srslte::log_ref log_h{"RRC"};
@ -73,12 +70,15 @@ private:
std::map<uint8_t, srslte::unique_byte_buffer_t> erab_info_list;
std::map<uint8_t, erab_t> erabs;
asn1::rrc::srb_to_add_mod_list_l current_srbs;
asn1::rrc::drb_to_add_mod_list_l current_drbs;
// last cfg
asn1::rrc::srb_to_add_mod_list_l last_srbs;
asn1::rrc::drb_to_add_mod_list_l last_drbs;
// pending cfg updates
asn1::rrc::srb_to_add_mod_list_l srbs_to_add;
asn1::rrc::drb_to_add_mod_list_l drbs_to_add;
asn1::rrc::drb_to_release_list_l drbs_to_release;
};
} // namespace srsenb

@ -21,7 +21,7 @@
#include "srsenb/hdr/stack/rrc/rrc_ue.h"
#include "srslte/asn1/rrc_asn1_utils.h"
#include "srslte/rrc/rrc_cfg_utils.h"
#include "srslte/rrc/bearer_cfg.h"
namespace srsenb {
@ -48,16 +48,12 @@ void bearer_handler::setup_srb(uint8_t srb_id)
return;
}
auto it = srslte::binary_find(current_srbs, srb_id);
if (it == current_srbs.end()) {
current_srbs.push_back({});
it = current_srbs.end() - 1;
it->srb_id = srb_id;
}
it->lc_ch_cfg_present = true;
it->lc_ch_cfg.set(srb_to_add_mod_s::lc_ch_cfg_c_::types_opts::default_value);
it->rlc_cfg_present = true;
it->rlc_cfg.set(srb_to_add_mod_s::rlc_cfg_c_::types_opts::default_value);
// Set SRBtoAddMod
auto srb_it = srslte::add_rrc_obj_id(srbs_to_add, srb_id);
srb_it->lc_ch_cfg_present = true;
srb_it->lc_ch_cfg.set(srb_to_add_mod_s::lc_ch_cfg_c_::types_opts::default_value);
srb_it->rlc_cfg_present = true;
srb_it->rlc_cfg.set(srb_to_add_mod_s::rlc_cfg_c_::types_opts::default_value);
}
int bearer_handler::setup_erab(uint8_t erab_id,
@ -93,13 +89,8 @@ int bearer_handler::setup_erab(uint8_t
rnti);
}
// Configure DRB
auto drb_it = srslte::binary_find(current_drbs, drbid);
if (drb_it == current_drbs.end()) {
current_drbs.push_back({});
drb_it = current_drbs.end() - 1;
drb_it->drb_id = drbid;
}
// Set DRBtoAddMod
auto drb_it = srslte::add_rrc_obj_id(drbs_to_add, drbid);
drb_it->lc_ch_id_present = true;
drb_it->lc_ch_id = (uint8_t)lcid;
drb_it->eps_bearer_id_present = true;
@ -121,28 +112,33 @@ int bearer_handler::setup_erab(uint8_t
void bearer_handler::fill_rrc_setup(asn1::rrc::rrc_conn_setup_r8_ies_s* msg)
{
fill_srb_to_add_mod_list(&msg->rr_cfg_ded);
last_srbs = current_srbs;
// Config RLC/PDCP
apply_bearer_updates(msg->rr_cfg_ded);
fill_and_apply_bearer_updates(msg->rr_cfg_ded);
}
void bearer_handler::fill_rrc_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg)
{
msg->rr_cfg_ded_present = true;
fill_srb_to_add_mod_list(&msg->rr_cfg_ded);
fill_drb_to_add_mod_list(&msg->rr_cfg_ded);
fill_pending_nas_info(msg);
last_srbs = current_srbs;
last_drbs = current_drbs;
fill_and_apply_bearer_updates(msg->rr_cfg_ded);
// Config RLC/PDCP
apply_bearer_updates(msg->rr_cfg_ded);
fill_pending_nas_info(msg);
}
void bearer_handler::apply_bearer_updates(const asn1::rrc::rr_cfg_ded_s& msg)
void bearer_handler::fill_and_apply_bearer_updates(asn1::rrc::rr_cfg_ded_s& msg)
{
// Add altered bearers to message
msg.srb_to_add_mod_list_present = srbs_to_add.size() > 0;
msg.srb_to_add_mod_list = srbs_to_add;
msg.drb_to_add_mod_list_present = drbs_to_add.size() > 0;
msg.drb_to_add_mod_list = drbs_to_add;
msg.drb_to_release_list_present = drbs_to_release.size() > 0;
msg.drb_to_release_list = drbs_to_release;
// Apply changes in internal bearer_handler DRB/SRBtoAddModLists
srslte::apply_srb_diff(last_srbs, msg, last_srbs);
srslte::apply_drb_diff(last_drbs, msg, last_drbs);
// Apply SRB updates to PDCP and RLC
if (msg.srb_to_add_mod_list_present) {
for (const srb_to_add_mod_s& srb : msg.srb_to_add_mod_list) {
// Configure SRB1 in RLC
@ -152,53 +148,26 @@ void bearer_handler::apply_bearer_updates(const asn1::rrc::rr_cfg_ded_s& msg)
pdcp->add_bearer(rnti, srb.srb_id, srslte::make_srb_pdcp_config_t(srb.srb_id, false));
}
}
}
//! Update RadioConfigDedicated with the newly added/modified/removed SRBs
bool bearer_handler::fill_srb_to_add_mod_list(rr_cfg_ded_s* msg)
{
msg->srb_to_add_mod_list_present = false;
msg->srb_to_add_mod_list = {};
// Policies on Release/Add/Mod of each SRB
auto on_rem = [](const srb_to_add_mod_s* removed_srb) {
// Releasing SRBs not supported
};
auto on_add = [msg](const srb_to_add_mod_s* add_srb) {
msg->srb_to_add_mod_list_present = true;
msg->srb_to_add_mod_list.push_back(*add_srb);
};
auto on_update = [](const srb_to_add_mod_s* src_srb, const srb_to_add_mod_s* target_srb) {
// TODO: Check if there is an update
};
srslte::apply_cfg_list_updates(last_srbs, current_srbs, on_rem, on_add, on_update);
return msg->srb_to_add_mod_list_present;
}
// Apply DRB updates to PDCP and RLC
if (msg.drb_to_release_list_present) {
log_h->error("Removing DRBs not currently supported\n");
}
if (msg.drb_to_add_mod_list_present) {
for (const drb_to_add_mod_s& drb : msg.drb_to_add_mod_list) {
// Configure DRBs in RLC
rlc->add_bearer(rnti, drb.lc_ch_id, srslte::make_rlc_config_t(drb.rlc_cfg));
// Configure DRB1 in PDCP
srslte::pdcp_config_t pdcp_cnfg_drb = srslte::make_drb_pdcp_config_t(drb.drb_id, false, drb.pdcp_cfg);
pdcp->add_bearer(rnti, drb.lc_ch_id, pdcp_cnfg_drb);
}
}
//! Update RadioConfigDedicated with the newly added/modified/removed DRBs
bool bearer_handler::fill_drb_to_add_mod_list(rr_cfg_ded_s* msg)
{
msg->drb_to_add_mod_list_present = false;
msg->drb_to_release_list_present = false;
msg->drb_to_add_mod_list.resize(0);
msg->drb_to_release_list.resize(0);
// Policies on Release/Add/Mod of each DRB
auto on_release = [msg](const drb_to_add_mod_s* released_drb) {
msg->drb_to_release_list_present = true;
msg->drb_to_release_list.push_back(released_drb->drb_id);
};
auto on_add = [msg](const drb_to_add_mod_s* added_drb) {
msg->drb_to_add_mod_list_present = true;
msg->drb_to_add_mod_list.push_back(*added_drb);
};
auto on_update = [](const drb_to_add_mod_s* src_drb, const drb_to_add_mod_s* target_drb) {
// TODO: Check if there is an update
};
srslte::apply_cfg_list_updates(last_drbs, current_drbs, on_release, on_add, on_update);
return msg->drb_to_add_mod_list_present or msg->drb_to_release_list_present;
// Reset ToAdd state
srbs_to_add = {};
drbs_to_add = {};
drbs_to_release.resize(0);
}
void bearer_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg)

Loading…
Cancel
Save