ue,rrc_nr: add message handler/sender for SA until security mode command

master
Andre Puschmann 3 years ago
parent 9507dbc534
commit 09b8d3ba6b

@ -24,6 +24,7 @@
#include "srsran/common/stack_procedure.h"
#include "srsran/common/task_scheduler.h"
#include "srsran/interfaces/ue_interfaces.h"
#include "srsran/interfaces/ue_nas_interfaces.h"
#include "srsran/interfaces/ue_nr_interfaces.h"
#include "srsran/interfaces/ue_rrc_interfaces.h"
#include "srsue/hdr/stack/upper/gw.h"
@ -53,6 +54,7 @@ public:
rlc_interface_rrc* rlc_,
pdcp_interface_rrc* pdcp_,
gw_interface_rrc* gw_,
nas_5g_interface_rrc_nr* nas_,
rrc_eutra_interface_rrc_nr* rrc_eutra_,
usim_interface_rrc_nr* usim_,
srsran::timer_handler* timers_,
@ -138,11 +140,15 @@ private:
void send_ul_info_transfer(srsran::unique_byte_buffer_t nas_msg);
void send_ul_ccch_msg(const asn1::rrc_nr::ul_ccch_msg_s& msg);
void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc_nr::ul_dcch_msg_s& msg);
void send_security_mode_complete();
// helpers
void handle_sib1(const asn1::rrc_nr::sib1_s& sib1);
bool handle_rrc_setup(const asn1::rrc_nr::rrc_setup_s& setup);
void handle_rrc_reconfig(const asn1::rrc_nr::rrc_recfg_s& reconfig);
void handle_dl_info_transfer(const asn1::rrc_nr::dl_info_transfer_s& dl_info_transfer);
void handle_security_mode_command(const asn1::rrc_nr::security_mode_cmd_s& smc);
void generate_as_keys();
srsran::task_sched_handle task_sched;
struct cmd_msg_t {
@ -163,6 +169,7 @@ private:
rlc_interface_rrc* rlc = nullptr;
pdcp_interface_rrc* pdcp = nullptr;
gw_interface_rrc* gw = nullptr;
nas_5g_interface_rrc_nr* nas = nullptr;
rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr;
usim_interface_rrc_nr* usim = nullptr;
stack_interface_rrc* stack = nullptr;
@ -238,6 +245,8 @@ private:
bool apply_drb_release(const uint8_t drb);
bool apply_security_cfg(const asn1::rrc_nr::security_cfg_s& security_cfg);
// Security configuration
bool security_is_activated = false;
srsran::as_security_config_t sec_cfg;
typedef enum { mcg_srb1, en_dc_srb3, nr } reconf_initiator_t;

@ -44,6 +44,7 @@ int rrc_nr::init(phy_interface_rrc_nr* phy_,
rlc_interface_rrc* rlc_,
pdcp_interface_rrc* pdcp_,
gw_interface_rrc* gw_,
nas_5g_interface_rrc_nr* nas_,
rrc_eutra_interface_rrc_nr* rrc_eutra_,
usim_interface_rrc_nr* usim_,
srsran::timer_handler* timers_,
@ -54,6 +55,7 @@ int rrc_nr::init(phy_interface_rrc_nr* phy_,
rlc = rlc_;
pdcp = pdcp_;
gw = gw_;
nas = nas_;
mac = mac_;
rrc_eutra = rrc_eutra_;
usim = usim_;
@ -241,24 +243,23 @@ void rrc_nr::decode_dl_ccch(unique_byte_buffer_t pdu)
dl_ccch_msg_type_c::c1_c_* c1 = &dl_ccch_msg.msg.c1();
switch (dl_ccch_msg.msg.c1().type().value) {
// case dl_ccch_msg_type_c::c1_c_::types::rrc_reject: {
// // 5.3.3.8
// rrc_conn_reject_r8_ies_s* reject_r8 = &c1->rrc_reject().crit_exts.c1().rrc_conn_reject_r8();
// logger.info("Received ConnectionReject. Wait time: %d", reject_r8->wait_time);
// srsran::console("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time);
// t300.stop();
// if (reject_r8->wait_time) {
// nas->set_barring(srsran::barring_t::all);
// t302.set(reject_r8->wait_time * 1000, [this](uint32_t tid) { timer_expired(tid); });
// t302.run();
// } else {
// // Perform the actions upon expiry of T302 if wait time is zero
// nas->set_barring(srsran::barring_t::none);
// start_go_idle();
// }
// } break;
case dl_ccch_msg_type_c::c1_c_::types::rrc_reject: {
// 5.3.15
const auto& reject = c1->rrc_reject();
srsran::console("Received RRC Reject");
t300.stop();
if (reject.crit_exts.rrc_reject().wait_time_present) {
// nas->set_barring(srsran::barring_t::all);
t302.set(reject.crit_exts.rrc_reject().wait_time * 1000, [this](uint32_t tid) { timer_expired(tid); });
t302.run();
} else {
// Perform the actions upon expiry of T302 if wait time is zero
// nas->set_barring(srsran::barring_t::none);
// start_go_idle();
}
} break;
case dl_ccch_msg_type_c::c1_c_::types::rrc_setup: {
transaction_id = c1->rrc_setup().rrc_transaction_id;
rrc_setup_s rrc_setup_copy = c1->rrc_setup();
@ -287,13 +288,22 @@ void rrc_nr::decode_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu)
switch (dl_dcch_msg.msg.c1().type().value) {
// TODO: ADD missing cases
case dl_dcch_msg_type_c::c1_c_::types::rrc_recfg: {
transaction_id = c1->rrc_recfg().rrc_transaction_id;
rrc_recfg_s recfg = c1->rrc_recfg();
task_sched.defer_task([this, recfg]() { handle_rrc_reconfig(recfg); });
break;
}
case dl_dcch_msg_type_c::c1_c_::types::dl_info_transfer: {
dl_info_transfer_s dl_info_transfer = c1->dl_info_transfer();
task_sched.defer_task([this, dl_info_transfer]() { handle_dl_info_transfer(dl_info_transfer); });
break;
}
case dl_dcch_msg_type_c::c1_c_::types::security_mode_cmd: {
security_mode_cmd_s smc = c1->security_mode_cmd();
task_sched.defer_task([this, smc]() { handle_security_mode_command(smc); });
break;
}
default:
logger.error("The provided DL-CCCH message type is not recognized or supported");
logger.error("The provided DL-DCCH message type is not recognized or supported");
break;
}
}
@ -546,7 +556,35 @@ uint16_t rrc_nr::get_mnc()
// Senders
void rrc_nr::send_ul_info_transfer(unique_byte_buffer_t nas_msg)
{
logger.warning("%s not implemented yet.", __FUNCTION__);
logger.debug("Preparing UL Info Transfer");
ul_dcch_msg_s ul_dcch_msg;
ul_info_transfer_ies_s* ul_info_transfer =
&ul_dcch_msg.msg.set_c1().set_ul_info_transfer().crit_exts.set_ul_info_transfer();
// Try to resize target buffer first
ul_info_transfer->ded_nas_msg.resize(nas_msg->N_bytes);
// check we have enough space in target buffer
if (nas_msg->N_bytes > ul_info_transfer->ded_nas_msg.size()) {
logger.error("NAS message too big to send in UL Info transfer (%d > %d).",
nas_msg->N_bytes,
ul_info_transfer->ded_nas_msg.size());
return;
}
// copy message content
memcpy(ul_info_transfer->ded_nas_msg.data(), nas_msg->msg, nas_msg->N_bytes);
// send message
send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg);
}
void rrc_nr::send_security_mode_complete()
{
ul_dcch_msg_s ul_dcch_msg;
auto& smc = ul_dcch_msg.msg.set_c1().set_security_mode_complete().crit_exts.set_security_mode_complete();
send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg);
}
void rrc_nr::send_setup_request(srsran::nr_establishment_cause_t cause)
@ -1987,6 +2025,8 @@ bool rrc_nr::handle_rrc_setup(const rrc_setup_s& setup)
void rrc_nr::handle_rrc_reconfig(const rrc_recfg_s& reconfig)
{
transaction_id = reconfig.rrc_transaction_id;
if (not conn_recfg_proc.launch(nr, false, reconfig)) {
logger.error("Unable to launch connection reconfiguration procedure");
return;
@ -1994,6 +2034,68 @@ void rrc_nr::handle_rrc_reconfig(const rrc_recfg_s& reconfig)
callback_list.add_proc(conn_recfg_proc);
}
void rrc_nr::handle_dl_info_transfer(const dl_info_transfer_s& dl_info_transfer)
{
transaction_id = dl_info_transfer.rrc_transaction_id;
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
if (pdu == nullptr) {
logger.error("Couldn't allocate PDU in %s().", __FUNCTION__);
return;
}
if (pdu->get_tailroom() < dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.size()) {
logger.error("DL Info Transfer too big (%d > %d)",
dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.size(),
pdu->get_tailroom());
return;
}
pdu->N_bytes = dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.size();
memcpy(pdu->msg, dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.data(), pdu->N_bytes);
nas->write_pdu(std::move(pdu));
}
void rrc_nr::handle_security_mode_command(const asn1::rrc_nr::security_mode_cmd_s& smc)
{
transaction_id = smc.rrc_transaction_id;
const auto& sec_algo_cfg = smc.crit_exts.security_mode_cmd().security_cfg_smc.security_algorithm_cfg;
sec_cfg.cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM)sec_algo_cfg.ciphering_algorithm.value;
if (sec_algo_cfg.integrity_prot_algorithm_present) {
sec_cfg.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM)sec_algo_cfg.integrity_prot_algorithm.value;
} else {
logger.error("Missing Integrity Algorithm Config");
}
logger.info("Received Security Mode Command nea: %s, nia: %s",
ciphering_algorithm_id_nr_text[sec_cfg.cipher_algo],
integrity_algorithm_id_nr_text[sec_cfg.integ_algo]);
// Generate AS security keys
generate_as_keys();
security_is_activated = true;
// Configure PDCP for security
uint32_t lcid = srb_to_lcid(nr_srb::srb1);
pdcp->config_security(lcid, sec_cfg);
pdcp->enable_integrity(lcid, DIRECTION_TXRX);
send_security_mode_complete();
pdcp->enable_encryption(lcid, DIRECTION_TXRX);
}
// Security helper used by Security Mode Command and Mobility handling routines
void rrc_nr::generate_as_keys()
{
uint8_t k_asme[32] = {};
// FIXME: need to add
// nas->get_k_asme(k_asme, 32);
logger.debug(k_asme, 32, "UE K_asme");
// logger.debug("Generating K_enb with UL NAS COUNT: %d", nas->get_k_enb_count());
// usim->generate_as_keys(k_asme, nas->get_k_enb_count(), &sec_cfg);
logger.info(sec_cfg.k_rrc_enc.data(), 32, "RRC encryption key - k_rrc_enc");
logger.info(sec_cfg.k_rrc_int.data(), 32, "RRC integrity key - k_rrc_int");
logger.info(sec_cfg.k_up_enc.data(), 32, "UP encryption key - k_up_enc");
}
// RLC interface
void rrc_nr::max_retx_attempted() {}
void rrc_nr::protocol_failure() {}

@ -107,6 +107,11 @@ class dummy_eutra : public rrc_eutra_interface_rrc_nr
void nr_scg_failure_information(const srsran::scg_failure_cause_t cause){};
};
class dummy_nas : public nas_5g_interface_rrc_nr
{
int write_pdu(srsran::unique_byte_buffer_t pdu) { return SRSRAN_SUCCESS; };
};
class dummy_sim : public usim_interface_rrc_nr
{
bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) { return true; }
@ -128,7 +133,7 @@ int rrc_nr_cap_request_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
srsran::byte_buffer_t caps;
dummy_phy dummy_phy;
@ -136,6 +141,7 @@ int rrc_nr_cap_request_test()
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -149,6 +155,7 @@ int rrc_nr_cap_request_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
@ -167,13 +174,14 @@ int rrc_nsa_reconfig_tdd_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -183,6 +191,7 @@ int rrc_nsa_reconfig_tdd_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
@ -266,13 +275,14 @@ int rrc_nsa_reconfig_fdd_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -282,6 +292,7 @@ int rrc_nsa_reconfig_fdd_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
@ -365,7 +376,7 @@ int rrc_nr_setup_request_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
srsran::byte_buffer_t caps;
dummy_phy dummy_phy;
@ -373,6 +384,7 @@ int rrc_nr_setup_request_test()
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -385,6 +397,7 @@ int rrc_nr_setup_request_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
@ -406,13 +419,14 @@ int rrc_nr_sib1_decoding_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -422,6 +436,7 @@ int rrc_nr_sib1_decoding_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
@ -451,13 +466,14 @@ int rrc_nr_setup_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -467,6 +483,7 @@ int rrc_nr_setup_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
@ -502,13 +519,14 @@ int rrc_nr_reconfig_test()
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
srsue::rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_nas dummy_nas;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
@ -518,6 +536,7 @@ int rrc_nr_reconfig_test()
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_nas,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),

@ -215,8 +215,17 @@ int ue_stack_lte::init(const stack_args_t& args_)
mac_nr.init(mac_nr_args, phy_nr, &rlc_nr, &rrc_nr);
rlc_nr.init(&pdcp_nr, &rrc_nr, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */);
pdcp_nr.init(&rlc_nr, &rrc_nr, gw);
rrc_nr.init(
phy_nr, &mac_nr, &rlc_nr, &pdcp_nr, gw, &rrc, usim.get(), task_sched.get_timer_handler(), this, args.rrc_nr);
rrc_nr.init(phy_nr,
&mac_nr,
&rlc_nr,
&pdcp_nr,
gw,
&nas_5g,
&rrc,
usim.get(),
task_sched.get_timer_handler(),
this,
args.rrc_nr);
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc);
args.nas_5g.ia5g = "0,1,2,3";

@ -78,8 +78,17 @@ int ue_stack_nr::init(const stack_args_t& args_)
rrc_args.log_hex_limit = args.log.rrc_hex_limit;
rrc_args.coreless.drb_lcid = 4;
rrc_args.coreless.ip_addr = "192.168.1.3";
rrc->init(
phy, mac.get(), rlc.get(), pdcp.get(), gw, nullptr, nullptr, task_sched.get_timer_handler(), this, rrc_args);
rrc->init(phy,
mac.get(),
rlc.get(),
pdcp.get(),
gw,
nullptr,
nullptr,
nullptr,
task_sched.get_timer_handler(),
this,
rrc_args);
rrc->init_core_less();
running = true;
start(STACK_MAIN_THREAD_PRIO);

Loading…
Cancel
Save