From a02b78d24d6775c3776121b2e070b438d0979ceb Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 8 Jan 2017 00:33:11 +0100 Subject: [PATCH] HackRF input: open and close device considering the possible sink buddy --- devices/hackrf/CMakeLists.txt | 1 + devices/hackrf/devicehackrf.cpp | 17 +++ devices/hackrf/devicehackrf.h | 2 + devices/hackrf/devicehackrfparam.h | 42 +++++ .../samplesource/hackrfinput/hackrfinput.cpp | 144 ++++++++++++++---- .../samplesource/hackrfinput/hackrfinput.h | 2 + 6 files changed, 177 insertions(+), 31 deletions(-) create mode 100644 devices/hackrf/devicehackrfparam.h diff --git a/devices/hackrf/CMakeLists.txt b/devices/hackrf/CMakeLists.txt index 27cd5ea7f..3e8617516 100644 --- a/devices/hackrf/CMakeLists.txt +++ b/devices/hackrf/CMakeLists.txt @@ -6,6 +6,7 @@ set(hackrfdevice_SOURCES set(hackrfdevice_HEADERS devicehackrf.h + devicehackrfparam.h ) if (BUILD_DEBIAN) diff --git a/devices/hackrf/devicehackrf.cpp b/devices/hackrf/devicehackrf.cpp index 972c0d379..a9bb56cf9 100644 --- a/devices/hackrf/devicehackrf.cpp +++ b/devices/hackrf/devicehackrf.cpp @@ -14,8 +14,25 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// +#include #include "devicehackrf.h" +hackrf_device *DeviceHackRF::open_hackrf(int sequence) +{ + hackrf_error rc; + + rc = (hackrf_error) hackrf_init(); + + // TODO: this may not work if several HackRF Devices are running concurrently. It should be handled globally in the application + if (rc != HACKRF_SUCCESS) + { + fprintf(stderr, "DeviceHackRF::open_hackrf: failed to initiate HackRF library %s\n", hackrf_error_name(rc)); + return 0; + } + + return open_hackrf_from_sequence(sequence); +} + hackrf_device *DeviceHackRF::open_hackrf_from_sequence(int sequence) { hackrf_device_list_t *hackrf_devices = hackrf_device_list(); diff --git a/devices/hackrf/devicehackrf.h b/devices/hackrf/devicehackrf.h index d976500d0..d645f95cb 100644 --- a/devices/hackrf/devicehackrf.h +++ b/devices/hackrf/devicehackrf.h @@ -22,6 +22,8 @@ class DeviceHackRF { public: + static hackrf_device *open_hackrf(int sequence); +private: static hackrf_device *open_hackrf_from_sequence(int sequence); }; diff --git a/devices/hackrf/devicehackrfparam.h b/devices/hackrf/devicehackrfparam.h new file mode 100644 index 000000000..83f0f6aec --- /dev/null +++ b/devices/hackrf/devicehackrfparam.h @@ -0,0 +1,42 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef DEVICES_HACKRF_DEVICEHACKRFPARAM_H_ +#define DEVICES_HACKRF_DEVICEHACKRFPARAM_H_ + +#include "libhackrf/hackrf.h" + +/** + * This structure is owned by each of the parties sharing the same physical device + * It allows exchange of information on the common resources + */ +/** + * This structure is owned by each of the parties sharing the same physical device + * It allows exchange of information on the common resources + */ +struct DeviceHackRFParams +{ + struct hackrf_device* m_dev; //!< device handle if the party has ownership else 0 + + DeviceHackRFParams() : + m_dev(0) + { + } +}; + + + +#endif /* DEVICES_HACKRF_DEVICEHACKRFPARAM_H_ */ diff --git a/plugins/samplesource/hackrfinput/hackrfinput.cpp b/plugins/samplesource/hackrfinput/hackrfinput.cpp index 353c6b332..c466d8521 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinput.cpp @@ -14,7 +14,7 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "../hackrfinput/hackrfinput.h" +#include "hackrfinput.h" #include #include @@ -23,7 +23,9 @@ #include "util/simpleserializer.h" #include "dsp/dspcommands.h" #include "dsp/dspengine.h" -#include +#include "device/devicesourceapi.h" +#include "device/devicesinkapi.h" + #include "hackrfinputgui.h" #include "hackrfinputthread.h" @@ -38,11 +40,17 @@ HackRFInput::HackRFInput(DeviceSourceAPI *deviceAPI) : m_hackRFThread(0), m_deviceDescription("HackRF") { + m_deviceAPI->setBuddySharedPtr(&m_sharedParams); } HackRFInput::~HackRFInput() { - stop(); + if (m_dev != 0) + { + stop(); + } + + m_deviceAPI->setBuddySharedPtr(0); } bool HackRFInput::init(const Message& cmd) @@ -52,20 +60,20 @@ bool HackRFInput::init(const Message& cmd) bool HackRFInput::start(int device) { - QMutexLocker mutexLocker(&m_mutex); - hackrf_error rc; +// QMutexLocker mutexLocker(&m_mutex); + if (m_dev != 0) + { + stop(); + } - rc = (hackrf_error) hackrf_init(); - - if (rc != HACKRF_SUCCESS) - { - qCritical("HackRFInput::start: failed to initiate HackRF library %s", hackrf_error_name(rc)); - } - - if (m_dev != 0) - { - stop(); - } +// hackrf_error rc; +// +// rc = (hackrf_error) hackrf_init(); +// +// if (rc != HACKRF_SUCCESS) +// { +// qCritical("HackRFInput::start: failed to initiate HackRF library %s", hackrf_error_name(rc)); +// } if (!m_sampleFifo.setSize(1<<19)) { @@ -73,11 +81,47 @@ bool HackRFInput::start(int device) return false; } - if ((m_dev = DeviceHackRF::open_hackrf_from_sequence(device)) == 0) - { - qCritical("HackRFInput::start: could not open HackRF #%d", device); - return false; - } + + if (m_deviceAPI->getSinkBuddies().size() > 0) + { + DeviceSinkAPI *buddy = m_deviceAPI->getSinkBuddies()[0]; + DeviceHackRFParams *buddySharedParams = (DeviceHackRFParams *) buddy->getBuddySharedPtr(); + + if (buddySharedParams == 0) + { + qCritical("HackRFInput::start: could not get shared parameters from buddy"); + return false; + } + + if (buddy->getDeviceSinkEngine()->state() == DSPDeviceSinkEngine::StRunning) // Tx side is running so it must have device ownership + { + if ((m_dev = buddySharedParams->m_dev) == 0) // get device handle from Tx but do not take ownership + { + qCritical("HackRFInput::start: could not get HackRF handle from buddy"); + return false; + } + } + else // Tx is not running so Rx opens device and takes ownership + { + if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0) + { + qCritical("HackRFInput::start: could not open HackRF #%d", device); + return false; + } + + m_sharedParams.m_dev = m_dev; + } + } + else // No Tx part open so Rx opens device and takes ownership + { + if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0) + { + qCritical("HackRFInput::start: could not open HackRF #%d", device); + return false; + } + + m_sharedParams.m_dev = m_dev; + } if((m_hackRFThread = new HackRFInputThread(m_dev, &m_sampleFifo)) == 0) { @@ -86,7 +130,7 @@ bool HackRFInput::start(int device) return false; } - mutexLocker.unlock(); +// mutexLocker.unlock(); applySettings(m_settings, true); @@ -100,7 +144,7 @@ bool HackRFInput::start(int device) void HackRFInput::stop() { qDebug("HackRFInput::stop"); - QMutexLocker mutexLocker(&m_mutex); +// QMutexLocker mutexLocker(&m_mutex); if(m_hackRFThread != 0) { @@ -109,14 +153,52 @@ void HackRFInput::stop() m_hackRFThread = 0; } - if(m_dev != 0) - { - hackrf_stop_rx(m_dev); - hackrf_close(m_dev); - m_dev = 0; - } + if(m_dev != 0) + { + hackrf_stop_rx(m_dev); + } - hackrf_exit(); + if (m_deviceAPI->getSinkBuddies().size() > 0) + { + DeviceSinkAPI *buddy = m_deviceAPI->getSinkBuddies()[0]; + DeviceHackRFParams *buddySharedParams = (DeviceHackRFParams *) buddy->getBuddySharedPtr(); + + if (buddy->getDeviceSinkEngine()->state() == DSPDeviceSinkEngine::StRunning) // Tx side running + { + if ((m_sharedParams.m_dev != 0) && (buddySharedParams->m_dev == 0)) // Rx has the ownership but not the Tx + { + buddySharedParams->m_dev = m_dev; // transfer ownership + } + } + else // Tx is not running so Rx must have the ownership + { + if(m_dev != 0) // close BladeRF + { + hackrf_close(m_dev); + hackrf_exit(); // TODO: this may not work if several HackRF Devices are running concurrently. It should be handled globally in the application + } + } + } + else // No Tx part open + { + if(m_dev != 0) // close BladeRF + { + hackrf_close(m_dev); + hackrf_exit(); // TODO: this may not work if several HackRF Devices are running concurrently. It should be handled globally in the application + } + } + + m_sharedParams.m_dev = 0; + m_dev = 0; + +// if(m_dev != 0) +// { +// hackrf_stop_rx(m_dev); +// hackrf_close(m_dev); +// m_dev = 0; +// } +// +// hackrf_exit(); } const QString& HackRFInput::getDeviceDescription() const @@ -176,7 +258,7 @@ void HackRFInput::setCenterFrequency(quint64 freq_hz) bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force) { - QMutexLocker mutexLocker(&m_mutex); +// QMutexLocker mutexLocker(&m_mutex); bool forwardChange = false; hackrf_error rc; diff --git a/plugins/samplesource/hackrfinput/hackrfinput.h b/plugins/samplesource/hackrfinput/hackrfinput.h index 9e50eec1f..3a12333f8 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.h +++ b/plugins/samplesource/hackrfinput/hackrfinput.h @@ -22,6 +22,7 @@ #include #include "hackrf/devicehackrf.h" +#include "hackrf/devicehackrfparam.h" #include "hackrfinputsettings.h" class DeviceSourceAPI; @@ -91,6 +92,7 @@ private: struct hackrf_device* m_dev; HackRFInputThread* m_hackRFThread; QString m_deviceDescription; + DeviceHackRFParams m_sharedParams; }; #endif // INCLUDE_HACKRFINPUT_H