summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/knx/device/mainwindow.cpp12
-rw-r--r--examples/knx/discoverer/main.cpp37
-rw-r--r--examples/knx/feature/mainwindow.cpp12
-rw-r--r--examples/knx/group/mainwindow.cpp12
-rw-r--r--examples/knx/router/main.cpp13
-rw-r--r--src/knx/core/qknxbytearray.cpp3
-rw-r--r--src/knx/core/qknxbytearray.h6
-rw-r--r--src/knx/netip/netip.pri1
-rw-r--r--src/knx/netip/qknxnetipconnectionheader.cpp2
-rw-r--r--src/knx/netip/qknxnetiproutingindication.cpp2
-rw-r--r--src/knx/netip/qknxnetipserverdiscoveryagent.cpp389
-rw-r--r--src/knx/netip/qknxnetipserverdiscoveryagent.h18
-rw-r--r--src/knx/netip/qknxnetipserverdiscoveryagent_p.cpp684
-rw-r--r--src/knx/netip/qknxnetipserverdiscoveryagent_p.h97
-rw-r--r--src/knx/netip/qknxnetipserverinfo.cpp49
-rw-r--r--src/knx/netip/qknxnetipserverinfo.h20
-rw-r--r--src/knx/netip/qknxnetipserverinfo_p.h6
-rw-r--r--src/knx/qknxdevicemanagementframe.cpp13
-rw-r--r--src/knx/ssl/qknxsecurekey.cpp4
-rw-r--r--src/knx/ssl/qsslsocket_openssl11_symbols_p.h2
-rw-r--r--src/knx/ssl/qsslsocket_openssl_symbols.cpp371
-rw-r--r--tests/auto/qknxnetipcri/tst_qknxnetipcri.cpp2
-rw-r--r--tests/auto/qknxnetiprouter/tst_qknxnetiprouter.cpp2
-rw-r--r--tests/auto/qknxtunnelframefactory/tst_qknxtunnelframefactory.cpp2
25 files changed, 1169 insertions, 592 deletions
diff --git a/.qmake.conf b/.qmake.conf
index b5e35ea..c6f1702 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -3,4 +3,4 @@ load(qt_build_config)
CONFIG += warning_clean
DEFINES += QT_NO_FOREACH
-MODULE_VERSION = 5.13.1
+MODULE_VERSION = 5.14.0
diff --git a/examples/knx/device/mainwindow.cpp b/examples/knx/device/mainwindow.cpp
index 54d3b6a..f1516a2 100644
--- a/examples/knx/device/mainwindow.cpp
+++ b/examples/knx/device/mainwindow.cpp
@@ -170,13 +170,16 @@ void MainWindow::on_actionImport_triggered()
on_devices_currentIndexChanged(ui->devices->currentIndex());
}
-void MainWindow::on_devices_currentIndexChanged(int /* index */)
+void MainWindow::on_devices_currentIndexChanged(int index)
{
delete m_device;
+ m_device = nullptr;
ui->secureConfigs->clear();
- const auto model = qobject_cast<QStandardItemModel*>(ui->devices->model());
- m_device = static_cast<DeviceItem *> (model->item(ui->devices->currentIndex()))->clone();
+ if (index >= 0) {
+ const auto model = qobject_cast<QStandardItemModel*>(ui->devices->model());
+ m_device = static_cast<DeviceItem *> (model->item(ui->devices->currentIndex()))->clone();
+ }
if (m_device) {
const auto deviceInfo = m_device->info();
@@ -190,6 +193,8 @@ void MainWindow::on_devices_currentIndexChanged(int /* index */)
.arg(config.userId())
.arg(ia.isValid() ? ia.toString() : tr("No specific address")), i);
}
+ } else {
+ m_device = new DeviceItem({});
}
ui->secureConfigs->setEnabled(bool(ui->secureConfigs->count())
@@ -311,6 +316,7 @@ void MainWindow::setupInterfaces()
if (i < 0)
return;
m_discoveryAgent.stop();
+ ui->devices->clear();
m_discoveryAgent.setLocalAddress(QHostAddress(ui->interfaces->currentData()
.toStringList().first()));
m_discoveryAgent.start();
diff --git a/examples/knx/discoverer/main.cpp b/examples/knx/discoverer/main.cpp
index 3cf564b..d9944cb 100644
--- a/examples/knx/discoverer/main.cpp
+++ b/examples/knx/discoverer/main.cpp
@@ -56,8 +56,6 @@
#include <QtKnx/QKnxNetIpServerDiscoveryAgent>
#include <QtKnx/QKnxNetIpSrpBuilder>
-#include <QtNetwork/QNetworkInterface>
-
static QString familyToString(QKnxNetIp::ServiceFamily id)
{
switch (id) {
@@ -83,17 +81,6 @@ static QString familyToString(QKnxNetIp::ServiceFamily id)
return "Unknown";
}
-QString interfaceFromAddress(const QHostAddress &address)
-{
- auto interfaces = QNetworkInterface::allInterfaces();
- for (const auto &interface : qAsConst(interfaces)) {
- if (interface.allAddresses().contains(address))
- return interface.humanReadableName();
- }
- return QString(address == QHostAddress(QKnxNetIp::Constants::MulticastAddress)
- ? "Multicast" : "Unknown");
-}
-
int main(int argc, char *argv[])
{
QCoreApplication discoverer(argc, argv);
@@ -130,10 +117,8 @@ int main(int argc, char *argv[])
agent.setLocalPort(parser.value("localPort").toUInt());
agent.setTimeout(parser.value("timeout").toInt() * 1000);
- if (parser.isSet("localAddress")) {
+ if (parser.isSet("localAddress"))
agent.setLocalAddress(QHostAddress(parser.value("localAddress")));
- agent.setResponseType(QKnxNetIpServerDiscoveryAgent::ResponseType::Unicast);
- }
if (parser.isSet("unicast"))
agent.setResponseType(QKnxNetIpServerDiscoveryAgent::ResponseType::Unicast);
@@ -189,21 +174,25 @@ int main(int argc, char *argv[])
QObject::connect(&agent, &QKnxNetIpServerDiscoveryAgent::finished, &discoverer,
&QCoreApplication::quit);
- agent.start();
-
- if (agent.error() == QKnxNetIpServerDiscoveryAgent::Error::None)
- discoverer.exec();
+ if (!parser.isSet("localAddress")) {
+ agent.start(QKnxNetIpServerDiscoveryAgent::InterfaceType::Ethernet
+ | QKnxNetIpServerDiscoveryAgent::InterfaceType::Wifi);
+ } else {
+ agent.start(QVector<QHostAddress> { agent.localAddress() });
+ }
- qInfo().noquote() << endl << "Device used to send the search request:";
- qInfo().noquote() << QString::fromLatin1(" Network interface: %1, address: %2, port: %3")
- .arg(interfaceFromAddress(agent.localAddress()), agent.localAddress().toString())
- .arg(agent.localPort());
+ if (agent.error() == QKnxNetIpServerDiscoveryAgent::Error::None
+ && agent.state() == QKnxNetIpServerDiscoveryAgent::State::Running) {
+ discoverer.exec();
+ }
const auto servers = agent.discoveredServers();
if (servers.size() > 0) {
qInfo().noquote() << endl << QString::fromLatin1("%1 server(s) found on the network.")
.arg(servers.size());
for (auto server : servers) {
+ qInfo().noquote() << QString::fromLatin1(" Network interface: %1, address: %2")
+ .arg(server.networkInterface().humanReadableName(), server.hostAddress().toString());
qInfo().noquote() << QString::fromLatin1(" Server: %1").arg(server.deviceName());
qInfo().noquote() << QString::fromLatin1(" Individual address: %1").arg(server
.individualAddress().toString());
diff --git a/examples/knx/feature/mainwindow.cpp b/examples/knx/feature/mainwindow.cpp
index 7e44327..8f32b06 100644
--- a/examples/knx/feature/mainwindow.cpp
+++ b/examples/knx/feature/mainwindow.cpp
@@ -170,13 +170,16 @@ void MainWindow::on_actionImport_triggered()
on_devices_currentIndexChanged(ui->devices->currentIndex());
}
-void MainWindow::on_devices_currentIndexChanged(int /* index */)
+void MainWindow::on_devices_currentIndexChanged(int index)
{
delete m_device;
+ m_device = nullptr;
ui->secureConfigs->clear();
- const auto model = qobject_cast<QStandardItemModel*>(ui->devices->model());
- m_device = static_cast<DeviceItem *> (model->item(ui->devices->currentIndex()))->clone();
+ if (index >= 0) {
+ const auto model = qobject_cast<QStandardItemModel*>(ui->devices->model());
+ m_device = static_cast<DeviceItem *> (model->item(ui->devices->currentIndex()))->clone();
+ }
if (m_device) {
const auto deviceInfo = m_device->info();
@@ -190,6 +193,8 @@ void MainWindow::on_devices_currentIndexChanged(int /* index */)
.arg(config.userId())
.arg(ia.isValid() ? ia.toString() : tr("No specific address")), i);
}
+ } else {
+ m_device = new DeviceItem({});
}
ui->secureConfigs->setEnabled(bool(ui->secureConfigs->count())
@@ -280,6 +285,7 @@ void MainWindow::setupInterfaces()
if (i < 0)
return;
m_discoveryAgent.stop();
+ ui->devices->clear();
m_discoveryAgent.setLocalAddress(QHostAddress(ui->interfaces->currentData()
.toStringList().first()));
m_discoveryAgent.start();
diff --git a/examples/knx/group/mainwindow.cpp b/examples/knx/group/mainwindow.cpp
index 4100e03..2e297af 100644
--- a/examples/knx/group/mainwindow.cpp
+++ b/examples/knx/group/mainwindow.cpp
@@ -169,13 +169,16 @@ void MainWindow::on_actionImport_triggered()
on_devices_currentIndexChanged(ui->devices->currentIndex());
}
-void MainWindow::on_devices_currentIndexChanged(int /* index */)
+void MainWindow::on_devices_currentIndexChanged(int index)
{
delete m_device;
+ m_device = nullptr;
ui->secureConfigs->clear();
- const auto model = qobject_cast<QStandardItemModel*>(ui->devices->model());
- m_device = static_cast<DeviceItem *> (model->item(ui->devices->currentIndex()))->clone();
+ if (index >= 0) {
+ const auto model = qobject_cast<QStandardItemModel*>(ui->devices->model());
+ m_device = static_cast<DeviceItem *> (model->item(ui->devices->currentIndex()))->clone();
+ }
if (m_device) {
const auto deviceInfo = m_device->info();
@@ -189,6 +192,8 @@ void MainWindow::on_devices_currentIndexChanged(int /* index */)
.arg(config.userId())
.arg(ia.isValid() ? ia.toString() : tr("No specific address")), i);
}
+ } else {
+ m_device = new DeviceItem({});
}
ui->secureConfigs->setEnabled(bool(ui->secureConfigs->count())
@@ -288,6 +293,7 @@ void MainWindow::setupInterfaces()
if (i < 0)
return;
m_discoveryAgent.stop();
+ ui->devices->clear();
m_discoveryAgent.setLocalAddress(QHostAddress(ui->interfaces->currentData()
.toStringList().first()));
m_discoveryAgent.start();
diff --git a/examples/knx/router/main.cpp b/examples/knx/router/main.cpp
index f9ccc9a..5218661 100644
--- a/examples/knx/router/main.cpp
+++ b/examples/knx/router/main.cpp
@@ -238,14 +238,13 @@ int main(int argc, char *argv[])
QNetworkInterface iface { QNetworkInterface::interfaceFromName(cliParser.value("interface")) };
if (!iface.isValid()) {
auto interfaces = iface.allInterfaces();
- QList<QNetworkInterface>::iterator found = ( std::find_if(interfaces.begin(),
- interfaces.end(),
- [](const QNetworkInterface &i){
- return i.type() == QNetworkInterface::Ethernet;
- }));
+ QList<QNetworkInterface>::iterator found = std::find_if(
+ interfaces.begin(), interfaces.end(), [](const QNetworkInterface &i) {
+ return i.type() == QNetworkInterface::Ethernet;
+ }
+ );
if (found == iface.allInterfaces().end()) {
- qInfo().noquote() << "No valid network interface given and no "
- "Ethernet adapter found. ";
+ qInfo().noquote() << "No valid network interface given and no Ethernet adapter found.";
cliParser.showHelp();
}
iface = static_cast<QNetworkInterface>(*found);
diff --git a/src/knx/core/qknxbytearray.cpp b/src/knx/core/qknxbytearray.cpp
index a93e3fa..bfec17d 100644
--- a/src/knx/core/qknxbytearray.cpp
+++ b/src/knx/core/qknxbytearray.cpp
@@ -243,6 +243,9 @@ void QKnxByteArray::clear()
*/
void QKnxByteArray::resize(int size)
{
+ if (size == m_bytes.size())
+ return;
+
if (size > m_bytes.size())
m_bytes.append(size - m_bytes.size(), 0x00);
else
diff --git a/src/knx/core/qknxbytearray.h b/src/knx/core/qknxbytearray.h
index f6feba5..b48b9c5 100644
--- a/src/knx/core/qknxbytearray.h
+++ b/src/knx/core/qknxbytearray.h
@@ -92,7 +92,11 @@ public:
void resize(int size);
inline quint8 at(int i) const { return m_bytes.at(i); }
- inline void set(int i, quint8 val) { m_bytes[i] = val; }
+
+ inline void set(int i, quint8 val) {
+ Q_ASSERT(i >= 0 && i < size());
+ m_bytes[i] = val;
+ }
inline void setValue(int i, quint8 val)
{
diff --git a/src/knx/netip/netip.pri b/src/knx/netip/netip.pri
index 88e2d58..4a154ab 100644
--- a/src/knx/netip/netip.pri
+++ b/src/knx/netip/netip.pri
@@ -96,6 +96,7 @@ SOURCES += $$PWD/qknxnetip.cpp \
$$PWD/qknxnetipsearchresponse.cpp \
$$PWD/qknxnetipserverdescriptionagent.cpp \
$$PWD/qknxnetipserverdiscoveryagent.cpp \
+ $$PWD/qknxnetipserverdiscoveryagent_p.cpp \
$$PWD/qknxnetipserverinfo.cpp \
$$PWD/qknxnetipservicefamiliesdib.cpp \
$$PWD/qknxnetipstruct.cpp \
diff --git a/src/knx/netip/qknxnetipconnectionheader.cpp b/src/knx/netip/qknxnetipconnectionheader.cpp
index 4bf2859..e571e43 100644
--- a/src/knx/netip/qknxnetipconnectionheader.cpp
+++ b/src/knx/netip/qknxnetipconnectionheader.cpp
@@ -237,7 +237,7 @@ QKnxNetIpConnectionHeader QKnxNetIpConnectionHeader::fromBytes(const QKnxByteArr
if (availableSize < 4 && availableSize < totalSize)
return {}; // header might be corrupted
- QKnxNetIpConnectionHeader hdr{ bytes.at(index + 1), bytes.at(index + 2), bytes.at(index + 3) };
+ QKnxNetIpConnectionHeader hdr { bytes.at(index + 1), bytes.at(index + 2), bytes.at(index + 3) };
if (totalSize > 4)
hdr.setConnectionTypeSpecificHeaderItems(bytes.mid(index + 4, totalSize - 4));
return hdr;
diff --git a/src/knx/netip/qknxnetiproutingindication.cpp b/src/knx/netip/qknxnetiproutingindication.cpp
index d84e732..43a1758 100644
--- a/src/knx/netip/qknxnetiproutingindication.cpp
+++ b/src/knx/netip/qknxnetiproutingindication.cpp
@@ -156,7 +156,7 @@ QKnxNetIpRoutingIndicationProxy::Builder QKnxNetIpRoutingIndicationProxy::builde
\code
QKnxLinkLayerFrame linkFrame = // create a link frame ....;
auto netIpframe = QKnxNetIpRoutingIndicationProxy::builder()
- .setLinkLayerFrame(linkFrame)
+ .setCemi(linkFrame)
.create();
\endcode
diff --git a/src/knx/netip/qknxnetipserverdiscoveryagent.cpp b/src/knx/netip/qknxnetipserverdiscoveryagent.cpp
index 30c3d1d..d00fd74 100644
--- a/src/knx/netip/qknxnetipserverdiscoveryagent.cpp
+++ b/src/knx/netip/qknxnetipserverdiscoveryagent.cpp
@@ -119,6 +119,8 @@ QT_BEGIN_NAMESPACE
A network error occurred.
\value NotIPv4
The network protocol used is not IPv4.
+ \value Timeout
+ A timeout occurred while waiting for the description response.
\value Unknown
An unknown error occurred.
*/
@@ -181,288 +183,12 @@ QT_BEGIN_NAMESPACE
\a state.
*/
-QKnxNetIpServerDiscoveryAgentPrivate::QKnxNetIpServerDiscoveryAgentPrivate(const QHostAddress &addr,
- quint16 prt)
- : port(prt)
- , address(addr)
-{}
-
-namespace QKnxPrivate
-{
- static void clearSocket(QUdpSocket **socket)
- {
- if (*socket) {
- (*socket)->disconnect();
- (*socket)->deleteLater();
- (*socket) = nullptr;
- }
- }
-}
-
-void QKnxNetIpServerDiscoveryAgentPrivate::setupSocket()
-{
- usedPort = port;
- usedAddress = address;
- QKnxPrivate::clearSocket(&socket);
-
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- socket = new QUdpSocket(q);
- socket->setSocketOption(QUdpSocket::SocketOption::MulticastTtlOption, ttl);
-
- QObject::connect(socket, &QUdpSocket::stateChanged, [&](QUdpSocket::SocketState s) {
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- switch (s) {
- case QUdpSocket::BoundState:
- setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Running);
-
- if (type == QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast) {
- QNetworkInterface mni;
- const auto interfaces = QNetworkInterface::allInterfaces();
- for (const auto &iface : interfaces) {
- if (!iface.flags().testFlag(QNetworkInterface::CanMulticast))
- continue;
-
- const auto entries = iface.addressEntries();
- for (const auto &entry : entries) {
- auto ip = entry.ip();
- if (ip.protocol() != QAbstractSocket::NetworkLayerProtocol::IPv4Protocol)
- continue;
- if (ip != address)
- continue;
- mni = iface;
- break;
- }
- }
-
- if (socket->joinMulticastGroup(multicastAddress, mni)) {
- usedPort = multicastPort;
- usedAddress = multicastAddress;
- } else {
- setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error::Network,
- QKnxNetIpServerDiscoveryAgent::tr("Could not join multicast group."));
- q->stop();
- }
- } else {
- usedPort = socket->localPort();
- usedAddress = socket->localAddress();
- }
-
- if (q->state() == QKnxNetIpServerDiscoveryAgent::State::Running) {
- servers.clear();
-
- const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> flags(discoveryMode);
- if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1)) {
- auto frame = QKnxNetIpSearchRequestProxy::builder()
- .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
- .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
- .setPort(nat ? quint16(0u) : usedPort).create()
- ).create();
- socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
- multicastPort);
- }
-
- if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2)) {
- auto frame = QKnxNetIpSearchRequestProxy::extendedBuilder()
- .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
- .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
- .setPort(nat ? quint16(0u) : usedPort).create()
- )
- .setExtendedParameters(srps).create();
- socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
- multicastPort);
- }
-
- setupAndStartReceiveTimer();
- setupAndStartFrequencyTimer();
- }
- break;
- default:
- break;
- }
- });
-
- using overload = void (QUdpSocket::*)(QUdpSocket::SocketError);
- QObject::connect(socket,
- static_cast<overload>(&QUdpSocket::error), [&](QUdpSocket::SocketError) {
- setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error::Network,
- socket->errorString());
-
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- q->stop();
- });
-
- QObject::connect(socket, &QUdpSocket::readyRead, [&]() {
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- while (socket->hasPendingDatagrams()) {
- if (q->state() != QKnxNetIpServerDiscoveryAgent::State::Running)
- break;
-
- auto datagram = socket->receiveDatagram();
- auto data = QKnxByteArray::fromByteArray(datagram.data());
- const auto header = QKnxNetIpFrameHeader::fromBytes(data, 0);
- if (!header.isValid())
- continue;
-
- if (header.serviceType() != QKnxNetIp::ServiceType::SearchResponse &&
- header.serviceType() != QKnxNetIp::ServiceType::ExtendedSearchResponse) {
- continue;
- }
-
- auto frame = QKnxNetIpFrame::fromBytes(data);
- auto response = QKnxNetIpSearchResponseProxy(frame);
- if (!response.isValid())
- continue;
-
- const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> flags(discoveryMode);
- if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1)
- && !response.isExtended()) {
- setAndEmitDeviceDiscovered({
- (nat ? QKnxNetIpHpaiProxy::builder()
- .setHostAddress(datagram.senderAddress())
- .setPort(datagram.senderPort()).create()
- : response.controlEndpoint()
- ), response.deviceHardware(), response.supportedFamilies()
- });
- }
-
- if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2)
- && response.isExtended()) {
- const auto optionalDibs = response.optionalDibs();
- setAndEmitDeviceDiscovered({
- (nat ? QKnxNetIpHpaiProxy::builder()
- .setHostAddress(datagram.senderAddress())
- .setPort(datagram.senderPort()).create()
- : response.controlEndpoint()
- ), response.deviceHardware(), response.supportedFamilies(),
- [&optionalDibs]() -> QKnxNetIpDib {
- for (const auto &dib : qAsConst(optionalDibs)) {
- if (dib.code() == QKnxNetIp::DescriptionType::TunnelingInfo)
- return dib;
- }
- return {};
- }(),
- [&optionalDibs]() -> QKnxNetIpDib {
- for (const auto &dib : qAsConst(optionalDibs)) {
- if (dib.code() == QKnxNetIp::DescriptionType::ExtendedDeviceInfo)
- return dib;
- }
- return {};
- }()
- });
- }
- }
- });
-}
-
-namespace QKnxPrivate
-{
- static void clearTimer(QTimer **timer)
- {
- if (*timer) {
- (*timer)->stop();
- (*timer)->disconnect();
- (*timer)->deleteLater();
- (*timer) = nullptr;
- }
- }
-}
-
-void QKnxNetIpServerDiscoveryAgentPrivate::setupAndStartReceiveTimer()
-{
- Q_Q(QKnxNetIpServerDiscoveryAgent);
-
- QKnxPrivate::clearTimer(&receiveTimer);
- if (timeout >= 0) {
- receiveTimer = new QTimer(q);
- receiveTimer->setSingleShot(true);
- receiveTimer->start(timeout);
- QObject::connect(receiveTimer, &QTimer::timeout, q, &QKnxNetIpServerDiscoveryAgent::stop);
- }
-}
-
-void QKnxNetIpServerDiscoveryAgentPrivate::setupAndStartFrequencyTimer()
-{
- Q_Q(QKnxNetIpServerDiscoveryAgent);
-
- QKnxPrivate::clearTimer(&frequencyTimer);
- if (frequency > 0) {
- frequencyTimer = new QTimer(q);
- frequencyTimer->setSingleShot(false);
- frequencyTimer->start(60000 / frequency);
-
- QObject::connect(frequencyTimer, &QTimer::timeout, [&]() {
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- if (q->state() == QKnxNetIpServerDiscoveryAgent::State::Running) {
- servers.clear();
-
- const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> flags(discoveryMode);
- if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1)) {
- auto frame = QKnxNetIpSearchRequestProxy::builder()
- .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
- .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
- .setPort(nat ? quint16(0u) : usedPort).create()
- ).create();
- socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
- multicastPort);
- }
-
- if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2)) {
- auto frame = QKnxNetIpSearchRequestProxy::extendedBuilder()
- .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
- .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
- .setPort(nat ? quint16(0u) : usedPort).create()
- )
- .setExtendedParameters(srps).create();
- socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
- multicastPort);
- }
- }
- });
- }
-}
-
-void QKnxNetIpServerDiscoveryAgentPrivate::setAndEmitStateChanged(
- QKnxNetIpServerDiscoveryAgent::State newState)
-{
- state = newState;
-
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- emit q->stateChanged(newState);
-
- if (state == QKnxNetIpServerDiscoveryAgent::State::Running)
- emit q->started();
- else if (state == QKnxNetIpServerDiscoveryAgent::State::NotRunning)
- emit q->finished();
-}
-
-void QKnxNetIpServerDiscoveryAgentPrivate::setAndEmitDeviceDiscovered(
- const QKnxNetIpServerInfo &discoveryInfo)
-{
- servers.append(discoveryInfo);
-
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- emit q->deviceDiscovered(discoveryInfo);
-}
-
-void QKnxNetIpServerDiscoveryAgentPrivate::setAndEmitErrorOccurred(
- QKnxNetIpServerDiscoveryAgent::Error newError, const QString &message)
-{
- error = newError;
- errorString = message;
-
- Q_Q(QKnxNetIpServerDiscoveryAgent);
- emit q->errorOccurred(error, errorString);
-}
-
-
-// -- QKnxNetIpServerDiscoveryAgent
-
/*!
Creates a KNXnet/IP server discovery agent with the parent \a parent.
*/
QKnxNetIpServerDiscoveryAgent::QKnxNetIpServerDiscoveryAgent(QObject *parent)
- : QKnxNetIpServerDiscoveryAgent(QHostAddress(QHostAddress::AnyIPv4), 0u, parent)
+ : QKnxNetIpServerDiscoveryAgent(QHostAddress(QHostAddress::Null), 0U, parent)
{}
/*!
@@ -470,7 +196,7 @@ QKnxNetIpServerDiscoveryAgent::QKnxNetIpServerDiscoveryAgent(QObject *parent)
*/
QKnxNetIpServerDiscoveryAgent::~QKnxNetIpServerDiscoveryAgent()
{
- stop();
+ d_func()->stop();
}
/*!
@@ -479,7 +205,7 @@ QKnxNetIpServerDiscoveryAgent::~QKnxNetIpServerDiscoveryAgent()
*/
QKnxNetIpServerDiscoveryAgent::QKnxNetIpServerDiscoveryAgent(const QHostAddress &localAddress,
QObject *parent)
- : QKnxNetIpServerDiscoveryAgent(localAddress, 0u, parent)
+ : QKnxNetIpServerDiscoveryAgent(localAddress, 0U, parent)
{}
/*!
@@ -500,8 +226,7 @@ QKnxNetIpServerDiscoveryAgent::QKnxNetIpServerDiscoveryAgent(const QHostAddress
*/
QKnxNetIpServerDiscoveryAgent::State QKnxNetIpServerDiscoveryAgent::state() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->state;
+ return d_func()->state;
}
/*!
@@ -509,8 +234,7 @@ QKnxNetIpServerDiscoveryAgent::State QKnxNetIpServerDiscoveryAgent::state() cons
*/
QKnxNetIpServerDiscoveryAgent::Error QKnxNetIpServerDiscoveryAgent::error() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->error;
+ return d_func()->error;
}
/*!
@@ -518,8 +242,7 @@ QKnxNetIpServerDiscoveryAgent::Error QKnxNetIpServerDiscoveryAgent::error() cons
*/
QString QKnxNetIpServerDiscoveryAgent::errorString() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->errorString;
+ return d_func()->errorString;
}
/*!
@@ -527,8 +250,7 @@ QString QKnxNetIpServerDiscoveryAgent::errorString() const
*/
QVector<QKnxNetIpServerInfo> QKnxNetIpServerDiscoveryAgent::discoveredServers() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->servers;
+ return d_func()->servers;
}
/*!
@@ -567,7 +289,8 @@ QHostAddress QKnxNetIpServerDiscoveryAgent::localAddress() const
}
/*!
- Sets the host address of a discovery agent to \a address.
+ Sets the host address of a discovery agent to \a address. To unset the local
+ address use \l QHostAddress::Null.
\note If the address changes during discovery, the new address will not be
used until the next run.
@@ -587,8 +310,7 @@ void QKnxNetIpServerDiscoveryAgent::setLocalAddress(const QHostAddress &address)
*/
int QKnxNetIpServerDiscoveryAgent::timeout() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->timeout;
+ return d_func()->timeout;
}
/*!
@@ -604,7 +326,6 @@ void QKnxNetIpServerDiscoveryAgent::setTimeout(int msec)
{
Q_D(QKnxNetIpServerDiscoveryAgent);
d->timeout = msec;
- d->setupAndStartReceiveTimer();
}
/*!
@@ -615,8 +336,7 @@ void QKnxNetIpServerDiscoveryAgent::setTimeout(int msec)
*/
int QKnxNetIpServerDiscoveryAgent::searchFrequency() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->frequency;
+ return d_func()->frequency;
}
/*!
@@ -641,8 +361,7 @@ void QKnxNetIpServerDiscoveryAgent::setSearchFrequency(int timesPerMinute)
*/
bool QKnxNetIpServerDiscoveryAgent::natAware() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->nat;
+ return d_func()->nat;
}
/*!
@@ -666,8 +385,7 @@ void QKnxNetIpServerDiscoveryAgent::setNatAware(bool useNat)
*/
quint8 QKnxNetIpServerDiscoveryAgent::multicastTtl() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->ttl;
+ return d_func()->ttl;
}
/*!
@@ -687,8 +405,7 @@ void QKnxNetIpServerDiscoveryAgent::setMulticastTtl(quint8 ttl)
*/
QKnxNetIpServerDiscoveryAgent::ResponseType QKnxNetIpServerDiscoveryAgent::responseType() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->type;
+ return d_func()->type;
}
/*!
@@ -709,8 +426,7 @@ void QKnxNetIpServerDiscoveryAgent::setResponseType(QKnxNetIpServerDiscoveryAgen
*/
QKnxNetIpServerDiscoveryAgent::DiscoveryModes QKnxNetIpServerDiscoveryAgent::discoveryMode() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->discoveryMode;
+ return d_func()->mode;
}
/*!
@@ -724,18 +440,18 @@ void QKnxNetIpServerDiscoveryAgent::setDiscoveryMode(QKnxNetIpServerDiscoveryAge
{
Q_D(QKnxNetIpServerDiscoveryAgent);
if (d->state == QKnxNetIpServerDiscoveryAgent::State::NotRunning)
- d->discoveryMode = mode;
+ d->mode = mode;
}
/*!
\since 5.12
+
Returns the search request parameter (SRP) objects used in an
\l {QKnxNetIpServerDiscoveryAgent::CoreV2} {extended search request}.
*/
QVector<QKnxNetIpSrp> QKnxNetIpServerDiscoveryAgent::extendedSearchParameters() const
{
- Q_D(const QKnxNetIpServerDiscoveryAgent);
- return d->srps;
+ return d_func()->srps;
}
/*!
@@ -752,8 +468,7 @@ QVector<QKnxNetIpSrp> QKnxNetIpServerDiscoveryAgent::extendedSearchParameters()
*/
void QKnxNetIpServerDiscoveryAgent::setExtendedSearchParameters(const QVector<QKnxNetIpSrp> &srps)
{
- Q_D(QKnxNetIpServerDiscoveryAgent);
- d->srps = srps;
+ d_func()->srps = srps;
}
/*!
@@ -761,26 +476,7 @@ void QKnxNetIpServerDiscoveryAgent::setExtendedSearchParameters(const QVector<QK
*/
void QKnxNetIpServerDiscoveryAgent::start()
{
- Q_D(QKnxNetIpServerDiscoveryAgent);
-
- if (d->state != QKnxNetIpServerDiscoveryAgent::State::NotRunning)
- return;
-
- auto isIPv4 = true;
- d->address.toIPv4Address(&isIPv4);
- if (isIPv4) {
- d->setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Starting);
-
- d->setupSocket();
- if (d->type == QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast) {
- d->socket->bind(QHostAddress::AnyIPv4, d->multicastPort, QUdpSocket::ShareAddress
- | QAbstractSocket::ReuseAddressHint);
- } else {
- d->socket->bind(d->address, d->port);
- }
- } else {
- d->setAndEmitErrorOccurred(Error::NotIPv4, tr("Only IPv4 local address supported."));
- }
+ d_func()->start();
}
/*!
@@ -791,32 +487,37 @@ void QKnxNetIpServerDiscoveryAgent::start()
void QKnxNetIpServerDiscoveryAgent::start(int timeout)
{
d_func()->timeout = timeout;
- start();
+ d_func()->start();
}
/*!
- Stops a server discovery agent.
+ Starts a server discovery agent with the network interfaces specified by
+ the list of local host \a addresses.
+
+ \note Does not emit the errorOccurred signal.
*/
-void QKnxNetIpServerDiscoveryAgent::stop()
+void QKnxNetIpServerDiscoveryAgent::start(const QVector<QHostAddress> &addresses)
{
- Q_D(QKnxNetIpServerDiscoveryAgent);
-
- if (d->state == State::Stopping || d->state == State::NotRunning)
- return;
-
- d->setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Stopping);
+ d_func()->start(addresses);
+}
- if (d->type == QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast
- && d->socket->state() == QUdpSocket::BoundState) {
- d->socket->leaveMulticastGroup(d->multicastAddress);
- }
- d->socket->close();
+/*!
+ Starts a server discovery agent with the network interfaces specified by
+ the list of interface types \a types.
- QKnxPrivate::clearSocket(&(d->socket));
- QKnxPrivate::clearTimer(&(d->receiveTimer));
- QKnxPrivate::clearTimer(&(d->frequencyTimer));
+ \note Does not emit the errorOccurred signal.
+*/
+void QKnxNetIpServerDiscoveryAgent::start(QKnxNetIpServerDiscoveryAgent::InterfaceTypes types)
+{
+ d_func()->start(types);
+}
- d->setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::NotRunning);
+/*!
+ Stops a server discovery agent.
+*/
+void QKnxNetIpServerDiscoveryAgent::stop()
+{
+ d_func()->stop();
}
/*!
diff --git a/src/knx/netip/qknxnetipserverdiscoveryagent.h b/src/knx/netip/qknxnetipserverdiscoveryagent.h
index 0fd0455..b7bdf83 100644
--- a/src/knx/netip/qknxnetipserverdiscoveryagent.h
+++ b/src/knx/netip/qknxnetipserverdiscoveryagent.h
@@ -60,6 +60,7 @@ public:
None,
Network,
NotIPv4,
+ Timeout,
Unknown = 0x80
};
Q_ENUM(Error)
@@ -79,8 +80,17 @@ public:
Q_ENUM(DiscoveryMode)
Q_DECLARE_FLAGS(DiscoveryModes, DiscoveryMode)
+ enum class InterfaceType : quint8
+ {
+ Loopback = 0x01,
+ Ethernet = 0x02,
+ Wifi = 0x04
+ };
+ Q_ENUM(InterfaceType)
+ Q_DECLARE_FLAGS(InterfaceTypes, InterfaceType)
+
QKnxNetIpServerDiscoveryAgent(QObject *parent = nullptr);
- ~QKnxNetIpServerDiscoveryAgent();
+ ~QKnxNetIpServerDiscoveryAgent() override;
explicit QKnxNetIpServerDiscoveryAgent(const QHostAddress &localAddress,
QObject *parent = nullptr);
@@ -122,9 +132,12 @@ public:
public Q_SLOTS:
void start();
- void start(int timeout);
void stop();
+ void start(int timeout);
+ void start(const QVector<QHostAddress> &localAddresses);
+ void start(QKnxNetIpServerDiscoveryAgent::InterfaceTypes types);
+
Q_SIGNALS:
void started();
void finished();
@@ -137,6 +150,7 @@ private:
QKnxNetIpServerDiscoveryAgent(QKnxNetIpServerDiscoveryAgentPrivate &dd, QObject *parent);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QKnxNetIpServerDiscoveryAgent::DiscoveryModes)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QKnxNetIpServerDiscoveryAgent::InterfaceTypes)
QT_END_NAMESPACE
diff --git a/src/knx/netip/qknxnetipserverdiscoveryagent_p.cpp b/src/knx/netip/qknxnetipserverdiscoveryagent_p.cpp
new file mode 100644
index 0000000..44e7bb5
--- /dev/null
+++ b/src/knx/netip/qknxnetipserverdiscoveryagent_p.cpp
@@ -0,0 +1,684 @@
+/******************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtKnx module.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "qknxnetipserverdiscoveryagent.h"
+#include "qknxnetipserverdiscoveryagent_p.h"
+
+#include <QtCore/qthread.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QKnxPrivate
+{
+ static void clearSocket(QUdpSocket **socket)
+ {
+ if (*socket) {
+ (*socket)->disconnect();
+ (*socket)->deleteLater();
+ (*socket) = nullptr;
+ }
+ }
+
+ static void clearTimer(QTimer **timer)
+ {
+ if (*timer) {
+ (*timer)->stop();
+ (*timer)->disconnect();
+ (*timer)->deleteLater();
+ (*timer) = nullptr;
+ }
+ }
+
+ static QVector<Adapter> adaptersForAddresses(const QVector<QHostAddress> addresses)
+ {
+ QVector<Adapter> adapters;
+ auto all = QNetworkInterface::allInterfaces();
+ for (const auto &iface : all) {
+ const auto flags = iface.flags();
+ if (!flags.testFlag(QNetworkInterface::IsUp)
+ && !flags.testFlag(QNetworkInterface::IsRunning)
+ && !flags.testFlag(QNetworkInterface::CanMulticast)) continue;
+
+ const auto type = iface.type();
+ if (type != QNetworkInterface::Wifi
+ && type != QNetworkInterface::Loopback
+ && type != QNetworkInterface::Ethernet) continue;
+
+ const auto entries = iface.addressEntries();
+ for (const auto &entry : entries) {
+ const auto address = entry.ip();
+ if (address.protocol() != QAbstractSocket::IPv4Protocol)
+ continue;
+ if (!addresses.contains(address))
+ continue;
+ adapters.append({ address, iface });
+ break;
+ }
+ }
+ return adapters;
+ }
+}
+
+Discoverer::Discoverer(const QHostAddress &address, const QNetworkInterface iface, const DiscovererConfig &c)
+ : QObject(nullptr)
+ , m_address(address)
+ , m_iface(iface)
+ , m_config(c)
+{}
+
+Discoverer::~Discoverer()
+{
+ finish();
+}
+
+void Discoverer::start()
+{
+ if (m_state != QKnxNetIpServerDiscoveryAgent::State::NotRunning)
+ return;
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Starting);
+
+ auto isIPv4 = true;
+ m_address.toIPv4Address(&isIPv4);
+ if (!isIPv4) {
+ emit errorOccurred(QKnxNetIpServerDiscoveryAgent::Error::NotIPv4,
+ QKnxNetIpServerDiscoveryAgent::tr("Only IPv4 local address supported."));
+ return finish();
+ }
+
+ m_socket = new QUdpSocket;
+ connect(m_socket, &QUdpSocket::readyRead, this, &Discoverer::onReadyRead);
+ using overload = void (QUdpSocket::*)(QUdpSocket::SocketError);
+ connect(m_socket, static_cast<overload>(&QUdpSocket::error), this, &Discoverer::onError);
+
+ bool bound = m_socket->bind(m_config.Multicast ? QHostAddress::AnyIPv4
+ : m_address,
+ m_config.Multicast ? 3671 : 0,
+ QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
+ if (!bound)
+ return finish();
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Running);
+
+ if (m_config.Multicast) {
+ m_socket->setMulticastInterface(m_iface);
+ if (!m_socket->joinMulticastGroup(m_multicast, m_iface)) {
+ emit errorOccurred(QKnxNetIpServerDiscoveryAgent::Error::Network,
+ QKnxNetIpServerDiscoveryAgent::tr("Could not join multicast group."));
+ return finish();
+ }
+ m_socket->setSocketOption(QUdpSocket::SocketOption::MulticastTtlOption, m_config.Ttl);
+ }
+
+ m_timer = new QTimer;
+ m_timer->setSingleShot(true);
+ connect(m_timer, &QTimer::timeout, this, &Discoverer::onTimeout);
+
+ if (m_config.DiscoveryCoreV1) {
+ const auto frame = QKnxNetIpSearchRequestProxy::builder()
+ .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::Builder()
+ .setPort(m_config.Nat ? 0 : (m_config.Multicast ? 3671 : m_socket->localPort()))
+ .setHostAddress(m_config.Nat ? QHostAddress::AnyIPv4
+ : (m_config.Multicast ? m_multicast : m_address))
+ .create())
+ .create();
+
+ if (frame.isValid())
+ m_socket->writeDatagram(frame.bytes().toByteArray(), m_multicast, 3671);
+ }
+
+ if (m_config.DiscoveryCoreV2) {
+ const auto frame = QKnxNetIpSearchRequestProxy::extendedBuilder()
+ .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::Builder()
+ .setPort(m_config.Nat ? 0 : (m_config.Multicast ? 3671 : m_socket->localPort()))
+ .setHostAddress(m_config.Nat ? QHostAddress::AnyIPv4
+ : (m_config.Multicast ? m_multicast : m_address))
+ .create())
+ .setExtendedParameters(m_config.ExtendedSearchParameters)
+ .create();
+ if (frame.isValid())
+ m_socket->writeDatagram(frame.bytes().toByteArray(), m_multicast, 3671);
+ }
+
+ m_timer->start(m_config.Timeout);
+}
+
+void Discoverer::finish()
+{
+ if (m_state == QKnxNetIpServerDiscoveryAgent::State::Stopping
+ || m_state == QKnxNetIpServerDiscoveryAgent::State::NotRunning) {
+ return;
+ }
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Stopping);
+
+ QKnxPrivate::clearTimer(&m_timer);
+
+ if (m_socket) {
+ if (m_config.Multicast && m_socket->state() == QUdpSocket::BoundState) {
+ m_socket->setMulticastInterface({});
+ m_socket->leaveMulticastGroup(m_multicast, m_iface);
+ }
+ QKnxPrivate::clearSocket(&m_socket);
+ }
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::NotRunning);
+}
+
+void Discoverer::onTimeout()
+{
+ if (m_devices.isEmpty())
+ emit timeout();
+ finish();
+}
+
+void Discoverer::onReadyRead()
+{
+ while (m_socket->hasPendingDatagrams()) {
+ if (m_state != QKnxNetIpServerDiscoveryAgent::State::Running)
+ break;
+
+ const auto datagram = m_socket->receiveDatagram();
+ const auto data = QKnxByteArray::fromByteArray(datagram.data());
+ const auto header = QKnxNetIpFrameHeader::fromBytes(data, 0);
+ if (!header.isValid())
+ continue;
+
+ if (header.serviceType() != QKnxNetIp::ServiceType::SearchResponse
+ && header.serviceType() != QKnxNetIp::ServiceType::ExtendedSearchResponse) {
+ continue;
+ }
+
+ const auto frame = QKnxNetIpFrame::fromBytes(data);
+ const auto proxy = QKnxNetIpSearchResponseProxy(frame);
+ if (!proxy.isValid())
+ continue;
+
+ if (m_config.DiscoveryCoreV1 && !proxy.isExtended()) {
+ emit deviceDiscovered(
+ {
+ (m_config.Nat ? QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(datagram.senderAddress())
+ .setPort(datagram.senderPort()).create()
+ : proxy.controlEndpoint()),
+ proxy.deviceHardware(),
+ proxy.supportedFamilies(),
+ m_address, m_iface
+ }
+ );
+ }
+
+ if (m_config.DiscoveryCoreV2 && proxy.isExtended()) {
+ const auto optionalDibs = proxy.optionalDibs();
+ emit deviceDiscovered(
+ {
+ (m_config.Nat ? QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(datagram.senderAddress())
+ .setPort(datagram.senderPort()).create()
+ : proxy.controlEndpoint()),
+ proxy.deviceHardware(),
+ proxy.supportedFamilies(),
+ m_address, m_iface,
+ [&optionalDibs]() -> QKnxNetIpDib {
+ for (const auto &dib : qAsConst(optionalDibs)) {
+ if (dib.code() == QKnxNetIp::DescriptionType::TunnelingInfo)
+ return dib;
+ }
+ return {};
+ }(),
+ [&optionalDibs]() -> QKnxNetIpDib {
+ for (const auto &dib : qAsConst(optionalDibs)) {
+ if (dib.code() == QKnxNetIp::DescriptionType::ExtendedDeviceInfo)
+ return dib;
+ }
+ return {};
+ }()
+ }
+ );
+ }
+ }
+}
+
+void Discoverer::onError(QUdpSocket::SocketError /* error */)
+{
+ emit errorOccurred(QKnxNetIpServerDiscoveryAgent::Error::Network,
+ m_socket ? m_socket->errorString()
+ : QKnxNetIpServerDiscoveryAgent::tr("Unknown socket error happened.")
+ );
+ finish();
+}
+
+void Discoverer::setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State state)
+{
+ m_state = state;
+ emit stateChanged(m_state);
+
+ if (m_state == QKnxNetIpServerDiscoveryAgent::State::Starting)
+ emit started();
+ if (m_state == QKnxNetIpServerDiscoveryAgent::State::Stopping)
+ emit finished(this);
+}
+
+QKnxNetIpServerDiscoveryAgentPrivate::QKnxNetIpServerDiscoveryAgentPrivate(const QHostAddress &addr,
+ quint16 prt)
+ : port(prt)
+ , address(addr)
+{}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::setupSocket()
+{
+ usedPort = port;
+ usedAddress = address;
+ QKnxPrivate::clearSocket(&socket);
+
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ socket = new QUdpSocket(q);
+
+ adapter = QKnxPrivate::adaptersForAddresses(QVector<QHostAddress> { address }).value(0);
+ QObject::connect(socket, &QUdpSocket::stateChanged, q, [&](QUdpSocket::SocketState s) {
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ switch (s) {
+ case QUdpSocket::BoundState:
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Running);
+ socket->setSocketOption(QUdpSocket::SocketOption::MulticastTtlOption, ttl);
+
+ if (type == QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast) {
+ QNetworkInterface mni;
+ const auto interfaces = QNetworkInterface::allInterfaces();
+ for (const auto &iface : interfaces) {
+ if (!iface.flags().testFlag(QNetworkInterface::CanMulticast))
+ continue;
+
+ const auto entries = iface.addressEntries();
+ for (const auto &entry : entries) {
+ auto ip = entry.ip();
+ if (ip.protocol() != QAbstractSocket::NetworkLayerProtocol::IPv4Protocol)
+ continue;
+ if (ip != address)
+ continue;
+ mni = iface;
+ break;
+ }
+ }
+
+ if (mni.isValid())
+ socket->setMulticastInterface(mni);
+
+ if (socket->joinMulticastGroup(multicastAddress, mni)) {
+ usedPort = multicastPort;
+ usedAddress = multicastAddress;
+ } else {
+ setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error::Network,
+ QKnxNetIpServerDiscoveryAgent::tr("Could not join multicast group."));
+ q->stop();
+ }
+ } else {
+ usedPort = socket->localPort();
+ usedAddress = socket->localAddress();
+ }
+
+ if (q->state() == QKnxNetIpServerDiscoveryAgent::State::Running) {
+ servers.clear();
+
+ const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> flags(mode);
+ if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1)) {
+ auto frame = QKnxNetIpSearchRequestProxy::builder()
+ .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
+ .setPort(nat ? quint16(0u) : usedPort).create()
+ ).create();
+ socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
+ multicastPort);
+ }
+
+ if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2)) {
+ auto frame = QKnxNetIpSearchRequestProxy::extendedBuilder()
+ .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
+ .setPort(nat ? quint16(0u) : usedPort).create()
+ )
+ .setExtendedParameters(srps).create();
+ socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
+ multicastPort);
+ }
+
+ setupAndStartReceiveTimer();
+ setupAndStartFrequencyTimer();
+ }
+ break;
+ default:
+ break;
+ }
+ });
+
+ using overload = void (QUdpSocket::*)(QUdpSocket::SocketError);
+ QObject::connect(socket,
+ static_cast<overload>(&QUdpSocket::error), q, [&](QUdpSocket::SocketError) {
+ setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error::Network,
+ socket->errorString());
+
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ q->stop();
+ });
+
+ QObject::connect(socket, &QUdpSocket::readyRead, q, [&]() {
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ while (socket->hasPendingDatagrams()) {
+ if (q->state() != QKnxNetIpServerDiscoveryAgent::State::Running)
+ break;
+
+ auto datagram = socket->receiveDatagram();
+ auto data = QKnxByteArray::fromByteArray(datagram.data());
+ const auto header = QKnxNetIpFrameHeader::fromBytes(data, 0);
+ if (!header.isValid())
+ continue;
+
+ if (header.serviceType() != QKnxNetIp::ServiceType::SearchResponse &&
+ header.serviceType() != QKnxNetIp::ServiceType::ExtendedSearchResponse) {
+ continue;
+ }
+
+ auto frame = QKnxNetIpFrame::fromBytes(data);
+ auto response = QKnxNetIpSearchResponseProxy(frame);
+ if (!response.isValid())
+ continue;
+
+ const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> flags(mode);
+ if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1)
+ && !response.isExtended()) {
+ setAndEmitDeviceDiscovered({
+ (nat ? QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(datagram.senderAddress())
+ .setPort(datagram.senderPort()).create()
+ : response.controlEndpoint()
+ ), response.deviceHardware(), response.supportedFamilies(),
+ adapter.address, adapter.iface
+ });
+ }
+
+ if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2)
+ && response.isExtended()) {
+ const auto optionalDibs = response.optionalDibs();
+ setAndEmitDeviceDiscovered({
+ (nat ? QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(datagram.senderAddress())
+ .setPort(datagram.senderPort()).create()
+ : response.controlEndpoint()
+ ), response.deviceHardware(), response.supportedFamilies(),
+ adapter.address, adapter.iface,
+ [&optionalDibs]() -> QKnxNetIpDib {
+ for (const auto &dib : qAsConst(optionalDibs)) {
+ if (dib.code() == QKnxNetIp::DescriptionType::TunnelingInfo)
+ return dib;
+ }
+ return {};
+ }(),
+ [&optionalDibs]() -> QKnxNetIpDib {
+ for (const auto &dib : qAsConst(optionalDibs)) {
+ if (dib.code() == QKnxNetIp::DescriptionType::ExtendedDeviceInfo)
+ return dib;
+ }
+ return {};
+ }()
+ });
+ }
+ }
+ });
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::setupAndStartReceiveTimer()
+{
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+
+ QKnxPrivate::clearTimer(&receiveTimer);
+ if (timeout >= 0) {
+ receiveTimer = new QTimer(q);
+ receiveTimer->setSingleShot(true);
+ receiveTimer->start(timeout);
+ QObject::connect(receiveTimer, &QTimer::timeout, q, &QKnxNetIpServerDiscoveryAgent::stop);
+ }
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::setupAndStartFrequencyTimer()
+{
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+
+ QKnxPrivate::clearTimer(&frequencyTimer);
+ if (frequency > 0) {
+ frequencyTimer = new QTimer(q);
+ frequencyTimer->setSingleShot(false);
+ frequencyTimer->start(60000 / frequency);
+
+ QObject::connect(frequencyTimer, &QTimer::timeout, q, [&]() {
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ if (q->state() == QKnxNetIpServerDiscoveryAgent::State::Running) {
+ servers.clear();
+
+ const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> flags(mode);
+ if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1)) {
+ auto frame = QKnxNetIpSearchRequestProxy::builder()
+ .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
+ .setPort(nat ? quint16(0u) : usedPort).create()
+ ).create();
+ socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
+ multicastPort);
+ }
+
+ if (flags.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2)) {
+ auto frame = QKnxNetIpSearchRequestProxy::extendedBuilder()
+ .setDiscoveryEndpoint(QKnxNetIpHpaiProxy::builder()
+ .setHostAddress(nat ? QHostAddress::AnyIPv4 : usedAddress)
+ .setPort(nat ? quint16(0u) : usedPort).create()
+ )
+ .setExtendedParameters(srps).create();
+ socket->writeDatagram(frame.bytes().toByteArray(), multicastAddress,
+ multicastPort);
+ }
+ }
+ });
+ }
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::setAndEmitStateChanged(
+ QKnxNetIpServerDiscoveryAgent::State newState)
+{
+ state = newState;
+
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ emit q->stateChanged(newState);
+
+ if (state == QKnxNetIpServerDiscoveryAgent::State::Running)
+ emit q->started();
+ else if (state == QKnxNetIpServerDiscoveryAgent::State::NotRunning)
+ emit q->finished();
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::setAndEmitDeviceDiscovered(
+ const QKnxNetIpServerInfo &discoveryInfo)
+{
+ servers.append(discoveryInfo);
+
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ emit q->deviceDiscovered(discoveryInfo);
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::setAndEmitErrorOccurred(
+ QKnxNetIpServerDiscoveryAgent::Error newError, const QString &message)
+{
+ error = newError;
+ errorString = message;
+
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ emit q->errorOccurred(error, errorString);
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::start()
+{
+ if (state != QKnxNetIpServerDiscoveryAgent::State::NotRunning)
+ return;
+
+ if (address.isNull())
+ address = QHostAddress(QHostAddress::AnyIPv4);
+
+ auto isIPv4 = true;
+ address.toIPv4Address(&isIPv4);
+ if (isIPv4) {
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Starting);
+ setupSocket();
+ if (type == QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast) {
+ socket->bind(QHostAddress::AnyIPv4, multicastPort, QUdpSocket::ShareAddress
+ | QAbstractSocket::ReuseAddressHint);
+ } else {
+ socket->bind(address, port);
+ }
+ } else {
+ setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error::NotIPv4,
+ QKnxNetIpServerDiscoveryAgent::tr("Only IPv4 local address supported."));
+ }
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::start(const QVector<Adapter> &adapters)
+{
+ if (state != QKnxNetIpServerDiscoveryAgent::State::NotRunning)
+ return;
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Starting);
+
+ if (adapters.isEmpty())
+ return stop();
+
+ Q_Q(QKnxNetIpServerDiscoveryAgent);
+ const QFlags<QKnxNetIpServerDiscoveryAgent::ResponseType> rtype(type);
+ const QFlags<QKnxNetIpServerDiscoveryAgent::DiscoveryMode> dmode(mode);
+ const DiscovererConfig config {
+ ttl,
+ timeout,
+ nat,
+ rtype.testFlag(QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast),
+ dmode.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1),
+ dmode.testFlag(QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV2),
+ srps
+ };
+
+ bool connectError = (adapters.count() == 1);
+ for (const auto &adapter : adapters) {
+ auto discoverer = new Discoverer(adapter.address, adapter.iface, config);
+ discoveries.append(discoverer);
+
+ auto thread = new QThread;
+ discoverer->moveToThread(thread);
+ QObject::connect(thread, &QThread::started, discoverer, &Discoverer::start);
+ QObject::connect(thread, &QThread::finished, discoverer, &Discoverer::deleteLater);
+
+ QObject::connect(thread, &QThread::started, discoverer, &Discoverer::start);
+ QObject::connect(thread, &QThread::finished, discoverer, &Discoverer::finish);
+
+ QObject::connect(discoverer, &Discoverer::finished, q, [&](Discoverer *ds) {
+ discoveries.removeAll(ds);
+ if (discoveries.isEmpty())
+ stop();
+ });
+ QObject::connect(discoverer, &Discoverer::finished, thread, &QThread::quit);
+ QObject::connect(discoverer, &Discoverer::deviceDiscovered, q, [&](const QKnxNetIpServerInfo &server) {
+ setAndEmitDeviceDiscovered(server);
+ });
+ if (connectError) {
+ QObject::connect(discoverer, &Discoverer::errorOccurred, q,
+ [&](QKnxNetIpServerDiscoveryAgent::Error error, const QString &errorString) {
+ setAndEmitErrorOccurred(error, errorString);
+ });
+ }
+ thread->start();
+ }
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Running);
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::start(const QVector<QHostAddress> addresses)
+{
+ start(QKnxPrivate::adaptersForAddresses(addresses));
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::start(QKnxNetIpServerDiscoveryAgent::InterfaceTypes types)
+{
+ QVector<Adapter> adapters;
+ auto all = QNetworkInterface::allInterfaces();
+ for (const auto &iface : all) {
+ const auto flags = iface.flags();
+ if (!flags.testFlag(QNetworkInterface::IsUp)
+ && !flags.testFlag(QNetworkInterface::IsRunning)
+ && !flags.testFlag(QNetworkInterface::CanMulticast)) continue;
+
+ const bool wifi = types.testFlag(QKnxNetIpServerDiscoveryAgent::InterfaceType::Wifi);
+ const bool loopback = types.testFlag(QKnxNetIpServerDiscoveryAgent::InterfaceType::Loopback);
+ const bool ethernet = types.testFlag(QKnxNetIpServerDiscoveryAgent::InterfaceType::Ethernet);
+
+ const auto type = iface.type();
+ if (!(wifi && type == QNetworkInterface::Wifi)
+ && !(loopback && type == QNetworkInterface::Loopback)
+ && !(ethernet && type == QNetworkInterface::Ethernet)) continue;
+
+ const auto entries = iface.addressEntries();
+ for (const auto &entry : entries) {
+ const auto address = entry.ip();
+ if (address.protocol() != QAbstractSocket::IPv4Protocol)
+ continue;
+ adapters.append({ address, iface });
+ break;
+ }
+ }
+ start(adapters);
+}
+
+void QKnxNetIpServerDiscoveryAgentPrivate::stop()
+{
+ if (state == QKnxNetIpServerDiscoveryAgent::State::Stopping
+ || state == QKnxNetIpServerDiscoveryAgent::State::NotRunning) {
+ return;
+ }
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::Stopping);
+
+ if (socket) {
+ if (type == QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast
+ && socket->state() == QUdpSocket::BoundState) {
+ socket->leaveMulticastGroup(multicastAddress);
+ }
+ socket->close();
+ }
+
+ QKnxPrivate::clearSocket(&(socket));
+ QKnxPrivate::clearTimer(&(receiveTimer));
+ QKnxPrivate::clearTimer(&(frequencyTimer));
+
+ setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State::NotRunning);
+}
+
+QT_END_NAMESPACE
diff --git a/src/knx/netip/qknxnetipserverdiscoveryagent_p.h b/src/knx/netip/qknxnetipserverdiscoveryagent_p.h
index 21bdcdf..46be5fe 100644
--- a/src/knx/netip/qknxnetipserverdiscoveryagent_p.h
+++ b/src/knx/netip/qknxnetipserverdiscoveryagent_p.h
@@ -47,14 +47,94 @@
#include <QtKnx/qknxnetipsearchrequest.h>
#include <QtKnx/qknxnetipsearchresponse.h>
#include <QtKnx/qknxnetipserverdiscoveryagent.h>
+
#include <QtNetwork/qhostaddress.h>
#include <QtNetwork/qnetworkdatagram.h>
+#include <QtNetwork/qnetworkinterface.h>
#include <QtNetwork/qudpsocket.h>
#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
+struct Adapter
+{
+ QHostAddress address;
+ QNetworkInterface iface;
+};
+
+struct DiscovererConfig
+{
+ DiscovererConfig() = default;
+ ~DiscovererConfig() = default;
+
+ DiscovererConfig(int ttl, int timeout, bool nat, bool multicast, bool coreV1, bool coreV2,
+ const QVector<QKnxNetIpSrp> &srps)
+ : Ttl(ttl)
+ , Timeout(timeout)
+ , Nat(nat)
+ , Multicast(multicast)
+ , DiscoveryCoreV1(coreV1)
+ , DiscoveryCoreV2(coreV2)
+ , ExtendedSearchParameters(srps)
+ {}
+
+ int Ttl { 64 };
+ int Timeout { 3000 };
+
+ bool Nat { false };
+ bool Multicast { true };
+
+ bool DiscoveryCoreV1 { true };
+ bool DiscoveryCoreV2 { true };
+
+ QVector<QKnxNetIpSrp> ExtendedSearchParameters;
+};
+
+class Discoverer : public QObject
+{
+ Q_OBJECT
+
+public:
+ Discoverer(const QHostAddress &address, const QNetworkInterface iface, const DiscovererConfig &config);
+ ~Discoverer() override;
+
+public slots:
+ void start();
+ void finish();
+
+signals:
+ void started();
+ void timeout();
+ void finished(Discoverer *iam);
+
+ void stateChanged(QKnxNetIpServerDiscoveryAgent::State state);
+ void errorOccurred(QKnxNetIpServerDiscoveryAgent::Error error, const QString &errorString);
+
+ void deviceDiscovered(const QKnxNetIpServerInfo &discoveryInfo);
+
+private slots:
+ void onTimeout();
+ void onReadyRead();
+ void onError(QUdpSocket::SocketError error);
+
+private:
+ void setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State state);
+
+private:
+ QHostAddress m_address;
+ QNetworkInterface m_iface;
+
+ QTimer *m_timer { nullptr };
+ QUdpSocket *m_socket { nullptr };
+
+ DiscovererConfig m_config;
+ QVector<QByteArray> m_devices;
+
+ QHostAddress m_multicast { QStringLiteral("224.0.23.12") };
+ QKnxNetIpServerDiscoveryAgent::State m_state { QKnxNetIpServerDiscoveryAgent::State::NotRunning };
+};
+
class Q_KNX_EXPORT QKnxNetIpServerDiscoveryAgentPrivate final : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QKnxNetIpServerDiscoveryAgent)
@@ -70,7 +150,13 @@ public:
void setAndEmitStateChanged(QKnxNetIpServerDiscoveryAgent::State newState);
void setAndEmitDeviceDiscovered(const QKnxNetIpServerInfo &discoveryInfo);
- void setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error e, const QString &message);
+ void setAndEmitErrorOccurred(QKnxNetIpServerDiscoveryAgent::Error newError, const QString &message);
+
+ void start();
+ void start(const QVector<Adapter> &adapters);
+ void start(const QVector<QHostAddress> addresses);
+ void start(QKnxNetIpServerDiscoveryAgent::InterfaceTypes types);
+ void stop();
private:
QUdpSocket *socket { nullptr };
@@ -78,12 +164,12 @@ private:
QTimer *frequencyTimer { nullptr };
quint16 port { 0 }, usedPort { 0 };
- QHostAddress address { QHostAddress::AnyIPv4 }, usedAddress;
+ QHostAddress address { QHostAddress::Null }, usedAddress;
const quint16 multicastPort { QKnxNetIp::Constants::DefaultPort };
const QHostAddress multicastAddress { QLatin1String(QKnxNetIp::Constants::MulticastAddress) };
- quint8 ttl { 60 };
+ quint8 ttl { 64 };
bool nat { false };
int frequency { 0 };
int timeout { QKnxNetIp::Timeout::SearchTimeout };
@@ -96,9 +182,12 @@ private:
QKnxNetIpServerDiscoveryAgent::ResponseType
type { QKnxNetIpServerDiscoveryAgent::ResponseType::Multicast };
- QKnxNetIpServerDiscoveryAgent::DiscoveryModes discoveryMode
+ QKnxNetIpServerDiscoveryAgent::DiscoveryModes mode
{ QKnxNetIpServerDiscoveryAgent::DiscoveryMode::CoreV1 };
QVector<QKnxNetIpSrp> srps;
+
+ Adapter adapter;
+ QVector<Discoverer*> discoveries;
};
QT_END_NAMESPACE
diff --git a/src/knx/netip/qknxnetipserverinfo.cpp b/src/knx/netip/qknxnetipserverinfo.cpp
index 31ac706..d8c6b62 100644
--- a/src/knx/netip/qknxnetipserverinfo.cpp
+++ b/src/knx/netip/qknxnetipserverinfo.cpp
@@ -98,7 +98,9 @@ QT_BEGIN_NAMESPACE
*/
QKnxNetIpServerInfo::QKnxNetIpServerInfo()
: d_ptr(new QKnxNetIpServerInfoPrivate)
-{}
+{
+ qRegisterMetaType<QKnxNetIpServerInfo>();
+}
/*!
Deletes a KNXnet/IP server information object.
@@ -254,6 +256,32 @@ QKnxNetIpDib QKnxNetIpServerInfo::extendedHardware() const
}
/*!
+ \since 5.14
+
+ Returns the host address which has been used to discover the KNXnet/IP
+ server hardware.
+
+ \sa QHostAddress
+*/
+QHostAddress QKnxNetIpServerInfo::hostAddress() const
+{
+ return d_ptr->address;
+}
+
+/*!
+ \since 5.14
+
+ Returns the network interface which has been used to discover the KNXnet/IP
+ server hardware.
+
+ \sa QNetworkInterface
+*/
+QNetworkInterface QKnxNetIpServerInfo::networkInterface() const
+{
+ return d_ptr->iinterface;
+}
+
+/*!
Constructs a copy of \a other.
*/
QKnxNetIpServerInfo::QKnxNetIpServerInfo(const QKnxNetIpServerInfo &other)
@@ -321,16 +349,13 @@ void QKnxNetIpServerInfo::swap(QKnxNetIpServerInfo &other) Q_DECL_NOTHROW
d_ptr.swap(other.d_ptr);
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
\internal
*/
QKnxNetIpServerInfo::QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNetIpDib &hardware,
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QKnxNetIpDib services)
-#else
- const QKnxNetIpDib &services) // ### Qt6: pass services as const reference
-#endif
: QKnxNetIpServerInfo()
{
d_ptr->hpai = hpai;
@@ -338,17 +363,29 @@ QKnxNetIpServerInfo::QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNe
d_ptr->services = services;
}
-
/*!
\internal
*/
QKnxNetIpServerInfo::QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNetIpDib &hardware,
const QKnxNetIpDib &services, const QKnxNetIpDib &tunneling, const QKnxNetIpDib &extHardware)
+ : QKnxNetIpServerInfo(hpai, hardware, services, {}, {}, tunneling, extHardware)
+{}
+
+#endif
+
+/*!
+ \internal
+*/
+QKnxNetIpServerInfo::QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNetIpDib &hardware,
+ const QKnxNetIpDib &services, const QHostAddress &address, const QNetworkInterface &iinterface,
+ const QKnxNetIpDib &tunneling, const QKnxNetIpDib &extHardware)
: QKnxNetIpServerInfo()
{
d_ptr->hpai = hpai;
d_ptr->hardware = hardware;
d_ptr->services = services;
+ d_ptr->address = address;
+ d_ptr->iinterface = iinterface;
d_ptr->tunnelingInfo = tunneling;
d_ptr->extendedHardware = extHardware;
}
diff --git a/src/knx/netip/qknxnetipserverinfo.h b/src/knx/netip/qknxnetipserverinfo.h
index 772586f..4db9656 100644
--- a/src/knx/netip/qknxnetipserverinfo.h
+++ b/src/knx/netip/qknxnetipserverinfo.h
@@ -39,6 +39,7 @@
#include <QtKnx/qknxnetiptunnelinginfodib.h>
#include <QtNetwork/qhostaddress.h>
+#include <QtNetwork/qnetworkinterface.h>
QT_BEGIN_NAMESPACE
@@ -46,6 +47,7 @@ struct QKnxNetIpServerInfoPrivate;
class Q_KNX_EXPORT QKnxNetIpServerInfo final
{
+ friend class Discoverer;
friend class QKnxNetIpServerDiscoveryAgentPrivate;
friend class QKnxNetIpServerDescriptionAgentPrivate;
@@ -72,6 +74,9 @@ public:
QKnxNetIpDib tunnelingInfo() const;
QKnxNetIpDib extendedHardware() const;
+ QHostAddress hostAddress() const;
+ QNetworkInterface networkInterface() const;
+
QKnxNetIpServerInfo(const QKnxNetIpServerInfo &other);
QKnxNetIpServerInfo &operator=(const QKnxNetIpServerInfo &other);
@@ -84,16 +89,23 @@ public:
void swap(QKnxNetIpServerInfo &other) Q_DECL_NOTHROW;
private:
- QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNetIpDib &hardware,
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNetIpDib &hardware,
QKnxNetIpDib services);
-#else
- const QKnxNetIpDib &services);
-#endif
QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai, const QKnxNetIpDib &hardware,
const QKnxNetIpDib &services, const QKnxNetIpDib &tunnelingInfo,
const QKnxNetIpDib &extendedHardware);
+#endif
+
+ QKnxNetIpServerInfo(const QKnxNetIpHpai &hpai,
+ const QKnxNetIpDib &hardware,
+ const QKnxNetIpDib &services,
+ const QHostAddress &hostAddress,
+ const QNetworkInterface &iinterface,
+ const QKnxNetIpDib &tunnelingInfo = {},
+ const QKnxNetIpDib &extendedHardware = {});
+
explicit QKnxNetIpServerInfo(QKnxNetIpServerInfoPrivate &dd);
private:
diff --git a/src/knx/netip/qknxnetipserverinfo_p.h b/src/knx/netip/qknxnetipserverinfo_p.h
index 869d909..ca0fd50 100644
--- a/src/knx/netip/qknxnetipserverinfo_p.h
+++ b/src/knx/netip/qknxnetipserverinfo_p.h
@@ -42,11 +42,15 @@
//
#include <QtCore/qshareddata.h>
+
#include <QtKnx/qtknxglobal.h>
#include <QtKnx/qknxnetipdevicedib.h>
#include <QtKnx/qknxnetiphpai.h>
#include <QtKnx/qknxnetipservicefamiliesdib.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtNetwork/qnetworkinterface.h>
+
QT_BEGIN_NAMESPACE
struct Q_KNX_EXPORT QKnxNetIpServerInfoPrivate final : public QSharedData
@@ -59,6 +63,8 @@ struct Q_KNX_EXPORT QKnxNetIpServerInfoPrivate final : public QSharedData
QKnxNetIpDib services;
QKnxNetIpDib tunnelingInfo;
QKnxNetIpDib extendedHardware;
+ QHostAddress address;
+ QNetworkInterface iinterface;
};
QT_END_NAMESPACE
diff --git a/src/knx/qknxdevicemanagementframe.cpp b/src/knx/qknxdevicemanagementframe.cpp
index 562dd00..c36c5ca 100644
--- a/src/knx/qknxdevicemanagementframe.cpp
+++ b/src/knx/qknxdevicemanagementframe.cpp
@@ -339,6 +339,7 @@ void QKnxDeviceManagementFrame::setObjectInstance(quint8 instance)
{
if (instance < 1)
return;
+ d_ptr->m_serviceInformation.resize(3);
d_ptr->m_serviceInformation.set(2, instance);
}
@@ -359,8 +360,10 @@ QKnxInterfaceObjectProperty QKnxDeviceManagementFrame::property() const
*/
void QKnxDeviceManagementFrame::setProperty(QKnxInterfaceObjectProperty pid)
{
- if (QKnxInterfaceObjectProperty::isProperty(pid))
+ if (QKnxInterfaceObjectProperty::isProperty(pid)) {
+ d_ptr->m_serviceInformation.resize(4);
d_ptr->m_serviceInformation.set(3, quint8(pid));
+ }
}
/*!
@@ -384,6 +387,8 @@ void QKnxDeviceManagementFrame::setNumberOfElements(quint8 numOfElements)
{
if (numOfElements > 0x0f)
return;
+
+ d_ptr->m_serviceInformation.resize(5);
d_ptr->m_serviceInformation.set(4,
(d_ptr->m_serviceInformation.value(4) & 0x0f) | (numOfElements << 4));
}
@@ -475,8 +480,7 @@ void QKnxDeviceManagementFrame::setError(QKnxNetIpCemiServer::Error error)
switch (messageCode()) {
case MessageCode::PropertyReadConfirmation:
case MessageCode::PropertyWriteConfirmation: {
- if (d_ptr->m_serviceInformation.size() < 7)
- d_ptr->m_serviceInformation.resize(7);
+ d_ptr->m_serviceInformation.resize(7);
d_ptr->m_serviceInformation.set(6, quint8(error));
}
default:
@@ -523,8 +527,7 @@ void QKnxDeviceManagementFrame::setReturnCode(QKnxNetIpCemiServer::ReturnCode co
return;
}
- if (d_ptr->m_serviceInformation.size() < 6)
- d_ptr->m_serviceInformation.resize(6);
+ d_ptr->m_serviceInformation.resize(6);
d_ptr->m_serviceInformation.set(5, quint8(code));
}
diff --git a/src/knx/ssl/qknxsecurekey.cpp b/src/knx/ssl/qknxsecurekey.cpp
index 5aadbf9..8ca21ae 100644
--- a/src/knx/ssl/qknxsecurekey.cpp
+++ b/src/knx/ssl/qknxsecurekey.cpp
@@ -57,9 +57,9 @@ public:
}
#if QT_CONFIG(opensslv11)
- EVP_PKEY *m_evpPKey{ nullptr };
+ EVP_PKEY *m_evpPKey { nullptr };
#endif
- QKnxSecureKey::Type m_type{ QKnxSecureKey::Type::Invalid };
+ QKnxSecureKey::Type m_type { QKnxSecureKey::Type::Invalid };
};
/*!
diff --git a/src/knx/ssl/qsslsocket_openssl11_symbols_p.h b/src/knx/ssl/qsslsocket_openssl11_symbols_p.h
index 0fe4ad3..bb88cf1 100644
--- a/src/knx/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/knx/ssl/qsslsocket_openssl11_symbols_p.h
@@ -82,6 +82,7 @@ Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem();
int q_DSA_bits(DSA *a);
int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
int q_RSA_bits(RSA *a);
int q_OPENSSL_sk_num(OPENSSL_STACK *a);
@@ -136,7 +137,6 @@ unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session)
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nullptr)
int q_EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
-int q_EVP_PKEY_up_ref(EVP_PKEY *pkey);
int q_EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
const unsigned char *pt, size_t ptlen);
diff --git a/src/knx/ssl/qsslsocket_openssl_symbols.cpp b/src/knx/ssl/qsslsocket_openssl_symbols.cpp
index c89cafb..d46f869 100644
--- a/src/knx/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/knx/ssl/qsslsocket_openssl_symbols.cpp
@@ -62,11 +62,11 @@
# include <QtCore/qlibrary.h>
#endif
#include <QtCore/qmutex.h>
-#include <private/qmutexpool_p.h>
#include <QtCore/qdatetime.h>
#if defined(Q_OS_UNIX)
#include <QtCore/qdir.h>
#endif
+#include <QtCore/private/qmemory_p.h>
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
#include <link.h>
#endif
@@ -142,47 +142,47 @@ void qsslSocketCannotResolveSymbolWarning(const char *functionName)
// Below are the functions first introduced in version 1.1:
-DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return 0, return)
+DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return nullptr, return)
DEFINEFUNC2(int, OPENSSL_init_ssl, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
DEFINEFUNC2(int, OPENSSL_init_crypto, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
-DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return 0, return)
-DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
+DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return nullptr, return)
+DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return)
DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return)
DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return)
+DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
DEFINEFUNC2(void, OPENSSL_sk_pop_free, OPENSSL_STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
-DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMMYARG)
DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return 0, return)
+DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return)
DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return)
DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
-DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return 0, return)
-DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return nullptr, return)
+DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return)
DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
-DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return 0, return)
+DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return nullptr, return)
DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG)
-DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return nullptr, return)
DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG)
DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
-DEFINEFUNC(const char *, OpenSSL_version, int a, a, return 0, return)
+DEFINEFUNC(const char *, OpenSSL_version, int a, a, return nullptr, return)
DEFINEFUNC(unsigned long, SSL_SESSION_get_ticket_lifetime_hint, const SSL_SESSION *session, session, return 0, return)
DEFINEFUNC4(void, DH_get0_pqg, const DH *dh, dh, const BIGNUM **p, p, const BIGNUM **q, q, const BIGNUM **g, g, return, DUMMYARG)
DEFINEFUNC(int, DH_bits, DH *dh, dh, return 0, return)
DEFINEFUNC2(int, EVP_PKEY_set_type, EVP_PKEY *pkey, pkey, int type, type, return 0, return)
DEFINEFUNC3(int, EVP_PKEY_set1_tls_encodedpoint, EVP_PKEY *pkey, pkey, const unsigned char *pt, pt, size_t ptlen, ptlen, return 0, return)
-DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *pkey, pkey, return 0, return)
DEFINEFUNC2(EVP_PKEY *, d2i_PrivateKey_bio, BIO *bp, bp, EVP_PKEY **a, a, return nullptr, return)
DEFINEFUNC2(int, i2d_PUBKEY_bio, BIO *bp, bp, EVP_PKEY *pkey, pkey, return 0, return)
@@ -198,15 +198,15 @@ DEFINEFUNC4(EVP_PKEY *, EVP_PKEY_new_raw_private_key, int type, type, ENGINE *e,
// Functions below are either deprecated or removed in OpenSSL >= 1.1:
-DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
+DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return nullptr, return)
#ifdef SSLEAY_MACROS
-DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
+DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return nullptr, return)
#endif
-DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return 0, return)
+DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return nullptr, return)
DEFINEFUNC(void, ERR_clear_error, DUMMYARG, DUMMYARG, return, DUMMYARG)
-DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
-DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
+DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return nullptr, return)
+DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return)
DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
@@ -217,23 +217,23 @@ DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
#ifdef SSLEAY_MACROS
-DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
-DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
+DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return nullptr, return)
+DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return nullptr, return)
#endif // SSLEAY_MACROS
DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
+DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return nullptr, return)
#else
-DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG)
DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
+DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return nullptr, return)
#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
@@ -245,49 +245,49 @@ DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#else
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return nullptr, return)
#ifdef SSLEAY_MACROS
DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
@@ -295,17 +295,17 @@ DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, retur
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return)
#endif
-DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
-DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
+DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return nullptr, return)
+DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return)
+DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return nullptr, return)
#endif
#endif
-DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
-DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
+DEFINEFUNC(const char *, SSLeay_version, int a, a, return nullptr, return)
#endif // QT_CONFIG(opensslv11)
@@ -314,22 +314,22 @@ DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return)
DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
-DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
+DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return nullptr, return)
DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
DEFINEFUNC2(BN_ULONG, BN_mod_word, const BIGNUM *a, a, BN_ULONG w, w, return static_cast<BN_ULONG>(-1), return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return 0, return)
+DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return nullptr, return)
DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return)
#endif
-DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
-DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
+DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return nullptr, return)
DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, void, DUMMYARG, return 0, return)
+DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, void, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, EVP_CIPHER_CTX_free, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return)
DEFINEFUNC2(int, EVP_CIPHER_CTX_set_key_length, EVP_CIPHER_CTX *ctx, ctx, int keylen, keylen, return 0, return)
@@ -338,13 +338,13 @@ DEFINEFUNC6(int, EVP_CipherInit_ex, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *
DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return)
DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return)
#ifndef OPENSSL_NO_DES
-DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_RC2
-DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
@@ -352,16 +352,16 @@ DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
#endif
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
-DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
-DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
+DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
+DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return 0, return)
+DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return)
#endif
-DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
-DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
-DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return 0, return)
+DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return nullptr, return)
+DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return nullptr, return)
DEFINEFUNC(int, OBJ_sn2nid, const char *s, s, return 0, return)
DEFINEFUNC(int, OBJ_ln2nid, const char *s, s, return 0, return)
DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, return -1, return)
@@ -370,24 +370,24 @@ DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d,
DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
#ifndef SSLEAY_MACROS
-DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#endif
-DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#endif
#endif // !SSLEAY_MACROS
-DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#endif
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
@@ -396,20 +396,20 @@ DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, ret
#endif
DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
-DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return)
DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return)
-DEFINEFUNC3(char *, SSL_CIPHER_description, const SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
+DEFINEFUNC3(char *, SSL_CIPHER_description, const SSL_CIPHER *a, a, char *b, b, int c, c, return nullptr, return)
DEFINEFUNC2(int, SSL_CIPHER_get_bits, const SSL_CIPHER *a, a, int *b, b, return 0, return)
DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return 0, return)
+DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return nullptr, return)
#else
-DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
+DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return nullptr, return)
#endif
DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return)
DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return)
@@ -420,9 +420,9 @@ DEFINEFUNC3(int, SSL_CTX_use_certificate_file, SSL_CTX *a, a, const char *b, b,
DEFINEFUNC2(int, SSL_CTX_use_PrivateKey, SSL_CTX *a, a, EVP_PKEY *b, b, return -1, return)
DEFINEFUNC2(int, SSL_CTX_use_RSAPrivateKey, SSL_CTX *a, a, RSA *b, b, return -1, return)
DEFINEFUNC3(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
-DEFINEFUNC(X509_STORE *, SSL_CTX_get_cert_store, const SSL_CTX *a, a, return 0, return)
+DEFINEFUNC(X509_STORE *, SSL_CTX_get_cert_store, const SSL_CTX *a, a, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
-DEFINEFUNC(SSL_CONF_CTX *, SSL_CONF_CTX_new, DUMMYARG, DUMMYARG, return 0, return);
+DEFINEFUNC(SSL_CONF_CTX *, SSL_CONF_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return);
DEFINEFUNC(void, SSL_CONF_CTX_free, SSL_CONF_CTX *a, a, return ,return);
DEFINEFUNC2(void, SSL_CONF_CTX_set_ssl_ctx, SSL_CONF_CTX *a, a, SSL_CTX *b, b, return, return);
DEFINEFUNC2(unsigned int, SSL_CONF_CTX_set_flags, SSL_CONF_CTX *a, a, unsigned int b, b, return 0, return);
@@ -430,23 +430,23 @@ DEFINEFUNC(int, SSL_CONF_CTX_finish, SSL_CONF_CTX *a, a, return 0, return);
DEFINEFUNC3(int, SSL_CONF_cmd, SSL_CONF_CTX *a, a, const char *b, b, const char *c, c, return 0, return);
#endif
DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
-DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
+DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
#else
-DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
+DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
#endif
DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
-DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return)
-DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
+DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
// 0.9.8 broke SC and BC by changing this function's signature.
DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
#else
DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
#endif
-DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return)
+DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return)
DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG)
@@ -455,8 +455,8 @@ DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return)
DEFINEFUNC2(int, SSL_set_session, SSL* to, to, SSL_SESSION *session, session, return -1, return)
DEFINEFUNC(void, SSL_SESSION_free, SSL_SESSION *ses, ses, return, DUMMYARG)
-DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return 0, return)
-DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return)
+DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return nullptr, return)
+DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC3(int, SSL_set_ex_data, SSL *ssl, ssl, int idx, idx, void *arg, arg, return 0, return)
DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return NULL, return)
@@ -470,18 +470,18 @@ DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, re
DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
DEFINEFUNC4(int, X509_digest, const X509 *x509, x509, const EVP_MD *type, type, unsigned char *md, md, unsigned int *len, len, return -1, return)
#ifndef SSLEAY_MACROS
-DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
+DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return nullptr, return)
#endif
DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
-DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
+DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
-DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
+DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return nullptr, return)
DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
-DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return)
-DEFINEFUNC(const X509V3_EXT_METHOD *, X509V3_EXT_get, X509_EXTENSION *a, a, return 0, return)
-DEFINEFUNC(void *, X509V3_EXT_d2i, X509_EXTENSION *a, a, return 0, return)
+DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return nullptr, return)
+DEFINEFUNC(const X509V3_EXT_METHOD *, X509V3_EXT_get, X509_EXTENSION *a, a, return nullptr, return)
+DEFINEFUNC(void *, X509V3_EXT_d2i, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(int, X509_EXTENSION_get_critical, X509_EXTENSION *a, a, return 0, return)
-DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, return 0, return)
+DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(void, BASIC_CONSTRAINTS_free, BASIC_CONSTRAINTS *a, a, return, DUMMYARG)
DEFINEFUNC(void, AUTHORITY_KEYID_free, AUTHORITY_KEYID *a, a, return, DUMMYARG)
DEFINEFUNC(void, GENERAL_NAME_free, GENERAL_NAME *a, a, return, DUMMYARG)
@@ -491,28 +491,28 @@ DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0
DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, return)
#endif
DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return)
-DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
-DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
-DEFINEFUNC(ASN1_INTEGER *, X509_get_serialNumber, X509 *a, a, return 0, return)
+DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return nullptr, return)
+DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return nullptr, return)
+DEFINEFUNC(ASN1_INTEGER *, X509_get_serialNumber, X509 *a, a, return nullptr, return)
DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
-DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
-DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return)
-DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return)
-DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
+DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return nullptr, return)
+DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return nullptr, return)
+DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return nullptr, return)
+DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return nullptr, return)
DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
-DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(int, X509_STORE_add_cert, X509_STORE *a, a, X509 *b, b, return 0, return)
DEFINEFUNC(void, X509_STORE_CTX_free, X509_STORE_CTX *a, a, return, DUMMYARG)
DEFINEFUNC4(int, X509_STORE_CTX_init, X509_STORE_CTX *a, a, X509_STORE *b, b, X509 *c, c, STACK_OF(X509) *d, d, return -1, return)
DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return)
-DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return 0, return)
-DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return nullptr, return)
+DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
-DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
DEFINEFUNC6(int, SSL_select_next_proto, unsigned char **out, out, unsigned char *outlen, outlen,
const unsigned char *in, in, unsigned int inlen, inlen,
@@ -539,15 +539,15 @@ DEFINEFUNC3(void, SSL_get0_alpn_selected, const SSL *s, s, const unsigned char *
unsigned *len, len, return, DUMMYARG)
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
-DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
-DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
-DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return)
+DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return 0, return)
-DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return)
+DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return nullptr, return)
+DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return nullptr, return)
DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG)
DEFINEFUNC2(size_t, EC_get_builtin_curves, EC_builtin_curve * r, r, size_t nitems, nitems, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
@@ -557,7 +557,7 @@ DEFINEFUNC(int, EC_curve_nist2nid, const char *name, name, return 0, return)
DEFINEFUNC5(int, PKCS12_parse, PKCS12 *p12, p12, const char *pass, pass, EVP_PKEY **pkey, pkey, \
X509 **cert, cert, STACK_OF(X509) **ca, ca, return 1, return);
-DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return 0, return);
+DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return nullptr, return);
DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
@@ -584,8 +584,8 @@ DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
#endif
#define RESOLVEFUNC(func) \
- if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
- && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
+ if (!(_q_##func = _q_PTR_##func(libs.ssl->resolve(#func))) \
+ && !(_q_##func = _q_PTR_##func(libs.crypto->resolve(#func)))) \
qsslSocketCannotResolveSymbolWarning(#func);
#if !defined QT_LINKED_OPENSSL
@@ -664,7 +664,7 @@ static QStringList libraryPathList()
// search in .app/Contents/Frameworks
UInt32 packageType;
- CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, NULL);
+ CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, nullptr);
if (packageType == FOUR_CHAR_CODE('APPL')) {
QUrl bundleUrl = QUrl::fromCFURL(QCFType<CFURLRef>(CFBundleCopyBundleURL(CFBundleGetMainBundle())));
QUrl frameworksUrl = QUrl::fromCFURL(QCFType<CFURLRef>(CFBundleCopyPrivateFrameworksURL(CFBundleGetMainBundle())));
@@ -684,7 +684,7 @@ static QStringList libraryPathList()
// discover paths of already loaded libraries
QSet<QString> loadedPaths;
dl_iterate_phdr(dlIterateCallback, &loadedPaths);
- paths.append(loadedPaths.toList());
+ paths.append(loadedPaths.values());
#endif
return paths;
@@ -721,34 +721,31 @@ static QStringList findAllLibCrypto()
# endif
#ifdef Q_OS_WIN
-static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, QPair<QSystemLibrary*, QSystemLibrary*> &pair)
-{
- pair.first = 0;
- pair.second = 0;
- QSystemLibrary *ssleay32 = new QSystemLibrary(ssleay32LibName);
+struct LoadedOpenSsl {
+ std::unique_ptr<QSystemLibrary> ssl, crypto;
+};
+
+static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, LoadedOpenSsl &result)
+{
+ auto ssleay32 = qt_make_unique<QSystemLibrary>(ssleay32LibName);
if (!ssleay32->load(false)) {
- delete ssleay32;
return FALSE;
}
- QSystemLibrary *libeay32 = new QSystemLibrary(libeay32LibName);
+ auto libeay32 = qt_make_unique<QSystemLibrary>(libeay32LibName);
if (!libeay32->load(false)) {
- delete ssleay32;
- delete libeay32;
return FALSE;
}
- pair.first = ssleay32;
- pair.second = libeay32;
+ result.ssl = std::move(ssleay32);
+ result.crypto = std::move(libeay32);
return TRUE;
}
-static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
+static LoadedOpenSsl loadOpenSsl()
{
- QPair<QSystemLibrary*,QSystemLibrary*> pair;
- pair.first = 0;
- pair.second = 0;
+ LoadedOpenSsl result;
#if QT_CONFIG(opensslv11)
// With OpenSSL 1.1 the names have changed to libssl-1_1(-x64) and libcrypto-1_1(-x64), for builds using
@@ -761,7 +758,7 @@ static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
#endif // !Q_PROCESSOR_x86_64
tryToLoadOpenSslWin32Library(QLatin1String("libssl-1_1" QT_SSL_SUFFIX),
- QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), pair);
+ QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), result);
#undef QT_SSL_SUFFIX
@@ -770,28 +767,30 @@ static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
// When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'.
// When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version)
// The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007)
- if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) {
- if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) {
- if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) {
- tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair);
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), result)) {
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), result)) {
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), result)) {
+ tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), result);
}
}
}
#endif // !QT_CONFIG(opensslv11)
- return pair;
+ return result;
}
#else
-static QPair<QLibrary*, QLibrary*> loadOpenSsl()
+struct LoadedOpenSsl {
+ std::unique_ptr<QLibrary> ssl, crypto;
+};
+
+static LoadedOpenSsl loadOpenSsl()
{
- QPair<QLibrary*,QLibrary*> pair;
+ LoadedOpenSsl result = {qt_make_unique<QLibrary>(), qt_make_unique<QLibrary>()};
# if defined(Q_OS_UNIX)
- QLibrary *&libssl = pair.first;
- QLibrary *&libcrypto = pair.second;
- libssl = new QLibrary;
- libcrypto = new QLibrary;
+ QLibrary * const libssl = result.ssl.get();
+ QLibrary * const libcrypto = result.crypto.get();
// Try to find the libssl library on the system.
//
@@ -809,6 +808,17 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
// reason, we will search a few common paths (see findAllLibSsl() above) in hopes
// we find one that works.
//
+ // If that fails, for OpenSSL 1.0 we also try some fallbacks -- look up
+ // libssl.so with a hardcoded soname. The reason is QTBUG-68156: the binary
+ // builds of Qt happen (at the time of this writing) on RHEL machines,
+ // which change SHLIB_VERSION_NUMBER to a non-portable string. When running
+ // those binaries on the target systems, this code won't pick up
+ // libssl.so.MODIFIED_SHLIB_VERSION_NUMBER because it doesn't exist there.
+ // Given that the only 1.0 supported release (at the time of this writing)
+ // is 1.0.2, with soname "1.0.0", give that a try too. Note that we mandate
+ // OpenSSL >= 1.0.0 with a configure-time check, and OpenSSL has kept binary
+ // compatibility between 1.0.0 and 1.0.2.
+ //
// It is important, however, to try the canonical name and the unversioned name
// without going through the loop. By not specifying a path, we let the system
// dlopen(3) function determine it for us. This will include any DT_RUNPATH or
@@ -824,11 +834,32 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
if (libcrypto->load() && libssl->load()) {
// libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
- return pair;
+ return result;
} else {
libssl->unload();
libcrypto->unload();
}
+
+#if !QT_CONFIG(opensslv11)
+ // first-and-half attempts: for OpenSSL 1.0 try to load some hardcoded sonames:
+ // - "1.0.0" is the official upstream one
+ // - "1.0.2" is found on some distributions (e.g. Debian) that patch OpenSSL
+ static const QLatin1String fallbackSonames[] = {
+ QLatin1String("1.0.0"),
+ QLatin1String("1.0.2")
+ };
+
+ for (auto fallbackSoname : fallbackSonames) {
+ libssl->setFileNameAndVersion(QLatin1String("ssl"), fallbackSoname);
+ libcrypto->setFileNameAndVersion(QLatin1String("crypto"), fallbackSoname);
+ if (libcrypto->load() && libssl->load()) {
+ return result;
+ } else {
+ libssl->unload();
+ libcrypto->unload();
+ }
+ }
+#endif
#endif
#ifndef Q_OS_DARWIN
@@ -842,7 +873,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
if (libcrypto->load() && libssl->load()) {
// libssl.so.0 and libcrypto.so.0 found
- return pair;
+ return result;
} else {
libssl->unload();
libcrypto->unload();
@@ -867,7 +898,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
if (libssl->load()) {
// libssl.so.x and libcrypto.so.x found
- return pair;
+ return result;
} else {
libssl->unload();
}
@@ -877,41 +908,33 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
}
// failed to load anything
- delete libssl;
- delete libcrypto;
- libssl = libcrypto = 0;
- return pair;
+ result = {};
+ return result;
# else
// not implemented for this platform yet
- return pair;
+ return result;
# endif
}
#endif
+static QBasicMutex symbolResolveMutex;
+static QBasicAtomicInt symbolsResolved = Q_BASIC_ATOMIC_INITIALIZER(false);
+static bool triedToResolveSymbols = false;
+
bool q_resolveOpenSslSymbols()
{
- static bool symbolsResolved = false;
- static bool triedToResolveSymbols = false;
-#ifndef QT_NO_THREAD
-#if QT_CONFIG(opensslv11)
- QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl));
-#else
- QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
-#endif
-#endif
- if (symbolsResolved)
+ if (symbolsResolved.loadAcquire())
+ return true;
+ QMutexLocker locker(&symbolResolveMutex);
+ if (symbolsResolved.loadRelaxed())
return true;
if (triedToResolveSymbols)
return false;
triedToResolveSymbols = true;
-#ifdef Q_OS_WIN
- QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
-#else
- QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
-#endif
- if (!libs.first || !libs.second)
+ LoadedOpenSsl libs = loadOpenSsl();
+ if (!libs.ssl || !libs.crypto)
// failed to load them
return false;
@@ -921,6 +944,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OPENSSL_init_crypto)
RESOLVEFUNC(ASN1_STRING_get0_data)
RESOLVEFUNC(EVP_CIPHER_CTX_reset)
+ RESOLVEFUNC(EVP_PKEY_up_ref)
RESOLVEFUNC(EVP_PKEY_base_id)
RESOLVEFUNC(RSA_bits)
RESOLVEFUNC(OPENSSL_sk_new_null)
@@ -951,8 +975,6 @@ bool q_resolveOpenSslSymbols()
if (!_q_OpenSSL_version) {
// Apparently, we were built with OpenSSL 1.1 enabled but are now using
// a wrong library.
- delete libs.first;
- delete libs.second;
qCWarning(lcSsl, "Incompatible version of OpenSSL");
return false;
}
@@ -962,7 +984,6 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DSA_bits)
RESOLVEFUNC(EVP_PKEY_set_type)
- RESOLVEFUNC(EVP_PKEY_up_ref)
RESOLVEFUNC(EVP_PKEY_set1_tls_encodedpoint)
RESOLVEFUNC(d2i_PrivateKey_bio)
@@ -1047,8 +1068,6 @@ bool q_resolveOpenSslSymbols()
// OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to
// resolve this symbol as a failure to resolve symbols.
// The right operand of '||' above is ... a bit of paranoia.
- delete libs.first;
- delete libs.second;
qCWarning(lcSsl, "Incompatible version of OpenSSL");
return false;
}
@@ -1306,9 +1325,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_sha256)
#endif
- symbolsResolved = true;
- delete libs.first;
- delete libs.second;
+ symbolsResolved.storeRelease(true);
return true;
}
#endif // QT_CONFIG(library)
diff --git a/tests/auto/qknxnetipcri/tst_qknxnetipcri.cpp b/tests/auto/qknxnetipcri/tst_qknxnetipcri.cpp
index c86c3af..2deae37 100644
--- a/tests/auto/qknxnetipcri/tst_qknxnetipcri.cpp
+++ b/tests/auto/qknxnetipcri/tst_qknxnetipcri.cpp
@@ -200,7 +200,7 @@ void tst_QKnxNetIpCri::testAdditionalData()
.create();
frame2 = QKnxNetIpCriProxy::builder()
.setConnectionType(QKnxNetIp::ConnectionType::Tunnel)
- .setAdditionalData(QKnxByteArray{ quint8(QKnxNetIp::TunnelLayer::Link), 0x00 }
+ .setAdditionalData(QKnxByteArray { quint8(QKnxNetIp::TunnelLayer::Link), 0x00 }
+ address.bytes())
.create();
QCOMPARE(frame, frame2);
diff --git a/tests/auto/qknxnetiprouter/tst_qknxnetiprouter.cpp b/tests/auto/qknxnetiprouter/tst_qknxnetiprouter.cpp
index 3474b61..47a002b 100644
--- a/tests/auto/qknxnetiprouter/tst_qknxnetiprouter.cpp
+++ b/tests/auto/qknxnetiprouter/tst_qknxnetiprouter.cpp
@@ -327,7 +327,7 @@ QKnxNetIpFrame dummyRoutingIndication(QKnxAddress dst, quint8 hopCount = 6)
.setMedium(QKnx::MediumType::NetIP)
.createFrame();
return QKnxNetIpRoutingIndicationProxy::builder()
- .setLinkLayerFrame(frame)
+ .setCemi(frame)
.create();
}
diff --git a/tests/auto/qknxtunnelframefactory/tst_qknxtunnelframefactory.cpp b/tests/auto/qknxtunnelframefactory/tst_qknxtunnelframefactory.cpp
index 6a42544..af06c8f 100644
--- a/tests/auto/qknxtunnelframefactory/tst_qknxtunnelframefactory.cpp
+++ b/tests/auto/qknxtunnelframefactory/tst_qknxtunnelframefactory.cpp
@@ -300,7 +300,7 @@ void tst_QKnxLinkLayerFrameBuilder::testMemoryRead()
.create();
QCOMPARE(extctr.destinationAddressType(), QKnxAddress::Type::Individual);
auto byts = extctr.bytes();
- QCOMPARE(extctr.bytes(), QKnxByteArray{0x60});
+ QCOMPARE(extctr.bytes(), QKnxByteArray { 0x60 });
auto frame = QKnxLinkLayerFrame::builder().setControlField(ctrl).setExtendedControlField(extctr)
.setTpdu(tpdu).setDestinationAddress(destination).setSourceAddress(source)