From 124af5a7b4b031ebb9ef8445edcf28badf84f553 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 30 Oct 2018 01:58:39 +0100 Subject: [PATCH] SoapySDR support: input: open and close --- devices/bladerf2/devicebladerf2shared.cpp | 3 +- devices/soapysdr/CMakeLists.txt | 2 + devices/soapysdr/devicesoapysdr.cpp | 5 + devices/soapysdr/devicesoapysdr.h | 1 + .../soapysdrinput/soapysdrinput.cpp | 120 +++++++++++++++++- .../soapysdrinput/soapysdrinput.h | 7 + 6 files changed, 135 insertions(+), 3 deletions(-) diff --git a/devices/bladerf2/devicebladerf2shared.cpp b/devices/bladerf2/devicebladerf2shared.cpp index 7339a7021..95a305f70 100644 --- a/devices/bladerf2/devicebladerf2shared.cpp +++ b/devices/bladerf2/devicebladerf2shared.cpp @@ -25,7 +25,8 @@ const int DeviceBladeRF2Shared::m_sampleFifoMinSize32 = 150000; // Fixed for DeviceBladeRF2Shared::DeviceBladeRF2Shared() : m_dev(0), m_channel(-1), - m_source(0) + m_source(0), + m_sink(0) {} DeviceBladeRF2Shared::~DeviceBladeRF2Shared() diff --git a/devices/soapysdr/CMakeLists.txt b/devices/soapysdr/CMakeLists.txt index 5ee756732..c410e6ee2 100644 --- a/devices/soapysdr/CMakeLists.txt +++ b/devices/soapysdr/CMakeLists.txt @@ -5,11 +5,13 @@ set (CMAKE_CXX_STANDARD 11) set(soapysdrdevice_SOURCES devicesoapysdr.cpp devicesoapysdrscan.cpp + devicesoapysdrshared.cpp ) set(soapysdrdevice_HEADERS devicesoapysdr.h devicesoapysdrscan.h + devicesoapysdrshared.h ) if (BUILD_DEBIAN) diff --git a/devices/soapysdr/devicesoapysdr.cpp b/devices/soapysdr/devicesoapysdr.cpp index 6cb06b258..2f5e18a1b 100644 --- a/devices/soapysdr/devicesoapysdr.cpp +++ b/devices/soapysdr/devicesoapysdr.cpp @@ -36,6 +36,11 @@ SoapySDR::Device *DeviceSoapySDR::openSoapySDR(uint32_t sequence) return openopenSoapySDRFromSequence(sequence); } +void DeviceSoapySDR::closeSoapySdr(SoapySDR::Device *device) +{ + SoapySDR::Device::unmake(device); +} + SoapySDR::Device *DeviceSoapySDR::openopenSoapySDRFromSequence(uint32_t sequence) { if (sequence > m_scanner.getNbDevices()) diff --git a/devices/soapysdr/devicesoapysdr.h b/devices/soapysdr/devicesoapysdr.h index 95e0b0d64..be697024f 100644 --- a/devices/soapysdr/devicesoapysdr.h +++ b/devices/soapysdr/devicesoapysdr.h @@ -28,6 +28,7 @@ class DEVICES_API DeviceSoapySDR public: static DeviceSoapySDR& instance(); SoapySDR::Device *openSoapySDR(uint32_t sequence); + void closeSoapySdr(SoapySDR::Device *device); uint32_t getNbDevices() const { return m_scanner.getNbDevices(); } const std::vector& getDevicesEnumeration() const { return m_scanner.getDevicesEnumeration(); } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index c62ab43b2..9bea83d1a 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -16,10 +16,19 @@ #include "util/simpleserializer.h" +#include "device/devicesourceapi.h" +#include "device/devicesinkapi.h" +#include "dsp/dspcommands.h" +#include "dsp/filerecord.h" +#include "dsp/dspengine.h" +#include "soapysdr/devicesoapysdr.h" + #include "soapysdrinput.h" -SoapySDRInput::SoapySDRInput(DeviceSourceAPI *deviceAPI __attribute__((unused))) : - m_deviceDescription("SoapySDRInput") +SoapySDRInput::SoapySDRInput(DeviceSourceAPI *deviceAPI) : + m_deviceAPI(deviceAPI), + m_deviceDescription("SoapySDRInput"), + m_running(false) { } @@ -32,6 +41,113 @@ void SoapySDRInput::destroy() delete this; } +bool SoapySDRInput::openDevice() +{ + if (!m_sampleFifo.setSize(96000 * 4)) + { + qCritical("SoapySDRInput::openDevice: could not allocate SampleFifo"); + return false; + } + else + { + qDebug("SoapySDRInput::openDevice: allocated SampleFifo"); + } + + // look for Rx buddies and get reference to the device object + if (m_deviceAPI->getSourceBuddies().size() > 0) // look source sibling first + { + qDebug("SoapySDRInput::openDevice: look in Rx buddies"); + + DeviceSourceAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0]; + DeviceSoapySDRShared *deviceSoapySDRShared = (DeviceSoapySDRShared*) sourceBuddy->getBuddySharedPtr(); + + if (deviceSoapySDRShared == 0) + { + qCritical("SoapySDRInput::openDevice: the source buddy shared pointer is null"); + return false; + } + + SoapySDR::Device *device = deviceSoapySDRShared->m_device; + + if (device == 0) + { + qCritical("SoapySDRInput::openDevice: cannot get device pointer from Rx buddy"); + return false; + } + + m_deviceShared.m_device = device; + } + // look for Tx buddies and get reference to the device object + else if (m_deviceAPI->getSinkBuddies().size() > 0) // then sink + { + qDebug("SoapySDRInput::openDevice: look in Tx buddies"); + + DeviceSinkAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0]; + DeviceSoapySDRShared *deviceSoapySDRShared = (DeviceSoapySDRShared*) sinkBuddy->getBuddySharedPtr(); + + if (deviceSoapySDRShared == 0) + { + qCritical("SoapySDRInput::openDevice: the sink buddy shared pointer is null"); + return false; + } + + SoapySDR::Device *device = deviceSoapySDRShared->m_device; + + if (device == 0) + { + qCritical("SoapySDRInput::openDevice: cannot get device pointer from Tx buddy"); + return false; + } + + m_deviceShared.m_device = device; + } + // There are no buddies then create the first SoapySDR device + else + { + qDebug("SoapySDRInput::openDevice: open device here"); + DeviceSoapySDR& deviceSoapySDR = DeviceSoapySDR::instance(); + m_deviceShared.m_device = deviceSoapySDR.openSoapySDR(m_deviceAPI->getSampleSourceSequence()); + + if (!m_deviceShared.m_device) + { + qCritical("BladeRF2Input::openDevice: cannot open BladeRF2 device"); + return false; + } + } + + m_deviceShared.m_channel = m_deviceAPI->getItemIndex(); // publicly allocate channel + m_deviceShared.m_source = this; + m_deviceAPI->setBuddySharedPtr(&m_deviceShared); // propagate common parameters to API + return true; +} + +void SoapySDRInput::closeDevice() +{ + if (m_deviceShared.m_device == 0) { // was never open + return; + } + + if (m_running) { + stop(); + } + +// if (m_thread) { // stills own the thread => transfer to a buddy +// moveThreadToBuddy(); +// } + + m_deviceShared.m_channel = -1; // publicly release channel + m_deviceShared.m_source = 0; + + // No buddies so effectively close the device + + if ((m_deviceAPI->getSinkBuddies().size() == 0) && (m_deviceAPI->getSourceBuddies().size() == 0)) + { + DeviceSoapySDR& deviceSoapySDR = DeviceSoapySDR::instance(); + deviceSoapySDR.closeSoapySdr(m_deviceShared.m_device); + m_deviceShared.m_device = 0; + } +} + void SoapySDRInput::init() { } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.h b/plugins/samplesource/soapysdrinput/soapysdrinput.h index 0beeb42d3..2c03ea257 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.h @@ -21,6 +21,7 @@ #include #include +#include "soapysdr/devicesoapysdrshared.h" #include "dsp/devicesamplesource.h" class DeviceSourceAPI; @@ -48,7 +49,13 @@ public: virtual bool handleMessage(const Message& message); private: + DeviceSourceAPI *m_deviceAPI; + DeviceSoapySDRShared m_deviceShared; QString m_deviceDescription; + bool m_running; + + bool openDevice(); + void closeDevice(); };