From d792ec16f29a7cb34bada871127f701ba9480100 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Wed, 10 Feb 2010 15:08:29 +1000 Subject: Convert Maemo6 backend into plugin. --- src/network/bearer/bearer.pri | 52 +- src/network/bearer/qnetworkconfigmanager_maemo.cpp | 759 ------------- src/network/bearer/qnetworkconfigmanager_maemo_p.h | 141 --- src/network/bearer/qnetworkconfiguration.cpp | 2 +- src/network/bearer/qnetworkconfiguration_maemo_p.h | 122 -- src/network/bearer/qnetworkconfiguration_p.h | 2 +- src/network/bearer/qnetworksession.cpp | 5 - src/network/bearer/qnetworksession_maemo.cpp | 1164 -------------------- src/network/bearer/qnetworksession_maemo_p.h | 170 --- src/network/bearer/qnetworksession_p.h | 8 +- src/plugins/bearer/bearer.pro | 1 + src/plugins/bearer/icd/icd.pro | 22 + src/plugins/bearer/icd/main.cpp | 84 ++ src/plugins/bearer/icd/monitor.cpp | 116 ++ src/plugins/bearer/icd/monitor.h | 116 ++ src/plugins/bearer/icd/qicdengine.cpp | 416 +++++++ src/plugins/bearer/icd/qicdengine.h | 122 ++ src/plugins/bearer/icd/qnetworksession_impl.cpp | 1105 +++++++++++++++++++ src/plugins/bearer/icd/qnetworksession_impl.h | 147 +++ 19 files changed, 2148 insertions(+), 2406 deletions(-) delete mode 100644 src/network/bearer/qnetworkconfigmanager_maemo.cpp delete mode 100644 src/network/bearer/qnetworkconfigmanager_maemo_p.h delete mode 100644 src/network/bearer/qnetworkconfiguration_maemo_p.h delete mode 100644 src/network/bearer/qnetworksession_maemo.cpp delete mode 100644 src/network/bearer/qnetworksession_maemo_p.h create mode 100644 src/plugins/bearer/icd/icd.pro create mode 100644 src/plugins/bearer/icd/main.cpp create mode 100644 src/plugins/bearer/icd/monitor.cpp create mode 100644 src/plugins/bearer/icd/monitor.h create mode 100644 src/plugins/bearer/icd/qicdengine.cpp create mode 100644 src/plugins/bearer/icd/qicdengine.h create mode 100644 src/plugins/bearer/icd/qnetworksession_impl.cpp create mode 100644 src/plugins/bearer/icd/qnetworksession_impl.h diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri index 7dc9195..c03c615 100644 --- a/src/network/bearer/bearer.pri +++ b/src/network/bearer/bearer.pri @@ -1,50 +1,18 @@ # Qt network bearer management module -#DEFINES += BEARER_MANAGEMENT_DEBUG - HEADERS += bearer/qnetworkconfiguration.h \ bearer/qnetworksession.h \ - bearer/qnetworkconfigmanager.h + bearer/qnetworkconfigmanager.h \ + bearer/qnetworkconfigmanager_p.h \ + bearer/qnetworkconfiguration_p.h \ + bearer/qnetworksession_p.h \ + bearer/qbearerengine_p.h \ + bearer/qbearerplugin.h SOURCES += bearer/qnetworksession.cpp \ bearer/qnetworkconfigmanager.cpp \ - bearer/qnetworkconfiguration.cpp - -maemo { - CONFIG += link_pkgconfig - - exists(../debug) { - message("Enabling debug messages.") - DEFINES += BEARER_MANAGEMENT_DEBUG - } - - HEADERS += bearer/qnetworksession_maemo_p.h \ - bearer/qnetworkconfigmanager_maemo_p.h \ - bearer/qnetworkconfiguration_maemo_p.h - - SOURCES += bearer/qnetworkconfigmanager_maemo.cpp \ - bearer/qnetworksession_maemo.cpp - - documentation.path = $$QT_MOBILITY_PREFIX/doc - documentation.files = doc/html - - PKGCONFIG += glib-2.0 dbus-glib-1 gconf-2.0 osso-ic conninet - - CONFIG += create_pc create_prl - QMAKE_PKGCONFIG_REQUIRES = glib-2.0 dbus-glib-1 gconf-2.0 osso-ic conninet - pkgconfig.path = $$QT_MOBILITY_LIB/pkgconfig - pkgconfig.files = QtBearer.pc - - INSTALLS += pkgconfig documentation -} else { - HEADERS += bearer/qnetworkconfigmanager_p.h \ - bearer/qnetworkconfiguration_p.h \ - bearer/qnetworksession_p.h \ - bearer/qbearerengine_p.h \ - bearer/qbearerplugin.h - - SOURCES += bearer/qnetworkconfigmanager_p.cpp \ - bearer/qbearerengine.cpp \ - bearer/qbearerplugin.cpp -} + bearer/qnetworkconfiguration.cpp \ + bearer/qnetworkconfigmanager_p.cpp \ + bearer/qbearerengine.cpp \ + bearer/qbearerplugin.cpp diff --git a/src/network/bearer/qnetworkconfigmanager_maemo.cpp b/src/network/bearer/qnetworkconfigmanager_maemo.cpp deleted file mode 100644 index 96da30d..0000000 --- a/src/network/bearer/qnetworkconfigmanager_maemo.cpp +++ /dev/null @@ -1,759 +0,0 @@ -/**************************************************************************** -** -** 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 QtNetwork module of the Qt Toolkit. -** -** $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 - -#include "qnetworkconfigmanager_maemo_p.h" - -#include -#include - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -#define IAP "/system/osso/connectivity/IAP" -static int iap_prefix_len; -static void notify_iap(GConfClient *client, guint id, - GConfEntry *entry, gpointer user_data); - - -/* The IapAddTimer is a helper class that makes sure we update - * the configuration only after all gconf additions to certain - * iap are finished (after a certain timeout) - */ -class _IapAddTimer : public QObject -{ - Q_OBJECT - -public: - _IapAddTimer() {} - ~_IapAddTimer() - { - if (timer.isActive()) { - QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - timer.stop(); - } - } - - void add(QString& iap_id, QNetworkConfigurationManagerPrivate *d); - - QString iap_id; - QTimer timer; - QNetworkConfigurationManagerPrivate *d; - -public Q_SLOTS: - void timeout(); -}; - - -void _IapAddTimer::add(QString& id, QNetworkConfigurationManagerPrivate *d_ptr) -{ - iap_id = id; - d = d_ptr; - - if (timer.isActive()) { - QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - timer.stop(); - } - timer.setSingleShot(true); - QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - timer.start(1500); -} - - -void _IapAddTimer::timeout() -{ - d->addConfiguration(iap_id); -} - - -class IapAddTimer { - QHash timers; - -public: - IapAddTimer() {} - ~IapAddTimer() {} - - void add(QString& iap_id, QNetworkConfigurationManagerPrivate *d); - void del(QString& iap_id); - void removeAll(); -}; - - -void IapAddTimer::removeAll() -{ - QHashIterator i(timers); - while (i.hasNext()) { - i.next(); - _IapAddTimer *t = i.value(); - delete t; - } - timers.clear(); -} - - -void IapAddTimer::add(QString& iap_id, QNetworkConfigurationManagerPrivate *d) -{ - if (timers.contains(iap_id)) { - _IapAddTimer *iap = timers.value(iap_id); - iap->add(iap_id, d); - } else { - _IapAddTimer *iap = new _IapAddTimer; - iap->add(iap_id, d); - timers.insert(iap_id, iap); - } -} - -void IapAddTimer::del(QString& iap_id) -{ - if (timers.contains(iap_id)) { - _IapAddTimer *iap = timers.take(iap_id); - delete iap; - } -} - - -class IapMonitor -{ -public: - IapMonitor() : first_call(true) { } - friend void notify_iap(GConfClient *, guint, - GConfEntry *entry, gpointer user_data); - - void setup(QNetworkConfigurationManagerPrivate *d); - void cleanup(); - -private: - bool first_call; - - void iapAdded(const char *key, GConfEntry *entry); - void iapDeleted(const char *key, GConfEntry *entry); - - Maemo::IAPMonitor *iap; - QNetworkConfigurationManagerPrivate *d; - IapAddTimer timers; -}; - -Q_GLOBAL_STATIC(IapMonitor, iapMonitor); - - -/* Notify func that is called when IAP is added or deleted */ -static void notify_iap(GConfClient *, guint, - GConfEntry *entry, gpointer user_data) -{ - const char *key = gconf_entry_get_key(entry); - if (key && g_str_has_prefix(key, IAP)) { - IapMonitor *ptr = (IapMonitor *)user_data; - if (gconf_entry_get_value(entry)) { - ptr->iapAdded(key, entry); - } else { - ptr->iapDeleted(key, entry); - } - } -} - - -void IapMonitor::setup(QNetworkConfigurationManagerPrivate *d_ptr) -{ - if (first_call) { - d = d_ptr; - iap_prefix_len = strlen(IAP); - iap = new Maemo::IAPMonitor(notify_iap, (gpointer)this); - first_call = false; - } -} - - -void IapMonitor::cleanup() -{ - if (!first_call) { - delete iap; - timers.removeAll(); - first_call = true; - } -} - - -void IapMonitor::iapAdded(const char *key, GConfEntry * /*entry*/) -{ - //qDebug("Notify called for added element: %s=%s", gconf_entry_get_key(entry), gconf_value_to_string(gconf_entry_get_value(entry))); - - /* We cannot know when the IAP is fully added to gconf, so a timer is - * installed instead. When the timer expires we hope that IAP is added ok. - */ - QString iap_id = QString(key + iap_prefix_len + 1).section('/',0,0); - timers.add(iap_id, d); -} - - -void IapMonitor::iapDeleted(const char *key, GConfEntry * /*entry*/) -{ - //qDebug("Notify called for deleted element: %s", gconf_entry_get_key(entry)); - - /* We are only interested in IAP deletions so we skip the config entries - */ - if (strstr(key + iap_prefix_len + 1, "/")) { - //qDebug("Deleting IAP config %s", key+iap_prefix_len); - return; - } - - QString iap_id = key + iap_prefix_len + 1; - d->deleteConfiguration(iap_id); -} - - - -void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities() -{ - capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces; - capFlags |= QNetworkConfigurationManager::DataStatistics; - capFlags |= QNetworkConfigurationManager::ForcedRoaming; -} - - -static inline QString network_attrs_to_security(uint network_attrs) -{ - uint cap = 0; - nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */ - if (cap & WLANCOND_OPEN) - return "NONE"; - else if (cap & WLANCOND_WEP) - return "WEP"; - else if (cap & WLANCOND_WPA_PSK) - return "WPA_PSK"; - else if (cap & WLANCOND_WPA_EAP) - return "WPA_EAP"; - return ""; -} - - -struct SSIDInfo { - QString iap_id; - QString wlan_security; -}; - - -void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigurationPrivate *ptr) -{ - QNetworkConfiguration item; - item.d = ptr; - emit configurationChanged(item); -} - -void QNetworkConfigurationManagerPrivate::deleteConfiguration(QString& iap_id) -{ - /* Called when IAPs are deleted in gconf, in this case we do not scan - * or read all the IAPs from gconf because it might take too much power - * (multiple applications would need to scan and read all IAPs from gconf) - */ - if (accessPointConfigurations.contains(iap_id)) { - QExplicitlySharedDataPointer priv = accessPointConfigurations.take(iap_id); - if (priv.data()) { - priv->isValid = false; -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "was removed from storage."; -#endif - - QNetworkConfiguration item; - item.d = priv; - emit configurationRemoved(item); - configChanged(priv.data(), false); - } else - qWarning("Configuration not found for IAP %s", iap_id.toAscii().data()); - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data()); -#endif - } -} - - -uint32_t QNetworkConfigurationManagerPrivate::getNetworkAttrs(bool is_iap_id, - QString& iap_id, - QString& iap_type, - QString security_method) -{ - guint network_attr = 0; - dbus_uint32_t cap = 0; - - if (iap_type == "WLAN_INFRA") - cap |= WLANCOND_INFRA; - else if (iap_type == "WLAN_ADHOC") - cap |= WLANCOND_ADHOC; - - if (security_method.isEmpty() && (cap & (WLANCOND_INFRA | WLANCOND_ADHOC))) { - Maemo::IAPConf saved_ap(iap_id); - security_method = saved_ap.value("wlan_security").toString(); - } - - if (!security_method.isEmpty()) { - if (security_method == "WEP") - cap |= WLANCOND_WEP; - else if (security_method == "WPA_PSK") - cap |= WLANCOND_WPA_PSK; - else if (security_method == "WPA_EAP") - cap |= WLANCOND_WPA_EAP; - else if (security_method == "NONE") - cap |= WLANCOND_OPEN; - - if (cap & (WLANCOND_WPA_PSK | WLANCOND_WPA_EAP)) { - Maemo::IAPConf saved_iap(iap_id); - bool wpa2_only = saved_iap.value("EAP_wpa2_only_mode").toBool(); - if (wpa2_only) { - cap |= WLANCOND_WPA2; - } - } - } - - cap2nwattr(cap, &network_attr); - if (is_iap_id) - network_attr |= ICD_NW_ATTR_IAPNAME; - - return (uint32_t)network_attr; -} - - -void QNetworkConfigurationManagerPrivate::addConfiguration(QString& iap_id) -{ - if (!accessPointConfigurations.contains(iap_id)) { - Maemo::IAPConf saved_iap(iap_id); - QString iap_type = saved_iap.value("type").toString(); - if (!iap_type.isEmpty()) { - QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); - cpPriv->name = saved_iap.value("name").toString(); - if (cpPriv->name.isEmpty()) - cpPriv->name = iap_id; - cpPriv->isValid = true; - cpPriv->id = iap_id; - cpPriv->iap_type = iap_type; - cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); - cpPriv->service_id = saved_iap.value("service_id").toString(); - cpPriv->service_type = saved_iap.value("service_type").toString(); - if (iap_type.startsWith("WLAN")) { - QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); - if (ssid.isEmpty()) { - qWarning() << "Cannot get ssid for" << iap_id; - } - } - cpPriv->type = QNetworkConfiguration::InternetAccessPoint; - cpPriv->state = QNetworkConfiguration::Defined; - - QExplicitlySharedDataPointer ptr(cpPriv); - accessPointConfigurations.insert(iap_id, ptr); - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("IAP: %s, name: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data()); -#endif - - QNetworkConfiguration item; - item.d = ptr; - emit configurationAdded(item); - configChanged(ptr.data(), true); - } else { - qWarning("IAP %s does not have \"type\" field defined, skipping this IAP.", iap_id.toAscii().data()); - } - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "already in gconf."; -#endif - - /* Check if the data in gconf changed and update configuration - * accordingly - */ - QExplicitlySharedDataPointer ptr = accessPointConfigurations.take(iap_id); - if (ptr.data()) { - Maemo::IAPConf changed_iap(iap_id); - QString iap_type = changed_iap.value("type").toString(); - bool update_needed = false; /* if IAP type or ssid changed, we need to change the state */ - - ptr->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); - ptr->service_id = changed_iap.value("service_id").toString(); - ptr->service_type = changed_iap.value("service_type").toString(); - - if (!iap_type.isEmpty()) { - ptr->name = changed_iap.value("name").toString(); - if (ptr->name.isEmpty()) - ptr->name = iap_id; - ptr->isValid = true; - if (ptr->iap_type != iap_type) { - ptr->iap_type = iap_type; - update_needed = true; - } - if (iap_type.startsWith("WLAN")) { - QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray(); - if (ssid.isEmpty()) { - qWarning() << "Cannot get ssid for" << iap_id; - } - if (ptr->network_id != ssid) { - ptr->network_id = ssid; - update_needed = true; - } - } - } - accessPointConfigurations.insert(iap_id, ptr); - if (update_needed) { - ptr->type = QNetworkConfiguration::InternetAccessPoint; - if (ptr->state != QNetworkConfiguration::Defined) { - ptr->state = QNetworkConfiguration::Defined; - configurationChanged(ptr.data()); - } - } - } else { - qWarning("Cannot find IAP %s from current configuration although it should be there.", iap_id.toAscii().data()); - } - } -} - - -void QNetworkConfigurationManagerPrivate::updateConfigurations() -{ - /* Contains known network id (like ssid) from storage */ - QMultiHash knownConfigs; - - /* All the scanned access points */ - QList scanned; - - /* Turn on IAP monitoring */ - iapMonitor()->setup(this); - - if (firstUpdate) { - /* We create a default configuration which is a pseudo config */ - QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); - cpPriv->name = "UserChoice"; - cpPriv->state = QNetworkConfiguration::Discovered; - cpPriv->isValid = true; - cpPriv->id = OSSO_IAP_ANY; - cpPriv->type = QNetworkConfiguration::UserChoice; - cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; - cpPriv->roamingSupported = false; - cpPriv->manager = this; - QExplicitlySharedDataPointer ptr(cpPriv); - userChoiceConfigurations.insert(cpPriv->id, ptr); - } - - /* We return currently configured IAPs in the first run and do the WLAN - * scan in subsequent runs. - */ - QList all_iaps; - Maemo::IAPConf::getAll(all_iaps); - - foreach (QString escaped_iap_id, all_iaps) { - QByteArray ssid; - - /* The key that is returned by getAll() needs to be unescaped */ - gchar *unescaped_id = gconf_unescape_key(escaped_iap_id.toUtf8().data(), -1); - QString iap_id = QString((char *)unescaped_id); - g_free(unescaped_id); - - Maemo::IAPConf saved_ap(iap_id); - bool is_temporary = saved_ap.value("temporary").toBool(); - if (is_temporary) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "is temporary, skipping it."; -#endif - continue; - } - - QString iap_type = saved_ap.value("type").toString(); - if (iap_type.startsWith("WLAN")) { - ssid = saved_ap.value("wlan_ssid").toByteArray(); - if (ssid.isEmpty()) { - qWarning() << "Cannot get ssid for" << iap_id; - continue; - } - - QString security_method = saved_ap.value("wlan_security").toString(); - SSIDInfo *info = new SSIDInfo; - info->iap_id = iap_id; - info->wlan_security = security_method; - knownConfigs.insert(ssid, info); - } else if (iap_type.isEmpty()) { - qWarning() << "IAP" << iap_id << "network type is not set! Skipping it"; - continue; - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "network type is" << iap_type; -#endif - ssid.clear(); - } - - if (!accessPointConfigurations.contains(iap_id)) { - QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); - //cpPriv->name = iap_info.value().toString(); - cpPriv->name = saved_ap.value("name").toString(); - if (cpPriv->name.isEmpty()) - if (!ssid.isEmpty() && ssid.size() > 0) - cpPriv->name = ssid.data(); - else - cpPriv->name = iap_id; - cpPriv->isValid = true; - cpPriv->id = iap_id; - cpPriv->network_id = ssid; - cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); - cpPriv->iap_type = iap_type; - cpPriv->service_id = saved_ap.value("service_id").toString(); - cpPriv->service_type = saved_ap.value("service_type").toString(); - cpPriv->type = QNetworkConfiguration::InternetAccessPoint; - cpPriv->state = QNetworkConfiguration::Defined; - cpPriv->manager = this; - - QExplicitlySharedDataPointer ptr(cpPriv); - accessPointConfigurations.insert(iap_id, ptr); - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("IAP: %s, name: %s, ssid: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); -#endif - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("IAP: %s, ssid: %s, already exists in the known list", iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); -#endif - } - } - - if (!firstUpdate) { - QStringList scannedNetworkTypes; - QStringList networkTypesToScan; - QString error; - Maemo::Icd icd(ICD_SHORT_SCAN_TIMEOUT); - - scannedNetworkTypes = icd.scan(ICD_SCAN_REQUEST_ACTIVE, - networkTypesToScan, - scanned, - error); - if (!error.isEmpty()) { - qWarning() << "Network scanning failed" << error; - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - if (!scanned.isEmpty()) - qDebug() << "Scan returned" << scanned.size() << "networks"; - else - qDebug() << "Scan returned nothing."; -#endif - } - } - - - /* This is skipped in the first update as scanned size is zero */ - if (!scanned.isEmpty()) - for (int i=0; i priv = accessPointConfigurations.take(iapid); - if (priv.data()) { - priv->state = QNetworkConfiguration::Discovered; /* Defined is set automagically */ - priv->network_attrs = ap.scan.network_attrs; - priv->service_id = ap.scan.service_id; - priv->service_type = ap.scan.service_type; - priv->service_attrs = ap.scan.service_attrs; - - configurationChanged(priv.data()); - accessPointConfigurations.insert(iapid, priv); -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("IAP: %s, ssid: %s, discovered", iapid.toAscii().data(), priv->network_id.data()); -#endif - - if (!ap.scan.network_type.startsWith("WLAN")) - continue; // not a wlan AP - - /* Remove scanned AP from known configurations so that we can - * emit configurationRemoved signal later - */ - QList known_iaps = knownConfigs.values(priv->network_id); - rescan_list: - if (!known_iaps.isEmpty()) { - for (int k=0; kiap_id << "security" << iap->wlan_security << "scan" << network_attrs_to_security(ap.scan.network_attrs); -#endif - - if (iap->wlan_security == - network_attrs_to_security(ap.scan.network_attrs)) { - /* Remove IAP from the list */ - knownConfigs.remove(priv->network_id, iap); -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Removed IAP" << iap->iap_id << "from unknown config"; -#endif - known_iaps.removeAt(k); - delete iap; - goto rescan_list; - } - } - } - } else { - qWarning() << "IAP" << iapid << "is missing in configuration."; - } - - } else { - /* Non saved access point data */ - QByteArray scanned_ssid = ap.scan.network_id; - QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); - QString hrs = scanned_ssid.data(); - - cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; - cpPriv->isValid = true; - cpPriv->id = scanned_ssid.data(); // Note: id is now ssid, it should be set to IAP id if the IAP is saved - cpPriv->network_id = scanned_ssid; - cpPriv->iap_type = ap.scan.network_type; - cpPriv->network_attrs = ap.scan.network_attrs; - cpPriv->service_id = ap.scan.service_id; - cpPriv->service_type = ap.scan.service_type; - cpPriv->service_attrs = ap.scan.service_attrs; - cpPriv->manager = this; - - cpPriv->type = QNetworkConfiguration::InternetAccessPoint; - cpPriv->state = QNetworkConfiguration::Undefined; - - QExplicitlySharedDataPointer ptr(cpPriv); - accessPointConfigurations.insert(cpPriv->id, ptr); - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan."; -#endif - - QNetworkConfiguration item; - item.d = ptr; - emit configurationAdded(item); - } - } - - - /* Remove non existing iaps since last update */ - if (!firstUpdate) { - QHashIterator i(knownConfigs); - while (i.hasNext()) { - i.next(); - SSIDInfo *iap = i.value(); - QString iap_id = iap->iap_id; - //qDebug() << i.key() << ": " << iap_id; - - QExplicitlySharedDataPointer priv = accessPointConfigurations.take(iap_id); - if (priv.data()) { - priv->isValid = false; -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "was removed as it was not found in scan."; -#endif - - QNetworkConfiguration item; - item.d = priv; - emit configurationRemoved(item); - configChanged(priv.data(), false); - - //if we would have SNAP support we would have to remove the references - //from existing ServiceNetworks to the removed access point configuration - } - } - } - - - QMutableHashIterator i(knownConfigs); - while (i.hasNext()) { - i.next(); - SSIDInfo *iap = i.value(); - delete iap; - i.remove(); - } - - if (!firstUpdate) - emit configurationUpdateComplete(); - - if (firstUpdate) - firstUpdate = false; -} - - -QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() -{ - /* Here we just return [ANY] request to icd and let the icd decide which - * IAP to connect. - */ - QNetworkConfiguration item; - if (userChoiceConfigurations.contains(OSSO_IAP_ANY)) - item.d = userChoiceConfigurations.value(OSSO_IAP_ANY); - return item; -} - - -void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() -{ - QTimer::singleShot(0, this, SLOT(updateConfigurations())); -} - - -void QNetworkConfigurationManagerPrivate::cleanup() -{ - iapMonitor()->cleanup(); -} - - -void QNetworkConfigurationManagerPrivate::configChanged(QNetworkConfigurationPrivate *ptr, bool added) -{ - if (added) { - if (ptr && ptr->state == QNetworkConfiguration::Active) { - onlineConfigurations++; - if (!firstUpdate && onlineConfigurations == 1) - emit onlineStateChanged(true); - } - } else { - if (ptr && ptr->state == QNetworkConfiguration::Active) { - onlineConfigurations--; - if (!firstUpdate && onlineConfigurations == 0) - emit onlineStateChanged(false); - if (onlineConfigurations < 0) - onlineConfigurations = 0; - } - } -} - - -#include "qnetworkconfigmanager_maemo.moc" -#include "moc_qnetworkconfigmanager_maemo_p.cpp" - -QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworkconfigmanager_maemo_p.h b/src/network/bearer/qnetworkconfigmanager_maemo_p.h deleted file mode 100644 index 5cc99c2..0000000 --- a/src/network/bearer/qnetworkconfigmanager_maemo_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** 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 QtNetwork module of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef QNETWORKCONFIGURATIONMANAGERPRIVATE_H -#define QNETWORKCONFIGURATIONMANAGERPRIVATE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - - -class QNetworkConfigurationManagerPrivate : public QObject -{ - Q_OBJECT -public: - QNetworkConfigurationManagerPrivate() - : QObject(0), capFlags(0), firstUpdate(true), onlineConfigurations(0) - { - registerPlatformCapabilities(); - updateConfigurations(); - } - - virtual ~QNetworkConfigurationManagerPrivate() - { - QList configIdents = snapConfigurations.keys(); - foreach(const QString oldIface, configIdents) { - QExplicitlySharedDataPointer priv = snapConfigurations.take(oldIface); - priv->isValid = false; - priv->id.clear(); - } - - configIdents = accessPointConfigurations.keys(); - foreach(const QString oldIface, configIdents) { - QExplicitlySharedDataPointer priv = accessPointConfigurations.take(oldIface); - priv->isValid = false; - priv->id.clear(); - } - - configIdents = userChoiceConfigurations.keys(); - foreach(const QString oldIface, configIdents) { - QExplicitlySharedDataPointer priv = userChoiceConfigurations.take(oldIface); - priv->isValid = false; - priv->id.clear(); - } - - cleanup(); - } - - QNetworkConfiguration defaultConfiguration(); - - QNetworkConfigurationManager::Capabilities capFlags; - void registerPlatformCapabilities(); - - void performAsyncConfigurationUpdate(); - - //this table contains an up to date list of all configs at any time. - //it must be updated if configurations change, are added/removed or - //the members of ServiceNetworks change - QHash > accessPointConfigurations; - QHash > snapConfigurations; - QHash > userChoiceConfigurations; - bool firstUpdate; - int onlineConfigurations; - friend class IapMonitor; - void cleanup(); - void deleteConfiguration(QString &iap_id); - void addConfiguration(QString &iap_id); - void configurationChanged(QNetworkConfigurationPrivate *ptr); - uint32_t getNetworkAttrs(bool is_iap_id, QString& iap_id, - QString& iap_type, QString security_method); - void configChanged(QNetworkConfigurationPrivate *ptr, bool added); - friend class QNetworkSessionPrivate; - -public slots: - void updateConfigurations(); - -Q_SIGNALS: - void configurationAdded(const QNetworkConfiguration& config); - void configurationRemoved(const QNetworkConfiguration& config); - void configurationUpdateComplete(); - void configurationChanged(const QNetworkConfiguration& config); - void onlineStateChanged(bool isOnline); -}; - -QT_END_NAMESPACE - -#endif //QNETWORKCONFIGURATIONMANAGERPRIVATE_H diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp index 1585be1..cf10677 100644 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/network/bearer/qnetworkconfiguration_maemo_p.h b/src/network/bearer/qnetworkconfiguration_maemo_p.h deleted file mode 100644 index 3b43312..0000000 --- a/src/network/bearer/qnetworkconfiguration_maemo_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** 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 QtNetwork module of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef QNETWORKCONFIGURATIONPRIVATE_H -#define QNETWORKCONFIGURATIONPRIVATE_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 -#include -#include - -QT_BEGIN_NAMESPACE - -class QNetworkConfigurationPrivate : public QSharedData -{ -public: - QNetworkConfigurationPrivate () - : isValid(false), type(QNetworkConfiguration::Invalid), - roamingSupported(false), purpose(QNetworkConfiguration::UnknownPurpose), - network_attrs(0), service_attrs(0), manager(0) - { - } - - ~QNetworkConfigurationPrivate() - { - //release pointers to member configurations - serviceNetworkMembers.clear(); - } - - QString name; - bool isValid; - QString id; - QNetworkConfiguration::StateFlags state; - QNetworkConfiguration::Type type; - bool roamingSupported; - QNetworkConfiguration::Purpose purpose; - - QList > serviceNetworkMembers; - QNetworkInterface serviceInterface; - - /* In Maemo the id field (defined above) is the IAP id (which typically is UUID) */ - QByteArray network_id; /* typically WLAN ssid or similar */ - QString iap_type; /* is this one WLAN or GPRS */ - QString bearerName() const - { - if (iap_type == "WLAN_INFRA" || - iap_type == "WLAN_ADHOC") - return QString("WLAN"); - else if (iap_type == "GPRS") - return QString("HSPA"); - - //return whatever it is - //this may have to be split up later on - return iap_type; - } - - uint32_t network_attrs; /* network attributes for this IAP, this is the value returned by icd and passed to it when connecting */ - - QString service_type; - QString service_id; - uint32_t service_attrs; - - QNetworkConfigurationManagerPrivate *manager; - -private: - - // disallow detaching - QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other); - QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other); -}; - -QT_END_NAMESPACE - -#endif //QNETWORKCONFIGURATIONPRIVATE_H diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h index 40aea8b..6b40946 100644 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index ba50ed6..f9bb9ea 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -45,12 +45,7 @@ #include "qnetworksession.h" #include "qbearerengine_p.h" #include "qnetworkconfigmanager_p.h" - -#if Q_WS_MAEMO_6 -#include "qnetworksession_maemo_p.h" -#else #include "qnetworksession_p.h" -#endif QT_BEGIN_NAMESPACE diff --git a/src/network/bearer/qnetworksession_maemo.cpp b/src/network/bearer/qnetworksession_maemo.cpp deleted file mode 100644 index 6fb4453..0000000 --- a/src/network/bearer/qnetworksession_maemo.cpp +++ /dev/null @@ -1,1164 +0,0 @@ -/**************************************************************************** -** -** 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 QtNetwork module of the Qt Toolkit. -** -** $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 - -#include "qnetworksession_maemo_p.h" -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -static QHash properties; - -static QString get_network_interface(); -static DBusConnection *dbus_connection; -static DBusHandlerResult signal_handler(DBusConnection *connection, - DBusMessage *message, - void *user_data); - -#define ICD_DBUS_MATCH "type='signal'," \ - "interface='" ICD_DBUS_INTERFACE "'," \ - "path='" ICD_DBUS_PATH "'" - - -static inline DBusConnection *get_dbus_conn(DBusError *error) -{ - DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error); -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn); -#endif - - return conn; -} - - -/* Helper class that monitors the Icd status messages and - * can change the IAP status accordingly. This is a singleton. - */ -class IcdListener : public QObject -{ - Q_OBJECT - -public: - IcdListener() : first_call(true) { } - friend DBusHandlerResult signal_handler(DBusConnection *connection, - DBusMessage *message, - void *user_data); - void setup(QNetworkSessionPrivate *d); - void cleanup(); - void cleanupSession(QNetworkSessionPrivate *ptr); - - enum IapConnectionStatus { - /* The IAP was connected */ - CONNECTED = 0, - /* The IAP was disconnected */ - DISCONNECTED, - /* The IAP is disconnecting */ - DISCONNECTING, - /* The IAP has a network address, but is not yet fully connected */ - NETWORK_UP - }; - -private: - void icdSignalReceived(QString&, QString&, QString&); - bool first_call; - QHash sessions; -}; - -Q_GLOBAL_STATIC(IcdListener, icdListener); - - -static DBusHandlerResult signal_handler(DBusConnection *, - DBusMessage *message, - void *user_data) -{ - if (dbus_message_is_signal(message, - ICD_DBUS_INTERFACE, - ICD_STATUS_CHANGED_SIG)) { - - IcdListener *icd = (IcdListener *)user_data; - DBusError error; - dbus_error_init(&error); - - char *iap_id = 0; - char *network_type = 0; - char *state = 0; - - if (dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &iap_id, - DBUS_TYPE_STRING, &network_type, - DBUS_TYPE_STRING, &state, - DBUS_TYPE_INVALID) == FALSE) { - qWarning() << QString("Failed to parse icd status signal: %1").arg(error.message); - } else { - QString _iap_id(iap_id); - QString _network_type(network_type); - QString _state(state); - - icd->icdSignalReceived(_iap_id, _network_type, _state); - } - - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_HANDLED; - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - - -void IcdListener::setup(QNetworkSessionPrivate *d) -{ - if (first_call) { - // We use the old Icd dbus interface like in ConIC - DBusError error; - dbus_error_init(&error); - - dbus_connection = get_dbus_conn(&error); - if (dbus_error_is_set(&error)) { - qWarning() << "Cannot get dbus connection."; - dbus_error_free(&error); - return; - } - - static struct DBusObjectPathVTable icd_vtable; - icd_vtable.message_function = signal_handler; - - dbus_bus_add_match(dbus_connection, ICD_DBUS_MATCH, &error); - if (dbus_error_is_set(&error)) { - qWarning() << "Cannot add match" << ICD_DBUS_MATCH; - dbus_error_free(&error); - return; - } - - if (dbus_connection_register_object_path(dbus_connection, - ICD_DBUS_PATH, - &icd_vtable, - (void*)this) == FALSE) { - qWarning() << "Cannot register dbus signal handler, interface"<< ICD_DBUS_INTERFACE << "path" << ICD_DBUS_PATH; - dbus_error_free(&error); - return; - } - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE; -#endif - first_call = false; - dbus_error_free(&error); - } - - QString id = d->activeConfig.identifier(); - if (!sessions.contains(id)) { - QNetworkSessionPrivate *ptr = d; - sessions.insert(id, ptr); - } -} - - -void IcdListener::icdSignalReceived(QString& iap_id, -#ifdef BEARER_MANAGEMENT_DEBUG - QString& network_type, -#else - QString&, -#endif - QString& state) -{ - if (iap_id == OSSO_IAP_SCAN) // icd sends scan status signals which we will ignore - return; - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Status received:" << iap_id << "type" << network_type << "state" << state; -#endif - - if (!sessions.contains(iap_id)) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "No session for IAP" << iap_id; -#endif - return; - } - - QNetworkSessionPrivate *session = sessions.value(iap_id); - QNetworkConfiguration ap_conf = session->manager.configurationFromIdentifier(iap_id); - if (!ap_conf.isValid()) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Unknown IAP" << iap_id; -#endif - return; - } - - IapConnectionStatus status; - - if (state == "IDLE") { - status = DISCONNECTED; - } else if (state == "CONNECTED") { - status = CONNECTED; - } else if (state == "NETWORKUP") { - status = NETWORK_UP; - } else { - //qDebug() << "Unknown state" << state; - return; - } - - if (status == DISCONNECTED) { - if (ap_conf.state() == QNetworkConfiguration::Active) { - /* The IAP was just disconnected by Icd */ - session->updateState(QNetworkSession::Disconnected); - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Got a network disconnect when in state" << ap_conf.state(); -#endif - } - } else if (status == CONNECTED) { - /* The IAP was just connected by Icd */ - session->updateState(QNetworkSession::Connected); - session->updateIdentifier(iap_id); - - if (session->publicConfig.identifier() == OSSO_IAP_ANY) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "connected when connecting to" << OSSO_IAP_ANY; -#endif - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "connected"; -#endif - } - } - - return; -} - - -void IcdListener::cleanup() -{ - if (!first_call) { - dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL); - dbus_connection_unref(dbus_connection); - } -} - - -void IcdListener::cleanupSession(QNetworkSessionPrivate *ptr) -{ - if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice) - (void)sessions.take(ptr->activeConfig.identifier()); - else - (void)sessions.take(ptr->publicConfig.identifier()); -} - - -void QNetworkSessionPrivate::cleanupSession(void) -{ - icdListener()->cleanupSession(this); -} - - -void QNetworkSessionPrivate::updateState(QNetworkSession::State newState) -{ - if( newState != state) { - state = newState; - - if (state == QNetworkSession::Disconnected) { - isOpen = false; - currentNetworkInterface.clear(); - if (publicConfig.type() == QNetworkConfiguration::UserChoice) - activeConfig.d->state = QNetworkConfiguration::Defined; - publicConfig.d->state = QNetworkConfiguration::Defined; - - } else if (state == QNetworkSession::Connected) { - isOpen = true; - if (publicConfig.type() == QNetworkConfiguration::UserChoice) { - activeConfig.d->state = QNetworkConfiguration::Active; - activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint; - } - publicConfig.d->state = QNetworkConfiguration::Active; - } - - emit q->stateChanged(newState); - } -} - - -void QNetworkSessionPrivate::updateIdentifier(QString &newId) -{ - if (publicConfig.type() == QNetworkConfiguration::UserChoice) { - activeConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME; - activeConfig.d->id = newId; - } else { - publicConfig.d->network_attrs |= ICD_NW_ATTR_IAPNAME; - if (publicConfig.d->id != newId) { - qWarning() << "Your config id changed from" << publicConfig.d->id << "to" << newId; - publicConfig.d->id = newId; - } - } -} - - -quint64 QNetworkSessionPrivate::getStatistics(bool sent) const -{ - /* This could be also implemented by using the Maemo::Icd::statistics() - * that gets the statistics data for a specific IAP. Change if - * necessary. - */ - Maemo::Icd icd; - QList stats_results; - quint64 counter_rx = 0, counter_tx = 0; - - if (!icd.statistics(stats_results)) { - return 0; - } - - foreach (Maemo::IcdStatisticsResult res, stats_results) { - if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) { - /* network_id is the IAP UUID */ - if (QString(res.params.network_id.data()) == activeConfig.identifier()) { - counter_tx = res.bytes_sent; - counter_rx = res.bytes_received; - } - } else { - /* We probably will never get to this branch */ - QNetworkConfigurationPrivate *d = activeConfig.d.data(); - if (res.params.network_id == d->network_id) { - counter_tx = res.bytes_sent; - counter_rx = res.bytes_received; - } - } - } - - if (sent) - return counter_tx; - else - return counter_rx; -} - - -quint64 QNetworkSessionPrivate::bytesWritten() const -{ - return getStatistics(true); -} - -quint64 QNetworkSessionPrivate::bytesReceived() const -{ - return getStatistics(false); -} - -quint64 QNetworkSessionPrivate::activeTime() const -{ - if (startTime.isNull()) { - return 0; - } - return startTime.secsTo(QDateTime::currentDateTime()); -} - - -QNetworkConfiguration& QNetworkSessionPrivate::copyConfig(QNetworkConfiguration &fromConfig, QNetworkConfiguration &toConfig, bool deepCopy) -{ - if (deepCopy) { - QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); - QExplicitlySharedDataPointer ptr(cpPriv); - toConfig.d = ptr; - } - - toConfig.d->name = fromConfig.d->name; - toConfig.d->isValid = fromConfig.d->isValid; - // Note that we do not copy id field here as the publicConfig does - // not contain a valid IAP id. - toConfig.d->state = fromConfig.d->state; - toConfig.d->type = fromConfig.d->type; - toConfig.d->roamingSupported = fromConfig.d->roamingSupported; - toConfig.d->purpose = fromConfig.d->purpose; - toConfig.d->network_id = fromConfig.d->network_id; - toConfig.d->iap_type = fromConfig.d->iap_type; - toConfig.d->network_attrs = fromConfig.d->network_attrs; - toConfig.d->service_type = fromConfig.d->service_type; - toConfig.d->service_id = fromConfig.d->service_id; - toConfig.d->service_attrs = fromConfig.d->service_attrs; - toConfig.d->manager = fromConfig.d->manager; - - return toConfig; -} - - -/* This is called by QNetworkSession constructor and it updates the current - * state of the configuration. - */ -void QNetworkSessionPrivate::syncStateWithInterface() -{ - /* Start to listen Icd status messages. */ - icdListener()->setup(this); - - /* Initially we are not active although the configuration might be in - * connected state. - */ - isOpen = false; - opened = false; - - QObject::connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged())); - - if (publicConfig.d.data()) { - QNetworkConfigurationManagerPrivate* mgr = (QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager; - if (mgr) { - QObject::connect(mgr, SIGNAL(configurationChanged(QNetworkConfiguration)), - this, SLOT(configurationChanged(QNetworkConfiguration))); - } else { - qWarning()<<"Manager object not set when trying to connect configurationChanged signal. Your configuration object is not correctly setup, did you remember to call manager.updateConfigurations() before creating session object?"; - state = QNetworkSession::Invalid; - lastError = QNetworkSession::UnknownSessionError; - return; - } - } - - state = QNetworkSession::Invalid; - lastError = QNetworkSession::UnknownSessionError; - - switch (publicConfig.type()) { - case QNetworkConfiguration::InternetAccessPoint: - activeConfig = publicConfig; - break; - case QNetworkConfiguration::ServiceNetwork: - serviceConfig = publicConfig; - break; - case QNetworkConfiguration::UserChoice: - // active config will contain correct data after open() has succeeded - copyConfig(publicConfig, activeConfig); - - /* We create new configuration that holds the actual configuration - * returned by icd. This way publicConfig still contains the - * original user specified configuration. - * - * Note that the new activeConfig configuration is not inserted - * to configurationManager as manager class will get the newly - * connected configuration from gconf when the IAP is saved. - * This configuration manager update is done by IapMonitor class. - * If the ANY connection fails in open(), then the configuration - * data is not saved to gconf and will not be added to - * configuration manager IAP list. - */ -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug()<<"New configuration created for" << publicConfig.identifier(); -#endif - break; - default: - /* Invalid configuration, no point continuing */ - return; - } - - if (!activeConfig.isValid()) - return; - - /* Get the initial state from icd */ - Maemo::Icd icd; - QList state_results; - - /* Update the active config from first connection, this is ok as icd - * supports only one connection anyway. - */ - if (icd.state(state_results) && !state_results.isEmpty()) { - - /* If we did not get full state back, then we are not - * connected and can skip the next part. - */ - if (!(state_results.first().params.network_attrs == 0 && - state_results.first().params.network_id.isEmpty())) { - - /* If we try to connect to specific IAP and we get results back - * that tell the icd is actually connected to another IAP, - * then do not update current state etc. - */ - if (publicConfig.type() == QNetworkConfiguration::UserChoice || - publicConfig.d->id == state_results.first().params.network_id) { - - switch (state_results.first().state) { - case ICD_STATE_DISCONNECTED: - state = QNetworkSession::Disconnected; - if (activeConfig.d.data()) - activeConfig.d->isValid = true; - break; - case ICD_STATE_CONNECTING: - state = QNetworkSession::Connecting; - if (activeConfig.d.data()) - activeConfig.d->isValid = true; - break; - case ICD_STATE_CONNECTED: - { - if (!state_results.first().error.isEmpty()) - break; - - const QString id = state_results.first().params.network_id; - - QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; - if (mgr->accessPointConfigurations.contains(id)) { - //we don't want the copied data if the config is already known by the manager - //just reuse it so that existing references to the old data get the same update - QExplicitlySharedDataPointer priv = mgr->accessPointConfigurations.value(activeConfig.d->id); - activeConfig.d = priv; - } - - - state = QNetworkSession::Connected; - activeConfig.d->network_id = state_results.first().params.network_id; - activeConfig.d->id = activeConfig.d->network_id; - activeConfig.d->network_attrs = state_results.first().params.network_attrs; - activeConfig.d->iap_type = state_results.first().params.network_type; - activeConfig.d->service_type = state_results.first().params.service_type; - activeConfig.d->service_id = state_results.first().params.service_id; - activeConfig.d->service_attrs = state_results.first().params.service_attrs; - activeConfig.d->type = QNetworkConfiguration::InternetAccessPoint; - activeConfig.d->state = QNetworkConfiguration::Active; - activeConfig.d->isValid = true; - currentNetworkInterface = get_network_interface(); - - Maemo::IAPConf iap_name(activeConfig.d->id); - QString name_value = iap_name.value("name").toString(); - if (!name_value.isEmpty()) - activeConfig.d->name = name_value; - else - activeConfig.d->name = activeConfig.d->id; - - - // Add the new active configuration to manager or update the old config - mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; - if (!(mgr->accessPointConfigurations.contains(activeConfig.d->id))) { - QExplicitlySharedDataPointer ptr = activeConfig.d; - mgr->accessPointConfigurations.insert(activeConfig.d->id, ptr); - - QNetworkConfiguration item; - item.d = ptr; - emit mgr->configurationAdded(item); - -#ifdef BEARER_MANAGEMENT_DEBUG - //qDebug()<<"New configuration"<id<<"added to manager in sync"; -#endif - - } else { - mgr->configurationChanged((QNetworkConfigurationPrivate*)(activeConfig.d.data())); -#ifdef BEARER_MANAGEMENT_DEBUG - //qDebug()<<"Existing configuration"<id<<"updated in manager in sync"; -#endif - } - - } - break; - - case ICD_STATE_DISCONNECTING: - state = QNetworkSession::Closing; - if (activeConfig.d.data()) - activeConfig.d->isValid = true; - break; - default: - break; - } - } - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "status_req tells icd is not connected"; -#endif - } - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "status_req did not return any results from icd"; -#endif - } - - networkConfigurationsChanged(); -} - - -void QNetworkSessionPrivate::networkConfigurationsChanged() -{ - if (serviceConfig.isValid()) - updateStateFromServiceNetwork(); - else - updateStateFromActiveConfig(); -} - - -void QNetworkSessionPrivate::updateStateFromServiceNetwork() -{ - QNetworkSession::State oldState = state; - - foreach (const QNetworkConfiguration &config, serviceConfig.children()) { - if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) - continue; - - if (activeConfig != config) { - activeConfig = config; - 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::clearConfiguration(QNetworkConfiguration &config) -{ - config.d->network_id.clear(); - config.d->iap_type.clear(); - config.d->network_attrs = 0; - config.d->service_type.clear(); - config.d->service_id.clear(); - config.d->service_attrs = 0; -} - - -void QNetworkSessionPrivate::updateStateFromActiveConfig() -{ - QNetworkSession::State oldState = state; - - bool newActive = false; - - if (!activeConfig.d.data()) - return; - - if (!activeConfig.isValid()) { - state = QNetworkSession::Invalid; - clearConfiguration(activeConfig); - } 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; - clearConfiguration(activeConfig); - } - - bool oldActive = isOpen; - isOpen = newActive; - - if (!oldActive && isOpen) - emit quitPendingWaitsForOpened(); - - if (oldActive && !isOpen) - emit q->closed(); - - if (oldState != state) { - emit q->stateChanged(state); - - if (state == QNetworkSession::Disconnected) { -#ifdef BEARER_MANAGEMENT_DEBUG - //qDebug()<<"session aborted error emitted for"<error(lastError); - } - } - -#ifdef BEARER_MANAGEMENT_DEBUG - //qDebug()<<"oldState ="<ifa_next) { - family = ifa->ifa_addr->sa_family; - if (family != AF_INET) { - continue; /* Currently only IPv4 is supported by icd dbus interface */ - } - if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) { - iface = QString(ifa->ifa_name); - break; - } - } - - freeifaddrs(ifaddr); - return iface; -} - - -void QNetworkSessionPrivate::open() -{ - if (serviceConfig.isValid()) { - lastError = QNetworkSession::OperationNotSupportedError; - emit q->error(lastError); - } else if (!isOpen) { - - if (publicConfig.type() == QNetworkConfiguration::UserChoice) { - /* Caller is trying to connect to default IAP. - * At this time we will not know the IAP details so we just - * connect and update the active config when the IAP is - * connected. - */ - opened = true; - state = QNetworkSession::Connecting; - emit q->stateChanged(state); - QTimer::singleShot(0, this, SLOT(do_open())); - return; - } - - /* User is connecting to one specific IAP. If that IAP is not - * in discovered state we cannot continue. - */ - if ((activeConfig.state() & QNetworkConfiguration::Discovered) != - QNetworkConfiguration::Discovered) { - lastError =QNetworkSession::InvalidConfigurationError; - emit q->error(lastError); - return; - } - opened = true; - - if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) { - state = QNetworkSession::Connecting; - emit q->stateChanged(state); - - QTimer::singleShot(0, this, SLOT(do_open())); - return; - } - - isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active; - if (isOpen) - emit quitPendingWaitsForOpened(); - } else { - /* We seem to be active so inform caller */ - emit quitPendingWaitsForOpened(); - } -} - - -void QNetworkSessionPrivate::do_open() -{ - icd_connection_flags flags = connectFlags; - bool st; - QString result; - QString iap = publicConfig.identifier(); - - if (state == QNetworkSession::Connected) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Already connected to" << activeConfig.identifier(); -#endif - emit q->stateChanged(QNetworkSession::Connected); - emit quitPendingWaitsForOpened(); - return; - } - - Maemo::IcdConnectResult connect_result; - Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT); - QNetworkConfiguration config; - if (publicConfig.type() == QNetworkConfiguration::UserChoice) - config = activeConfig; - else - config = publicConfig; - - if (iap == OSSO_IAP_ANY) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connecting to default IAP" << iap; -#endif - st = icd.connect(flags, connect_result); - - } else { - - QList params; - Maemo::ConnectParams param; - param.connect.service_type = config.d->service_type; - param.connect.service_attrs = config.d->service_attrs; - param.connect.service_id = config.d->service_id; - param.connect.network_type = config.d->iap_type; - param.connect.network_attrs = config.d->network_attrs; - if (config.d->network_attrs & ICD_NW_ATTR_IAPNAME) - param.connect.network_id = QByteArray(iap.toLatin1()); - else - param.connect.network_id = config.d->network_id; - params.append(param); - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s", - param.connect.network_id.data(), - param.connect.network_type.toAscii().constData(), - param.connect.network_attrs, - param.connect.service_type.toAscii().constData(), - param.connect.service_attrs, - param.connect.service_id.toAscii().constData()); -#endif - st = icd.connect(flags, params, connect_result); - } - - if (st) { - result = connect_result.connect.network_id.data(); - QString connected_iap = result; - - if (connected_iap.isEmpty()) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connect to"<< iap << "failed, result is empty"; -#endif - updateState(QNetworkSession::Disconnected); - emit quitPendingWaitsForOpened(); - emit q->error(QNetworkSession::InvalidConfigurationError); - if (publicConfig.type() == QNetworkConfiguration::UserChoice) - cleanupAnyConfiguration(); - return; - } - - /* If the user tried to connect to some specific connection (foo) - * and we were already connected to some other connection (bar), - * then we cannot activate this session although icd has a valid - * connection to somewhere. - */ - if ((publicConfig.type() != QNetworkConfiguration::UserChoice) && - (connected_iap != config.identifier())) { - updateState(QNetworkSession::Disconnected); - emit quitPendingWaitsForOpened(); - emit q->error(QNetworkSession::InvalidConfigurationError); - return; - } - - - /* Did we connect to non saved IAP? */ - if (!(config.d->network_attrs & ICD_NW_ATTR_IAPNAME)) { - /* Because the connection succeeded, the IAP is now known. - */ - config.d->network_attrs |= ICD_NW_ATTR_IAPNAME; - config.d->id = connected_iap; - } - - /* User might have changed the IAP name when a new IAP was saved */ - Maemo::IAPConf iap_name(config.d->id); - QString name = iap_name.value("name").toString(); - if (!name.isEmpty()) - config.d->name = name; - - config.d->iap_type = connect_result.connect.network_type; - - config.d->isValid = true; - config.d->state = QNetworkConfiguration::Active; - config.d->type = QNetworkConfiguration::InternetAccessPoint; - - startTime = QDateTime::currentDateTime(); - updateState(QNetworkSession::Connected); - - currentNetworkInterface = get_network_interface(); - -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connected to" << result << config.d->name << "at" << currentNetworkInterface; -#endif - - /* We first check if the configuration already exists in the manager - * and if it is not found there, we then insert it. Note that this - * is only done for user choice config only because it can be missing - * from config manager list. - */ - - if (publicConfig.d->type == QNetworkConfiguration::UserChoice) { - -#ifdef BEARER_MANAGEMENT_DEBUG -#if 0 - QList configs; - QNetworkConfigurationManagerPrivate *conPriv = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager; - QList cpsIdents = conPriv->accessPointConfigurations.keys(); - foreach( QString ii, cpsIdents) { - QExplicitlySharedDataPointer p = - conPriv->accessPointConfigurations.value(ii); - QNetworkConfiguration pt; - pt.d = conPriv->accessPointConfigurations.value(ii); - configs << pt; - } - - int all = configs.count(); - qDebug() << "All configurations:" << all; - foreach(QNetworkConfiguration p, configs) { - qDebug() << p.name() <<": isvalid->" <"<< p.type() << - " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() << - " purpose->" << p.purpose() << " state->" << p.state(); - } -#endif -#endif - - QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)config.d.data()->manager; - if (!mgr->accessPointConfigurations.contains(result)) { - QExplicitlySharedDataPointer ptr = config.d; - mgr->accessPointConfigurations.insert(result, ptr); - - QNetworkConfiguration item; - item.d = ptr; - emit mgr->configurationAdded(item); - -#ifdef BEARER_MANAGEMENT_DEBUG - //qDebug()<<"New configuration"< priv = mgr->accessPointConfigurations.value(result); - QNetworkConfiguration reference; - reference.d = priv; - copyConfig(config, reference, false); - config = reference; - activeConfig = reference; - mgr->configurationChanged((QNetworkConfigurationPrivate*)(config.d.data())); - -#ifdef BEARER_MANAGEMENT_DEBUG - //qDebug()<<"Existing configuration"<error(QNetworkSession::UnknownSessionError); - } -} - - -void QNetworkSessionPrivate::cleanupAnyConfiguration() -{ -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug()<<"Removing configuration created for" << activeConfig.d->id; -#endif - activeConfig = publicConfig; -} - - -void QNetworkSessionPrivate::close() -{ - if (serviceConfig.isValid()) { - lastError = QNetworkSession::OperationNotSupportedError; - emit q->error(lastError); - } else if (isOpen) { - opened = false; - isOpen = 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); - - Maemo::Icd icd; -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "stopping session" << publicConfig.identifier(); -#endif - icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT); - startTime = QDateTime(); - - /* Note that the state will go disconnected in - * updateStateFromActiveConfig() which gets called after - * configurationChanged is emitted (below). - */ - - activeConfig.d->state = QNetworkConfiguration::Discovered; - QNetworkConfigurationManagerPrivate *mgr = (QNetworkConfigurationManagerPrivate*)activeConfig.d.data()->manager; - mgr->configurationChanged((QNetworkConfigurationPrivate*)activeConfig.d.data()); - - opened = false; - isOpen = false; - - } else { - opened = false; - isOpen = 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() || state != QNetworkSession::Connected) - return QNetworkInterface(); - - if (currentNetworkInterface.isEmpty()) - return QNetworkInterface(); - - return QNetworkInterface::interfaceFromName(currentNetworkInterface); -} - - -void QNetworkSessionPrivate::setSessionProperty(const QString& key, const QVariant& value) -{ - if (value.isValid()) { - properties.insert(key, value); - - if (key == "ConnectInBackground") { - bool v = value.toBool(); - if (v) - connectFlags = ICD_CONNECTION_FLAG_APPLICATION_EVENT; - else - connectFlags = ICD_CONNECTION_FLAG_USER_EVENT; - } - } else { - properties.remove(key); - - /* Set default value when property is removed */ - if (key == "ConnectInBackground") - connectFlags = ICD_CONNECTION_FLAG_USER_EVENT; - } -} - - -QVariant QNetworkSessionPrivate::sessionProperty(const QString& key) const -{ - return properties.value(key); -} - - -QString QNetworkSessionPrivate::errorString() const -{ - QString errorStr; - switch(q->error()) { - case QNetworkSession::RoamingError: - errorStr = QObject::tr("Roaming error"); - break; - case QNetworkSession::SessionAbortedError: - errorStr = QObject::tr("Session aborted by user or system"); - break; - default: - case QNetworkSession::UnknownSessionError: - errorStr = QObject::tr("Unidentified Error"); - break; - } - return errorStr; -} - - -QNetworkSession::SessionError QNetworkSessionPrivate::error() const -{ - return QNetworkSession::UnknownSessionError; -} - -#include "qnetworksession_maemo.moc" -#include "moc_qnetworksession_maemo_p.cpp" - -QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworksession_maemo_p.h b/src/network/bearer/qnetworksession_maemo_p.h deleted file mode 100644 index ff294f6..0000000 --- a/src/network/bearer/qnetworksession_maemo_p.h +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** 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 QtNetwork module of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef QNETWORKSESSIONPRIVATE_H -#define QNETWORKSESSIONPRIVATE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// -#include "qnetworkconfigmanager_maemo_p.h" -#include "qnetworksession.h" - -#include -#include -#include - -#ifdef Q_WS_MAEMO_6 -#include -#endif - -QT_BEGIN_NAMESPACE - -class QNetworkSessionPrivate : public QObject -{ - Q_OBJECT -public: - QNetworkSessionPrivate() : - tx_data(0), rx_data(0), m_activeTime(0), isOpen(false), -#ifdef Q_WS_MAEMO_6 - connectFlags(ICD_CONNECTION_FLAG_USER_EVENT) -#else - connectFlags(0) -#endif - { - } - - ~QNetworkSessionPrivate() - { - cleanupSession(); - } - - //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(); - - QNetworkInterface currentInterface() const; - QVariant sessionProperty(const QString& key) const; - void setSessionProperty(const QString& key, const QVariant& value); - - void open(); - void close(); - void stop(); - void migrate(); - void accept(); - void ignore(); - void reject(); - - QString errorString() const; //must return translated string - QNetworkSession::SessionError error() const; - - quint64 bytesWritten() const; - quint64 bytesReceived() const; - quint64 activeTime() const; - -private: - void updateStateFromServiceNetwork(); - void updateStateFromActiveConfig(); - -Q_SIGNALS: - //releases any pending waitForOpened() calls - void quitPendingWaitsForOpened(); - -private Q_SLOTS: - void do_open(); - void networkConfigurationsChanged(); - void configurationChanged(const QNetworkConfiguration &config); - -private: - QNetworkConfigurationManager manager; - - quint64 tx_data; - quint64 rx_data; - quint64 m_activeTime; - - // The config set on QNetworkSession. - QNetworkConfiguration publicConfig; - - // If publicConfig is a ServiceNetwork this is a copy of publicConfig. - // If publicConfig is an UserChoice that is resolved to a ServiceNetwork this is the actual - // ServiceNetwork configuration. - QNetworkConfiguration serviceConfig; - - // This is the actual active configuration currently in use by the session. - // Either a copy of publicConfig or one of serviceConfig.children(). - QNetworkConfiguration activeConfig; - - QNetworkConfiguration& copyConfig(QNetworkConfiguration &fromConfig, QNetworkConfiguration &toConfig, bool deepCopy = true); - void clearConfiguration(QNetworkConfiguration &config); - void cleanupAnyConfiguration(); - - QNetworkSession::State state; - bool isOpen; - bool opened; - icd_connection_flags connectFlags; - - QNetworkSession::SessionError lastError; - - QNetworkSession* q; - friend class QNetworkSession; - - QDateTime startTime; - QString currentNetworkInterface; - friend class IcdListener; - void updateState(QNetworkSession::State); - void updateIdentifier(QString &newId); - quint64 getStatistics(bool sent) const; - void cleanupSession(void); -}; - -QT_END_NAMESPACE - -#endif //QNETWORKSESSIONPRIVATE_H - diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h index a6bb7cb..76691b3 100644 --- a/src/network/bearer/qnetworksession_p.h +++ b/src/network/bearer/qnetworksession_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -109,6 +109,12 @@ protected: return config.d; } + inline void setPrivateConfiguration(QNetworkConfiguration &config, + QNetworkConfigurationPrivatePointer ptr) const + { + config.d = ptr; + } + Q_SIGNALS: //releases any pending waitForOpened() calls void quitPendingWaitsForOpened(); diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index 7347735..95c9851 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -5,5 +5,6 @@ win32:SUBDIRS += nla win32:!wince*:SUBDIRS += nativewifi macx:SUBDIRS += corewlan symbian:SUBDIRS += symbian +maemo6:contains(QT_CONFIG, dbus):SUBDIRS += icd isEmpty(SUBDIRS):SUBDIRS += generic diff --git a/src/plugins/bearer/icd/icd.pro b/src/plugins/bearer/icd/icd.pro new file mode 100644 index 0000000..5eaf5af --- /dev/null +++ b/src/plugins/bearer/icd/icd.pro @@ -0,0 +1,22 @@ +TARGET = qicdbearer +include(../../qpluginbase.pri) + +QT += network dbus + +CONFIG += link_pkgconfig +PKGCONFIG += glib-2.0 dbus-glib-1 gconf-2.0 osso-ic conninet + +HEADERS += qicdengine.h \ + monitor.h \ + qnetworksession_impl.h + +SOURCES += main.cpp \ + qicdengine.cpp \ + monitor.cpp \ + qnetworksession_impl.cpp + +#DEFINES += BEARER_MANAGEMENT_DEBUG + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/icd/main.cpp b/src/plugins/bearer/icd/main.cpp new file mode 100644 index 0000000..8984d2c --- /dev/null +++ b/src/plugins/bearer/icd/main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $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 "qicdengine.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QIcdEnginePlugin : public QBearerEnginePlugin +{ +public: + QIcdEnginePlugin(); + ~QIcdEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QIcdEnginePlugin::QIcdEnginePlugin() +{ +} + +QIcdEnginePlugin::~QIcdEnginePlugin() +{ +} + +QStringList QIcdEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("icd"); +} + +QBearerEngine *QIcdEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("icd")) + return new QIcdEngine; + else + return 0; +} + +Q_EXPORT_STATIC_PLUGIN(QIcdEnginePlugin) +Q_EXPORT_PLUGIN2(qicdbearer, QIcdEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/monitor.cpp b/src/plugins/bearer/icd/monitor.cpp new file mode 100644 index 0000000..0ff45d2 --- /dev/null +++ b/src/plugins/bearer/icd/monitor.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $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 "monitor.h" +#include "qicdengine.h" + +#include +#include +#include +#include + +#define IAP "/system/osso/connectivity/IAP" + +static int iap_prefix_len; + +/* Notify func that is called when IAP is added or deleted */ +void notify_iap(GConfClient *, guint, GConfEntry *entry, gpointer user_data) +{ + const char *key = gconf_entry_get_key(entry); + if (key && g_str_has_prefix(key, IAP)) { + IapMonitor *ptr = (IapMonitor *)user_data; + if (gconf_entry_get_value(entry)) { + ptr->iapAdded(key, entry); + } else { + ptr->iapDeleted(key, entry); + } + } +} + + +void IapMonitor::setup(QIcdEngine *d_ptr) +{ + if (first_call) { + d = d_ptr; + iap_prefix_len = strlen(IAP); + iap = new Maemo::IAPMonitor(notify_iap, (gpointer)this); + first_call = false; + } +} + + +void IapMonitor::cleanup() +{ + if (!first_call) { + delete iap; + timers.removeAll(); + first_call = true; + } +} + + +void IapMonitor::iapAdded(const char *key, GConfEntry * /*entry*/) +{ + //qDebug("Notify called for added element: %s=%s", + // gconf_entry_get_key(entry), gconf_value_to_string(gconf_entry_get_value(entry))); + + /* We cannot know when the IAP is fully added to gconf, so a timer is + * installed instead. When the timer expires we hope that IAP is added ok. + */ + QString iap_id = QString(key + iap_prefix_len + 1).section('/',0,0); + timers.add(iap_id, d); +} + + +void IapMonitor::iapDeleted(const char *key, GConfEntry * /*entry*/) +{ + //qDebug("Notify called for deleted element: %s", gconf_entry_get_key(entry)); + + /* We are only interested in IAP deletions so we skip the config entries + */ + if (strstr(key + iap_prefix_len + 1, "/")) { + //qDebug("Deleting IAP config %s", key+iap_prefix_len); + return; + } + + QString iap_id = key + iap_prefix_len + 1; + d->deleteConfiguration(iap_id); +} diff --git a/src/plugins/bearer/icd/monitor.h b/src/plugins/bearer/icd/monitor.h new file mode 100644 index 0000000..82b0f36 --- /dev/null +++ b/src/plugins/bearer/icd/monitor.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef MONITOR_H +#define MONITOR_H + +#include +#include + +#include +#include + +#include + +class QIcdEngine; + +/* The IapAddTimer is a helper class that makes sure we update + * the configuration only after all gconf additions to certain + * iap are finished (after a certain timeout) + */ +class _IapAddTimer : public QObject +{ + Q_OBJECT + +public: + _IapAddTimer() {} + ~_IapAddTimer() + { + if (timer.isActive()) { + QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.stop(); + } + } + + void add(QString& iap_id, QIcdEngine *d); + + QString iap_id; + QTimer timer; + QIcdEngine *d; + +public Q_SLOTS: + void timeout(); +}; + +class IapAddTimer { + QHash timers; + +public: + IapAddTimer() {} + ~IapAddTimer() {} + + void add(QString& iap_id, QIcdEngine *d); + void del(QString& iap_id); + void removeAll(); +}; + +class IapMonitor +{ +public: + IapMonitor() : first_call(true) { } + friend void notify_iap(GConfClient *, guint, + GConfEntry *entry, gpointer user_data); + + void setup(QIcdEngine *d); + void cleanup(); + +private: + bool first_call; + + void iapAdded(const char *key, GConfEntry *entry); + void iapDeleted(const char *key, GConfEntry *entry); + + Maemo::IAPMonitor *iap; + QIcdEngine *d; + IapAddTimer timers; +}; + +#endif // MONITOR_H diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp new file mode 100644 index 0000000..3233eda --- /dev/null +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -0,0 +1,416 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $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 "qicdengine.h" +#include "monitor.h" +#include "qnetworksession_impl.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +IcdNetworkConfigurationPrivate::IcdNetworkConfigurationPrivate() +: network_attrs(0), service_attrs(0) +{ +} + +IcdNetworkConfigurationPrivate::~IcdNetworkConfigurationPrivate() +{ +} + +QString IcdNetworkConfigurationPrivate::bearerName() const +{ + if (iap_type == QLatin1String("WLAN_INFRA") || + iap_type == QLatin1String("WLAN_ADHOC")) { + return QLatin1String("WLAN"); + } else if (iap_type == QLatin1String("GPRS")) { + return QLatin1String("HSPA"); + } else { + return iap_type; + } +} + +static inline QString network_attrs_to_security(uint network_attrs) +{ + uint cap = 0; + nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */ + if (cap & WLANCOND_OPEN) + return "NONE"; + else if (cap & WLANCOND_WEP) + return "WEP"; + else if (cap & WLANCOND_WPA_PSK) + return "WPA_PSK"; + else if (cap & WLANCOND_WPA_EAP) + return "WPA_EAP"; + return ""; +} + +QIcdEngine::QIcdEngine(QObject *parent) +: QBearerEngine(parent), iapMonitor(new IapMonitor) +{ + /* Turn on IAP monitoring */ + iapMonitor->setup(this); + + doRequestUpdate(); +} + +QIcdEngine::~QIcdEngine() +{ +} + +bool QIcdEngine::hasIdentifier(const QString &id) +{ + return accessPointConfigurations.contains(id) || + snapConfigurations.contains(id) || + userChoiceConfigurations.contains(id); +} + +void QIcdEngine::requestUpdate() +{ + QTimer::singleShot(0, this, SLOT(doRequestUpdate())); +} + +static uint32_t getNetworkAttrs(bool is_iap_id, + QString& iap_id, + QString& iap_type, + QString security_method) +{ + guint network_attr = 0; + dbus_uint32_t cap = 0; + + if (iap_type == "WLAN_INFRA") + cap |= WLANCOND_INFRA; + else if (iap_type == "WLAN_ADHOC") + cap |= WLANCOND_ADHOC; + + if (security_method.isEmpty() && (cap & (WLANCOND_INFRA | WLANCOND_ADHOC))) { + Maemo::IAPConf saved_ap(iap_id); + security_method = saved_ap.value("wlan_security").toString(); + } + + if (!security_method.isEmpty()) { + if (security_method == "WEP") + cap |= WLANCOND_WEP; + else if (security_method == "WPA_PSK") + cap |= WLANCOND_WPA_PSK; + else if (security_method == "WPA_EAP") + cap |= WLANCOND_WPA_EAP; + else if (security_method == "NONE") + cap |= WLANCOND_OPEN; + + if (cap & (WLANCOND_WPA_PSK | WLANCOND_WPA_EAP)) { + Maemo::IAPConf saved_iap(iap_id); + bool wpa2_only = saved_iap.value("EAP_wpa2_only_mode").toBool(); + if (wpa2_only) { + cap |= WLANCOND_WPA2; + } + } + } + + cap2nwattr(cap, &network_attr); + if (is_iap_id) + network_attr |= ICD_NW_ATTR_IAPNAME; + + return (uint32_t)network_attr; +} + +void QIcdEngine::doRequestUpdate() +{ + QStringList previous = accessPointConfigurations.keys(); + + /* All the scanned access points */ + QList scanned; + + /* We create a default configuration which is a pseudo config */ + if (!userChoiceConfigurations.contains(OSSO_IAP_ANY)) { + QNetworkConfigurationPrivatePointer ptr(new IcdNetworkConfigurationPrivate); + + ptr->name = QLatin1String("UserChoice"); + ptr->state = QNetworkConfiguration::Discovered; + ptr->isValid = true; + ptr->id = OSSO_IAP_ANY; + ptr->type = QNetworkConfiguration::UserChoice; + ptr->purpose = QNetworkConfiguration::UnknownPurpose; + ptr->roamingSupported = false; + + userChoiceConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + + /* We return currently configured IAPs in the first run and do the WLAN + * scan in subsequent runs. + */ + QList all_iaps; + Maemo::IAPConf::getAll(all_iaps); + + foreach (QString escaped_iap_id, all_iaps) { + QByteArray ssid; + + /* The key that is returned by getAll() needs to be unescaped */ + gchar *unescaped_id = gconf_unescape_key(escaped_iap_id.toUtf8().data(), -1); + QString iap_id = QString((char *)unescaped_id); + g_free(unescaped_id); + + previous.removeAll(iap_id); + + Maemo::IAPConf saved_ap(iap_id); + bool is_temporary = saved_ap.value("temporary").toBool(); + if (is_temporary) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "is temporary, skipping it."; +#endif + continue; + } + + QString iap_type = saved_ap.value("type").toString(); + if (iap_type.startsWith("WLAN")) { + ssid = saved_ap.value("wlan_ssid").toByteArray(); + if (ssid.isEmpty()) { + qWarning() << "Cannot get ssid for" << iap_id; + continue; + } + + QString security_method = saved_ap.value("wlan_security").toString(); + } else if (iap_type.isEmpty()) { + qWarning() << "IAP" << iap_id << "network type is not set! Skipping it"; + continue; + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "network type is" << iap_type; +#endif + ssid.clear(); + } + + if (!accessPointConfigurations.contains(iap_id)) { + IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + + cpPriv->name = saved_ap.value("name").toString(); + if (cpPriv->name.isEmpty()) + if (!ssid.isEmpty() && ssid.size() > 0) + cpPriv->name = ssid.data(); + else + cpPriv->name = iap_id; + cpPriv->isValid = true; + cpPriv->id = iap_id; + cpPriv->network_id = ssid; + cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); + cpPriv->iap_type = iap_type; + cpPriv->service_id = saved_ap.value("service_id").toString(); + cpPriv->service_type = saved_ap.value("service_type").toString(); + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + cpPriv->state = QNetworkConfiguration::Defined; + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(iap_id, ptr); + emit configurationAdded(ptr); + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, name: %s, ssid: %s, added to known list", + iap_id.toAscii().data(), ptr->name.toAscii().data(), + !ssid.isEmpty() ? ssid.data() : "-"); +#endif + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, ssid: %s, already exists in the known list", + iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); +#endif + } + } + + if (sender()) { + QStringList scannedNetworkTypes; + QStringList networkTypesToScan; + QString error; + Maemo::Icd icd(ICD_SHORT_SCAN_TIMEOUT); + + scannedNetworkTypes = icd.scan(ICD_SCAN_REQUEST_ACTIVE, + networkTypesToScan, + scanned, + error); + if (!error.isEmpty()) { + qWarning() << "Network scanning failed" << error; + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + if (!scanned.isEmpty()) + qDebug() << "Scan returned" << scanned.size() << "networks"; + else + qDebug() << "Scan returned nothing."; +#endif + } + } + + /* This is skipped in the first update as scanned size is zero */ + if (!scanned.isEmpty()) { + for (int i=0; iisValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->state != QNetworkConfiguration::Discovered) { + ptr->state = QNetworkConfiguration::Discovered; + changed = true; + } + + toIcdConfig(ptr)->network_attrs = ap.scan.network_attrs; + toIcdConfig(ptr)->service_id = ap.scan.service_id; + toIcdConfig(ptr)->service_type = ap.scan.service_type; + toIcdConfig(ptr)->service_attrs = ap.scan.service_attrs; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, ssid: %s, discovered", + iapid.toAscii().data(), scanned_ssid.data()); +#endif + + if (changed) + emit configurationChanged(ptr); + + if (!ap.scan.network_type.startsWith("WLAN")) + continue; // not a wlan AP + } + } else { + IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + + QString hrs = scanned_ssid.data(); + + cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; + cpPriv->isValid = true; + // Note: id is now ssid, it should be set to IAP id if the IAP is saved + cpPriv->id = scanned_ssid.data(); + cpPriv->network_id = scanned_ssid; + cpPriv->iap_type = ap.scan.network_type; + if (cpPriv->iap_type.isEmpty()) + cpPriv->iap_type = QLatin1String("WLAN"); + cpPriv->network_attrs = ap.scan.network_attrs; + cpPriv->service_id = ap.scan.service_id; + cpPriv->service_type = ap.scan.service_type; + cpPriv->service_attrs = ap.scan.service_attrs; + + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + cpPriv->state = QNetworkConfiguration::Undefined; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan."; +#endif + + previous.removeAll(cpPriv->id); + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + } + } + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(previous.takeFirst()); + + emit configurationRemoved(ptr); + } + + if (sender()) + emit updateCompleted(); +} + +void QIcdEngine::deleteConfiguration(const QString &iap_id) +{ + /* Called when IAPs are deleted in gconf, in this case we do not scan + * or read all the IAPs from gconf because it might take too much power + * (multiple applications would need to scan and read all IAPs from gconf) + */ + if (accessPointConfigurations.contains(iap_id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(iap_id); + + if (ptr) { + ptr->isValid = false; +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "was removed from storage."; +#endif + + emit configurationRemoved(ptr); + } else { + qWarning("Configuration not found for IAP %s", iap_id.toAscii().data()); + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data()); +#endif + } +} + +QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const +{ + return QNetworkConfigurationManager::CanStartAndStopInterfaces | + QNetworkConfigurationManager::DataStatistics | + QNetworkConfigurationManager::ForcedRoaming; +} + +QNetworkSessionPrivate *QIcdEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl(this); +} + +QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration() +{ + // Here we just return [ANY] request to icd and let the icd decide which IAP to connect. + return userChoiceConfigurations.value(OSSO_IAP_ANY); +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h new file mode 100644 index 0000000..30b5711 --- /dev/null +++ b/src/plugins/bearer/icd/qicdengine.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef QICDENGINE_H +#define QICDENGINE_H + +#include + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; +class IapMonitor; + +class IcdNetworkConfigurationPrivate : public QNetworkConfigurationPrivate +{ +public: + IcdNetworkConfigurationPrivate(); + ~IcdNetworkConfigurationPrivate(); + + QString bearerName() const; + + // In Maemo the id field (defined in QNetworkConfigurationPrivate) + // is the IAP id (which typically is UUID) + QByteArray network_id; // typically WLAN ssid or similar + QString iap_type; // is this one WLAN or GPRS + + // Network attributes for this IAP, this is the value returned by icd and + // passed to it when connecting. + uint32_t network_attrs; + + QString service_type; + QString service_id; + uint32_t service_attrs; +}; + +inline IcdNetworkConfigurationPrivate *toIcdConfig(QNetworkConfigurationPrivatePointer ptr) +{ + return static_cast(ptr.data()); +} + +class QIcdEngine : public QBearerEngine +{ + Q_OBJECT + + friend class QNetworkSessionPrivateImpl; + +public: + QIcdEngine(QObject *parent = 0); + ~QIcdEngine(); + + bool hasIdentifier(const QString &id); + + void requestUpdate(); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + + void deleteConfiguration(const QString &iap_id); + +private: + inline void addSessionConfiguration(QNetworkConfigurationPrivatePointer ptr) + { + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + + inline void changedSessionConfiguration(QNetworkConfigurationPrivatePointer ptr) + { + emit configurationChanged(ptr); + } + +private Q_SLOTS: + void doRequestUpdate(); + +private: + IapMonitor *iapMonitor; +}; + +QT_END_NAMESPACE + +#endif // QICDENGINE_H diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp new file mode 100644 index 0000000..6cc4a1d --- /dev/null +++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp @@ -0,0 +1,1105 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $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_impl.h" +#include "qicdengine.h" + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +static QHash properties; + +static QString get_network_interface(); +static DBusConnection *dbus_connection; +static DBusHandlerResult signal_handler(DBusConnection *connection, + DBusMessage *message, + void *user_data); + +#define ICD_DBUS_MATCH "type='signal'," \ + "interface='" ICD_DBUS_INTERFACE "'," \ + "path='" ICD_DBUS_PATH "'" + + +static inline DBusConnection *get_dbus_conn(DBusError *error) +{ + DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error); +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn); +#endif + + return conn; +} + + +/* Helper class that monitors the Icd status messages and + * can change the IAP status accordingly. This is a singleton. + */ +class IcdListener : public QObject +{ + Q_OBJECT + +public: + IcdListener() : first_call(true) { } + friend DBusHandlerResult signal_handler(DBusConnection *connection, + DBusMessage *message, + void *user_data); + void setup(QNetworkSessionPrivateImpl *d); + void cleanup(); + void cleanupSession(QNetworkSessionPrivateImpl *ptr); + + enum IapConnectionStatus { + /* The IAP was connected */ + CONNECTED = 0, + /* The IAP was disconnected */ + DISCONNECTED, + /* The IAP is disconnecting */ + DISCONNECTING, + /* The IAP has a network address, but is not yet fully connected */ + NETWORK_UP + }; + +private: + void icdSignalReceived(QString&, QString&, QString&); + bool first_call; + QHash sessions; +}; + +Q_GLOBAL_STATIC(IcdListener, icdListener); + + +static DBusHandlerResult signal_handler(DBusConnection *, + DBusMessage *message, + void *user_data) +{ + if (dbus_message_is_signal(message, + ICD_DBUS_INTERFACE, + ICD_STATUS_CHANGED_SIG)) { + + IcdListener *icd = (IcdListener *)user_data; + DBusError error; + dbus_error_init(&error); + + char *iap_id = 0; + char *network_type = 0; + char *state = 0; + + if (dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &iap_id, + DBUS_TYPE_STRING, &network_type, + DBUS_TYPE_STRING, &state, + DBUS_TYPE_INVALID) == FALSE) { + qWarning() << QString("Failed to parse icd status signal: %1").arg(error.message); + } else { + QString _iap_id(iap_id); + QString _network_type(network_type); + QString _state(state); + + icd->icdSignalReceived(_iap_id, _network_type, _state); + } + + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + +void IcdListener::setup(QNetworkSessionPrivateImpl *d) +{ + if (first_call) { + // We use the old Icd dbus interface like in ConIC + DBusError error; + dbus_error_init(&error); + + dbus_connection = get_dbus_conn(&error); + if (dbus_error_is_set(&error)) { + qWarning() << "Cannot get dbus connection."; + dbus_error_free(&error); + return; + } + + static struct DBusObjectPathVTable icd_vtable; + icd_vtable.message_function = signal_handler; + + dbus_bus_add_match(dbus_connection, ICD_DBUS_MATCH, &error); + if (dbus_error_is_set(&error)) { + qWarning() << "Cannot add match" << ICD_DBUS_MATCH; + dbus_error_free(&error); + return; + } + + if (dbus_connection_register_object_path(dbus_connection, + ICD_DBUS_PATH, + &icd_vtable, + (void*)this) == FALSE) { + qWarning() << "Cannot register dbus signal handler, interface"<< ICD_DBUS_INTERFACE << "path" << ICD_DBUS_PATH; + dbus_error_free(&error); + return; + } + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE; +#endif + first_call = false; + dbus_error_free(&error); + } + + QString id = d->activeConfig.identifier(); + if (!sessions.contains(id)) { + QNetworkSessionPrivateImpl *ptr = d; + sessions.insert(id, ptr); + } +} + + +void IcdListener::icdSignalReceived(QString& iap_id, +#ifdef BEARER_MANAGEMENT_DEBUG + QString& network_type, +#else + QString&, +#endif + QString& state) +{ + if (iap_id == OSSO_IAP_SCAN) // icd sends scan status signals which we will ignore + return; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Status received:" << iap_id << "type" << network_type << "state" << state; +#endif + + if (!sessions.contains(iap_id)) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "No session for IAP" << iap_id; +#endif + return; + } + + QNetworkSessionPrivateImpl *session = sessions.value(iap_id); + QNetworkConfiguration ap_conf = + QNetworkConfigurationManager().configurationFromIdentifier(iap_id); + if (!ap_conf.isValid()) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Unknown IAP" << iap_id; +#endif + return; + } + + IapConnectionStatus status; + + if (state == "IDLE") { + status = DISCONNECTED; + } else if (state == "CONNECTED") { + status = CONNECTED; + } else if (state == "NETWORKUP") { + status = NETWORK_UP; + } else { + //qDebug() << "Unknown state" << state; + return; + } + + if (status == DISCONNECTED) { + if (ap_conf.state() == QNetworkConfiguration::Active) { + /* The IAP was just disconnected by Icd */ + session->updateState(QNetworkSession::Disconnected); + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Got a network disconnect when in state" << ap_conf.state(); +#endif + } + } else if (status == CONNECTED) { + /* The IAP was just connected by Icd */ + session->updateState(QNetworkSession::Connected); + session->updateIdentifier(iap_id); + + if (session->publicConfig.identifier() == OSSO_IAP_ANY) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "connected when connecting to" << OSSO_IAP_ANY; +#endif + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "connected"; +#endif + } + } + + return; +} + + +void IcdListener::cleanup() +{ + if (!first_call) { + dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL); + dbus_connection_unref(dbus_connection); + } +} + + +void IcdListener::cleanupSession(QNetworkSessionPrivateImpl *ptr) +{ + if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice) + (void)sessions.take(ptr->activeConfig.identifier()); + else + (void)sessions.take(ptr->publicConfig.identifier()); +} + + +void QNetworkSessionPrivateImpl::cleanupSession(void) +{ + icdListener()->cleanupSession(this); +} + + +void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState) +{ + if (newState == state) + return; + + state = newState; + + if (state == QNetworkSession::Disconnected) { + isOpen = false; + currentNetworkInterface.clear(); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + privateConfiguration(activeConfig)->state = QNetworkConfiguration::Defined; + privateConfiguration(publicConfig)->state = QNetworkConfiguration::Defined; + + } else if (state == QNetworkSession::Connected) { + isOpen = true; + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + privateConfiguration(activeConfig)->state = QNetworkConfiguration::Active; + privateConfiguration(activeConfig)->type = QNetworkConfiguration::InternetAccessPoint; + } + privateConfiguration(publicConfig)->state = QNetworkConfiguration::Active; + } + + emit stateChanged(newState); +} + + +void QNetworkSessionPrivateImpl::updateIdentifier(QString &newId) +{ + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + toIcdConfig(privateConfiguration(activeConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME; + privateConfiguration(activeConfig)->id = newId; + } else { + toIcdConfig(privateConfiguration(publicConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME; + if (privateConfiguration(publicConfig)->id != newId) { + qWarning() << "Your config id changed from" << privateConfiguration(publicConfig)->id + << "to" << newId; + privateConfiguration(publicConfig)->id = newId; + } + } +} + + +quint64 QNetworkSessionPrivateImpl::getStatistics(bool sent) const +{ + /* This could be also implemented by using the Maemo::Icd::statistics() + * that gets the statistics data for a specific IAP. Change if + * necessary. + */ + Maemo::Icd icd; + QList stats_results; + quint64 counter_rx = 0, counter_tx = 0; + + if (!icd.statistics(stats_results)) { + return 0; + } + + foreach (Maemo::IcdStatisticsResult res, stats_results) { + if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) { + /* network_id is the IAP UUID */ + if (QString(res.params.network_id.data()) == activeConfig.identifier()) { + counter_tx = res.bytes_sent; + counter_rx = res.bytes_received; + } + } else { + /* We probably will never get to this branch */ + if (res.params.network_id == toIcdConfig(privateConfiguration(activeConfig))->network_id) { + counter_tx = res.bytes_sent; + counter_rx = res.bytes_received; + } + } + } + + if (sent) + return counter_tx; + else + return counter_rx; +} + + +quint64 QNetworkSessionPrivateImpl::bytesWritten() const +{ + return getStatistics(true); +} + +quint64 QNetworkSessionPrivateImpl::bytesReceived() const +{ + return getStatistics(false); +} + +quint64 QNetworkSessionPrivateImpl::activeTime() const +{ + if (startTime.isNull()) { + return 0; + } + return startTime.secsTo(QDateTime::currentDateTime()); +} + + +QNetworkConfiguration& QNetworkSessionPrivateImpl::copyConfig(QNetworkConfiguration &fromConfig, + QNetworkConfiguration &toConfig, + bool deepCopy) +{ + IcdNetworkConfigurationPrivate *cpPriv; + if (deepCopy) { + cpPriv = new IcdNetworkConfigurationPrivate; + setPrivateConfiguration(toConfig, QNetworkConfigurationPrivatePointer(cpPriv)); + } else { + cpPriv = toIcdConfig(privateConfiguration(toConfig)); + } + + cpPriv->name = privateConfiguration(fromConfig)->name; + cpPriv->isValid = privateConfiguration(fromConfig)->isValid; + // Note that we do not copy id field here as the publicConfig does + // not contain a valid IAP id. + cpPriv->state = privateConfiguration(fromConfig)->state; + cpPriv->type = privateConfiguration(fromConfig)->type; + cpPriv->roamingSupported = privateConfiguration(fromConfig)->roamingSupported; + cpPriv->purpose = privateConfiguration(fromConfig)->purpose; + cpPriv->network_id = toIcdConfig(privateConfiguration(fromConfig))->network_id; + cpPriv->iap_type = toIcdConfig(privateConfiguration(fromConfig))->iap_type; + cpPriv->network_attrs = toIcdConfig(privateConfiguration(fromConfig))->network_attrs; + cpPriv->service_type = toIcdConfig(privateConfiguration(fromConfig))->service_type; + cpPriv->service_id = toIcdConfig(privateConfiguration(fromConfig))->service_id; + cpPriv->service_attrs = toIcdConfig(privateConfiguration(fromConfig))->service_attrs; + + return toConfig; +} + + +/* This is called by QNetworkSession constructor and it updates the current + * state of the configuration. + */ +void QNetworkSessionPrivateImpl::syncStateWithInterface() +{ + /* Start to listen Icd status messages. */ + icdListener()->setup(this); + + /* Initially we are not active although the configuration might be in + * connected state. + */ + isOpen = false; + opened = false; + + connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged())); + + connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)), + this, SLOT(configurationChanged(QNetworkConfiguration))); + + state = QNetworkSession::Invalid; + lastError = QNetworkSession::UnknownSessionError; + + switch (publicConfig.type()) { + case QNetworkConfiguration::InternetAccessPoint: + activeConfig = publicConfig; + break; + case QNetworkConfiguration::ServiceNetwork: + serviceConfig = publicConfig; + break; + case QNetworkConfiguration::UserChoice: + // active config will contain correct data after open() has succeeded + copyConfig(publicConfig, activeConfig); + + /* We create new configuration that holds the actual configuration + * returned by icd. This way publicConfig still contains the + * original user specified configuration. + * + * Note that the new activeConfig configuration is not inserted + * to configurationManager as manager class will get the newly + * connected configuration from gconf when the IAP is saved. + * This configuration manager update is done by IapMonitor class. + * If the ANY connection fails in open(), then the configuration + * data is not saved to gconf and will not be added to + * configuration manager IAP list. + */ +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug()<<"New configuration created for" << publicConfig.identifier(); +#endif + break; + default: + /* Invalid configuration, no point continuing */ + return; + } + + if (!activeConfig.isValid()) + return; + + /* Get the initial state from icd */ + Maemo::Icd icd; + QList state_results; + + /* Update the active config from first connection, this is ok as icd + * supports only one connection anyway. + */ + if (icd.state(state_results) && !state_results.isEmpty()) { + + /* If we did not get full state back, then we are not + * connected and can skip the next part. + */ + if (!(state_results.first().params.network_attrs == 0 && + state_results.first().params.network_id.isEmpty())) { + + /* If we try to connect to specific IAP and we get results back + * that tell the icd is actually connected to another IAP, + * then do not update current state etc. + */ + if (publicConfig.type() == QNetworkConfiguration::UserChoice || + privateConfiguration(publicConfig)->id == state_results.first().params.network_id) { + + switch (state_results.first().state) { + case ICD_STATE_DISCONNECTED: + state = QNetworkSession::Disconnected; + if (privateConfiguration(activeConfig)) + privateConfiguration(activeConfig)->isValid = true; + break; + case ICD_STATE_CONNECTING: + state = QNetworkSession::Connecting; + if (privateConfiguration(activeConfig)) + privateConfiguration(activeConfig)->isValid = true; + break; + case ICD_STATE_CONNECTED: + { + if (!state_results.first().error.isEmpty()) + break; + + const QString id = state_results.first().params.network_id; + + QNetworkConfiguration config = manager.configurationFromIdentifier(id); + if (config.isValid()) { + //we don't want the copied data if the config is already known by the manager + //just reuse it so that existing references to the old data get the same update + setPrivateConfiguration(activeConfig, privateConfiguration(config)); + } + + QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + + state = QNetworkSession::Connected; + toIcdConfig(ptr)->network_id = state_results.first().params.network_id; + ptr->id = toIcdConfig(ptr)->network_id; + toIcdConfig(ptr)->network_attrs = state_results.first().params.network_attrs; + toIcdConfig(ptr)->iap_type = state_results.first().params.network_type; + toIcdConfig(ptr)->service_type = state_results.first().params.service_type; + toIcdConfig(ptr)->service_id = state_results.first().params.service_id; + toIcdConfig(ptr)->service_attrs = state_results.first().params.service_attrs; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->state = QNetworkConfiguration::Active; + ptr->isValid = true; + currentNetworkInterface = get_network_interface(); + + Maemo::IAPConf iap_name(privateConfiguration(activeConfig)->id); + QString name_value = iap_name.value("name").toString(); + if (!name_value.isEmpty()) + privateConfiguration(activeConfig)->name = name_value; + else + privateConfiguration(activeConfig)->name = privateConfiguration(activeConfig)->id; + + + // Add the new active configuration to manager or update the old config + if (!(engine->accessPointConfigurations.contains(privateConfiguration(activeConfig)->id))) + engine->addSessionConfiguration(privateConfiguration(activeConfig)); + else + engine->changedSessionConfiguration(privateConfiguration(activeConfig)); + } + break; + + case ICD_STATE_DISCONNECTING: + state = QNetworkSession::Closing; + if (privateConfiguration(activeConfig)) + privateConfiguration(activeConfig)->isValid = true; + break; + default: + break; + } + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "status_req tells icd is not connected"; +#endif + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "status_req did not return any results from icd"; +#endif + } + + networkConfigurationsChanged(); +} + + +void QNetworkSessionPrivateImpl::networkConfigurationsChanged() +{ + if (serviceConfig.isValid()) + updateStateFromServiceNetwork(); + else + updateStateFromActiveConfig(); +} + + +void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() +{ + QNetworkSession::State oldState = state; + + foreach (const QNetworkConfiguration &config, serviceConfig.children()) { + if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) + continue; + + if (activeConfig != config) { + activeConfig = config; + 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::clearConfiguration(QNetworkConfiguration &config) +{ + toIcdConfig(privateConfiguration(config))->network_id.clear(); + toIcdConfig(privateConfiguration(config))->iap_type.clear(); + toIcdConfig(privateConfiguration(config))->network_attrs = 0; + toIcdConfig(privateConfiguration(config))->service_type.clear(); + toIcdConfig(privateConfiguration(config))->service_id.clear(); + toIcdConfig(privateConfiguration(config))->service_attrs = 0; +} + + +void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() +{ + QNetworkSession::State oldState = state; + + bool newActive = false; + + if (!privateConfiguration(activeConfig)) + return; + + if (!activeConfig.isValid()) { + state = QNetworkSession::Invalid; + clearConfiguration(activeConfig); + } 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; + //clearConfiguration(activeConfig); + } + + bool oldActive = isOpen; + isOpen = newActive; + + if (!oldActive && isOpen) + emit quitPendingWaitsForOpened(); + + if (oldActive && !isOpen) + emit closed(); + + if (oldState != state) { + emit stateChanged(state); + + if (state == QNetworkSession::Disconnected) { +#ifdef BEARER_MANAGEMENT_DEBUG + //qDebug()<<"session aborted error emitted for"<ifa_next) { + family = ifa->ifa_addr->sa_family; + if (family != AF_INET) { + continue; /* Currently only IPv4 is supported by icd dbus interface */ + } + if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) { + iface = QString(ifa->ifa_name); + break; + } + } + + freeifaddrs(ifaddr); + return iface; +} + + +void QNetworkSessionPrivateImpl::open() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (!isOpen) { + + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + /* Caller is trying to connect to default IAP. + * At this time we will not know the IAP details so we just + * connect and update the active config when the IAP is + * connected. + */ + opened = true; + state = QNetworkSession::Connecting; + emit stateChanged(state); + QTimer::singleShot(0, this, SLOT(do_open())); + return; + } + + /* User is connecting to one specific IAP. If that IAP is not + * in discovered state we cannot continue. + */ + if ((activeConfig.state() & QNetworkConfiguration::Discovered) != + QNetworkConfiguration::Discovered) { + lastError =QNetworkSession::InvalidConfigurationError; + emit QNetworkSessionPrivate::error(lastError); + return; + } + opened = true; + + if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) { + state = QNetworkSession::Connecting; + emit stateChanged(state); + + QTimer::singleShot(0, this, SLOT(do_open())); + return; + } + + isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active; + if (isOpen) + emit quitPendingWaitsForOpened(); + } else { + /* We seem to be active so inform caller */ + emit quitPendingWaitsForOpened(); + } +} + + +void QNetworkSessionPrivateImpl::do_open() +{ + icd_connection_flags flags = connectFlags; + bool st; + QString result; + QString iap = publicConfig.identifier(); + + if (state == QNetworkSession::Connected) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Already connected to" << activeConfig.identifier(); +#endif + emit stateChanged(QNetworkSession::Connected); + emit quitPendingWaitsForOpened(); + return; + } + + Maemo::IcdConnectResult connect_result; + Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT); + QNetworkConfiguration config; + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + config = activeConfig; + else + config = publicConfig; + + if (iap == OSSO_IAP_ANY) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connecting to default IAP" << iap; +#endif + st = icd.connect(flags, connect_result); + + } else { + + QList params; + Maemo::ConnectParams param; + param.connect.service_type = toIcdConfig(privateConfiguration(config))->service_type; + param.connect.service_attrs = toIcdConfig(privateConfiguration(config))->service_attrs; + param.connect.service_id = toIcdConfig(privateConfiguration(config))->service_id; + param.connect.network_type = toIcdConfig(privateConfiguration(config))->iap_type; + param.connect.network_attrs = toIcdConfig(privateConfiguration(config))->network_attrs; + if (toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME) + param.connect.network_id = QByteArray(iap.toLatin1()); + else + param.connect.network_id = toIcdConfig(privateConfiguration(config))->network_id; + params.append(param); + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s", + param.connect.network_id.data(), + param.connect.network_type.toAscii().constData(), + param.connect.network_attrs, + param.connect.service_type.toAscii().constData(), + param.connect.service_attrs, + param.connect.service_id.toAscii().constData()); +#endif + st = icd.connect(flags, params, connect_result); + } + + if (st) { + result = connect_result.connect.network_id.data(); + QString connected_iap = result; + + if (connected_iap.isEmpty()) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connect to"<< iap << "failed, result is empty"; +#endif + updateState(QNetworkSession::Disconnected); + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + cleanupAnyConfiguration(); + return; + } + + /* If the user tried to connect to some specific connection (foo) + * and we were already connected to some other connection (bar), + * then we cannot activate this session although icd has a valid + * connection to somewhere. + */ + if ((publicConfig.type() != QNetworkConfiguration::UserChoice) && + (connected_iap != config.identifier())) { + updateState(QNetworkSession::Disconnected); + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); + return; + } + + + /* Did we connect to non saved IAP? */ + if (!(toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)) { + /* Because the connection succeeded, the IAP is now known. + */ + toIcdConfig(privateConfiguration(config))->network_attrs |= ICD_NW_ATTR_IAPNAME; + privateConfiguration(config)->id = connected_iap; + } + + /* User might have changed the IAP name when a new IAP was saved */ + Maemo::IAPConf iap_name(privateConfiguration(config)->id); + QString name = iap_name.value("name").toString(); + if (!name.isEmpty()) + privateConfiguration(config)->name = name; + + toIcdConfig(privateConfiguration(config))->iap_type = connect_result.connect.network_type; + + privateConfiguration(config)->isValid = true; + privateConfiguration(config)->state = QNetworkConfiguration::Active; + privateConfiguration(config)->type = QNetworkConfiguration::InternetAccessPoint; + + startTime = QDateTime::currentDateTime(); + updateState(QNetworkSession::Connected); + + currentNetworkInterface = get_network_interface(); + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connected to" << result << config.name() << "at" << currentNetworkInterface; +#endif + + /* We first check if the configuration already exists in the manager + * and if it is not found there, we then insert it. Note that this + * is only done for user choice config only because it can be missing + * from config manager list. + */ + + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + if (!engine->accessPointConfigurations.contains(result)) { + engine->addSessionConfiguration(privateConfiguration(config)); + } else { + QNetworkConfigurationPrivatePointer priv = + engine->accessPointConfigurations.value(result); + QNetworkConfiguration reference; + setPrivateConfiguration(reference, priv); + copyConfig(config, reference, false); + config = reference; + activeConfig = reference; + engine->changedSessionConfiguration(privateConfiguration(config)); + } + } + + emit quitPendingWaitsForOpened(); + + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connect to"<< iap << "failed, status:" << connect_result.status; +#endif + updateState(QNetworkSession::Disconnected); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + cleanupAnyConfiguration(); + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(QNetworkSession::UnknownSessionError); + } +} + + +void QNetworkSessionPrivateImpl::cleanupAnyConfiguration() +{ +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug()<<"Removing configuration created for" << activeConfig.identifier(); +#endif + activeConfig = publicConfig; +} + + +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); + + Maemo::Icd icd; +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "stopping session" << publicConfig.identifier(); +#endif + icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT); + startTime = QDateTime(); + + /* Note that the state will go disconnected in + * updateStateFromActiveConfig() which gets called after + * configurationChanged is emitted (below). + */ + + privateConfiguration(activeConfig)->state = QNetworkConfiguration::Discovered; + engine->changedSessionConfiguration(privateConfiguration(activeConfig)); + + opened = false; + isOpen = false; + + } else { + opened = false; + isOpen = false; + emit closed(); + } + } +} + + +void QNetworkSessionPrivateImpl::migrate() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +void QNetworkSessionPrivateImpl::accept() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +void QNetworkSessionPrivateImpl::ignore() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +void QNetworkSessionPrivateImpl::reject() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const +{ + if (!publicConfig.isValid() || state != QNetworkSession::Connected) + return QNetworkInterface(); + + if (currentNetworkInterface.isEmpty()) + return QNetworkInterface(); + + return QNetworkInterface::interfaceFromName(currentNetworkInterface); +} + + +void QNetworkSessionPrivateImpl::setSessionProperty(const QString& key, const QVariant& value) +{ + if (value.isValid()) { + properties.insert(key, value); + + if (key == "ConnectInBackground") { + bool v = value.toBool(); + if (v) + connectFlags = ICD_CONNECTION_FLAG_APPLICATION_EVENT; + else + connectFlags = ICD_CONNECTION_FLAG_USER_EVENT; + } + } else { + properties.remove(key); + + /* Set default value when property is removed */ + if (key == "ConnectInBackground") + connectFlags = ICD_CONNECTION_FLAG_USER_EVENT; + } +} + + +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& key) const +{ + return properties.value(key); +} + + +QString QNetworkSessionPrivateImpl::errorString() const +{ + QString errorStr; + switch(q->error()) { + case QNetworkSession::RoamingError: + errorStr = QObject::tr("Roaming error"); + break; + case QNetworkSession::SessionAbortedError: + errorStr = QObject::tr("Session aborted by user or system"); + break; + default: + case QNetworkSession::UnknownSessionError: + errorStr = QObject::tr("Unidentified Error"); + break; + } + return errorStr; +} + + +QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const +{ + return QNetworkSession::UnknownSessionError; +} + +#include "qnetworksession_impl.moc" + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/qnetworksession_impl.h b/src/plugins/bearer/icd/qnetworksession_impl.h new file mode 100644 index 0000000..22e41b3 --- /dev/null +++ b/src/plugins/bearer/icd/qnetworksession_impl.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** 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 QtNetwork module of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#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 for the convenience +// of the QLibrary class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +//#include "qnetworkconfigmanager_maemo_p.h" +//#include "qnetworksession.h" + +//#include +//#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QIcdEngine; + +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate +{ + Q_OBJECT + +public: + QNetworkSessionPrivateImpl(QIcdEngine *engine) + : engine(engine), connectFlags(ICD_CONNECTION_FLAG_USER_EVENT) + { + } + + ~QNetworkSessionPrivateImpl() + { + cleanupSession(); + } + + //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(); + + QNetworkInterface currentInterface() const; + QVariant sessionProperty(const QString& key) const; + void setSessionProperty(const QString& key, const QVariant& value); + + void open(); + void close(); + void stop(); + + void migrate(); + void accept(); + void ignore(); + void reject(); + + QString errorString() const; //must return translated string + QNetworkSession::SessionError error() const; + + quint64 bytesWritten() const; + quint64 bytesReceived() const; + quint64 activeTime() const; + +private: + void updateStateFromServiceNetwork(); + void updateStateFromActiveConfig(); + +private Q_SLOTS: + void do_open(); + void networkConfigurationsChanged(); + void configurationChanged(const QNetworkConfiguration &config); + +private: + QNetworkConfigurationManager manager; + QIcdEngine *engine; + + QNetworkConfiguration& copyConfig(QNetworkConfiguration &fromConfig, QNetworkConfiguration &toConfig, bool deepCopy = true); + void clearConfiguration(QNetworkConfiguration &config); + void cleanupAnyConfiguration(); + + bool opened; + icd_connection_flags connectFlags; + + QNetworkSession::SessionError lastError; + + QDateTime startTime; + QString currentNetworkInterface; + friend class IcdListener; + void updateState(QNetworkSession::State); + void updateIdentifier(QString &newId); + quint64 getStatistics(bool sent) const; + void cleanupSession(void); +}; + +QT_END_NAMESPACE + +#endif //QNETWORKSESSIONPRIVATE_H + -- cgit v0.12