mirror of https://github.com/pvnis/srsRAN_4G.git
Add 5G NAS infrastructure
parent
505225d845
commit
fb92118bb7
@ -0,0 +1,98 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSUE_NAS_5G_H
|
||||
#define SRSUE_NAS_5G_H
|
||||
|
||||
#include "nas_base.h"
|
||||
#include "srsran/common/buffer_pool.h"
|
||||
#include "srsran/common/common.h"
|
||||
#include "srsran/common/nas_pcap.h"
|
||||
#include "srsran/common/security.h"
|
||||
#include "srsran/common/stack_procedure.h"
|
||||
#include "srsran/common/task_scheduler.h"
|
||||
#include "srsran/interfaces/ue_gw_interfaces.h"
|
||||
#include "srsran/interfaces/ue_nas_interfaces.h"
|
||||
#include "srsran/interfaces/ue_rrc_interfaces.h"
|
||||
#include "srsran/interfaces/ue_usim_interfaces.h"
|
||||
#include "srsran/srslog/srslog.h"
|
||||
#include "srsue/hdr/stack/upper/nas_5gmm_state.h"
|
||||
#include "srsue/hdr/stack/upper/nas_config.h"
|
||||
|
||||
using srsran::byte_buffer_t;
|
||||
|
||||
namespace srsue {
|
||||
|
||||
class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_interface_procedures
|
||||
{
|
||||
public:
|
||||
explicit nas_5g(srsran::task_sched_handle task_sched_);
|
||||
virtual ~nas_5g();
|
||||
int init(usim_interface_nas* usim_, rrc_nr_interface_nas_5g* rrc_nr_, gw_interface_nas* gw_, const nas_args_t& cfg_);
|
||||
void stop();
|
||||
void run_tti();
|
||||
|
||||
// Stack+RRC interface
|
||||
bool is_registered();
|
||||
|
||||
// timer callback
|
||||
void timer_expired(uint32_t timeout_id);
|
||||
|
||||
// Stack interface
|
||||
int switch_on();
|
||||
int switch_off();
|
||||
int enable_data();
|
||||
int disable_data();
|
||||
int start_service_request();
|
||||
|
||||
private:
|
||||
rrc_nr_interface_nas_5g* rrc_nr = nullptr;
|
||||
usim_interface_nas* usim = nullptr;
|
||||
gw_interface_nas* gw = nullptr;
|
||||
|
||||
bool running = false;
|
||||
|
||||
nas_args_t cfg = {};
|
||||
mm5g_state_t state = {};
|
||||
|
||||
// Security
|
||||
bool ia5g_caps[8] = {};
|
||||
bool ea5g_caps[8] = {};
|
||||
|
||||
// timers
|
||||
srsran::task_sched_handle task_sched;
|
||||
srsran::timer_handler::unique_timer t3502; // started when registration failure and the attempt counter is equal to 5
|
||||
srsran::timer_handler::unique_timer t3510; // started when transmission of REGISTRATION REQUEST message. ON EXPIRY:
|
||||
// start T3511 or T3502 as specified in subclause 5.5.1.2.7
|
||||
srsran::timer_handler::unique_timer t3511; // started when registration failure due to lower layer failure
|
||||
srsran::timer_handler::unique_timer t3521; // started when detach request is sent
|
||||
srsran::timer_handler::unique_timer reregistration_timer; // started to trigger delayed re-attach
|
||||
|
||||
// Values according to TS 24.501 Sec 10.2
|
||||
const uint32_t t3502_duration_ms = 12 * 60 * 1000; // 12m
|
||||
const uint32_t t3510_duration_ms = 15 * 1000; // 15s
|
||||
const uint32_t t3511_duration_ms = 10 * 1000; // 10s
|
||||
const uint32_t t3521_duration_ms = 15 * 1000; // 15s
|
||||
const uint32_t reregistration_timer_duration_ms = 2 * 1000; // 2s (arbitrarily chosen to delay re-attach)
|
||||
|
||||
srsran::proc_manager_list_t callbacks;
|
||||
|
||||
// Procedures
|
||||
// Forward declartion
|
||||
class registration_procedure;
|
||||
|
||||
srsran::proc_t<registration_procedure> registration_proc;
|
||||
|
||||
int send_registration_request();
|
||||
};
|
||||
} // namespace srsue
|
||||
#endif
|
@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSUE_NAS_5G_PROCEDURES_H_
|
||||
#define SRSUE_NAS_5G_PROCEDURES_H_
|
||||
|
||||
#include "srsue/hdr/stack/upper/nas_5g.h"
|
||||
|
||||
namespace srsue {
|
||||
|
||||
/**
|
||||
* @brief 5G NAS registration procedure
|
||||
*
|
||||
* Specified in 24 501 V16.7.0
|
||||
* 5GMM specific procedures
|
||||
* 5.5.1 Registration procedure
|
||||
*/
|
||||
class nas_5g::registration_procedure
|
||||
{
|
||||
public:
|
||||
explicit registration_procedure(nas_5g_interface_procedures* parent_nas_);
|
||||
srsran::proc_outcome_t init();
|
||||
srsran::proc_outcome_t step();
|
||||
static const char* name() { return "Registration Procedure"; }
|
||||
|
||||
private:
|
||||
nas_5g_interface_procedures* parent_nas;
|
||||
};
|
||||
} // namespace srsue
|
||||
|
||||
#endif // SRSUE_NAS_5G_PROCEDURES_H_
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSUE_NR_NAS_MM5G_STATE_H
|
||||
#define SRSUE_NR_NAS_MM5G_STATE_H
|
||||
|
||||
#include "srsran/srslog/srslog.h"
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
namespace srsue {
|
||||
|
||||
// 5GMM states (3GPP 24.501 v16.07.0)
|
||||
class mm5g_state_t
|
||||
{
|
||||
public:
|
||||
enum class state_t {
|
||||
null = 0,
|
||||
deregistered,
|
||||
registered_initiated,
|
||||
registered,
|
||||
deregistered_initiated,
|
||||
service_request_initiated,
|
||||
};
|
||||
|
||||
// 5GMM-DEREGISTERED sub-states (3GPP 24.501 v16.07.0)
|
||||
enum class deregistered_substate_t {
|
||||
null = 0, // This should be used when not in mm5g-DEREGISTERED
|
||||
normal_service,
|
||||
limited_service,
|
||||
attempting_to_registration,
|
||||
plmn_search,
|
||||
no_supi,
|
||||
no_cell_available,
|
||||
e_call_inactive,
|
||||
initial_registration_needed,
|
||||
};
|
||||
|
||||
// 5GMM-DEREGISTERED sub-states (3GPP 24.501 v16.07.0)
|
||||
enum class registered_substate_t {
|
||||
null = 0, // This should be used when not in mm5g-REGISTERED
|
||||
normal_service,
|
||||
non_allowed_service,
|
||||
attempting_registration_update,
|
||||
limited_service,
|
||||
plmn_search,
|
||||
no_cell_available,
|
||||
update_needed,
|
||||
};
|
||||
|
||||
// FSM setters
|
||||
void set_null();
|
||||
void set_deregistered(deregistered_substate_t substate);
|
||||
void set_deregistered_initiated();
|
||||
void set_registered(registered_substate_t substate);
|
||||
void set_registered_initiated();
|
||||
void set_service_request_initiated();
|
||||
|
||||
// FSM getters
|
||||
state_t get_state() { return state; }
|
||||
deregistered_substate_t get_deregistered_substate() { return deregistered_substate; }
|
||||
registered_substate_t get_registered_substate() { return registered_substate; }
|
||||
|
||||
// Text Helpers
|
||||
const std::string get_full_state_text();
|
||||
|
||||
private:
|
||||
std::atomic<state_t> state{state_t::null};
|
||||
deregistered_substate_t deregistered_substate = deregistered_substate_t::null;
|
||||
registered_substate_t registered_substate = registered_substate_t::null;
|
||||
srslog::basic_logger& logger = srslog::fetch_basic_logger("NAS-5G");
|
||||
};
|
||||
|
||||
const char* mm5g_state_text(mm5g_state_t::state_t type);
|
||||
const char* mm5g_deregistered_substate_text(mm5g_state_t::deregistered_substate_t type);
|
||||
const char* mm5g_registered_substate_text(mm5g_state_t::registered_substate_t type);
|
||||
|
||||
} // namespace srsue
|
||||
#endif
|
@ -0,0 +1,236 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsue/hdr/stack/upper/nas_5g.h"
|
||||
#include "srsran/asn1/nas_5g_ies.h"
|
||||
#include "srsran/asn1/nas_5g_msg.h"
|
||||
#include "srsran/common/bcd_helpers.h"
|
||||
#include "srsran/common/security.h"
|
||||
#include "srsran/common/standard_streams.h"
|
||||
#include "srsran/common/string_helpers.h"
|
||||
#include "srsran/interfaces/ue_gw_interfaces.h"
|
||||
#include "srsran/interfaces/ue_rrc_interfaces.h"
|
||||
#include "srsran/interfaces/ue_usim_interfaces.h"
|
||||
#include "srsue/hdr/stack/upper/nas_5g_procedures.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace srsran;
|
||||
using namespace srsran::nas_5g;
|
||||
|
||||
namespace srsue {
|
||||
|
||||
/*********************************************************************
|
||||
* NAS 5G (NR)
|
||||
********************************************************************/
|
||||
|
||||
nas_5g::nas_5g(srsran::task_sched_handle task_sched_) :
|
||||
nas_base("NAS-5G"),
|
||||
task_sched(task_sched_),
|
||||
t3502(task_sched_.get_unique_timer()),
|
||||
t3510(task_sched_.get_unique_timer()),
|
||||
t3511(task_sched_.get_unique_timer()),
|
||||
t3521(task_sched_.get_unique_timer()),
|
||||
reregistration_timer(task_sched_.get_unique_timer()),
|
||||
registration_proc(this)
|
||||
{
|
||||
// Configure timers
|
||||
t3502.set(t3502_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||
t3510.set(t3510_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||
t3511.set(t3511_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||
t3521.set(t3521_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||
reregistration_timer.set(reregistration_timer_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||
}
|
||||
|
||||
nas_5g::~nas_5g() {}
|
||||
|
||||
void nas_5g::stop()
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
int nas_5g::init(usim_interface_nas* usim_,
|
||||
rrc_nr_interface_nas_5g* rrc_nr_,
|
||||
gw_interface_nas* gw_,
|
||||
const nas_args_t& cfg_)
|
||||
{
|
||||
usim = usim_;
|
||||
rrc_nr = rrc_nr_;
|
||||
gw = gw_;
|
||||
cfg = cfg_;
|
||||
|
||||
// parse and sanity check EIA list
|
||||
if (parse_security_algorithm_list(cfg_.ia5g, ia5g_caps) != SRSRAN_SUCCESS) {
|
||||
logger.warning("Failed to parse integrity algorithm list: Defaulting to 5G-EI1-128, 5G-EI2-128, 5G-EI3-128");
|
||||
ia5g_caps[0] = false;
|
||||
ia5g_caps[1] = true;
|
||||
ia5g_caps[2] = true;
|
||||
ia5g_caps[3] = true;
|
||||
}
|
||||
|
||||
// parse and sanity check EEA list
|
||||
if (parse_security_algorithm_list(cfg_.ea5g, ea5g_caps) != SRSRAN_SUCCESS) {
|
||||
logger.warning(
|
||||
"Failed to parse encryption algorithm list: Defaulting to 5G-EA0, 5G-EA1-128, 5G-EA2-128, 5G-EA3-128");
|
||||
ea5g_caps[0] = true;
|
||||
ea5g_caps[1] = true;
|
||||
ea5g_caps[2] = true;
|
||||
ea5g_caps[3] = true;
|
||||
}
|
||||
|
||||
running = true;
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
void nas_5g::run_tti()
|
||||
{
|
||||
// Process PLMN selection ongoing procedures
|
||||
callbacks.run();
|
||||
|
||||
// Transmit intiating messages if necessary
|
||||
switch (state.get_state()) {
|
||||
case mm5g_state_t::state_t::deregistered:
|
||||
// TODO Make sure cell selection is finished after transitioning from another state (if required)
|
||||
// Make sure the RRC is finished transitioning to RRC Idle
|
||||
if (reregistration_timer.is_running()) {
|
||||
logger.debug("Waiting for re-attach timer to expire to attach again.");
|
||||
return;
|
||||
}
|
||||
switch (state.get_deregistered_substate()) {
|
||||
case mm5g_state_t::deregistered_substate_t::plmn_search:
|
||||
case mm5g_state_t::deregistered_substate_t::normal_service:
|
||||
case mm5g_state_t::deregistered_substate_t::initial_registration_needed:
|
||||
registration_proc.launch();
|
||||
break;
|
||||
case mm5g_state_t::deregistered_substate_t::attempting_to_registration:
|
||||
case mm5g_state_t::deregistered_substate_t::no_supi:
|
||||
case mm5g_state_t::deregistered_substate_t::no_cell_available:
|
||||
case mm5g_state_t::deregistered_substate_t::e_call_inactive:
|
||||
logger.debug("Attempting to registration (not implemented) %s", state.get_full_state_text().c_str());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case mm5g_state_t::state_t::registered:
|
||||
break;
|
||||
case mm5g_state_t::state_t::deregistered_initiated:
|
||||
logger.debug("UE detaching...");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Senders
|
||||
******************************************************************************/
|
||||
|
||||
int nas_5g::send_registration_request()
|
||||
{
|
||||
unique_byte_buffer_t pdu = srsran::make_byte_buffer();
|
||||
if (!pdu) {
|
||||
logger.error("Couldn't allocate PDU in %s().", __FUNCTION__);
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
|
||||
logger.info("Generating registration request");
|
||||
|
||||
nas_5gs_msg nas_msg;
|
||||
registration_request_t& reg_req = nas_msg.set_registration_request();
|
||||
|
||||
reg_req.registration_type_5gs.follow_on_request_bit =
|
||||
registration_type_5gs_t::follow_on_request_bit_type_::options::no_follow_on_request_pending;
|
||||
reg_req.registration_type_5gs.registration_type =
|
||||
registration_type_5gs_t::registration_type_type_::options::initial_registration;
|
||||
mobile_identity_5gs_t::suci_s& suci = reg_req.mobile_identity_5gs.set_suci();
|
||||
suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi;
|
||||
mcc_to_bytes(0x0, suci.mcc.data());
|
||||
uint8_t mnc_len;
|
||||
mnc_to_bytes(0x0, suci.mnc.data(), &mnc_len);
|
||||
suci.scheme_output.resize(15);
|
||||
usim->get_imsi_vec(suci.scheme_output.data(), 15);
|
||||
logger.info("Requesting IMSI attach (IMSI=%s)", usim->get_imsi_str().c_str());
|
||||
|
||||
if (nas_msg.pack(pdu) != SRSASN_SUCCESS) {
|
||||
logger.error("Failed to pack registration request");
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
|
||||
if (pcap != nullptr) {
|
||||
pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes);
|
||||
}
|
||||
|
||||
// start T3510
|
||||
logger.debug("Starting T3410. Timeout in %d ms.", t3510.duration());
|
||||
t3510.run();
|
||||
|
||||
state.set_registered_initiated();
|
||||
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* UE Stack and RRC common Interface
|
||||
******************************************************************************/
|
||||
bool nas_5g::is_registered()
|
||||
{
|
||||
return state.get_state() == mm5g_state_t::state_t::registered;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* NAS Timers
|
||||
******************************************************************************/
|
||||
void nas_5g::timer_expired(uint32_t timeout_id)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* UE Stack Interface
|
||||
******************************************************************************/
|
||||
int nas_5g::switch_on()
|
||||
{
|
||||
logger.info("Switching on");
|
||||
state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search);
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
int nas_5g::switch_off()
|
||||
{
|
||||
logger.info("Switching off");
|
||||
// TODO
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
int nas_5g::enable_data()
|
||||
{
|
||||
logger.info("Enabling data services");
|
||||
return switch_on();
|
||||
}
|
||||
|
||||
int nas_5g::disable_data()
|
||||
{
|
||||
logger.info("Disabling data services");
|
||||
// TODO
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
int nas_5g::start_service_request()
|
||||
{
|
||||
logger.info("Service Request");
|
||||
// TODO
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace srsue
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsue/hdr/stack/upper/nas_5g_procedures.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace srsran;
|
||||
|
||||
namespace srsue {
|
||||
|
||||
nas_5g::registration_procedure::registration_procedure(nas_5g_interface_procedures* parent_nas_) :
|
||||
parent_nas(parent_nas_)
|
||||
{}
|
||||
|
||||
srsran::proc_outcome_t nas_5g::registration_procedure::init()
|
||||
{
|
||||
parent_nas->send_registration_request();
|
||||
return srsran::proc_outcome_t::yield;
|
||||
}
|
||||
srsran::proc_outcome_t nas_5g::registration_procedure::step()
|
||||
{
|
||||
return srsran::proc_outcome_t::success;
|
||||
}
|
||||
|
||||
} // namespace srsue
|
@ -0,0 +1,149 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
#include "srsue/hdr/stack/upper/nas_5gmm_state.h"
|
||||
|
||||
namespace srsue {
|
||||
|
||||
// FSM setters
|
||||
void mm5g_state_t::set_null()
|
||||
{
|
||||
state = state_t::null;
|
||||
deregistered_substate = deregistered_substate_t::null;
|
||||
registered_substate = registered_substate_t::null;
|
||||
logger.debug("Changed to mm5g state: %s", get_full_state_text().c_str());
|
||||
}
|
||||
|
||||
void mm5g_state_t::set_deregistered(deregistered_substate_t substate)
|
||||
{
|
||||
state = state_t::deregistered;
|
||||
deregistered_substate = substate;
|
||||
registered_substate = registered_substate_t::null;
|
||||
logger.debug("Changed to mm5g state: %s", get_full_state_text().c_str());
|
||||
}
|
||||
|
||||
void mm5g_state_t::set_deregistered_initiated()
|
||||
{
|
||||
state = state_t::deregistered_initiated;
|
||||
deregistered_substate = deregistered_substate_t::null;
|
||||
registered_substate = registered_substate_t::null;
|
||||
logger.debug("Changed to mm5g state: %s", get_full_state_text().c_str());
|
||||
}
|
||||
|
||||
void mm5g_state_t::set_registered(registered_substate_t substate)
|
||||
{
|
||||
state = state_t::registered;
|
||||
deregistered_substate = deregistered_substate_t::null;
|
||||
registered_substate = substate;
|
||||
logger.debug("Changed to mm5g state: %s", get_full_state_text().c_str());
|
||||
}
|
||||
|
||||
void mm5g_state_t::set_registered_initiated()
|
||||
{
|
||||
state = state_t::registered_initiated;
|
||||
deregistered_substate = deregistered_substate_t::null;
|
||||
registered_substate = registered_substate_t::null;
|
||||
logger.debug("Changed to mm5g state: %s", get_full_state_text().c_str());
|
||||
}
|
||||
|
||||
void mm5g_state_t::set_service_request_initiated()
|
||||
{
|
||||
state = state_t::service_request_initiated;
|
||||
deregistered_substate = deregistered_substate_t::null;
|
||||
registered_substate = registered_substate_t::null;
|
||||
logger.debug("Changed to mm5g state: %s", get_full_state_text().c_str());
|
||||
}
|
||||
|
||||
const std::string mm5g_state_t::get_full_state_text()
|
||||
{
|
||||
if (state == state_t::deregistered) {
|
||||
return mm5g_state_text(state) + std::string(", with substate ") +
|
||||
mm5g_deregistered_substate_text(deregistered_substate);
|
||||
} else if (state == state_t::registered) {
|
||||
return mm5g_state_text(state) + std::string(", with substate ") +
|
||||
mm5g_registered_substate_text(registered_substate);
|
||||
} else {
|
||||
return mm5g_state_text(state);
|
||||
}
|
||||
return std::string("Invalid State");
|
||||
}
|
||||
|
||||
/*
|
||||
* Logging helper functions
|
||||
*/
|
||||
const char* mm5g_state_text(mm5g_state_t::state_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case mm5g_state_t::state_t::null:
|
||||
return "NULL";
|
||||
case mm5g_state_t::state_t::deregistered:
|
||||
return "DEREGISTERED";
|
||||
case mm5g_state_t::state_t::registered_initiated:
|
||||
return "REGISTERED-INITIATED";
|
||||
case mm5g_state_t::state_t::registered:
|
||||
return "REGISTERED";
|
||||
case mm5g_state_t::state_t::deregistered_initiated:
|
||||
return "DEREGISTERED-INITIATED";
|
||||
case mm5g_state_t::state_t::service_request_initiated:
|
||||
return "SERVICE-REQUEST-INITIATED";
|
||||
}
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
const char* mm5g_deregistered_substate_text(mm5g_state_t::deregistered_substate_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case mm5g_state_t::deregistered_substate_t::null:
|
||||
return "NULL";
|
||||
case mm5g_state_t::deregistered_substate_t::normal_service:
|
||||
return "NORMAL-SERVICE";
|
||||
case mm5g_state_t::deregistered_substate_t::limited_service:
|
||||
return "LIMITED-SERVICE";
|
||||
case mm5g_state_t::deregistered_substate_t::attempting_to_registration:
|
||||
return "ATTEMPTING-TO-REGISTRATION";
|
||||
case mm5g_state_t::deregistered_substate_t::plmn_search:
|
||||
return "PLMN-SEARCH";
|
||||
case mm5g_state_t::deregistered_substate_t::no_supi:
|
||||
return "NO-SUPI";
|
||||
case mm5g_state_t::deregistered_substate_t::no_cell_available:
|
||||
return "NO-CELL-AVAILABLE";
|
||||
case mm5g_state_t::deregistered_substate_t::e_call_inactive:
|
||||
return "eCALL-INACTIVE";
|
||||
case mm5g_state_t::deregistered_substate_t::initial_registration_needed:
|
||||
return "ATTACH-NEEDED";
|
||||
}
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
const char* mm5g_registered_substate_text(mm5g_state_t::registered_substate_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case mm5g_state_t::registered_substate_t::null:
|
||||
return "NULL";
|
||||
case mm5g_state_t::registered_substate_t::normal_service:
|
||||
return "NORMAL-SERVICE";
|
||||
case mm5g_state_t::registered_substate_t::non_allowed_service:
|
||||
return "NON-ALLOWED-SERVICE";
|
||||
case mm5g_state_t::registered_substate_t::attempting_registration_update:
|
||||
return "ATTEMPTING-REGISTRATION-UPDATE";
|
||||
case mm5g_state_t::registered_substate_t::limited_service:
|
||||
return "LIMITED-SERVICE";
|
||||
case mm5g_state_t::registered_substate_t::plmn_search:
|
||||
return "PLMN-SEARCH";
|
||||
case mm5g_state_t::registered_substate_t::no_cell_available:
|
||||
return "NO-CELL-AVAILABLE";
|
||||
case mm5g_state_t::registered_substate_t::update_needed:
|
||||
return "UPDATE-NEEDED";
|
||||
}
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
} // namespace srsue
|
@ -0,0 +1,108 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsran/common/bcd_helpers.h"
|
||||
#include "srsran/common/test_common.h"
|
||||
#include "srsran/common/tsan_options.h"
|
||||
#include "srsran/interfaces/ue_pdcp_interfaces.h"
|
||||
#include "srsran/srslog/srslog.h"
|
||||
#include "srsran/test/ue_test_interfaces.h"
|
||||
#include "srsue/hdr/stack/upper/gw.h"
|
||||
#include "srsue/hdr/stack/upper/nas_5g.h"
|
||||
#include "srsue/hdr/stack/upper/test/nas_test_common.h"
|
||||
|
||||
using namespace srsue;
|
||||
using namespace srsran;
|
||||
|
||||
#define HAVE_PCAP 0
|
||||
|
||||
int amf_attach_request_test(srsran::nas_pcap* pcap)
|
||||
{
|
||||
int ret = SRSRAN_ERROR;
|
||||
|
||||
rrc_nr_dummy rrc_nr_dummy;
|
||||
pdcp_dummy pdcp_dummy;
|
||||
|
||||
srsue::usim usim(srslog::fetch_basic_logger("USIM"));
|
||||
usim_args_t args;
|
||||
args.mode = "soft";
|
||||
args.algo = "xor";
|
||||
args.imei = "353490069873319";
|
||||
args.imsi = "001010123456789";
|
||||
args.k = "00112233445566778899aabbccddeeff";
|
||||
args.op = "63BFA50EE6523365FF14C1F45F88737D";
|
||||
usim.init(&args);
|
||||
|
||||
nas_args_t nas_cfg;
|
||||
nas_cfg.force_imsi_attach = true;
|
||||
nas_cfg.apn_name = "test123";
|
||||
nas_cfg.ia5g = "0,1,2,3";
|
||||
nas_cfg.ea5g = "0,1,2,3";
|
||||
|
||||
test_stack_dummy<srsue::nas_5g> stack(&pdcp_dummy);
|
||||
srsue::nas_5g nas_5g(&stack.task_sched);
|
||||
srsue::gw gw;
|
||||
|
||||
if (pcap != nullptr) {
|
||||
nas_5g.start_pcap(pcap);
|
||||
}
|
||||
|
||||
gw_args_t gw_args;
|
||||
gw_args.tun_dev_name = "tun0";
|
||||
gw_args.log.gw_level = "debug";
|
||||
gw_args.log.gw_hex_limit = 100000;
|
||||
|
||||
gw.init(gw_args, &stack);
|
||||
stack.init(&nas_5g);
|
||||
|
||||
nas_5g.init(&usim, &rrc_nr_dummy, &gw, nas_cfg);
|
||||
rrc_nr_dummy.init(&nas_5g);
|
||||
|
||||
// trigger test
|
||||
stack.switch_on();
|
||||
stack.stop();
|
||||
|
||||
gw.stop();
|
||||
ret = SRSRAN_SUCCESS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Setup logging.
|
||||
auto& rrc_logger = srslog::fetch_basic_logger("RRC", false);
|
||||
rrc_logger.set_level(srslog::basic_levels::debug);
|
||||
rrc_logger.set_hex_dump_max_size(100000);
|
||||
auto& nas_logger = srslog::fetch_basic_logger("NAS", false);
|
||||
nas_logger.set_level(srslog::basic_levels::debug);
|
||||
nas_logger.set_hex_dump_max_size(100000);
|
||||
auto& usim_logger = srslog::fetch_basic_logger("USIM", false);
|
||||
usim_logger.set_level(srslog::basic_levels::debug);
|
||||
usim_logger.set_hex_dump_max_size(100000);
|
||||
auto& gw_logger = srslog::fetch_basic_logger("GW", false);
|
||||
gw_logger.set_level(srslog::basic_levels::debug);
|
||||
gw_logger.set_hex_dump_max_size(100000);
|
||||
|
||||
// Start the log backend.
|
||||
srslog::init();
|
||||
#if HAVE_PCAP
|
||||
srsran::nas_pcap pcap;
|
||||
pcap.open("nas_5g_test.pcap", 0, srsran::srsran_rat_t::nr);
|
||||
TESTASSERT(amf_attach_request_test(&pcap) == SRSRAN_SUCCESS);
|
||||
pcap.close();
|
||||
#else
|
||||
TESTASSERT(amf_attach_request_test(nullptr) == SRSRAN_SUCCESS);
|
||||
#endif // HAVE_PCAP
|
||||
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue