|
|
|
@ -36,87 +36,91 @@
|
|
|
|
|
|
|
|
|
|
#include <SoapySDR/Device.h>
|
|
|
|
|
#include <SoapySDR/Formats.h>
|
|
|
|
|
//#include "lime/LimeSuite.h"
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
|
|
SoapySDRKwargs args;
|
|
|
|
|
SoapySDRDevice *device;
|
|
|
|
|
SoapySDRRange *ranges;
|
|
|
|
|
|
|
|
|
|
SoapySDRStream *rxStream;
|
|
|
|
|
SoapySDRStream *txStream;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} rf_soapy_handler_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int soapy_error(void *h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_get_freq_range(void *h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_suppress_handler(const char *x)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_msg_handler(const char *msg)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_suppress_stdout(void *h)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool isLocked(rf_soapy_handler_t *handler, char *sensor_name, void *value_h)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
printf("TODO: implement isLocked()\n");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char* rf_soapy_devname(void* h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
printf("TODO: implement rf_soapy_devname()\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool rf_soapy_rx_wait_lo_locked(void *h)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_set_tx_cal(void *h, srslte_rf_cal_t *cal)
|
|
|
|
|
{
|
|
|
|
|
printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n");
|
|
|
|
|
// not supported
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_set_rx_cal(void *h, srslte_rf_cal_t *cal)
|
|
|
|
|
{
|
|
|
|
|
// not supported
|
|
|
|
|
printf("TODO: implement rf_soapy_set_rx_cal()\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int rf_soapy_start_rx_stream(void *h)
|
|
|
|
|
{
|
|
|
|
|
//printf("starting SOAPY rx stream \n");
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
//SoapySDRStream *rxStream;
|
|
|
|
|
|
|
|
|
|
if(SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0)!=0)//start streaming
|
|
|
|
|
if (SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0) != 0)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -124,41 +128,38 @@ int rf_soapy_start_rx_stream(void *h)
|
|
|
|
|
int rf_soapy_start_tx_stream(void *h)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
//SoapySDRStream *rxStream;
|
|
|
|
|
if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) {
|
|
|
|
|
printf("setupStream fail: %s\n", SoapySDRDevice_lastError());
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(SoapySDRDevice_activateStream(handler->device, handler->txStream, 0, 0, 0) != 0)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int rf_soapy_stop_rx_stream(void *h)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
if (SoapySDRDevice_deactivateStream(handler->device, handler->rxStream, 0, 0) != 0)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int rf_soapy_stop_tx_stream(void *h)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
|
|
|
|
|
if(SoapySDRDevice_deactivateStream(handler->device, handler->txStream, 0, 0) != 0)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rf_soapy_flush_buffer(void *h)
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
@ -170,29 +171,33 @@ void rf_soapy_flush_buffer(void *h)
|
|
|
|
|
} while (n > 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool rf_soapy_has_rssi(void *h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
printf("TODO: implement rf_soapy_has_rssi()\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float rf_soapy_get_rssi(void *h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
printf("TODO: implement rf_soapy_get_rssi()\n");
|
|
|
|
|
return 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: add multi-channel support
|
|
|
|
|
int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
|
|
|
|
|
{//SoapySDRKwargs soapy_args = {};
|
|
|
|
|
{
|
|
|
|
|
size_t length;
|
|
|
|
|
const SoapySDRKwargs *soapy_args = SoapySDRDevice_enumerate(NULL, &length);
|
|
|
|
|
|
|
|
|
|
if(length == 0)
|
|
|
|
|
{
|
|
|
|
|
if (length == 0) {
|
|
|
|
|
printf("No Soapy devices found.\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < length; i++)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < length; i++) {
|
|
|
|
|
printf("Soapy Has Found device #%d: ", (int)i);
|
|
|
|
|
for (size_t j = 0; j < soapy_args[i].size; j++)
|
|
|
|
|
{
|
|
|
|
@ -201,38 +206,27 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SoapySDRrgs_set(&soapy_args, "driver", "rtlsdr");
|
|
|
|
|
SoapySDRDevice *sdr = SoapySDRDevice_make(&(soapy_args[0]));
|
|
|
|
|
|
|
|
|
|
if(sdr == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (sdr == NULL) {
|
|
|
|
|
printf("failed to create SOAPY object\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//SoapySDRKwargs_clear(&soapy_args);
|
|
|
|
|
// create handler
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) malloc(sizeof(rf_soapy_handler_t));
|
|
|
|
|
bzero(handler, sizeof(rf_soapy_handler_t));
|
|
|
|
|
*h = handler;
|
|
|
|
|
handler->device = sdr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//size_t channels[1];
|
|
|
|
|
//channels[0] = 0;
|
|
|
|
|
|
|
|
|
|
if (SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) {
|
|
|
|
|
printf("setupStream fail: %s\n", SoapySDRDevice_lastError());
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int rf_soapy_open(char *args, void **h)
|
|
|
|
|
{
|
|
|
|
|
return rf_soapy_open_multi(args, h, 1);
|
|
|
|
@ -242,28 +236,38 @@ int rf_soapy_open(char *args, void **h)
|
|
|
|
|
int rf_soapy_close(void *h)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
if (handler->txStream) {
|
|
|
|
|
rf_soapy_stop_tx_stream(handler);
|
|
|
|
|
SoapySDRDevice_closeStream(handler->device, handler->txStream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (handler->rxStream) {
|
|
|
|
|
rf_soapy_stop_rx_stream(handler);
|
|
|
|
|
SoapySDRDevice_closeStream(handler->device, handler->rxStream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SoapySDRDevice_unmake(handler->device);
|
|
|
|
|
free(handler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rf_soapy_set_master_clock_rate(void *h, double rate)
|
|
|
|
|
{
|
|
|
|
|
// Allow the soapy to automatically set the appropriate clock rate
|
|
|
|
|
|
|
|
|
|
printf("SET MASTER CLOCK RATE\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool rf_soapy_is_master_clock_dynamic(void *h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
printf("TODO: implement rf_soapy_is_master_clock_dynamic()\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double rf_soapy_set_rx_srate(void *h, double rate)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0) {
|
|
|
|
|
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError());
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
@ -276,8 +280,7 @@ double rf_soapy_set_rx_srate(void *h, double rate)
|
|
|
|
|
double rf_soapy_set_tx_srate(void *h, double rate)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0) {
|
|
|
|
|
printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError());
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
@ -286,9 +289,9 @@ double rf_soapy_set_tx_srate(void *h, double rate)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double rf_soapy_set_rx_gain(void *h, double gain)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_RX, 0, gain) != 0)
|
|
|
|
|
{
|
|
|
|
@ -296,10 +299,11 @@ double rf_soapy_set_rx_gain(void *h, double gain)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
double ret = rf_soapy_get_rx_gain(h);
|
|
|
|
|
printf("gain has been set to %f.2 \n",ret);
|
|
|
|
|
printf("Rx gain has been set to %f.2 \n",ret);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double rf_soapy_set_tx_gain(void *h, double gain)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
@ -309,27 +313,27 @@ double rf_soapy_set_tx_gain(void *h, double gain)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
double ret = rf_soapy_get_rx_gain(h);
|
|
|
|
|
printf("gain has been set to %f.2 \n",ret);
|
|
|
|
|
printf("Tx gain has been set to %f.2 \n",ret);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double rf_soapy_get_rx_gain(void *h)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_RX,0);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double rf_soapy_get_tx_gain(void *h)
|
|
|
|
|
{
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_TX,0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double rf_soapy_set_rx_freq(void *h, double freq)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
if (SoapySDRDevice_setFrequency(handler->device, SOAPY_SDR_RX, 0, freq, NULL) != 0)
|
|
|
|
|
{
|
|
|
|
@ -338,9 +342,8 @@ double rf_soapy_set_rx_freq(void *h, double freq)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double ret = SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0);
|
|
|
|
|
printf("Frequency has been set to %f : \n",ret);
|
|
|
|
|
printf("Rx frequency has been set to %f : \n",ret);
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rf_soapy_set_tx_freq(void *h, double freq)
|
|
|
|
@ -352,7 +355,7 @@ double rf_soapy_set_tx_freq(void *h, double freq)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
double ret = SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0);
|
|
|
|
|
printf("Frequency has been set to %f : \n",ret);
|
|
|
|
|
printf("Tx frequency has been set to %f : \n",ret);
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
@ -382,7 +385,6 @@ int rf_soapy_recv_with_time_multi(void *h,
|
|
|
|
|
long long timeNs; //timestamp for receive buffer
|
|
|
|
|
int n = 0;
|
|
|
|
|
do {
|
|
|
|
|
|
|
|
|
|
size_t rx_samples = nsamples;
|
|
|
|
|
|
|
|
|
|
if (rx_samples > nsamples - n)
|
|
|
|
@ -408,8 +410,6 @@ int rf_soapy_recv_with_time_multi(void *h,
|
|
|
|
|
//*frac_secs = (timeNs % 1000000000)/1000000000;
|
|
|
|
|
// printf("ret=%d, flags=%d, timeNs=%lld\n", ret, flags, timeNs);
|
|
|
|
|
return n;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rf_soapy_recv_with_time(void *h,
|
|
|
|
@ -433,25 +433,14 @@ int rf_soapy_send_timed(void *h,
|
|
|
|
|
bool is_start_of_burst,
|
|
|
|
|
bool is_end_of_burst)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int flags;
|
|
|
|
|
long long timeNs;
|
|
|
|
|
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
|
|
|
|
timeNs = secs * 1000000000;
|
|
|
|
|
timeNs = timeNs + (frac_secs * 1000000000);
|
|
|
|
|
int ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, &data, nsamples, &flags, timeNs, 100000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(ret != nsamples)
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|