SRSUE: Created delay channel emulator and added fading to the UE
This commit is contained in:
parent
709e769d0d
commit
9ab2b2de81
|
@ -35,6 +35,7 @@
|
|||
#include "srslte/common/common.h"
|
||||
#include "srslte/common/interfaces_common.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srslte/phy/channel/channel.h"
|
||||
#include "srslte/phy/rf/rf.h"
|
||||
#include "srslte/upper/rlc_interface.h"
|
||||
|
||||
|
@ -758,6 +759,7 @@ typedef struct {
|
|||
uint32_t intra_freq_meas_len_ms;
|
||||
uint32_t intra_freq_meas_period_ms;
|
||||
bool pregenerate_signals;
|
||||
srslte::channel::args_t dl_channel_args;
|
||||
} phy_args_t;
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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_CHANNEL_H
|
||||
#define SRSLTE_CHANNEL_H
|
||||
|
||||
#include "delay.h"
|
||||
#include "fading.h"
|
||||
#include <srslte/config.h>
|
||||
#include <srslte/srslte.h>
|
||||
#include <string>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class channel
|
||||
{
|
||||
public:
|
||||
typedef struct {
|
||||
// General
|
||||
bool enable = false;
|
||||
|
||||
// Fading options
|
||||
std::string fading_model = "";
|
||||
|
||||
// Delay options
|
||||
float delay_min_us = 0;
|
||||
float delay_max_us = 0;
|
||||
uint32_t delay_period_s = 0;
|
||||
} args_t;
|
||||
|
||||
channel(const args_t& channel_args, uint32_t _nof_ports);
|
||||
~channel();
|
||||
void set_srate(uint32_t srate);
|
||||
void run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint32_t len, const srslte_timestamp_t& t);
|
||||
|
||||
private:
|
||||
srslte_channel_fading_t* fading[SRSLTE_MAX_PORTS];
|
||||
srslte_channel_delay_t* delay[SRSLTE_MAX_PORTS];
|
||||
cf_t* buffer_in = nullptr;
|
||||
cf_t* buffer_out = nullptr;
|
||||
uint32_t nof_ports = 0;
|
||||
uint32_t current_srate = 0;
|
||||
args_t args;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
#endif // SRSLTE_CHANNEL_H
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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_DELAY_H
|
||||
#define SRSLTE_DELAY_H
|
||||
|
||||
#include <srslte/config.h>
|
||||
#include <srslte/phy/common/timestamp.h>
|
||||
#include <srslte/phy/utils/ringbuffer.h>
|
||||
|
||||
typedef struct {
|
||||
float delay_min_us;
|
||||
float delay_max_us;
|
||||
uint32_t period_s;
|
||||
uint32_t srate_max_hz;
|
||||
uint32_t srate_hz;
|
||||
|
||||
srslte_ringbuffer_t rb;
|
||||
cf_t* zero_buffer;
|
||||
} srslte_channel_delay_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SRSLTE_API int srslte_channel_delay_init(
|
||||
srslte_channel_delay_t* q, float delay_min_ns, float delay_max_ns, uint32_t period_s, uint32_t srate_max_hz);
|
||||
|
||||
SRSLTE_API void srslte_channel_delay_update_srate(srslte_channel_delay_t* q, uint32_t srate_hz);
|
||||
|
||||
SRSLTE_API void srslte_channel_delay_free(srslte_channel_delay_t* q);
|
||||
|
||||
SRSLTE_API void srslte_channel_delay_execute(
|
||||
srslte_channel_delay_t* q, const cf_t* in, cf_t* out, uint32_t len, const srslte_timestamp_t* ts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SRSLTE_DELAY_H
|
|
@ -58,6 +58,10 @@ typedef struct {
|
|||
cf_t* state; // Length fft_size/2
|
||||
} srslte_channel_fading_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SRSLTE_API int srslte_channel_fading_init(srslte_channel_fading_t* q, double srate, const char* model, uint32_t seed);
|
||||
|
||||
SRSLTE_API void srslte_channel_fading_free(srslte_channel_fading_t* q);
|
||||
|
@ -65,4 +69,8 @@ SRSLTE_API void srslte_channel_fading_free(srslte_channel_fading_t* q);
|
|||
SRSLTE_API double srslte_channel_fading_execute(
|
||||
srslte_channel_fading_t* q, const cf_t* in, cf_t* out, uint32_t nof_samples, double init_time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SRSLTE_FADING_H
|
||||
|
|
|
@ -42,24 +42,21 @@ typedef struct SRSLTE_API{
|
|||
double frac_secs;
|
||||
}srslte_timestamp_t;
|
||||
|
||||
SRSLTE_API int srslte_timestamp_init(srslte_timestamp_t *t,
|
||||
time_t full_secs,
|
||||
double frac_secs);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SRSLTE_API int srslte_timestamp_init(srslte_timestamp_t* t, time_t full_secs, double frac_secs);
|
||||
|
||||
SRSLTE_API void srslte_timestamp_init_uint64(srslte_timestamp_t* ts_time, uint64_t ts_count, double base_srate);
|
||||
|
||||
SRSLTE_API int srslte_timestamp_copy(srslte_timestamp_t *dest,
|
||||
srslte_timestamp_t *src);
|
||||
SRSLTE_API int srslte_timestamp_copy(srslte_timestamp_t* dest, srslte_timestamp_t* src);
|
||||
|
||||
SRSLTE_API int srslte_timestamp_compare(srslte_timestamp_t* a, srslte_timestamp_t* b);
|
||||
|
||||
SRSLTE_API int srslte_timestamp_add(srslte_timestamp_t *t,
|
||||
time_t full_secs,
|
||||
double frac_secs);
|
||||
SRSLTE_API int srslte_timestamp_add(srslte_timestamp_t* t, time_t full_secs, double frac_secs);
|
||||
|
||||
SRSLTE_API int srslte_timestamp_sub(srslte_timestamp_t *t,
|
||||
time_t full_secs,
|
||||
double frac_secs);
|
||||
SRSLTE_API int srslte_timestamp_sub(srslte_timestamp_t* t, time_t full_secs, double frac_secs);
|
||||
|
||||
SRSLTE_API double srslte_timestamp_real(srslte_timestamp_t *t);
|
||||
|
||||
|
@ -69,4 +66,8 @@ SRSLTE_API uint32_t srslte_timestamp_uint32(srslte_timestamp_t *t);
|
|||
|
||||
SRSLTE_API uint64_t srslte_timestamp_uint64(const srslte_timestamp_t* t, double srate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SRSLTE_TIMESTAMP_H
|
||||
|
|
|
@ -30,38 +30,40 @@
|
|||
typedef struct {
|
||||
uint8_t *buffer;
|
||||
bool active;
|
||||
int capacity;
|
||||
int count;
|
||||
int wpm;
|
||||
int rpm;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cvar;
|
||||
} srslte_ringbuffer_t;
|
||||
int capacity;
|
||||
int count;
|
||||
int wpm;
|
||||
int rpm;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cvar;
|
||||
} srslte_ringbuffer_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SRSLTE_API int srslte_ringbuffer_init(srslte_ringbuffer_t *q,
|
||||
int capacity);
|
||||
SRSLTE_API int srslte_ringbuffer_init(srslte_ringbuffer_t* q, int capacity);
|
||||
|
||||
SRSLTE_API void srslte_ringbuffer_free(srslte_ringbuffer_t *q);
|
||||
|
||||
SRSLTE_API void srslte_ringbuffer_reset(srslte_ringbuffer_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ringbuffer_status(srslte_ringbuffer_t *q);
|
||||
SRSLTE_API int srslte_ringbuffer_status(srslte_ringbuffer_t* q);
|
||||
|
||||
SRSLTE_API int srslte_ringbuffer_space(srslte_ringbuffer_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ringbuffer_write(srslte_ringbuffer_t *q,
|
||||
void *ptr,
|
||||
int nof_bytes);
|
||||
SRSLTE_API int srslte_ringbuffer_write(srslte_ringbuffer_t* q, void* ptr, int nof_bytes);
|
||||
|
||||
SRSLTE_API int srslte_ringbuffer_read(srslte_ringbuffer_t *q,
|
||||
void *ptr,
|
||||
int nof_bytes);
|
||||
SRSLTE_API int srslte_ringbuffer_read(srslte_ringbuffer_t* q, void* ptr, int nof_bytes);
|
||||
|
||||
SRSLTE_API int srslte_ringbuffer_read_timed(srslte_ringbuffer_t* q, void* p, int nof_bytes, uint32_t timeout_ms);
|
||||
|
||||
SRSLTE_API void srslte_ringbuffer_stop(srslte_ringbuffer_t *q);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SRSLTE_RINGBUFFER_H
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
file(GLOB SOURCES "*.c")
|
||||
file(GLOB SOURCES "*.c" "*.cc")
|
||||
add_library(srslte_channel OBJECT ${SOURCES})
|
||||
|
||||
add_subdirectory(test)
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 <cstdlib>
|
||||
#include <srslte/phy/channel/channel.h>
|
||||
#include <srslte/srslte.h>
|
||||
|
||||
using namespace srslte;
|
||||
|
||||
channel::channel(const channel::args_t& channel_args, uint32_t _nof_ports)
|
||||
{
|
||||
int ret = SRSLTE_SUCCESS;
|
||||
uint32_t srate_max = (uint32_t)srslte_symbol_sz(SRSLTE_MAX_PRB) * 15000;
|
||||
uint32_t buffer_size = (uint32_t)SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB) * 5; // be safe, 5 Subframes
|
||||
|
||||
// Copy args
|
||||
args = channel_args;
|
||||
|
||||
// Allocate internal buffers
|
||||
buffer_in = (cf_t*)srslte_vec_malloc(sizeof(cf_t) * buffer_size);
|
||||
buffer_out = (cf_t*)srslte_vec_malloc(sizeof(cf_t) * buffer_size);
|
||||
if (!buffer_out || !buffer_in) {
|
||||
ret = SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
nof_ports = _nof_ports;
|
||||
for (uint32_t i = 0; i < nof_ports; i++) {
|
||||
// Create fading channel
|
||||
if (!channel_args.fading_model.empty() && channel_args.fading_model != "none" && ret == SRSLTE_SUCCESS) {
|
||||
fading[i] = (srslte_channel_fading_t*)calloc(sizeof(srslte_channel_fading_t), 1);
|
||||
ret = srslte_channel_fading_init(fading[i], srate_max, channel_args.fading_model.c_str(), 0x1234 * i);
|
||||
} else {
|
||||
fading[i] = nullptr;
|
||||
}
|
||||
|
||||
// Create delay
|
||||
if (channel_args.delay_period_s && ret == SRSLTE_SUCCESS) {
|
||||
delay[i] = (srslte_channel_delay_t*)calloc(sizeof(srslte_channel_delay_t), 1);
|
||||
ret = srslte_channel_delay_init(
|
||||
delay[i], channel_args.delay_min_us, channel_args.delay_max_us, channel_args.delay_period_s, srate_max);
|
||||
} else {
|
||||
delay[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != SRSLTE_SUCCESS) {
|
||||
fprintf(stderr, "Error: Creating channel\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
channel::~channel()
|
||||
{
|
||||
if (buffer_in) {
|
||||
free(buffer_in);
|
||||
}
|
||||
|
||||
if (buffer_out) {
|
||||
free(buffer_out);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < nof_ports; i++) {
|
||||
if (fading[i]) {
|
||||
srslte_channel_fading_free(fading[i]);
|
||||
free(fading[i]);
|
||||
}
|
||||
|
||||
if (delay[i]) {
|
||||
srslte_channel_delay_free(delay[i]);
|
||||
free(delay[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void channel::run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint32_t len, const srslte_timestamp_t& t)
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < nof_ports; i++) {
|
||||
// Copy input buffer
|
||||
memcpy(buffer_in, in[i], sizeof(cf_t) * len);
|
||||
|
||||
if (fading[i]) {
|
||||
srslte_channel_fading_execute(fading[i], buffer_in, buffer_out, len, t.full_secs + t.frac_secs);
|
||||
memcpy(buffer_in, buffer_out, sizeof(cf_t) * len);
|
||||
}
|
||||
|
||||
if (delay[i]) {
|
||||
srslte_channel_delay_execute(delay[i], 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);
|
||||
}
|
||||
}
|
||||
|
||||
void channel::set_srate(uint32_t srate)
|
||||
{
|
||||
if (current_srate != srate) {
|
||||
for (uint32_t i = 0; i < nof_ports; i++) {
|
||||
if (fading[i]) {
|
||||
srslte_channel_fading_free(fading[i]);
|
||||
|
||||
srslte_channel_fading_init(fading[i], srate, args.fading_model.c_str(), 0x1234 * i);
|
||||
}
|
||||
|
||||
if (delay[i]) {
|
||||
srslte_channel_delay_update_srate(delay[i], srate);
|
||||
}
|
||||
current_srate = srate;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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 <math.h>
|
||||
#include <srslte/phy/channel/delay.h>
|
||||
#include <srslte/srslte.h>
|
||||
|
||||
static inline double caulculate_delay_us(srslte_channel_delay_t* q, const srslte_timestamp_t* ts)
|
||||
{
|
||||
uint32_t mod_secs = (uint32_t)(ts->full_secs % q->period_s);
|
||||
double arg = 2.0 * M_PI * ((double)mod_secs + ts->frac_secs) / (double)q->period_s;
|
||||
double delay_us = q->delay_min_us + (q->delay_max_us - q->delay_min_us) * (1.0 + sin(arg)) / 2.0;
|
||||
|
||||
return delay_us;
|
||||
}
|
||||
|
||||
static inline uint32_t caulculate_delay_nsamples(srslte_channel_delay_t* q, double delay_us)
|
||||
{
|
||||
return (uint32_t)round(delay_us * (double)q->srate_hz / 1e6);
|
||||
}
|
||||
|
||||
static inline uint32_t ringbuffer_available_nsamples(srslte_channel_delay_t* q)
|
||||
{
|
||||
return srslte_ringbuffer_status(&q->rb) / sizeof(cf_t);
|
||||
}
|
||||
|
||||
int srslte_channel_delay_init(
|
||||
srslte_channel_delay_t* q, float delay_min_us, float delay_max_us, uint32_t period_s, uint32_t srate_max_hz)
|
||||
{
|
||||
// Calculate buffer size
|
||||
uint32_t buff_size = (uint32_t)ceilf(delay_max_us * (float)srate_max_hz);
|
||||
|
||||
// Create ring buffer
|
||||
int ret = srslte_ringbuffer_init(&q->rb, sizeof(cf_t) * buff_size);
|
||||
|
||||
// Create zero buffer
|
||||
q->zero_buffer = srslte_vec_malloc(sizeof(cf_t) * buff_size);
|
||||
if (!q->zero_buffer) {
|
||||
ret = SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Load initial parameters
|
||||
q->delay_min_us = delay_min_us;
|
||||
q->delay_max_us = delay_max_us;
|
||||
q->srate_max_hz = srate_max_hz;
|
||||
q->srate_hz = srate_max_hz;
|
||||
q->period_s = period_s;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_channel_delay_update_srate(srslte_channel_delay_t* q, uint32_t srate_hz)
|
||||
{
|
||||
srslte_ringbuffer_reset(&q->rb);
|
||||
q->srate_hz = srate_hz;
|
||||
}
|
||||
|
||||
void srslte_channel_delay_free(srslte_channel_delay_t* q)
|
||||
{
|
||||
srslte_ringbuffer_free(&q->rb);
|
||||
|
||||
if (q->zero_buffer) {
|
||||
free(q->zero_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_channel_delay_execute(
|
||||
srslte_channel_delay_t* q, const cf_t* in, cf_t* out, uint32_t len, const srslte_timestamp_t* ts)
|
||||
{
|
||||
double delay_us = caulculate_delay_us(q, ts);
|
||||
uint32_t delay_nsamples = caulculate_delay_nsamples(q, delay_us);
|
||||
uint32_t available_nsamples = ringbuffer_available_nsamples(q);
|
||||
uint32_t read_nsamples = SRSLTE_MIN(delay_nsamples, len);
|
||||
uint32_t copy_nsamples = (len > read_nsamples) ? (len - read_nsamples) : 0;
|
||||
|
||||
if (available_nsamples < delay_nsamples) {
|
||||
uint32_t nzeros = delay_nsamples - available_nsamples;
|
||||
bzero(q->zero_buffer, sizeof(cf_t) * nzeros);
|
||||
srslte_ringbuffer_write(&q->rb, q->zero_buffer, sizeof(cf_t) * nzeros);
|
||||
} else if (available_nsamples > delay_nsamples) {
|
||||
srslte_ringbuffer_read(&q->rb, q->zero_buffer, sizeof(cf_t) * (available_nsamples - delay_nsamples));
|
||||
}
|
||||
|
||||
// Read buffered samples
|
||||
srslte_ringbuffer_read(&q->rb, out, sizeof(cf_t) * read_nsamples);
|
||||
|
||||
// Read other samples
|
||||
if (copy_nsamples) {
|
||||
memcpy(&out[read_nsamples], in, sizeof(cf_t) * copy_nsamples);
|
||||
}
|
||||
|
||||
// Write new sampels
|
||||
srslte_ringbuffer_write(&q->rb, (void*)&in[copy_nsamples], sizeof(cf_t) * read_nsamples);
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <pthread.h>
|
||||
#include <srslte/phy/channel/channel.h>
|
||||
|
||||
#include "async_scell_recv.h"
|
||||
#include "phy_common.h"
|
||||
|
@ -281,6 +282,7 @@ private:
|
|||
phy_common* worker_com;
|
||||
prach* prach_buffer;
|
||||
async_scell_recv_vector* scell_sync;
|
||||
srslte::channel* channel_emulator = nullptr;
|
||||
|
||||
// Object for synchronization of the primary cell
|
||||
srslte_ue_sync_t ue_sync;
|
||||
|
|
|
@ -147,6 +147,13 @@ void parse_args(all_args_t* args, int argc, char* argv[])
|
|||
("gw.ip_devname", bpo::value<string>(&args->stack.gw.tun_dev_name)->default_value("tun_srsue"), "Name of the tun_srsue device")
|
||||
("gw.ip_netmask", bpo::value<string>(&args->stack.gw.tun_dev_netmask)->default_value("255.255.255.0"), "Netmask of the tun_srsue device")
|
||||
|
||||
/* Channel emulator section */
|
||||
("channel.dl.enable", bpo::value<bool>(&args->phy.dl_channel_args.enable)->default_value(false), "Enable/Disable internal Downlink channel emulator")
|
||||
("channel.dl.fading_model", bpo::value<std::string>(&args->phy.dl_channel_args.fading_model)->default_value("none"), "Fading model (none, EPA5, EVA70, ETU300, etc)")
|
||||
("channel.dl.delay_period", bpo::value<uint32_t >(&args->phy.dl_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)")
|
||||
("channel.dl.delay_maximum_us", bpo::value<float >(&args->phy.dl_channel_args.delay_max_us)->default_value(100.0f), "Maximum delay in microseconds")
|
||||
("channel.dl.delay_minimum_us", bpo::value<float >(&args->phy.dl_channel_args.delay_min_us)->default_value(0.0f), "Maximum delay in microseconds")
|
||||
|
||||
/* Expert section */
|
||||
("expert.phy.worker_cpu_mask",
|
||||
bpo::value<int>(&args->phy.worker_cpu_mask)->default_value(-1),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "srsue/hdr/phy/sync.h"
|
||||
#include "srslte/common/log.h"
|
||||
#include "srslte/phy/channel/channel.h"
|
||||
#include "srslte/srslte.h"
|
||||
#include "srsue/hdr/phy/sf_worker.h"
|
||||
#include <algorithm>
|
||||
|
@ -91,6 +92,11 @@ void sync::init(radio_interface_phy* _radio,
|
|||
return;
|
||||
}
|
||||
|
||||
if (worker_com->args->dl_channel_args.enable) {
|
||||
channel_emulator = new srslte::channel(worker_com->args->dl_channel_args,
|
||||
worker_com->args->nof_rx_ant * worker_com->args->nof_rx_ant);
|
||||
}
|
||||
|
||||
nof_workers = workers_pool->get_nof_workers();
|
||||
worker_com->set_nof_workers(nof_workers);
|
||||
|
||||
|
@ -128,6 +134,11 @@ sync::~sync()
|
|||
}
|
||||
pthread_mutex_destroy(&rrc_mutex);
|
||||
srslte_ue_sync_free(&ue_sync);
|
||||
|
||||
// Destroy channel emulator if created
|
||||
if (channel_emulator) {
|
||||
delete channel_emulator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -925,6 +936,11 @@ void sync::get_current_cell(srslte_cell_t* cell, uint32_t* earfcn)
|
|||
int sync::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time)
|
||||
{
|
||||
if (radio_h->rx_now(0, data, nsamples, rx_time)) {
|
||||
if (channel_emulator && rx_time) {
|
||||
channel_emulator->set_srate(current_srate);
|
||||
channel_emulator->run(data, data, nsamples, *rx_time);
|
||||
}
|
||||
|
||||
int offset = nsamples - current_sflen;
|
||||
if (abs(offset) < 10 && offset != 0) {
|
||||
next_radio_offset[0] = offset;
|
||||
|
|
|
@ -179,6 +179,25 @@ imei = 353490069873319
|
|||
[gui]
|
||||
enable = false
|
||||
|
||||
#####################################################################
|
||||
# Channel emulator options:
|
||||
# dl.enable: Enable/Disable internal Downlink channel emulator
|
||||
#
|
||||
# -- Fading emulator
|
||||
# dl.fading_model: Fading model (none, EPA5, EVA70, ETU300, etc)
|
||||
#
|
||||
# -- Delay Emulator: d(t) = d_min + (d_max - d_min) * sin(2pi*t/period) / 2
|
||||
# dl.delay_period: Delay period in seconds (integer).
|
||||
# dl.delay_maximum_us: Maximum delay in microseconds
|
||||
# dl.delay_minumum_us: Minimum delay in microseconds
|
||||
#####################################################################
|
||||
[channel]
|
||||
#dl.enable = false
|
||||
#dl.fading_model = none
|
||||
#dl.delay_period = 3600
|
||||
#dl.delay_maximum_us = 100
|
||||
#dl.delay_minimum_us = 10
|
||||
|
||||
#####################################################################
|
||||
# Expert configuration options
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue