summaryrefslogtreecommitdiffstats
path: root/src/network/bearer/qnetworksession_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/bearer/qnetworksession_p.cpp')
-rw-r--r--src/network/bearer/qnetworksession_p.cpp542
1 files changed, 542 insertions, 0 deletions
diff --git a/src/network/bearer/qnetworksession_p.cpp b/src/network/bearer/qnetworksession_p.cpp
new file mode 100644
index 0000000..c6f9833
--- /dev/null
+++ b/src/network/bearer/qnetworksession_p.cpp
@@ -0,0 +1,542 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworksession_p.h"
+#include "qnetworksession.h"
+#include "qnetworksessionengine_p.h"
+#include "qgenericengine_p.h"
+
+#ifdef Q_OS_WIN
+#include "qnlaengine_win_p.h"
+#endif
+#ifdef Q_OS_WIN32
+#include "qnativewifiengine_win_p.h"
+#endif
+#ifdef Q_OS_DARWIN
+#include "qcorewlanengine_mac_p.h"
+#endif
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qmutex.h>
+
+#include <QtNetwork/qnetworkinterface.h>
+
+#if defined(BACKEND_NM)
+#include "qnmwifiengine_unix_p.h"
+#endif
+
+QTM_BEGIN_NAMESPACE
+
+#if defined(BACKEND_NM)
+static bool NetworkManagerAvailable()
+{
+ QDBusConnection dbusConnection = QDBusConnection::systemBus();
+ if (dbusConnection.isConnected()) {
+ QDBusConnectionInterface *dbiface = dbusConnection.interface();
+ QDBusReply<bool> reply = dbiface->isServiceRegistered("org.freedesktop.NetworkManager");
+ if (reply.isValid())
+ return reply.value();
+ }
+ return false;
+}
+#endif
+
+static QNetworkSessionEngine *getEngineFromId(const QString &id)
+{
+#ifdef Q_OS_WIN
+ QNlaEngine *nla = QNlaEngine::instance();
+ if (nla && nla->hasIdentifier(id))
+ return nla;
+#endif
+
+#ifdef Q_OS_WIN32
+ QNativeWifiEngine *nativeWifi = QNativeWifiEngine::instance();
+ if (nativeWifi && nativeWifi->hasIdentifier(id))
+ return nativeWifi;
+#endif
+
+#if defined(BACKEND_NM)
+ if(NetworkManagerAvailable()) {
+ QNmWifiEngine *nmwiifi = QNmWifiEngine::instance();
+ if (nmwiifi && nmwiifi->hasIdentifier(id))
+ return nmwiifi;
+ }
+#endif
+#ifdef Q_OS_DARWIN
+ QCoreWlanEngine *coreWifi = QCoreWlanEngine::instance();
+ if (coreWifi && coreWifi->hasIdentifier(id))
+ return coreWifi;
+
+#endif
+ QGenericEngine *generic = QGenericEngine::instance();
+ if (generic && generic->hasIdentifier(id))
+ return generic;
+
+ return 0;
+}
+
+class QNetworkSessionManagerPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QNetworkSessionManagerPrivate(QObject *parent = 0);
+ ~QNetworkSessionManagerPrivate();
+
+ void forceSessionClose(const QNetworkConfiguration &config);
+
+Q_SIGNALS:
+ void forcedSessionClose(const QNetworkConfiguration &config);
+};
+
+#include "qnetworksession_p.moc"
+
+Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager);
+
+QNetworkSessionManagerPrivate::QNetworkSessionManagerPrivate(QObject *parent)
+: QObject(parent)
+{
+}
+
+QNetworkSessionManagerPrivate::~QNetworkSessionManagerPrivate()
+{
+}
+
+void QNetworkSessionManagerPrivate::forceSessionClose(const QNetworkConfiguration &config)
+{
+ emit forcedSessionClose(config);
+}
+
+void QNetworkSessionPrivate::syncStateWithInterface()
+{
+ connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged()));
+ connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SLOT(configurationChanged(QNetworkConfiguration)));
+ connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)),
+ this, SLOT(forcedSessionClose(QNetworkConfiguration)));
+
+ opened = false;
+ state = QNetworkSession::Invalid;
+ lastError = QNetworkSession::UnknownSessionError;
+
+ qRegisterMetaType<QNetworkSessionEngine::ConnectionError>
+ ("QNetworkSessionEngine::ConnectionError");
+
+ switch (publicConfig.type()) {
+ case QNetworkConfiguration::InternetAccessPoint:
+ activeConfig = publicConfig;
+ engine = getEngineFromId(activeConfig.identifier());
+ if (engine) {
+ connect(engine, SIGNAL(connectionError(QString,QNetworkSessionEngine::ConnectionError)),
+ this, SLOT(connectionError(QString,QNetworkSessionEngine::ConnectionError)),
+ Qt::QueuedConnection);
+ }
+ break;
+ case QNetworkConfiguration::ServiceNetwork:
+ serviceConfig = publicConfig;
+ // Defer setting engine and signals until open().
+ // fall through
+ case QNetworkConfiguration::UserChoice:
+ // Defer setting serviceConfig and activeConfig until open().
+ // fall through
+ default:
+ engine = 0;
+ }
+
+ networkConfigurationsChanged();
+}
+
+void QNetworkSessionPrivate::open()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit q->error(lastError);
+ } else if (!isActive) {
+ if ((activeConfig.state() & QNetworkConfiguration::Discovered) !=
+ QNetworkConfiguration::Discovered) {
+ lastError =QNetworkSession::InvalidConfigurationError;
+ emit q->error(lastError);
+ return;
+ }
+ opened = true;
+
+ if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active &&
+ (activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
+ state = QNetworkSession::Connecting;
+ emit q->stateChanged(state);
+
+ engine->connectToId(activeConfig.identifier());
+ }
+
+ isActive = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
+ if (isActive)
+ emit quitPendingWaitsForOpened();
+ }
+}
+
+void QNetworkSessionPrivate::close()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit q->error(lastError);
+ } else if (isActive) {
+ opened = false;
+ isActive = false;
+ emit q->closed();
+ }
+}
+
+void QNetworkSessionPrivate::stop()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit q->error(lastError);
+ } else {
+ if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ state = QNetworkSession::Closing;
+ emit q->stateChanged(state);
+
+ engine->disconnectFromId(activeConfig.identifier());
+
+ sessionManager()->forceSessionClose(activeConfig);
+ }
+
+ opened = false;
+ isActive = false;
+ emit q->closed();
+ }
+}
+
+void QNetworkSessionPrivate::migrate()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+void QNetworkSessionPrivate::accept()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+void QNetworkSessionPrivate::ignore()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+void QNetworkSessionPrivate::reject()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+QNetworkInterface QNetworkSessionPrivate::currentInterface() const
+{
+ if (!publicConfig.isValid() || !engine || state != QNetworkSession::Connected)
+ return QNetworkInterface();
+
+ QString interface = engine->getInterfaceFromId(activeConfig.identifier());
+
+ if (interface.isEmpty())
+ return QNetworkInterface();
+ return QNetworkInterface::interfaceFromName(interface);
+}
+
+QVariant QNetworkSessionPrivate::sessionProperty(const QString& /*key*/) const
+{
+ return QVariant();
+}
+
+void QNetworkSessionPrivate::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/)
+{
+}
+
+QString QNetworkSessionPrivate::bearerName() const
+{
+ if (!publicConfig.isValid() || !engine)
+ return QString();
+
+ return engine->bearerName(activeConfig.identifier());
+}
+
+QString QNetworkSessionPrivate::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.");
+
+ }
+
+ return QString();
+}
+
+QNetworkSession::SessionError QNetworkSessionPrivate::error() const
+{
+ return lastError;
+}
+
+quint64 QNetworkSessionPrivate::bytesWritten() const
+{
+#if defined(BACKEND_NM)
+ if( state == QNetworkSession::Connected ) {
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ foreach (const QNetworkConfiguration &config, publicConfig.children()) {
+ if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ return static_cast<QNmWifiEngine*>(getEngineFromId(config.d->id))->sentDataForId(config.d->id);
+ }
+ }
+ } else {
+ return static_cast<QNmWifiEngine*>(getEngineFromId(activeConfig.d->id))->sentDataForId(activeConfig.d->id);
+ }
+ }
+#endif
+ return tx_data;
+}
+
+quint64 QNetworkSessionPrivate::bytesReceived() const
+{
+#if defined(BACKEND_NM)
+ if( state == QNetworkSession::Connected ) {
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ foreach (const QNetworkConfiguration &config, publicConfig.children()) {
+ if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ return static_cast<QNmWifiEngine*>(getEngineFromId(activeConfig.d->id))->receivedDataForId(config.d->id);
+ }
+ }
+ } else {
+ return static_cast<QNmWifiEngine*>(getEngineFromId(activeConfig.d->id))->receivedDataForId(activeConfig.d->id);
+ }
+ }
+#endif
+ return rx_data;
+}
+
+quint64 QNetworkSessionPrivate::activeTime() const
+{
+#if defined(BACKEND_NM)
+ if (startTime.isNull()) {
+ return 0;
+ }
+ if(state == QNetworkSession::Connected )
+ return startTime.secsTo(QDateTime::currentDateTime());
+#endif
+ return m_activeTime;
+}
+
+void QNetworkSessionPrivate::updateStateFromServiceNetwork()
+{
+ QNetworkSession::State oldState = state;
+
+ foreach (const QNetworkConfiguration &config, serviceConfig.children()) {
+ if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active)
+ continue;
+
+ if (activeConfig != config) {
+ if (engine) {
+ disconnect(engine, SIGNAL(connectionError(QString,QNetworkSessionEngine::ConnectionError)),
+ this, SLOT(connectionError(QString,QNetworkSessionEngine::ConnectionError)));
+ }
+
+ activeConfig = config;
+ engine = getEngineFromId(activeConfig.identifier());
+ if (engine) {
+ connect(engine, SIGNAL(connectionError(QString,QNetworkSessionEngine::ConnectionError)),
+ this, SLOT(connectionError(QString,QNetworkSessionEngine::ConnectionError)),
+ Qt::QueuedConnection);
+ }
+ emit q->newConfigurationActivated();
+ }
+
+ state = QNetworkSession::Connected;
+ if (state != oldState)
+ emit q->stateChanged(state);
+
+ return;
+ }
+
+ if (serviceConfig.children().isEmpty())
+ state = QNetworkSession::NotAvailable;
+ else
+ state = QNetworkSession::Disconnected;
+
+ if (state != oldState)
+ emit q->stateChanged(state);
+}
+
+void QNetworkSessionPrivate::updateStateFromActiveConfig()
+{
+ QNetworkSession::State oldState = state;
+
+ bool newActive = false;
+
+ if (!activeConfig.isValid()) {
+ state = QNetworkSession::Invalid;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ state = QNetworkSession::Connected;
+ newActive = opened;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
+ state = QNetworkSession::Disconnected;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+ state = QNetworkSession::NotAvailable;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) {
+ state = QNetworkSession::NotAvailable;
+ }
+
+ bool oldActive = isActive;
+ isActive = newActive;
+
+ if (!oldActive && isActive)
+ emit quitPendingWaitsForOpened();
+ if (oldActive && !isActive)
+ emit q->closed();
+
+ if (oldState != state)
+ emit q->stateChanged(state);
+}
+
+void QNetworkSessionPrivate::networkConfigurationsChanged()
+{
+ if (serviceConfig.isValid())
+ updateStateFromServiceNetwork();
+ else
+ updateStateFromActiveConfig();
+#if defined(BACKEND_NM)
+ setActiveTimeStamp();
+#endif
+}
+
+void QNetworkSessionPrivate::configurationChanged(const QNetworkConfiguration &config)
+{
+ if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig))
+ updateStateFromServiceNetwork();
+ else if (config == activeConfig)
+ updateStateFromActiveConfig();
+}
+
+void QNetworkSessionPrivate::forcedSessionClose(const QNetworkConfiguration &config)
+{
+ if (activeConfig == config) {
+ opened = false;
+ isActive = false;
+
+ emit q->closed();
+
+ lastError = QNetworkSession::SessionAbortedError;
+ emit q->error(lastError);
+ }
+}
+
+void QNetworkSessionPrivate::connectionError(const QString &id, QNetworkSessionEngine::ConnectionError error)
+{
+ if (activeConfig.identifier() == id) {
+ networkConfigurationsChanged();
+ switch (error) {
+ case QNetworkSessionEngine::OperationNotSupported:
+ lastError = QNetworkSession::OperationNotSupportedError;
+ opened = false;
+ break;
+ case QNetworkSessionEngine::InterfaceLookupError:
+ case QNetworkSessionEngine::ConnectError:
+ case QNetworkSessionEngine::DisconnectionError:
+ default:
+ lastError = QNetworkSession::UnknownSessionError;
+ }
+
+ emit quitPendingWaitsForOpened();
+ emit q->error(lastError);
+ }
+}
+
+#if defined(BACKEND_NM)
+void QNetworkSessionPrivate::setActiveTimeStamp()
+{
+ if(NetworkManagerAvailable()) {
+ startTime = QDateTime();
+ return;
+ }
+ QString connectionIdent = q->configuration().identifier();
+ QString interface = currentInterface().hardwareAddress().toLower();
+ QString devicePath = "/org/freedesktop/Hal/devices/net_" + interface.replace(":","_");
+
+ QString path;
+ QString serviceName;
+ QNetworkManagerInterface * ifaceD;
+ ifaceD = new QNetworkManagerInterface();
+
+ QList<QDBusObjectPath> connections = ifaceD->activeConnections();
+ foreach(QDBusObjectPath conpath, connections) {
+ QNetworkManagerConnectionActive *conDetails;
+ conDetails = new QNetworkManagerConnectionActive(conpath.path());
+ QDBusObjectPath connection = conDetails->connection();
+ serviceName = conDetails->serviceName();
+ QList<QDBusObjectPath> so = conDetails->devices();
+ foreach(QDBusObjectPath device, so) {
+
+ if(device.path() == devicePath) {
+ path = connection.path();
+ }
+ break;
+ }
+ }
+if(serviceName.isEmpty())
+ return;
+ QNetworkManagerSettings *settingsiface;
+ settingsiface = new QNetworkManagerSettings(serviceName);
+ QList<QDBusObjectPath> list = settingsiface->listConnections();
+ foreach(QDBusObjectPath path, list) {
+ QNetworkManagerSettingsConnection *sysIface;
+ sysIface = new QNetworkManagerSettingsConnection(serviceName, path.path());
+ startTime = QDateTime::fromTime_t(sysIface->getTimestamp());
+ // isActive = (publicConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
+ }
+ if(startTime.isNull())
+ startTime = QDateTime::currentDateTime();
+}
+#endif
+
+#include "moc_qnetworksession_p.cpp"
+QTM_END_NAMESPACE
+