From b3d9a94dd561eb07ed82ef1b851a4a3fefd19f0b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 26 Oct 2020 15:45:21 +0100 Subject: [PATCH] SIDEKIQ: fix tx time protection --- lib/src/phy/rf/rf_skiq_imp.c | 1 + lib/src/phy/rf/rf_skiq_imp_cfg.h | 9 ++++++- lib/src/phy/rf/rf_skiq_imp_port.c | 43 ++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/lib/src/phy/rf/rf_skiq_imp.c b/lib/src/phy/rf/rf_skiq_imp.c index 3d502f100..6497e85ce 100644 --- a/lib/src/phy/rf/rf_skiq_imp.c +++ b/lib/src/phy/rf/rf_skiq_imp.c @@ -898,6 +898,7 @@ int rf_skiq_send_timed_multi(void* h_, if (is_start_of_burst) { if (has_time_spec) { h->next_tstamp = time_to_tstamp(h, secs, frac_secs); + SKIQ_RF_DEBUG("[Tx SOB] ts=%ld\n", h->next_tstamp); } else { h->next_tstamp = rf_skiq_card_read_rf_timestamp(&h->cards[0]); h->next_tstamp += (uint64_t)round(h->current_srate_hz / 10); // increment a 10th of a second diff --git a/lib/src/phy/rf/rf_skiq_imp_cfg.h b/lib/src/phy/rf/rf_skiq_imp_cfg.h index 758a02ea0..aa98c5bd2 100644 --- a/lib/src/phy/rf/rf_skiq_imp_cfg.h +++ b/lib/src/phy/rf/rf_skiq_imp_cfg.h @@ -100,4 +100,11 @@ extern uint32_t rf_skiq_logging_level; } \ } while (false) -#endif // SRSRAN_RF_SKIQ_IMP_CFG_H +#define SKIQ_RF_ERROR(...) \ + do { \ + if (rf_skiq_logging_level >= SKIQ_LOG_ERROR) { \ + fprintf(stdout, "[SKIQ RF ERROR] " __VA_ARGS__); \ + } \ + } while (false) + +#endif // SRSLTE_RF_SKIQ_IMP_CFG_H diff --git a/lib/src/phy/rf/rf_skiq_imp_port.c b/lib/src/phy/rf/rf_skiq_imp_port.c index 592041474..e0376bf23 100644 --- a/lib/src/phy/rf/rf_skiq_imp_port.c +++ b/lib/src/phy/rf/rf_skiq_imp_port.c @@ -84,25 +84,44 @@ static void* writer_thread(void* arg) break; } + // If the ring buffer read resulted in timeout + if (n == SRSRAN_ERROR_TIMEOUT) { + continue; + } + // Ignore blocks with TS=0 - if (q->p_tx_block->timestamp == 0) { + if (p_tx_block->timestamp == 0) { continue; } // Check if the timestamp is the past (this can be caused by sample rate change) - if (last_tx_ts > q->p_tx_block->timestamp) { - skiq_read_curr_tx_timestamp(q->card, q->hdl, &last_tx_ts); - if (last_tx_ts > q->p_tx_block->timestamp) { - ERROR("Tx block (ts=%ld) is in the past (%ld), ignoring\n", q->p_tx_block->timestamp, last_tx_ts); + if (last_tx_ts > p_tx_block->timestamp) { + + // Get current RF timestamp + uint64_t curr_tx_ts = 0UL; + skiq_read_curr_tx_timestamp(q->card, q->hdl, &curr_tx_ts); + + // Avoids giving a block to the FPGA that has already passed, otherwise it could hang forever + if (curr_tx_ts > p_tx_block->timestamp) { + SKIQ_RF_ERROR("[Tx %d:%d block] Tx block (ts=%ld) is in the past (last_tx_ts=%ld, curr_tx_ts=%ld), ignoring\n", + q->card, + (int)q->hdl, + q->p_tx_block->timestamp, + last_tx_ts, + curr_tx_ts); continue; } } - last_tx_ts = q->p_tx_block->timestamp + q->block_size; + last_tx_ts = p_tx_block->timestamp + q->block_size; // If the ring-buffer did not return with error code... if (n > SRSRAN_SUCCESS) { - SKIQ_RF_DEBUG( - "[Tx %d:%d block] ts=%ld; nsamples=%d;\n", q->card, (int)q->hdl, p_tx_block->timestamp, q->block_size); + SKIQ_RF_DEBUG("[Tx %d:%d block] ts=%ld; nsamples=%d; last_tx_ts=%ld;\n", + q->card, + (int)q->hdl, + p_tx_block->timestamp, + q->block_size, + last_tx_ts); if (skiq_transmit(q->card, q->hdl, p_tx_block, NULL) < 0) { ERROR("Error transmitting card %d\n", q->card); @@ -247,7 +266,7 @@ void rf_skiq_tx_port_end_of_burst(rf_skiq_tx_port_t* q) // Write block into the ring-buffer srsran_ringbuffer_write_block(&q->rb, q->p_tx_block, q->p_block_nbytes); - SKIQ_RF_DEBUG("[Tx %d:%d] Padding offset=%d; n=%d; ts=%ld\n", + SKIQ_RF_DEBUG("[Tx EOB %d:%d] Padding offset=%d; n=%d; ts=%ld\n", q->card, (int)q->hdl, q->next_offset, @@ -268,6 +287,11 @@ int rf_skiq_tx_port_send(rf_skiq_tx_port_t* q, const cf_t* buffer, uint32_t nsam return nsamples; } + // If no data and no block has started, early return + if (buffer == NULL && q->next_offset == 0) { + return nsamples; + } + pthread_mutex_lock(&q->mutex); // Calculate destination where IQ shall be stored @@ -390,6 +414,7 @@ int rf_skiq_rx_port_init(rf_skiq_rx_port_t* q, uint8_t card, skiq_rx_hdl_t hdl, void rf_skiq_rx_port_free(rf_skiq_rx_port_t* q) { + srsran_ringbuffer_free(&q->rb); }