From 90de3e5c903b67b2e5f3d7dc14266fe24f1daa23 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Wed, 14 Apr 2010 16:23:22 +1000 Subject: Bearer management changes from Qt Mobility (7a5ff985) 7a5ff9859f5775915ae80c287f51c772599c2379 --- config.tests/unix/icd/icd.cpp | 8 +- configure | 34 +- examples/network/bearermonitor/bearermonitor.cpp | 28 +- examples/network/bearermonitor/bearermonitor.h | 7 +- examples/network/bearermonitor/bearermonitor.pro | 27 +- .../network/bearermonitor/bearermonitor_maemo.ui | 310 ++++++++ examples/network/bearermonitor/sessionwidget.cpp | 11 + examples/network/bearermonitor/sessionwidget.h | 9 +- .../network/bearermonitor/sessionwidget_maemo.ui | 262 +++++++ src/network/bearer/qnetworksession.cpp | 4 + src/plugins/bearer/corewlan/qcorewlanengine.mm | 89 ++- src/plugins/bearer/icd/icd.pro | 2 - src/plugins/bearer/icd/monitor.cpp | 84 -- src/plugins/bearer/icd/monitor.h | 114 --- src/plugins/bearer/icd/qicdengine.cpp | 841 +++++++++++++++++---- src/plugins/bearer/icd/qicdengine.h | 31 +- src/plugins/bearer/icd/qnetworksession_impl.cpp | 778 ++++++++----------- src/plugins/bearer/icd/qnetworksession_impl.h | 73 +- .../bearer/symbian/qnetworksession_impl.cpp | 166 ++-- src/plugins/bearer/symbian/qnetworksession_impl.h | 9 +- .../qnetworkconfiguration.pro | 2 +- .../tst_qnetworkconfiguration.cpp | 15 +- .../qnetworkconfigurationmanager.pro | 2 +- .../tst_qnetworkconfigurationmanager.cpp | 13 +- tests/auto/qnetworksession/lackey/main.cpp | 7 +- tests/auto/qnetworksession/test/test.pro | 2 +- .../qnetworksession/test/tst_qnetworksession.cpp | 32 +- tests/manual/bearerex/bearerex.h | 11 +- tests/manual/bearerex/bearerex.pro | 14 +- tests/manual/bearerex/bearerex_maemo.ui | 100 +++ tests/manual/bearerex/sessiondialog_maemo.ui | 151 ++++ 31 files changed, 2246 insertions(+), 990 deletions(-) create mode 100644 examples/network/bearermonitor/bearermonitor_maemo.ui create mode 100644 examples/network/bearermonitor/sessionwidget_maemo.ui delete mode 100644 src/plugins/bearer/icd/monitor.cpp delete mode 100644 src/plugins/bearer/icd/monitor.h create mode 100644 tests/manual/bearerex/bearerex_maemo.ui create mode 100644 tests/manual/bearerex/sessiondialog_maemo.ui diff --git a/config.tests/unix/icd/icd.cpp b/config.tests/unix/icd/icd.cpp index e3701ac..8b74fd6 100644 --- a/config.tests/unix/icd/icd.cpp +++ b/config.tests/unix/icd/icd.cpp @@ -42,14 +42,12 @@ #include #include #include -//#include +#include +#include +#include #include -#include -#include - int main(int, char **) { - dbus_shutdown(); return 0; } diff --git a/configure b/configure index 5478d06..d6e401b 100755 --- a/configure +++ b/configure @@ -5241,25 +5241,47 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QWS" = "yes" ]; then if [ "$CFG_GLIB" = "yes" -a "$CFG_ICD" != "no" ]; then # ICD support has a cyclic dependency on Qt. if [ -n "$PKG_CONFIG" ]; then - QT_CFLAGS_ICD=`$PKG_CONFIG --cflags dbus-glib-1 gconf-2.0 osso-ic conninet 2>/dev/null` - QT_LIBS_ICD=`$PKG_CONFIG --libs dbus-glib-1 gconf-2.0 osso-ic conninet 2>/dev/null` + QT_CFLAGS_ICD=`$PKG_CONFIG --cflags osso-ic conninet 2>/dev/null` + QT_LIBS_ICD=`$PKG_CONFIG --libs osso-ic conninet 2>/dev/null` QT_CFLAGS_QTNETWORK=`$PKG_CONFIG --cflags QtNetwork 2>/dev/null` QT_LIBS_QTNETWORK=`$PKG_CONFIG --libs QtNetwork 2>/dev/null` else - QT_CFLAGS_QTNETOWRK= + QT_CFLAGS_QTNETWORK= QT_LIBS_QTNETWORK= fi if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/icd "ICD" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_ICD $QT_LIBS_ICD $QT_CFLAGS_QTNETWORK $QT_LIBS_QTNETWORK; then [ "$CFG_ICD" = "auto" ] && CFG_ICD=yes - QMakeVar set QT_CFLAGS_ICD "$QT_CFLAGS_ICD" - QMakeVar set QT_LIBS_ICD "$QT_LIBS_ICD" + # remove system Qt includes and libraries + QT_CFLAGS_ICD_TRIMMED= + for i in $QT_CFLAGS_ICD; do + case $i in + *qt*) + ;; + *) + QT_CFLAGS_ICD_TRIMMED="$QT_CFLAGS_ICD_TRIMMED $i" + ;; + esac + done + QT_LIBS_ICD_TRIMMED= + for i in $QT_LIBS_ICD; do + case $i in + *qt*|-lQt*) + ;; + *) + QT_LIBS_ICD_TRIMMED="$QT_LIBS_ICD_TRIMMED $i" + ;; + esac + done + + QMakeVar set QT_CFLAGS_ICD "$QT_CFLAGS_ICD_TRIMMED" + QMakeVar set QT_LIBS_ICD "$QT_LIBS_ICD_TRIMMED" else if [ "$CFG_ICD" = "auto" ]; then CFG_ICD=no elif [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then # CFG_ICD is "yes" - echo "The ICD Bearer Management plugin cannot be enabled because dbus-glib-1, gconf-2.0, osso-ic or conninet was not found." + echo "The ICD Bearer Management plugin cannot be enabled because osso-ic or conninet was not found." echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp index 5b2bad1..4a6c6ff 100644 --- a/examples/network/bearermonitor/bearermonitor.cpp +++ b/examples/network/bearermonitor/bearermonitor.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) ** @@ -43,7 +43,7 @@ #include "sessionwidget.h" #include - +#include #ifdef Q_OS_WIN #include #undef interface @@ -57,15 +57,20 @@ BearerMonitor::BearerMonitor(QWidget *parent) : QWidget(parent) { setupUi(this); +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) + newSessionButton->hide(); + deleteSessionButton->hide(); +#else delete tabWidget->currentWidget(); sessionGroup->hide(); -#if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE) +#endif +#if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) setWindowState(Qt::WindowMaximized); #endif updateConfigurations(); - +#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty()); - +#endif QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration(); for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem *item = treeWidget->topLevelItem(i); @@ -101,9 +106,10 @@ BearerMonitor::BearerMonitor(QWidget *parent) connect(newSessionButton, SIGNAL(clicked()), this, SLOT(createNewSession())); +#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) connect(deleteSessionButton, SIGNAL(clicked()), this, SLOT(deleteSession())); - +#endif connect(scanButton, SIGNAL(clicked()), this, SLOT(performScan())); } @@ -234,9 +240,15 @@ void BearerMonitor::updateConfigurations() void BearerMonitor::onlineStateChanged(bool isOnline) { if (isOnline) +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) + QMessageBox::information(this, "Connection state changed", "Online", QMessageBox::Close); + else + QMessageBox::information(this, "Connection state changed", "Offline", QMessageBox::Close); +#else onlineState->setText(tr("Online")); else onlineState->setText(tr("Offline")); +#endif } #ifdef Q_OS_WIN @@ -362,7 +374,9 @@ void BearerMonitor::createSessionFor(QTreeWidgetItem *item) tabWidget->addTab(session, conf.name()); +#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) sessionGroup->show(); +#endif sessionWidgets.append(session); } @@ -374,6 +388,7 @@ void BearerMonitor::createNewSession() createSessionFor(item); } +#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) void BearerMonitor::deleteSession() { SessionWidget *session = qobject_cast(tabWidget->currentWidget()); @@ -386,6 +401,7 @@ void BearerMonitor::deleteSession() sessionGroup->hide(); } } +#endif void BearerMonitor::performScan() { diff --git a/examples/network/bearermonitor/bearermonitor.h b/examples/network/bearermonitor/bearermonitor.h index d7025dd..3172b5b 100644 --- a/examples/network/bearermonitor/bearermonitor.h +++ b/examples/network/bearermonitor/bearermonitor.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) ** @@ -46,6 +46,8 @@ #include #if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE) #include "ui_bearermonitor_240_320.h" +#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) +#include "ui_bearermonitor_maemo.h" #else #include "ui_bearermonitor_640_480.h" #endif @@ -80,8 +82,9 @@ private slots: void createSessionFor(QTreeWidgetItem *item); void createNewSession(); +#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) void deleteSession(); - +#endif void performScan(); private: diff --git a/examples/network/bearermonitor/bearermonitor.pro b/examples/network/bearermonitor/bearermonitor.pro index 4b86187..42100bc 100644 --- a/examples/network/bearermonitor/bearermonitor.pro +++ b/examples/network/bearermonitor/bearermonitor.pro @@ -1,3 +1,6 @@ +TARGET = bearermonitor +QT = core gui network + HEADERS = sessionwidget.h \ bearermonitor.h @@ -5,22 +8,18 @@ SOURCES = main.cpp \ bearermonitor.cpp \ sessionwidget.cpp -FORMS = bearermonitor_240_320.ui \ - bearermonitor_640_480.ui \ - sessionwidget.ui - -TARGET = bearermonitor - -QT = core gui network - -win32 { - !wince* { - LIBS += -lWs2_32 - } else { - LIBS += -lWs2 - } +maemo5|maemo6 { + FORMS = bearermonitor_maemo.ui \ + sessionwidget_maemo.ui +} else { + FORMS = bearermonitor_240_320.ui \ + bearermonitor_640_480.ui \ + sessionwidget.ui } +win32:!wince*:LIBS += -lWs2_32 +wince*:LIBS += -lWs2 + CONFIG += console symbian:TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/examples/network/bearermonitor/bearermonitor_maemo.ui b/examples/network/bearermonitor/bearermonitor_maemo.ui new file mode 100644 index 0000000..5f17e7d --- /dev/null +++ b/examples/network/bearermonitor/bearermonitor_maemo.ui @@ -0,0 +1,310 @@ + + + BearerMonitor + + + + 0 + 0 + 612 + 495 + + + + Form + + + + + + + 0 + 0 + + + + 0 + + + false + + + + Configurations + + + + + + + 0 + 0 + + + + false + + + + 1 + + + + + + + + + + + + Name: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + State: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Type: + + + + + + + + 0 + 0 + + + + Invalid + + + + + + + + + + + Purpose: + + + + + + + + 0 + 0 + + + + Unknown + + + + + + + + + + + Identifier: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Roaming: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Children: + + + + + + + + 0 + 0 + + + + + + + + + + + + + Network Location Awareness + + + + + + Register + + + + + + + Unregister + + + + + + + + + + New Session + + + + + + + Delete Session + + + + + + + Scan + + + + + + + 0 + + + 23280 + + + false + + + false + + + %p% + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + diff --git a/examples/network/bearermonitor/sessionwidget.cpp b/examples/network/bearermonitor/sessionwidget.cpp index 655c1ac..443f4b2 100644 --- a/examples/network/bearermonitor/sessionwidget.cpp +++ b/examples/network/bearermonitor/sessionwidget.cpp @@ -75,6 +75,10 @@ SessionWidget::SessionWidget(const QNetworkConfiguration &config, QWidget *paren this, SLOT(closeSession())); connect(stopSessionButton, SIGNAL(clicked()), this, SLOT(stopSession())); +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) + connect(deleteSessionButton, SIGNAL(clicked()), + this, SLOT(deleteSession())); +#endif } SessionWidget::~SessionWidget() @@ -91,6 +95,13 @@ void SessionWidget::timerEvent(QTimerEvent *e) } } +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) +void SessionWidget::deleteSession() +{ + delete this; +} +#endif + void SessionWidget::updateSession() { updateSessionState(session->state()); diff --git a/examples/network/bearermonitor/sessionwidget.h b/examples/network/bearermonitor/sessionwidget.h index ae5cc96..5e9d62c 100644 --- a/examples/network/bearermonitor/sessionwidget.h +++ b/examples/network/bearermonitor/sessionwidget.h @@ -42,8 +42,11 @@ #ifndef SESSIONWIDGET_H #define SESSIONWIDGET_H +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) +#include "ui_sessionwidget_maemo.h" +#else #include "ui_sessionwidget.h" - +#endif #include QT_USE_NAMESPACE @@ -68,7 +71,9 @@ private Q_SLOTS: void closeSession(); void stopSession(); void updateSession(); - +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) + void deleteSession(); +#endif private: QNetworkSession *session; int statsTimer; diff --git a/examples/network/bearermonitor/sessionwidget_maemo.ui b/examples/network/bearermonitor/sessionwidget_maemo.ui new file mode 100644 index 0000000..86f915c --- /dev/null +++ b/examples/network/bearermonitor/sessionwidget_maemo.ui @@ -0,0 +1,262 @@ + + + SessionWidget + + + + 0 + 0 + 497 + 615 + + + + Form + + + + + + + + + + Session ID: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + 0 + 0 + + + + Session State: + + + + + + + + 0 + 0 + + + + Invalid + + + + + + + + + + + Configuration: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Bearer: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Interface Name: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Interface GUID: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Last Error: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Error String + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + Open + + + + + + + Close + + + + + + + Blocking Open + + + + + + + Stop + + + + + + + Delete + + + + + + + + + + diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index 1bba56f..638bee7 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -225,6 +225,10 @@ QT_BEGIN_NAMESPACE QNetworkSession::QNetworkSession(const QNetworkConfiguration& connectionConfig, QObject* parent) : QObject(parent), d(0) { + // invalid configuration + if (connectionConfig.identifier().isNull()) + return; + foreach (QBearerEngine *engine, qNetworkConfigurationManagerPrivate()->engines()) { if (engine->hasIdentifier(connectionConfig.identifier())) { d = engine->createSessionBackend(); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index b59ccee..e418432 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -91,7 +91,7 @@ [locker lock]; QMacCocoaAutoReleasePool pool; center = [NSNotificationCenter defaultCenter]; - currentInterface = [CWInterface interface]; + currentInterface = [CWInterface interfaceWithName:nil]; // [center addObserver:self selector:@selector(notificationHandler:) name:kCWLinkDidChangeNotification object:nil]; [center addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil]; [locker unlock]; @@ -154,7 +154,7 @@ QCoreWlanEngine::QCoreWlanEngine(QObject *parent) } else { hasWifi = false; } - requestUpdate(); + QMetaObject::invokeMethod(this, "requestUpdate", Qt::QueuedConnection); } QCoreWlanEngine::~QCoreWlanEngine() @@ -193,14 +193,13 @@ void QCoreWlanEngine::connectToId(const QString &id) NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; QString wantedSsid; + bool using8021X = false; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name)); - const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + getNetworkNameFromSsid(ptr->name))); + const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + getNetworkNameFromSsid(ptr->name))); - bool using8021X = false; - if (idHash2 != id) { + if (idHash != id) { NSArray *array = [CW8021XProfile allUser8021XProfiles]; for (NSUInteger i = 0; i < [array count]; ++i) { @@ -382,6 +381,41 @@ void QCoreWlanEngine::doRequestUpdate() emit updateCompleted(); } +QString QCoreWlanEngine::getSsidFromNetworkName(const QString &name) +{ + QMapIterator > i(userProfiles); + while (i.hasNext()) { + i.next(); + QMap map = i.value(); + QMapIterator ij(i.value()); + while (ij.hasNext()) { + ij.next(); + const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + i.key())); + if (name == i.key() || name == networkNameHash) { + return ij.key(); + } + } + } + return QString(); +} + +QString QCoreWlanEngine::getNetworkNameFromSsid(const QString &ssid) +{ + QMapIterator > i(userProfiles); + while (i.hasNext()) { + i.next(); + QMap map = i.value(); + QMapIterator ij(i.value()); + while (ij.hasNext()) { + ij.next(); + if(ij.key() == ssid) { + return i.key(); + } + } + } + return QString(); +} + QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) { QMutexLocker locker(&mutex); @@ -404,7 +438,6 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil]; NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err]; CWNetwork *apNetwork; - if (!err) { for(uint row=0; row < [apArray count]; row++ ) { @@ -676,42 +709,6 @@ bool QCoreWlanEngine::requiresPolling() const return true; } -QString QCoreWlanEngine::getSsidFromNetworkName(const QString &name) -{ - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key())); - if(name == i.key() || name == networkNameHash) { - return ij.key(); - } - } - } - return QString(); -} - -QString QCoreWlanEngine::getNetworkNameFromSsid(const QString &ssid) -{ - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - if(ij.key() == ssid) { - return i.key(); - } - } - } - return QString(); -} - - void QCoreWlanEngine::getUserConfigurations() { QMacCocoaAutoReleasePool pool; @@ -724,7 +721,7 @@ void QCoreWlanEngine::getUserConfigurations() NSString *nsInterfaceName = [wifiInterface name]; // add user configured system networks SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil); - NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]); + NSDictionary *airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName] autorelease]); CFRelease(dynRef); NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"]; @@ -742,7 +739,7 @@ void QCoreWlanEngine::getUserConfigurations() // 802.1X user profiles QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist"; - NSDictionary* eapDict = [[NSMutableDictionary alloc] initWithContentsOfFile:qt_mac_QStringToNSString(userProfilePath)]; + NSDictionary* eapDict = [[NSDictionary alloc] initWithContentsOfFile:qt_mac_QStringToNSString(userProfilePath)]; NSString *profileStr= @"Profiles"; NSString *nameStr = @"UserDefinedName"; NSString *networkSsidStr = @"Wireless Network"; @@ -773,8 +770,10 @@ void QCoreWlanEngine::getUserConfigurations() } } } + [itemDict release]; } } + [eapDict release]; } } diff --git a/src/plugins/bearer/icd/icd.pro b/src/plugins/bearer/icd/icd.pro index f411de2..c7337f5 100644 --- a/src/plugins/bearer/icd/icd.pro +++ b/src/plugins/bearer/icd/icd.pro @@ -7,12 +7,10 @@ QMAKE_CXXFLAGS += $$QT_CFLAGS_ICD LIBS += $$QT_LIBS_ICD HEADERS += qicdengine.h \ - monitor.h \ qnetworksession_impl.h SOURCES += main.cpp \ qicdengine.cpp \ - monitor.cpp \ qnetworksession_impl.cpp #DEFINES += BEARER_MANAGEMENT_DEBUG diff --git a/src/plugins/bearer/icd/monitor.cpp b/src/plugins/bearer/icd/monitor.cpp deleted file mode 100644 index 5b0af7e..0000000 --- a/src/plugins/bearer/icd/monitor.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** 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 - - -void IapMonitor::setup(QIcdEngine *d_ptr) -{ - if (first_call) { - d = d_ptr; - first_call = false; - } -} - - -void IapMonitor::cleanup() -{ - if (!first_call) { - timers.removeAll(); - first_call = true; - } -} - - -void IapMonitor::iapAdded(const QString &iap_id) -{ - /* We cannot know when the IAP is fully added to db, so a timer is - * installed instead. When the timer expires we hope that IAP is added ok. - */ - QString id = iap_id; - timers.add(id, d); -} - - -void IapMonitor::iapRemoved(const QString &iap_id) -{ - QString id = iap_id; - d->deleteConfiguration(id); -} - diff --git a/src/plugins/bearer/icd/monitor.h b/src/plugins/bearer/icd/monitor.h deleted file mode 100644 index 10ffb30..0000000 --- a/src/plugins/bearer/icd/monitor.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** 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 db 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 Maemo::IAPMonitor -{ -public: - IapMonitor() : first_call(true) { } - - void setup(QIcdEngine *d); - void cleanup(); - -protected: - void iapAdded(const QString &iapId); - void iapRemoved(const QString &iapId); - -private: - bool first_call; - - QIcdEngine *d; - IapAddTimer timers; -}; - -#endif // MONITOR_H diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp index 7a4cb9d..a6cf0c2 100644 --- a/src/plugins/bearer/icd/qicdengine.cpp +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -40,12 +40,12 @@ ****************************************************************************/ #include "qicdengine.h" -#include "monitor.h" #include "qnetworksession_impl.h" +#include #include -#include #include +#include QT_BEGIN_NAMESPACE @@ -70,6 +70,208 @@ QString IcdNetworkConfigurationPrivate::bearerName() const } } +/* The IapAddTimer is a helper class that makes sure we update + * the configuration only after all db 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(); +}; + + +void _IapAddTimer::add(QString& id, QIcdEngine *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, QIcdEngine *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, QIcdEngine *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 Maemo::IAPMonitor +{ +public: + IapMonitor() : first_call(true) { } + + void setup(QIcdEngine *d); + void cleanup(); + +protected: + void iapAdded(const QString &iapId); + void iapRemoved(const QString &iapId); + +private: + bool first_call; + + QIcdEngine *d; + IapAddTimer timers; +}; + +void IapMonitor::setup(QIcdEngine *d_ptr) +{ + if (first_call) { + d = d_ptr; + first_call = false; + } +} + + +void IapMonitor::cleanup() +{ + if (!first_call) { + timers.removeAll(); + first_call = true; + } +} + + +void IapMonitor::iapAdded(const QString &iap_id) +{ + /* We cannot know when the IAP is fully added to db, so a timer is + * installed instead. When the timer expires we hope that IAP is added ok. + */ + QString id = iap_id; + timers.add(id, d); +} + + +void IapMonitor::iapRemoved(const QString &iap_id) +{ + QString id = iap_id; + d->deleteConfiguration(id); +} + +QIcdEngine::QIcdEngine(QObject *parent) +: QBearerEngine(parent), iapMonitor(new IapMonitor), m_dbusInterface(0), + firstUpdate(true), m_scanGoingOn(false) +{ + QMetaObject::invokeMethod(this, "doRequestUpdate", Qt::QueuedConnection); + init(); +} + +QIcdEngine::~QIcdEngine() +{ + cleanup(); + delete iapMonitor; +} + +QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const +{ + return QNetworkConfigurationManager::CanStartAndStopInterfaces | + QNetworkConfigurationManager::DataStatistics | + QNetworkConfigurationManager::ForcedRoaming | + QNetworkConfigurationManager::NetworkSessionRequired; +} + +void QIcdEngine::init() +{ + // Setup DBus Interface for ICD + m_dbusInterface = new QDBusInterface(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, + QDBusConnection::systemBus(), + this); + connect(&m_scanTimer, SIGNAL(timeout()), this, SLOT(finishAsyncConfigurationUpdate())); + m_scanTimer.setSingleShot(true); + + /* Turn on IAP state monitoring */ + startListeningStateSignalsForAllConnections(); + + /* Turn on IAP add/remove monitoring */ + iapMonitor->setup(this); + + /* We create a default configuration which is a pseudo config */ + QNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + 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; + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + userChoiceConfigurations.insert(cpPriv->id, ptr); +} + static inline QString network_attrs_to_security(uint network_attrs) { uint cap = 0; @@ -85,38 +287,40 @@ static inline QString network_attrs_to_security(uint network_attrs) return ""; } -QIcdEngine::QIcdEngine(QObject *parent) -: QBearerEngine(parent), iapMonitor(new IapMonitor) -{ - /* Turn on IAP monitoring */ - iapMonitor->setup(this); - doRequestUpdate(); -} +struct SSIDInfo { + QString iap_id; + QString wlan_security; +}; -QIcdEngine::~QIcdEngine() -{ -} -bool QIcdEngine::hasIdentifier(const QString &id) +void QIcdEngine::deleteConfiguration(const QString &iap_id) { QMutexLocker locker(&mutex); - return accessPointConfigurations.contains(id) || - snapConfigurations.contains(id) || - userChoiceConfigurations.contains(id); -} - -void QIcdEngine::requestUpdate() -{ - QMutexLocker locker(&mutex); + /* Called when IAPs are deleted in db, in this case we do not scan + * or read all the IAPs from db because it might take too much power + * (multiple applications would need to scan and read all IAPs from db) + */ + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(iap_id); + if (ptr) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "was removed from storage."; +#endif - QTimer::singleShot(0, this, SLOT(doRequestUpdate())); + locker.unlock(); + emit configurationRemoved(ptr); + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data()); +#endif + } } + static uint32_t getNetworkAttrs(bool is_iap_id, - QString& iap_id, - QString& iap_type, + const QString &iap_id, + const QString &iap_type, QString security_method) { guint network_attr = 0; @@ -158,45 +362,171 @@ static uint32_t getNetworkAttrs(bool is_iap_id, return (uint32_t)network_attr; } -void QIcdEngine::doRequestUpdate() + +void QIcdEngine::addConfiguration(QString& iap_id) { + // Note: When new IAP is created, this function gets called multiple times + // in a row. + // For example: Empty type & name for WLAN was stored into newly + // created IAP data in gconf when this function gets + // called for the first time. + // WLAN type & name are updated into IAP data in gconf + // as soon as WLAN connection is up and running. + // => And this function gets called again. + QMutexLocker locker(&mutex); - QStringList previous = accessPointConfigurations.keys(); + if (!accessPointConfigurations.contains(iap_id)) { + Maemo::IAPConf saved_iap(iap_id); + QString iap_type = saved_iap.value("type").toString(); + QString iap_name = saved_iap.value("name").toString(); + QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); + if (!iap_type.isEmpty() && !iap_name.isEmpty()) { + // Check if new IAP is actually Undefined WLAN configuration + // Note: SSID is used as an iap id for Undefined WLAN configurations + // => configuration must be searched using SSID + if (!ssid.isEmpty() && accessPointConfigurations.contains(ssid)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(ssid); + if (ptr) { + ptr->mutex.lock(); + ptr->id = iap_id; + toIcdConfig(ptr)->iap_type = iap_type; + toIcdConfig(ptr)->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); + toIcdConfig(ptr)->network_id = ssid; + toIcdConfig(ptr)->service_id = saved_iap.value("service_id").toString(); + toIcdConfig(ptr)->service_type = saved_iap.value("service_type").toString(); + if (m_onlineIapId == iap_id) { + ptr->state = QNetworkConfiguration::Active; + } else { + ptr->state = QNetworkConfiguration::Defined; + } + ptr->mutex.unlock(); + accessPointConfigurations.insert(iap_id, ptr); - /* All the scanned access points */ - QList scanned; + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + } + } else { + IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + 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(QLatin1String("WLAN"))) { + QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); + if (ssid.isEmpty()) { + qWarning() << "Cannot get ssid for" << iap_id; + } + cpPriv->network_id = ssid; + } + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + if (m_onlineIapId == iap_id) { + cpPriv->state = QNetworkConfiguration::Active; + } else { + cpPriv->state = QNetworkConfiguration::Defined; + } - /* We create a default configuration which is a pseudo config */ - if (!userChoiceConfigurations.contains(OSSO_IAP_ANY)) { - QNetworkConfigurationPrivatePointer ptr(new IcdNetworkConfigurationPrivate); + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(iap_id, ptr); - 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; +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, name: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data()); +#endif + locker.unlock(); + emit configurationAdded(ptr); + locker.relock(); + } + } else { + qWarning("IAP %s does not have \"type\" or \"name\" fields defined, skipping this IAP.", iap_id.toAscii().data()); + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "already in db."; +#endif - userChoiceConfigurations.insert(ptr->id, ptr); + /* Check if the data in db changed and update configuration accordingly + */ + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iap_id); + if (ptr) { + 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 */ + + QMutexLocker configLocker(&ptr->mutex); + + toIcdConfig(ptr)->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); + toIcdConfig(ptr)->service_id = changed_iap.value("service_id").toString(); + toIcdConfig(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 (toIcdConfig(ptr)->iap_type != iap_type) { + toIcdConfig(ptr)->iap_type = iap_type; + update_needed = true; + } + if (iap_type.startsWith(QLatin1String("WLAN"))) { + QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray(); + if (ssid.isEmpty()) { + qWarning() << "Cannot get ssid for" << iap_id; + } + if (toIcdConfig(ptr)->network_id != ssid) { + toIcdConfig(ptr)->network_id = ssid; + update_needed = true; + } + } + } + + if (update_needed) { + ptr->type = QNetworkConfiguration::InternetAccessPoint; + if (m_onlineIapId == iap_id) { + if (ptr->state < QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Active; + + configLocker.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + } + } else if (ptr->state < QNetworkConfiguration::Defined) { + ptr->state = QNetworkConfiguration::Defined; - locker.unlock(); - emit configurationAdded(ptr); - locker.relock(); + configLocker.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + } + } + } else { + qWarning("Cannot find IAP %s from current configuration although it should be there.", iap_id.toAscii().data()); + } } +} + +void QIcdEngine::doRequestUpdate(QList scanned) +{ + QMutexLocker locker(&mutex); + + /* Contains all known iap_ids from storage */ + QList knownConfigs = accessPointConfigurations.keys(); + + /* Contains all known WLAN network ids (like ssid) from storage */ + QMultiHash notDiscoveredWLANConfigs; - /* 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 iap_id, all_iaps) { + foreach (const QString &iap_id, all_iaps) { QByteArray ssid; - previous.removeAll(iap_id); - Maemo::IAPConf saved_ap(iap_id); bool is_temporary = saved_ap.value("temporary").toBool(); if (is_temporary) { @@ -207,12 +537,16 @@ void QIcdEngine::doRequestUpdate() } QString iap_type = saved_ap.value("type").toString(); - if (iap_type.startsWith("WLAN")) { + if (iap_type.startsWith(QLatin1String("WLAN"))) { ssid = saved_ap.value("wlan_ssid").toByteArray(); if (ssid.isEmpty()) continue; QString security_method = saved_ap.value("wlan_security").toString(); + SSIDInfo *info = new SSIDInfo; + info->iap_id = iap_id; + info->wlan_security = security_method; + notDiscoveredWLANConfigs.insert(ssid, info); } else if (iap_type.isEmpty()) { continue; } else { @@ -227,10 +561,10 @@ void QIcdEngine::doRequestUpdate() 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; + if (!ssid.isEmpty() && ssid.size() > 0) + cpPriv->name = ssid.data(); + else + cpPriv->name = iap_id; } cpPriv->isValid = true; cpPriv->id = iap_id; @@ -255,6 +589,7 @@ void QIcdEngine::doRequestUpdate() !ssid.isEmpty() ? ssid.data() : "-"); #endif } else { + knownConfigs.removeOne(iap_id); #ifdef BEARER_MANAGEMENT_DEBUG qDebug("IAP: %s, ssid: %s, already exists in the known list", iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); @@ -262,47 +597,16 @@ void QIcdEngine::doRequestUpdate() } } - 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()) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Network scanning failed" << error; -#endif - } 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; imutex.lock(); @@ -324,7 +628,7 @@ void QIcdEngine::doRequestUpdate() #ifdef BEARER_MANAGEMENT_DEBUG qDebug("IAP: %s, ssid: %s, discovered", - iapid.toAscii().data(), scanned_ssid.data()); + iapid.toAscii().data(), toIcdConfig(ptr)->network_id.data()); #endif ptr->mutex.unlock(); @@ -337,101 +641,350 @@ void QIcdEngine::doRequestUpdate() if (!ap.scan.network_type.startsWith(QLatin1String("WLAN"))) continue; // not a wlan AP + + /* Remove scanned AP from discovered WLAN configurations so that we can + * emit configurationRemoved signal later + */ + ptr->mutex.lock(); + QList known_iaps = notDiscoveredWLANConfigs.values(toIcdConfig(ptr)->network_id); +rescan_list: + if (!known_iaps.isEmpty()) { + for (int k=0; kwlan_security == + network_attrs_to_security(ap.scan.network_attrs)) { + /* Remove IAP from the list */ + notDiscoveredWLANConfigs.remove(toIcdConfig(ptr)->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; + } + } + } + ptr->mutex.unlock(); } } 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; + /* Non saved access point data */ + QByteArray scanned_ssid = ap.scan.network_id; + if (!accessPointConfigurations.contains(scanned_ssid)) { + IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + 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->type = QNetworkConfiguration::InternetAccessPoint; + cpPriv->state = QNetworkConfiguration::Undefined; #ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan."; + 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); - QNetworkConfigurationPrivatePointer ptr(cpPriv); - accessPointConfigurations.insert(ptr->id, ptr); + locker.unlock(); + emit configurationAdded(ptr); + locker.relock(); + } else { + knownConfigs.removeOne(scanned_ssid); + } + } + } + } + + if (!firstUpdate) { + // Update Defined status to all defined WLAN IAPs which + // could not be found when access points were scanned + QHashIterator i(notDiscoveredWLANConfigs); + while (i.hasNext()) { + i.next(); + SSIDInfo *iap = i.value(); + QString iap_id = iap->iap_id; + //qDebug() << i.key() << ": " << iap_id; + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iap_id); + if (ptr) { + QMutexLocker configLocker(&ptr->mutex); + + // WLAN AccessPoint configuration could not be Discovered + // => Make sure that configuration state is Defined + if (ptr->state > QNetworkConfiguration::Defined) { + ptr->state = QNetworkConfiguration::Defined; + + configLocker.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + } + } + } + /* Remove non existing iaps since last update */ + foreach (const QString &oldIface, knownConfigs) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface); + if (ptr) { locker.unlock(); - emit configurationAdded(ptr); + emit configurationRemoved(ptr); locker.relock(); + //if we would have SNAP support we would have to remove the references + //from existing ServiceNetworks to the removed access point configuration } } } - while (!previous.isEmpty()) { - QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.take(previous.takeFirst()); + QMutableHashIterator i(notDiscoveredWLANConfigs); + while (i.hasNext()) { + i.next(); + SSIDInfo *iap = i.value(); + delete iap; + i.remove(); + } + if (!firstUpdate) { locker.unlock(); - emit configurationRemoved(ptr); + emit updateCompleted(); locker.relock(); } - if (sender()) { - locker.unlock(); - emit updateCompleted(); + if (firstUpdate) + firstUpdate = false; +} + +QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration() +{ + QMutexLocker locker(&mutex); + + // Here we just return [ANY] request to icd and let the icd decide which IAP to connect. + return userChoiceConfigurations.value(OSSO_IAP_ANY); +} + +void QIcdEngine::startListeningStateSignalsForAllConnections() +{ + QMutexLocker locker(&mutex); + + // Start listening ICD_DBUS_API_STATE_SIG signals + m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_STATE_SIG, + this, SLOT(connectionStateSignalsSlot(QDBusMessage))); + + // Calling ICD_DBUS_API_STATE_REQ makes sure that initial state will be updated immediately + m_gettingInitialConnectionState = true; + m_dbusInterface->call(ICD_DBUS_API_STATE_REQ); +} + +void QIcdEngine::connectionStateSignalsSlot(QDBusMessage msg) +{ + QMutexLocker locker(&mutex); + + QList arguments = msg.arguments(); + if (arguments[1].toUInt() != 0 || arguments.count() < 8) { + return; } + + QString iapid = arguments[5].toByteArray().data(); + uint icd_connection_state = arguments[7].toUInt(); + + switch (icd_connection_state) { + case ICD_STATE_CONNECTED: + { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iapid); + if (ptr) { + QMutexLocker configLocker(&ptr->mutex); + + ptr->type = QNetworkConfiguration::InternetAccessPoint; + if (ptr->state != QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Active; + if (!m_gettingInitialConnectionState) { + configLocker.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + } + m_onlineIapId = iapid; + } + } else { + // This gets called when new WLAN IAP is created using Connection dialog + // At this point Undefined WLAN configuration has SSID as iap id + // => Because of that configuration can not be found from + // accessPointConfigurations using correct iap id + m_onlineIapId = iapid; + } + break; + } + case ICD_STATE_DISCONNECTED: + { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iapid); + if (ptr) { + QMutexLocker configLocker(&ptr->mutex); + + ptr->type = QNetworkConfiguration::InternetAccessPoint; + if (ptr->state == QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Discovered; + if (!m_gettingInitialConnectionState) { + configLocker.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + + // Note: If ICD switches used IAP from one to another: + // 1) new IAP is reported to be online first + // 2) old IAP is reported to be offline then + // => Device can be reported to be offline only + // if last known online IAP is reported to be disconnected + if (iapid == m_onlineIapId) { + // It's known that there is only one global ICD connection + // => Because ICD state was reported to be DISCONNECTED, Device is offline + m_onlineIapId.clear(); + } + } + } + } else { + // Disconnected IAP was not found from accessPointConfigurations + // => Reason: Online IAP was removed which resulted ICD to disconnect + if (iapid == m_onlineIapId) { + // It's known that there is only one global ICD connection + // => Because ICD state was reported to be DISCONNECTED, Device is offline + m_onlineIapId.clear(); + } + } + break; + } + default: + break; + } + + locker.unlock(); + emit iapStateChanged(iapid, icd_connection_state); + locker.relock(); + + m_gettingInitialConnectionState = false; } -void QIcdEngine::deleteConfiguration(const QString &iap_id) +void QIcdEngine::requestUpdate() { QMutexLocker locker(&mutex); - /* Called when IAPs are deleted in db, in this case we do not scan - * or read all the IAPs from db because it might take too much power - * (multiple applications would need to scan and read all IAPs from db) - */ - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(iap_id); - if (ptr) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "IAP" << iap_id << "was removed from storage."; -#endif + if (m_scanGoingOn) { + return; + } + m_scanGoingOn = true; + + m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_SCAN_SIG, + this, SLOT(asyncUpdateConfigurationsSlot(QDBusMessage))); + + QDBusMessage msg = m_dbusInterface->call(ICD_DBUS_API_SCAN_REQ, + (uint)ICD_SCAN_REQUEST_ACTIVE); + m_typesToBeScanned = msg.arguments()[0].value(); + m_scanTimer.start(ICD_SHORT_SCAN_TIMEOUT); +} - locker.unlock(); - emit configurationRemoved(ptr); - } else { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data()); -#endif +void QIcdEngine::cancelAsyncConfigurationUpdate() +{ + QMutexLocker locker(&mutex); + + if (!m_scanGoingOn) { + return; + } + m_scanGoingOn = false; + + if (m_scanTimer.isActive()) { + m_scanTimer.stop(); } + + m_dbusInterface->connection().disconnect(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_SCAN_SIG, + this, SLOT(asyncUpdateConfigurationsSlot(QDBusMessage))); + + // Stop scanning rounds by calling ICD_DBUS_API_SCAN_CANCEL + // <=> If ICD_DBUS_API_SCAN_CANCEL is not called, new scanning round will + // be started after the module scan timeout. + m_dbusInterface->call(ICD_DBUS_API_SCAN_CANCEL); } -QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const +void QIcdEngine::finishAsyncConfigurationUpdate() { - return QNetworkConfigurationManager::CanStartAndStopInterfaces | - QNetworkConfigurationManager::DataStatistics | - QNetworkConfigurationManager::ForcedRoaming | - QNetworkConfigurationManager::NetworkSessionRequired; + QMutexLocker locker(&mutex); + + cancelAsyncConfigurationUpdate(); + doRequestUpdate(m_scanResult); + m_scanResult.clear(); } -QNetworkSessionPrivate *QIcdEngine::createSessionBackend() +void QIcdEngine::asyncUpdateConfigurationsSlot(QDBusMessage msg) { - return new QNetworkSessionPrivateImpl(this); + QMutexLocker locker(&mutex); + + QList arguments = msg.arguments(); + uint icd_scan_status = arguments.takeFirst().toUInt(); + if (icd_scan_status == ICD_SCAN_COMPLETE) { + m_typesToBeScanned.removeOne(arguments[6].toString()); + if (!m_typesToBeScanned.count()) { + finishAsyncConfigurationUpdate(); + } + } else { + Maemo::IcdScanResult scanResult; + scanResult.status = icd_scan_status; + scanResult.timestamp = arguments.takeFirst().toUInt(); + scanResult.scan.service_type = arguments.takeFirst().toString(); + scanResult.service_name = arguments.takeFirst().toString(); + scanResult.scan.service_attrs = arguments.takeFirst().toUInt(); + scanResult.scan.service_id = arguments.takeFirst().toString(); + scanResult.service_priority = arguments.takeFirst().toInt(); + scanResult.scan.network_type = arguments.takeFirst().toString(); + scanResult.network_name = arguments.takeFirst().toString(); + scanResult.scan.network_attrs = arguments.takeFirst().toUInt(); + scanResult.scan.network_id = arguments.takeFirst().toByteArray(); + scanResult.network_priority = arguments.takeFirst().toInt(); + scanResult.signal_strength = arguments.takeFirst().toInt(); + scanResult.station_id = arguments.takeFirst().toString(); + scanResult.signal_dB = arguments.takeFirst().toInt(); + + m_scanResult.append(scanResult); + } } -QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration() +void QIcdEngine::cleanup() +{ + if (m_scanGoingOn) { + m_scanTimer.stop(); + m_dbusInterface->call(ICD_DBUS_API_SCAN_CANCEL); + } + iapMonitor->cleanup(); +} + +bool QIcdEngine::hasIdentifier(const QString &id) { QMutexLocker locker(&mutex); - // Here we just return [ANY] request to icd and let the icd decide which IAP to connect. - return userChoiceConfigurations.value(OSSO_IAP_ANY); + return accessPointConfigurations.contains(id) || + snapConfigurations.contains(id) || + userChoiceConfigurations.contains(id); } +QNetworkSessionPrivate *QIcdEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl(this); +} + +#include "qicdengine.moc" + QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h index 50cda62..a2e9a2f 100644 --- a/src/plugins/bearer/icd/qicdengine.h +++ b/src/plugins/bearer/icd/qicdengine.h @@ -44,10 +44,15 @@ #include +#include + +#include + QT_BEGIN_NAMESPACE class QNetworkConfigurationPrivate; class IapMonitor; +class QDBusInterface; class IcdNetworkConfigurationPrivate : public QNetworkConfigurationPrivate { @@ -118,11 +123,35 @@ public: emit configurationChanged(ptr); } + void init(); + void cleanup(); + + void addConfiguration(QString &iap_id); + +Q_SIGNALS: + void iapStateChanged(const QString& iapid, uint icd_connection_state); + private Q_SLOTS: - void doRequestUpdate(); + void doRequestUpdate(QList scanned = QList()); + void cancelAsyncConfigurationUpdate(); + void finishAsyncConfigurationUpdate(); + void asyncUpdateConfigurationsSlot(QDBusMessage msg); + void connectionStateSignalsSlot(QDBusMessage msg); + +private: + void startListeningStateSignalsForAllConnections(); private: IapMonitor *iapMonitor; + QDBusInterface *m_dbusInterface; + QTimer m_scanTimer; + QString m_onlineIapId; + QStringList m_typesToBeScanned; + QList m_scanResult; + + bool firstUpdate; + bool m_gettingInitialConnectionState; + bool m_scanGoingOn; }; QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp index 5bf95dc..2928a31 100644 --- a/src/plugins/bearer/icd/qnetworksession_impl.cpp +++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp @@ -44,294 +44,146 @@ #include -#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) +QDBusArgument &operator<<(QDBusArgument &argument, + const ICd2DetailsDBusStruct &icd2) { - 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; + argument.beginStructure(); + argument << icd2.serviceType; + argument << icd2.serviceAttributes; + argument << icd2.setviceId; + argument << icd2.networkType; + argument << icd2.networkAttributes; + argument << icd2.networkId; + argument.endStructure(); + return argument; } - -/* 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) +const QDBusArgument &operator>>(const QDBusArgument &argument, + ICd2DetailsDBusStruct &icd2) { - 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) { -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << QString("Failed to parse icd status signal: %1").arg(error.message); -#endif - } 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; + argument.beginStructure(); + argument >> icd2.serviceType; + argument >> icd2.serviceAttributes; + argument >> icd2.setviceId; + argument >> icd2.networkType; + argument >> icd2.networkAttributes; + argument >> icd2.networkId; + argument.endStructure(); + return argument; } - -void IcdListener::setup(QNetworkSessionPrivateImpl *d) +const QDBusArgument &operator>>(const QDBusArgument &argument, + ICd2DetailsList &detailsList) { - 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)) { - 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)) { - dbus_error_free(&error); - return; - } - - if (dbus_connection_register_object_path(dbus_connection, - ICD_DBUS_PATH, - &icd_vtable, - (void*)this) == FALSE) { - dbus_error_free(&error); - return; - } + argument.beginArray(); + detailsList.clear(); -#ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE; -#endif - first_call = false; - dbus_error_free(&error); - } + while (!argument.atEnd()) { + ICd2DetailsDBusStruct element; + argument >> element; + detailsList.append(element); + } - QString id = d->activeConfig.identifier(); - if (!sessions.contains(id)) { - QNetworkSessionPrivateImpl *ptr = d; - sessions.insert(id, ptr); - } + argument.endArray(); + return argument; } - -void IcdListener::icdSignalReceived(QString& iap_id, -#ifdef BEARER_MANAGEMENT_DEBUG - QString& network_type, -#else - QString&, -#endif - QString& state) +QDBusArgument &operator<<(QDBusArgument &argument, + const ICd2DetailsList &detailsList) { - 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; + argument.beginArray(qMetaTypeId()); + for (int i = 0; i < detailsList.count(); ++i) + argument << detailsList[i]; + argument.endArray(); + return argument; } +static QHash properties; -void IcdListener::cleanup() +static QString get_network_interface(); + +void QNetworkSessionPrivateImpl::iapStateChanged(const QString& iapid, uint icd_connection_state) { - if (!first_call) { - dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL); - dbus_connection_unref(dbus_connection); + if ((publicConfig.type() == QNetworkConfiguration::UserChoice) && opened) { + updateIdentifier(iapid); } -} - -void IcdListener::cleanupSession(QNetworkSessionPrivateImpl *ptr) -{ - if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice) - (void)sessions.take(ptr->activeConfig.identifier()); - else - (void)sessions.take(ptr->publicConfig.identifier()); + if (((publicConfig.type() == QNetworkConfiguration::UserChoice) && + (activeConfig.identifier() == iapid)) || + (publicConfig.identifier() == iapid)) { + switch (icd_connection_state) { + case ICD_STATE_CONNECTING: + updateState(QNetworkSession::Connecting); + break; + case ICD_STATE_CONNECTED: + updateState(QNetworkSession::Connected); + break; + case ICD_STATE_DISCONNECTING: + updateState(QNetworkSession::Closing); + break; + case ICD_STATE_DISCONNECTED: + updateState(QNetworkSession::Disconnected); + break; + default: + break; + } + } } - void QNetworkSessionPrivateImpl::cleanupSession(void) { - icdListener()->cleanupSession(this); - QObject::disconnect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State))); } 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) { - IcdNetworkConfigurationPrivate *icdConfig = - toIcdConfig(privateConfiguration(activeConfig)); - - icdConfig->mutex.lock(); - icdConfig->state = QNetworkConfiguration::Defined; - icdConfig->mutex.unlock(); - } - - IcdNetworkConfigurationPrivate *icdConfig = - toIcdConfig(privateConfiguration(publicConfig)); - - icdConfig->mutex.lock(); - icdConfig->state = QNetworkConfiguration::Defined; - icdConfig->mutex.unlock(); - - } else if (state == QNetworkSession::Connected) { - isOpen = true; + if (newState != state) { + if (newState == QNetworkSession::Disconnected) { + if (isOpen) { + // The Session was aborted by the user or system + lastError = QNetworkSession::SessionAbortedError; + emit QNetworkSessionPrivate::error(lastError); + emit closed(); + } + if (m_stopTimer.isActive()) { + // Session was closed by calling stop() + m_stopTimer.stop(); + } + isOpen = false; + opened = false; + currentNetworkInterface.clear(); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + copyConfig(publicConfig, activeConfig); + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(activeConfig)); + + icdConfig->mutex.lock(); + icdConfig->state = QNetworkConfiguration::Defined; + icdConfig->mutex.unlock(); + } else { + if (!activeConfig.isValid()) { + // Active configuration (IAP) was removed from system + // => Connection was disconnected and configuration became + // invalid + // => Also Session state must be changed to invalid + newState = QNetworkSession::Invalid; + } + } + } else if (newState == QNetworkSession::Connected) { + if (opened) { + isOpen = true; + } if (publicConfig.type() == QNetworkConfiguration::UserChoice) { IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(activeConfig)); @@ -350,11 +202,15 @@ void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState) icdConfig->mutex.unlock(); } - emit stateChanged(newState); + if (newState != state) { + state = newState; + emit stateChanged(newState); + } + } } -void QNetworkSessionPrivateImpl::updateIdentifier(QString &newId) +void QNetworkSessionPrivateImpl::updateIdentifier(const QString &newId) { if (publicConfig.type() == QNetworkConfiguration::UserChoice) { IcdNetworkConfigurationPrivate *icdConfig = @@ -479,9 +335,6 @@ QNetworkConfiguration& QNetworkSessionPrivateImpl::copyConfig(QNetworkConfigurat */ 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. */ @@ -490,8 +343,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged())); - connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)), - this, SLOT(configurationChanged(QNetworkConfiguration))); + connect(engine, SIGNAL(iapStateChanged(const QString&, uint)), + this, SLOT(iapStateChanged(const QString&, uint))); QObject::connect(q, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(updateProxies(QNetworkSession::State))); @@ -500,14 +353,14 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() switch (publicConfig.type()) { case QNetworkConfiguration::InternetAccessPoint: - activeConfig = publicConfig; + activeConfig = publicConfig; break; case QNetworkConfiguration::ServiceNetwork: - serviceConfig = publicConfig; + serviceConfig = publicConfig; break; case QNetworkConfiguration::UserChoice: // active config will contain correct data after open() has succeeded - copyConfig(publicConfig, activeConfig); + copyConfig(publicConfig, activeConfig); /* We create new configuration that holds the actual configuration * returned by icd. This way publicConfig still contains the @@ -541,7 +394,6 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() * 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. */ @@ -554,35 +406,28 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() */ if (publicConfig.type() == QNetworkConfiguration::UserChoice || publicConfig.identifier() == state_results.first().params.network_id) { - switch (state_results.first().state) { case ICD_STATE_DISCONNECTED: - state = QNetworkSession::Disconnected; - { - QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); - if (ptr) { - ptr->mutex.lock(); - ptr->isValid = true; - ptr->mutex.unlock(); - } + state = QNetworkSession::Disconnected; + if (QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig)) { + ptr->mutex.lock(); + ptr->isValid = true; + ptr->mutex.unlock(); } - break; + break; case ICD_STATE_CONNECTING: - state = QNetworkSession::Connecting; - { - QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); - if (ptr) { - ptr->mutex.lock(); - ptr->isValid = true; - ptr->mutex.unlock(); - } + state = QNetworkSession::Connecting; + if (QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig)) { + ptr->mutex.lock(); + ptr->isValid = true; + ptr->mutex.unlock(); } - break; + break; case ICD_STATE_CONNECTED: - { - if (!state_results.first().error.isEmpty()) - break; - + { + if (!state_results.first().error.isEmpty()) + break; + const QString id = state_results.first().params.network_id; QNetworkConfiguration config = manager.configurationFromIdentifier(id); @@ -607,7 +452,7 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() ptr->type = QNetworkConfiguration::InternetAccessPoint; ptr->state = QNetworkConfiguration::Active; ptr->isValid = true; - currentNetworkInterface = get_network_interface(); + currentNetworkInterface = get_network_interface(); Maemo::IAPConf iap_name(ptr->id); QString name_value = iap_name.value("name").toString(); @@ -616,8 +461,7 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() else ptr->name = ptr->id; - - // Add the new active configuration to manager or update the old config + // Add the new active configuration to manager or update the old config if (!engine->hasIdentifier(ptr->id)) { configLocker.unlock(); engine->addSessionConfiguration(ptr); @@ -625,24 +469,21 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() configLocker.unlock(); engine->changedSessionConfiguration(ptr); } - } - break; + } + break; case ICD_STATE_DISCONNECTING: - state = QNetworkSession::Closing; - { - QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); - if (ptr) { - ptr->mutex.lock(); - ptr->isValid = true; - ptr->mutex.unlock(); - } + state = QNetworkSession::Closing; + if (QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig)) { + ptr->mutex.lock(); + ptr->isValid = true; + ptr->mutex.unlock(); } - break; + break; default: - break; + break; } - } + } } else { #ifdef BEARER_MANAGEMENT_DEBUG qDebug() << "status_req tells icd is not connected"; @@ -733,7 +574,6 @@ void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() state = QNetworkSession::NotAvailable; } else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) { state = QNetworkSession::NotAvailable; - //clearConfiguration(activeConfig); } bool oldActive = isOpen; @@ -748,7 +588,7 @@ void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() if (oldState != state) { emit stateChanged(state); - if (state == QNetworkSession::Disconnected) { + if (state == QNetworkSession::Disconnected && oldActive) { #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; - } + if (ifa->ifa_addr) { + 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); @@ -825,11 +657,18 @@ static QString get_network_interface() void QNetworkSessionPrivateImpl::open() { + if (m_stopTimer.isActive()) { + m_stopTimer.stop(); + } + if (!publicConfig.isValid()) { + lastError = QNetworkSession::InvalidConfigurationError; + emit QNetworkSessionPrivate::error(lastError); + return; + } 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 @@ -857,189 +696,183 @@ void QNetworkSessionPrivateImpl::open() if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) { state = QNetworkSession::Connecting; emit stateChanged(state); - - QTimer::singleShot(0, this, SLOT(do_open())); - return; + 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(); + /* 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(); + qDebug() << "Already connected to" << activeConfig.identifier(); #endif emit stateChanged(QNetworkSession::Connected); - emit quitPendingWaitsForOpened(); + emit quitPendingWaitsForOpened(); return; } - Maemo::IcdConnectResult connect_result; - Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT); - QNetworkConfiguration config; if (publicConfig.type() == QNetworkConfiguration::UserChoice) - config = activeConfig; + config = activeConfig; else - config = publicConfig; + config = publicConfig; if (iap == OSSO_IAP_ANY) { #ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connecting to default IAP" << iap; + qDebug() << "connecting to default IAP" << iap; #endif - st = icd.connect(flags, connect_result); - + m_connectRequestTimer.start(ICD_LONG_CONNECT_TIMEOUT); + m_dbusInterface->asyncCall(ICD_DBUS_API_CONNECT_REQ, (uint)flags); // Return value ignored + m_asynchCallActive = true; } else { + IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); - QList params; - Maemo::ConnectParams param; - - IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); - - icdConfig->mutex.lock(); - param.connect.service_type = icdConfig->service_type; - param.connect.service_attrs = icdConfig->service_attrs; - param.connect.service_id = icdConfig->service_id; - param.connect.network_type = icdConfig->iap_type; - param.connect.network_attrs = icdConfig->network_attrs; - if (icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME) - param.connect.network_id = QByteArray(iap.toLatin1()); - else - param.connect.network_id = icdConfig->network_id; - params.append(param); - icdConfig->mutex.unlock(); + icdConfig->mutex.lock(); + ICd2DetailsDBusStruct icd2; + icd2.serviceType = icdConfig->service_type; + icd2.serviceAttributes = icdConfig->service_attrs; + icd2.setviceId = icdConfig->service_id; + icd2.networkType = icdConfig->iap_type; + icd2.networkAttributes = icdConfig->network_attrs; + if (icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME) { + icd2.networkId = QByteArray(iap.toLatin1()); + } else { + icd2.networkId = icdConfig->network_id; + } + icdConfig->mutex.unlock(); #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()); + qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s", + icd2.networkId.data(), + icd2.networkType.toAscii().constData(), + icd2.networkAttributes, + icd2.serviceType.toAscii().constData(), + icd2.serviceAttributes, + icd2.setviceId.toAscii().constData()); #endif - st = icd.connect(flags, params, connect_result); - } - if (st) { - result = connect_result.connect.network_id.data(); - QString connected_iap = result; + ICd2DetailsList paramArray; + paramArray.append(icd2); + m_connectRequestTimer.start(ICD_LONG_CONNECT_TIMEOUT); + m_dbusInterface->asyncCall(ICD_DBUS_API_CONNECT_REQ, (uint)flags, QVariant::fromValue(paramArray)); // Return value ignored + m_asynchCallActive = true; + } +} - if (connected_iap.isEmpty()) { +void QNetworkSessionPrivateImpl::stateChange(const QDBusMessage& rep) +{ + if (m_asynchCallActive == true) { + if (m_connectRequestTimer.isActive()) + m_connectRequestTimer.stop(); + m_asynchCallActive = false; + + QString result = rep.arguments().at(5).toString(); // network id or empty string + QString connected_iap = result; + if (connected_iap.isEmpty()) { #ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connect to"<< iap << "failed, result is empty"; + qDebug() << "connect to"<< publicConfig.identifier() << "failed, result is empty"; #endif - updateState(QNetworkSession::Disconnected); - 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 QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); - return; - } - - IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); - - /* Did we connect to non saved IAP? */ - icdConfig->mutex.lock(); - if (!(icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME)) { - /* Because the connection succeeded, the IAP is now known. - */ - icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME; - icdConfig->id = connected_iap; - } + updateState(QNetworkSession::Disconnected); + emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + copyConfig(publicConfig, activeConfig); + return; + } - /* User might have changed the IAP name when a new IAP was saved */ - Maemo::IAPConf iap_name(icdConfig->id); - QString name = iap_name.value("name").toString(); - if (!name.isEmpty()) - icdConfig->name = name; + /* 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 QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); + return; + } - icdConfig->iap_type = connect_result.connect.network_type; + IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); - icdConfig->isValid = true; - icdConfig->state = QNetworkConfiguration::Active; - icdConfig->type = QNetworkConfiguration::InternetAccessPoint; + /* Did we connect to non saved IAP? */ + icdConfig->mutex.lock(); + if (!(icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME)) { + /* Because the connection succeeded, the IAP is now known. + */ + icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME; + icdConfig->id = connected_iap; + } - icdConfig->mutex.unlock(); + /* User might have changed the IAP name when a new IAP was saved */ + Maemo::IAPConf iap_name(icdConfig->id); + QString name = iap_name.value("name").toString(); + if (!name.isEmpty()) + icdConfig->name = name; - startTime = QDateTime::currentDateTime(); - updateState(QNetworkSession::Connected); + icdConfig->iap_type = rep.arguments().at(3).toString(); // connect_result.connect.network_type; + icdConfig->isValid = true; + icdConfig->state = QNetworkConfiguration::Active; + icdConfig->type = QNetworkConfiguration::InternetAccessPoint; - currentNetworkInterface = get_network_interface(); + icdConfig->mutex.unlock(); + startTime = QDateTime::currentDateTime(); + updateState(QNetworkSession::Connected); + //currentNetworkInterface = get_network_interface(); #ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connected to" << result << config.name() << "at" << currentNetworkInterface; + //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->hasIdentifier(result)) { - engine->addSessionConfiguration(privateConfiguration(config)); - } else { - QNetworkConfigurationPrivatePointer priv = engine->configuration(result); - QNetworkConfiguration reference; - setPrivateConfiguration(reference, priv); - copyConfig(config, reference, false); - config = reference; - activeConfig = reference; - engine->changedSessionConfiguration(privateConfiguration(config)); - } - } - - emit quitPendingWaitsForOpened(); + /* 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->hasIdentifier(result)) { + engine->addSessionConfiguration(privateConfiguration(config)); + } else { + QNetworkConfigurationPrivatePointer priv = engine->configuration(result); + QNetworkConfiguration reference; + setPrivateConfiguration(reference, priv); + copyConfig(config, reference, false); + privateConfiguration(reference)->id = result; // Note: Id was not copied in copyConfig() function + config = reference; + activeConfig = reference; + engine->changedSessionConfiguration(privateConfiguration(config)); - } else { #ifdef BEARER_MANAGEMENT_DEBUG - qDebug() << "connect to"<< iap << "failed, status:" << connect_result.status; + qDebug()<<"Existing configuration"<mutex.lock(); - ptr->state = QNetworkConfiguration::Discovered; - ptr->mutex.unlock(); - engine->changedSessionConfiguration(ptr); + icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT); + startTime = QDateTime(); - opened = false; - isOpen = false; + /* Note: Session state will change to disconnected + * as soon as QNetworkConfigurationManager sends + * corresponding iapStateChanged signal. + */ + // Make sure that this Session will send closed signal + // even though ICD connection will not ever get closed + m_stopTimer.start(ICD_SHORT_CONNECT_TIMEOUT); // 10 seconds wait + } } else { opened = false; isOpen = false; @@ -1090,6 +925,15 @@ void QNetworkSessionPrivateImpl::stop() } } +void QNetworkSessionPrivateImpl::finishStopBySendingClosedSignal() +{ + if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + state = QNetworkSession::Connected; + emit stateChanged(state); + } + + emit closed(); +} void QNetworkSessionPrivateImpl::migrate() { @@ -1199,6 +1043,4 @@ void QNetworkSessionPrivateImpl::clearProxyInformation() Maemo::ProxyConf::clear(); } -#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 index c02faac..d15f401 100644 --- a/src/plugins/bearer/icd/qnetworksession_impl.h +++ b/src/plugins/bearer/icd/qnetworksession_impl.h @@ -57,6 +57,12 @@ #include #include +#include + +#include +#include +#include +#include #include @@ -64,14 +70,52 @@ QT_BEGIN_NAMESPACE class QIcdEngine; +struct ICd2DetailsDBusStruct +{ + QString serviceType; + uint serviceAttributes; + QString setviceId; + QString networkType; + uint networkAttributes; + QByteArray networkId; +}; + +typedef QList ICd2DetailsList; + class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate { Q_OBJECT public: QNetworkSessionPrivateImpl(QIcdEngine *engine) - : engine(engine), connectFlags(ICD_CONNECTION_FLAG_USER_EVENT), currentState(QNetworkSession::Invalid) + : engine(engine), + connectFlags(ICD_CONNECTION_FLAG_USER_EVENT), + currentState(QNetworkSession::Invalid), + m_asynchCallActive(false) { + m_stopTimer.setSingleShot(true); + connect(&m_stopTimer, SIGNAL(timeout()), this, SLOT(finishStopBySendingClosedSignal())); + + QDBusConnection systemBus = QDBusConnection::systemBus(); + + m_dbusInterface = new QDBusInterface(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, + systemBus, + this); + + systemBus.connect(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_CONNECT_SIG, + this, + SLOT(stateChange(const QDBusMessage&))); + + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + + m_connectRequestTimer.setSingleShot(true); + connect(&m_connectRequestTimer, SIGNAL(timeout()), this, SLOT(connectTimeout())); } ~QNetworkSessionPrivateImpl() @@ -114,16 +158,21 @@ private: private Q_SLOTS: void do_open(); void networkConfigurationsChanged(); - void configurationChanged(const QNetworkConfiguration &config); + void iapStateChanged(const QString& iapid, uint icd_connection_state); void updateProxies(QNetworkSession::State newState); + void finishStopBySendingClosedSignal(); + void stateChange(const QDBusMessage& rep); + void connectTimeout(); private: QNetworkConfigurationManager manager; QIcdEngine *engine; + // The config set on QNetworkSession. + QNetworkConfiguration config; + QNetworkConfiguration& copyConfig(QNetworkConfiguration &fromConfig, QNetworkConfiguration &toConfig, bool deepCopy = true); void clearConfiguration(QNetworkConfiguration &config); - void cleanupAnyConfiguration(); bool opened; icd_connection_flags connectFlags; @@ -134,15 +183,31 @@ private: QString currentNetworkInterface; friend class IcdListener; void updateState(QNetworkSession::State); - void updateIdentifier(QString &newId); + void updateIdentifier(const QString &newId); quint64 getStatistics(bool sent) const; void cleanupSession(void); void updateProxyInformation(); void clearProxyInformation(); QNetworkSession::State currentState; + + QDBusInterface *m_dbusInterface; + + QTimer m_stopTimer; + + bool m_asynchCallActive; + QTimer m_connectRequestTimer; }; +// Marshall the ICd2DetailsDBusStruct data into a D-Bus argument +QDBusArgument &operator<<(QDBusArgument &argument, const ICd2DetailsDBusStruct &icd2); + +// Retrieve the ICd2DetailsDBusStruct data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, ICd2DetailsDBusStruct &icd2); + +Q_DECLARE_METATYPE(ICd2DetailsDBusStruct); +Q_DECLARE_METATYPE(ICd2DetailsList); + QT_END_NAMESPACE #endif //QNETWORKSESSIONPRIVATE_H diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp index 512ea51..36fbc51 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -53,16 +53,13 @@ QT_BEGIN_NAMESPACE QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine) : CActive(CActive::EPriorityStandard), engine(engine), ipConnectionNotifier(0), iError(QNetworkSession::UnknownSessionError), - iALREnabled(0) + iALREnabled(0), iConnectInBackground(false) { CActiveScheduler::Add(this); - - // Try to load "Open C" dll dynamically and - // try to attach to setdefaultif function dynamically. - if (iOpenCLibrary.Load(_L("libc")) == KErrNone) { - iDynamicSetdefaultif = (TOpenCSetdefaultifFunction)iOpenCLibrary.Lookup(564); - } +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + iMobility = NULL; +#endif TRAP_IGNORE(iConnectionMonitor.ConnectL()); } @@ -88,14 +85,12 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl() iConnection.Close(); iSocketServ.Close(); - if (iDynamicSetdefaultif) { - iDynamicSetdefaultif(0); - } + + // Close global 'Open C' RConnection + setdefaultif(0); iConnectionMonitor.CancelNotifications(); iConnectionMonitor.Close(); - - iOpenCLibrary.Close(); } void QNetworkSessionPrivateImpl::syncStateWithInterface() @@ -203,13 +198,24 @@ QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const } #endif -QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& key) const { + if (key == "ConnectInBackground") { + return QVariant(iConnectInBackground); + } return QVariant(); } -void QNetworkSessionPrivateImpl::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/) +void QNetworkSessionPrivateImpl::setSessionProperty(const QString& key, const QVariant& value) { + // Valid value means adding property, invalid means removing it. + if (key == "ConnectInBackground") { + if (value.isValid()) { + iConnectInBackground = value.toBool(); + } else { + iConnectInBackground = EFalse; + } + } } QString QNetworkSessionPrivateImpl::errorString() const @@ -318,14 +324,12 @@ void QNetworkSessionPrivateImpl::open() #endif connected = ETrue; startTime = QDateTime::currentDateTime(); - if (iDynamicSetdefaultif) { - // Use name of the IAP to set default IAP - QByteArray nameAsByteArray = publicConfig.name().toUtf8(); - ifreq ifr; - strcpy(ifr.ifr_name, nameAsByteArray.constData()); - - error = iDynamicSetdefaultif(&ifr); - } + // Use name of the IAP to open global 'Open C' RConnection + QByteArray nameAsByteArray = publicConfig.name().toUtf8(); + ifreq ifr; + memset(&ifr, 0, sizeof(struct ifreq)); + strcpy(ifr.ifr_name, nameAsByteArray.constData()); + error = setdefaultif(&ifr); isOpen = true; // Make sure that state will be Connected newState(QNetworkSession::Connected); @@ -337,14 +341,30 @@ void QNetworkSessionPrivateImpl::open() } } if (!connected) { - TCommDbConnPref pref; - pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(publicConfig)); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + // With One Click Connectivity (Symbian^3 onwards) it is possible + // to connect silently, without any popups. + TConnPrefList pref; + TExtendedConnPref prefs; + + symbianConfig->mutex.lock(); + prefs.SetIapId(symbianConfig->numericId); + symbianConfig->mutex.unlock(); + if (iConnectInBackground) { + prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent ); + } + pref.AppendL(&prefs); +#else + TCommDbConnPref pref; + pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); + symbianConfig->mutex.lock(); pref.SetIapId(symbianConfig->numericId); symbianConfig->mutex.unlock(); +#endif iConnection.Start(pref, iStatus); if (!IsActive()) { SetActive(); @@ -355,9 +375,21 @@ void QNetworkSessionPrivateImpl::open() SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(publicConfig)); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + TConnPrefList snapPref; + TExtendedConnPref prefs; + symbianConfig->mutex.lock(); + prefs.SetSnapId(symbianConfig->numericId); + symbianConfig->mutex.unlock(); + if (iConnectInBackground) { + prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent ); + } + snapPref.AppendL(&prefs); +#else symbianConfig->mutex.lock(); TConnSnapPref snapPref(symbianConfig->numericId); symbianConfig->mutex.unlock(); +#endif iConnection.Start(snapPref, iStatus); if (!IsActive()) { SetActive(); @@ -441,9 +473,9 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals) iConnection.Close(); iSocketServ.Close(); - if (iDynamicSetdefaultif) { - iDynamicSetdefaultif(0); - } + + // Close global 'Open C' RConnection + setdefaultif(0); #ifdef Q_CC_NOKIAX86 if ((allowSignals && iapClientCount(activeIap) <= 0) || @@ -513,18 +545,26 @@ void QNetworkSessionPrivateImpl::stop() void QNetworkSessionPrivateImpl::migrate() { #ifdef SNAP_FUNCTIONALITY_AVAILABLE - iMobility->MigrateToPreferredCarrier(); + if (iMobility) { + // Close global 'Open C' RConnection + setdefaultif(0); + // Start migrating to new IAP + iMobility->MigrateToPreferredCarrier(); + } #endif } void QNetworkSessionPrivateImpl::ignore() { #ifdef SNAP_FUNCTIONALITY_AVAILABLE - iMobility->IgnorePreferredCarrier(); - if (!iALRUpgradingConnection) { - newState(QNetworkSession::Disconnected); - } else { - newState(QNetworkSession::Connected,iOldRoamingIap); + if (iMobility) { + iMobility->IgnorePreferredCarrier(); + + if (!iALRUpgradingConnection) { + newState(QNetworkSession::Disconnected); + } else { + newState(QNetworkSession::Connected,iOldRoamingIap); + } } #endif } @@ -532,27 +572,43 @@ void QNetworkSessionPrivateImpl::ignore() void QNetworkSessionPrivateImpl::accept() { #ifdef SNAP_FUNCTIONALITY_AVAILABLE - iMobility->NewCarrierAccepted(); - if (iDynamicSetdefaultif) { - // Use name of the IAP to set default IAP - QByteArray nameAsByteArray = activeConfig.name().toUtf8(); + if (iMobility) { + iMobility->NewCarrierAccepted(); + + QNetworkConfiguration newActiveConfig = activeConfiguration(iNewRoamingIap); + + // Use name of the new IAP to open global 'Open C' RConnection + QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); ifreq ifr; + memset(&ifr, 0, sizeof(struct ifreq)); strcpy(ifr.ifr_name, nameAsByteArray.constData()); + setdefaultif(&ifr); - iDynamicSetdefaultif(&ifr); + newState(QNetworkSession::Connected, iNewRoamingIap); } - newState(QNetworkSession::Connected, iNewRoamingIap); #endif } void QNetworkSessionPrivateImpl::reject() { #ifdef SNAP_FUNCTIONALITY_AVAILABLE - iMobility->NewCarrierRejected(); - if (!iALRUpgradingConnection) { - newState(QNetworkSession::Disconnected); - } else { - newState(QNetworkSession::Connected, iOldRoamingIap); + if (iMobility) { + iMobility->NewCarrierRejected(); + + if (!iALRUpgradingConnection) { + newState(QNetworkSession::Disconnected); + } else { + QNetworkConfiguration newActiveConfig = activeConfiguration(iOldRoamingIap); + + // Use name of the old IAP to open global 'Open C' RConnection + QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); + ifreq ifr; + memset(&ifr, 0, sizeof(struct ifreq)); + strcpy(ifr.ifr_name, nameAsByteArray.constData()); + setdefaultif(&ifr); + + newState(QNetworkSession::Connected, iOldRoamingIap); + } } #endif } @@ -849,13 +905,13 @@ void QNetworkSessionPrivateImpl::RunL() QNetworkConfiguration newActiveConfig = activeConfiguration(); if (!newActiveConfig.isValid()) { error = KErrGeneral; - } else if (iDynamicSetdefaultif) { - // Use name of the IAP to set default IAP - QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); + } else { + // Use name of the IAP to open global 'Open C' RConnection ifreq ifr; + memset(&ifr, 0, sizeof(struct ifreq)); + QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); strcpy(ifr.ifr_name, nameAsByteArray.constData()); - - error = iDynamicSetdefaultif(&ifr); + error = setdefaultif(&ifr); } if (error != KErrNone) { @@ -951,14 +1007,12 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint #endif #ifdef SNAP_FUNCTIONALITY_AVAILABLE - if (iDynamicSetdefaultif) { - // Use name of the IAP to set default IAP - QByteArray nameAsByteArray = activeConfig.name().toUtf8(); - ifreq ifr; - strcpy(ifr.ifr_name, nameAsByteArray.constData()); + // Use name of the IAP to set default IAP + QByteArray nameAsByteArray = activeConfig.name().toUtf8(); + ifreq ifr; + strcpy(ifr.ifr_name, nameAsByteArray.constData()); - iDynamicSetdefaultif(&ifr); - } + setdefaultif(&ifr); #endif } diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h index 9a57eae..7116519 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.h +++ b/src/plugins/bearer/symbian/qnetworksession_impl.h @@ -64,8 +64,9 @@ #ifdef SNAP_FUNCTIONALITY_AVAILABLE #include #endif - -typedef int(*TOpenCSetdefaultifFunction)(const struct ifreq*); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + #include +#endif QT_BEGIN_NAMESPACE @@ -152,9 +153,6 @@ private: // data QDateTime startTime; - RLibrary iOpenCLibrary; - TOpenCSetdefaultifFunction iDynamicSetdefaultif; - mutable RSocketServ iSocketServ; mutable RConnection iConnection; mutable RConnectionMonitor iConnectionMonitor; @@ -166,6 +164,7 @@ private: // data QNetworkSession::SessionError iError; TInt iALREnabled; TBool iALRUpgradingConnection; + TBool iConnectInBackground; QList iKnownConfigsBeforeConnectionStart; diff --git a/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro b/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro index df2d2d9..ca463bd 100644 --- a/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro +++ b/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro @@ -8,7 +8,7 @@ symbian { TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData } -maemo6 { +maemo6|maemo5 { CONFIG += link_pkgconfig PKGCONFIG += conninet diff --git a/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp index 70f4447..ce3acb7 100644 --- a/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp +++ b/tests/auto/qnetworkconfiguration/tst_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) ** @@ -41,10 +41,11 @@ #include #include "../qbearertestcommon.h" -#include "qnetworkconfiguration.h" -#include "qnetworkconfigmanager.h" -#ifdef Q_WS_MAEMO_6 +#include +#include + +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) #include #include #endif @@ -65,7 +66,7 @@ private slots: void isRoamingAvailable(); private: -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) Maemo::IAPConf *iapconf; Maemo::IAPConf *iapconf2; Maemo::IAPConf *gprsiap; @@ -77,7 +78,7 @@ private: void tst_QNetworkConfiguration::initTestCase() { -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) iapconf = new Maemo::IAPConf("007"); iapconf->setValue("ipv4_type", "AUTO"); iapconf->setValue("wlan_wepkey1", "connt"); @@ -150,7 +151,7 @@ void tst_QNetworkConfiguration::initTestCase() void tst_QNetworkConfiguration::cleanupTestCase() { -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) iapconf->clear(); delete iapconf; iapconf2->clear(); diff --git a/tests/auto/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro b/tests/auto/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro index e0028e5..d9c1d6b 100644 --- a/tests/auto/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro +++ b/tests/auto/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro @@ -8,7 +8,7 @@ symbian { TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData } -maemo6 { +maemo6|maemo5 { CONFIG += link_pkgconfig PKGCONFIG += conninet diff --git a/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp b/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp index 30c5a74..7cc527c 100644 --- a/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp +++ b/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp @@ -41,10 +41,11 @@ #include #include "../qbearertestcommon.h" -#include "qnetworkconfiguration.h" -#include "qnetworkconfigmanager.h" -#ifdef Q_WS_MAEMO_6 +#include +#include + +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) #include #include #endif @@ -66,7 +67,7 @@ private slots: void configurationFromIdentifier(); private: -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) Maemo::IAPConf *iapconf; Maemo::IAPConf *iapconf2; Maemo::IAPConf *gprsiap; @@ -78,7 +79,7 @@ private: void tst_QNetworkConfigurationManager::initTestCase() { -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) iapconf = new Maemo::IAPConf("007"); iapconf->setValue("ipv4_type", "AUTO"); iapconf->setValue("wlan_wepkey1", "connt"); @@ -152,7 +153,7 @@ void tst_QNetworkConfigurationManager::initTestCase() void tst_QNetworkConfigurationManager::cleanupTestCase() { -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) iapconf->clear(); delete iapconf; iapconf2->clear(); diff --git a/tests/auto/qnetworksession/lackey/main.cpp b/tests/auto/qnetworksession/lackey/main.cpp index 66d6dd4..8759b52 100644 --- a/tests/auto/qnetworksession/lackey/main.cpp +++ b/tests/auto/qnetworksession/lackey/main.cpp @@ -42,9 +42,10 @@ #include #include #include -#include -#include -#include + +#include +#include +#include #include diff --git a/tests/auto/qnetworksession/test/test.pro b/tests/auto/qnetworksession/test/test.pro index d248b10..bfffe90 100644 --- a/tests/auto/qnetworksession/test/test.pro +++ b/tests/auto/qnetworksession/test/test.pro @@ -19,7 +19,7 @@ symbian { TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData PowerMgmt } -maemo6 { +maemo6|maemo5 { CONFIG += link_pkgconfig PKGCONFIG += conninet diff --git a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp index 58b0576..23cdc6a 100644 --- a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp +++ b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp @@ -44,10 +44,11 @@ #include #include #include "../../qbearertestcommon.h" -#include -#include -#ifdef Q_WS_MAEMO_6 +#include +#include + +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) #include #include #endif @@ -72,6 +73,8 @@ public slots: private slots: + void robustnessBombing(); + void outOfProcessSession(); void invalidSession(); @@ -100,7 +103,7 @@ private: int inProcessSessionManagementCount; -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) Maemo::IAPConf *iapconf; Maemo::IAPConf *iapconf2; Maemo::IAPConf *gprsiap; @@ -123,7 +126,7 @@ void tst_QNetworkSession::initTestCase() qRegisterMetaType("QNetworkConfiguration"); qRegisterMetaType("QNetworkConfiguration::Type"); -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) iapconf = new Maemo::IAPConf("007"); iapconf->setValue("ipv4_type", "AUTO"); iapconf->setValue("wlan_wepkey1", "connt"); @@ -209,7 +212,7 @@ void tst_QNetworkSession::cleanupTestCase() "inProcessSessionManagement()"); } -#ifdef Q_WS_MAEMO_6 +#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5) iapconf->clear(); delete iapconf; iapconf2->clear(); @@ -232,6 +235,23 @@ void tst_QNetworkSession::cleanupTestCase() #endif } +// Robustness test for calling interfaces in nonsense order / with nonsense parameters +void tst_QNetworkSession::robustnessBombing() +{ + QNetworkConfigurationManager mgr; + QNetworkSession testSession(mgr.defaultConfiguration()); + // Should not reset even session is not opened + testSession.migrate(); + testSession.accept(); + testSession.ignore(); + testSession.reject(); + quint64 temp; + temp = testSession.bytesWritten(); + temp = testSession.bytesReceived(); + temp = testSession.activeTime(); +} + + void tst_QNetworkSession::invalidSession() { // 1. Verify that session created with invalid configuration remains in invalid state diff --git a/tests/manual/bearerex/bearerex.h b/tests/manual/bearerex/bearerex.h index 2875d6a..6bcb3e5 100644 --- a/tests/manual/bearerex/bearerex.h +++ b/tests/manual/bearerex/bearerex.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) ** @@ -44,10 +44,15 @@ #include -#include "ui_bearerex.h" #include "ui_detailedinfodialog.h" -#include "ui_sessiondialog.h" +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) +#include "ui_bearerex_maemo.h" +#include "ui_sessiondialog_maemo.h" +#else +#include "ui_bearerex.h" +#include "ui_sessiondialog.h" +#endif #include "qnetworkconfigmanager.h" #include "qnetworksession.h" #include "xqlistwidget.h" diff --git a/tests/manual/bearerex/bearerex.pro b/tests/manual/bearerex/bearerex.pro index 927f982..7b21183 100644 --- a/tests/manual/bearerex/bearerex.pro +++ b/tests/manual/bearerex/bearerex.pro @@ -5,9 +5,15 @@ QT += core \ gui \ network -FORMS += sessiondialog.ui \ - bearerex.ui \ - detailedinfodialog.ui +FORMS += detailedinfodialog.ui +maemo5|maemo6 { + FORMS += sessiondialog_maemo.ui \ + bearerex_maemo.ui +} else { + FORMS += sessiondialog.ui \ + bearerex.ui +} + # Example headers and sources HEADERS += bearerex.h \ @@ -17,4 +23,4 @@ SOURCES += bearerex.cpp \ main.cpp \ xqlistwidget.cpp -symbian:TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData \ No newline at end of file +symbian:TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData diff --git a/tests/manual/bearerex/bearerex_maemo.ui b/tests/manual/bearerex/bearerex_maemo.ui new file mode 100644 index 0000000..cb17e38 --- /dev/null +++ b/tests/manual/bearerex/bearerex_maemo.ui @@ -0,0 +1,100 @@ + + + BearerExMainWindow + + + + 0 + 0 + 360 + 640 + + + + Bearer Example + + + + + + + + Main + + + + + + + + Network Configurations + + + Qt::AlignCenter + + + + + + + + + + + + + + Update Configs + + + + + + + Update List + + + + + + + Create Session + + + + + + + Show Details + + + + + + + + + + Events + + + + + + + + + Clear + + + + + + + + + + + + + diff --git a/tests/manual/bearerex/sessiondialog_maemo.ui b/tests/manual/bearerex/sessiondialog_maemo.ui new file mode 100644 index 0000000..5eb98ce --- /dev/null +++ b/tests/manual/bearerex/sessiondialog_maemo.ui @@ -0,0 +1,151 @@ + + + SessionTab + + + + 0 + 0 + 423 + 214 + + + + + + + QFormLayout::ExpandingFieldsGrow + + + + + SNAP + + + + + + + true + + + + + + + IAP + + + + + + + true + + + true + + + + + + + Bearer + + + + + + + true + + + + + + + Sent/Rec. + + + + + + + true + + + + + + + State + + + + + + + true + + + + + + + + + + + Open Session + + + + + + + Close Session + + + + + + + Stop Conn. + + + + + + + Send Test Req. + + + + + + + Create QHttp + + + + + + + Delete Session + + + + + + + Enable ALR + + + + + + + + + + -- cgit v0.12