Add local/remote port for UDP connections

This commit is contained in:
Alex Spataru 2021-10-21 17:52:21 -05:00
parent 6593dcc9f9
commit e97c05c2c9
5 changed files with 237 additions and 72 deletions

View File

@ -87,9 +87,11 @@ Item {
// //
// Network settings // Network settings
// //
property alias port: network.port
property alias address: network.address property alias address: network.address
property alias tcpPort: network.tcpPort
property alias socketType: network.socketType property alias socketType: network.socketType
property alias udpLocalPort: network.udpLocalPort
property alias udpRemotePort: network.udpRemotePort
property alias udpMulticastEnabled: network.udpMulticastEnabled property alias udpMulticastEnabled: network.udpMulticastEnabled
// //
@ -300,10 +302,10 @@ Item {
Layout.minimumHeight: implicitHeight Layout.minimumHeight: implicitHeight
Layout.maximumHeight: implicitHeight Layout.maximumHeight: implicitHeight
Layout.preferredHeight: implicitHeight Layout.preferredHeight: implicitHeight
onCurrentIndexChanged: getImplicitHeight() onCurrentIndexChanged: updateHeight()
Component.onCompleted: getImplicitHeight() Component.onCompleted: updateHeight()
function getImplicitHeight() { function updateHeight() {
stack.implicitHeight = 0 stack.implicitHeight = 0
switch (currentIndex) { switch (currentIndex) {
@ -335,6 +337,14 @@ Item {
SetupPanes.Network { SetupPanes.Network {
id: network id: network
onUiChanged: timer.start()
Timer {
id: timer
interval: 50
onTriggered: stack.updateHeight()
}
background: TextField { background: TextField {
enabled: false enabled: false
palette.base: Cpp_ThemeManager.setupPanelBackground palette.base: Cpp_ThemeManager.setupPanelBackground

View File

@ -31,10 +31,17 @@ Control {
// //
// Access to properties // Access to properties
// //
property alias port: _portText.text
property alias address: _address.text property alias address: _address.text
property alias tcpPort: _tcpPort.text
property alias udpLocalPort: _udpLocalPort.text
property alias udpRemotePort: _udpRemotePort.text
property alias socketType: _typeCombo.currentIndex property alias socketType: _typeCombo.currentIndex
property alias udpMulticastEnabled: _udpMulticast.checked property alias udpMulticastEnabled: _udpMulticast.checked
//
// Signals
//
signal uiChanged()
// //
// React to network manager events // React to network manager events
@ -42,14 +49,20 @@ Control {
Connections { Connections {
target: Cpp_IO_Network target: Cpp_IO_Network
function onHostChanged() { function onAddressChanged() {
if (_address.text.length > 0) if (_address.text.length > 0)
_address.text = Cpp_IO_Network.host _address.text = Cpp_IO_Network.remoteAddress
} }
function onPortChanged() { function onPortChanged() {
if (_portText.text.length > 0) if (_tcpPort.text.length > 0)
_portText.text = Cpp_IO_Network.port _tcpPort.text = Cpp_IO_Network.tcpPort
if (_udpLocalPort.text.length > 0)
_udpLocalPort.text = Cpp_IO_Network.udpLocalPort
if (_udpRemotePort.text.length > 0)
_udpRemotePort.text = Cpp_IO_Network.udpRemotePort
} }
} }
@ -83,6 +96,8 @@ Control {
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (currentIndex !== Cpp_IO_Network.socketTypeIndex) if (currentIndex !== Cpp_IO_Network.socketTypeIndex)
Cpp_IO_Network.socketTypeIndex = currentIndex Cpp_IO_Network.socketTypeIndex = currentIndex
root.uiChanged()
} }
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
@ -97,18 +112,18 @@ Control {
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
enabled: !Cpp_IO_Manager.connected enabled: !Cpp_IO_Manager.connected
Behavior on opacity {NumberAnimation{}} Behavior on opacity {NumberAnimation{}}
text: qsTr("Host") + ":" text: qsTr("Remote address") + ":"
} TextField { } TextField {
id: _address id: _address
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: Cpp_IO_Network.defaultHost placeholderText: Cpp_IO_Network.defaultAddress
Component.onCompleted: text = Cpp_IO_Network.host Component.onCompleted: text = Cpp_IO_Network.remoteAddress
onTextChanged: { onTextChanged: {
if (Cpp_IO_Network.host !== text && text.length > 0) if (Cpp_IO_Network.remoteAddress !== text && text.length > 0)
Cpp_IO_Network.host = text Cpp_IO_Network.remoteAddress = text
if (text.length === 0) if (text.length === 0)
Cpp_IO_Network.host = Cpp_IO_Network.defaultHost Cpp_IO_Network.remoteAddress = Cpp_IO_Network.defaultAddress
} }
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
@ -117,24 +132,25 @@ Control {
} }
// //
// Port // TCP port
// //
Label { Label {
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
text: qsTr("Port") + ":"
enabled: !Cpp_IO_Manager.connected enabled: !Cpp_IO_Manager.connected
Behavior on opacity {NumberAnimation{}} Behavior on opacity {NumberAnimation{}}
text: qsTr("Port") + ":" visible: Cpp_IO_Network.socketTypeIndex === 0
} TextField { } TextField {
id: _portText id: _tcpPort
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: Cpp_IO_Network.defaultPort placeholderText: Cpp_IO_Network.defaultTcpPort
Component.onCompleted: text = Cpp_IO_Network.port Component.onCompleted: text = Cpp_IO_Network.tcpPort
onTextChanged: { onTextChanged: {
if (Cpp_IO_Network.port !== text && text.length > 0) if (Cpp_IO_Network.tcpPort !== text && text.length > 0)
Cpp_IO_Network.port = text Cpp_IO_Network.tcpPort = text
if (text.length === 0) if (text.length === 0)
Cpp_IO_Network.port = Cpp_IO_Network.defaultPort Cpp_IO_Network.port = Cpp_IO_Network.defaultTcpPort
} }
validator: IntValidator { validator: IntValidator {
@ -144,6 +160,77 @@ Control {
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
enabled: !Cpp_IO_Manager.connected enabled: !Cpp_IO_Manager.connected
visible: Cpp_IO_Network.socketTypeIndex === 0
Behavior on opacity {NumberAnimation{}}
}
//
// TCP port
//
Label {
opacity: enabled ? 1 : 0.5
text: qsTr("Local port") + ":"
enabled: !Cpp_IO_Manager.connected
Behavior on opacity {NumberAnimation{}}
visible: Cpp_IO_Network.socketTypeIndex === 1 && !udpMulticastEnabled
} TextField {
id: _udpLocalPort
Layout.fillWidth: true
placeholderText: Cpp_IO_Network.defaultUdpLocalPort
Component.onCompleted: text = Cpp_IO_Network.udpLocalPort
onTextChanged: {
if (Cpp_IO_Network.udpLocalPort !== text && text.length > 0)
Cpp_IO_Network.udpLocalPort = text
if (text.length === 0)
Cpp_IO_Network.udpLocalPort = Cpp_IO_Network.defaultUdpLocalPort
}
validator: IntValidator {
bottom: 0
top: 65535
}
opacity: enabled ? 1 : 0.5
enabled: !Cpp_IO_Manager.connected
visible: Cpp_IO_Network.socketTypeIndex === 1 && !udpMulticastEnabled
Behavior on opacity {NumberAnimation{}}
}
//
// Output port
//
Label {
opacity: enabled ? 1 : 0.5
text: qsTr("Remote port") + ":"
enabled: !Cpp_IO_Manager.connected
Behavior on opacity {NumberAnimation{}}
visible: Cpp_IO_Network.socketTypeIndex === 1
} TextField {
id: _udpRemotePort
Layout.fillWidth: true
placeholderText: Cpp_IO_Network.defaultUdpRemotePort
Component.onCompleted: text = Cpp_IO_Network.udpRemotePort
onTextChanged: {
if (Cpp_IO_Network.udpRemotePort !== text && text.length > 0)
Cpp_IO_Network.udpRemotePort = text
if (text.length === 0)
Cpp_IO_Network.udpRemotePort = Cpp_IO_Network.defaultUdpRemotePort
}
validator: IntValidator {
bottom: 0
top: 65535
}
opacity: enabled ? 1 : 0.5
enabled: !Cpp_IO_Manager.connected
visible: Cpp_IO_Network.socketTypeIndex === 1
Behavior on opacity {NumberAnimation{}} Behavior on opacity {NumberAnimation{}}
} }
@ -154,16 +241,21 @@ Control {
text: qsTr("Multicast") + ":" text: qsTr("Multicast") + ":"
opacity: _udpMulticast.enabled ? 1 : 0.5 opacity: _udpMulticast.enabled ? 1 : 0.5
Behavior on opacity {NumberAnimation{}} Behavior on opacity {NumberAnimation{}}
visible: Cpp_IO_Network.socketTypeIndex === 1
} CheckBox { } CheckBox {
id: _udpMulticast id: _udpMulticast
opacity: enabled ? 1 : 0.5 opacity: enabled ? 1 : 0.5
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.leftMargin: -app.spacing Layout.leftMargin: -app.spacing
checked: Cpp_IO_Network.udpMulticast checked: Cpp_IO_Network.udpMulticast
visible: Cpp_IO_Network.socketTypeIndex === 1
enabled: Cpp_IO_Network.socketTypeIndex === 1 && !Cpp_IO_Manager.connected enabled: Cpp_IO_Network.socketTypeIndex === 1 && !Cpp_IO_Manager.connected
onCheckedChanged: { onCheckedChanged: {
if (Cpp_IO_Network.udpMulticast !== checked) if (Cpp_IO_Network.udpMulticast !== checked)
Cpp_IO_Network.udpMulticast = checked Cpp_IO_Network.udpMulticast = checked
root.uiChanged()
} }
Behavior on opacity {NumberAnimation{}} Behavior on opacity {NumberAnimation{}}

View File

@ -36,8 +36,10 @@ Network::Network()
, m_udpMulticast(false) , m_udpMulticast(false)
, m_lookupActive(false) , m_lookupActive(false)
{ {
setHost(""); setRemoteAddress("");
setPort(defaultPort()); setTcpPort(defaultTcpPort());
setUdpLocalPort(defaultUdpLocalPort());
setUdpRemotePort(defaultUdpRemotePort());
setSocketType(QAbstractSocket::TcpSocket); setSocketType(QAbstractSocket::TcpSocket);
connect(&m_tcpSocket, &QTcpSocket::errorOccurred, this, &Network::onErrorOccurred); connect(&m_tcpSocket, &QTcpSocket::errorOccurred, this, &Network::onErrorOccurred);
connect(&m_udpSocket, &QUdpSocket::errorOccurred, this, &Network::onErrorOccurred); connect(&m_udpSocket, &QUdpSocket::errorOccurred, this, &Network::onErrorOccurred);
@ -65,17 +67,33 @@ Network *Network::getInstance()
/** /**
* Returns the host address * Returns the host address
*/ */
QString Network::host() const QString Network::remoteAddress() const
{ {
return m_host; return m_address;
} }
/** /**
* Returns the network port number * Returns the TCP port number
*/ */
quint16 Network::port() const quint16 Network::tcpPort() const
{ {
return m_port; return m_tcpPort;
}
/**
* Returns the UDP local port number
*/
quint16 Network::udpLocalPort() const
{
return m_udpLocalPort;
}
/**
* Returns the UDP remote port number
*/
quint16 Network::udpRemotePort() const
{
return m_udpRemotePort;
} }
/** /**
@ -120,7 +138,7 @@ int Network::socketTypeIndex() const
*/ */
bool Network::configurationOk() const bool Network::configurationOk() const
{ {
return port() > 0 && m_hostExists; return tcpPort() > 0 && m_hostExists;
} }
/** /**
@ -156,18 +174,15 @@ QIODevice *Network::openNetworkPort()
QAbstractSocket *socket = nullptr; QAbstractSocket *socket = nullptr;
// Get host & port // Get host & port
auto hostAddr = host(); auto hostAddr = remoteAddress();
auto portAddr = port();
if (hostAddr.isEmpty()) if (hostAddr.isEmpty())
hostAddr = defaultHost(); hostAddr = defaultAddress();
if (portAddr <= 0)
portAddr = defaultPort();
// TCP connection, assign socket pointer & connect to host // TCP connection, assign socket pointer & connect to host
if (socketType() == QAbstractSocket::TcpSocket) if (socketType() == QAbstractSocket::TcpSocket)
{ {
socket = &m_tcpSocket; socket = &m_tcpSocket;
m_tcpSocket.connectToHost(hostAddr, portAddr); m_tcpSocket.connectToHost(hostAddr, tcpPort());
} }
// UDP connection, assign socket pointer & bind to host // UDP connection, assign socket pointer & bind to host
@ -178,20 +193,24 @@ QIODevice *Network::openNetworkPort()
{ {
QHostAddress address(hostAddr); QHostAddress address(hostAddr);
if (address.protocol() == QAbstractSocket::IPv4Protocol) if (address.protocol() == QAbstractSocket::IPv4Protocol)
m_udpSocket.bind(QHostAddress::AnyIPv4, portAddr, m_udpSocket.bind(QHostAddress::AnyIPv4, udpRemotePort(),
QUdpSocket::ShareAddress); QUdpSocket::ShareAddress);
else if (address.protocol() == QAbstractSocket::IPv6Protocol) else if (address.protocol() == QAbstractSocket::IPv6Protocol)
m_udpSocket.bind(QHostAddress::AnyIPv6, portAddr, m_udpSocket.bind(QHostAddress::AnyIPv6, udpRemotePort(),
QUdpSocket::ShareAddress); QUdpSocket::ShareAddress);
else else
m_udpSocket.bind(QHostAddress::Any, portAddr, QUdpSocket::ShareAddress); m_udpSocket.bind(QHostAddress::Any, udpRemotePort(),
QUdpSocket::ShareAddress);
m_udpSocket.joinMulticastGroup(address); m_udpSocket.joinMulticastGroup(address);
} }
// Bind the UDP socket to an individual host // Bind the UDP socket to an individual host
else else
m_udpSocket.connectToHost(hostAddr, portAddr); {
m_udpSocket.bind(QHostAddress::LocalHost, udpLocalPort());
m_udpSocket.connectToHost(hostAddr, udpRemotePort());
}
// Update socket pointer // Update socket pointer
socket = &m_udpSocket; socket = &m_udpSocket;
@ -227,24 +246,42 @@ void Network::disconnectDevice()
} }
/** /**
* Sets the @c port number * Changes the TCP socket's @c port number
*/ */
void Network::setPort(const quint16 port) void Network::setTcpPort(const quint16 port)
{ {
m_port = port; m_tcpPort = port;
emit portChanged();
}
/**
* Changes the UDP socket's local @c port number
*/
void Network::setUdpLocalPort(const quint16 port)
{
m_udpLocalPort = port;
emit portChanged();
}
/**
* Changes the UDP socket's remote @c port number
*/
void Network::setUdpRemotePort(const quint16 port)
{
m_udpRemotePort = port;
emit portChanged(); emit portChanged();
} }
/** /**
* Sets the IPv4 or IPv6 address specified by the input string representation * Sets the IPv4 or IPv6 address specified by the input string representation
*/ */
void Network::setHost(const QString &host) void Network::setRemoteAddress(const QString &address)
{ {
// Check if host name exists // Check if host name exists
if (QHostAddress(host).isNull()) if (QHostAddress(address).isNull())
{ {
m_hostExists = false; m_hostExists = false;
lookup(host); lookup(address);
} }
// Host is an IP address, host should exist // Host is an IP address, host should exist
@ -252,8 +289,8 @@ void Network::setHost(const QString &host)
m_hostExists = true; m_hostExists = true;
// Change host // Change host
m_host = host; m_address = address;
emit hostChanged(); emit addressChanged();
} }
/** /**
@ -323,7 +360,7 @@ void Network::lookupFinished(const QHostInfo &info)
if (addresses.count() >= 1) if (addresses.count() >= 1)
{ {
m_hostExists = true; m_hostExists = true;
emit hostChanged(); emit addressChanged();
return; return;
} }
} }

View File

@ -43,13 +43,21 @@ class Network : public QObject
{ {
// clang-format off // clang-format off
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString host Q_PROPERTY(QString remoteAddress
READ host READ remoteAddress
WRITE setHost WRITE setRemoteAddress
NOTIFY hostChanged) NOTIFY addressChanged)
Q_PROPERTY(quint16 port Q_PROPERTY(quint16 tcpPort
READ port READ tcpPort
WRITE setPort WRITE setTcpPort
NOTIFY portChanged)
Q_PROPERTY(quint16 udpLocalPort
READ udpLocalPort
WRITE setUdpLocalPort
NOTIFY portChanged)
Q_PROPERTY(quint16 udpRemotePort
READ udpRemotePort
WRITE setUdpRemotePort
NOTIFY portChanged) NOTIFY portChanged)
Q_PROPERTY(QAbstractSocket::SocketType socketType Q_PROPERTY(QAbstractSocket::SocketType socketType
READ socketType READ socketType
@ -62,11 +70,17 @@ class Network : public QObject
Q_PROPERTY(QVector<QString> socketTypes Q_PROPERTY(QVector<QString> socketTypes
READ socketTypes READ socketTypes
CONSTANT) CONSTANT)
Q_PROPERTY(QString defaultHost Q_PROPERTY(QString defaultAddress
READ defaultHost READ defaultAddress
CONSTANT) CONSTANT)
Q_PROPERTY(quint16 defaultPort Q_PROPERTY(quint16 defaultTcpPort
READ defaultPort READ defaultTcpPort
CONSTANT)
Q_PROPERTY(quint16 defaultUdpLocalPort
READ defaultUdpLocalPort
CONSTANT)
Q_PROPERTY(quint16 defaultUdpRemotePort
READ defaultUdpRemotePort
CONSTANT) CONSTANT)
Q_PROPERTY(bool lookupActive Q_PROPERTY(bool lookupActive
READ lookupActive READ lookupActive
@ -78,8 +92,8 @@ class Network : public QObject
// clang-format on // clang-format on
signals: signals:
void hostChanged();
void portChanged(); void portChanged();
void addressChanged();
void socketTypeChanged(); void socketTypeChanged();
void udpMulticastChanged(); void udpMulticastChanged();
void lookupActiveChanged(); void lookupActiveChanged();
@ -87,8 +101,12 @@ signals:
public: public:
static Network *getInstance(); static Network *getInstance();
QString host() const; QString remoteAddress() const;
quint16 port() const;
quint16 tcpPort() const;
quint16 udpLocalPort() const;
quint16 udpRemotePort() const;
bool udpMulticast() const; bool udpMulticast() const;
bool lookupActive() const; bool lookupActive() const;
int socketTypeIndex() const; int socketTypeIndex() const;
@ -98,8 +116,11 @@ public:
QTcpSocket *tcpSocket() { return &m_tcpSocket; } QTcpSocket *tcpSocket() { return &m_tcpSocket; }
QUdpSocket *udpSocket() { return &m_udpSocket; } QUdpSocket *udpSocket() { return &m_udpSocket; }
static QString defaultHost() { return "127.0.0.1"; }
static quint16 defaultPort() { return 23; } static QString defaultAddress() { return "127.0.0.1"; }
static quint16 defaultTcpPort() { return 23; }
static quint16 defaultUdpRemotePort() { return 53; }
static quint16 defaultUdpLocalPort() { return 8888; }
QIODevice *openNetworkPort(); QIODevice *openNetworkPort();
@ -107,11 +128,13 @@ public slots:
void setTcpSocket(); void setTcpSocket();
void setUdpSocket(); void setUdpSocket();
void disconnectDevice(); void disconnectDevice();
void setPort(const quint16 port);
void setHost(const QString &host);
void lookup(const QString &host); void lookup(const QString &host);
void setTcpPort(const quint16 port);
void setUdpLocalPort(const quint16 port);
void setUdpMulticast(const bool enabled); void setUdpMulticast(const bool enabled);
void setSocketTypeIndex(const int index); void setSocketTypeIndex(const int index);
void setUdpRemotePort(const quint16 port);
void setRemoteAddress(const QString &address);
void setSocketType(const QAbstractSocket::SocketType type); void setSocketType(const QAbstractSocket::SocketType type);
private slots: private slots:
@ -123,15 +146,18 @@ private:
~Network(); ~Network();
private: private:
QString m_host; QString m_address;
quint16 m_port; quint16 m_tcpPort;
bool m_hostExists; bool m_hostExists;
bool m_udpMulticast; bool m_udpMulticast;
bool m_lookupActive; bool m_lookupActive;
QIODevice *m_device; QIODevice *m_device;
quint16 m_udpLocalPort;
quint16 m_udpRemotePort;
QAbstractSocket::SocketType m_socketType;
QTcpSocket m_tcpSocket; QTcpSocket m_tcpSocket;
QUdpSocket m_udpSocket; QUdpSocket m_udpSocket;
QAbstractSocket::SocketType m_socketType;
}; };
} }
} }

View File

@ -79,8 +79,8 @@ Manager::Manager()
// Configure signals/slots // Configure signals/slots
auto serial = DataSources::Serial::getInstance(); auto serial = DataSources::Serial::getInstance();
auto netwrk = DataSources::Network::getInstance(); auto netwrk = DataSources::Network::getInstance();
connect(netwrk, SIGNAL(hostChanged()), this, SIGNAL(configurationChanged()));
connect(netwrk, SIGNAL(portChanged()), this, SIGNAL(configurationChanged())); connect(netwrk, SIGNAL(portChanged()), this, SIGNAL(configurationChanged()));
connect(netwrk, SIGNAL(addressChanged()), this, SIGNAL(configurationChanged()));
connect(this, SIGNAL(dataSourceChanged()), this, SIGNAL(configurationChanged())); connect(this, SIGNAL(dataSourceChanged()), this, SIGNAL(configurationChanged()));
connect(serial, SIGNAL(portIndexChanged()), this, SIGNAL(configurationChanged())); connect(serial, SIGNAL(portIndexChanged()), this, SIGNAL(configurationChanged()));
} }