Added procedure for NR reconfiguration and RRC with NR complete

master
David Rupprecht 4 years ago committed by David Rupprecht
parent 145528ad32
commit 64299960bd

@ -26,6 +26,7 @@
#include "pdcp_interface_types.h"
#include "rlc_interface_types.h"
#include "rrc_interface_types.h"
#include "srslte/asn1/asn1_utils.h"
#include "srslte/asn1/liblte_mme.h"
#include "srslte/common/common.h"
#include "srslte/common/interfaces_common.h"
@ -155,6 +156,7 @@ class rrc_eutra_interface_rrc_nr
{
public:
virtual void new_cell_meas_nr(const std::vector<phy_meas_nr_t>& meas) = 0;
virtual void nr_rrc_con_reconfig_complete(bool status) = 0;
};
// RRC interface for PHY
@ -264,9 +266,18 @@ public:
class rrc_nr_interface_rrc
{
public:
virtual void get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps) = 0;
virtual void get_nr_capabilities(srslte::byte_buffer_t* nr_cap) = 0;
virtual void phy_set_cells_to_meas(uint32_t carrier_freq_r15) = 0;
virtual void get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps) = 0;
virtual void get_nr_capabilities(srslte::byte_buffer_t* nr_cap) = 0;
virtual void phy_set_cells_to_meas(uint32_t carrier_freq_r15) = 0;
virtual void phy_meas_stop() = 0;
virtual bool rrc_reconfiguration(bool endc_release_and_add_r15,
bool nr_secondary_cell_group_cfg_r15_present,
asn1::dyn_octstring nr_secondary_cell_group_cfg_r15,
bool sk_counter_r15_present,
uint32_t sk_counter_r15,
bool nr_radio_bearer_cfg1_r15_present,
asn1::dyn_octstring nr_radio_bearer_cfg1_r15) = 0;
virtual bool is_config_pending() = 0;
};
// PDCP interface for RLC

@ -118,6 +118,7 @@ public:
// NR interface
#ifdef HAVE_5GNR
void new_cell_meas_nr(const std::vector<phy_meas_nr_t>& meas);
void nr_rrc_con_reconfig_complete(bool status);
#endif
// PHY interface
@ -358,7 +359,7 @@ private:
void send_con_setup_complete(srslte::unique_byte_buffer_t nas_msg);
void send_ul_info_transfer(srslte::unique_byte_buffer_t nas_msg);
void send_security_mode_complete();
void send_rrc_con_reconfig_complete();
void send_rrc_con_reconfig_complete(bool contains_nr_complete = false);
// Parsers
void process_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu);
@ -416,6 +417,10 @@ private:
void set_mac_default();
void set_rrc_default();
#ifdef HAVE_5GNR
bool nr_reconfiguration_proc(const asn1::rrc::rrc_conn_recfg_r8_ies_s& rx_recfg);
#endif
// Helpers for nr communicaiton
asn1::rrc::ue_cap_rat_container_s get_eutra_nr_capabilities();
asn1::rrc::ue_cap_rat_container_s get_nr_capabilities();

@ -74,7 +74,12 @@ public:
const srslte::byte_buffer_t* pdu,
const T& msg,
const std::string& msg_type);
template <class T>
void log_rrc_message(const std::string& source,
direction_t dir,
asn1::dyn_octstring oct,
const T& msg,
const std::string& msg_type);
// PHY interface
void in_sync() final;
void out_of_sync() final;
@ -95,8 +100,16 @@ public:
// RRC (LTE) interface
void get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps);
void get_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps);
void phy_meas_stop();
void phy_set_cells_to_meas(uint32_t carrier_freq_r15);
bool rrc_reconfiguration(bool endc_release_and_add_r15,
bool nr_secondary_cell_group_cfg_r15_present,
asn1::dyn_octstring nr_secondary_cell_group_cfg_r15,
bool sk_counter_r15_present,
uint32_t sk_counter_r15,
bool nr_radio_bearer_cfg1_r15_present,
asn1::dyn_octstring nr_radio_bearer_cfg1_r15);
bool is_config_pending();
// STACK interface
void cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell);
@ -140,6 +153,32 @@ private:
srslte::timer_handler* timers = nullptr;
std::string get_rb_name(uint32_t lcid) final { return srslte::to_string((srslte::rb_id_nr_t)lcid); }
class connection_reconf_no_ho_proc
{
public:
explicit connection_reconf_no_ho_proc(rrc_nr* parent_);
srslte::proc_outcome_t init(const bool endc_release_and_add_r15,
const asn1::rrc_nr::rrc_recfg_s& rrc_recfg,
const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg,
const uint32_t sk_counter_r15,
const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg);
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
static const char* name() { return "NR Connection Reconfiguration"; }
srslte::proc_outcome_t react(const bool& config_complete);
void then(const srslte::proc_state_t& result);
private:
// const
rrc_nr* rrc_ptr;
asn1::rrc_nr::rrc_recfg_s rrc_recfg;
asn1::rrc_nr::cell_group_cfg_s cell_group_cfg;
};
srslte::proc_t<connection_reconf_no_ho_proc> conn_recfg_proc;
srslte::proc_manager_list_t callback_list;
};
} // namespace srsue

@ -206,6 +206,7 @@ private:
// const
rrc* rrc_ptr;
// args
bool has_5g_nr_reconfig = false;
asn1::rrc::rrc_conn_recfg_r8_ies_s rx_recfg;
};

@ -421,6 +421,13 @@ void rrc::process_new_cell_meas_nr(const std::vector<phy_meas_nr_t>& meas)
bool neighbour_added = meas_cells_nr.process_new_cell_meas(meas_lte, filter);
}
void rrc::nr_rrc_con_reconfig_complete(bool status)
{
if (conn_recfg_proc.is_busy()) {
conn_recfg_proc.trigger(status);
}
}
#endif
/* This function is called from a PHY worker thus must return very quickly.
@ -752,6 +759,62 @@ void rrc::timer_expired(uint32_t timeout_id)
}
}
#ifdef HAVE_5GNR
bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg)
{
if (!(rx_recfg.non_crit_ext_present && rx_recfg.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present &&
rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext
.non_crit_ext_present)) {
return true;
}
const asn1::rrc::rrc_conn_recfg_v1510_ies_s* rrc_conn_recfg_v1510_ies =
&rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext;
if (!rrc_conn_recfg_v1510_ies->nr_cfg_r15_present) {
return true;
}
bool endc_release_and_add_r15 = false;
bool nr_secondary_cell_group_cfg_r15_present = false;
asn1::dyn_octstring nr_secondary_cell_group_cfg_r15;
bool sk_counter_r15_present = false;
uint32_t sk_counter_r15 = 0;
bool nr_radio_bearer_cfg1_r15_present = false;
asn1::dyn_octstring nr_radio_bearer_cfg1_r15;
endc_release_and_add_r15 = rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().endc_release_and_add_r15;
if (rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15_present == true) {
nr_secondary_cell_group_cfg_r15_present = true;
nr_secondary_cell_group_cfg_r15 = rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15;
}
if (rrc_conn_recfg_v1510_ies->sk_counter_r15_present) {
sk_counter_r15_present = true;
sk_counter_r15 = rrc_conn_recfg_v1510_ies->sk_counter_r15;
}
if (rrc_conn_recfg_v1510_ies->nr_radio_bearer_cfg1_r15_present) {
nr_radio_bearer_cfg1_r15_present = true;
nr_radio_bearer_cfg1_r15 = rrc_conn_recfg_v1510_ies->nr_radio_bearer_cfg1_r15;
}
return rrc_nr->rrc_reconfiguration(endc_release_and_add_r15,
nr_secondary_cell_group_cfg_r15_present,
nr_secondary_cell_group_cfg_r15,
sk_counter_r15_present,
sk_counter_r15,
nr_radio_bearer_cfg1_r15_present,
nr_radio_bearer_cfg1_r15);
}
#endif
/*******************************************************************************
*
*
@ -934,14 +997,31 @@ void rrc::send_security_mode_complete()
send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg);
}
void rrc::send_rrc_con_reconfig_complete()
void rrc::send_rrc_con_reconfig_complete(bool contains_nr_complete)
{
rrc_log->debug("Preparing RRC Connection Reconfig Complete\n");
ul_dcch_msg_s ul_dcch_msg;
ul_dcch_msg.msg.set_c1().set_rrc_conn_recfg_complete().crit_exts.set_rrc_conn_recfg_complete_r8();
ul_dcch_msg.msg.c1().rrc_conn_recfg_complete().rrc_transaction_id = transaction_id;
rrc_conn_recfg_complete_r8_ies_s* rrc_conn_recfg_complete_r8 =
&ul_dcch_msg.msg.set_c1().set_rrc_conn_recfg_complete().crit_exts.set_rrc_conn_recfg_complete_r8();
if (contains_nr_complete == true) {
rrc_log->debug("Preparing RRC Connection Reconfig Complete with NR Complete\n");
rrc_conn_recfg_complete_r8->non_crit_ext_present = true;
rrc_conn_recfg_complete_r8->non_crit_ext.non_crit_ext_present = true;
rrc_conn_recfg_complete_r8->non_crit_ext.non_crit_ext.non_crit_ext_present = true;
rrc_conn_recfg_complete_r8->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true;
rrc_conn_recfg_complete_r8->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true;
rrc_conn_recfg_complete_v1430_ies_s* rrc_conn_recfg_complete_v1430_ies =
&rrc_conn_recfg_complete_r8->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext;
rrc_conn_recfg_complete_v1430_ies->non_crit_ext_present = true;
rrc_conn_recfg_complete_v1430_ies->non_crit_ext.scg_cfg_resp_nr_r15_present = true;
rrc_conn_recfg_complete_v1430_ies->non_crit_ext.scg_cfg_resp_nr_r15.from_string("00");
}
send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg);
}

@ -73,6 +73,9 @@ void rrc::rrc_meas::update_phy()
{
std::list<meas_obj_to_add_mod_s> objects = meas_cfg.get_active_objects();
rrc_ptr->phy->meas_stop();
#ifdef HAVE_5GNR
rrc_ptr->rrc_nr->phy_meas_stop();
#endif
for (const auto& obj : objects) {
switch (obj.meas_obj.type().value) {
case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_eutra: {

@ -12,13 +12,19 @@
#include "srsue/hdr/stack/rrc/rrc_nr.h"
using namespace asn1::rrc_nr;
#define Error(fmt, ...) rrc_ptr->log_h->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define Warning(fmt, ...) rrc_ptr->log_h->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define Info(fmt, ...) rrc_ptr->log_h->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define Debug(fmt, ...) rrc_ptr->log_h->debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
using namespace asn1::rrc_nr;
using namespace asn1;
using namespace srslte;
namespace srsue {
const char* rrc_nr::rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"};
rrc_nr::rrc_nr(srslte::task_sched_handle task_sched_) : log_h("RRC"), task_sched(task_sched_) {}
rrc_nr::rrc_nr(srslte::task_sched_handle task_sched_) : log_h("RRC"), task_sched(task_sched_), conn_recfg_proc(this) {}
rrc_nr::~rrc_nr() = default;
@ -117,6 +123,29 @@ void rrc_nr::log_rrc_message(const std::string& source,
}
}
template <class T>
void rrc_nr::log_rrc_message(const std::string& source,
direction_t dir,
dyn_octstring oct,
const T& msg,
const std::string& msg_type)
{
if (log_h->get_level() == srslte::LOG_LEVEL_INFO) {
log_h->info("%s - %s %s (%d B)\n", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size());
} else if (log_h->get_level() >= srslte::LOG_LEVEL_DEBUG) {
asn1::json_writer json_writer;
msg.to_json(json_writer);
log_h->debug_hex(oct.data(),
oct.size(),
"%s - %s %s (%d B)\n",
source.c_str(),
(dir == Rx) ? "Rx" : "Tx",
msg_type.c_str(),
oct.size());
log_h->debug_long("Content:\n%s\n", json_writer.to_string().c_str());
}
}
// PHY interface
void rrc_nr::in_sync() {}
void rrc_nr::out_of_sync() {}
@ -250,6 +279,79 @@ void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps_pdu)
return;
}
bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15,
bool nr_secondary_cell_group_cfg_r15_present,
asn1::dyn_octstring nr_secondary_cell_group_cfg_r15,
bool sk_counter_r15_present,
uint32_t sk_counter_r15,
bool nr_radio_bearer_cfg1_r15_present,
asn1::dyn_octstring nr_radio_bearer_cfg1_r15)
{
// sanity check only for now
if (nr_secondary_cell_group_cfg_r15_present == false || sk_counter_r15_present == false ||
nr_radio_bearer_cfg1_r15_present == false) {
log_h->error("RRC NR Reconfiguration failed sanity check failed\n");
return false;
}
rrc_recfg_s rrc_recfg;
cell_group_cfg_s cell_group_cfg;
radio_bearer_cfg_s radio_bearer_cfg;
asn1::SRSASN_CODE err;
cbit_ref bref(nr_secondary_cell_group_cfg_r15.data(), nr_secondary_cell_group_cfg_r15.size());
err = rrc_recfg.unpack(bref);
if (err != asn1::SRSASN_SUCCESS) {
log_h->error("Could not unpack NR reconfiguration message.\n");
return false;
}
log_rrc_message(
"RRC NR Reconfiguration", Rx, nr_secondary_cell_group_cfg_r15, rrc_recfg, "NR Secondary Cell Group Cfg R15");
if (rrc_recfg.crit_exts.type() == asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg) {
if (rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group_present == true) {
cbit_ref bref0(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.data(),
rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.size());
err = cell_group_cfg.unpack(bref0);
if (err != asn1::SRSASN_SUCCESS) {
log_h->error("Could not unpack cell group message message.\n");
return false;
}
log_rrc_message("RRC NR Reconfiguration",
Rx,
rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group,
cell_group_cfg,
"Secondary Cell Group Config");
} else {
log_h->error("Reconfiguration does not contain Secondary Cell Group Config\n");
return false;
}
}
cbit_ref bref1(nr_radio_bearer_cfg1_r15.data(), nr_radio_bearer_cfg1_r15.size());
err = radio_bearer_cfg.unpack(bref1);
if (err != asn1::SRSASN_SUCCESS) {
log_h->error("Could not unpack radio bearer config.\n");
return false;
}
log_rrc_message("RRC NR Reconfiguration", Rx, nr_radio_bearer_cfg1_r15, radio_bearer_cfg, "Radio Bearer Config R15");
if (not conn_recfg_proc.launch(
endc_release_and_add_r15, rrc_recfg, cell_group_cfg, sk_counter_r15, radio_bearer_cfg)) {
log_h->error("Unable to launch NR RRC configuration procedure\n");
return false;
} else {
callback_list.add_proc(conn_recfg_proc);
}
return true;
}
void rrc_nr::get_nr_capabilities(srslte::byte_buffer_t* nr_caps_pdu)
{
@ -291,6 +393,14 @@ void rrc_nr::get_nr_capabilities(srslte::byte_buffer_t* nr_caps_pdu)
return;
};
void rrc_nr::phy_meas_stop()
{
// possbile race condition for fake_measurement timer, which might be set at the same moment as stopped => fix with
// phy integration
log_h->debug("[NR] Stopping fake measurements\n");
fake_measurement_timer.stop();
}
void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15)
{
log_h->debug("[NR] Measuring phy cell %d \n", carrier_freq_r15);
@ -300,6 +410,14 @@ void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15)
fake_measurement_timer.run();
}
bool rrc_nr::is_config_pending()
{
if (conn_recfg_proc.is_busy()) {
return true;
}
return false;
}
// RLC interface
void rrc_nr::max_retx_attempted() {}
@ -307,4 +425,42 @@ void rrc_nr::max_retx_attempted() {}
void rrc_nr::cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell)
{}
/* Procedures */
rrc_nr::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(rrc_nr* parent_) : rrc_ptr(parent_) {}
proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool endc_release_and_add_r15,
const asn1::rrc_nr::rrc_recfg_s& rrc_recfg,
const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg,
const uint32_t sk_counter_r15,
const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg)
{
Info("Starting...\n");
return proc_outcome_t::success;
}
proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::react(const bool& config_complete)
{
if (not config_complete) {
Error("Failed to config PHY\n");
return proc_outcome_t::error;
}
rrc_ptr->rrc_eutra->nr_rrc_con_reconfig_complete(true);
Info("Reconfig NR return successful\n");
return proc_outcome_t::success;
}
void rrc_nr::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result)
{
if (result.is_success()) {
Info("Finished %s successfully\n", name());
return;
}
// Section 5.3.5.5 - Reconfiguration failure
// rrc_ptr->con_reconfig_failed();
}
} // namespace srsue

@ -972,9 +972,9 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc::
return proc_outcome_t::error;
}
}
// Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside apply_scell_config()
// Note that apply_scell_config() calls set_scell() and set_config() which run in the background.
// Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside
// apply_scell_config() Note that apply_scell_config() calls set_scell() and set_config() which run in the
// background.
rrc_ptr->apply_scell_config(&rx_recfg, true);
if (!rrc_ptr->measurements->parse_meas_config(
@ -982,6 +982,16 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc::
return proc_outcome_t::error;
}
// Apply NR config
#ifdef HAVE_5GNR
bool rtn = rrc_ptr->nr_reconfiguration_proc(rx_recfg);
if (rtn == false) {
rrc_ptr->rrc_log->error("Can not launch NR RRC Reconfiguration procedure\n");
return proc_outcome_t::error;
}
has_5g_nr_reconfig = true;
#endif
// No phy config was scheduled, run config completion immediately
if (rrc_ptr->phy_ctrl->is_config_pending()) {
return react(true);
@ -1001,7 +1011,18 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& conf
return proc_outcome_t::yield;
}
rrc_ptr->send_rrc_con_reconfig_complete();
#ifdef HAVE_5GNR
// in case there is rrc_nr to configure, wait for rrc nr configuration
if (has_5g_nr_reconfig == true && rrc_ptr->rrc_nr->is_config_pending()) {
return proc_outcome_t::yield;
}
#endif
if (has_5g_nr_reconfig == true) {
rrc_ptr->send_rrc_con_reconfig_complete(true);
} else {
rrc_ptr->send_rrc_con_reconfig_complete();
}
srslte::unique_byte_buffer_t nas_pdu;
for (auto& pdu : rx_recfg.ded_info_nas_list) {
@ -1021,12 +1042,16 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& conf
void rrc::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result)
{
// Reset 5G NR reconfig variable
has_5g_nr_reconfig = false;
if (result.is_success()) {
rrc_ptr->rrc_log->info("Finished %s successfully\n", name());
return;
}
// Section 5.3.5.5 - Reconfiguration failure
// TODO: if RRC NR configuration this also need to be signaled via LTE
rrc_ptr->con_reconfig_failed();
}

@ -169,6 +169,18 @@ public:
void get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps) override{};
void get_nr_capabilities(srslte::byte_buffer_t* nr_cap) override{};
void phy_set_cells_to_meas(uint32_t carrier_freq_r15) override{};
void phy_meas_stop() override{};
bool rrc_reconfiguration(bool endc_release_and_add_r15,
bool nr_secondary_cell_group_cfg_r15_present,
asn1::dyn_octstring nr_secondary_cell_group_cfg_r15,
bool sk_counter_r15_present,
uint32_t sk_counter_r15,
bool nr_radio_bearer_cfg1_r15_present,
asn1::dyn_octstring nr_radio_bearer_cfg1_r15) override
{
return false;
};
bool is_config_pending() override { return false; };
};
class nas_test : public srsue::nas

Loading…
Cancel
Save