diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-17 09:41:36 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-17 09:41:36 +0200 |
commit | 02164e0288f714f1ea93afb32548548686773d1d (patch) | |
tree | d7ed16267f7659af63e78c8de8915ed0208b598b /src/network | |
parent | 4a7e7103e713448c05d9d30cab8b7e52406b46a6 (diff) | |
parent | 6f27bb135246b7fe9d11ba58e05d2b7661bc2080 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Change-Id: Ia1da879a7bd8f71a649661a1844144dd67d60b3a
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/bearer/bearer.pri | 3 | ||||
-rw-r--r-- | src/network/bearer/qbearerengine_impl_p.h | 85 | ||||
-rw-r--r-- | src/network/bearer/qnetworksession_impl.cpp | 439 | ||||
-rw-r--r-- | src/network/bearer/qnetworksession_impl_p.h | 134 |
4 files changed, 661 insertions, 0 deletions
diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri index d58d5ec168..bcb7a5971e 100644 --- a/src/network/bearer/bearer.pri +++ b/src/network/bearer/bearer.pri @@ -6,11 +6,14 @@ HEADERS += bearer/qnetworkconfiguration.h \ bearer/qnetworkconfigmanager_p.h \ bearer/qnetworkconfiguration_p.h \ bearer/qnetworksession_p.h \ + bearer/qnetworksession_impl_p.h \ bearer/qbearerengine_p.h \ + bearer/qbearerengine_impl_p.h \ bearer/qbearerplugin_p.h \ bearer/qsharednetworksession_p.h SOURCES += bearer/qnetworksession.cpp \ + bearer/qnetworksession_impl.cpp \ bearer/qnetworkconfigmanager.cpp \ bearer/qnetworkconfiguration.cpp \ bearer/qnetworkconfigmanager_p.cpp \ diff --git a/src/network/bearer/qbearerengine_impl_p.h b/src/network/bearer/qbearerengine_impl_p.h new file mode 100644 index 0000000000..4221b73276 --- /dev/null +++ b/src/network/bearer/qbearerengine_impl_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or 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.GPL2 and 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBEARERENGINE_IMPL_H +#define QBEARERENGINE_IMPL_H + +#include <QtNetwork/private/qbearerengine_p.h> + +#ifndef QT_NO_BEARERMANAGEMENT + +QT_BEGIN_NAMESPACE + +class Q_NETWORK_EXPORT QBearerEngineImpl : public QBearerEngine +{ + Q_OBJECT + +public: + enum ConnectionError { + InterfaceLookupError = 0, + ConnectError, + OperationNotSupported, + DisconnectionError, + }; + + QBearerEngineImpl(QObject *parent = nullptr) : QBearerEngine(parent) {} + ~QBearerEngineImpl() {} + + virtual void connectToId(const QString &id) = 0; + virtual void disconnectFromId(const QString &id) = 0; + + virtual QString getInterfaceFromId(const QString &id) = 0; + + virtual QNetworkSession::State sessionStateForId(const QString &id) = 0; + + virtual quint64 bytesWritten(const QString &) { return Q_UINT64_C(0); } + virtual quint64 bytesReceived(const QString &) { return Q_UINT64_C(0); } + virtual quint64 startTime(const QString &) { return Q_UINT64_C(0); } + +Q_SIGNALS: + void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error); +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QBearerEngineImpl::ConnectionError) + +#endif // QT_NO_BEARERMANAGEMENT + +#endif // QBEARERENGINE_IMPL_H diff --git a/src/network/bearer/qnetworksession_impl.cpp b/src/network/bearer/qnetworksession_impl.cpp new file mode 100644 index 0000000000..4b8631d4db --- /dev/null +++ b/src/network/bearer/qnetworksession_impl.cpp @@ -0,0 +1,439 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or 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.GPL2 and 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// see comment in ../platformdefs_win.h. +#define WIN32_LEAN_AND_MEAN 1 + +#include "qnetworksession_impl_p.h" +#include "qbearerengine_impl_p.h" + +#include <QtNetwork/qnetworksession.h> +#include <QtNetwork/private/qnetworkconfigmanager_p.h> + +#include <QtCore/qdatetime.h> +#include <QtCore/qdebug.h> +#include <QtCore/qmutex.h> +#include <QtCore/qstringlist.h> + +#ifndef QT_NO_BEARERMANAGEMENT + +QT_BEGIN_NAMESPACE + +static QBearerEngineImpl *getEngineFromId(const QString &id) +{ + QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); + if (priv) { + const auto engines = priv->engines(); + for (QBearerEngine *engine : engines) { + QBearerEngineImpl *engineImpl = qobject_cast<QBearerEngineImpl *>(engine); + if (engineImpl && engineImpl->hasIdentifier(id)) + return engineImpl; + } + } + + return 0; +} + +class QNetworkSessionManagerPrivate : public QObject +{ + Q_OBJECT + +public: + QNetworkSessionManagerPrivate(QObject *parent = 0) : QObject(parent) {} + ~QNetworkSessionManagerPrivate() {} + + inline void forceSessionClose(const QNetworkConfiguration &config) + { emit forcedSessionClose(config); } + +Q_SIGNALS: + void forcedSessionClose(const QNetworkConfiguration &config); +}; + +Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager); + +void QNetworkSessionPrivateImpl::syncStateWithInterface() +{ + connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)), + this, SLOT(forcedSessionClose(QNetworkConfiguration))); + + opened = false; + isOpen = false; + state = QNetworkSession::Invalid; + lastError = QNetworkSession::UnknownSessionError; + + qRegisterMetaType<QBearerEngineImpl::ConnectionError>(); + + switch (publicConfig.type()) { + case QNetworkConfiguration::InternetAccessPoint: + activeConfig = publicConfig; + engine = getEngineFromId(activeConfig.identifier()); + if (engine) { + qRegisterMetaType<QNetworkConfigurationPrivatePointer>(); + connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)), + this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)), + Qt::QueuedConnection); + connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)), + Qt::QueuedConnection); + } + break; + case QNetworkConfiguration::ServiceNetwork: + serviceConfig = publicConfig; + // Defer setting engine and signals until open(). + Q_FALLTHROUGH(); + case QNetworkConfiguration::UserChoice: + // Defer setting serviceConfig and activeConfig until open(). + Q_FALLTHROUGH(); + default: + engine = 0; + } + + networkConfigurationsChanged(); +} + +void QNetworkSessionPrivateImpl::open() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (!isOpen) { + if ((activeConfig.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) { + lastError = QNetworkSession::InvalidConfigurationError; + state = QNetworkSession::Invalid; + emit stateChanged(state); + emit QNetworkSessionPrivate::error(lastError); + return; + } + opened = true; + + if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active && + (activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { + state = QNetworkSession::Connecting; + emit stateChanged(state); + + engine->connectToId(activeConfig.identifier()); + } + + isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active; + if (isOpen) + emit quitPendingWaitsForOpened(); + } +} + +void QNetworkSessionPrivateImpl::close() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (isOpen) { + opened = false; + isOpen = false; + emit closed(); + } +} + +void QNetworkSessionPrivateImpl::stop() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else { + if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + state = QNetworkSession::Closing; + emit stateChanged(state); + + engine->disconnectFromId(activeConfig.identifier()); + + sessionManager()->forceSessionClose(activeConfig); + } + + opened = false; + isOpen = false; + emit closed(); + } +} + +void QNetworkSessionPrivateImpl::migrate() +{ +} + +void QNetworkSessionPrivateImpl::accept() +{ +} + +void QNetworkSessionPrivateImpl::ignore() +{ +} + +void QNetworkSessionPrivateImpl::reject() +{ +} + +#ifndef QT_NO_NETWORKINTERFACE +QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const +{ + if (!engine || state != QNetworkSession::Connected || !publicConfig.isValid()) + return QNetworkInterface(); + + QString iface = engine->getInterfaceFromId(activeConfig.identifier()); + if (iface.isEmpty()) + return QNetworkInterface(); + return QNetworkInterface::interfaceFromName(iface); +} +#endif + +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString &key) const +{ + if (key == QLatin1String("AutoCloseSessionTimeout")) { + if (engine && engine->requiresPolling() && + !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) { + return sessionTimeout >= 0 ? sessionTimeout * 10000 : -1; + } + } + + return QVariant(); +} + +void QNetworkSessionPrivateImpl::setSessionProperty(const QString &key, const QVariant &value) +{ + if (key == QLatin1String("AutoCloseSessionTimeout")) { + if (engine && engine->requiresPolling() && + !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) { + int timeout = value.toInt(); + if (timeout >= 0) { + connect(engine, SIGNAL(updateCompleted()), + this, SLOT(decrementTimeout()), Qt::UniqueConnection); + sessionTimeout = timeout / 10000; // convert to poll intervals + } else { + disconnect(engine, SIGNAL(updateCompleted()), this, SLOT(decrementTimeout())); + sessionTimeout = -1; + } + } + } +} + +QString QNetworkSessionPrivateImpl::errorString() const +{ + switch (lastError) { + case QNetworkSession::UnknownSessionError: + return tr("Unknown session error."); + case QNetworkSession::SessionAbortedError: + return tr("The session was aborted by the user or system."); + case QNetworkSession::OperationNotSupportedError: + return tr("The requested operation is not supported by the system."); + case QNetworkSession::InvalidConfigurationError: + return tr("The specified configuration cannot be used."); + case QNetworkSession::RoamingError: + return tr("Roaming was aborted or is not possible."); + default: + break; + } + + return QString(); +} + +QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const +{ + return lastError; +} + +quint64 QNetworkSessionPrivateImpl::bytesWritten() const +{ + if (engine && state == QNetworkSession::Connected) + return engine->bytesWritten(activeConfig.identifier()); + return Q_UINT64_C(0); +} + +quint64 QNetworkSessionPrivateImpl::bytesReceived() const +{ + if (engine && state == QNetworkSession::Connected) + return engine->bytesReceived(activeConfig.identifier()); + return Q_UINT64_C(0); +} + +quint64 QNetworkSessionPrivateImpl::activeTime() const +{ + if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0)) + return QDateTime::currentSecsSinceEpoch() - startTime; + return Q_UINT64_C(0); +} + +QNetworkSession::UsagePolicies QNetworkSessionPrivateImpl::usagePolicies() const +{ + return currentPolicies; +} + +void QNetworkSessionPrivateImpl::setUsagePolicies(QNetworkSession::UsagePolicies newPolicies) +{ + if (newPolicies != currentPolicies) { + currentPolicies = newPolicies; + emit usagePoliciesChanged(currentPolicies); + } +} + +void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() +{ + QNetworkSession::State oldState = state; + + const auto configs = serviceConfig.children(); + for (const QNetworkConfiguration &config : configs) { + if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) + continue; + + if (activeConfig != config) { + if (engine) { + disconnect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError))); + } + + activeConfig = config; + engine = getEngineFromId(activeConfig.identifier()); + + if (engine) { + connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)), + Qt::QueuedConnection); + } + emit newConfigurationActivated(); + } + + state = QNetworkSession::Connected; + if (state != oldState) + emit stateChanged(state); + + return; + } + + if (serviceConfig.children().isEmpty()) + state = QNetworkSession::NotAvailable; + else + state = QNetworkSession::Disconnected; + + if (state != oldState) + emit stateChanged(state); +} + +void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() +{ + if (!engine) + return; + + QNetworkSession::State oldState = state; + state = engine->sessionStateForId(activeConfig.identifier()); + + bool oldActive = isOpen; + isOpen = (state == QNetworkSession::Connected) ? opened : false; + + if (!oldActive && isOpen) + emit quitPendingWaitsForOpened(); + if (oldActive && !isOpen) + emit closed(); + + if (oldState != state) + emit stateChanged(state); +} + +void QNetworkSessionPrivateImpl::networkConfigurationsChanged() +{ + if (serviceConfig.isValid()) + updateStateFromServiceNetwork(); + else + updateStateFromActiveConfig(); + + if (engine) + startTime = engine->startTime(activeConfig.identifier()); +} + +void QNetworkSessionPrivateImpl::configurationChanged(QNetworkConfigurationPrivatePointer config) +{ + if (serviceConfig.isValid() && + (config->id == serviceConfig.identifier() || config->id == activeConfig.identifier())) { + updateStateFromServiceNetwork(); + } else if (config->id == activeConfig.identifier()) { + updateStateFromActiveConfig(); + } +} + +void QNetworkSessionPrivateImpl::forcedSessionClose(const QNetworkConfiguration &config) +{ + if (activeConfig == config) { + opened = false; + isOpen = false; + + emit closed(); + + lastError = QNetworkSession::SessionAbortedError; + emit QNetworkSessionPrivate::error(lastError); + } +} + +void QNetworkSessionPrivateImpl::connectionError(const QString &id, QBearerEngineImpl::ConnectionError error) +{ + if (activeConfig.identifier() == id) { + networkConfigurationsChanged(); + switch (error) { + case QBearerEngineImpl::OperationNotSupported: + lastError = QNetworkSession::OperationNotSupportedError; + opened = false; + break; + case QBearerEngineImpl::InterfaceLookupError: + case QBearerEngineImpl::ConnectError: + case QBearerEngineImpl::DisconnectionError: + default: + lastError = QNetworkSession::UnknownSessionError; + } + + emit QNetworkSessionPrivate::error(lastError); + } +} + +void QNetworkSessionPrivateImpl::decrementTimeout() +{ + if (--sessionTimeout <= 0) { + disconnect(engine, SIGNAL(updateCompleted()), this, SLOT(decrementTimeout())); + sessionTimeout = -1; + close(); + } +} + +QT_END_NAMESPACE + +#include "qnetworksession_impl.moc" + +#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qnetworksession_impl_p.h b/src/network/bearer/qnetworksession_impl_p.h new file mode 100644 index 0000000000..b174760152 --- /dev/null +++ b/src/network/bearer/qnetworksession_impl_p.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or 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.GPL2 and 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKSESSION_IMPL_H +#define QNETWORKSESSION_IMPL_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qbearerengine_impl_p.h" + +#include <QtNetwork/private/qnetworkconfigmanager_p.h> +#include <QtNetwork/private/qnetworksession_p.h> + +#ifndef QT_NO_BEARERMANAGEMENT + +QT_BEGIN_NAMESPACE + +class QBearerEngineImpl; + +class Q_NETWORK_EXPORT QNetworkSessionPrivateImpl : public QNetworkSessionPrivate +{ + Q_OBJECT + +public: + QNetworkSessionPrivateImpl() + : engine(nullptr), startTime(0), lastError(QNetworkSession::UnknownSessionError), sessionTimeout(-1), currentPolicies(QNetworkSession::NoPolicy), opened(false) + {} + ~QNetworkSessionPrivateImpl() + {} + + //called by QNetworkSession constructor and ensures + //that the state is immediately updated (w/o actually opening + //a session). Also this function should take care of + //notification hooks to discover future state changes. + void syncStateWithInterface() override; + +#ifndef QT_NO_NETWORKINTERFACE + QNetworkInterface currentInterface() const override; +#endif + QVariant sessionProperty(const QString& key) const override; + void setSessionProperty(const QString& key, const QVariant& value) override; + + void open() override; + void close() override; + void stop() override; + void migrate() override; + void accept() override; + void ignore() override; + void reject() override; + + QString errorString() const override; //must return translated string + QNetworkSession::SessionError error() const override; + + quint64 bytesWritten() const override; + quint64 bytesReceived() const override; + quint64 activeTime() const override; + + QNetworkSession::UsagePolicies usagePolicies() const override; + void setUsagePolicies(QNetworkSession::UsagePolicies) override; + +private Q_SLOTS: + void networkConfigurationsChanged(); + void configurationChanged(QNetworkConfigurationPrivatePointer config); + void forcedSessionClose(const QNetworkConfiguration &config); + void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error); + void decrementTimeout(); + +private: + void updateStateFromServiceNetwork(); + void updateStateFromActiveConfig(); + +private: + QBearerEngineImpl *engine; + + quint64 startTime; + + QNetworkSession::SessionError lastError; + + int sessionTimeout; + QNetworkSession::UsagePolicies currentPolicies; + + bool opened; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_BEARERMANAGEMENT + +#endif // QNETWORKSESSION_IMPL_H |