diff --git a/lib/include/srslte/phy/channel/channel.h b/lib/include/srslte/phy/channel/channel.h index 2f53f735c..76062658e 100644 --- a/lib/include/srslte/phy/channel/channel.h +++ b/lib/include/srslte/phy/channel/channel.h @@ -24,6 +24,7 @@ #include "delay.h" #include "fading.h" +#include "rlf.h" #include #include #include @@ -46,6 +47,11 @@ public: float delay_min_us = 10; float delay_max_us = 100; uint32_t delay_period_s = 3600; + + // RLF options + bool rlf_enable = false; + uint32_t rlf_t_on_ms = 10000; + uint32_t rlf_t_off_ms = 2000; } args_t; channel(const args_t& channel_args, uint32_t _nof_ports); @@ -56,6 +62,7 @@ public: private: srslte_channel_fading_t* fading[SRSLTE_MAX_PORTS]; srslte_channel_delay_t* delay[SRSLTE_MAX_PORTS]; + srslte_channel_rlf_t* rlf; // RLF has no buffers / no multiple instance is required cf_t* buffer_in = nullptr; cf_t* buffer_out = nullptr; uint32_t nof_ports = 0; diff --git a/lib/include/srslte/phy/channel/rlf.h b/lib/include/srslte/phy/channel/rlf.h new file mode 100644 index 000000000..36e3ee836 --- /dev/null +++ b/lib/include/srslte/phy/channel/rlf.h @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef SRSLTE_RLF_H +#define SRSLTE_RLF_H + +#include +#include + +typedef struct { + uint32_t t_on_ms; + uint32_t t_off_ms; +} srslte_channel_rlf_t; + +#ifdef __cplusplus +extern "C" { +#endif + +SRSLTE_API void srslte_channel_rlf_init(srslte_channel_rlf_t* q, uint32_t t_on_ms, uint32_t t_off_ms); + +SRSLTE_API void srslte_channel_rlf_execute( + srslte_channel_rlf_t* q, const cf_t* in, cf_t* out, uint32_t nsamples, const srslte_timestamp_t* ts); + +SRSLTE_API void srslte_channel_rlf_free(srslte_channel_rlf_t* q); + +#ifdef __cplusplus +} +#endif + +#endif // SRSLTE_RLF_H diff --git a/lib/src/phy/channel/channel.cc b/lib/src/phy/channel/channel.cc index ea6eaef6b..dcf4a8709 100644 --- a/lib/src/phy/channel/channel.cc +++ b/lib/src/phy/channel/channel.cc @@ -62,6 +62,11 @@ channel::channel(const channel::args_t& channel_args, uint32_t _nof_ports) } } + if (channel_args.rlf_enable && ret == SRSLTE_SUCCESS) { + rlf = (srslte_channel_rlf_t*)calloc(sizeof(srslte_channel_rlf_t), 1); + srslte_channel_rlf_init(rlf, channel_args.rlf_t_on_ms, channel_args.rlf_t_off_ms); + } + if (ret != SRSLTE_SUCCESS) { fprintf(stderr, "Error: Creating channel\n\n"); } @@ -77,6 +82,11 @@ channel::~channel() free(buffer_out); } + if (rlf) { + srslte_channel_rlf_free(rlf); + free(rlf); + } + for (uint32_t i = 0; i < nof_ports; i++) { if (fading[i]) { srslte_channel_fading_free(fading[i]); @@ -107,6 +117,11 @@ void channel::run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint3 memcpy(buffer_in, buffer_out, sizeof(cf_t) * len); } + if (rlf) { + srslte_channel_rlf_execute(rlf, buffer_in, buffer_out, len, &t); + memcpy(buffer_in, buffer_out, sizeof(cf_t) * len); + } + // Copy output buffer memcpy(out[i], buffer_out, sizeof(cf_t) * len); } diff --git a/lib/src/phy/channel/rlf.c b/lib/src/phy/channel/rlf.c new file mode 100644 index 000000000..bc304f48e --- /dev/null +++ b/lib/src/phy/channel/rlf.c @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include +#include + +void srslte_channel_rlf_init(srslte_channel_rlf_t* q, uint32_t t_on_ms, uint32_t t_off_ms) +{ + q->t_on_ms = t_on_ms; + q->t_off_ms = t_off_ms; +} + +void srslte_channel_rlf_execute( + srslte_channel_rlf_t* q, const cf_t* in, cf_t* out, uint32_t nsamples, const srslte_timestamp_t* ts) +{ + uint32_t period_ms = q->t_on_ms + q->t_off_ms; + double full_secs_ms = (ts->full_secs * 1000) % period_ms; + double frac_secs_ms = (ts->frac_secs * 1000); + double time_ms = full_secs_ms + frac_secs_ms; + + if (time_ms < q->t_on_ms) { + srslte_vec_sc_prod_cfc(in, 1.0f, out, nsamples); + } else { + srslte_vec_sc_prod_cfc(in, 0.0f, out, nsamples); + } +} + +void srslte_channel_rlf_free(srslte_channel_rlf_t* q) +{ + // Do nothing +} \ No newline at end of file diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 11e5690f8..caf4c9af2 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -28,8 +28,6 @@ extern "C" { #include #include -uint32_t zero_tti = 0; - namespace srslte { bool radio::init(log_filter* _log_h, char* args, char* devname, uint32_t nof_channels) @@ -149,26 +147,18 @@ bool radio::rx_now(cf_t* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_ { bool ret = true; - if (!radio_is_streaming) { - srslte_rf_start_rx_stream(&rf_device, false); - radio_is_streaming = true; - } + if (!radio_is_streaming) { + srslte_rf_start_rx_stream(&rf_device, false); + radio_is_streaming = true; + } - time_t* full_secs = rxd_time ? &rxd_time->full_secs : NULL; - double* frac_secs = rxd_time ? &rxd_time->frac_secs : NULL; + time_t* full_secs = rxd_time ? &rxd_time->full_secs : NULL; + double* frac_secs = rxd_time ? &rxd_time->frac_secs : NULL; - if (srslte_rf_recv_with_time_multi(&rf_device, (void**)buffer, nof_samples, true, full_secs, frac_secs) > 0) { - ret = true; - } else { - ret = false; - } - - if (zero_tti) { - bzero(buffer[0], sizeof(cf_t) * nof_samples); - zero_tti--; - if (!zero_tti) { - printf("-- end of zeros\n"); - } + if (srslte_rf_recv_with_time_multi(&rf_device, (void**)buffer, nof_samples, true, full_secs, frac_secs) > 0) { + ret = true; + } else { + ret = false; } return ret; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 0977f4574..5c3463283 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -40,7 +40,6 @@ #include "srslte/common/metrics_hub.h" #include "srslte/version.h" -extern uint32_t zero_tti; extern bool simulate_rlf; using namespace std; @@ -151,10 +150,13 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("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)") - ("channel.dl.delay.enable", bpo::value(&args->phy.dl_channel_args.delay_enable)->default_value(false), "Enable/Disable Delay simulator") - ("channel.dl.delay.period", bpo::value(&args->phy.dl_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)") - ("channel.dl.delay.maximum_us", bpo::value(&args->phy.dl_channel_args.delay_max_us)->default_value(100.0f), "Maximum delay in microseconds") - ("channel.dl.delay.minimum_us", bpo::value(&args->phy.dl_channel_args.delay_min_us)->default_value(10.0f), "Minimum delay in microseconds") + ("channel.dl.delay.enable", bpo::value(&args->phy.dl_channel_args.delay_enable)->default_value(false), "Enable/Disable Delay simulator") + ("channel.dl.delay.period", bpo::value(&args->phy.dl_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)") + ("channel.dl.delay.maximum_us", bpo::value(&args->phy.dl_channel_args.delay_max_us)->default_value(100.0f), "Maximum delay in microseconds") + ("channel.dl.delay.minimum_us", bpo::value(&args->phy.dl_channel_args.delay_min_us)->default_value(10.0f), "Minimum delay in microseconds") + ("channel.dl.rlf.enable", bpo::value(&args->phy.dl_channel_args.rlf_enable)->default_value(false), "Enable/Disable Radio-Link Failure simulator") + ("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)") /* Expert section */ ("expert.phy.worker_cpu_mask", @@ -480,9 +482,6 @@ void* input_loop(void* m) } else if (0 == key.compare("rlf")) { simulate_rlf = true; cout << "Sending Radio Link Failure" << endl; - } else if (0 == key.find("zeros ")) { - zero_tti = std::stoi(key.substr(6)); - cout << "Receiving zeros for " << zero_tti << " ms" << endl; } else if (0 == key.compare("q")) { running = false; } diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 918793d24..bd6659bb8 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -193,6 +193,11 @@ enable = false # dl.delay.period: Delay period in seconds (integer). # dl.delay.maximum_us: Maximum delay in microseconds # dl.delay.minumum_us: Minimum delay in microseconds +# +# -- Radio-Link Failure (RLF) Emulator +# dl.rlf.enable: Enable/disable RLF simulator +# dl.rlf.t_on_ms: Time for On state of the channel (ms) +# dl.rlf.t_off_ms: Time for Off state of the channel (ms) ##################################################################### [channel] #dl.enable = false @@ -202,6 +207,9 @@ enable = false #dl.delay.period = 3600 #dl.delay.maximum_us = 100 #dl.delay.minimum_us = 10 +#dl.rlf.enable = false +#dl.rlf.t_on_ms = 10000 +#dl.rlf.t_off_ms = 2000 ##################################################################### # Expert configuration options