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