srsue,sa: dummy rrc_nr to initiate dummy cell_select and phy_cfg

This commit is contained in:
Ismael Gomez 2021-11-30 14:45:19 +01:00
parent c08c56fd1d
commit 219bae4fd3
19 changed files with 212 additions and 73 deletions

View File

@ -27,7 +27,6 @@ class rrc_interface_phy_nr
public:
virtual void in_sync() = 0;
virtual void out_of_sync() = 0;
virtual void run_tti(const uint32_t tti) = 0;
virtual void set_phy_config_complete(bool status) = 0;
/**
@ -100,8 +99,6 @@ public:
tb_ul_t tb; // only single TB in UL
} tb_action_ul_t;
virtual int sf_indication(const uint32_t tti) = 0; ///< TODO: rename to slot indication
// Query the MAC for the current RNTI to look for
struct sched_rnti_t {
uint16_t id;
@ -314,7 +311,11 @@ public:
// Combined interface for PHY to access stack (MAC and RRC)
class stack_interface_phy_nr : public mac_interface_phy_nr, public rrc_interface_phy_nr
{};
{
public:
/* Indicate new TTI */
virtual void run_tti(const uint32_t tti, const uint32_t tti_jump) = 0;
};
// Combined interface for stack (MAC and RRC) to access PHY
class phy_interface_stack_nr : public phy_interface_mac_nr, public phy_interface_rrc_nr

76
srsue/hdr/phy/dummy_phy.h Normal file
View File

@ -0,0 +1,76 @@
/**
*
* \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 SRSRAN_DUMMY_PHY_H
#define SRSRAN_DUMMY_PHY_H
#include "srsran/interfaces/phy_interface_types.h"
#include "srsue/hdr/phy/ue_phy_base.h"
namespace srsue {
class dummy_phy final : public ue_phy_base, public phy_interface_stack_lte
{
public:
// ue_phy_base
std::string get_type() final { return "dummy_phy"; }
void stop() final {}
void wait_initialize() final {}
bool is_initialized() final { return false; }
void start_plot() final {}
void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) final {}
// phy_interface_stack_lte
void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm, float ta_base_sec = 0.0f) final
{}
prach_info_t prach_get_info() final { return {}; }
/* Indicates the transmission of a SR signal in the next opportunity */
void sr_send() final {}
int sr_last_tx_tti() final { return 0; }
void set_mch_period_stop(uint32_t stop) final {}
bool set_config(const srsran::phy_cfg_t& config, uint32_t cc_idx = 0) final { return false; }
bool set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) final { return false; }
void set_config_tdd(srsran_tdd_config_t& tdd_config) final {}
void set_config_mbsfn_sib2(srsran::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) final {}
void set_config_mbsfn_sib13(const srsran::sib13_t& sib13) final {}
void set_config_mbsfn_mcch(const srsran::mcch_msg_t& mcch) final {}
void deactivate_scells() final {}
/* Measurements interface */
void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci) final {}
void meas_stop() final {}
/* Cell search and selection procedures */
bool cell_search() final { return false; }
bool cell_select(phy_cell_t cell) final { return false; }
bool cell_is_camping() final { return false; }
/* Time advance commands */
void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final {}
void set_timeadv(uint32_t tti, uint32_t ta_cmd) final {}
/* Activate / Disactivate SCell*/
void set_activation_deactivation_scell(uint32_t cmd, uint32_t tti) final {}
/* Sets RAR dci payload */
void set_rar_grant(uint8_t grant_payload[SRSRAN_RAR_GRANT_LEN], uint16_t rnti) final {}
uint32_t get_current_tti() final { return 0; }
float get_phr() final { return 0.0; }
float get_pathloss_db() final { return 0.0; }
};
} // namespace srsue
#endif // SRSRAN_DUMMY_PHY_H

View File

@ -111,6 +111,8 @@ private:
void run_state_cell_select();
void run_state_cell_camping();
int radio_recv_fnc(srsran::rf_buffer_t& data, srsran_timestamp_t* rx_time);
void run_stack_tti();
void run_thread() override;
};

View File

@ -23,10 +23,11 @@ namespace srsue {
/**
* @brief NR Standalone PHY
*/
class phy_nr_sa final : public ue_phy_base, public phy_interface_stack_nr
class phy_nr_sa final : public ue_phy_base, public phy_interface_stack_nr, public srsran::phy_interface_radio
{
public:
phy_nr_sa(const char* logname);
~phy_nr_sa() final { stop(); }
int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_);
void wait_initialize() final;
@ -36,6 +37,9 @@ public:
void start_plot() final {}
void radio_overflow() final {}
void radio_failure() final {}
std::string get_type() final { return "nr_soft"; }
int set_rar_grant(uint32_t rar_slot_idx,
@ -63,7 +67,6 @@ private:
srslog::basic_logger& logger_phy_lib;
nr::worker_pool workers;
phy_common common;
nr::sync_sa sync;
srsran::phy_cfg_nr_t config_nr = {};

View File

@ -81,6 +81,9 @@ public:
asn1::dyn_octstring oct,
const T& msg,
const std::string& msg_type);
void run_tti(uint32_t tti);
// PHY interface
void in_sync() final;
void out_of_sync() final;
@ -91,7 +94,6 @@ public:
void protocol_failure() final;
// MAC interface
void run_tti(uint32_t tti) final;
void ra_completed() final;
void ra_problem() final;
void release_pucch_srs() final;

View File

@ -62,9 +62,11 @@ typedef struct {
rrc_nr_args_t rrc_nr;
std::string ue_category_str;
nas_args_t nas;
nas_5g_args_t nas_5g;
gw_args_t gw;
uint32_t sync_queue_size; // Max allowed difference between PHY and Stack clocks (in TTI)
bool have_tti_time_stats;
bool attach_on_nr;
} stack_args_t;
class ue_stack_base

View File

@ -35,6 +35,7 @@
#include "srsue/hdr/ue_metrics_interface.h"
#include "ue_stack_base.h"
#include "upper/nas.h"
#include "upper/nas_5g.h"
#include "upper/usim.h"
#include <functional>
#include <pthread.h>
@ -127,7 +128,6 @@ public:
void cell_search_found_cell(const cell_search_result_t& result) final {}
// MAC Interface for NR PHY
int sf_indication(const uint32_t tti) final { return SRSRAN_SUCCESS; }
void tb_decoded(const uint32_t cc_idx,
const mac_nr_grant_dl_t& grant,
mac_interface_phy_nr::tb_action_dl_result_t result) final
@ -147,11 +147,6 @@ public:
mac_nr.new_grant_ul(cc_idx, grant, action);
}
void run_tti(const uint32_t tti) final
{
// ignored, timing will be handled by EUTRA
}
void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) final
{
mac_nr.prach_sent(tti, s_id, t_id, f_id, ul_carrier_id);
@ -232,6 +227,7 @@ private:
srsran::pdcp pdcp_nr;
srsue::rrc_nr rrc_nr;
srsue::nas nas;
srsue::nas_5g nas_5g;
std::unique_ptr<usim_base> usim;
ue_bearer_manager bearers; // helper to manage mapping between EPS and radio bearers

View File

@ -72,17 +72,15 @@ public:
// RRC interface for PHY
void in_sync() final;
void out_of_sync() final;
void run_tti(const uint32_t tti) final;
void set_phy_config_complete(bool status) override;
void set_phy_config_complete(bool status) final;
void cell_search_found_cell(const cell_search_result_t& result) final;
void run_tti(uint32_t tti, uint32_t tti_jump) final;
// MAC interface for PHY
sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) final { return mac->get_dl_sched_rnti_nr(tti); }
sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) final { return mac->get_ul_sched_rnti_nr(tti); }
int sf_indication(const uint32_t tti) final
{
run_tti(tti);
return SRSRAN_SUCCESS;
}
void tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_result_t result) final
{
mac->tb_decoded(cc_idx, grant, std::move(result));

View File

@ -105,6 +105,7 @@ public:
private:
// UE consists of a radio, a PHY and a stack element
std::unique_ptr<ue_phy_base> phy;
std::unique_ptr<ue_phy_base> dummy_phy;
std::unique_ptr<srsran::radio_base> radio;
std::unique_ptr<ue_stack_base> stack;
std::unique_ptr<gw> gw_inst;

View File

@ -119,7 +119,7 @@ void slot_sync::run_stack_tti()
// Run stack
logger.debug("run_stack_tti: calling stack tti=%d, tti_jump=%d", tti, tti_jump);
stack->run_tti(tti);
stack->run_tti(tti, tti_jump);
logger.debug("run_stack_tti: stack called");
}

View File

@ -117,12 +117,12 @@ int phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::
logger_phy.set_hex_dump_max_size(args.log.phy_hex_limit);
if (!check_args(args)) {
return false;
return SRSRAN_ERROR;
}
is_configured = false;
start();
return true;
return SRSRAN_SUCCESS;
}
// Initializes PHY in a thread

View File

@ -58,8 +58,7 @@ phy_nr_sa::phy_nr_sa(const char* logname) :
logger(srslog::fetch_basic_logger(logname)),
logger_phy_lib(srslog::fetch_basic_logger("PHY_LIB")),
sync(logger, workers),
workers(logger, 4),
common(logger)
workers(logger, 4)
{}
int phy_nr_sa::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_)
@ -81,14 +80,14 @@ int phy_nr_sa::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_,
logger.set_hex_dump_max_size(args.log.phy_hex_limit);
if (!check_args(args)) {
return false;
return SRSRAN_ERROR;
}
is_configured = false;
std::thread t([this]() { init_background(); });
init_thread = std::move(t);
return true;
return SRSRAN_SUCCESS;
}
void phy_nr_sa::init_background()
@ -201,7 +200,7 @@ bool phy_nr_sa::start_cell_select(const cell_select_args_t& req)
cmd_worker_cell.add_cmd([this, req]() {
// Request cell search to lower synchronization instance.
start_cell_select(req);
sync.cell_select_run(req);
});
return true;
@ -241,16 +240,10 @@ bool phy_nr_sa::set_config(const srsran::phy_cfg_nr_t& cfg)
// Setup carrier configuration asynchronously
cmd_worker.add_cmd([this]() {
// tune radio
for (uint32_t i = 0; i < common.args->nof_nr_carriers; i++) {
logger.info("Tuning Rx channel %d to %.2f MHz",
i + common.args->nof_lte_carriers,
config_nr.carrier.dl_center_frequency_hz / 1e6);
radio->set_rx_freq(i + common.args->nof_lte_carriers, config_nr.carrier.dl_center_frequency_hz);
logger.info("Tuning Tx channel %d to %.2f MHz",
i + common.args->nof_lte_carriers,
config_nr.carrier.ul_center_frequency_hz / 1e6);
radio->set_tx_freq(i + common.args->nof_lte_carriers, config_nr.carrier.ul_center_frequency_hz);
}
logger.info("Tuning Rx channel %d to %.2f MHz", 0, config_nr.carrier.dl_center_frequency_hz / 1e6);
radio->set_rx_freq(0, config_nr.carrier.dl_center_frequency_hz);
logger.info("Tuning Tx channel %d to %.2f MHz", 0, config_nr.carrier.ul_center_frequency_hz / 1e6);
radio->set_tx_freq(0, config_nr.carrier.ul_center_frequency_hz);
// Set UE configuration
bool ret = workers.set_config(config_nr);

View File

@ -200,6 +200,7 @@ void sync_sa::run_state_cell_select()
{
// TODO
tti = 0;
phy_state.state_exit();
}
void sync_sa::run_state_cell_camping()
@ -242,9 +243,13 @@ void sync_sa::run_thread()
rf_buffer.set_nof_samples(slot_sz);
rf_buffer.set(0, rx_buffer);
if (not radio->rx_now(rf_buffer, last_rx_time)) {
#ifdef useradio
if (not slot_synchronizer.recv_callback(rf_buffer, last_rx_time.get_ptr(0))) {
logger.error("SYNC: receiving from radio\n");
}
#else
sleep(1);
#endif
}
switch (phy_state.run_state()) {
case sync_state::IDLE:
@ -255,13 +260,18 @@ void sync_sa::run_thread()
break;
case sync_state::SFN_SYNC:
run_state_cell_select();
break;
case sync_state::CAMPING:
run_state_cell_camping();
break;
}
// Advance stack TTI
#ifdef useradio
slot_synchronizer.run_stack_tti();
#else
stack->run_tti(tti, 1);
#endif
}
// Advance stack TTI
stack->run_tti(tti);
}
void sync_sa::worker_end(const srsran::phy_common_interface::worker_context_t& w_ctx,
const bool& tx_enable,

View File

@ -12,6 +12,7 @@
#include "srsue/hdr/stack/rrc_nr/rrc_nr.h"
#include "srsran/common/band_helper.h"
#include "srsran/common/phy_cfg_nr_default.h"
#include "srsran/common/security.h"
#include "srsran/common/standard_streams.h"
#include "srsran/interfaces/ue_pdcp_interfaces.h"
@ -223,6 +224,17 @@ bool rrc_nr::is_connected()
int rrc_nr::connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t sdu)
{
srsran::phy_cfg_nr_default_t::reference_cfg_t cfg = {};
cfg.carrier = srsran::phy_cfg_nr_default_t::reference_cfg_t::R_CARRIER_CUSTOM_10MHZ;
cfg.duplex = srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD;
phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{cfg}};
phy_interface_rrc_nr::cell_select_args_t cell_cfg = {};
cell_cfg.carrier = phy_cfg.carrier;
cell_cfg.ssb_cfg = phy_cfg.get_ssb_cfg();
phy->start_cell_select(cell_cfg);
sleep(1);
phy->set_config(phy_cfg);
return SRSRAN_SUCCESS;
}

View File

@ -48,6 +48,7 @@ ue_stack_lte::ue_stack_lte() :
pdcp(&task_sched, "PDCP"),
pdcp_nr(&task_sched, "PDCP-NR"),
nas(srslog::fetch_basic_logger("NAS", false), &task_sched),
nas_5g(srslog::fetch_basic_logger("NAS5G", false), &task_sched),
thread("STACK"),
task_sched(512, 64),
tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD)
@ -217,6 +218,7 @@ int ue_stack_lte::init(const stack_args_t& args_)
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.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc);
nas_5g.init(usim.get(), &rrc_nr, gw, args.nas_5g);
running = true;
start(STACK_MAIN_THREAD_PRIO);
@ -238,6 +240,7 @@ void ue_stack_lte::stop_impl()
usim->stop();
nas.stop();
nas_5g.stop();
rrc.stop();
rlc.stop();
@ -262,7 +265,13 @@ bool ue_stack_lte::switch_on()
{
if (running) {
stack_logger.info("Triggering NAS switch on\n");
if (!ue_task_queue.try_push([this]() { nas.switch_on(); })) {
if (!ue_task_queue.try_push([this]() {
if (args.attach_on_nr) {
nas_5g.switch_on();
} else {
nas.switch_on();
}
})) {
stack_logger.error("Triggering NAS switch on: ue_task_queue is full\n");
}
} else {
@ -477,6 +486,7 @@ void ue_stack_lte::run_tti_impl(uint32_t tti, uint32_t tti_jump)
rrc.run_tti();
rrc_nr.run_tti(tti);
nas.run_tti();
nas_5g.run_tti();
if (args.have_tti_time_stats) {
std::chrono::nanoseconds dur = tti_tprof.stop();

View File

@ -185,7 +185,7 @@ void ue_stack_nr::out_of_sync()
// pending_tasks.push(sync_task_queue, task_t{[this](task_t*) { rrc.out_of_sync(); }});
}
void ue_stack_nr::run_tti(uint32_t tti)
void ue_stack_nr::run_tti(uint32_t tti, uint32_t tti_jump)
{
sync_task_queue.push([this, tti]() { run_tti_impl(tti); });
}

View File

@ -17,7 +17,9 @@
#include "srsran/radio/radio.h"
#include "srsran/radio/radio_null.h"
#include "srsran/srsran.h"
#include "srsue/hdr/phy/dummy_phy.h"
#include "srsue/hdr/phy/phy.h"
#include "srsue/hdr/phy/phy_nr_sa.h"
#include "srsue/hdr/stack/ue_stack_lte.h"
#include "srsue/hdr/stack/ue_stack_nr.h"
#include <algorithm>
@ -66,30 +68,12 @@ int ue::init(const all_args_t& args_)
return SRSRAN_ERROR;
}
std::unique_ptr<srsue::phy> lte_phy = std::unique_ptr<srsue::phy>(new srsue::phy);
if (!lte_phy) {
srsran::console("Error creating LTE PHY instance.\n");
return SRSRAN_ERROR;
}
std::unique_ptr<srsran::radio> lte_radio = std::unique_ptr<srsran::radio>(new srsran::radio);
if (!lte_radio) {
srsran::console("Error creating radio multi instance.\n");
return SRSRAN_ERROR;
}
// init layers
if (lte_radio->init(args.rf, lte_phy.get())) {
srsran::console("Error initializing radio.\n");
return SRSRAN_ERROR;
}
// from here onwards do not exit immediately if something goes wrong as sub-layers may already use interfaces
if (lte_phy->init(args.phy, lte_stack.get(), lte_radio.get())) {
srsran::console("Error initializing PHY.\n");
ret = SRSRAN_ERROR;
}
srsue::phy_args_nr_t phy_args_nr = {};
phy_args_nr.max_nof_prb = args.phy.nr_max_nof_prb;
phy_args_nr.rf_channel_offset = args.phy.nof_lte_carriers;
@ -98,14 +82,66 @@ int ue::init(const all_args_t& args_)
phy_args_nr.worker_cpu_mask = args.phy.worker_cpu_mask;
phy_args_nr.log = args.phy.log;
phy_args_nr.store_pdsch_ko = args.phy.nr_store_pdsch_ko;
if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) {
srsran::console("Error initializing NR PHY.\n");
ret = SRSRAN_ERROR;
}
if (lte_stack->init(args.stack, lte_phy.get(), lte_phy.get(), gw_ptr.get())) {
srsran::console("Error initializing stack.\n");
ret = SRSRAN_ERROR;
// init layers
if (args.phy.nof_lte_carriers == 0) {
// SA mode
std::unique_ptr<srsue::phy_nr_sa> nr_phy = std::unique_ptr<srsue::phy_nr_sa>(new srsue::phy_nr_sa("PHY-SA"));
if (!nr_phy) {
srsran::console("Error creating LTE PHY instance.\n");
return SRSRAN_ERROR;
}
// In SA mode, pass the NR SA phy to the radio
if (lte_radio->init(args.rf, nr_phy.get())) {
srsran::console("Error initializing radio.\n");
return SRSRAN_ERROR;
}
if (nr_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) {
srsran::console("Error initializing PHY NR SA.\n");
ret = SRSRAN_ERROR;
}
std::unique_ptr<srsue::dummy_phy> dummy_lte_phy = std::unique_ptr<srsue::dummy_phy>(new srsue::dummy_phy);
if (!dummy_lte_phy) {
srsran::console("Error creating LTE PHY instance.\n");
return SRSRAN_ERROR;
}
// In SA mode, pass NR PHY pointer to stack
args.stack.attach_on_nr = true;
if (lte_stack->init(args.stack, dummy_lte_phy.get(), nr_phy.get(), gw_ptr.get())) {
srsran::console("Error initializing stack.\n");
ret = SRSRAN_ERROR;
}
phy = std::move(nr_phy);
dummy_phy = std::move(dummy_lte_phy);
} else {
// LTE or NSA mode
std::unique_ptr<srsue::phy> lte_phy = std::unique_ptr<srsue::phy>(new srsue::phy);
if (!lte_phy) {
srsran::console("Error creating LTE PHY instance.\n");
return SRSRAN_ERROR;
}
if (lte_radio->init(args.rf, lte_phy.get())) {
srsran::console("Error initializing radio.\n");
return SRSRAN_ERROR;
}
// from here onwards do not exit immediately if something goes wrong as sub-layers may already use interfaces
if (lte_phy->init(args.phy, lte_stack.get(), lte_radio.get())) {
srsran::console("Error initializing PHY.\n");
ret = SRSRAN_ERROR;
}
if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) {
srsran::console("Error initializing NR PHY.\n");
ret = SRSRAN_ERROR;
}
if (lte_stack->init(args.stack, lte_phy.get(), lte_phy.get(), gw_ptr.get())) {
srsran::console("Error initializing stack.\n");
ret = SRSRAN_ERROR;
}
phy = std::move(lte_phy);
}
if (gw_ptr->init(args.gw, lte_stack.get())) {
@ -116,7 +152,6 @@ int ue::init(const all_args_t& args_)
// move ownership
stack = std::move(lte_stack);
gw_inst = std::move(gw_ptr);
phy = std::move(lte_phy);
radio = std::move(lte_radio);
if (phy) {
@ -124,7 +159,6 @@ int ue::init(const all_args_t& args_)
phy->wait_initialize();
srsran::console("done!\n");
}
return ret;
}

View File

@ -69,7 +69,7 @@ public:
}
void in_sync() override {}
void out_of_sync() override {}
void run_tti(const uint32_t tti) override
void run_tti(const uint32_t tti, const uint32_t tti_jump) override
{
wait_tti();
@ -84,7 +84,6 @@ public:
}
}
}
int sf_indication(const uint32_t tti) override { return 0; }
sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) override
{
std::unique_lock<std::mutex> lock(rnti_mutex);

View File

@ -199,7 +199,7 @@ public:
ue_worker->set_context(ue_context);
// Run UE stack
ue_stack.run_tti(slot_idx);
ue_stack.run_tti(slot_idx, 1);
// Start UE work
ue_phy_com.push_semaphore(ue_worker);