2017-01-07 22:13:20 -05:00
///////////////////////////////////////////////////////////////////////////////////
// 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 //
2019-04-11 00:39:30 -04:00
// (at your option) any later version. //
2017-01-07 22:13:20 -05:00
// //
// 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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
# include <string.h>
# include <errno.h>
2018-12-26 15:03:26 -05:00
2017-01-07 22:13:20 -05:00
# include <QDebug>
2018-12-26 15:03:26 -05:00
# include <QNetworkReply>
# include <QBuffer>
2017-01-07 22:13:20 -05:00
2017-12-09 19:57:50 -05:00
# include "SWGDeviceSettings.h"
# include "SWGDeviceState.h"
2017-01-07 22:13:20 -05:00
# include "util/simpleserializer.h"
# include "dsp/dspcommands.h"
# include "dsp/dspengine.h"
2019-05-08 16:11:53 -04:00
# include "device/deviceapi.h"
2017-08-08 16:37:53 -04:00
# include "hackrf/devicehackrfshared.h"
2017-01-07 22:13:20 -05:00
# include "hackrfoutputthread.h"
2018-12-26 15:03:26 -05:00
# include "hackrfoutput.h"
2017-01-07 22:13:20 -05:00
MESSAGE_CLASS_DEFINITION ( HackRFOutput : : MsgConfigureHackRF , Message )
2017-12-14 12:02:49 -05:00
MESSAGE_CLASS_DEFINITION ( HackRFOutput : : MsgStartStop , Message )
2017-01-07 22:13:20 -05:00
MESSAGE_CLASS_DEFINITION ( HackRFOutput : : MsgReportHackRF , Message )
2019-05-08 16:11:53 -04:00
HackRFOutput : : HackRFOutput ( DeviceAPI * deviceAPI ) :
2017-01-07 22:13:20 -05:00
m_deviceAPI ( deviceAPI ) ,
m_settings ( ) ,
2019-11-14 19:04:24 -05:00
m_dev ( nullptr ) ,
m_hackRFThread ( nullptr ) ,
2017-04-13 19:41:02 -04:00
m_deviceDescription ( " HackRFOutput " ) ,
m_running ( false )
2017-01-07 22:13:20 -05:00
{
2017-04-13 19:41:02 -04:00
openDevice ( ) ;
2019-05-20 18:27:08 -04:00
m_deviceAPI - > setNbSinkStreams ( 1 ) ;
2017-01-07 22:13:20 -05:00
m_deviceAPI - > setBuddySharedPtr ( & m_sharedParams ) ;
2018-12-26 15:03:26 -05:00
m_networkManager = new QNetworkAccessManager ( ) ;
connect ( m_networkManager , SIGNAL ( finished ( QNetworkReply * ) ) , this , SLOT ( networkManagerFinished ( QNetworkReply * ) ) ) ;
2017-01-07 22:13:20 -05:00
}
HackRFOutput : : ~ HackRFOutput ( )
{
2018-12-26 15:03:26 -05:00
disconnect ( m_networkManager , SIGNAL ( finished ( QNetworkReply * ) ) , this , SLOT ( networkManagerFinished ( QNetworkReply * ) ) ) ;
delete m_networkManager ;
if ( m_running ) {
stop ( ) ;
}
2017-04-13 19:41:02 -04:00
closeDevice ( ) ;
2017-01-07 22:13:20 -05:00
m_deviceAPI - > setBuddySharedPtr ( 0 ) ;
}
2017-09-16 05:34:25 -04:00
void HackRFOutput : : destroy ( )
{
delete this ;
}
2017-04-13 19:41:02 -04:00
bool HackRFOutput : : openDevice ( )
2017-01-07 22:13:20 -05:00
{
if ( m_dev ! = 0 )
{
2017-04-13 19:41:02 -04:00
closeDevice ( ) ;
2017-01-07 22:13:20 -05:00
}
2019-11-14 19:04:24 -05:00
m_sampleSourceFifo . resize ( SampleSourceFifo : : getSizePolicy ( m_settings . m_devSampleRate ) ) ;
2017-01-07 22:13:20 -05:00
if ( m_deviceAPI - > getSourceBuddies ( ) . size ( ) > 0 )
{
2019-05-08 16:11:53 -04:00
DeviceAPI * buddy = m_deviceAPI - > getSourceBuddies ( ) [ 0 ] ;
2017-01-07 22:13:20 -05:00
DeviceHackRFParams * buddySharedParams = ( DeviceHackRFParams * ) buddy - > getBuddySharedPtr ( ) ;
if ( buddySharedParams = = 0 )
{
2017-04-13 19:41:02 -04:00
qCritical ( " HackRFOutput::openDevice: could not get shared parameters from buddy " ) ;
2017-01-07 22:13:20 -05:00
return false ;
}
2017-04-13 19:41:02 -04:00
if ( ( m_dev = buddySharedParams - > m_dev ) = = 0 ) // device is not opened by buddy
2017-01-07 22:13:20 -05:00
{
2017-04-13 19:41:02 -04:00
qCritical ( " HackRFOutput::openDevice: could not get HackRF handle from buddy " ) ;
return false ;
2017-01-07 22:13:20 -05:00
}
2017-04-13 19:41:02 -04:00
m_sharedParams = * ( buddySharedParams ) ; // copy parameters from buddy
m_sharedParams . m_dev = m_dev ;
2017-01-07 22:13:20 -05:00
}
2017-04-13 19:41:02 -04:00
else
2017-01-07 22:13:20 -05:00
{
2019-05-08 16:11:53 -04:00
if ( ( m_dev = DeviceHackRF : : open_hackrf ( qPrintable ( m_deviceAPI - > getSamplingDeviceSerial ( ) ) ) ) = = 0 )
2017-01-07 22:13:20 -05:00
{
2019-05-08 16:11:53 -04:00
qCritical ( " HackRFOutput::openDevice: could not open HackRF %s " , qPrintable ( m_deviceAPI - > getSamplingDeviceSerial ( ) ) ) ;
2017-01-07 22:13:20 -05:00
return false ;
}
m_sharedParams . m_dev = m_dev ;
}
2017-04-13 19:41:02 -04:00
return true ;
}
2017-12-25 06:59:44 -05:00
void HackRFOutput : : init ( )
{
applySettings ( m_settings , true ) ;
}
2017-04-13 21:44:49 -04:00
bool HackRFOutput : : start ( )
2017-04-13 19:41:02 -04:00
{
if ( ! m_dev ) {
return false ;
}
2019-03-30 19:40:42 -04:00
if ( m_running ) {
stop ( ) ;
}
2017-04-13 19:41:02 -04:00
2018-02-24 04:29:27 -05:00
m_hackRFThread = new HackRFOutputThread ( m_dev , & m_sampleSourceFifo ) ;
2017-01-07 22:13:20 -05:00
// mutexLocker.unlock();
applySettings ( m_settings , true ) ;
2019-04-02 07:43:47 -04:00
m_hackRFThread - > setLog2Interpolation ( m_settings . m_log2Interp ) ;
m_hackRFThread - > setFcPos ( ( int ) m_settings . m_fcPos ) ;
2017-01-07 22:13:20 -05:00
m_hackRFThread - > startWork ( ) ;
qDebug ( " HackRFOutput::start: started " ) ;
2017-04-13 19:41:02 -04:00
m_running = true ;
2017-01-07 22:13:20 -05:00
return true ;
}
2017-04-13 19:41:02 -04:00
void HackRFOutput : : closeDevice ( )
2017-01-07 22:13:20 -05:00
{
2017-04-13 19:41:02 -04:00
if ( m_deviceAPI - > getSourceBuddies ( ) . size ( ) = = 0 )
2017-01-07 22:13:20 -05:00
{
2017-04-13 19:41:02 -04:00
qDebug ( " HackRFOutput::closeDevice: closing device since Rx side is not open " ) ;
2017-01-07 22:13:20 -05:00
if ( m_dev ! = 0 ) // close HackRF
{
hackrf_close ( m_dev ) ;
2017-04-13 19:49:48 -04:00
//hackrf_exit(); // TODO: this may not work if several HackRF Devices are running concurrently. It should be handled globally in the application
2017-01-07 22:13:20 -05:00
}
}
m_sharedParams . m_dev = 0 ;
m_dev = 0 ;
}
2017-04-13 19:41:02 -04:00
void HackRFOutput : : stop ( )
{
qDebug ( " HackRFOutput::stop " ) ;
// QMutexLocker mutexLocker(&m_mutex);
if ( m_hackRFThread ! = 0 )
{
m_hackRFThread - > stopWork ( ) ;
delete m_hackRFThread ;
m_hackRFThread = 0 ;
}
m_running = false ;
}
2017-12-27 22:04:50 -05:00
QByteArray HackRFOutput : : serialize ( ) const
{
return m_settings . serialize ( ) ;
}
bool HackRFOutput : : deserialize ( const QByteArray & data )
{
bool success = true ;
if ( ! m_settings . deserialize ( data ) )
{
m_settings . resetToDefaults ( ) ;
success = false ;
}
MsgConfigureHackRF * message = MsgConfigureHackRF : : create ( m_settings , true ) ;
m_inputMessageQueue . push ( message ) ;
if ( m_guiMessageQueue )
{
MsgConfigureHackRF * messageToGUI = MsgConfigureHackRF : : create ( m_settings , true ) ;
m_guiMessageQueue - > push ( messageToGUI ) ;
}
return success ;
}
2017-01-07 22:13:20 -05:00
const QString & HackRFOutput : : getDeviceDescription ( ) const
{
return m_deviceDescription ;
}
int HackRFOutput : : getSampleRate ( ) const
{
int rate = m_settings . m_devSampleRate ;
return ( rate / ( 1 < < m_settings . m_log2Interp ) ) ;
}
quint64 HackRFOutput : : getCenterFrequency ( ) const
{
return m_settings . m_centerFrequency ;
}
2017-12-27 22:04:50 -05:00
void HackRFOutput : : setCenterFrequency ( qint64 centerFrequency )
{
HackRFOutputSettings settings = m_settings ;
settings . m_centerFrequency = centerFrequency ;
MsgConfigureHackRF * message = MsgConfigureHackRF : : create ( settings , false ) ;
m_inputMessageQueue . push ( message ) ;
if ( m_guiMessageQueue )
{
MsgConfigureHackRF * messageToGUI = MsgConfigureHackRF : : create ( settings , false ) ;
m_guiMessageQueue - > push ( messageToGUI ) ;
}
}
2017-01-07 22:13:20 -05:00
bool HackRFOutput : : handleMessage ( const Message & message )
{
if ( MsgConfigureHackRF : : match ( message ) )
{
MsgConfigureHackRF & conf = ( MsgConfigureHackRF & ) message ;
qDebug ( ) < < " HackRFOutput::handleMessage: MsgConfigureHackRF " ;
2017-10-14 01:13:57 -04:00
bool success = applySettings ( conf . getSettings ( ) , conf . getForce ( ) ) ;
2017-01-07 22:13:20 -05:00
if ( ! success )
{
2017-09-17 18:01:29 -04:00
qDebug ( " HackRFOutput::handleMessage: MsgConfigureHackRF: config error " ) ;
2017-01-07 22:13:20 -05:00
}
return true ;
}
2017-12-14 12:02:49 -05:00
else if ( MsgStartStop : : match ( message ) )
{
MsgStartStop & cmd = ( MsgStartStop & ) message ;
qDebug ( ) < < " HackRFOutput::handleMessage: MsgStartStop: " < < ( cmd . getStartStop ( ) ? " start " : " stop " ) ;
if ( cmd . getStartStop ( ) )
{
2019-05-08 16:11:53 -04:00
if ( m_deviceAPI - > initDeviceEngine ( ) )
2017-12-14 12:02:49 -05:00
{
2019-05-08 16:11:53 -04:00
m_deviceAPI - > startDeviceEngine ( ) ;
2017-12-14 12:02:49 -05:00
}
}
else
{
2019-05-08 16:11:53 -04:00
m_deviceAPI - > stopDeviceEngine ( ) ;
2017-12-14 12:02:49 -05:00
}
2018-12-26 15:03:26 -05:00
if ( m_settings . m_useReverseAPI ) {
webapiReverseSendStartStop ( cmd . getStartStop ( ) ) ;
}
2017-12-14 12:02:49 -05:00
return true ;
}
2019-03-30 19:40:42 -04:00
else if ( DeviceHackRFShared : : MsgSynchronizeFrequency : : match ( message ) )
{
DeviceHackRFShared : : MsgSynchronizeFrequency & freqMsg = ( DeviceHackRFShared : : MsgSynchronizeFrequency & ) message ;
qint64 centerFrequency = DeviceSampleSink : : calculateCenterFrequency (
freqMsg . getFrequency ( ) ,
0 ,
m_settings . m_log2Interp ,
2019-04-01 08:40:01 -04:00
( DeviceSampleSink : : fcPos_t ) m_settings . m_fcPos ,
2019-03-30 19:40:42 -04:00
m_settings . m_devSampleRate ) ;
qDebug ( " HackRFOutput::handleMessage: MsgSynchronizeFrequency: centerFrequency: %lld Hz " , centerFrequency ) ;
HackRFOutputSettings settings = m_settings ;
settings . m_centerFrequency = centerFrequency ;
if ( m_guiMessageQueue )
{
MsgConfigureHackRF * messageToGUI = MsgConfigureHackRF : : create ( settings , false ) ;
m_guiMessageQueue - > push ( messageToGUI ) ;
}
m_settings . m_centerFrequency = settings . m_centerFrequency ;
int sampleRate = m_settings . m_devSampleRate / ( 1 < < m_settings . m_log2Interp ) ;
DSPSignalNotification * notif = new DSPSignalNotification ( sampleRate , m_settings . m_centerFrequency ) ;
m_deviceAPI - > getDeviceEngineInputMessageQueue ( ) - > push ( notif ) ;
return true ;
}
2017-01-07 22:13:20 -05:00
else
{
return false ;
}
}
2017-12-28 19:40:34 -05:00
void HackRFOutput : : setDeviceCenterFrequency ( quint64 freq_hz , qint32 LOppmTenths )
2017-01-07 22:13:20 -05:00
{
2019-03-30 19:40:42 -04:00
if ( ! m_dev ) {
return ;
}
2017-01-07 22:13:20 -05:00
2019-03-30 19:40:42 -04:00
qint64 df = ( ( qint64 ) freq_hz * LOppmTenths ) / 10000000LL ;
hackrf_error rc = ( hackrf_error ) hackrf_set_freq ( m_dev , static_cast < uint64_t > ( freq_hz + df ) ) ;
2017-01-07 22:13:20 -05:00
2019-03-30 19:40:42 -04:00
if ( rc ! = HACKRF_SUCCESS ) {
qWarning ( " HackRFOutput::setDeviceCenterFrequency: could not frequency to %llu Hz " , freq_hz + df ) ;
} else {
qDebug ( " HackRFOutput::setDeviceCenterFrequency: frequency set to %llu Hz " , freq_hz + df ) ;
}
2017-01-07 22:13:20 -05:00
}
bool HackRFOutput : : applySettings ( const HackRFOutputSettings & settings , bool force )
{
// QMutexLocker mutexLocker(&m_mutex);
2017-08-08 15:30:04 -04:00
bool forwardChange = false ;
bool suspendThread = false ;
bool threadWasRunning = false ;
2017-01-07 22:13:20 -05:00
hackrf_error rc ;
2018-12-26 15:03:26 -05:00
QList < QString > reverseAPIKeys ;
qDebug ( ) < < " HackRFOutput::applySettings "
2019-03-30 15:44:55 -04:00
< < " m_centerFrequency: " < < settings . m_centerFrequency
< < " m_LOppmTenths: " < < settings . m_LOppmTenths
< < " m_bandwidth: " < < settings . m_bandwidth
< < " m_devSampleRate: " < < settings . m_devSampleRate
< < " m_log2Interp: " < < settings . m_log2Interp
2019-03-31 17:09:50 -04:00
< < " m_fcPos: " < < settings . m_fcPos
2019-03-30 15:44:55 -04:00
< < " m_biasT: " < < settings . m_biasT
< < " m_lnaExt: " < < settings . m_lnaExt
< < " m_vgaGain: " < < settings . m_vgaGain
< < " m_useReverseAPI: " < < settings . m_useReverseAPI
< < " m_reverseAPIAddress: " < < settings . m_reverseAPIAddress
< < " m_reverseAPIPort: " < < settings . m_reverseAPIPort
< < " m_reverseAPIDeviceIndex: " < < settings . m_reverseAPIDeviceIndex
2018-12-26 15:03:26 -05:00
< < " force: " < < force ;
if ( ( m_settings . m_devSampleRate ! = settings . m_devSampleRate ) | | force ) {
reverseAPIKeys . append ( " devSampleRate " ) ;
}
2017-01-07 22:13:20 -05:00
2017-08-08 15:30:04 -04:00
if ( ( m_settings . m_devSampleRate ! = settings . m_devSampleRate ) | |
2017-08-08 17:09:51 -04:00
( m_settings . m_log2Interp ! = settings . m_log2Interp ) | | force )
2017-08-08 15:30:04 -04:00
{
suspendThread = true ;
}
if ( suspendThread )
{
if ( m_hackRFThread )
{
if ( m_hackRFThread - > isRunning ( ) )
{
m_hackRFThread - > stopWork ( ) ;
threadWasRunning = true ;
}
}
}
2017-01-09 19:02:28 -05:00
if ( ( m_settings . m_devSampleRate ! = settings . m_devSampleRate ) | | ( m_settings . m_log2Interp ! = settings . m_log2Interp ) | | force )
{
2017-01-07 22:13:20 -05:00
forwardChange = true ;
2019-11-14 19:04:24 -05:00
unsigned int fifoRate = std : : max (
( unsigned int ) settings . m_devSampleRate / ( 1 < < settings . m_log2Interp ) ,
DeviceHackRFShared : : m_sampleFifoMinRate ) ;
m_sampleSourceFifo . resize ( SampleSourceFifo : : getSizePolicy ( fifoRate ) ) ;
2017-01-09 19:02:28 -05:00
}
if ( ( m_settings . m_devSampleRate ! = settings . m_devSampleRate ) | | force )
{
2017-01-07 22:13:20 -05:00
if ( m_dev ! = 0 )
{
2017-01-09 19:02:28 -05:00
rc = ( hackrf_error ) hackrf_set_sample_rate_manual ( m_dev , settings . m_devSampleRate , 1 ) ;
2017-01-07 22:13:20 -05:00
if ( rc ! = HACKRF_SUCCESS )
{
2017-04-01 18:23:02 -04:00
qCritical ( " HackRFOutput::applySettings: could not set sample rate to %llu S/s: %s " ,
2017-01-09 19:02:28 -05:00
settings . m_devSampleRate ,
2017-01-07 22:13:20 -05:00
hackrf_error_name ( rc ) ) ;
}
else
{
2017-08-08 07:12:16 -04:00
qDebug ( " HackRFOutput::applySettings: sample rate set to %llu S/s " ,
settings . m_devSampleRate ) ;
2017-01-07 22:13:20 -05:00
}
}
}
if ( ( m_settings . m_log2Interp ! = settings . m_log2Interp ) | | force )
{
2018-12-26 15:03:26 -05:00
reverseAPIKeys . append ( " log2Interp " ) ;
2017-04-13 19:41:02 -04:00
if ( m_hackRFThread ! = 0 )
2017-01-07 22:13:20 -05:00
{
2017-01-09 19:02:28 -05:00
m_hackRFThread - > setLog2Interpolation ( settings . m_log2Interp ) ;
qDebug ( ) < < " HackRFOutput: set interpolation to " < < ( 1 < < settings . m_log2Interp ) ;
2017-01-07 22:13:20 -05:00
}
}
2019-03-30 19:40:42 -04:00
if ( ( m_settings . m_centerFrequency ! = settings . m_centerFrequency ) | | force ) {
2018-12-26 15:03:26 -05:00
reverseAPIKeys . append ( " centerFrequency " ) ;
}
if ( ( m_settings . m_LOppmTenths ! = settings . m_LOppmTenths ) | | force ) {
reverseAPIKeys . append ( " LOppmTenths " ) ;
}
2019-04-02 07:43:47 -04:00
if ( ( m_settings . m_fcPos ! = settings . m_fcPos ) | | force ) {
reverseAPIKeys . append ( " fcPos " ) ;
}
2019-08-28 02:45:58 -04:00
if ( ( m_settings . m_transverterMode ! = settings . m_transverterMode ) | | force ) {
reverseAPIKeys . append ( " transverterMode " ) ;
}
if ( ( m_settings . m_transverterDeltaFrequency ! = settings . m_transverterDeltaFrequency ) | | force ) {
reverseAPIKeys . append ( " transverterDeltaFrequency " ) ;
}
2018-12-26 15:03:26 -05:00
2019-04-01 08:40:01 -04:00
if ( ( m_settings . m_centerFrequency ! = settings . m_centerFrequency ) | |
( m_settings . m_devSampleRate ! = settings . m_devSampleRate ) | |
( m_settings . m_LOppmTenths ! = settings . m_LOppmTenths ) | |
( m_settings . m_log2Interp ! = settings . m_log2Interp ) | |
2019-08-28 02:45:58 -04:00
( m_settings . m_fcPos ! = settings . m_fcPos ) | |
( m_settings . m_transverterMode ! = settings . m_transverterMode ) | |
( m_settings . m_transverterDeltaFrequency ! = settings . m_transverterDeltaFrequency ) | | force )
2017-01-07 22:13:20 -05:00
{
2019-03-30 19:40:42 -04:00
qint64 deviceCenterFrequency = DeviceSampleSink : : calculateDeviceCenterFrequency (
settings . m_centerFrequency ,
2019-08-28 02:45:58 -04:00
settings . m_transverterDeltaFrequency ,
2019-03-30 19:40:42 -04:00
settings . m_log2Interp ,
2019-04-01 08:40:01 -04:00
( DeviceSampleSink : : fcPos_t ) settings . m_fcPos ,
2019-08-28 02:45:58 -04:00
settings . m_devSampleRate ,
2019-09-15 07:31:37 -04:00
settings . m_transverterMode ) ;
2019-03-30 19:40:42 -04:00
setDeviceCenterFrequency ( deviceCenterFrequency , settings . m_LOppmTenths ) ;
if ( m_deviceAPI - > getSourceBuddies ( ) . size ( ) > 0 )
{
2019-05-08 16:11:53 -04:00
DeviceAPI * buddy = m_deviceAPI - > getSourceBuddies ( ) [ 0 ] ;
2019-03-30 19:40:42 -04:00
DeviceHackRFShared : : MsgSynchronizeFrequency * freqMsg = DeviceHackRFShared : : MsgSynchronizeFrequency : : create ( deviceCenterFrequency ) ;
2019-05-08 16:11:53 -04:00
buddy - > getSamplingDeviceInputMessageQueue ( ) - > push ( freqMsg ) ;
2019-03-30 19:40:42 -04:00
}
2017-01-07 22:13:20 -05:00
forwardChange = true ;
}
2019-03-31 17:09:50 -04:00
if ( ( m_settings . m_fcPos ! = settings . m_fcPos ) | | force )
{
if ( m_hackRFThread ! = 0 ) {
m_hackRFThread - > setFcPos ( ( int ) settings . m_fcPos ) ;
}
}
2017-01-07 22:13:20 -05:00
if ( ( m_settings . m_vgaGain ! = settings . m_vgaGain ) | | force )
{
2018-12-26 15:03:26 -05:00
reverseAPIKeys . append ( " vgaGain " ) ;
2017-01-07 22:13:20 -05:00
if ( m_dev ! = 0 )
{
2017-01-09 19:02:28 -05:00
rc = ( hackrf_error ) hackrf_set_txvga_gain ( m_dev , settings . m_vgaGain ) ;
2017-01-07 22:13:20 -05:00
2018-12-26 15:03:26 -05:00
if ( rc ! = HACKRF_SUCCESS ) {
2017-01-07 22:13:20 -05:00
qDebug ( " HackRFOutput::applySettings: hackrf_set_txvga_gain failed: %s " , hackrf_error_name ( rc ) ) ;
2018-12-26 15:03:26 -05:00
} else {
2017-01-09 19:02:28 -05:00
qDebug ( ) < < " HackRFOutput:applySettings: TxVGA gain set to " < < settings . m_vgaGain ;
2017-01-07 22:13:20 -05:00
}
}
}
if ( ( m_settings . m_bandwidth ! = settings . m_bandwidth ) | | force )
{
2018-12-26 15:03:26 -05:00
reverseAPIKeys . append ( " bandwidth " ) ;
2017-01-07 22:13:20 -05:00
if ( m_dev ! = 0 )
{
2017-05-26 11:42:57 -04:00
uint32_t bw_index = hackrf_compute_baseband_filter_bw_round_down_lt ( settings . m_bandwidth + 1 ) ; // +1 so the round down to lower than yields desired bandwidth
2017-01-07 22:13:20 -05:00
rc = ( hackrf_error ) hackrf_set_baseband_filter_bandwidth ( m_dev , bw_index ) ;
2018-12-26 15:03:26 -05:00
if ( rc ! = HACKRF_SUCCESS ) {
2017-01-07 22:13:20 -05:00
qDebug ( " HackRFInput::applySettings: hackrf_set_baseband_filter_bandwidth failed: %s " , hackrf_error_name ( rc ) ) ;
2018-12-26 15:03:26 -05:00
} else {
2017-01-09 19:02:28 -05:00
qDebug ( ) < < " HackRFInput:applySettings: Baseband BW filter set to " < < settings . m_bandwidth < < " Hz " ;
2017-01-07 22:13:20 -05:00
}
}
}
if ( ( m_settings . m_biasT ! = settings . m_biasT ) | | force )
{
2018-12-26 15:03:26 -05:00
reverseAPIKeys . append ( " biasT " ) ;
2017-01-07 22:13:20 -05:00
if ( m_dev ! = 0 )
{
2017-01-09 19:02:28 -05:00
rc = ( hackrf_error ) hackrf_set_antenna_enable ( m_dev , ( settings . m_biasT ? 1 : 0 ) ) ;
2017-01-07 22:13:20 -05:00
2018-12-26 15:03:26 -05:00
if ( rc ! = HACKRF_SUCCESS ) {
2017-01-07 22:13:20 -05:00
qDebug ( " HackRFInput::applySettings: hackrf_set_antenna_enable failed: %s " , hackrf_error_name ( rc ) ) ;
2018-12-26 15:03:26 -05:00
} else {
2017-01-09 19:02:28 -05:00
qDebug ( ) < < " HackRFInput:applySettings: bias tee set to " < < settings . m_biasT ;
2017-01-07 22:13:20 -05:00
}
}
}
if ( ( m_settings . m_lnaExt ! = settings . m_lnaExt ) | | force )
{
2018-12-26 15:03:26 -05:00
reverseAPIKeys . append ( " lnaExt " ) ;
2017-01-07 22:13:20 -05:00
if ( m_dev ! = 0 )
{
2017-01-09 19:02:28 -05:00
rc = ( hackrf_error ) hackrf_set_amp_enable ( m_dev , ( settings . m_lnaExt ? 1 : 0 ) ) ;
2017-01-07 22:13:20 -05:00
2018-12-26 15:03:26 -05:00
if ( rc ! = HACKRF_SUCCESS ) {
2017-01-07 22:13:20 -05:00
qDebug ( " HackRFInput::applySettings: hackrf_set_amp_enable failed: %s " , hackrf_error_name ( rc ) ) ;
2018-12-26 15:03:26 -05:00
} else {
2017-01-09 19:02:28 -05:00
qDebug ( ) < < " HackRFInput:applySettings: extra LNA set to " < < settings . m_lnaExt ;
2017-01-07 22:13:20 -05:00
}
}
}
2017-08-08 15:30:04 -04:00
if ( threadWasRunning )
{
m_hackRFThread - > startWork ( ) ;
}
2018-12-26 15:03:26 -05:00
if ( settings . m_useReverseAPI )
{
bool fullUpdate = ( ( m_settings . m_useReverseAPI ! = settings . m_useReverseAPI ) & & settings . m_useReverseAPI ) | |
( m_settings . m_reverseAPIAddress ! = settings . m_reverseAPIAddress ) | |
( m_settings . m_reverseAPIPort ! = settings . m_reverseAPIPort ) | |
( m_settings . m_reverseAPIDeviceIndex ! = settings . m_reverseAPIDeviceIndex ) ;
webapiReverseSendSettings ( reverseAPIKeys , settings , fullUpdate | | force ) ;
}
m_settings = settings ;
2017-01-09 19:02:28 -05:00
2017-01-07 22:13:20 -05:00
if ( forwardChange )
{
2017-01-08 11:39:02 -05:00
int sampleRate = m_settings . m_devSampleRate / ( 1 < < m_settings . m_log2Interp ) ;
2017-01-07 22:13:20 -05:00
DSPSignalNotification * notif = new DSPSignalNotification ( sampleRate , m_settings . m_centerFrequency ) ;
2017-09-13 17:42:28 -04:00
m_deviceAPI - > getDeviceEngineInputMessageQueue ( ) - > push ( notif ) ;
2017-01-07 22:13:20 -05:00
}
return true ;
}
2017-12-09 19:57:50 -05:00
2017-12-28 19:40:34 -05:00
int HackRFOutput : : webapiSettingsGet (
SWGSDRangel : : SWGDeviceSettings & response ,
2018-11-13 02:51:14 -05:00
QString & errorMessage )
2017-12-28 19:40:34 -05:00
{
2018-11-13 02:51:14 -05:00
( void ) errorMessage ;
2017-12-28 19:40:34 -05:00
response . setHackRfOutputSettings ( new SWGSDRangel : : SWGHackRFOutputSettings ( ) ) ;
2018-02-21 07:50:50 -05:00
response . getHackRfOutputSettings ( ) - > init ( ) ;
2017-12-28 19:40:34 -05:00
webapiFormatDeviceSettings ( response , m_settings ) ;
return 200 ;
}
int HackRFOutput : : webapiSettingsPutPatch (
bool force ,
const QStringList & deviceSettingsKeys ,
SWGSDRangel : : SWGDeviceSettings & response , // query + response
2018-11-13 02:51:14 -05:00
QString & errorMessage )
2017-12-28 19:40:34 -05:00
{
2018-11-13 02:51:14 -05:00
( void ) errorMessage ;
2017-12-28 19:40:34 -05:00
HackRFOutputSettings settings = m_settings ;
2019-08-04 14:24:44 -04:00
webapiUpdateDeviceSettings ( settings , deviceSettingsKeys , response ) ;
2017-12-28 19:40:34 -05:00
2019-08-04 14:24:44 -04:00
MsgConfigureHackRF * msg = MsgConfigureHackRF : : create ( settings , force ) ;
m_inputMessageQueue . push ( msg ) ;
if ( m_guiMessageQueue ) // forward to GUI if any
{
MsgConfigureHackRF * msgToGUI = MsgConfigureHackRF : : create ( settings , force ) ;
m_guiMessageQueue - > push ( msgToGUI ) ;
}
webapiFormatDeviceSettings ( response , settings ) ;
return 200 ;
}
void HackRFOutput : : webapiUpdateDeviceSettings (
HackRFOutputSettings & settings ,
const QStringList & deviceSettingsKeys ,
SWGSDRangel : : SWGDeviceSettings & response )
{
2017-12-28 19:40:34 -05:00
if ( deviceSettingsKeys . contains ( " centerFrequency " ) ) {
settings . m_centerFrequency = response . getHackRfOutputSettings ( ) - > getCenterFrequency ( ) ;
}
if ( deviceSettingsKeys . contains ( " LOppmTenths " ) ) {
settings . m_LOppmTenths = response . getHackRfOutputSettings ( ) - > getLOppmTenths ( ) ;
}
if ( deviceSettingsKeys . contains ( " bandwidth " ) ) {
settings . m_bandwidth = response . getHackRfOutputSettings ( ) - > getBandwidth ( ) ;
}
if ( deviceSettingsKeys . contains ( " vgaGain " ) ) {
settings . m_vgaGain = response . getHackRfOutputSettings ( ) - > getVgaGain ( ) ;
}
if ( deviceSettingsKeys . contains ( " log2Interp " ) ) {
settings . m_log2Interp = response . getHackRfOutputSettings ( ) - > getLog2Interp ( ) ;
}
2019-04-02 07:43:47 -04:00
if ( deviceSettingsKeys . contains ( " fcPos " ) )
{
2019-04-15 19:00:50 -04:00
int fcPos = response . getHackRfOutputSettings ( ) - > getFcPos ( ) ;
2019-04-02 07:43:47 -04:00
fcPos = fcPos < 0 ? 0 : fcPos > 2 ? 2 : fcPos ;
settings . m_fcPos = ( HackRFOutputSettings : : fcPos_t ) fcPos ;
}
2017-12-28 19:40:34 -05:00
if ( deviceSettingsKeys . contains ( " devSampleRate " ) ) {
settings . m_devSampleRate = response . getHackRfOutputSettings ( ) - > getDevSampleRate ( ) ;
}
if ( deviceSettingsKeys . contains ( " biasT " ) ) {
settings . m_biasT = response . getHackRfOutputSettings ( ) - > getBiasT ( ) ! = 0 ;
}
if ( deviceSettingsKeys . contains ( " lnaExt " ) ) {
settings . m_lnaExt = response . getHackRfOutputSettings ( ) - > getLnaExt ( ) ! = 0 ;
}
2019-08-28 02:45:58 -04:00
if ( deviceSettingsKeys . contains ( " transverterDeltaFrequency " ) ) {
2019-11-14 19:04:24 -05:00
settings . m_transverterDeltaFrequency = response . getHackRfOutputSettings ( ) - > getTransverterDeltaFrequency ( ) ;
2019-08-28 02:45:58 -04:00
}
if ( deviceSettingsKeys . contains ( " transverterMode " ) ) {
2019-11-14 19:04:24 -05:00
settings . m_transverterMode = response . getHackRfOutputSettings ( ) - > getTransverterMode ( ) ! = 0 ;
2019-08-28 02:45:58 -04:00
}
2019-01-11 08:45:00 -05:00
if ( deviceSettingsKeys . contains ( " useReverseAPI " ) ) {
settings . m_useReverseAPI = response . getHackRfOutputSettings ( ) - > getUseReverseApi ( ) ! = 0 ;
}
if ( deviceSettingsKeys . contains ( " reverseAPIAddress " ) ) {
settings . m_reverseAPIAddress = * response . getHackRfOutputSettings ( ) - > getReverseApiAddress ( ) ;
}
if ( deviceSettingsKeys . contains ( " reverseAPIPort " ) ) {
settings . m_reverseAPIPort = response . getHackRfOutputSettings ( ) - > getReverseApiPort ( ) ;
}
if ( deviceSettingsKeys . contains ( " reverseAPIDeviceIndex " ) ) {
settings . m_reverseAPIDeviceIndex = response . getHackRfOutputSettings ( ) - > getReverseApiDeviceIndex ( ) ;
}
2017-12-28 19:40:34 -05:00
}
void HackRFOutput : : webapiFormatDeviceSettings ( SWGSDRangel : : SWGDeviceSettings & response , const HackRFOutputSettings & settings )
{
response . getHackRfOutputSettings ( ) - > setCenterFrequency ( settings . m_centerFrequency ) ;
response . getHackRfOutputSettings ( ) - > setLOppmTenths ( settings . m_LOppmTenths ) ;
response . getHackRfOutputSettings ( ) - > setBandwidth ( settings . m_bandwidth ) ;
response . getHackRfOutputSettings ( ) - > setVgaGain ( settings . m_vgaGain ) ;
response . getHackRfOutputSettings ( ) - > setLog2Interp ( settings . m_log2Interp ) ;
2019-04-02 07:43:47 -04:00
response . getHackRfOutputSettings ( ) - > setFcPos ( settings . m_fcPos ) ;
2017-12-28 19:40:34 -05:00
response . getHackRfOutputSettings ( ) - > setDevSampleRate ( settings . m_devSampleRate ) ;
response . getHackRfOutputSettings ( ) - > setBiasT ( settings . m_biasT ? 1 : 0 ) ;
response . getHackRfOutputSettings ( ) - > setLnaExt ( settings . m_lnaExt ? 1 : 0 ) ;
2019-08-28 02:45:58 -04:00
response . getHackRfOutputSettings ( ) - > setTransverterDeltaFrequency ( settings . m_transverterDeltaFrequency ) ;
response . getHackRfOutputSettings ( ) - > setTransverterMode ( settings . m_transverterMode ? 1 : 0 ) ;
2019-01-11 08:45:00 -05:00
response . getHackRfOutputSettings ( ) - > setUseReverseApi ( settings . m_useReverseAPI ? 1 : 0 ) ;
if ( response . getHackRfOutputSettings ( ) - > getReverseApiAddress ( ) ) {
* response . getHackRfOutputSettings ( ) - > getReverseApiAddress ( ) = settings . m_reverseAPIAddress ;
} else {
response . getHackRfOutputSettings ( ) - > setReverseApiAddress ( new QString ( settings . m_reverseAPIAddress ) ) ;
}
response . getHackRfOutputSettings ( ) - > setReverseApiPort ( settings . m_reverseAPIPort ) ;
response . getHackRfOutputSettings ( ) - > setReverseApiDeviceIndex ( settings . m_reverseAPIDeviceIndex ) ;
2017-12-28 19:40:34 -05:00
}
2017-12-09 19:57:50 -05:00
int HackRFOutput : : webapiRunGet (
SWGSDRangel : : SWGDeviceState & response ,
2018-11-13 02:51:14 -05:00
QString & errorMessage )
2017-12-09 19:57:50 -05:00
{
2018-11-13 02:51:14 -05:00
( void ) errorMessage ;
2017-12-09 19:57:50 -05:00
m_deviceAPI - > getDeviceEngineStateStr ( * response . getState ( ) ) ;
return 200 ;
}
int HackRFOutput : : webapiRun (
bool run ,
SWGSDRangel : : SWGDeviceState & response ,
2018-11-13 02:51:14 -05:00
QString & errorMessage )
2017-12-09 19:57:50 -05:00
{
2018-11-13 02:51:14 -05:00
( void ) errorMessage ;
2017-12-14 17:29:12 -05:00
m_deviceAPI - > getDeviceEngineStateStr ( * response . getState ( ) ) ;
2017-12-14 12:02:49 -05:00
MsgStartStop * message = MsgStartStop : : create ( run ) ;
m_inputMessageQueue . push ( message ) ;
if ( m_guiMessageQueue )
2017-12-09 19:57:50 -05:00
{
2017-12-14 12:02:49 -05:00
MsgStartStop * messagetoGui = MsgStartStop : : create ( run ) ;
m_guiMessageQueue - > push ( messagetoGui ) ;
2017-12-09 19:57:50 -05:00
}
return 200 ;
}
2018-12-26 15:03:26 -05:00
void HackRFOutput : : webapiReverseSendSettings ( QList < QString > & deviceSettingsKeys , const HackRFOutputSettings & settings , bool force )
{
SWGSDRangel : : SWGDeviceSettings * swgDeviceSettings = new SWGSDRangel : : SWGDeviceSettings ( ) ;
2019-05-07 08:43:38 -04:00
swgDeviceSettings - > setDirection ( 1 ) ; // single Tx
2019-03-25 08:46:42 -04:00
swgDeviceSettings - > setOriginatorIndex ( m_deviceAPI - > getDeviceSetIndex ( ) ) ;
2018-12-26 15:03:26 -05:00
swgDeviceSettings - > setDeviceHwType ( new QString ( " HackRF " ) ) ;
swgDeviceSettings - > setHackRfOutputSettings ( new SWGSDRangel : : SWGHackRFOutputSettings ( ) ) ;
SWGSDRangel : : SWGHackRFOutputSettings * swgHackRFOutputSettings = swgDeviceSettings - > getHackRfOutputSettings ( ) ;
// transfer data that has been modified. When force is on transfer all data except reverse API data
if ( deviceSettingsKeys . contains ( " centerFrequency " ) | | force ) {
swgHackRFOutputSettings - > setCenterFrequency ( settings . m_centerFrequency ) ;
}
if ( deviceSettingsKeys . contains ( " LOppmTenths " ) | | force ) {
swgHackRFOutputSettings - > setLOppmTenths ( settings . m_LOppmTenths ) ;
}
if ( deviceSettingsKeys . contains ( " bandwidth " ) | | force ) {
swgHackRFOutputSettings - > setBandwidth ( settings . m_bandwidth ) ;
}
if ( deviceSettingsKeys . contains ( " vgaGain " ) | | force ) {
swgHackRFOutputSettings - > setVgaGain ( settings . m_vgaGain ) ;
}
if ( deviceSettingsKeys . contains ( " log2Interp " ) | | force ) {
swgHackRFOutputSettings - > setLog2Interp ( settings . m_log2Interp ) ;
}
2019-04-02 07:43:47 -04:00
if ( deviceSettingsKeys . contains ( " fcPos " ) | | force ) {
swgHackRFOutputSettings - > setFcPos ( ( int ) settings . m_fcPos ) ;
}
2018-12-26 15:03:26 -05:00
if ( deviceSettingsKeys . contains ( " devSampleRate " ) | | force ) {
swgHackRFOutputSettings - > setDevSampleRate ( settings . m_devSampleRate ) ;
}
if ( deviceSettingsKeys . contains ( " biasT " ) | | force ) {
swgHackRFOutputSettings - > setBiasT ( settings . m_biasT ? 1 : 0 ) ;
}
if ( deviceSettingsKeys . contains ( " lnaExt " ) | | force ) {
swgHackRFOutputSettings - > setLnaExt ( settings . m_lnaExt ? 1 : 0 ) ;
}
2019-08-28 02:45:58 -04:00
if ( deviceSettingsKeys . contains ( " transverterDeltaFrequency " ) | | force ) {
swgHackRFOutputSettings - > setTransverterDeltaFrequency ( settings . m_transverterDeltaFrequency ) ;
}
if ( deviceSettingsKeys . contains ( " transverterMode " ) | | force ) {
swgHackRFOutputSettings - > setTransverterMode ( settings . m_transverterMode ? 1 : 0 ) ;
}
2018-12-26 15:03:26 -05:00
QString deviceSettingsURL = QString ( " http://%1:%2/sdrangel/deviceset/%3/device/settings " )
. arg ( settings . m_reverseAPIAddress )
. arg ( settings . m_reverseAPIPort )
. arg ( settings . m_reverseAPIDeviceIndex ) ;
m_networkRequest . setUrl ( QUrl ( deviceSettingsURL ) ) ;
m_networkRequest . setHeader ( QNetworkRequest : : ContentTypeHeader , " application/json " ) ;
2019-11-14 19:04:24 -05:00
QBuffer * buffer = new QBuffer ( ) ;
2018-12-26 15:03:26 -05:00
buffer - > open ( ( QBuffer : : ReadWrite ) ) ;
buffer - > write ( swgDeviceSettings - > asJson ( ) . toUtf8 ( ) ) ;
buffer - > seek ( 0 ) ;
// Always use PATCH to avoid passing reverse API settings
2019-11-14 19:04:24 -05:00
QNetworkReply * reply = m_networkManager - > sendCustomRequest ( m_networkRequest , " PATCH " , buffer ) ;
buffer - > setParent ( reply ) ;
2018-12-26 15:03:26 -05:00
delete swgDeviceSettings ;
}
void HackRFOutput : : webapiReverseSendStartStop ( bool start )
{
2019-03-25 10:26:01 -04:00
SWGSDRangel : : SWGDeviceSettings * swgDeviceSettings = new SWGSDRangel : : SWGDeviceSettings ( ) ;
2019-05-07 08:43:38 -04:00
swgDeviceSettings - > setDirection ( 1 ) ; // single Tx
2019-03-25 10:26:01 -04:00
swgDeviceSettings - > setOriginatorIndex ( m_deviceAPI - > getDeviceSetIndex ( ) ) ;
swgDeviceSettings - > setDeviceHwType ( new QString ( " HackRF " ) ) ;
2018-12-26 15:03:26 -05:00
QString deviceSettingsURL = QString ( " http://%1:%2/sdrangel/deviceset/%3/device/run " )
. arg ( m_settings . m_reverseAPIAddress )
. arg ( m_settings . m_reverseAPIPort )
. arg ( m_settings . m_reverseAPIDeviceIndex ) ;
m_networkRequest . setUrl ( QUrl ( deviceSettingsURL ) ) ;
2019-03-25 10:26:01 -04:00
m_networkRequest . setHeader ( QNetworkRequest : : ContentTypeHeader , " application/json " ) ;
2019-11-14 19:04:24 -05:00
QBuffer * buffer = new QBuffer ( ) ;
2019-03-25 10:26:01 -04:00
buffer - > open ( ( QBuffer : : ReadWrite ) ) ;
buffer - > write ( swgDeviceSettings - > asJson ( ) . toUtf8 ( ) ) ;
buffer - > seek ( 0 ) ;
2019-11-14 19:04:24 -05:00
QNetworkReply * reply ;
2018-12-26 15:03:26 -05:00
if ( start ) {
2019-11-14 19:04:24 -05:00
reply = m_networkManager - > sendCustomRequest ( m_networkRequest , " POST " , buffer ) ;
2018-12-26 15:03:26 -05:00
} else {
2019-11-14 19:04:24 -05:00
reply = m_networkManager - > sendCustomRequest ( m_networkRequest , " DELETE " , buffer ) ;
2018-12-26 15:03:26 -05:00
}
2019-06-14 10:58:09 -04:00
2019-11-14 19:04:24 -05:00
buffer - > setParent ( reply ) ;
2019-06-14 10:58:09 -04:00
delete swgDeviceSettings ;
2018-12-26 15:03:26 -05:00
}
void HackRFOutput : : networkManagerFinished ( QNetworkReply * reply )
{
QNetworkReply : : NetworkError replyError = reply - > error ( ) ;
if ( replyError )
{
qWarning ( ) < < " HackRFOutput::networkManagerFinished: "
< < " error( " < < ( int ) replyError
< < " ): " < < replyError
< < " : " < < reply - > errorString ( ) ;
2019-11-14 19:04:24 -05:00
}
else
{
QString answer = reply - > readAll ( ) ;
answer . chop ( 1 ) ; // remove last \n
qDebug ( " HackRFOutput::networkManagerFinished: reply: \n %s " , answer . toStdString ( ) . c_str ( ) ) ;
2018-12-26 15:03:26 -05:00
}
2019-11-14 19:04:24 -05:00
reply - > deleteLater ( ) ;
2018-12-26 15:03:26 -05:00
}