diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index fb000ef98..542424bca 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -763,6 +763,7 @@ typedef struct { bool pregenerate_signals; srslte::channel::args_t dl_channel_args; + srslte::channel::args_t ul_channel_args; } phy_args_t; /* RAT agnostic Interface MAC -> PHY */ diff --git a/lib/src/phy/channel/channel.cc b/lib/src/phy/channel/channel.cc index dcf4a8709..ff677de6b 100644 --- a/lib/src/phy/channel/channel.cc +++ b/lib/src/phy/channel/channel.cc @@ -123,7 +123,7 @@ void channel::run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint3 } // Copy output buffer - memcpy(out[i], buffer_out, sizeof(cf_t) * len); + memcpy(out[i], buffer_in, sizeof(cf_t) * len); } } diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index bf518ee10..78f325493 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -177,6 +177,7 @@ private: radio_interface_phy* radio_h; float cfo; srslte::log* log_h; + srslte::channel_ptr ul_channel = nullptr; int rar_grant_tti; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 5c3463283..8cd59ac3d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -146,7 +146,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("gw.ip_devname", bpo::value(&args->stack.gw.tun_dev_name)->default_value("tun_srsue"), "Name of the tun_srsue device") ("gw.ip_netmask", bpo::value(&args->stack.gw.tun_dev_netmask)->default_value("255.255.255.0"), "Netmask of the tun_srsue device") - /* Channel emulator section */ + /* Downlink Channel emulator section */ ("channel.dl.enable", bpo::value(&args->phy.dl_channel_args.enable)->default_value(false), "Enable/Disable internal Downlink channel emulator") ("channel.dl.fading.enable", bpo::value(&args->phy.dl_channel_args.fading_enable)->default_value(false), "Enable/Disable Fading model") ("channel.dl.fading.model", bpo::value(&args->phy.dl_channel_args.fading_model)->default_value("none"), "Fading model + maximum doppler (E.g. none, epa5, eva70, etu300, etc)") @@ -158,6 +158,18 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("channel.dl.rlf.t_on_ms", bpo::value(&args->phy.dl_channel_args.rlf_t_on_ms)->default_value(10000), "Time for On state of the channel (ms)") ("channel.dl.rlf.t_off_ms", bpo::value(&args->phy.dl_channel_args.rlf_t_off_ms)->default_value(2000), "Time for Off state of the channel (ms)") + /* Uplink Channel emulator section */ + ("channel.ul.enable", bpo::value(&args->phy.ul_channel_args.enable)->default_value(false), "Enable/Disable internal Uplink channel emulator") + ("channel.ul.fading.enable", bpo::value(&args->phy.ul_channel_args.fading_enable)->default_value(false), "Enable/Disable Fading model") + ("channel.ul.fading.model", bpo::value(&args->phy.ul_channel_args.fading_model)->default_value("none"), "Fading model + maximum doppler (E.g. none, epa5, eva70, etu300, etc)") + ("channel.ul.delay.enable", bpo::value(&args->phy.ul_channel_args.delay_enable)->default_value(false), "Enable/Disable Delay simulator") + ("channel.ul.delay.period", bpo::value(&args->phy.ul_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)") + ("channel.ul.delay.maximum_us", bpo::value(&args->phy.ul_channel_args.delay_max_us)->default_value(100.0f), "Maximum delay in microseconds") + ("channel.ul.delay.minimum_us", bpo::value(&args->phy.ul_channel_args.delay_min_us)->default_value(10.0f), "Minimum delay in microseconds") + ("channel.ul.rlf.enable", bpo::value(&args->phy.ul_channel_args.rlf_enable)->default_value(false), "Enable/Disable Radio-Link Failure simulator") + ("channel.ul.rlf.t_on_ms", bpo::value(&args->phy.ul_channel_args.rlf_t_on_ms)->default_value(10000), "Time for On state of the channel (ms)") + ("channel.ul.rlf.t_off_ms", bpo::value(&args->phy.ul_channel_args.rlf_t_off_ms)->default_value(2000), "Time for Off state of the channel (ms)") + /* Expert section */ ("expert.phy.worker_cpu_mask", bpo::value(&args->phy.worker_cpu_mask)->default_value(-1), diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 0978d1ed3..b07948166 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -125,6 +125,12 @@ void phy_common::init(phy_args_t* _args, args = _args; is_first_tx = true; sr_last_tx_tti = -1; + + // Instantiate UL channel emulator + if (args->ul_channel_args.enable) { + ul_channel = + srslte::channel_ptr(new srslte::channel(args->ul_channel_args, args->nof_rf_channels * args->nof_rx_ant)); + } } void phy_common::set_ue_dl_cfg(srslte_ue_dl_cfg_t* ue_dl_cfg) @@ -565,11 +571,21 @@ void phy_common::worker_end(uint32_t tti, // For each radio, transmit for (uint32_t i = 0; i < args->nof_radios; i++) { if (tx_enable && !srslte_timestamp_iszero(&tx_time[i])) { + + if (ul_channel) { + ul_channel->run(buffer[i], buffer[i], nof_samples[i], tx_time[i]); + } + radio_h->tx(i, buffer[i], nof_samples[i], tx_time[i]); is_first_of_burst[i] = false; } else { if (radio_h->is_continuous_tx()) { if (!is_first_of_burst[i]) { + + if (ul_channel && !srslte_timestamp_iszero(&tx_time[i])) { + ul_channel->run(buffer[i], buffer[i], nof_samples[i], tx_time[i]); + } + radio_h->tx(i, zeros_multi, nof_samples[i], tx_time[i]); } } else { @@ -588,6 +604,10 @@ void phy_common::worker_end(uint32_t tti, void phy_common::set_cell(const srslte_cell_t& c) { cell = c; + + if (ul_channel) { + ul_channel->set_srate((uint32_t)srslte_sampling_freq_hz(cell.nof_prb)); + } } uint32_t phy_common::get_nof_prb() diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 5a7e78a12..a16af6dcb 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -93,8 +93,7 @@ void sync::init(radio_interface_phy* _radio, } if (worker_com->args->dl_channel_args.enable) { - channel_emulator = srslte::channel_ptr(new srslte::channel( - worker_com->args->dl_channel_args, worker_com->args->nof_rx_ant * worker_com->args->nof_rx_ant)); + channel_emulator = srslte::channel_ptr(new srslte::channel(worker_com->args->dl_channel_args, nof_rf_channels)); } nof_workers = workers_pool->get_nof_workers(); diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 42eb8dca5..8bab35586 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -210,6 +210,16 @@ enable = false #dl.rlf.enable = false #dl.rlf.t_on_ms = 10000 #dl.rlf.t_off_ms = 2000 +#ul.enable = false +#ul.fading.enable = false +#ul.fading.model = none +#ul.delay.enable = false +#ul.delay.period = 3600 +#ul.delay.maximum_us = 100 +#ul.delay.minimum_us = 10 +#ul.rlf.enable = false +#ul.rlf.t_on_ms = 10000 +#ul.rlf.t_off_ms = 2000 ##################################################################### # Expert configuration options