diff --git a/plugins/samplesource/remoteinput/remoteinput.cpp b/plugins/samplesource/remoteinput/remoteinput.cpp
index e5a306617..f19a6c31e 100644
--- a/plugins/samplesource/remoteinput/remoteinput.cpp
+++ b/plugins/samplesource/remoteinput/remoteinput.cpp
@@ -242,8 +242,14 @@ void RemoteInput::applySettings(const RemoteInputSettings& settings, bool force)
settings.m_iqCorrection ? "true" : "false");
}
- m_remoteInputUDPHandler->configureUDPLink(settings.m_dataAddress, settings.m_dataPort);
- m_remoteInputUDPHandler->getRemoteAddress(remoteAddress);
+ if ((m_settings.m_dataAddress != settings.m_dataAddress) ||
+ (m_settings.m_dataPort != settings.m_dataPort) ||
+ (m_settings.m_multicastAddress != settings.m_multicastAddress) ||
+ (m_settings.m_multicastJoin != settings.m_multicastJoin) || force)
+ {
+ m_remoteInputUDPHandler->configureUDPLink(settings.m_dataAddress, settings.m_dataPort, settings.m_multicastAddress, settings.m_multicastJoin);
+ m_remoteInputUDPHandler->getRemoteAddress(remoteAddress);
+ }
mutexLocker.unlock();
diff --git a/plugins/samplesource/remoteinput/remoteinputgui.cpp b/plugins/samplesource/remoteinput/remoteinputgui.cpp
index 5f44d7011..78ffd14f9 100644
--- a/plugins/samplesource/remoteinput/remoteinputgui.cpp
+++ b/plugins/samplesource/remoteinput/remoteinputgui.cpp
@@ -304,6 +304,11 @@ void RemoteInputGui::displaySettings()
ui->apiPort->setText(tr("%1").arg(m_settings.m_apiPort));
ui->dataPort->setText(tr("%1").arg(m_settings.m_dataPort));
ui->dataAddress->setText(m_settings.m_dataAddress);
+ ui->multicastAddress->setText(m_settings.m_multicastAddress);
+ ui->multicastJoin->setChecked(m_settings.m_multicastJoin);
+
+ ui->dataApplyButton->setEnabled(false);
+ ui->dataApplyButton->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
ui->dcOffset->setChecked(m_settings.m_dcBlock);
ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
@@ -339,14 +344,9 @@ void RemoteInputGui::on_apiApplyButton_clicked(bool checked)
void RemoteInputGui::on_dataApplyButton_clicked(bool checked)
{
(void) checked;
- m_settings.m_dataAddress = ui->dataAddress->text();
- bool dataOk;
- int udpDataPort = ui->dataPort->text().toInt(&dataOk);
-
- if((dataOk) && (udpDataPort >= 1024) && (udpDataPort < 65535)) {
- m_settings.m_dataPort = udpDataPort;
- }
+ ui->dataApplyButton->setEnabled(false);
+ ui->dataApplyButton->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
sendSettings();
}
@@ -365,23 +365,38 @@ void RemoteInputGui::on_apiAddress_returnPressed()
void RemoteInputGui::on_dataAddress_returnPressed()
{
m_settings.m_dataAddress = ui->dataAddress->text();
- sendSettings();
+ ui->dataApplyButton->setEnabled(true);
+ ui->dataApplyButton->setStyleSheet("QPushButton { background-color : green; }");
}
void RemoteInputGui::on_dataPort_returnPressed()
{
- bool dataOk;
- int udpDataPort = ui->dataPort->text().toInt(&dataOk);
+ bool ok;
+ quint16 udpPort = ui->dataPort->text().toInt(&ok);
- if((!dataOk) || (udpDataPort < 1024) || (udpDataPort > 65535))
- {
- return;
- }
- else
- {
- m_settings.m_dataPort = udpDataPort;
- sendSettings();
+ if ((!ok) || (udpPort < 1024)) {
+ udpPort = 9998;
}
+
+ m_settings.m_dataPort = udpPort;
+ ui->dataPort->setText(tr("%1").arg(m_settings.m_dataPort));
+
+ ui->dataApplyButton->setEnabled(true);
+ ui->dataApplyButton->setStyleSheet("QPushButton { background-color : green; }");
+}
+
+void RemoteInputGui::on_multicastAddress_returnPressed()
+{
+ m_settings.m_multicastAddress = ui->multicastAddress->text();
+ ui->dataApplyButton->setEnabled(true);
+ ui->dataApplyButton->setStyleSheet("QPushButton { background-color : green; }");
+}
+
+void RemoteInputGui::on_multicastJoin_toggled(bool checked)
+{
+ m_settings.m_multicastJoin = checked;
+ ui->dataApplyButton->setEnabled(true);
+ ui->dataApplyButton->setStyleSheet("QPushButton { background-color : green; }");
}
void RemoteInputGui::on_apiPort_returnPressed()
diff --git a/plugins/samplesource/remoteinput/remoteinputgui.h b/plugins/samplesource/remoteinput/remoteinputgui.h
index 129bbf687..a3072de02 100644
--- a/plugins/samplesource/remoteinput/remoteinputgui.h
+++ b/plugins/samplesource/remoteinput/remoteinputgui.h
@@ -129,6 +129,8 @@ private slots:
void on_apiPort_returnPressed();
void on_dataAddress_returnPressed();
void on_dataPort_returnPressed();
+ void on_multicastAddress_returnPressed();
+ void on_multicastJoin_toggled(bool checked);
void on_startStop_toggled(bool checked);
void on_eventCountsReset_clicked(bool checked);
void updateHardware();
diff --git a/plugins/samplesource/remoteinput/remoteinputgui.ui b/plugins/samplesource/remoteinput/remoteinputgui.ui
index 0cfc7220c..305de464e 100644
--- a/plugins/samplesource/remoteinput/remoteinputgui.ui
+++ b/plugins/samplesource/remoteinput/remoteinputgui.ui
@@ -686,6 +686,9 @@
16777215
+
+ Set API link
+
Set
@@ -723,7 +726,7 @@
- Local data connection IPv4 address
+ Local network interface IPv4 address
000.000.000.000
@@ -758,7 +761,7 @@
- Local data connection port
+ Local data port
00000
@@ -792,6 +795,9 @@
16777215
+
+ Set data link
+
Set
@@ -799,6 +805,58 @@
+ -
+
+
-
+
+
+ Join or leave multicast group
+
+
+ Mcast
+
+
+
+ -
+
+
+
+ 120
+ 0
+
+
+
+
+ 120
+ 16777215
+
+
+
+ Multicast group address
+
+
+ 000.000.000.000
+
+
+ 0.0.0.0
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
-
-
diff --git a/plugins/samplesource/remoteinput/remoteinputsettings.cpp b/plugins/samplesource/remoteinput/remoteinputsettings.cpp
index 5336389df..1e3a72065 100644
--- a/plugins/samplesource/remoteinput/remoteinputsettings.cpp
+++ b/plugins/samplesource/remoteinput/remoteinputsettings.cpp
@@ -29,6 +29,8 @@ void RemoteInputSettings::resetToDefaults()
m_apiPort = 9091;
m_dataAddress = "127.0.0.1";
m_dataPort = 9090;
+ m_multicastAddress = "224.0.0.1";
+ m_multicastJoin = false;
m_dcBlock = false;
m_iqCorrection = false;
m_useReverseAPI = false;
@@ -41,6 +43,8 @@ QByteArray RemoteInputSettings::serialize() const
{
SimpleSerializer s(1);
+ s.writeString(3, m_multicastAddress);
+ s.writeBool(4, m_multicastJoin);
s.writeString(5, m_apiAddress);
s.writeU32(6, m_apiPort);
s.writeU32(7, m_dataPort);
@@ -69,6 +73,8 @@ bool RemoteInputSettings::deserialize(const QByteArray& data)
{
quint32 uintval;
+ d.readString(3, &m_multicastAddress, "224.0.0.1");
+ d.readBool(4, &m_multicastJoin, false);
d.readString(5, &m_apiAddress, "127.0.0.1");
d.readU32(6, &uintval, 9090);
m_apiPort = uintval % (1<<16);
diff --git a/plugins/samplesource/remoteinput/remoteinputsettings.h b/plugins/samplesource/remoteinput/remoteinputsettings.h
index bc11d5b8e..60cec764d 100644
--- a/plugins/samplesource/remoteinput/remoteinputsettings.h
+++ b/plugins/samplesource/remoteinput/remoteinputsettings.h
@@ -26,6 +26,8 @@ struct RemoteInputSettings {
quint16 m_apiPort;
QString m_dataAddress;
quint16 m_dataPort;
+ QString m_multicastAddress;
+ bool m_multicastJoin;
bool m_dcBlock;
bool m_iqCorrection;
bool m_useReverseAPI;
diff --git a/plugins/samplesource/remoteinput/remoteinputudphandler.cpp b/plugins/samplesource/remoteinput/remoteinputudphandler.cpp
index d5aba1186..38abf1c8c 100644
--- a/plugins/samplesource/remoteinput/remoteinputudphandler.cpp
+++ b/plugins/samplesource/remoteinput/remoteinputudphandler.cpp
@@ -27,6 +27,7 @@
#include "remoteinput.h"
MESSAGE_CLASS_DEFINITION(RemoteInputUDPHandler::MsgReportSampleRateChange, Message)
+MESSAGE_CLASS_DEFINITION(RemoteInputUDPHandler::MsgUDPAddressAndPort, Message)
RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
@@ -38,6 +39,8 @@ RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceA
m_dataAddress(QHostAddress::LocalHost),
m_remoteAddress(QHostAddress::LocalHost),
m_dataPort(9090),
+ m_multicastAddress(QStringLiteral("224.0.0.1")),
+ m_multicast(false),
m_dataConnected(false),
m_udpBuf(0),
m_udpReadBytes(0),
@@ -68,6 +71,8 @@ RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceA
m_throttlems = m_masterTimer.interval();
#endif
m_rateDivider = 1000 / m_throttlems;
+
+ connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()));
}
RemoteInputUDPHandler::~RemoteInputUDPHandler()
@@ -90,24 +95,31 @@ void RemoteInputUDPHandler::start()
return;
}
- if (!m_dataSocket)
- {
+ if (!m_dataSocket) {
m_dataSocket = new QUdpSocket(this);
}
if (!m_dataConnected)
{
- connect(m_dataSocket, SIGNAL(readyRead()), this, SLOT(dataReadyRead())); //, Qt::QueuedConnection);
-
- if (m_dataSocket->bind(m_dataAddress, m_dataPort))
+ if (m_dataSocket->bind(m_multicast ? QHostAddress::AnyIPv4 : m_dataAddress, m_dataPort, QUdpSocket::ShareAddress))
{
qDebug("RemoteInputUDPHandler::start: bind data socket to %s:%d", m_dataAddress.toString().toStdString().c_str(), m_dataPort);
+
+ if (m_multicast)
+ {
+ if (m_dataSocket->joinMulticastGroup(m_multicastAddress)) {
+ qDebug("RemoteInputUDPHandler::start: joined multicast group %s", qPrintable(m_multicastAddress.toString()));
+ } else {
+ qDebug("RemoteInputUDPHandler::start: failed joining multicast group %s", qPrintable(m_multicastAddress.toString()));
+ }
+ }
+
+ connect(m_dataSocket, SIGNAL(readyRead()), this, SLOT(dataReadyRead())); //, Qt::QueuedConnection);
m_dataConnected = true;
}
else
{
qWarning("RemoteInputUDPHandler::start: cannot bind data port %d", m_dataPort);
- disconnect(m_dataSocket, SIGNAL(readyRead()), this, SLOT(dataReadyRead()));
m_dataConnected = false;
}
}
@@ -143,17 +155,37 @@ void RemoteInputUDPHandler::stop()
m_running = false;
}
-void RemoteInputUDPHandler::configureUDPLink(const QString& address, quint16 port)
+void RemoteInputUDPHandler::configureUDPLink(const QString& address, quint16 port, const QString& multicastAddress, bool multicastJoin)
{
- qDebug("RemoteInputUDPHandler::configureUDPLink: %s:%d", address.toStdString().c_str(), port);
+ Message* msg = MsgUDPAddressAndPort::create(address, port, multicastAddress, multicastJoin);
+ m_inputMessageQueue.push(msg);
+}
+
+void RemoteInputUDPHandler::applyUDPLink(const QString& address, quint16 port, const QString& multicastAddress, bool multicastJoin)
+{
+ qDebug() << "RemoteInputUDPHandler::applyUDPLink: "
+ << " address: " << address
+ << " port: " << port
+ << " multicastAddress: " << multicastAddress
+ << " multicastJoin: " << multicastJoin;
+
bool addressOK = m_dataAddress.setAddress(address);
if (!addressOK)
{
- qWarning("RemoteInputUDPHandler::configureUDPLink: invalid address %s. Set to localhost.", address.toStdString().c_str());
+ qWarning("RemoteInputUDPHandler::applyUDPLink: invalid address %s. Set to localhost.", address.toStdString().c_str());
m_dataAddress = QHostAddress::LocalHost;
}
+ m_multicast = multicastJoin;
+ addressOK = m_multicastAddress.setAddress(multicastAddress);
+
+ if (!addressOK)
+ {
+ qWarning("RemoteInputUDPHandler::applyUDPLink: invalid multicast address %s. disabling multicast.", address.toStdString().c_str());
+ m_multicast = false;
+ }
+
m_dataPort = port;
stop();
start();
@@ -389,3 +421,29 @@ void RemoteInputUDPHandler::tick()
}
}
}
+
+void RemoteInputUDPHandler::handleMessages()
+{
+ Message* message;
+
+ while ((message = m_inputMessageQueue.pop()) != 0)
+ {
+ if (handleMessage(*message)) {
+ delete message;
+ }
+ }
+}
+
+bool RemoteInputUDPHandler::handleMessage(const Message& cmd)
+{
+ if (RemoteInputUDPHandler::MsgUDPAddressAndPort::match(cmd))
+ {
+ RemoteInputUDPHandler::MsgUDPAddressAndPort& notif = (RemoteInputUDPHandler::MsgUDPAddressAndPort&) cmd;
+ applyUDPLink(notif.getAddress(), notif.getPort(), notif.getMulticastAddress(), notif.getMulticastJoin());
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/plugins/samplesource/remoteinput/remoteinputudphandler.h b/plugins/samplesource/remoteinput/remoteinputudphandler.h
index 53425fc68..4e498dd21 100644
--- a/plugins/samplesource/remoteinput/remoteinputudphandler.h
+++ b/plugins/samplesource/remoteinput/remoteinputudphandler.h
@@ -24,6 +24,7 @@
#include
#include
+#include "util/messagequeue.h"
#include "remoteinputbuffer.h"
#define REMOTEINPUT_THROTTLE_MS 50
@@ -63,7 +64,7 @@ public:
void setMessageQueueToGUI(MessageQueue *queue) { m_messageQueueToGUI = queue; }
void start();
void stop();
- void configureUDPLink(const QString& address, quint16 port);
+ void configureUDPLink(const QString& address, quint16 port, const QString& multicastAddress, bool multicastJoin);
void getRemoteAddress(QString& s) const { s = m_remoteAddress.toString(); }
int getNbOriginalBlocks() const { return RemoteNbOrginalBlocks; }
bool isStreaming() const { return m_masterTimerConnected; }
@@ -77,6 +78,35 @@ public slots:
void dataReadyRead();
private:
+ class MsgUDPAddressAndPort : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ const QString& getAddress() const { return m_address; }
+ quint16 getPort() const { return m_port; }
+ const QString& getMulticastAddress() const { return m_multicastAddress; }
+ bool getMulticastJoin() const { return m_multicastJoin; }
+
+ static MsgUDPAddressAndPort* create(const QString& address, quint16 port, const QString& multicastAddress, bool multicastJoin)
+ {
+ return new MsgUDPAddressAndPort(address, port, multicastAddress, multicastJoin);
+ }
+
+ private:
+ QString m_address;
+ quint16 m_port;
+ QString m_multicastAddress;
+ bool m_multicastJoin;
+
+ MsgUDPAddressAndPort(const QString& address, quint16 port, const QString& multicastAddress, bool multicastJoin) :
+ Message(),
+ m_address(address),
+ m_port(port),
+ m_multicastAddress(multicastAddress),
+ m_multicastJoin(multicastJoin)
+ { }
+ };
+
DeviceAPI *m_deviceAPI;
const QTimer& m_masterTimer;
bool m_masterTimerConnected;
@@ -87,6 +117,8 @@ private:
QHostAddress m_dataAddress;
QHostAddress m_remoteAddress;
quint16 m_dataPort;
+ QHostAddress m_multicastAddress;
+ bool m_multicast;
bool m_dataConnected;
char *m_udpBuf;
qint64 m_udpReadBytes;
@@ -109,13 +141,18 @@ private:
bool m_throttleToggle;
bool m_autoCorrBuffer;
+ MessageQueue m_inputMessageQueue;
+
void connectTimer();
void disconnectTimer();
void processData();
void adjustNbDecoderSlots(const RemoteMetaDataFEC& metaData);
+ void applyUDPLink(const QString& address, quint16 port, const QString& multicastAddress, bool muticastJoin);
+ bool handleMessage(const Message& message);
private slots:
void tick();
+ void handleMessages();
};