HackRF: Rx/Tx opem/close new style

This commit is contained in:
f4exb 2017-04-14 01:41:02 +02:00
parent ecdc99f59b
commit dea2764811
5 changed files with 112 additions and 132 deletions

View File

@ -38,39 +38,29 @@ HackRFOutput::HackRFOutput(DeviceSinkAPI *deviceAPI) :
m_settings(), m_settings(),
m_dev(0), m_dev(0),
m_hackRFThread(0), m_hackRFThread(0),
m_deviceDescription("HackRFOutput") m_deviceDescription("HackRFOutput"),
m_running(false)
{ {
openDevice();
m_deviceAPI->setBuddySharedPtr(&m_sharedParams); m_deviceAPI->setBuddySharedPtr(&m_sharedParams);
} }
HackRFOutput::~HackRFOutput() HackRFOutput::~HackRFOutput()
{ {
if (m_dev != 0) if (m_running) stop();
{ closeDevice();
stop();
}
m_deviceAPI->setBuddySharedPtr(0); m_deviceAPI->setBuddySharedPtr(0);
} }
bool HackRFOutput::start(int device) bool HackRFOutput::openDevice()
{ {
// QMutexLocker mutexLocker(&m_mutex);
if (m_dev != 0) if (m_dev != 0)
{ {
stop(); closeDevice();
} }
// 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));
// }
m_sampleSourceFifo.resize(m_settings.m_devSampleRate/(1<<(m_settings.m_log2Interp <= 4 ? m_settings.m_log2Interp : 4))); m_sampleSourceFifo.resize(m_settings.m_devSampleRate/(1<<(m_settings.m_log2Interp <= 4 ? m_settings.m_log2Interp : 4)));
int device = m_deviceAPI->getSampleSinkSequence();
if (m_deviceAPI->getSourceBuddies().size() > 0) if (m_deviceAPI->getSourceBuddies().size() > 0)
{ {
@ -79,40 +69,47 @@ bool HackRFOutput::start(int device)
if (buddySharedParams == 0) if (buddySharedParams == 0)
{ {
qCritical("HackRFOutput::start: could not get shared parameters from buddy"); qCritical("HackRFOutput::openDevice: could not get shared parameters from buddy");
return false; return false;
} }
if (buddy->getDeviceSourceEngine()->state() == DSPDeviceSourceEngine::StRunning) // Rx side is running so it must have device ownership if ((m_dev = buddySharedParams->m_dev) == 0) // device is not opened by buddy
{ {
if ((m_dev = buddySharedParams->m_dev) == 0) // get device handle from Rx but do not take ownership qCritical("HackRFOutput::openDevice: could not get HackRF handle from buddy");
{ return false;
qCritical("HackRFOutput::start: could not get HackRF handle from buddy");
return false;
}
} }
else // Rx is not running so Tx opens device and takes ownership
{
if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0)
{
qCritical("HackRFOutput::start: could not open HackRF #%d", device);
return false;
}
m_sharedParams.m_dev = m_dev; m_sharedParams = *(buddySharedParams); // copy parameters from buddy
} m_sharedParams.m_dev = m_dev;
} }
else // No Rx part open so Tx opens device and takes ownership else
{ {
if (hackrf_init() != HACKRF_SUCCESS) // TODO: this may not work if several HackRF Devices are running concurrently. It should be handled globally in the application
{
qCritical("HackRFInput::openDevice: could not init HackRF");
return false;
}
if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0) if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0)
{ {
qCritical("HackRFOutput::start: could not open HackRF #%d", device); qCritical("HackRFOutput::openDevice: could not open HackRF #%d", device);
return false; return false;
} }
m_sharedParams.m_dev = m_dev; m_sharedParams.m_dev = m_dev;
} }
return true;
}
bool HackRFOutput::start(int device)
{
if (!m_dev) {
return false;
}
if (m_running) stop();
if((m_hackRFThread = new HackRFOutputThread(m_dev, &m_sampleSourceFifo)) == 0) if((m_hackRFThread = new HackRFOutputThread(m_dev, &m_sampleSourceFifo)) == 0)
{ {
qFatal("HackRFOutput::start: out of memory"); qFatal("HackRFOutput::start: out of memory");
@ -123,14 +120,34 @@ bool HackRFOutput::start(int device)
// mutexLocker.unlock(); // mutexLocker.unlock();
applySettings(m_settings, true); applySettings(m_settings, true);
m_hackRFThread->setSamplerate(m_settings.m_devSampleRate);
m_hackRFThread->setLog2Interpolation(m_settings.m_log2Interp);
m_hackRFThread->startWork(); m_hackRFThread->startWork();
qDebug("HackRFOutput::start: started"); qDebug("HackRFOutput::start: started");
m_running = true;
return true; return true;
} }
void HackRFOutput::closeDevice()
{
if (m_deviceAPI->getSourceBuddies().size() == 0)
{
qDebug("HackRFOutput::closeDevice: closing device since Rx side is not open");
if(m_dev != 0) // close HackRF
{
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;
}
void HackRFOutput::stop() void HackRFOutput::stop()
{ {
qDebug("HackRFOutput::stop"); qDebug("HackRFOutput::stop");
@ -143,43 +160,7 @@ void HackRFOutput::stop()
m_hackRFThread = 0; m_hackRFThread = 0;
} }
if (m_dev != 0) m_running = false;
{
hackrf_stop_tx(m_dev);
}
if (m_deviceAPI->getSourceBuddies().size() > 0)
{
DeviceSourceAPI *buddy = m_deviceAPI->getSourceBuddies()[0];
DeviceHackRFParams *buddySharedParams = (DeviceHackRFParams *) buddy->getBuddySharedPtr();
if (buddy->getDeviceSourceEngine()->state() == DSPDeviceSourceEngine::StRunning) // Rx side running
{
if ((m_sharedParams.m_dev != 0) && (buddySharedParams->m_dev == 0)) // Tx has the ownership but not the Rx
{
buddySharedParams->m_dev = m_dev; // transfer ownership
}
}
else // Rx is not running so Tx must have the ownership
{
if(m_dev != 0) // close HackRF
{
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 Rx part open
{
if(m_dev != 0) // close HackRF
{
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;
} }
const QString& HackRFOutput::getDeviceDescription() const const QString& HackRFOutput::getDeviceDescription() const
@ -270,16 +251,19 @@ bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool forc
} }
else else
{ {
qDebug("HackRFOutput::applySettings: sample rate set to %llu S/s", if (m_hackRFThread != 0)
settings.m_devSampleRate); {
m_hackRFThread->setSamplerate(settings.m_devSampleRate); qDebug("HackRFOutput::applySettings: sample rate set to %llu S/s",
settings.m_devSampleRate);
m_hackRFThread->setSamplerate(settings.m_devSampleRate);
}
} }
} }
} }
if ((m_settings.m_log2Interp != settings.m_log2Interp) || force) if ((m_settings.m_log2Interp != settings.m_log2Interp) || force)
{ {
if(m_hackRFThread != 0) if (m_hackRFThread != 0)
{ {
m_hackRFThread->setLog2Interpolation(settings.m_log2Interp); m_hackRFThread->setLog2Interpolation(settings.m_log2Interp);
qDebug() << "HackRFOutput: set interpolation to " << (1<<settings.m_log2Interp); qDebug() << "HackRFOutput: set interpolation to " << (1<<settings.m_log2Interp);

View File

@ -81,6 +81,8 @@ public:
virtual bool handleMessage(const Message& message); virtual bool handleMessage(const Message& message);
private: private:
bool openDevice();
void closeDevice();
bool applySettings(const HackRFOutputSettings& settings, bool force); bool applySettings(const HackRFOutputSettings& settings, bool force);
// hackrf_device *open_hackrf_from_sequence(int sequence); // hackrf_device *open_hackrf_from_sequence(int sequence);
void setCenterFrequency(quint64 freq_hz, qint32 LOppmTenths); void setCenterFrequency(quint64 freq_hz, qint32 LOppmTenths);
@ -92,6 +94,7 @@ private:
HackRFOutputThread* m_hackRFThread; HackRFOutputThread* m_hackRFThread;
QString m_deviceDescription; QString m_deviceDescription;
DeviceHackRFParams m_sharedParams; DeviceHackRFParams m_sharedParams;
bool m_running;
}; };
#endif // INCLUDE_HACKRFINPUT_H #endif // INCLUDE_HACKRFINPUT_H

View File

@ -69,15 +69,26 @@ void HackRFOutputThread::run()
rc = (hackrf_error) hackrf_start_tx(m_dev, tx_callback, this); rc = (hackrf_error) hackrf_start_tx(m_dev, tx_callback, this);
if (rc == HACKRF_SUCCESS)
{
qDebug("HackRFOutputThread::run: started HackRF Tx");
}
else
{
qDebug("HackRFOutputThread::run: failed to start HackRF Tx: %s", hackrf_error_name(rc));
}
m_running = true; m_running = true;
m_startWaiter.wakeAll(); m_startWaiter.wakeAll();
if (rc != HACKRF_SUCCESS) if (rc == HACKRF_SUCCESS)
{
qCritical("HackRFOutputThread::run: failed to start HackRF Tx: %s", hackrf_error_name(rc));
}
else
{ {
if (hackrf_is_streaming(m_dev) == HACKRF_TRUE) {
qDebug("HackRFThread::run: HackRF is streaming");
} else {
qDebug("HackRFThread::run: HackRF is not streaming");
}
while ((m_running) && (hackrf_is_streaming(m_dev) == HACKRF_TRUE)) while ((m_running) && (hackrf_is_streaming(m_dev) == HACKRF_TRUE))
{ {
usleep(200000); usleep(200000);

View File

@ -78,27 +78,23 @@ bool HackRFInput::openDevice()
return false; return false;
} }
if (buddy->getDeviceSinkEngine()->state() == DSPDeviceSinkEngine::StRunning) // Tx side is running so it must have device ownership if (buddySharedParams->m_dev == 0) // device is not opened by buddy
{ {
if ((m_dev = buddySharedParams->m_dev) == 0) // get device handle from Tx but do not take ownership qCritical("HackRFInput::openDevice: could not get HackRF handle from buddy");
{ return false;
qCritical("HackRFInput::openDevice: 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::openDevice: could not open HackRF #%d", device);
return false;
}
m_sharedParams.m_dev = m_dev; m_sharedParams = *(buddySharedParams); // copy parameters from buddy
} m_dev = m_sharedParams.m_dev; // get HackRF handle
} }
else // No Tx part open so Rx opens device and takes ownership else
{ {
if (hackrf_init() != HACKRF_SUCCESS) // TODO: this may not work if several HackRF Devices are running concurrently. It should be handled globally in the application
{
qCritical("HackRFInput::openDevice: could not init HackRF");
return false;
}
if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0) if ((m_dev = DeviceHackRF::open_hackrf(device)) == 0)
{ {
qCritical("HackRFInput::openDevice: could not open HackRF #%d", device); qCritical("HackRFInput::openDevice: could not open HackRF #%d", device);
@ -114,9 +110,8 @@ bool HackRFInput::openDevice()
bool HackRFInput::start(int device) bool HackRFInput::start(int device)
{ {
// QMutexLocker mutexLocker(&m_mutex); // QMutexLocker mutexLocker(&m_mutex);
if (m_dev != 0) if (!m_dev) {
{ return false;
stop();
} }
if (m_running) stop(); if (m_running) stop();
@ -146,34 +141,10 @@ bool HackRFInput::start(int device)
void HackRFInput::closeDevice() void HackRFInput::closeDevice()
{ {
if(m_dev != 0) if (m_deviceAPI->getSinkBuddies().size() == 0)
{ {
hackrf_stop_rx(m_dev); qDebug("HackRFInput::closeDevice: closing device since Tx side is not open");
}
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 if(m_dev != 0) // close BladeRF
{ {
hackrf_close(m_dev); hackrf_close(m_dev);

View File

@ -76,15 +76,26 @@ void HackRFInputThread::run()
rc = (hackrf_error) hackrf_start_rx(m_dev, rx_callback, this); rc = (hackrf_error) hackrf_start_rx(m_dev, rx_callback, this);
if (rc == HACKRF_SUCCESS)
{
qDebug("HackRFThread::run: started HackRF Rx");
}
else
{
qDebug("HackRFThread::run: failed to start HackRF Rx: %s", hackrf_error_name(rc));
}
m_running = true; m_running = true;
m_startWaiter.wakeAll(); m_startWaiter.wakeAll();
if (rc != HACKRF_SUCCESS) if (rc == HACKRF_SUCCESS)
{
qCritical("HackRFThread::run: failed to start HackRF Rx: %s", hackrf_error_name(rc));
}
else
{ {
if (hackrf_is_streaming(m_dev) == HACKRF_TRUE) {
qDebug("HackRFThread::run: HackRF is streaming");
} else {
qDebug("HackRFThread::run: HackRF is not streaming");
}
while ((m_running) && (hackrf_is_streaming(m_dev) == HACKRF_TRUE)) while ((m_running) && (hackrf_is_streaming(m_dev) == HACKRF_TRUE))
{ {
usleep(200000); usleep(200000);