diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp index d215a1957..55cafb98e 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp @@ -22,6 +22,9 @@ #include #include +#include +#include + #include "ui_sdrdaemonsinkgui.h" #include "plugin/pluginapi.h" #include "gui/colormapper.h" @@ -43,8 +46,15 @@ SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceSinkAPI *deviceAPI, QWidget* parent) : m_sampleRate(0), m_samplesCount(0), m_tickCount(0), - m_lastEngineState((DSPDeviceSinkEngine::State)-1) + m_lastEngineState((DSPDeviceSinkEngine::State)-1), + m_doApplySettings(true) { + m_nnSender = nn_socket(AF_SP, NN_PAIR); + assert(m_nnSender != -1); + int millis = 500; + int rc = nn_setsockopt (m_nnSender, NN_SOL_SOCKET, NN_SNDTIMEO, &millis, sizeof (millis)); + assert (rc == 0); + ui->setupUi(this); ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold)); @@ -58,13 +68,15 @@ SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceSinkAPI *deviceAPI, QWidget* parent) : connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); m_statusTimer.start(500); - displaySettings(); - m_deviceSampleSink = new SDRdaemonSinkOutput(m_deviceAPI, m_deviceAPI->getMainWindow()->getMasterTimer()); connect(m_deviceSampleSink->getOutputMessageQueueToGUI(), SIGNAL(messageEnqueued()), this, SLOT(handleSinkMessages())); m_deviceAPI->setSink(m_deviceSampleSink); connect(m_deviceAPI->getDeviceOutputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleDSPMessages()), Qt::QueuedConnection); + + displaySettings(); + sendControl(true); + sendSettings(); } SDRdaemonSinkGui::~SDRdaemonSinkGui() @@ -72,6 +84,11 @@ SDRdaemonSinkGui::~SDRdaemonSinkGui() delete ui; } +void SDRdaemonSinkGui::blockApplySettings(bool block) +{ + m_doApplySettings = !block; +} + void SDRdaemonSinkGui::destroy() { delete this; @@ -89,8 +106,10 @@ QString SDRdaemonSinkGui::getName() const void SDRdaemonSinkGui::resetToDefaults() { + blockApplySettings(true); m_settings.resetToDefaults(); displaySettings(); + blockApplySettings(false); sendSettings(); } @@ -103,6 +122,7 @@ void SDRdaemonSinkGui::setCenterFrequency(qint64 centerFrequency) { m_settings.m_centerFrequency = centerFrequency; displaySettings(); + sendControl(); sendSettings(); } @@ -113,12 +133,19 @@ QByteArray SDRdaemonSinkGui::serialize() const bool SDRdaemonSinkGui::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + blockApplySettings(true); + + if(m_settings.deserialize(data)) + { displaySettings(); + blockApplySettings(false); + sendControl(true); sendSettings(); return true; - } else { - resetToDefaults(); + } + else + { + blockApplySettings(false); return false; } } @@ -184,6 +211,107 @@ void SDRdaemonSinkGui::displaySettings() { ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000); ui->sampleRate->setValue(m_settings.m_sampleRate); + ui->deviceRateText->setText(tr("%1k").arg((float)(m_sampleRate*(1<interp->setCurrentIndex(m_settings.m_log2Interp); + ui->txDelay->setValue(m_settings.m_txDelay/10); + ui->txDelayText->setText(tr("%1").arg(m_settings.m_txDelay)); + ui->nbFECBlocks->setValue(m_settings.m_nbFECBlocks); + + QString s0 = QString::number(128 + m_settings.m_nbFECBlocks, 'f', 0); + QString s1 = QString::number(m_settings.m_nbFECBlocks, 'f', 0); + ui->nominalNbBlocksText->setText(tr("%1/%2").arg(s0).arg(s1)); + + ui->address->setText(m_settings.m_address); + ui->dataPort->setText(tr("%1").arg(m_settings.m_dataPort)); + ui->controlPort->setText(tr("%1").arg(m_settings.m_controlPort)); + ui->specificParms->setText(m_settings.m_specificParameters); +} + +void SDRdaemonSinkGui::sendControl(bool force) +{ + if ((m_settings.m_address != m_controlSettings.m_address) || + (m_settings.m_controlPort != m_controlSettings.m_controlPort) || force) + { + int rc = nn_shutdown(m_nnSender, 0); + + if (rc < 0) { + qDebug() << "SDRdaemonSinkGui::sendControl: disconnection failed"; + } else { + qDebug() << "SDRdaemonSinkGui::sendControl: disconnection successful"; + } + + std::ostringstream os; + os << "tcp://" << m_settings.m_address.toStdString() << ":" << m_settings.m_controlPort; + std::string addrstrng = os.str(); + rc = nn_connect(m_nnSender, addrstrng.c_str()); + + if (rc < 0) + { + qDebug() << "SDRdaemonSinkGui::sendControl: connection to " << addrstrng.c_str() << " failed"; + QMessageBox::information(this, tr("Message"), tr("Cannot connect to remote control port")); + return; + } + else + { + qDebug() << "SDRdaemonSinkGui::sendControl: connection to " << addrstrng.c_str() << " successful"; + force = true; + } + } + + std::ostringstream os; + int nbArgs = 0; + bool ok; + + if ((m_settings.m_centerFrequency != m_controlSettings.m_centerFrequency) || force) + { + os << "freq=" << m_settings.m_centerFrequency*1000LL; + nbArgs++; + } + + if ((m_settings.m_sampleRate != m_controlSettings.m_sampleRate) || force) + { + if (nbArgs > 0) os << ","; + os << "srate=" << m_settings.m_sampleRate; + nbArgs++; + } + + if ((m_settings.m_log2Interp != m_controlSettings.m_log2Interp) || force) + { + if (nbArgs > 0) os << ","; + os << "interp=" << m_settings.m_log2Interp; + nbArgs++; + } + + if ((m_settings.m_specificParameters != m_controlSettings.m_specificParameters) || force) + { + if (nbArgs > 0) os << ","; + os << m_settings.m_specificParameters.toStdString(); + nbArgs++; + } + + if (nbArgs > 0) + { + int config_size = os.str().size(); + int rc = nn_send(m_nnSender, (void *) os.str().c_str(), config_size, 0); + + if (rc != config_size) + { + QMessageBox::information(this, tr("Message"), tr("Cannot send message to remote control port")); + } + else + { + qDebug() << "SDRdaemonSinkGui::sendControl:" + << " remoteAddress: " << m_settings.m_address + << " message: " << os.str().c_str(); + } + } + + m_controlSettings.m_address = m_settings.m_address; + m_controlSettings.m_controlPort = m_settings.m_controlPort; + m_controlSettings.m_centerFrequency = m_settings.m_controlPort; + m_controlSettings.m_sampleRate = m_settings.m_sampleRate; + m_controlSettings.m_log2Interp = m_settings.m_log2Interp; + m_controlSettings.m_specificParameters = m_settings.m_specificParameters; } void SDRdaemonSinkGui::sendSettings() @@ -233,12 +361,14 @@ void SDRdaemonSinkGui::updateStatus() void SDRdaemonSinkGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; + sendControl(); sendSettings(); } void SDRdaemonSinkGui::on_sampleRate_changed(quint64 value) { m_settings.m_sampleRate = value; + sendControl(); sendSettings(); } @@ -250,9 +380,82 @@ void SDRdaemonSinkGui::on_interp_currentIndexChanged(int index) m_settings.m_log2Interp = index; updateSampleRateAndFrequency(); + sendControl(); +} + +void SDRdaemonSinkGui::on_txDelay_valueChanged(int value) +{ + m_settings.m_txDelay = value * 10; + ui->txDelayText->setText(tr("%1").arg(10*value)); sendSettings(); } +void SDRdaemonSinkGui::on_nbFECBlocks_valueChanged(int value) +{ + m_settings.m_nbFECBlocks = value; + int nbOriginalBlocks = 128; + int nbFECBlocks = value; + QString s = QString::number(nbOriginalBlocks + nbFECBlocks, 'f', 0); + QString s1 = QString::number(nbFECBlocks, 'f', 0); + ui->nominalNbBlocksText->setText(tr("%1/%2").arg(s).arg(s1)); + sendSettings(); +} + +void SDRdaemonSinkGui::on_address_textEdited(const QString& arg1) +{ + m_settings.m_address = ui->address->text(); + sendControl(); + sendSettings(); +} + +void SDRdaemonSinkGui::on_dataPort_textEdited(const QString& arg1) +{ + bool dataOk; + int udpDataPort = ui->dataPort->text().toInt(&dataOk); + + if((!dataOk) || (udpDataPort < 1024) || (udpDataPort > 65535)) + { + return; + } + else + { + m_settings.m_dataPort = udpDataPort; + } + + sendSettings(); +} + +void SDRdaemonSinkGui::on_controlPort_textEdited(const QString& arg1) +{ + bool ctlOk; + int udpCtlPort = ui->dataPort->text().toInt(&ctlOk); + + if((!ctlOk) || (udpCtlPort < 1024) || (udpCtlPort > 65535)) + { + return; + } + else + { + m_settings.m_controlPort = udpCtlPort; + } + + sendControl(); +} + +void SDRdaemonSinkGui::on_specificParms_textEdited(const QString& arg1) +{ + m_settings.m_specificParameters = ui->specificParms->text(); + sendControl(); +} + +void on_applyButton_clicked(bool checked) +{ +} + +void on_sendButton_clicked(bool checked) +{ +} + void SDRdaemonSinkGui::on_startStop_toggled(bool checked) { if (checked) diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h index 5a6e6b2b2..a5c9d1125 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h @@ -53,7 +53,8 @@ private: Ui::SDRdaemonSinkGui* ui; DeviceSinkAPI* m_deviceAPI; - SDRdaemonSinkSettings m_settings; + SDRdaemonSinkSettings m_settings; //!< current settings + SDRdaemonSinkSettings m_controlSettings; //!< settings last sent to device via control port QTimer m_updateTimer; QTimer m_statusTimer; DeviceSampleSink* m_deviceSampleSink; @@ -62,9 +63,14 @@ private: int m_samplesCount; std::size_t m_tickCount; int m_lastEngineState; + bool m_doApplySettings; + int m_nnSender; + + void blockApplySettings(bool block); void displaySettings(); void displayTime(); + void sendControl(bool force = false); void sendSettings(); void updateWithStreamTime(); void updateSampleRateAndFrequency(); @@ -74,10 +80,16 @@ private slots: void handleSinkMessages(); void on_centerFrequency_changed(quint64 value); void on_sampleRate_changed(quint64 value); - void on_startStop_toggled(bool checked); - void on_interp_currentIndexChanged(int index); - void on_txDelay_valueChanged(int value); + void on_interp_currentIndexChanged(int index); + void on_txDelay_valueChanged(int value); void on_nbFECBlocks_valueChanged(int value); + void on_address_textEdited(const QString& arg1); + void on_dataPort_textEdited(const QString& arg1); + void on_controlPort_textEdited(const QString& arg1); + void on_specificParms_textEdited(const QString& arg1); + void on_applyButton_clicked(bool checked); + void on_sendButton_clicked(bool checked); + void on_startStop_toggled(bool checked); void updateHardware(); void updateStatus(); void tick(); diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.ui b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.ui index d656823ad..8452cb3f4 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.ui +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.ui @@ -308,9 +308,18 @@ + + + 32 + 0 + + 0000 + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + @@ -357,7 +366,7 @@ - 50 + 52 0 diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.cpp index 648454a2c..d9ca43df1 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.cpp @@ -27,8 +27,12 @@ void SDRdaemonSinkSettings::resetToDefaults() m_centerFrequency = 435000*1000; m_sampleRate = 48000; m_log2Interp = 0; + m_txDelay = 300; + m_nbFECBlocks = 0; m_address = "127.0.0.1"; - m_port = 9090; + m_dataPort = 9090; + m_controlPort = 9090; + m_specificParameters = ""; } QByteArray SDRdaemonSinkSettings::serialize() const @@ -37,8 +41,12 @@ QByteArray SDRdaemonSinkSettings::serialize() const s.writeU64(1, m_sampleRate); s.writeU32(2, m_log2Interp); - s.writeString(3, m_address); - s.writeU32(4, m_port); + s.writeU32(3, m_txDelay); + s.writeU32(4, m_nbFECBlocks); + s.writeString(5, m_address); + s.writeU32(6, m_dataPort); + s.writeU32(7, m_controlPort); + s.writeString(8, m_specificParameters); return s.final(); } @@ -59,9 +67,14 @@ bool SDRdaemonSinkSettings::deserialize(const QByteArray& data) quint32 uintval; d.readU64(1, &m_sampleRate, 48000); d.readU32(2, &m_log2Interp, 0); - d.readString(3, &m_address, ""); - d.readU32(4, &uintval, 9090); - m_port = uintval % (1<<16); + d.readU32(3, &m_txDelay, 300); + d.readU32(4, &m_nbFECBlocks, 0); + d.readString(5, &m_address, "127.0.0.1"); + d.readU32(6, &uintval, 9090); + m_dataPort = uintval % (1<<16); + d.readU32(7, &uintval, 9090); + m_controlPort = uintval % (1<<16); + d.readString(5, &m_specificParameters, ""); return true; } else diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.h index acc5596ec..05d73e844 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinksettings.h @@ -23,8 +23,12 @@ struct SDRdaemonSinkSettings { quint64 m_centerFrequency; quint64 m_sampleRate; quint32 m_log2Interp; + quint32 m_txDelay; + quint32 m_nbFECBlocks; QString m_address; - quint16 m_port; + quint16 m_dataPort; + quint16 m_controlPort; + QString m_specificParameters; SDRdaemonSinkSettings(); void resetToDefaults();