1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 10:05:46 -05:00
sdrangel/plugins/samplesource/sdrplayv3/sdrplayv3input.cpp
Mykola Dvornik 15337cac66 Fix bug that prevents settings changes updates via reverse API
Most plugins that use reverse API to PATCH settings updates to remote
server only do so when `useReverseAPI` is toggled, but not when the
relevant settings are being updated. So lets fix the precondition to
use the `m_useReverseAPI` flag instead.
2024-04-14 18:58:12 +02:00

1460 lines
54 KiB
C++

///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
// Copyright (C) 2021 Franco Venturi <fventuri@comcast.net> //
// Copyright (C) 2022 Piotr Majkrzak <piotr@majkrzak.dev> //
// Copyright (C) 2023 Daniele Forsi <iu5hkx@gmail.com> //
// //
// 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 //
// (at your option) any later version. //
// //
// 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>
#include <QDebug>
#include <QNetworkReply>
#include <QBuffer>
#include "SWGDeviceSettings.h"
#include "SWGDeviceState.h"
#include "SWGDeviceReport.h"
#include "SWGSDRPlayV3Report.h"
#include "util/simpleserializer.h"
#include "dsp/dspcommands.h"
#include "sdrplayv3input.h"
#include <device/deviceapi.h>
#include "sdrplayv3thread.h"
MESSAGE_CLASS_DEFINITION(SDRPlayV3Input::MsgConfigureSDRPlayV3, Message)
MESSAGE_CLASS_DEFINITION(SDRPlayV3Input::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(SDRPlayV3Input::MsgSaveReplay, Message)
SDRPlayV3Input::SDRPlayV3Input(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_settings(),
m_dev(nullptr),
m_devParams(nullptr),
m_sdrPlayThread(nullptr),
m_deviceDescription("SDRPlayV3"),
m_devNumber(0),
m_running(false)
{
m_sampleFifo.setLabel(m_deviceDescription);
openDevice();
m_deviceAPI->setNbSourceStreams(1);
m_networkManager = new QNetworkAccessManager();
QObject::connect(
m_networkManager,
&QNetworkAccessManager::finished,
this,
&SDRPlayV3Input::networkManagerFinished
);
}
SDRPlayV3Input::~SDRPlayV3Input()
{
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
this,
&SDRPlayV3Input::networkManagerFinished
);
delete m_networkManager;
if (m_running) {
stop();
}
closeDevice();
}
void SDRPlayV3Input::destroy()
{
delete this;
}
bool SDRPlayV3Input::openDevice()
{
qDebug() << "SDRPlayV3Input::openDevice";
m_devNumber = m_deviceAPI->getSamplingDeviceSequence();
if (m_dev != 0)
{
closeDevice();
}
if (!m_sampleFifo.setSize(96000 * 4))
{
qCritical("SDRPlayV3Input::openDevice: could not allocate SampleFifo");
return false;
}
sdrplay_api_LockDeviceApi();
sdrplay_api_ErrT err;
unsigned int count;
if ((err = sdrplay_api_GetDevices(m_devs, &count, sizeof(m_devs) / sizeof(sdrplay_api_DeviceT))) == sdrplay_api_Success)
{
m_dev = &m_devs[m_devNumber];
m_dev->tuner = sdrplay_api_Tuner_A;
m_dev->rspDuoMode = sdrplay_api_RspDuoMode_Single_Tuner;
if ((err = sdrplay_api_SelectDevice(m_dev)) == sdrplay_api_Success)
{
sdrplay_api_UnlockDeviceApi();
if ((err = sdrplay_api_GetDeviceParams(m_dev->dev, &m_devParams)) == sdrplay_api_Success)
{
qDebug() << "SDRPlayV3Input::openDevice: opened successfully";
}
else
{
qCritical() << "SDRPlayV3Input::openDevice: could not get device parameters: " << sdrplay_api_GetErrorString(err);
return false;
}
}
else
{
qCritical() << "SDRPlayV3Input::openDevice: could not select device: " << sdrplay_api_GetErrorString(err);
sdrplay_api_UnlockDeviceApi();
return false;
}
}
else
{
qCritical() << "SDRPlayV3Input::openDevice: could not get devices: " << sdrplay_api_GetErrorString(err);
sdrplay_api_UnlockDeviceApi();
return false;
}
sdrplay_api_UnlockDeviceApi();
return true;
}
bool SDRPlayV3Input::start()
{
qDebug() << "SDRPlayV3Input::start";
if (!m_dev) {
return false;
}
if (m_running) stop();
m_sdrPlayThread = new SDRPlayV3Thread(m_dev, &m_sampleFifo, &m_replayBuffer);
m_sdrPlayThread->setLog2Decimation(m_settings.m_log2Decim);
m_sdrPlayThread->setFcPos((int) m_settings.m_fcPos);
m_sdrPlayThread->startWork();
m_running = m_sdrPlayThread->isRunning();
applySettings(m_settings, QList<QString>(), true, true);
return true;
}
void SDRPlayV3Input::closeDevice()
{
qDebug() << "SDRPlayV3Input::closeDevice";
if (m_dev != 0)
{
sdrplay_api_ReleaseDevice(m_dev);
m_dev = 0;
}
m_deviceDescription.clear();
}
void SDRPlayV3Input::init()
{
applySettings(m_settings, QList<QString>(), true, true);
}
void SDRPlayV3Input::stop()
{
qDebug() << "SDRPlayV3Input::stop";
QMutexLocker mutexLocker(&m_mutex);
if(m_sdrPlayThread)
{
m_sdrPlayThread->stopWork();
delete m_sdrPlayThread;
m_sdrPlayThread = nullptr;
}
m_running = false;
}
QByteArray SDRPlayV3Input::serialize() const
{
return m_settings.serialize();
}
bool SDRPlayV3Input::deserialize(const QByteArray& data)
{
bool success = true;
if (!m_settings.deserialize(data))
{
m_settings.resetToDefaults();
success = false;
}
MsgConfigureSDRPlayV3* message = MsgConfigureSDRPlayV3::create(m_settings, QList<QString>(), true);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureSDRPlayV3* messageToGUI = MsgConfigureSDRPlayV3::create(m_settings, QList<QString>(), true);
m_guiMessageQueue->push(messageToGUI);
}
return success;
}
const QString& SDRPlayV3Input::getDeviceDescription() const
{
return m_deviceDescription;
}
int SDRPlayV3Input::getSampleRate() const
{
uint32_t fsHz = m_settings.m_devSampleRate;
sdrplay_api_Bw_MHzT bwType = SDRPlayV3Bandwidths::getBandwidthEnum(m_settings.m_bandwidthIndex);
sdrplay_api_If_kHzT ifType = SDRPlayV3IF::getIFEnum(m_settings.m_ifFrequencyIndex);
if(
((fsHz == 8192000) && (bwType == sdrplay_api_BW_1_536) && (ifType == sdrplay_api_IF_2_048)) ||
((fsHz == 8000000) && (bwType == sdrplay_api_BW_1_536) && (ifType == sdrplay_api_IF_2_048)) ||
((fsHz == 8000000) && (bwType == sdrplay_api_BW_5_000) && (ifType == sdrplay_api_IF_2_048)) ||
((fsHz == 2000000) && (bwType <= sdrplay_api_BW_0_300) && (ifType == sdrplay_api_IF_0_450))) {
fsHz /= 4;
} else if ((fsHz == 2000000) && (bwType == sdrplay_api_BW_0_600) && (ifType == sdrplay_api_IF_0_450)) {
fsHz /= 2;
}else if ((fsHz == 6000000) && (bwType <= sdrplay_api_BW_1_536) && (ifType == sdrplay_api_IF_1_620)) {
fsHz /= 3;
}
return fsHz / (1 << m_settings.m_log2Decim);
}
quint64 SDRPlayV3Input::getCenterFrequency() const
{
return m_settings.m_centerFrequency;
}
void SDRPlayV3Input::setCenterFrequency(qint64 centerFrequency)
{
SDRPlayV3Settings settings = m_settings;
settings.m_centerFrequency = centerFrequency;
MsgConfigureSDRPlayV3* message = MsgConfigureSDRPlayV3::create(settings, QList<QString>{"centerFrequency"}, false);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureSDRPlayV3* messageToGUI = MsgConfigureSDRPlayV3::create(settings, QList<QString>{"centerFrequency"}, false);
m_guiMessageQueue->push(messageToGUI);
}
}
bool SDRPlayV3Input::handleMessage(const Message& message)
{
if (MsgConfigureSDRPlayV3::match(message))
{
MsgConfigureSDRPlayV3& conf = (MsgConfigureSDRPlayV3&) message;
qDebug() << "SDRPlayV3Input::handleMessage: MsgConfigureSDRPlayV3";
if (!applySettings( conf.getSettings(), conf.getSettingsKeys(), false, conf.getForce())) {
qDebug("SDRPlayV3Input::handleMessage: config error");
}
return true;
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
qDebug() << "SDRPlayV3Input::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
{
if (m_deviceAPI->initDeviceEngine())
{
m_deviceAPI->startDeviceEngine();
}
}
else
{
m_deviceAPI->stopDeviceEngine();
}
if (m_settings.m_useReverseAPI) {
webapiReverseSendStartStop(cmd.getStartStop());
}
return true;
}
else if (MsgSaveReplay::match(message))
{
MsgSaveReplay& cmd = (MsgSaveReplay&) message;
m_replayBuffer.save(cmd.getFilename(), m_settings.m_devSampleRate, getCenterFrequency());
return true;
}
else
{
return false;
}
}
bool SDRPlayV3Input::applySettings(const SDRPlayV3Settings& settings, const QList<QString>& settingsKeys, bool forwardChange, bool force)
{
qDebug() << "SDRPlayV3Input::applySettings: forwardChange: " << forwardChange << " force: " << force << settings.getDebugString(settingsKeys, force);
QMutexLocker mutexLocker(&m_mutex);
sdrplay_api_ErrT err;
if (settingsKeys.contains("tuner") || force)
{
if (m_running)
{
if (getDeviceId() == SDRPLAY_RSPduo_ID)
{
if (((m_dev->tuner == sdrplay_api_Tuner_A) && (settings.m_tuner == 1))
|| ((m_dev->tuner == sdrplay_api_Tuner_B) && (settings.m_tuner == 0)))
{
if ((err = sdrplay_api_SwapRspDuoActiveTuner (m_dev->dev, &m_dev->tuner, settings.m_antenna == 1 ? sdrplay_api_RspDuo_AMPORT_1 : sdrplay_api_RspDuo_AMPORT_2)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not swap tuners: " << sdrplay_api_GetErrorString(err);
}
}
}
}
if (settingsKeys.contains("dcBlock") || force)
{
if (m_running)
{
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->ctrlParams.dcOffset.DCenable = settings.m_dcBlock ? 1 : 0;
else
m_devParams->rxChannelB->ctrlParams.dcOffset.DCenable = settings.m_dcBlock ? 1 : 0;
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Ctrl_DCoffsetIQimbalance, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set DC offset enable: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("iqCorrection") || force)
{
if (m_running)
{
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->ctrlParams.dcOffset.IQenable = settings.m_iqCorrection ? 1 : 0;
else
m_devParams->rxChannelB->ctrlParams.dcOffset.IQenable = settings.m_iqCorrection ? 1 : 0;
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Ctrl_DCoffsetIQimbalance, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set IQ offset enable: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("ifAGC") || force)
{
if (m_running)
{
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->ctrlParams.agc.enable = settings.m_ifAGC ? sdrplay_api_AGC_CTRL_EN : sdrplay_api_AGC_DISABLE;
else
m_devParams->rxChannelB->ctrlParams.agc.enable = settings.m_ifAGC ? sdrplay_api_AGC_CTRL_EN : sdrplay_api_AGC_DISABLE;
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Ctrl_Agc, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set AGC enable: " << sdrplay_api_GetErrorString(err);
}
}
// Need to reset IF gain manual setting after AGC is disabled
if (settingsKeys.contains("lnaIndex")
|| settingsKeys.contains("ifGain")
|| settingsKeys.contains("ifAGC") || force)
{
if (m_running)
{
if (m_dev->tuner == sdrplay_api_Tuner_A)
{
m_devParams->rxChannelA->tunerParams.gain.gRdB = -settings.m_ifGain;
m_devParams->rxChannelA->tunerParams.gain.LNAstate = settings.m_lnaIndex;
m_devParams->rxChannelA->tunerParams.gain.minGr = sdrplay_api_EXTENDED_MIN_GR;
}
else
{
m_devParams->rxChannelB->tunerParams.gain.gRdB = -settings.m_ifGain;
m_devParams->rxChannelB->tunerParams.gain.LNAstate = settings.m_lnaIndex;
m_devParams->rxChannelB->tunerParams.gain.minGr = sdrplay_api_EXTENDED_MIN_GR;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set gain: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("devSampleRate") || force)
{
if (m_running)
{
int sampleRate = settings.m_devSampleRate;
m_devParams->devParams->fsFreq.fsHz = (double)sampleRate;
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Dev_Fs, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set sample rate to " << sampleRate << " : " << sdrplay_api_GetErrorString(err);
else
qDebug() << "SDRPlayV3Input::applySettings: sample rate set to " << sampleRate;
forwardChange = true;
if (settings.m_devSampleRate != m_settings.m_devSampleRate) {
m_replayBuffer.clear();
}
}
}
if (settingsKeys.contains("log2Decim") || force)
{
if (m_sdrPlayThread)
{
m_sdrPlayThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "SDRPlayV3Input::applySettings: set decimation to " << (1<<settings.m_log2Decim);
}
}
if (settingsKeys.contains("fcPos") || force)
{
if (m_sdrPlayThread)
{
m_sdrPlayThread->setFcPos((int) settings.m_fcPos);
qDebug() << "SDRPlayV3Input:applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
}
}
if (settingsKeys.contains("iqOrder") || force)
{
if (m_sdrPlayThread) {
m_sdrPlayThread->setIQOrder(settings.m_iqOrder);
}
}
if (settingsKeys.contains("centerFrequency")
|| settingsKeys.contains("LOppmTenths")
|| settingsKeys.contains("fcPos")
|| settingsKeys.contains("log2Decim")
|| settingsKeys.contains("transverterMode")
|| settingsKeys.contains("transverterDeltaFrequency") || force)
{
qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency(
settings.m_centerFrequency,
settings.m_transverterDeltaFrequency,
settings.m_log2Decim,
(DeviceSampleSource::fcPos_t) settings.m_fcPos,
settings.m_devSampleRate,
DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD,
settings.m_transverterMode);
forwardChange = true;
if (m_running)
{
if (setDeviceCenterFrequency(deviceCenterFrequency)) {
qDebug() << "SDRPlayV3Input::applySettings: center freq: " << settings.m_centerFrequency << " Hz";
}
}
}
if (settingsKeys.contains("bandwidthIndex") || force)
{
if (m_running)
{
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->tunerParams.bwType = SDRPlayV3Bandwidths::getBandwidthEnum(settings.m_bandwidthIndex);
else
m_devParams->rxChannelB->tunerParams.bwType = SDRPlayV3Bandwidths::getBandwidthEnum(settings.m_bandwidthIndex);
m_sdrPlayThread->resetRfChanged();
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Tuner_BwType, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set bandwidth: " << sdrplay_api_GetErrorString(err);
if (!m_sdrPlayThread->waitForRfChanged())
qCritical() << "SDRPlayV3Input::applySettings: could not set bandwidth: Rf update timed out";
}
}
if (settingsKeys.contains("ifFrequencyIndex") || force)
{
if (m_running)
{
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->tunerParams.ifType = SDRPlayV3IF::getIFEnum(settings.m_ifFrequencyIndex);
else
m_devParams->rxChannelB->tunerParams.ifType = SDRPlayV3IF::getIFEnum(settings.m_ifFrequencyIndex);
m_sdrPlayThread->resetRfChanged();
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Tuner_IfType, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set IF frequency: " << sdrplay_api_GetErrorString(err);
if (!m_sdrPlayThread->waitForRfChanged())
qCritical() << "SDRPlayV3Input::applySettings: could not set IF frequency: Rf update timed out";
}
}
if (settingsKeys.contains("biasTee") || force)
{
if (m_running)
{
sdrplay_api_ReasonForUpdateT update = sdrplay_api_Update_None;
sdrplay_api_ReasonForUpdateExtension1T updateExt = sdrplay_api_Update_Ext1_None;
switch (getDeviceId())
{
case SDRPLAY_RSP1A_ID:
case SDRPLAY_RSP1B_ID:
m_devParams->rxChannelA->rsp1aTunerParams.biasTEnable = settings.m_biasTee;
update = sdrplay_api_Update_Rsp1a_BiasTControl;
break;
case SDRPLAY_RSP2_ID:
m_devParams->rxChannelA->rsp2TunerParams.biasTEnable = settings.m_biasTee;
update = sdrplay_api_Update_Rsp2_BiasTControl;
break;
case SDRPLAY_RSPduo_ID:
// Only channel B has bias tee
if (m_dev->tuner == sdrplay_api_Tuner_B)
{
m_devParams->rxChannelB->rspDuoTunerParams.biasTEnable = settings.m_biasTee;
update = sdrplay_api_Update_RspDuo_BiasTControl;
}
break;
case SDRPLAY_RSPdx_ID:
m_devParams->devParams->rspDxParams.biasTEnable = settings.m_biasTee;
updateExt = sdrplay_api_Update_RspDx_BiasTControl;
break;
default:
// SDRPLAY_RSP1_ID doesn't have a bias tee
break;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, update, updateExt)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set state of bias tee: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("amNotch") || force)
{
if (m_running)
{
sdrplay_api_ReasonForUpdateT update = sdrplay_api_Update_None;
sdrplay_api_ReasonForUpdateExtension1T updateExt = sdrplay_api_Update_Ext1_None;
switch (getDeviceId())
{
case SDRPLAY_RSPduo_ID:
if (m_dev->tuner == sdrplay_api_Tuner_A)
{
m_devParams->rxChannelA->rspDuoTunerParams.tuner1AmNotchEnable = settings.m_amNotch;
update = sdrplay_api_Update_RspDuo_Tuner1AmNotchControl;
}
break;
default:
// Other devices don't have AM notch filter
break;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, update, updateExt)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set state of AM notch filter: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("fmNotch") || force)
{
if (m_running)
{
sdrplay_api_ReasonForUpdateT update = sdrplay_api_Update_None;
sdrplay_api_ReasonForUpdateExtension1T updateExt = sdrplay_api_Update_Ext1_None;
switch (getDeviceId())
{
case SDRPLAY_RSP1A_ID:
case SDRPLAY_RSP1B_ID:
m_devParams->devParams->rsp1aParams.rfNotchEnable = settings.m_fmNotch;
update = sdrplay_api_Update_Rsp1a_RfNotchControl;
break;
case SDRPLAY_RSP2_ID:
m_devParams->rxChannelA->rsp2TunerParams.rfNotchEnable = settings.m_fmNotch;
update = sdrplay_api_Update_Rsp2_RfNotchControl;
break;
case SDRPLAY_RSPduo_ID:
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->rspDuoTunerParams.rfNotchEnable = settings.m_fmNotch;
else
m_devParams->rxChannelB->rspDuoTunerParams.rfNotchEnable = settings.m_fmNotch;
update = sdrplay_api_Update_RspDuo_RfNotchControl;
break;
case SDRPLAY_RSPdx_ID:
m_devParams->devParams->rspDxParams.rfNotchEnable = settings.m_fmNotch;
updateExt = sdrplay_api_Update_RspDx_RfNotchControl;
break;
default:
// SDRPLAY_RSP1_ID doesn't have notch filter
break;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, update, updateExt)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set state of MW/FM notch filter: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("dabNotch") || force)
{
if (m_running)
{
sdrplay_api_ReasonForUpdateT update = sdrplay_api_Update_None;
sdrplay_api_ReasonForUpdateExtension1T updateExt = sdrplay_api_Update_Ext1_None;
switch (getDeviceId())
{
case SDRPLAY_RSP1A_ID:
case SDRPLAY_RSP1B_ID:
m_devParams->devParams->rsp1aParams.rfDabNotchEnable = settings.m_dabNotch;
update = sdrplay_api_Update_Rsp1a_RfDabNotchControl;
break;
case SDRPLAY_RSPduo_ID:
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->rspDuoTunerParams.rfDabNotchEnable = settings.m_dabNotch;
else
m_devParams->rxChannelB->rspDuoTunerParams.rfDabNotchEnable = settings.m_dabNotch;
update = sdrplay_api_Update_RspDuo_RfDabNotchControl;
break;
case SDRPLAY_RSPdx_ID:
m_devParams->devParams->rspDxParams.rfDabNotchEnable = settings.m_dabNotch;
updateExt = sdrplay_api_Update_RspDx_RfDabNotchControl;
break;
default:
// SDRPLAY_RSP1_ID and SDRPLAY_RSP2_ID don't have DAB filter
break;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, update, updateExt)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set state of DAB notch filter: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("antenna") || force)
{
if (m_running)
{
sdrplay_api_ReasonForUpdateT update = sdrplay_api_Update_None;
sdrplay_api_ReasonForUpdateExtension1T updateExt = sdrplay_api_Update_Ext1_None;
switch (getDeviceId())
{
case SDRPLAY_RSP2_ID:
m_devParams->rxChannelA->rsp2TunerParams.amPortSel = settings.m_antenna == 2 ? sdrplay_api_Rsp2_AMPORT_1 : sdrplay_api_Rsp2_AMPORT_2;
m_devParams->rxChannelA->rsp2TunerParams.antennaSel = settings.m_antenna == 1 ? sdrplay_api_Rsp2_ANTENNA_B : sdrplay_api_Rsp2_ANTENNA_A;
update = (sdrplay_api_ReasonForUpdateT) (sdrplay_api_Update_Rsp2_AntennaControl | sdrplay_api_Update_Rsp2_AmPortSelect);
break;
case SDRPLAY_RSPduo_ID:
if (m_dev->tuner == sdrplay_api_Tuner_A)
{
m_devParams->rxChannelA->rspDuoTunerParams.tuner1AmPortSel = settings.m_antenna == 1 ? sdrplay_api_RspDuo_AMPORT_1 : sdrplay_api_RspDuo_AMPORT_2;
update = sdrplay_api_Update_RspDuo_AmPortSelect;
}
break;
case SDRPLAY_RSPdx_ID:
m_devParams->devParams->rspDxParams.antennaSel = (sdrplay_api_RspDx_AntennaSelectT)settings.m_antenna;
updateExt = sdrplay_api_Update_RspDx_AntennaControl;
break;
default:
// SDRPLAY_RSP1_ID, SDRPLAY_RSP1A_ID, SDRPLAY_RSP1B_ID only have one antenna
break;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, update, updateExt)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set antenna: " << sdrplay_api_GetErrorString(err);
}
}
if (settingsKeys.contains("extRef") || force)
{
if (m_running)
{
sdrplay_api_ReasonForUpdateT update = sdrplay_api_Update_None;
sdrplay_api_ReasonForUpdateExtension1T updateExt = sdrplay_api_Update_Ext1_None;
switch (getDeviceId())
{
case SDRPLAY_RSP2_ID:
m_devParams->devParams->rsp2Params.extRefOutputEn = settings.m_extRef;
update = sdrplay_api_Update_Rsp2_ExtRefControl;
break;
case SDRPLAY_RSPduo_ID:
m_devParams->devParams->rspDuoParams.extRefOutputEn = settings.m_extRef;
update = sdrplay_api_Update_RspDuo_ExtRefControl;
break;
default:
// Other devices do not have external reference output
break;
}
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, update, updateExt)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Input::applySettings: could not set state of external reference output: " << sdrplay_api_GetErrorString(err);
}
}
if (settings.m_useReverseAPI)
{
bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) ||
settingsKeys.contains("reverseAPIAddress") ||
settingsKeys.contains("reverseAPIPort") ||
settingsKeys.contains("reverseAPIDeviceIndex");
webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
}
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
if (settingsKeys.contains("replayLength") || settingsKeys.contains("devSampleRate") || force) {
m_replayBuffer.setSize(m_settings.m_replayLength, m_settings.m_devSampleRate);
}
if (settingsKeys.contains("replayOffset") || settingsKeys.contains("devSampleRate") || force) {
m_replayBuffer.setReadOffset(((unsigned)(m_settings.m_replayOffset * m_settings.m_devSampleRate)) * 2);
}
if (settingsKeys.contains("replayLoop") || force) {
m_replayBuffer.setLoop(m_settings.m_replayLoop);
}
if (forwardChange)
{
int sampleRate = getSampleRate();
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
return true;
}
bool SDRPlayV3Input::setDeviceCenterFrequency(quint64 freq_hz)
{
qint64 df = ((qint64)freq_hz * m_settings.m_LOppmTenths) / 10000000LL;
freq_hz += df;
sdrplay_api_ErrT err;
if (m_dev->tuner == sdrplay_api_Tuner_A)
m_devParams->rxChannelA->tunerParams.rfFreq.rfHz = (double)freq_hz;
else
m_devParams->rxChannelB->tunerParams.rfFreq.rfHz = (double)freq_hz;
m_sdrPlayThread->resetRfChanged();
if ((err = sdrplay_api_Update(m_dev->dev, m_dev->tuner, sdrplay_api_Update_Tuner_Frf, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
{
qWarning("SDRPlayV3Input::setDeviceCenterFrequency: could not set frequency to %llu Hz", freq_hz);
return false;
}
else if (!m_sdrPlayThread->waitForRfChanged())
{
qWarning() << "SDRPlayV3Input::setDeviceCenterFrequency: could not set frequency: Rf update timed out";
return false;
}
else
{
qDebug("SDRPlayV3Input::setDeviceCenterFrequency: frequency set to %llu Hz", freq_hz);
return true;
}
}
int SDRPlayV3Input::webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
{
(void) errorMessage;
m_deviceAPI->getDeviceEngineStateStr(*response.getState());
return 200;
}
int SDRPlayV3Input::webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
{
(void) errorMessage;
m_deviceAPI->getDeviceEngineStateStr(*response.getState());
MsgStartStop *message = MsgStartStop::create(run);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgStartStop *msgToGUI = MsgStartStop::create(run);
m_guiMessageQueue->push(msgToGUI);
}
return 200;
}
int SDRPlayV3Input::webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage)
{
(void) errorMessage;
response.setSdrPlayV3Settings(new SWGSDRangel::SWGSDRPlayV3Settings());
response.getSdrPlayV3Settings()->init();
webapiFormatDeviceSettings(response, m_settings);
return 200;
}
int SDRPlayV3Input::webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage)
{
(void) errorMessage;
SDRPlayV3Settings settings = m_settings;
QStringList deviceSettingsKeysModifiable = deviceSettingsKeys;
webapiUpdateDeviceSettings(settings, deviceSettingsKeysModifiable, response);
// Convert lnaGain to lnaIndex
if (deviceSettingsKeysModifiable.contains("lnaGain"))
{
int lnaGain = response.getSdrPlayV3Settings()->getLnaGain();
settings.m_lnaIndex = mapLNAGainDBToLNAIndex(lnaGain, settings.m_centerFrequency);
deviceSettingsKeysModifiable.append("lnaIndex");
}
MsgConfigureSDRPlayV3 *msg = MsgConfigureSDRPlayV3::create(settings, deviceSettingsKeysModifiable, force);
m_inputMessageQueue.push(msg);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureSDRPlayV3 *msgToGUI = MsgConfigureSDRPlayV3::create(settings, deviceSettingsKeysModifiable, force);
m_guiMessageQueue->push(msgToGUI);
}
webapiFormatDeviceSettings(response, settings);
return 200;
}
void SDRPlayV3Input::webapiUpdateDeviceSettings(
SDRPlayV3Settings& settings,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response)
{
if (deviceSettingsKeys.contains("centerFrequency")) {
settings.m_centerFrequency = response.getSdrPlayV3Settings()->getCenterFrequency();
}
if (deviceSettingsKeys.contains("LOppmTenths")) {
settings.m_LOppmTenths = response.getSdrPlayV3Settings()->getLOppmTenths();
}
if (deviceSettingsKeys.contains("ifFrequencyIndex")) {
settings.m_ifFrequencyIndex = response.getSdrPlayV3Settings()->getIfFrequencyIndex();
}
if (deviceSettingsKeys.contains("bandwidthIndex")) {
settings.m_bandwidthIndex = response.getSdrPlayV3Settings()->getBandwidthIndex();
}
if (deviceSettingsKeys.contains("devSampleRate")) {
settings.m_devSampleRate = response.getSdrPlayV3Settings()->getDevSampleRate();
}
if (deviceSettingsKeys.contains("log2Decim")) {
settings.m_log2Decim = response.getSdrPlayV3Settings()->getLog2Decim();
}
if (deviceSettingsKeys.contains("fcPos"))
{
int fcPos = response.getSdrPlayV3Settings()->getFcPos();
fcPos = fcPos < 0 ? 0 : fcPos > 2 ? 2 : fcPos;
settings.m_fcPos = (SDRPlayV3Settings::fcPos_t) fcPos;
}
if (deviceSettingsKeys.contains("dcBlock")) {
settings.m_dcBlock = response.getSdrPlayV3Settings()->getDcBlock() != 0;
}
if (deviceSettingsKeys.contains("iqCorrection")) {
settings.m_iqCorrection = response.getSdrPlayV3Settings()->getIqCorrection() != 0;
}
if (deviceSettingsKeys.contains("lnaIndex")) {
settings.m_lnaIndex = response.getSdrPlayV3Settings()->getLnaIndex();
}
if (deviceSettingsKeys.contains("ifAGC")) {
settings.m_ifAGC = response.getSdrPlayV3Settings()->getIfAgc() != 0;
}
if (deviceSettingsKeys.contains("ifGain")) {
settings.m_ifGain = response.getSdrPlayV3Settings()->getIfGain();
}
if (deviceSettingsKeys.contains("amNotch")) {
settings.m_amNotch = response.getSdrPlayV3Settings()->getAmNotch();
}
if (deviceSettingsKeys.contains("fmNotch")) {
settings.m_fmNotch = response.getSdrPlayV3Settings()->getFmNotch();
}
if (deviceSettingsKeys.contains("dabNotch")) {
settings.m_dabNotch = response.getSdrPlayV3Settings()->getDabNotch();
}
if (deviceSettingsKeys.contains("extRef")) {
settings.m_extRef = response.getSdrPlayV3Settings()->getExtRef();
}
if (deviceSettingsKeys.contains("tuner")) {
settings.m_tuner = response.getSdrPlayV3Settings()->getTuner();
}
if (deviceSettingsKeys.contains("antenna")) {
settings.m_antenna = response.getSdrPlayV3Settings()->getAntenna();
}
if (deviceSettingsKeys.contains("transverterDeltaFrequency")) {
settings.m_transverterDeltaFrequency = response.getSdrPlayV3Settings()->getTransverterDeltaFrequency();
}
if (deviceSettingsKeys.contains("transverterMode")) {
settings.m_transverterMode = response.getSdrPlayV3Settings()->getTransverterMode() != 0;
}
if (deviceSettingsKeys.contains("iqOrder")) {
settings.m_iqOrder = response.getSdrPlayV3Settings()->getIqOrder() != 0;
}
if (deviceSettingsKeys.contains("biasTee")) {
settings.m_biasTee = response.getSdrPlayV3Settings()->getBiasTee() != 0;
}
if (deviceSettingsKeys.contains("useReverseAPI")) {
settings.m_useReverseAPI = response.getSdrPlayV3Settings()->getUseReverseApi() != 0;
}
if (deviceSettingsKeys.contains("reverseAPIAddress")) {
settings.m_reverseAPIAddress = *response.getSdrPlayV3Settings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getSdrPlayV3Settings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getSdrPlayV3Settings()->getReverseApiDeviceIndex();
}
}
void SDRPlayV3Input::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SDRPlayV3Settings& settings)
{
response.getSdrPlayV3Settings()->setCenterFrequency(settings.m_centerFrequency);
response.getSdrPlayV3Settings()->setLOppmTenths(settings.m_LOppmTenths);
response.getSdrPlayV3Settings()->setIfFrequencyIndex(settings.m_ifFrequencyIndex);
response.getSdrPlayV3Settings()->setBandwidthIndex(settings.m_bandwidthIndex);
response.getSdrPlayV3Settings()->setDevSampleRate(settings.m_devSampleRate);
response.getSdrPlayV3Settings()->setLog2Decim(settings.m_log2Decim);
response.getSdrPlayV3Settings()->setFcPos((int) settings.m_fcPos);
response.getSdrPlayV3Settings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
response.getSdrPlayV3Settings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
response.getSdrPlayV3Settings()->setLnaIndex(settings.m_lnaIndex);
response.getSdrPlayV3Settings()->setLnaGain(0); // Write only setting
response.getSdrPlayV3Settings()->setIfAgc(settings.m_ifAGC ? 1 : 0);
response.getSdrPlayV3Settings()->setIfGain(settings.m_ifGain);
response.getSdrPlayV3Settings()->setAmNotch(settings.m_amNotch);
response.getSdrPlayV3Settings()->setFmNotch(settings.m_fmNotch);
response.getSdrPlayV3Settings()->setDabNotch(settings.m_dabNotch);
response.getSdrPlayV3Settings()->setExtRef(settings.m_extRef);
response.getSdrPlayV3Settings()->setTuner(settings.m_tuner);
response.getSdrPlayV3Settings()->setAntenna(settings.m_antenna);
response.getSdrPlayV3Settings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency);
response.getSdrPlayV3Settings()->setTransverterMode(settings.m_transverterMode ? 1 : 0);
response.getSdrPlayV3Settings()->setIqOrder(settings.m_iqOrder ? 1 : 0);
response.getSdrPlayV3Settings()->setBiasTee(settings.m_biasTee ? 1 : 0);
response.getSdrPlayV3Settings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
if (response.getSdrPlayV3Settings()->getReverseApiAddress()) {
*response.getSdrPlayV3Settings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
} else {
response.getSdrPlayV3Settings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
}
response.getSdrPlayV3Settings()->setReverseApiPort(settings.m_reverseAPIPort);
response.getSdrPlayV3Settings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
}
int SDRPlayV3Input::webapiReportGet(
SWGSDRangel::SWGDeviceReport& response,
QString& errorMessage)
{
(void) errorMessage;
response.setSdrPlayV3Report(new SWGSDRangel::SWGSDRPlayV3Report());
response.getSdrPlayV3Report()->init();
webapiFormatDeviceReport(response);
return 200;
}
void SDRPlayV3Input::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response)
{
response.getSdrPlayV3Report()->setIntermediateFrequencies(new QList<SWGSDRangel::SWGFrequency*>);
for (unsigned int i = 0; i < SDRPlayV3IF::getNbIFs(); i++)
{
response.getSdrPlayV3Report()->getIntermediateFrequencies()->append(new SWGSDRangel::SWGFrequency);
response.getSdrPlayV3Report()->getIntermediateFrequencies()->back()->setFrequency(SDRPlayV3IF::getIF(i));
}
response.getSdrPlayV3Report()->setBandwidths(new QList<SWGSDRangel::SWGBandwidth*>);
for (unsigned int i = 0; i < SDRPlayV3Bandwidths::getNbBandwidths(); i++)
{
response.getSdrPlayV3Report()->getBandwidths()->append(new SWGSDRangel::SWGBandwidth);
response.getSdrPlayV3Report()->getBandwidths()->back()->setBandwidth(SDRPlayV3Bandwidths::getBandwidth(i));
}
switch(getDeviceId())
{
case SDRPLAY_RSP1_ID:
response.getSdrPlayV3Report()->setDeviceType(new QString("RSP1"));
break;
case SDRPLAY_RSP1A_ID:
response.getSdrPlayV3Report()->setDeviceType(new QString("RSP1A"));
break;
case SDRPLAY_RSP2_ID:
response.getSdrPlayV3Report()->setDeviceType(new QString("RSP2"));
break;
case SDRPLAY_RSPduo_ID:
response.getSdrPlayV3Report()->setDeviceType(new QString("RSPduo"));
break;
case SDRPLAY_RSPdx_ID:
response.getSdrPlayV3Report()->setDeviceType(new QString("RSPdx"));
break;
default:
response.getSdrPlayV3Report()->setDeviceType(new QString("Unknown"));
break;
}
}
void SDRPlayV3Input::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const SDRPlayV3Settings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("SDRplayV3"));
swgDeviceSettings->setSdrPlayV3Settings(new SWGSDRangel::SWGSDRPlayV3Settings());
SWGSDRangel::SWGSDRPlayV3Settings *swgSDRPlayV3Settings = swgDeviceSettings->getSdrPlayV3Settings();
// transfer data that has been modified. When force is on transfer all data except reverse API data
if (deviceSettingsKeys.contains("centerFrequency") || force) {
swgSDRPlayV3Settings->setCenterFrequency(settings.m_centerFrequency);
}
if (deviceSettingsKeys.contains("LOppmTenths") || force) {
swgSDRPlayV3Settings->setLOppmTenths(settings.m_LOppmTenths);
}
if (deviceSettingsKeys.contains("ifFrequencyIndex") || force) {
swgSDRPlayV3Settings->setIfFrequencyIndex(settings.m_ifFrequencyIndex);
}
if (deviceSettingsKeys.contains("bandwidthIndex") || force) {
swgSDRPlayV3Settings->setBandwidthIndex(settings.m_bandwidthIndex);
}
if (deviceSettingsKeys.contains("devSampleRate") || force) {
swgSDRPlayV3Settings->setDevSampleRate(settings.m_devSampleRate);
}
if (deviceSettingsKeys.contains("log2Decim") || force) {
swgSDRPlayV3Settings->setLog2Decim(settings.m_log2Decim);
}
if (deviceSettingsKeys.contains("fcPos") || force) {
swgSDRPlayV3Settings->setFcPos((int) settings.m_fcPos);
}
if (deviceSettingsKeys.contains("dcBlock") || force) {
swgSDRPlayV3Settings->setDcBlock(settings.m_dcBlock ? 1 : 0);
}
if (deviceSettingsKeys.contains("iqCorrection") || force) {
swgSDRPlayV3Settings->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
}
if (deviceSettingsKeys.contains("lnaIndex") || force) {
swgSDRPlayV3Settings->setLnaIndex(settings.m_lnaIndex);
}
if (deviceSettingsKeys.contains("lnaGain") || force) {
swgSDRPlayV3Settings->setLnaGain(0); // Write only setting
}
if (deviceSettingsKeys.contains("ifAGC") || force) {
swgSDRPlayV3Settings->setIfAgc(settings.m_ifAGC ? 1 : 0);
}
if (deviceSettingsKeys.contains("ifGain") || force) {
swgSDRPlayV3Settings->setIfGain(settings.m_ifGain);
}
if (deviceSettingsKeys.contains("amNotch") || force) {
swgSDRPlayV3Settings->setAmNotch(settings.m_amNotch);
}
if (deviceSettingsKeys.contains("fmNotch") || force) {
swgSDRPlayV3Settings->setFmNotch(settings.m_fmNotch);
}
if (deviceSettingsKeys.contains("dabNotch") || force) {
swgSDRPlayV3Settings->setDabNotch(settings.m_dabNotch);
}
if (deviceSettingsKeys.contains("extRef") || force) {
swgSDRPlayV3Settings->setExtRef(settings.m_extRef);
}
if (deviceSettingsKeys.contains("tuner") || force) {
swgSDRPlayV3Settings->setTuner(settings.m_tuner);
}
if (deviceSettingsKeys.contains("antenna") || force) {
swgSDRPlayV3Settings->setAntenna(settings.m_antenna);
}
if (deviceSettingsKeys.contains("transverterDeltaFrequency") || force) {
swgSDRPlayV3Settings->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency);
}
if (deviceSettingsKeys.contains("transverterMode") || force) {
swgSDRPlayV3Settings->setTransverterMode(settings.m_transverterMode ? 1 : 0);
}
if (deviceSettingsKeys.contains("iqOrder") || force) {
swgSDRPlayV3Settings->setIqOrder(settings.m_iqOrder ? 1 : 0);
}
if (deviceSettingsKeys.contains("biasTee") || force) {
swgSDRPlayV3Settings->setBiasTee(settings.m_biasTee ? 1 : 0);
}
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");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
// Always use PATCH to avoid passing reverse API settings
QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
buffer->setParent(reply);
delete swgDeviceSettings;
}
void SDRPlayV3Input::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("SDRplayV3"));
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));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
if (start) {
reply = m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
} else {
reply = m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
}
buffer->setParent(reply);
delete swgDeviceSettings;
}
void SDRPlayV3Input::networkManagerFinished(QNetworkReply *reply)
{
QNetworkReply::NetworkError replyError = reply->error();
if (replyError)
{
qWarning() << "SDRPlayV3Input::networkManagerFinished:"
<< " error(" << (int) replyError
<< "): " << replyError
<< ": " << reply->errorString();
}
else
{
QString answer = reply->readAll();
answer.chop(1); // remove last \n
qDebug("SDRPlayV3Input::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
}
reply->deleteLater();
}
int SDRPlayV3Input::getDeviceId() const
{
if (m_dev != nullptr)
return m_dev->hwVer; // E.g. SDRPLAY_RSPduo_ID
else
return -1;
}
// Convert gain in dB to closest index
int SDRPlayV3Input::mapLNAGainDBToLNAIndex(int gainDB, qint64 frequency) const
{
const int *attenuations = SDRPlayV3LNA::getAttenuations(getDeviceId(), frequency);
int len = attenuations[0];
for (int i = 1; i <= len; i++)
{
if (gainDB >= -attenuations[i]) {
return i - 1;
}
}
return len - 1;
}
// Convert index to gain in dB
int SDRPlayV3Input::mapLNAIndexToLNAGainDB(int lnaIndex, qint64 frequency) const
{
const int *attenuations = SDRPlayV3LNA::getAttenuations(getDeviceId(), frequency);
int len = attenuations[0];
if (lnaIndex < len) {
return attenuations[lnaIndex+1];
} else {
return -1000;
}
}
// ====================================================================
sdrplay_api_Bw_MHzT SDRPlayV3Bandwidths::m_bwEnums[m_nb_bw] = {
sdrplay_api_BW_0_200,
sdrplay_api_BW_0_300,
sdrplay_api_BW_0_600,
sdrplay_api_BW_1_536,
sdrplay_api_BW_5_000,
sdrplay_api_BW_6_000,
sdrplay_api_BW_7_000,
sdrplay_api_BW_8_000
};
unsigned int SDRPlayV3Bandwidths::m_bw[m_nb_bw] = {
200000, // 0
300000, // 1
600000, // 2
1536000, // 3
5000000, // 4
6000000, // 5
7000000, // 6
8000000, // 7
};
sdrplay_api_Bw_MHzT SDRPlayV3Bandwidths::getBandwidthEnum(unsigned int bandwidth_index)
{
if (bandwidth_index < m_nb_bw)
{
return m_bwEnums[bandwidth_index];
}
else
{
return m_bwEnums[0];
}
}
unsigned int SDRPlayV3Bandwidths::getBandwidth(unsigned int bandwidth_index)
{
if (bandwidth_index < m_nb_bw)
{
return m_bw[bandwidth_index];
}
else
{
return m_bw[0];
}
}
unsigned int SDRPlayV3Bandwidths::getBandwidthIndex(unsigned int bandwidth)
{
for (unsigned int i=0; i < m_nb_bw; i++)
{
if (bandwidth == m_bw[i])
{
return i;
}
}
return 0;
}
unsigned int SDRPlayV3Bandwidths::getNbBandwidths()
{
return SDRPlayV3Bandwidths::m_nb_bw;
}
// ====================================================================
sdrplay_api_If_kHzT SDRPlayV3IF::m_ifEnums[m_nb_if] = {
sdrplay_api_IF_Zero,
sdrplay_api_IF_0_450,
sdrplay_api_IF_1_620,
sdrplay_api_IF_2_048
};
unsigned int SDRPlayV3IF::m_if[m_nb_if] = {
0, // 0
450000, // 1
1620000, // 2
2048000, // 3
};
sdrplay_api_If_kHzT SDRPlayV3IF::getIFEnum(unsigned int if_index)
{
if (if_index < m_nb_if)
{
return m_ifEnums[if_index];
}
else
{
return m_ifEnums[0];
}
}
unsigned int SDRPlayV3IF::getIF(unsigned int if_index)
{
if (if_index < m_nb_if)
{
return m_if[if_index];
}
else
{
return m_if[0];
}
}
unsigned int SDRPlayV3IF::getIFIndex(unsigned int iff)
{
for (unsigned int i=0; i < m_nb_if; i++)
{
if (iff == m_if[i])
{
return i;
}
}
return 0;
}
unsigned int SDRPlayV3IF::getNbIFs()
{
return SDRPlayV3IF::m_nb_if;
}
// ====================================================================
// LNA state attenuation values - for some devices, such as rsp1, this is combination of LNA and mixer attenuation
const int SDRPlayV3LNA::rsp1Attenuation[3][5] =
{
{4, 0, 24, 19, 43},
{4, 0, 7, 19, 26},
{4, 0, 5, 19, 24}
};
const int SDRPlayV3LNA::rsp1AAttenuation[4][11] =
{
{7, 0, 6, 12, 18, 37, 42, 61},
{10, 0, 6, 12, 18, 20, 26, 32, 38, 57, 62},
{10, 0, 7, 13, 19, 20, 27, 33, 39, 45, 64},
{ 9, 0, 6, 12, 20, 26, 32, 38, 43, 62}
};
const int SDRPlayV3LNA::rsp1BAttenuation[5][11] =
{
{7, 0, 6, 12, 18, 37, 42, 61},
{10, 0, 6, 12, 18, 20, 26, 32, 38, 57, 62},
{10, 0, 6, 12, 18, 20, 26, 32, 38, 57, 62},
{10, 0, 7, 13, 19, 20, 27, 33, 39, 45, 64},
{ 9, 0, 6, 12, 20, 26, 32, 38, 43, 62}
};
const int SDRPlayV3LNA::rsp2Attenuation[3][10] =
{
{9, 0, 10, 15, 21, 24, 34, 39, 45, 64},
{6, 0, 7, 10, 17, 22, 41},
{6, 0, 5, 21, 15, 15, 32}
};
const int SDRPlayV3LNA::rspDuoAttenuation[5][11] =
{
{ 7, 0, 6, 12, 18, 37, 42, 61},
{10, 0, 6, 12, 18, 20, 26, 32, 38, 57, 62},
{10, 0, 7, 13, 19, 20, 27, 33, 39, 45, 64},
{ 9, 0, 6, 12, 20, 26, 32, 38, 43, 62},
{ 5, 0, 6, 12, 18, 37} // HiZ port
};
const int SDRPlayV3LNA::rspDxAttenuation[7][29] =
{
{22, 0, 3, 6, 9, 12, 15, 18, 21, 24, 25, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60},
{19, 0, 3, 6, 9, 12, 15, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60},
{20, 0, 3, 6, 9, 12, 15, 18, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60},
{27, 0, 3, 6, 9, 12, 15, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84},
{28, 0, 3, 6, 9, 12, 15, 18, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84},
{21, 0, 7, 10, 13, 16, 19, 22, 25, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67},
{19, 0, 5, 8, 11, 14, 17, 20, 32, 35, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65}
};
const int *SDRPlayV3LNA::getAttenuations(int deviceId, qint64 frequency)
{
int row;
const int *lnaAttenuation;
switch (deviceId)
{
case SDRPLAY_RSP1_ID:
if (frequency < 420000000)
row = 0;
else if (frequency < 10000000000)
row = 1;
else
row = 2;
lnaAttenuation = &rsp1Attenuation[row][0];
break;
case SDRPLAY_RSP1A_ID:
if (frequency < 60000000)
row = 0;
else if (frequency < 420000000)
row = 1;
else if (frequency < 1000000000)
row = 2;
else
row = 3;
lnaAttenuation = &rsp1AAttenuation[row][0];
break;
case SDRPLAY_RSP1B_ID:
if (frequency < 50000000)
row = 0;
else if (frequency < 60000000)
row = 1;
else if (frequency < 420000000)
row = 2;
else if (frequency < 1000000000)
row = 3;
else
row = 4;
lnaAttenuation = &rsp1BAttenuation[row][0];
break;
case SDRPLAY_RSP2_ID:
if (frequency < 420000000)
row = 0;
else if (frequency < 1000000000)
row = 1;
else
row = 2;
lnaAttenuation = &rsp2Attenuation[row][0];
break;
case SDRPLAY_RSPduo_ID:
if (frequency < 60000000)
row = 0;
else if (frequency < 420000000)
row = 1;
else if (frequency < 1000000000)
row = 2;
else
row = 3;
lnaAttenuation = &rspDuoAttenuation[row][0];
break;
case SDRPLAY_RSPdx_ID:
if (frequency < 2000000)
row = 0;
else if (frequency < 12000000)
row = 1;
else if (frequency < 60000000)
row = 2;
else if (frequency < 250000000)
row = 3;
else if (frequency < 420000000)
row = 4;
else if (frequency < 1000000000)
row = 5;
else
row = 6;
lnaAttenuation = &rspDxAttenuation[row][0];
break;
default:
lnaAttenuation = nullptr;
break;
}
return lnaAttenuation;
}