Removing support for direct LimeSDR drivers - only supporting through SoapySDR

master
Paul Sutton 8 years ago
parent 5d4d07a14a
commit b2c3b31a59

@ -84,7 +84,7 @@ else(POLARSSL_FOUND)
set(POLAR_LIBRARIES "${MBEDTLS_LIBRARIES}") set(POLAR_LIBRARIES "${MBEDTLS_LIBRARIES}")
add_definitions(-DHAVE_MBEDTLS) add_definitions(-DHAVE_MBEDTLS)
else(MBEDTLS_FOUND) else(MBEDTLS_FOUND)
message(FATAL_ERROR "Either polarssl or mbedtls is required to compile srsUE") message(FATAL_ERROR "Either polarssl or mbedtls is required to compile srsLTE")
endif (MBEDTLS_FOUND) endif (MBEDTLS_FOUND)
endif(POLARSSL_FOUND) endif(POLARSSL_FOUND)
@ -120,20 +120,15 @@ if(SOAPYSDR_FOUND)
link_directories(${SOAPYSDR_LIBRARY_DIRS}) link_directories(${SOAPYSDR_LIBRARY_DIRS})
endif(SOAPYSDR_FOUND) endif(SOAPYSDR_FOUND)
find_package(LimeSDR) if(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
if(LIMESDR_FOUND)
include_directories(${LIMESDR_INCLUDE_DIRS})
link_directories(${LIMESDR_LIBRARY_DIRS})
endif(LIMESDR_FOUND)
if(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND OR LIMESDR_FOUND)
set(RF_FOUND TRUE CACHE INTERNAL "RF frontend found") set(RF_FOUND TRUE CACHE INTERNAL "RF frontend found")
else(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND OR LIMESDR_FOUND) else(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
set(RF_FOUND FALSE CACHE INTERNAL "RF frontend found") set(RF_FOUND FALSE CACHE INTERNAL "RF frontend found")
add_definitions(-DDISABLE_RF) add_definitions(-DDISABLE_RF)
endif(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND OR LIMESDR_FOUND) endif(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
if(ENABLE_SRSUE OR ENABLE_SRSENB) if(ENABLE_SRSUE OR ENABLE_SRSENB)
# Find Boost
set(BOOST_REQUIRED_COMPONENTS set(BOOST_REQUIRED_COMPONENTS
program_options program_options
system system

@ -33,11 +33,6 @@ if(RF_FOUND)
list(APPEND SOURCES_RF rf_blade_imp.c) list(APPEND SOURCES_RF rf_blade_imp.c)
endif (BLADERF_FOUND) endif (BLADERF_FOUND)
if (LIMESDR_FOUND)
add_definitions(-DENABLE_LIMESDR)
list(APPEND SOURCES_RF rf_limesdr_imp.c)
endif (LIMESDR_FOUND)
if (SOAPYSDR_FOUND) if (SOAPYSDR_FOUND)
add_definitions(-DENABLE_SOAPYSDR) add_definitions(-DENABLE_SOAPYSDR)
list(APPEND SOURCES_RF rf_soapy_imp.c) list(APPEND SOURCES_RF rf_soapy_imp.c)
@ -55,10 +50,6 @@ if(RF_FOUND)
target_link_libraries(srslte_rf ${BLADERF_LIBRARIES}) target_link_libraries(srslte_rf ${BLADERF_LIBRARIES})
endif (BLADERF_FOUND) endif (BLADERF_FOUND)
if (LIMESDR_FOUND)
target_link_libraries(srslte_rf ${LIMESDR_LIBRARIES})
endif (LIMESDR_FOUND)
if (SOAPYSDR_FOUND) if (SOAPYSDR_FOUND)
target_link_libraries(srslte_rf ${SOAPYSDR_LIBRARIES}) target_link_libraries(srslte_rf ${SOAPYSDR_LIBRARIES})
endif (SOAPYSDR_FOUND) endif (SOAPYSDR_FOUND)

@ -140,45 +140,6 @@ static rf_dev_t dev_blade = {
}; };
#endif #endif
/* Define implementation for LimeSDR */
#ifdef ENABLE_LIMESDR
#include "rf_limesdr_imp.h"
static rf_dev_t dev_limesdr = {
"limesdr",
rf_limesdr_devname,
rf_limesdr_rx_wait_lo_locked,
rf_limesdr_start_rx_stream,
rf_limesdr_stop_rx_stream,
rf_limesdr_flush_buffer,
rf_limesdr_has_rssi,
rf_limesdr_get_rssi,
rf_limesdr_suppress_stdout,
rf_limesdr_register_error_handler,
rf_limesdr_open,
rf_limesdr_open_multi,
rf_limesdr_close,
rf_limesdr_set_master_clock_rate,
rf_limesdr_is_master_clock_dynamic,
rf_limesdr_set_rx_srate,
rf_limesdr_set_rx_gain,
rf_limesdr_set_tx_gain,
rf_limesdr_get_rx_gain,
rf_limesdr_get_tx_gain,
rf_limesdr_set_rx_freq,
rf_limesdr_set_tx_srate,
rf_limesdr_set_tx_freq,
rf_limesdr_get_time,
rf_limesdr_recv_with_time,
rf_limesdr_recv_with_time_multi,
rf_limesdr_send_timed,
rf_limesdr_set_tx_cal,
rf_limesdr_set_rx_cal
};
#endif
#ifdef ENABLE_SOAPYSDR #ifdef ENABLE_SOAPYSDR
#include "rf_soapy_imp.h" #include "rf_soapy_imp.h"
@ -270,9 +231,6 @@ static rf_dev_t *available_devices[] = {
#ifdef ENABLE_BLADERF #ifdef ENABLE_BLADERF
&dev_blade, &dev_blade,
#endif #endif
#ifdef ENABLE_LIMESDR
&dev_limesdr,
#endif
#ifdef ENABLE_DUMMY_DEV #ifdef ENABLE_DUMMY_DEV
&dev_dummy, &dev_dummy,
#endif #endif

@ -1,475 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* 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 <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "srslte/srslte.h"
#include "rf_limesdr_imp.h"
#include "srslte/phy/rf/rf.h"
#include "lime/LimeSuite.h"
typedef struct {
char *devname;
lms_dev_info_t *dev_info;
lms_device_t *device;
lms_info_str_t list[8];
lms_stream_t rx_stream;
lms_stream_t tx_stream;
int sampling_rate;
bool rx_is_streaming;
bool tx_is_streaming;
int channel;
int buffer_size;
int num_buffers;
lms_stream_meta_t tx_metadata; //Use metadata for additional control over sample receive function behaviour
lms_stream_meta_t rx_metadata; //Use metadata for additional control over sample receive function behaviour
lms_range_t rx_range;
lms_range_t tx_range;
} rf_limesdr_handler_t;
int lime_error(void *h)
{
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
//print last error message
fprintf(stderr, "Error: %s\n", LMS_GetLastErrorMessage());
if(handler->device != NULL)
LMS_Close(handler->device);
return SRSLTE_ERROR;
}
void rf_limesdr_get_freq_range(void *h)
{
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
LMS_GetLOFrequencyRange(handler->device, LMS_CH_RX, &(handler->rx_range));
LMS_GetLOFrequencyRange(handler->device, LMS_CH_TX, &(handler->tx_range));
}
void rf_limesdr_suppress_handler(const char *x)
{
// not supported
}
void rf_limesdr_msg_handler(const char *msg)
{
// not supported
}
void rf_limesdr_suppress_stdout(void *h)
{
// not supported
}
void rf_limesdr_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler)
{
// not supported
}
static bool isLocked(rf_limesdr_handler_t *handler, char *sensor_name, void *value_h)
{
// not supported
return true;
}
char* rf_limesdr_devname(void* h)
{
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
handler->dev_info = LMS_GetDeviceInfo(handler);
return handler->dev_info->deviceName;
}
bool rf_limesdr_rx_wait_lo_locked(void *h)
{
// not supported
return true;
}
void rf_limesdr_set_tx_cal(void *h, srslte_rf_cal_t *cal)
{
// not supported
}
void rf_limesdr_set_rx_cal(void *h, srslte_rf_cal_t *cal)
{
// not supported
}
int rf_limesdr_start_rx_stream(void *h)
{
printf("Starting rx stream\n");
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(LMS_StartStream(&(handler->rx_stream)) != 0){
return lime_error(h);
}
return 0;
}
int rf_limesdr_start_tx_stream(void *h)
{
printf("Starting tx stream\n");
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(LMS_StartStream(&(handler->tx_stream)) != 0){
return lime_error(h);
}
return 0;
}
int rf_limesdr_stop_rx_stream(void *h)
{
printf("Stopping rx stream\n");
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
//stream is stopped but can be started again with LMS_StartStream()
if(LMS_StopStream(&(handler->rx_stream)) != 0){
return lime_error(h);
}
return 0;
}
int rf_limesdr_stop_tx_stream(void *h)
{
printf("Stopping tx stream\n");
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
//stream is stopped but can be started again with LMS_StartStream()
if(LMS_StopStream(&(handler->tx_stream)) != 0){
return lime_error(h);
}
return 0;
}
void rf_limesdr_flush_buffer(void *h)
{
int n;
cf_t tmp1[1024];
cf_t tmp2[1024];
void *data[2] = {tmp1, tmp2};
do {
n = rf_limesdr_recv_with_time_multi(h, data, 1024, 0, NULL, NULL);
} while (n > 0);
}
bool rf_limesdr_has_rssi(void *h)
{
return false;
}
float rf_limesdr_get_rssi(void *h)
{
return 0.0;
}
//TODO: add multi-channel support
int rf_limesdr_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
{
return rf_limesdr_open(args, h);
}
int rf_limesdr_open(char *args, void **h)
{
printf("Opening device\n");
*h = NULL;
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) malloc(sizeof(rf_limesdr_handler_t));
if (!handler) {
perror("malloc");
return -1;
}
*h = handler;
handler->device = NULL;
handler->buffer_size = 1024;
handler->num_buffers = 8;
handler->channel = 0;
int n;
if ((n = LMS_GetDeviceList(handler->list)) < 0) //NULL can be passed to only get number of devices
return SRSLTE_ERROR;
if (LMS_Open(&(handler->device), handler->list[0], NULL))
return SRSLTE_ERROR;
if (LMS_Init(handler->device) != 0)
return SRSLTE_ERROR;
if (LMS_EnableChannel(handler->device, LMS_CH_RX, handler->channel, true) != 0)
return lime_error(handler);
if (LMS_EnableChannel(handler->device, LMS_CH_TX, handler->channel, true) != 0)
return lime_error(handler);
rf_limesdr_get_freq_range(handler);
handler->rx_is_streaming = false;
handler->rx_stream.channel = handler->channel; //channel number
handler->rx_stream.fifoSize = 1024 * 1024; //fifo size in samples
handler->rx_stream.throughputVsLatency = 1.0; //optimize for max throughput
handler->rx_stream.isTx = false; //RX channel
handler->rx_stream.dataFmt = LMS_FMT_F32;
handler->rx_metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
handler->rx_metadata.waitForTimestamp = false; //Do not wait for specific timestamps
if (LMS_SetupStream(handler->device, &(handler->rx_stream)) != 0)
return lime_error(handler);
handler->tx_is_streaming = false;
handler->tx_stream.channel = handler->channel; //channel number
handler->tx_stream.fifoSize = 1024 * 1024; //fifo size in samples
handler->tx_stream.throughputVsLatency = 1.0; //optimize for max throughput
handler->tx_stream.isTx = true; //TX channel
handler->rx_stream.dataFmt = LMS_FMT_F32;
handler->tx_metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
handler->tx_metadata.waitForTimestamp = false; //Do not wait for specific timestamps
if (LMS_SetupStream(handler->device, &(handler->tx_stream)) != 0)
return lime_error(handler);
return SRSLTE_SUCCESS;
}
int rf_limesdr_close(void *h)
{
printf("Closing device\n");
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(handler->rx_is_streaming) {
LMS_StopStream(&(handler->rx_stream));
}
LMS_DestroyStream(handler->device, &(handler->rx_stream)); //stream is deallocated and can no longer be used
if(handler->tx_is_streaming) {
LMS_StopStream(&(handler->tx_stream));
}
LMS_DestroyStream(handler->device, &(handler->tx_stream)); //stream is deallocated and can no longer be used
LMS_Close(handler->device);
return SRSLTE_SUCCESS;
}
void rf_limesdr_set_master_clock_rate(void *h, double rate)
{
// Allow the limesdr to automatically set the appropriate clock rate
}
bool rf_limesdr_is_master_clock_dynamic(void *h)
{
return true;
}
double rf_limesdr_set_rx_srate(void *h, double rate)
{
fprintf(stdout, "Setting rx rate: %f\n", rate);
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if (LMS_SetSampleRate(handler->device, rate, 0) != 0)
return lime_error(handler);
handler->sampling_rate = rate;
return rate;
}
double rf_limesdr_set_tx_srate(void *h, double rate)
{
fprintf(stdout, "Setting tx rate: %f\n", rate);
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if (LMS_SetSampleRate(handler->device, rate, 0) != 0)
return lime_error(handler);
handler->sampling_rate = rate;
return rate;
}
double rf_limesdr_set_rx_gain(void *h, double gain)
{
fprintf(stdout, "Setting rx gain: %f\n", gain);
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if (LMS_SetNormalizedGain(handler->device, LMS_CH_RX, handler->channel, gain) != 0)
return lime_error(handler);
return gain;
}
double rf_limesdr_set_tx_gain(void *h, double gain)
{
fprintf(stdout, "Setting tx gain: %f\n", gain);
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if (LMS_SetNormalizedGain(handler->device, LMS_CH_TX, handler->channel, gain) != 0)
return lime_error(handler);
return gain;
}
double rf_limesdr_get_rx_gain(void *h)
{
double gain;
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(LMS_GetNormalizedGain(handler->device, LMS_CH_RX,handler->channel,&gain) != 0)
return lime_error(handler);
return gain;
}
double rf_limesdr_get_tx_gain(void *h)
{
double gain;
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(LMS_GetNormalizedGain(handler->device, LMS_CH_TX, handler->channel, &gain) != 0)
return lime_error(handler);
return gain;
}
double rf_limesdr_set_rx_freq(void *h, double freq)
{
fprintf(stdout, "Setting rx freq: %f\n", freq);
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(freq > handler->rx_range.max || freq < handler->rx_range.min) {
fprintf(stderr, "Requested freq outside supported range. freq: %f, min: %f, max: %f\n", freq, handler->rx_range.min, handler->rx_range.max);
return SRSLTE_ERROR;
}
if(LMS_SetLOFrequency(handler->device, LMS_CH_RX, handler->channel, freq) != 0)
return lime_error(handler);
// Automatic antenna port selection doesn't work - so set manually
int ant_port = 1; // manually select antenna index 1 (LNA_H)
if(freq < 1.5e9) {
ant_port = 2; // manually select antenna index 2 (LNA_L)
}
if (LMS_SetAntenna(handler->device, LMS_CH_RX, handler->channel, ant_port) != 0)
return lime_error(handler);
lms_name_t antenna_list[10]; //large enough list for antenna names.
//Alternatively, NULL can be passed to LMS_GetAntennaList() to find out number of available antennae
int n = 0;
if ((n = LMS_GetAntennaList(handler->device, LMS_CH_RX, 0, antenna_list)) < 0)
return lime_error(handler);
fprintf(stdout, "Available antennae:\n"); //print available antennae names
for(int i = 0; i < n; i++)
fprintf(stdout, "%d : %s\n", i, antenna_list[i]);
if((n = LMS_GetAntenna(handler->device, LMS_CH_RX, handler->channel)) < 0) //get currently selected antenna index
return lime_error(handler);
fprintf(stdout, "Selected antenna: %d : %s\n", n, antenna_list[n]); //print antenna index and name
return freq;
}
double rf_limesdr_set_tx_freq(void *h, double freq)
{
fprintf(stdout, "Setting tx freq: %f\n", freq);
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
if(freq > handler->tx_range.max || freq < handler->tx_range.min) {
fprintf(stderr, "Requested freq outside supported range. freq: %f, min: %f, max: %f\n", freq, handler->rx_range.min, handler->rx_range.max);
return SRSLTE_ERROR;
}
if(LMS_SetLOFrequency(handler->device, LMS_CH_TX, handler->channel, freq) != 0)
return lime_error(handler);
return freq;
}
void rf_limesdr_get_time(void *h, time_t *secs, double *frac_secs) {
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
LMS_RecvStream(&(handler->rx_stream),NULL,0, &(handler->rx_metadata), 0);
if (secs && frac_secs) {
*secs = (handler->rx_metadata.timestamp) / (handler->sampling_rate);
int remainder = handler->rx_metadata.timestamp % handler->sampling_rate;
*frac_secs = remainder/(handler->sampling_rate);
}
}
//TODO: add multi-channel support
int rf_limesdr_recv_with_time_multi(void *h,
void **data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs)
{
return rf_limesdr_recv_with_time(h, *data, nsamples, blocking, secs, frac_secs);
}
int rf_limesdr_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs)
{
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
int samples = LMS_RecvStream(&(handler->rx_stream),data,nsamples, &(handler->rx_metadata), blocking ? 1000:0);
if (secs && frac_secs) {
*secs = (handler->rx_metadata.timestamp) / (handler->sampling_rate);
int remainder = handler->rx_metadata.timestamp % handler->sampling_rate;
*frac_secs = remainder/(handler->sampling_rate);
}
return samples;
}
int rf_limesdr_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst)
{
rf_limesdr_handler_t *handler = (rf_limesdr_handler_t*) h;
//float *data_in = (float*) data;
if(!handler->tx_is_streaming)
rf_limesdr_start_tx_stream(h);
handler->tx_metadata.timestamp = secs*handler->sampling_rate;
handler->tx_metadata.timestamp += frac_secs*handler->sampling_rate;
LMS_SendStream(&(handler->rx_stream), data, nsamples, &(handler->tx_metadata), blocking ? 1000:0);
return 1;
}

@ -1,118 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* 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 <stdbool.h>
#include <stdint.h>
#include "srslte/config.h"
#include "srslte/phy/rf/rf.h"
SRSLTE_API int rf_limesdr_open( char *args,
void **handler);
SRSLTE_API int rf_limesdr_open_multi( char *args,
void **handler,
uint32_t nof_rx_antennas);
SRSLTE_API char* rf_limesdr_devname(void *h);
SRSLTE_API int rf_limesdr_close(void *h);
SRSLTE_API void rf_limesdr_set_tx_cal(void *h, srslte_rf_cal_t *cal);
SRSLTE_API void rf_limesdr_set_rx_cal(void *h, srslte_rf_cal_t *cal);
SRSLTE_API int rf_limesdr_start_rx_stream(void *h);
SRSLTE_API int rf_limesdr_stop_rx_stream(void *h);
SRSLTE_API void rf_limesdr_flush_buffer(void *h);
SRSLTE_API bool rf_limesdr_has_rssi(void *h);
SRSLTE_API float rf_limesdr_get_rssi(void *h);
SRSLTE_API bool rf_limesdr_rx_wait_lo_locked(void *h);
SRSLTE_API void rf_limesdr_set_master_clock_rate(void *h,
double rate);
SRSLTE_API bool rf_limesdr_is_master_clock_dynamic(void *h);
SRSLTE_API double rf_limesdr_set_rx_srate(void *h,
double freq);
SRSLTE_API double rf_limesdr_set_rx_gain(void *h,
double gain);
SRSLTE_API double rf_limesdr_get_rx_gain(void *h);
SRSLTE_API double rf_limesdr_set_tx_gain(void *h,
double gain);
SRSLTE_API double rf_limesdr_get_tx_gain(void *h);
SRSLTE_API void rf_limesdr_suppress_stdout(void *h);
SRSLTE_API void rf_limesdr_register_error_handler(void *h, srslte_rf_error_handler_t error_handler);
SRSLTE_API double rf_limesdr_set_rx_freq(void *h,
double freq);
SRSLTE_API int rf_limesdr_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs);
SRSLTE_API int rf_limesdr_recv_with_time_multi(void *h,
void **data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs);
SRSLTE_API double rf_limesdr_set_tx_srate(void *h,
double freq);
SRSLTE_API double rf_limesdr_set_tx_freq(void *h,
double freq);
SRSLTE_API void rf_limesdr_get_time(void *h,
time_t *secs,
double *frac_secs);
SRSLTE_API int rf_limesdr_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst);
Loading…
Cancel
Save