Introducing nr_rrc <-> rrc interface for eutra and nr cap query

master
David Rupprecht 4 years ago committed by Andre Puschmann
parent 020d0dacc8
commit b79eef0860

@ -260,6 +260,13 @@ public:
virtual void enable_encryption(uint32_t lcid,
srslte::srslte_direction_t direction = srslte::srslte_direction_t::DIRECTION_TXRX) = 0;
};
// RRC NR interface for RRC (LTE)
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;
};
// PDCP interface for RLC
class pdcp_interface_rlc

@ -79,7 +79,10 @@ public:
nas_interface_rrc* nas_,
usim_interface_rrc* usim_,
gw_interface_rrc* gw_,
const rrc_args_t& args_);
#ifdef HAVE_5GNR
rrc_nr_interface_rrc* rrc_nr_,
#endif
const rrc_args_t& args_);
void stop();
@ -179,7 +182,9 @@ private:
nas_interface_rrc* nas = nullptr;
usim_interface_rrc* usim = nullptr;
gw_interface_rrc* gw = nullptr;
#ifdef HAVE_5GNR
rrc_nr_interface_rrc* rrc_nr = nullptr;
#endif
srslte::unique_byte_buffer_t dedicated_info_nas;
void send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg);
@ -410,6 +415,10 @@ private:
void set_phy_default();
void set_mac_default();
void set_rrc_default();
// 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();
};
} // namespace srsue

@ -41,6 +41,7 @@ struct rrc_nr_metrics_t {};
class rrc_nr final : public rrc_interface_phy_nr,
public rrc_interface_pdcp,
public rrc_interface_rlc,
public rrc_nr_interface_rrc,
public srslte::timer_callback
{
public:
@ -85,6 +86,10 @@ public:
void write_pdu_pcch(srslte::unique_byte_buffer_t pdu) final;
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) final;
// 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);
// STACK interface
void cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell);

@ -19,6 +19,7 @@
#include "srsue/hdr/ue_metrics_interface.h"
#include "rrc/rrc.h"
#include "rrc/rrc_nr.h"
#include "upper/gw.h"
#include "upper/usim.h"

@ -167,6 +167,9 @@ private:
srslte::rlc rlc;
srslte::pdcp pdcp;
srsue::rrc rrc;
#ifdef HAVE_5GNR
srsue::rrc_nr rrc_nr;
#endif
srsue::nas nas;
std::unique_ptr<usim_base> usim;
};

@ -7,6 +7,11 @@
#
set(SOURCES rrc.cc rrc_procedures.cc rrc_meas.cc rrc_cell.cc phy_controller.cc)
if(ENABLE_5GNR)
set(SOURCES ${SOURCES} rrc_nr.cc)
endif()
add_library(srsue_rrc STATIC ${SOURCES})
if(ENABLE_5GNR)

@ -99,7 +99,10 @@ void rrc::init(phy_interface_rrc_lte* phy_,
nas_interface_rrc* nas_,
usim_interface_rrc* usim_,
gw_interface_rrc* gw_,
const rrc_args_t& args_)
#ifdef HAVE_5GNR
rrc_nr_interface_rrc* rrc_nr_,
#endif
const rrc_args_t& args_)
{
pool = byte_buffer_pool::get_instance();
phy = phy_;
@ -109,7 +112,9 @@ void rrc::init(phy_interface_rrc_lte* phy_,
nas = nas_;
usim = usim_;
gw = gw_;
#ifdef HAVE_5GNR
rrc_nr = rrc_nr_;
#endif
args = args_;
auto on_every_cell_selection = [this](uint32_t earfcn, uint32_t pci, bool csel_result) {
@ -154,7 +159,6 @@ void rrc::init(phy_interface_rrc_lte* phy_,
// initiate unique procedures
ue_required_sibs.assign(&required_sibs[0], &required_sibs[NOF_REQUIRED_SIBS]);
running = true;
initiated = true;
}
@ -1764,6 +1768,9 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry)
cap.feature_group_inds_present = true;
cap.feature_group_inds.from_number(args.feature_group);
ue_eutra_cap_v1280_ies_s* ue_eutra_cap_v1280_ies;
ue_eutra_cap_v1360_ies_s* ue_eutra_cap_v1360_ies;
ue_eutra_cap_v1450_ies_s* ue_eutra_cap_v1450_ies;
if (args.release > 8) {
ue_eutra_cap_v920_ies_s cap_v920;
@ -1919,6 +1926,64 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry)
.non_crit_ext.non_crit_ext_present = true;
cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext
.non_crit_ext.non_crit_ext = cap_v1250;
// 12.50
cap.non_crit_ext.non_crit_ext.non_crit_ext.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 = true;
// 12.60
cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.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 = true;
// 12.70
cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.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 = true;
}
// Release 13
if (args.release > 12) {
// 12.80
ue_eutra_cap_v1280_ies =
&cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext
.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext;
ue_eutra_cap_v1280_ies->non_crit_ext_present = true;
// 13.10
ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext_present = true;
// 13.20
ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true;
// 13.30
ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true;
// 13.40
ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true;
// 13.50
ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present =
true;
}
// Release 14
if (args.release > 13) {
// 13.60
ue_eutra_cap_v1360_ies =
&ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext;
ue_eutra_cap_v1360_ies->non_crit_ext_present = true;
// 14.30
ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext_present = true;
// 14.40
ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true;
// 14.50
ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true;
}
// Release 15
if (args.release > 14) {
ue_eutra_cap_v1450_ies = &ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext;
// 14.60
ue_eutra_cap_v1450_ies->non_crit_ext_present = true;
irat_params_nr_r15_s irat_params_nr_r15;
irat_params_nr_r15.en_dc_r15_present = true;
irat_params_nr_r15.supported_band_list_en_dc_r15_present = true;
supported_band_nr_r15_s supported_band_nr_r15;
supported_band_nr_r15.band_nr_r15 = 78;
irat_params_nr_r15.supported_band_list_en_dc_r15.push_back(supported_band_nr_r15);
ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15_present = true;
ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15 = irat_params_nr_r15;
}
// Pack caps and copy to cap info
@ -1930,12 +1995,49 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry)
info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.resize(cap_len);
memcpy(info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.data(), buf, cap_len);
rat_idx++;
}
#ifdef HAVE_5GNR
else if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request[i] == rat_type_e::eutra_nr && has_nr_dc()) {
info->ue_cap_rat_container_list[rat_idx] = get_eutra_nr_capabilities();
rrc_log->info("Including EUTRA-NR capabilities in UE Capability Info (%d B)\n",
info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.size());
rat_idx++;
} else if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request[i] == rat_type_e::nr && has_nr_dc()) {
info->ue_cap_rat_container_list[rat_idx] = get_nr_capabilities();
rrc_log->info("Including NR capabilities in UE Capability Info (%d B)\n",
info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.size());
rat_idx++;
}
#endif
else {
rrc_log->error("RAT Type of UE Cap request not supported or not configured\n");
}
}
// resize container back to the actually filled items
info->ue_cap_rat_container_list.resize(rat_idx);
#ifdef HAVE_5GNR
if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext_present) {
if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext.non_crit_ext_present) {
if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext.non_crit_ext.non_crit_ext_present) {
if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present) {
if (enquiry.crit_exts.c1()
.ue_cap_enquiry_r8()
.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present) {
if (enquiry.crit_exts.c1()
.ue_cap_enquiry_r8()
.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext
.requested_freq_bands_nr_mrdc_r15_present) {
rrc_log->debug("Requested Freq Bands NR MRDC R15 present\n");
}
}
}
}
}
}
#endif
send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg);
}
@ -2565,5 +2667,36 @@ void rrc::set_rrc_default()
const std::string rrc::rb_id_str[] =
{"SRB0", "SRB1", "SRB2", "DRB1", "DRB2", "DRB3", "DRB4", "DRB5", "DRB6", "DRB7", "DRB8"};
// Helpers for nr communicaiton
asn1::rrc::ue_cap_rat_container_s rrc::get_eutra_nr_capabilities()
{
srslte::byte_buffer_t caps_buf;
asn1::rrc::ue_cap_rat_container_s cap;
#ifdef HAVE_5GNR
rrc_nr->get_eutra_nr_capabilities(&caps_buf);
#else
rrc_log->error("Not able to access get_eutra_nr_capabilities function\n");
#endif
cap.rat_type = asn1::rrc::rat_type_e::eutra_nr;
cap.ue_cap_rat_container.resize(caps_buf.N_bytes);
memcpy(cap.ue_cap_rat_container.data(), caps_buf.msg, caps_buf.N_bytes);
return cap;
}
asn1::rrc::ue_cap_rat_container_s rrc::get_nr_capabilities()
{
srslte::byte_buffer_t caps_buf;
asn1::rrc::ue_cap_rat_container_s cap;
#ifdef HAVE_5GNR
rrc_nr->get_nr_capabilities(&caps_buf);
#else
rrc_log->error("Not able to access get_nr_capabilities function\n");
#endif
cap.rat_type = asn1::rrc::rat_type_e::nr;
cap.ue_cap_rat_container.resize(caps_buf.N_bytes);
memcpy(cap.ue_cap_rat_container.data(), caps_buf.msg, caps_buf.N_bytes);
return cap;
}
} // namespace srsue

@ -86,6 +86,33 @@ void rrc_nr::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) {}
void rrc_nr::write_pdu_pcch(srslte::unique_byte_buffer_t pdu) {}
void rrc_nr::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {}
void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps)
{
uint8_t eutra_nr_cap_raw[] = {0x01, 0x1c, 0x04, 0x81, 0x60, 0x00, 0x1c, 0x4d, 0x00, 0x00, 0x00, 0x04,
0x00, 0x40, 0x04, 0x04, 0xd0, 0x10, 0x74, 0x06, 0x14, 0xe8, 0x1b, 0x10,
0x78, 0x00, 0x00, 0x20, 0x00, 0x10, 0x08, 0x08, 0x01, 0x00, 0x20};
memcpy(eutra_nr_caps->msg, eutra_nr_cap_raw, sizeof(eutra_nr_cap_raw));
eutra_nr_caps->N_bytes = sizeof(eutra_nr_cap_raw);
log_h->debug_hex(
eutra_nr_caps->msg, eutra_nr_caps->N_bytes, "EUTRA-NR capabilities (%u B)\n", eutra_nr_caps->N_bytes);
return;
}
void rrc_nr::get_nr_capabilities(srslte::byte_buffer_t* nr_caps)
{
uint8_t nr_cap_raw[] = {
0xe1, 0x00, 0x00, 0x00, 0x01, 0x47, 0x7a, 0x03, 0x02, 0x00, 0x00, 0x01, 0x40, 0x48, 0x07, 0x06, 0x0e, 0x02, 0x0c,
0x00, 0x02, 0x13, 0x60, 0x10, 0x73, 0xe4, 0x20, 0xf0, 0x00, 0x80, 0xc1, 0x30, 0x08, 0x0c, 0x00, 0x00, 0x0a, 0x05,
0x89, 0xba, 0xc2, 0x19, 0x43, 0x40, 0x88, 0x10, 0x74, 0x18, 0x60, 0x4c, 0x04, 0x41, 0x6c, 0x90, 0x14, 0x06, 0x0c,
0x78, 0xc7, 0x3e, 0x42, 0x0f, 0x00, 0x58, 0x0c, 0x0e, 0x0e, 0x02, 0x21, 0x3c, 0x84, 0xfc, 0x4d, 0xe0, 0x00, 0x12,
0x00, 0x00, 0x00, 0x00, 0xe5, 0x4d, 0x00, 0x01, 0x00, 0x00, 0x04, 0x18, 0x60, 0x00, 0x34, 0xaa, 0x60};
memcpy(nr_caps->msg, nr_cap_raw, sizeof(nr_cap_raw));
nr_caps->N_bytes = sizeof(nr_cap_raw);
log_h->debug_hex(nr_caps->msg, nr_caps->N_bytes, "NR capabilities (%u B)\n", nr_caps->N_bytes);
return;
}
// RLC interface
void rrc_nr::max_retx_attempted() {}

@ -31,6 +31,9 @@ ue_stack_lte::ue_stack_lte() :
rlc("RLC"),
mac("MAC", &task_sched),
rrc(this, &task_sched),
#ifdef HAVE_5GNR
rrc_nr(),
#endif
pdcp(&task_sched, "PDCP"),
nas(&task_sched),
thread("STACK"),
@ -118,7 +121,11 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
rlc.init(&pdcp, &rrc, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */);
pdcp.init(&rlc, &rrc, gw);
nas.init(usim.get(), &rrc, gw, args.nas);
#ifdef HAVE_5GNR
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc);
#else
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, args.rrc);
#endif
running = true;
start(STACK_MAIN_THREAD_PRIO);

@ -233,7 +233,11 @@ public:
nastest = std::unique_ptr<nas_test>(new nas_test(&stack->task_sched));
pdcptest = std::unique_ptr<pdcp_test>(new pdcp_test(log_->get_service_name().c_str(), &stack->task_sched));
}
#ifdef HAVE_5GNR
void init() { rrc::init(&phytest, &mactest, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, nullptr, {}); }
#else
void init() { rrc::init(&phytest, &mactest, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, {}); }
#endif
void run_tti(uint32_t tti_)
{

Loading…
Cancel
Save