diff --git a/lib/src/phy/rf/rf_helper.h b/lib/src/phy/rf/rf_helper.h index 980abfe7d..9d5cba450 100644 --- a/lib/src/phy/rf/rf_helper.h +++ b/lib/src/phy/rf/rf_helper.h @@ -118,4 +118,17 @@ static inline int parse_uint32(char* args, const char* config_arg_base, int chan return ret; } +static inline int parse_int32(char* args, const char* config_arg_base, int channel_index, int32_t* value) +{ + char tmp_value[RF_PARAM_LEN] = {0}; + int ret = parse_string(args, config_arg_base, channel_index, tmp_value); + + // Copy parsed value only if was found, otherwise it keeps the default + if (ret == SRSLTE_SUCCESS) { + *value = (int32_t)strtof(tmp_value, NULL); + } + + return ret; +} + #endif /* SRSLTE_RF_HELPER_H_ */ diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index f2afd98e7..f27e28fc4 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -286,10 +286,8 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) } for (int i = 0; i < handler->nof_channels; i++) { - char rx_port[RF_PARAM_LEN] = {}; - char tx_port[RF_PARAM_LEN] = {}; - // rx_port + char rx_port[RF_PARAM_LEN] = {}; parse_string(args, "rx_port", i, rx_port); // rx_freq @@ -297,7 +295,11 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) parse_double(args, "rx_freq", i, &rx_freq); rx_opts.frequency_mhz = (uint32_t)(rx_freq / 1e6); + // rx_offset + parse_int32(args, "rx_offset", i, &rx_opts.sample_offset); + // tx_port + char tx_port[RF_PARAM_LEN] = {}; parse_string(args, "tx_port", i, tx_port); // tx_freq diff --git a/lib/src/phy/rf/rf_zmq_imp_rx.c b/lib/src/phy/rf/rf_zmq_imp_rx.c index 75d504e8e..ed325116f 100644 --- a/lib/src/phy/rf/rf_zmq_imp_rx.c +++ b/lib/src/phy/rf/rf_zmq_imp_rx.c @@ -108,6 +108,7 @@ int rf_zmq_rx_open(rf_zmq_rx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock q->sample_format = opts.sample_format; q->frequency_mhz = opts.frequency_mhz; q->fail_on_disconnect = opts.fail_on_disconnect; + q->sample_offset = opts.sample_offset; if (opts.socket_type == ZMQ_SUB) { zmq_setsockopt(q->sock, ZMQ_SUBSCRIBE, "", 0); @@ -201,6 +202,27 @@ int rf_zmq_rx_baseband(rf_zmq_rx_t* q, cf_t* buffer, uint32_t nsamples) sample_sz = 2 * sizeof(short); } + // If the read needs to be delayed + while (q->sample_offset > 0) { + uint32_t n_offset = SRSLTE_MIN(q->sample_offset, NBYTES2NSAMPLES(ZMQ_MAX_BUFFER_SIZE)); + srslte_vec_zero(q->temp_buffer, n_offset); + int n = srslte_ringbuffer_write(&q->ringbuffer, q->temp_buffer, (int)(n_offset * sample_sz)); + if (n < SRSLTE_SUCCESS) { + return n; + } + q->sample_offset -= n_offset; + } + + // If the read needs to be advanced + while (q->sample_offset < 0) { + uint32_t n_offset = SRSLTE_MIN(-q->sample_offset, NBYTES2NSAMPLES(ZMQ_MAX_BUFFER_SIZE)); + int n = srslte_ringbuffer_read_timed(&q->ringbuffer, q->temp_buffer, (int)(n_offset * sample_sz), ZMQ_TIMEOUT_MS); + if (n < SRSLTE_SUCCESS) { + return n; + } + q->sample_offset += n_offset; + } + int n = srslte_ringbuffer_read_timed(&q->ringbuffer, dst_buffer, sample_sz * nsamples, ZMQ_TIMEOUT_MS); if (n < 0) { return n; diff --git a/lib/src/phy/rf/rf_zmq_imp_trx.h b/lib/src/phy/rf/rf_zmq_imp_trx.h index 049a8f0e8..e4b48a6f7 100644 --- a/lib/src/phy/rf/rf_zmq_imp_trx.h +++ b/lib/src/phy/rf/rf_zmq_imp_trx.h @@ -62,6 +62,7 @@ typedef struct { void* temp_buffer_convert; uint32_t frequency_mhz; bool fail_on_disconnect; + int32_t sample_offset; } rf_zmq_rx_t; typedef struct { @@ -70,6 +71,7 @@ typedef struct { rf_zmq_format_t sample_format; uint32_t frequency_mhz; bool fail_on_disconnect; + int32_t sample_offset; ///< offset in samples } rf_zmq_opts_t; /*