Fix a data race in the UHD class wrapper where the last error member was being set concurrently causing random crashes.

Introduce a new macro to catch UHD exceptions and log them directly instead of storing an error string, similar to what errno does.

Remove usrp logging helpers that depend on the now removed member since all calls potentially log the error directly.
master
faluco 4 years ago committed by Andre Puschmann
parent 8087bb01e4
commit a70ad58440

@ -33,18 +33,18 @@ private:
Debug("Making USRP object with args '" << dev_addr.to_string() << "'");
UHD_SAFE_C_SAVE_ERROR(this, usrp = uhd::usrp::multi_usrp::make(dev_addr);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp = uhd::usrp::multi_usrp::make(dev_addr);)
}
uhd_error set_tx_subdev(const std::string& string)
{
Info("Setting tx_subdev_spec to '" << string << "'");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_tx_subdev_spec(string);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_tx_subdev_spec(string);)
}
uhd_error set_rx_subdev(const std::string& string)
{
Info("Setting rx_subdev_spec to '" << string << "'");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_rx_subdev_spec(string);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_rx_subdev_spec(string);)
}
uhd_error test_ad936x_device(uint32_t nof_channels)
@ -92,7 +92,7 @@ private:
}
if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) {
last_error = md.strerror();
Error(md.strerror());
return UHD_ERROR_IO;
}
@ -236,9 +236,8 @@ public:
// Otherwise, close USRP and open again
usrp = nullptr;
Warning("Failed to open Rx stream '" << last_error << "', trying to open device again. " << ntrials
<< " trials left. Waiting for " << FE_RX_RESET_SLEEP_TIME_MS.count()
<< " ms");
Warning("Failed to open Rx stream, trying to open device again. "
<< ntrials << " trials left. Waiting for " << FE_RX_RESET_SLEEP_TIME_MS.count() << " ms");
// Sleep
std::this_thread::sleep_for(FE_RX_RESET_SLEEP_TIME_MS);
@ -254,103 +253,101 @@ public:
uhd_error get_mboard_name(std::string& mboard_name) override
{
UHD_SAFE_C_SAVE_ERROR(this, mboard_name = usrp->get_mboard_name();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(mboard_name = usrp->get_mboard_name();)
}
uhd_error get_mboard_sensor_names(std::vector<std::string>& sensors) override
{
UHD_SAFE_C_SAVE_ERROR(this, sensors = usrp->get_mboard_sensor_names();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(sensors = usrp->get_mboard_sensor_names();)
}
uhd_error get_rx_sensor_names(std::vector<std::string>& sensors) override
{
UHD_SAFE_C_SAVE_ERROR(this, sensors = usrp->get_rx_sensor_names();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(sensors = usrp->get_rx_sensor_names();)
}
uhd_error get_sensor(const std::string& sensor_name, double& sensor_value) override
{
UHD_SAFE_C_SAVE_ERROR(this, sensor_value = usrp->get_mboard_sensor(sensor_name).to_real();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(sensor_value = usrp->get_mboard_sensor(sensor_name).to_real();)
}
uhd_error get_sensor(const std::string& sensor_name, bool& sensor_value) override
{
UHD_SAFE_C_SAVE_ERROR(this, sensor_value = usrp->get_mboard_sensor(sensor_name).to_bool();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(sensor_value = usrp->get_mboard_sensor(sensor_name).to_bool();)
}
uhd_error get_rx_sensor(const std::string& sensor_name, bool& sensor_value) override
{
UHD_SAFE_C_SAVE_ERROR(this, sensor_value = usrp->get_rx_sensor(sensor_name).to_bool();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(sensor_value = usrp->get_rx_sensor(sensor_name).to_bool();)
}
uhd_error set_time_unknown_pps(const uhd::time_spec_t& timespec) override
{
Debug("Setting Time at next PPS...");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_time_unknown_pps(timespec);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_time_unknown_pps(timespec);)
}
uhd_error get_time_now(uhd::time_spec_t& timespec) override
{
UHD_SAFE_C_SAVE_ERROR(this, timespec = usrp->get_time_now();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(timespec = usrp->get_time_now();)
}
uhd_error set_sync_source(const std::string& sync_source, const std::string& clock_source) override
{
Debug("Setting PPS source to '" << sync_source << "' and clock source to '" << clock_source << "'");
#if UHD_VERSION < 3140099
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_clock_source(clock_source); usrp->set_time_source(sync_source);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_clock_source(clock_source); usrp->set_time_source(sync_source);)
#else
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_sync_source(clock_source, sync_source);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_sync_source(clock_source, sync_source);)
#endif
}
uhd_error get_gain_range(uhd::gain_range_t& tx_gain_range, uhd::gain_range_t& rx_gain_range) override
{
UHD_SAFE_C_SAVE_ERROR(this, tx_gain_range = usrp->get_tx_gain_range(); rx_gain_range = usrp->get_rx_gain_range();)
SRSRAN_UHD_SAFE_C_LOG_ERROR(tx_gain_range = usrp->get_tx_gain_range(); rx_gain_range = usrp->get_rx_gain_range();)
}
uhd_error set_master_clock_rate(double rate) override
{
Debug("Setting master clock rate to " << rate / 1e6 << " MHz");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_master_clock_rate(rate);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_master_clock_rate(rate);)
}
uhd_error set_rx_rate(double rate) override
{
Debug("Setting Rx Rate to " << rate / 1e6 << "MHz");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_rx_rate(rate);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_rx_rate(rate);)
}
uhd_error set_tx_rate(double rate) override
{
Debug("Setting Tx Rate to " << rate / 1e6 << "MHz");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_tx_rate(rate);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_tx_rate(rate);)
}
uhd_error set_command_time(const uhd::time_spec_t& timespec) override
{
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_command_time(timespec);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_command_time(timespec);)
}
uhd_error get_rx_stream(size_t& max_num_samps) override
{
Debug("Creating Rx stream");
UHD_SAFE_C_SAVE_ERROR(
this, rx_stream = nullptr; rx_stream = usrp->get_rx_stream(stream_args);
max_num_samps = rx_stream->get_max_num_samps();
if (max_num_samps == 0UL) {
last_error = "The maximum number of receive samples is zero.";
return UHD_ERROR_VALUE;
})
SRSRAN_UHD_SAFE_C_LOG_ERROR(rx_stream = nullptr; rx_stream = usrp->get_rx_stream(stream_args);
max_num_samps = rx_stream->get_max_num_samps();
if (max_num_samps == 0UL) {
Error("The maximum number of receive samples is zero.");
return UHD_ERROR_VALUE;
})
}
uhd_error get_tx_stream(size_t& max_num_samps) override
{
Debug("Creating Tx stream");
UHD_SAFE_C_SAVE_ERROR(
this, tx_stream = nullptr; tx_stream = usrp->get_tx_stream(stream_args);
max_num_samps = tx_stream->get_max_num_samps();
if (max_num_samps == 0UL) {
last_error = "The maximum number of transmit samples is zero.";
return UHD_ERROR_VALUE;
})
SRSRAN_UHD_SAFE_C_LOG_ERROR(tx_stream = nullptr; tx_stream = usrp->get_tx_stream(stream_args);
max_num_samps = tx_stream->get_max_num_samps();
if (max_num_samps == 0UL) {
Error("The maximum number of transmit samples is zero.");
return UHD_ERROR_VALUE;
})
}
uhd_error set_tx_gain(size_t ch, double gain) override
{
Debug("Setting channel " << ch << " Tx gain to " << gain << " dB");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_tx_gain(gain, ch);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_tx_gain(gain, ch);)
}
uhd_error set_rx_gain(size_t ch, double gain) override
{
Debug("Setting channel " << ch << " Rx gain to " << gain << " dB");
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_rx_gain(gain, ch);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(usrp->set_rx_gain(gain, ch);)
}
uhd_error get_rx_gain(double& gain) override { UHD_SAFE_C_SAVE_ERROR(this, gain = usrp->get_rx_gain();) }
uhd_error get_tx_gain(double& gain) override { UHD_SAFE_C_SAVE_ERROR(this, gain = usrp->get_tx_gain();) }
uhd_error get_rx_gain(double& gain) override { SRSRAN_UHD_SAFE_C_LOG_ERROR(gain = usrp->get_rx_gain();) }
uhd_error get_tx_gain(double& gain) override { SRSRAN_UHD_SAFE_C_LOG_ERROR(gain = usrp->get_tx_gain();) }
uhd_error set_tx_freq(uint32_t ch, double target_freq, double& actual_freq) override
{
Debug("Setting channel " << ch << " Tx frequency to " << target_freq / 1e6 << " MHz");
@ -369,8 +366,8 @@ public:
tune_request.dsp_freq_policy = uhd::tune_request_t::POLICY_AUTO;
}
UHD_SAFE_C_SAVE_ERROR(this, uhd::tune_result_t tune_result = usrp->set_tx_freq(tune_request, ch);
actual_freq = tune_result.target_rf_freq;)
SRSRAN_UHD_SAFE_C_LOG_ERROR(uhd::tune_result_t tune_result = usrp->set_tx_freq(tune_request, ch);
actual_freq = tune_result.target_rf_freq;)
}
uhd_error set_rx_freq(uint32_t ch, double target_freq, double& actual_freq) override
{
@ -390,8 +387,8 @@ public:
tune_request.dsp_freq_policy = uhd::tune_request_t::POLICY_AUTO;
}
UHD_SAFE_C_SAVE_ERROR(this, uhd::tune_result_t tune_result = usrp->set_rx_freq(tune_request, ch);
actual_freq = tune_result.target_rf_freq;)
SRSRAN_UHD_SAFE_C_LOG_ERROR(uhd::tune_result_t tune_result = usrp->set_rx_freq(tune_request, ch);
actual_freq = tune_result.target_rf_freq;)
}
};

@ -190,11 +190,6 @@ void suppress_handler(const char* x)
static cf_t zero_mem[64 * 1024] = {};
#define print_usrp_error(h) \
do { \
ERROR("USRP reported the following error: %s", h->uhd->last_error.c_str()); \
} while (false)
static void log_overflow(rf_uhd_handler_t* h)
{
if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) {
@ -243,8 +238,6 @@ static void log_underflow(rf_uhd_handler_t* h)
static void log_rx_error(rf_uhd_handler_t* h)
{
if (h->uhd_error_handler) {
ERROR("USRP reported the following error: %s", h->uhd->last_error.c_str());
srsran_rf_error_t error;
bzero(&error, sizeof(srsran_rf_error_t));
error.type = srsran_rf_error_t::SRSRAN_RF_ERROR_RX;
@ -272,7 +265,6 @@ static void* async_thread(void* h)
if (handler->uhd->is_tx_ready()) {
lock.unlock();
if (handler->uhd->recv_async_msg(md, RF_UHD_IMP_ASYNCH_MSG_TIMEOUT_S, valid) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return nullptr;
}
@ -369,7 +361,6 @@ static int set_time_to_gps_time(rf_uhd_handler_t* handler)
std::vector<std::string> sensors;
if (handler->uhd->get_mboard_sensor_names(sensors) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -395,14 +386,12 @@ static int set_time_to_gps_time(rf_uhd_handler_t* handler)
// Get actual sensor value
double frac_secs = 0.0;
if (handler->uhd->get_sensor(sensor_name, frac_secs) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
// Get time and set
printf("Setting USRP time to %fs\n", frac_secs);
if (handler->uhd->set_time_unknown_pps(uhd::time_spec_t(frac_secs)) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -423,13 +412,11 @@ static int wait_sensor_locked(rf_uhd_handler_t* handler,
if (is_mboard) {
// motherboard sensor
if (handler->uhd->get_mboard_sensor_names(sensors) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
} else {
// daughterboard sensor
if (handler->uhd->get_rx_sensor_names(sensors) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -457,12 +444,10 @@ static int wait_sensor_locked(rf_uhd_handler_t* handler,
// Get actual sensor value
if (is_mboard) {
if (handler->uhd->get_sensor(sensor_name, is_locked) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
} else {
if (handler->uhd->get_rx_sensor(sensor_name, is_locked) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -510,7 +495,6 @@ static inline int rf_uhd_start_rx_stream_unsafe(rf_uhd_handler_t* handler)
// Issue stream command
if (handler->uhd->start_rx_stream(RF_UHD_IMP_STREAM_DELAY_S) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -537,7 +521,6 @@ static inline int rf_uhd_stop_rx_stream_unsafe(rf_uhd_handler_t* handler)
// Issue stream command
if (handler->uhd->stop_rx_stream() != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -579,7 +562,6 @@ void rf_uhd_flush_buffer(void* h)
do {
if (handler->uhd->receive(data, handler->rx_nof_samples, md, 0.0, false, rxd_samples) != UHD_ERROR_NONE) {
log_rx_error(handler);
print_usrp_error(handler);
return;
}
} while (rxd_samples > 0 and md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE);
@ -764,7 +746,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
// Make USRP
if (handler->uhd->usrp_make(device_addr, nof_channels) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -785,7 +766,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
if (handler->devname.empty()) {
std::string mboard_name;
if (handler->uhd->get_mboard_name(mboard_name) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -810,7 +790,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
// Set sync source
if (handler->uhd->set_sync_source(sync_src, clock_src) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -837,11 +816,9 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
// Set default Tx/Rx rates
if (handler->uhd->set_rx_rate(handler->rx_rate) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
if (handler->uhd->set_tx_rate(handler->tx_rate) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -851,12 +828,10 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
}
if (handler->uhd->get_rx_stream(handler->rx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
if (handler->uhd->get_tx_stream(handler->tx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -865,7 +840,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
for (uint32_t i = 0; i < nof_channels; i++) {
if (std::isnormal(handler->rx_freq[i])) {
if (handler->uhd->set_rx_freq(i, handler->rx_freq[i], handler->rx_freq[i]) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
rf_uhd_rx_wait_lo_locked(handler);
@ -875,7 +849,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
for (uint32_t i = 0; i < nof_channels; i++) {
if (std::isnormal(handler->tx_freq[i])) {
if (handler->uhd->set_tx_freq(i, handler->tx_freq[i], handler->tx_freq[i]) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -885,7 +858,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
uhd::gain_range_t tx_gain_range;
uhd::gain_range_t rx_gain_range;
if (handler->uhd->get_gain_range(tx_gain_range, rx_gain_range) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
handler->info.min_tx_gain = tx_gain_range.start();
@ -906,7 +878,6 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels
// Restore priorities
if (uhd_set_thread_priority(0, false) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -965,9 +936,7 @@ static inline void rf_uhd_set_master_clock_rate_unsafe(rf_uhd_handler_t* handler
{
// Set master clock rate if it is allowed and change is required
if (handler->dynamic_master_rate and handler->current_master_clock != rate) {
if (handler->uhd->set_master_clock_rate(rate) != UHD_ERROR_NONE) {
print_usrp_error(handler);
}
handler->uhd->set_master_clock_rate(rate);
handler->current_master_clock = rate;
}
}
@ -990,7 +959,6 @@ static inline int rf_uhd_imp_end_burst(rf_uhd_handler_t* handler)
// Actual base-band transmission
if (handler->uhd->send(buffs_ptr, 0, md, RF_UHD_IMP_TRX_TIMEOUT_S, txd_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -1025,7 +993,6 @@ double rf_uhd_set_rx_srate(void* h, double freq)
if (handler->nof_rx_channels > 1) {
uhd::time_spec_t timespec;
if (handler->uhd->get_time_now(timespec) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
timespec += RF_UHD_IMP_TIMED_COMMAND_DELAY_S;
@ -1034,13 +1001,11 @@ double rf_uhd_set_rx_srate(void* h, double freq)
// Set RX rate
if (handler->uhd->set_rx_rate(freq) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
if (RF_UHD_IMP_PROHIBITED_STREAM_REMAKE.count(handler->devname) == 0) {
if (handler->uhd->get_rx_stream(handler->rx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -1079,7 +1044,6 @@ double rf_uhd_set_tx_srate(void* h, double freq)
if (handler->nof_tx_channels > 1) {
uhd::time_spec_t timespec;
if (handler->uhd->get_time_now(timespec) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
timespec += RF_UHD_IMP_TIMED_COMMAND_DELAY_S;
@ -1088,13 +1052,11 @@ double rf_uhd_set_tx_srate(void* h, double freq)
// Set TX rate
if (handler->uhd->set_tx_rate(freq) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
if (RF_UHD_IMP_PROHIBITED_STREAM_REMAKE.count(handler->devname) == 0) {
if (handler->uhd->get_tx_stream(handler->tx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -1114,7 +1076,6 @@ int rf_uhd_set_rx_gain(void* h, double gain)
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
for (size_t i = 0; i < handler->nof_rx_channels; i++) {
if (rf_uhd_set_rx_gain_ch(h, i, gain)) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -1125,7 +1086,6 @@ int rf_uhd_set_rx_gain_ch(void* h, uint32_t ch, double gain)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
if (handler->uhd->set_rx_gain(ch, gain) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
return SRSRAN_SUCCESS;
@ -1136,7 +1096,6 @@ int rf_uhd_set_tx_gain(void* h, double gain)
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
for (size_t i = 0; i < handler->nof_tx_channels; i++) {
if (rf_uhd_set_tx_gain_ch(h, i, gain)) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
}
@ -1147,7 +1106,6 @@ int rf_uhd_set_tx_gain_ch(void* h, uint32_t ch, double gain)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
if (handler->uhd->set_tx_gain(ch, gain) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
return SRSRAN_SUCCESS;
@ -1159,7 +1117,6 @@ double rf_uhd_get_rx_gain(void* h)
double gain = 0.0;
if (handler->uhd->get_rx_gain(gain) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -1172,7 +1129,6 @@ double rf_uhd_get_tx_gain(void* h)
double gain = 0.0;
if (handler->uhd->get_tx_gain(gain) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -1201,13 +1157,9 @@ static bool rf_uhd_set_freq_ch(rf_uhd_handler_t* handler, uint32_t ch, double& f
// Set frequency
if (is_tx) {
if (handler->uhd->set_tx_freq(ch, freq, curr_freq) != UHD_ERROR_NONE) {
print_usrp_error(handler);
}
handler->uhd->set_tx_freq(ch, freq, curr_freq);
} else {
if (handler->uhd->set_rx_freq(ch, freq, curr_freq) != UHD_ERROR_NONE) {
print_usrp_error(handler);
}
handler->uhd->set_rx_freq(ch, freq, curr_freq);
}
return true;
}
@ -1251,9 +1203,7 @@ void rf_uhd_get_time(void* h, time_t* secs, double* frac_secs)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
uhd::time_spec_t timespec;
if (handler->uhd->get_time_now(timespec) != UHD_ERROR_NONE) {
print_usrp_error(handler);
}
handler->uhd->get_time_now(timespec);
if (secs != nullptr) {
*secs = timespec.get_full_secs();
}
@ -1271,9 +1221,7 @@ void rf_uhd_sync_pps(void* h)
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
uhd::time_spec_t timespec(0.0);
if (handler->uhd->set_time_unknown_pps(timespec) != UHD_ERROR_NONE) {
print_usrp_error(handler);
}
handler->uhd->set_time_unknown_pps(timespec);
}
int rf_uhd_recv_with_time(void* h, void* data, uint32_t nsamples, bool blocking, time_t* secs, double* frac_secs)
@ -1323,7 +1271,6 @@ int rf_uhd_recv_with_time_multi(void* h,
if (handler->uhd->receive(buffs_ptr, num_rx_samples, md, 1.0, false, rxd_samples) != UHD_ERROR_NONE) {
log_rx_error(handler);
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -1417,7 +1364,6 @@ int rf_uhd_send_timed_multi(void* h,
if (is_start_of_burst) {
// It gets the USRP time for transmissions without time
if (handler->uhd->get_time_now(md.time_spec) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
@ -1499,7 +1445,6 @@ int rf_uhd_send_timed_multi(void* h,
if (handler->tx_state != RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK) {
// Actual transmission
if (handler->uhd->send(buffs_ptr, tx_samples, md, RF_UHD_IMP_TRX_TIMEOUT_S, txd_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}

@ -99,17 +99,16 @@ private:
// Destroy any previous USRP instance
device3 = nullptr;
UHD_SAFE_C_SAVE_ERROR(this, device3 = uhd::device3::make(dev_addr);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(device3 = uhd::device3::make(dev_addr);)
}
template <class T>
uhd_error parse_param(uhd::device_addr_t& args, const std::string& param, T& value, bool pop = true)
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// Check if parameter exists
if (not args.has_key(param)) {
last_error = "RF-NOC requires " + param + " parameter";
Error("RF-NOC requires " + param + " parameter");
return UHD_ERROR_KEY;
}
@ -135,14 +134,14 @@ private:
// Parse number of radios
parse_param(args, "rfnoc_nof_radios", nof_radios);
if (nof_radios == 0) {
last_error = "RF-NOC Number of radios cannot be zero";
Error("RF-NOC Number of radios cannot be zero");
return UHD_ERROR_KEY;
}
// Parse number of channels per radio
parse_param(args, "rfnoc_nof_channels", nof_channels);
if (nof_channels == 0) {
last_error = "RF-NOC Number of channels cannot be zero";
Error("RF-NOC Number of channels cannot be zero");
return UHD_ERROR_KEY;
}
@ -158,8 +157,7 @@ private:
uhd_error create_control_interfaces()
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// Create Radio control
if (not loopback) {
radio_ctrl.resize(nof_radios);
@ -316,9 +314,7 @@ private:
nof_samples_per_packet = spp * 4 + 2 * sizeof(uint64_t);
}
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// Get Tx and Rx Graph
graph = device3->create_graph("graph");
@ -358,9 +354,7 @@ private:
nof_samples_per_packet = spp * 4 + 2 * sizeof(uint64_t);
}
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// Get Tx and Rx Graph
graph = device3->create_graph("graph");
@ -416,10 +410,10 @@ public:
// Check number of channels
if (nof_channels_ % nof_channels != 0 or nof_channels_ / nof_channels > nof_radios) {
last_error = "Number of requested channels (" + std::to_string(nof_channels_) +
") is different than the RFNOC "
"available channels (" +
std::to_string(nof_radios * nof_channels) + ")";
Error("Number of requested channels (" + std::to_string(nof_channels_) +
") is different than the RFNOC "
"available channels (" +
std::to_string(nof_radios * nof_channels) + ")");
return UHD_ERROR_VALUE;
}
@ -461,49 +455,41 @@ public:
};
uhd_error get_mboard_sensor_names(std::vector<std::string>& sensors) override
{
UHD_SAFE_C_SAVE_ERROR(
this, if (device3->get_tree()->exists(TREE_MBOARD_SENSORS)) {
sensors = device3->get_tree()->list(TREE_MBOARD_SENSORS);
})
SRSRAN_UHD_SAFE_C_LOG_ERROR(if (device3->get_tree()->exists(TREE_MBOARD_SENSORS)) {
sensors = device3->get_tree()->list(TREE_MBOARD_SENSORS);
})
}
uhd_error get_rx_sensor_names(std::vector<std::string>& sensors) override
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
if (device3->get_tree()->exists(TREE_RX_SENSORS)) { sensors = device3->get_tree()->list(TREE_RX_SENSORS); })
}
uhd_error get_sensor(const std::string& sensor_name, double& sensor_value) override
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
sensor_value =
device3->get_tree()->access<uhd::sensor_value_t>(TREE_MBOARD_SENSORS / sensor_name).get().to_real();)
}
uhd_error get_sensor(const std::string& sensor_name, bool& sensor_value) override
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
sensor_value =
device3->get_tree()->access<uhd::sensor_value_t>(TREE_MBOARD_SENSORS / sensor_name).get().to_bool();)
}
uhd_error get_rx_sensor(const std::string& sensor_name, bool& sensor_value) override
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
sensor_value = device3->get_tree()->access<uhd::sensor_value_t>(TREE_RX_SENSORS / sensor_name).get().to_bool();)
}
uhd_error set_time_unknown_pps(const uhd::time_spec_t& timespec) override
{
Info("Setting time " << timespec.get_real_secs() << " at next PPS...");
UHD_SAFE_C_SAVE_ERROR(
this,
for (auto& r
: radio_ctrl) { r->set_time_next_pps(timespec); });
SRSRAN_UHD_SAFE_C_LOG_ERROR(for (auto& r : radio_ctrl) { r->set_time_next_pps(timespec); });
}
uhd_error get_time_now(uhd::time_spec_t& timespec) override
{
UHD_SAFE_C_SAVE_ERROR(this, timespec = device3->get_tree()->access<uhd::time_spec_t>(TREE_TIME_NOW).get();
Info("-- " << timespec.get_real_secs());)
SRSRAN_UHD_SAFE_C_LOG_ERROR(timespec = device3->get_tree()->access<uhd::time_spec_t>(TREE_TIME_NOW).get();
Info("-- " << timespec.get_real_secs());)
}
uhd_error set_sync_source(const std::string& sync_source, const std::string& clock_source) override
{
@ -511,13 +497,12 @@ public:
return UHD_ERROR_NONE;
}
UHD_SAFE_C_SAVE_ERROR(
this, for (size_t radio_idx = 0; radio_idx < nof_radios; radio_idx++) {
UHD_LOG_DEBUG(radio_id[radio_idx],
"Setting PPS source to '" << sync_source << "' and clock source to '" << clock_source << "'");
radio_ctrl[radio_idx]->set_clock_source(clock_source);
radio_ctrl[radio_idx]->set_time_source(sync_source);
})
SRSRAN_UHD_SAFE_C_LOG_ERROR(for (size_t radio_idx = 0; radio_idx < nof_radios; radio_idx++) {
UHD_LOG_DEBUG(radio_id[radio_idx],
"Setting PPS source to '" << sync_source << "' and clock source to '" << clock_source << "'");
radio_ctrl[radio_idx]->set_clock_source(clock_source);
radio_ctrl[radio_idx]->set_time_source(sync_source);
})
}
uhd_error get_gain_range(uhd::gain_range_t& tx_gain_range, uhd::gain_range_t& rx_gain_range) override
{
@ -529,29 +514,27 @@ public:
uhd_error set_master_clock_rate(double rate) override { return UHD_ERROR_NONE; }
uhd_error set_rx_rate(double rate) override
{
UHD_SAFE_C_SAVE_ERROR(
this, for (size_t i = 0; i < nof_radios; i++) {
for (size_t j = 0; j < nof_channels; j++) {
UHD_LOG_DEBUG(ddc_id[i], "Setting channel " << j << " output rate to " << rate / 1e6 << " MHz");
ddc_ctrl[i]->set_arg("output_rate", std::to_string(rate), j);
}
})
SRSRAN_UHD_SAFE_C_LOG_ERROR(for (size_t i = 0; i < nof_radios; i++) {
for (size_t j = 0; j < nof_channels; j++) {
UHD_LOG_DEBUG(ddc_id[i], "Setting channel " << j << " output rate to " << rate / 1e6 << " MHz");
ddc_ctrl[i]->set_arg("output_rate", std::to_string(rate), j);
}
})
}
uhd_error set_tx_rate(double rate) override
{
UHD_SAFE_C_SAVE_ERROR(
this, for (size_t i = 0; i < nof_radios; i++) {
for (size_t j = 0; j < nof_channels; j++) {
UHD_LOG_DEBUG(duc_id[i], "Setting channel " << j << " input rate to " << rate / 1e6 << " MHz");
duc_ctrl[i]->set_arg("input_rate", std::to_string(rate), j);
}
})
SRSRAN_UHD_SAFE_C_LOG_ERROR(for (size_t i = 0; i < nof_radios; i++) {
for (size_t j = 0; j < nof_channels; j++) {
UHD_LOG_DEBUG(duc_id[i], "Setting channel " << j << " input rate to " << rate / 1e6 << " MHz");
duc_ctrl[i]->set_arg("input_rate", std::to_string(rate), j);
}
})
}
uhd_error set_command_time(const uhd::time_spec_t& timespec) override { return UHD_ERROR_NONE; }
uhd_error get_rx_stream(size_t& max_num_samps) override
{
UHD_SAFE_C_SAVE_ERROR(
this, uhd::stream_args_t stream_args("fc32", "sc16");
SRSRAN_UHD_SAFE_C_LOG_ERROR(
uhd::stream_args_t stream_args("fc32", "sc16");
stream_args.channels.resize(nof_radios * nof_channels);
@ -575,8 +558,8 @@ public:
}
uhd_error get_tx_stream(size_t& max_num_samps) override
{
UHD_SAFE_C_SAVE_ERROR(
this, uhd::stream_args_t stream_args("fc32", "sc16");
SRSRAN_UHD_SAFE_C_LOG_ERROR(
uhd::stream_args_t stream_args("fc32", "sc16");
stream_args.channels.resize(nof_radios * nof_channels);
if (spp != 0) { stream_args.args["spp"] = std::to_string(spp); }
@ -605,7 +588,7 @@ public:
uhd_error set_tx_gain(size_t ch, double gain) override
{
if (ch >= nof_channels * nof_radios) {
last_error = "Invalid channel index " + std::to_string(ch);
Error("Invalid channel index " + std::to_string(ch));
return UHD_ERROR_INDEX;
}
@ -618,12 +601,11 @@ public:
// Set the gain for the channel zero only
if (channel_idx != 0) {
last_error = "None";
return UHD_ERROR_NONE;
}
UHD_SAFE_C_SAVE_ERROR(
this, UHD_LOG_DEBUG(radio_id[radio_idx], "Setting TX Gain: " << gain << " dB...");
SRSRAN_UHD_SAFE_C_LOG_ERROR(
UHD_LOG_DEBUG(radio_id[radio_idx], "Setting TX Gain: " << gain << " dB...");
radio_ctrl[radio_idx]->set_tx_gain(gain, 0);
UHD_LOG_DEBUG(radio_id[radio_idx], "Actual TX Gain: " << radio_ctrl[radio_idx]->get_rx_gain(0) << " dB...");)
}
@ -631,7 +613,7 @@ public:
uhd_error set_rx_gain(size_t ch, double gain) override
{
if (ch >= nof_channels * nof_radios) {
last_error = "Invalid channel index " + std::to_string(ch);
Error("Invalid channel index " + std::to_string(ch));
return UHD_ERROR_INDEX;
}
@ -644,12 +626,11 @@ public:
// Set the gain for the channel zero only
if (channel_idx != 0) {
last_error = "None";
return UHD_ERROR_NONE;
}
UHD_SAFE_C_SAVE_ERROR(
this, UHD_LOG_DEBUG(radio_id[radio_idx], "Setting RX Gain: " << gain << " dB...");
SRSRAN_UHD_SAFE_C_LOG_ERROR(
UHD_LOG_DEBUG(radio_id[radio_idx], "Setting RX Gain: " << gain << " dB...");
radio_ctrl[radio_idx]->set_rx_gain(gain, 0);
UHD_LOG_DEBUG(radio_id[radio_idx], "Actual RX Gain: " << radio_ctrl[radio_idx]->get_rx_gain(0) << " dB...");)
}
@ -659,7 +640,7 @@ public:
return UHD_ERROR_NONE;
}
UHD_SAFE_C_SAVE_ERROR(this, gain = radio_ctrl[0]->get_tx_gain(0);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(gain = radio_ctrl[0]->get_tx_gain(0);)
}
uhd_error get_rx_gain(double& gain) override
{
@ -667,23 +648,22 @@ public:
return UHD_ERROR_NONE;
}
UHD_SAFE_C_SAVE_ERROR(this, gain = radio_ctrl[0]->get_rx_gain(0);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(gain = radio_ctrl[0]->get_rx_gain(0);)
}
uhd_error set_tx_freq(uint32_t ch, double target_freq, double& actual_freq) override
{
if (ch >= tx_freq_hz.size()) {
last_error = "Invalid channel index " + std::to_string(ch);
Error("Invalid channel index " + std::to_string(ch));
return UHD_ERROR_INDEX;
}
if (not std::isnormal(target_freq)) {
last_error = "Invalid TX frequency value " + std::to_string(target_freq) + " for channel " + std::to_string(ch);
Error("Invalid TX frequency value " + std::to_string(target_freq) + " for channel " + std::to_string(ch));
return UHD_ERROR_VALUE;
}
// Nothing to update
if (std::round(tx_freq_hz[ch]) == std::round(target_freq)) {
last_error = "None";
return UHD_ERROR_NONE;
}
@ -695,9 +675,7 @@ public:
size_t i = ch / nof_channels;
size_t j = ch % nof_channels;
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// Set Radio Tx freq
if (not std::isnormal(tx_center_freq_hz[i]) and not loopback) {
UHD_LOG_DEBUG(radio_id[i],
@ -722,18 +700,17 @@ public:
uhd_error set_rx_freq(uint32_t ch, double target_freq, double& actual_freq) override
{
if (ch >= rx_freq_hz.size()) {
last_error = "Invalid channel index " + std::to_string(ch);
Error("Invalid channel index " + std::to_string(ch));
return UHD_ERROR_INDEX;
}
if (not std::isnormal(target_freq)) {
last_error = "Invalid TX frequency value " + std::to_string(target_freq) + " for channel " + std::to_string(ch);
Error("Invalid TX frequency value " + std::to_string(target_freq) + " for channel " + std::to_string(ch));
return UHD_ERROR_VALUE;
}
// Nothing to update
if (std::round(rx_freq_hz[ch]) == std::round(target_freq)) {
last_error = "None";
return UHD_ERROR_NONE;
}
@ -745,9 +722,7 @@ public:
size_t i = ch / nof_channels;
size_t j = ch % nof_channels;
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// Set Radio Tx freq
if (not std::isnormal(rx_center_freq_hz[i]) and not loopback) {
UHD_LOG_DEBUG(radio_id[i], "Setting RX Freq: " << target_freq / 1e6 << " MHz...");

@ -16,17 +16,37 @@
#include <uhd/utils/log.hpp>
#ifdef UHD_LOG_INFO
#define Error(message) UHD_LOG_ERROR("UHD RF", message)
#define Warning(message) UHD_LOG_WARNING("UHD RF", message)
#define Info(message) UHD_LOG_INFO("UHD RF", message)
#define Debug(message) UHD_LOG_DEBUG("UHD RF", message)
#define Trace(message) UHD_LOG_TRACE("UHD RF", message)
#else
#define Error(message) UHD_LOG << message << std::endl
#define Warning(message) UHD_LOG << message << std::endl
#define Info(message) UHD_LOG << message << std::endl
#define Debug(message) UHD_LOG << message << std::endl
#define Trace(message) UHD_LOG << message << std::endl
#endif
#define SRSRAN_UHD_SAFE_C_LOG_ERROR(...) \
try { \
__VA_ARGS__ \
} catch (const uhd::exception& e) { \
Error(e.what()); \
return error_from_uhd_exception(&e); \
} catch (const boost::exception& e) { \
Error(boost::diagnostic_information(e)); \
return UHD_ERROR_BOOSTEXCEPT; \
} catch (const std::exception& e) { \
Error(e.what()); \
return UHD_ERROR_STDEXCEPT; \
} catch (...) { \
Error("Unrecognized exception caught."); \
return UHD_ERROR_UNKNOWN; \
} \
return UHD_ERROR_NONE;
#ifdef ENABLE_UHD_X300_FW_RESET
#include <uhd/transport/udp_simple.hpp>
@ -45,8 +65,7 @@ private:
#ifdef ENABLE_UHD_X300_FW_RESET
uhd_error try_usrp_x300_reset(const uhd::device_addr_t& dev_addr)
{
UHD_SAFE_C_SAVE_ERROR(
this,
SRSRAN_UHD_SAFE_C_LOG_ERROR(
// It is not possible to reset device if IP address is not provided
if (not dev_addr.has_key("addr")) { return UHD_ERROR_NONE; }
@ -109,8 +128,6 @@ protected:
}
public:
std::string last_error;
virtual uhd_error usrp_make(const uhd::device_addr_t& dev_addr, uint32_t nof_channels) = 0;
virtual uhd_error get_mboard_name(std::string& mboard_name) = 0;
virtual uhd_error get_mboard_sensor_names(std::vector<std::string>& sensors) = 0;
@ -129,19 +146,19 @@ public:
return err;
}
UHD_SAFE_C_SAVE_ERROR(this, uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
stream_cmd.time_spec = time_spec;
stream_cmd.time_spec += delay;
stream_cmd.stream_now = not std::isnormal(delay);
SRSRAN_UHD_SAFE_C_LOG_ERROR(uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
stream_cmd.time_spec = time_spec;
stream_cmd.time_spec += delay;
stream_cmd.stream_now = not std::isnormal(delay);
rx_stream->issue_stream_cmd(stream_cmd);)
rx_stream->issue_stream_cmd(stream_cmd);)
}
uhd_error stop_rx_stream()
{
Debug("Stopping Rx stream");
UHD_SAFE_C_SAVE_ERROR(this, uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
stream_cmd.stream_now = true;
rx_stream->issue_stream_cmd(stream_cmd);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
stream_cmd.stream_now = true;
rx_stream->issue_stream_cmd(stream_cmd);)
}
virtual uhd_error set_sync_source(const std::string& sync_source, const std::string& clock_source) = 0;
virtual uhd_error get_gain_range(uhd::gain_range_t& tx_gain_range, uhd::gain_range_t& rx_gain_range) = 0;
@ -164,12 +181,13 @@ public:
const bool one_packet,
size_t& nof_rxd_samples)
{
UHD_SAFE_C_SAVE_ERROR(this, uhd::rx_streamer::buffs_type buffs_cpp(buffs, rx_stream->get_num_channels());
nof_rxd_samples = rx_stream->recv(buffs_cpp, nsamps_per_buff, metadata, timeout, one_packet);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(uhd::rx_streamer::buffs_type buffs_cpp(buffs, rx_stream->get_num_channels());
nof_rxd_samples =
rx_stream->recv(buffs_cpp, nsamps_per_buff, metadata, timeout, one_packet);)
}
virtual uhd_error recv_async_msg(uhd::async_metadata_t& async_metadata, double timeout, bool& valid)
{
UHD_SAFE_C_SAVE_ERROR(this, valid = tx_stream->recv_async_msg(async_metadata, timeout);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(valid = tx_stream->recv_async_msg(async_metadata, timeout);)
}
uhd_error send(void** buffs,
const size_t nsamps_per_buff,
@ -177,8 +195,8 @@ public:
const double timeout,
size_t& nof_txd_samples)
{
UHD_SAFE_C_SAVE_ERROR(this, uhd::tx_streamer::buffs_type buffs_cpp(buffs, tx_stream->get_num_channels());
nof_txd_samples = tx_stream->send(buffs_cpp, nsamps_per_buff, metadata, timeout);)
SRSRAN_UHD_SAFE_C_LOG_ERROR(uhd::tx_streamer::buffs_type buffs_cpp(buffs, tx_stream->get_num_channels());
nof_txd_samples = tx_stream->send(buffs_cpp, nsamps_per_buff, metadata, timeout);)
}
virtual bool is_rx_ready() { return rx_stream != nullptr; }
virtual bool is_tx_ready() { return tx_stream != nullptr; }

@ -88,7 +88,6 @@ private:
if (valid) {
switch (async_metadata.event_code) {
case uhd::async_metadata_t::EVENT_CODE_BURST_ACK:
Warning("BURST ACK") break;
case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW:
@ -223,16 +222,13 @@ public:
uhd::log::set_console_level(uhd::log::severity_level::trace);
if (rfnoc->usrp_make(hint, config.nof_channels * config.nof_radios) != UHD_ERROR_NONE) {
Warning(rfnoc->last_error);
return SRSRAN_ERROR;
}
if (rfnoc->set_tx_rate(config.srate_hz) != UHD_ERROR_NONE) {
Warning(rfnoc->last_error);
return SRSRAN_ERROR;
}
if (rfnoc->set_rx_rate(config.srate_hz) != UHD_ERROR_NONE) {
Warning(rfnoc->last_error);
return SRSRAN_ERROR;
}
@ -248,7 +244,6 @@ public:
}
if (rfnoc->start_rx_stream(config.init_tx_time) != UHD_ERROR_NONE) {
Warning(rfnoc->last_error);
return SRSRAN_ERROR;
}

Loading…
Cancel
Save