summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.tests/mac/corewlan/corewlan.pro3
-rw-r--r--config.tests/mac/corewlan/corewlantest.mm49
-rw-r--r--config.tests/unix/networkmanager/main.cpp51
-rw-r--r--config.tests/unix/networkmanager/networkmanager.pro3
-rwxr-xr-xconfigure236
-rw-r--r--doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp9
-rw-r--r--doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp49
-rw-r--r--examples/network/bearercloud/bearercloud.cpp197
-rw-r--r--examples/network/bearercloud/bearercloud.h81
-rw-r--r--examples/network/bearercloud/bearercloud.pro16
-rw-r--r--examples/network/bearercloud/cloud.cpp361
-rw-r--r--examples/network/bearercloud/cloud.h99
-rw-r--r--examples/network/bearercloud/icons.qrc7
-rw-r--r--examples/network/bearercloud/lan.svg76
-rw-r--r--examples/network/bearercloud/main.cpp89
-rw-r--r--examples/network/bearercloud/unknown.svg76
-rw-r--r--examples/network/bearercloud/wlan.svg151
-rw-r--r--examples/network/bearermonitor/bearermonitor.cpp395
-rw-r--r--examples/network/bearermonitor/bearermonitor.h92
-rw-r--r--examples/network/bearermonitor/bearermonitor.pro26
-rw-r--r--examples/network/bearermonitor/bearermonitor_240_320.ui420
-rw-r--r--examples/network/bearermonitor/bearermonitor_640_480.ui386
-rw-r--r--examples/network/bearermonitor/main.cpp55
-rw-r--r--examples/network/bearermonitor/sessionwidget.cpp177
-rw-r--r--examples/network/bearermonitor/sessionwidget.h78
-rw-r--r--examples/network/bearermonitor/sessionwidget.ui307
-rw-r--r--examples/network/network.pro4
-rw-r--r--qmake/Makefile.unix14
-rw-r--r--qmake/Makefile.win3212
-rw-r--r--qmake/Makefile.win32-g++9
-rw-r--r--qmake/Makefile.win32-g++-sh9
-rw-r--r--qmake/generators/symbian/initprojectdeploy_symbian.cpp96
-rw-r--r--qmake/generators/symbian/initprojectdeploy_symbian.h2
-rw-r--r--qmake/generators/symbian/symmake.cpp3
-rw-r--r--qmake/generators/symbian/symmake_abld.cpp3
-rw-r--r--qmake/generators/symbian/symmake_sbsv2.cpp3
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp97
-rw-r--r--qmake/project.cpp5
-rw-r--r--qmake/qmake.pri9
-rw-r--r--qmake/qmake.pro4
-rw-r--r--src/declarative/qml/qmllist.h3
-rw-r--r--src/gui/painting/qpainter.cpp1
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp33
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h6
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp48
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h5
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp198
-rw-r--r--src/network/access/qnetworkaccessmanager.h17
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h15
-rw-r--r--src/network/access/qnetworkreply.cpp5
-rw-r--r--src/network/access/qnetworkreply.h1
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp160
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h31
-rw-r--r--src/network/bearer/bearer.pri18
-rw-r--r--src/network/bearer/qbearerengine.cpp75
-rw-r--r--src/network/bearer/qbearerengine_p.h112
-rw-r--r--src/network/bearer/qbearerplugin.cpp (renamed from qmake/generators/symbian/epocroot.h)22
-rw-r--r--src/network/bearer/qbearerplugin_p.h93
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp419
-rw-r--r--src/network/bearer/qnetworkconfigmanager.h101
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp211
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.h114
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp396
-rw-r--r--src/network/bearer/qnetworkconfiguration.h115
-rw-r--r--src/network/bearer/qnetworkconfiguration_p.h107
-rw-r--r--src/network/bearer/qnetworksession.cpp684
-rw-r--r--src/network/bearer/qnetworksession.h132
-rw-r--r--src/network/bearer/qnetworksession_p.h150
-rw-r--r--src/network/network.pro1
-rw-r--r--src/plugins/bearer/bearer.pro14
-rw-r--r--src/plugins/bearer/corewlan/corewlan.pro24
-rw-r--r--src/plugins/bearer/corewlan/main.cpp84
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.h99
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm553
-rw-r--r--src/plugins/bearer/generic/generic.pro16
-rw-r--r--src/plugins/bearer/generic/main.cpp84
-rw-r--r--src/plugins/bearer/generic/qgenericengine.cpp333
-rw-r--r--src/plugins/bearer/generic/qgenericengine.h92
-rw-r--r--src/plugins/bearer/icd/icd.pro22
-rw-r--r--src/plugins/bearer/icd/main.cpp84
-rw-r--r--src/plugins/bearer/icd/monitor.cpp116
-rw-r--r--src/plugins/bearer/icd/monitor.h116
-rw-r--r--src/plugins/bearer/icd/qicdengine.cpp426
-rw-r--r--src/plugins/bearer/icd/qicdengine.h130
-rw-r--r--src/plugins/bearer/icd/qnetworksession_impl.cpp1104
-rw-r--r--src/plugins/bearer/icd/qnetworksession_impl.h147
-rw-r--r--src/plugins/bearer/nativewifi/main.cpp139
-rw-r--r--src/plugins/bearer/nativewifi/nativewifi.pro17
-rw-r--r--src/plugins/bearer/nativewifi/platformdefs.h322
-rw-r--r--src/plugins/bearer/nativewifi/qnativewifiengine.cpp495
-rw-r--r--src/plugins/bearer/nativewifi/qnativewifiengine.h104
-rw-r--r--src/plugins/bearer/networkmanager/main.cpp89
-rw-r--r--src/plugins/bearer/networkmanager/networkmanager.pro20
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp847
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.h139
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp1046
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.h397
-rw-r--r--src/plugins/bearer/networkmanager/qnmdbushelper.cpp117
-rw-r--r--src/plugins/bearer/networkmanager/qnmdbushelper.h73
-rw-r--r--src/plugins/bearer/nla/main.cpp84
-rw-r--r--src/plugins/bearer/nla/nla.pro23
-rw-r--r--src/plugins/bearer/nla/qnlaengine.cpp661
-rw-r--r--src/plugins/bearer/nla/qnlaengine.h114
-rw-r--r--src/plugins/bearer/platformdefs_win.h134
-rw-r--r--src/plugins/bearer/qbearerengine_impl.h81
-rw-r--r--src/plugins/bearer/qnetworksession_impl.cpp408
-rw-r--r--src/plugins/bearer/qnetworksession_impl.h130
-rw-r--r--src/plugins/bearer/symbian/main.cpp84
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp1135
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.h196
-rw-r--r--src/plugins/bearer/symbian/symbian.pro37
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp1006
-rw-r--r--src/plugins/bearer/symbian/symbianengine.h205
-rw-r--r--src/plugins/plugins.pro2
-rw-r--r--src/s60installs/s60installs.pro11
-rw-r--r--tests/auto/auto.pro3
-rw-r--r--tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp2
-rw-r--r--tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp2
-rw-r--r--tests/auto/qbearertestcommon.h74
-rw-r--r--tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro15
-rw-r--r--tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp335
-rw-r--r--tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro15
-rw-r--r--tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp303
-rw-r--r--tests/auto/qnetworksession/lackey/lackey.pro15
-rw-r--r--tests/auto/qnetworksession/lackey/main.cpp145
-rw-r--r--tests/auto/qnetworksession/qnetworksession.pro2
-rw-r--r--tests/auto/qnetworksession/test/test.pro26
-rw-r--r--tests/auto/qnetworksession/test/tst_qnetworksession.cpp919
-rw-r--r--tests/manual/bearerex/bearerex.cpp561
-rw-r--r--tests/manual/bearerex/bearerex.h142
-rw-r--r--tests/manual/bearerex/bearerex.pro20
-rw-r--r--tests/manual/bearerex/bearerex.ui95
-rw-r--r--tests/manual/bearerex/detailedinfodialog.ui54
-rw-r--r--tests/manual/bearerex/main.cpp59
-rw-r--r--tests/manual/bearerex/sessiondialog.ui139
-rw-r--r--tests/manual/bearerex/xqlistwidget.cpp67
-rw-r--r--tests/manual/bearerex/xqlistwidget.h59
-rw-r--r--tests/manual/networkmanager/README2
-rw-r--r--tests/manual/networkmanager/dialog.ui213
-rw-r--r--tests/manual/networkmanager/networkmanager.pro9
-rw-r--r--tests/manual/networkmanager/networkmanagertest.cpp287
-rw-r--r--tests/manual/networkmanager/nmview.cpp1028
-rw-r--r--tests/manual/networkmanager/nmview.h109
-rw-r--r--tests/manual/networkmanager/startdlg.cpp96
-rw-r--r--tests/manual/networkmanager/startdlg.h59
-rw-r--r--tools/shared/symbian/epocroot.cpp230
-rw-r--r--tools/shared/symbian/epocroot.h67
-rw-r--r--tools/shared/windows/registry.cpp161
-rw-r--r--tools/shared/windows/registry.h64
149 files changed, 23645 insertions, 324 deletions
diff --git a/config.tests/mac/corewlan/corewlan.pro b/config.tests/mac/corewlan/corewlan.pro
new file mode 100644
index 0000000000..8451af3e5b
--- /dev/null
+++ b/config.tests/mac/corewlan/corewlan.pro
@@ -0,0 +1,3 @@
+SOURCES = corewlantest.mm
+LIBS += -framework CoreWLAN -framework Foundation
+CONFIG -= app_bundle qt
diff --git a/config.tests/mac/corewlan/corewlantest.mm b/config.tests/mac/corewlan/corewlantest.mm
new file mode 100644
index 0000000000..3a29d84a02
--- /dev/null
+++ b/config.tests/mac/corewlan/corewlantest.mm
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the config.tests 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 <CoreWLAN/CoreWLAN.h>
+#include <CoreWLAN/CWInterface.h>
+
+int main()
+{
+ [CWInterface interfaceWithName:@"en2"];
+ return 0;
+}
diff --git a/config.tests/unix/networkmanager/main.cpp b/config.tests/unix/networkmanager/main.cpp
new file mode 100644
index 0000000000..7b91ae0372
--- /dev/null
+++ b/config.tests/unix/networkmanager/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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 config.tests 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$
+**
+****************************************************************************/
+
+#if defined(QT_NO_DBUS)
+#error Qt is not configured with DBus support.
+#endif
+
+#include <NetworkManager/NetworkManager.h>
+
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/config.tests/unix/networkmanager/networkmanager.pro b/config.tests/unix/networkmanager/networkmanager.pro
new file mode 100644
index 0000000000..c41204f49f
--- /dev/null
+++ b/config.tests/unix/networkmanager/networkmanager.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+CONFIG -= qt dylib
+mac:CONFIG -= app_bundle
diff --git a/configure b/configure
index f1fe686238..1e7c65eee3 100755
--- a/configure
+++ b/configure
@@ -783,6 +783,8 @@ OPT_HELP=
CFG_SILENT=no
CFG_GRAPHICS_SYSTEM=default
CFG_ALSA=auto
+CFG_NETWORKMANAGER=auto
+CFG_COREWLAN=auto
# initalize variables used for installation
QT_INSTALL_PREFIX=
@@ -5444,6 +5446,14 @@ if [ "$PLATFORM_MAC" = "yes" ]; then
# Always enable Phonon (unless it was explicitly disabled)
CFG_PHONON=yes
fi
+
+ if [ "$CFG_COREWLAN" = "auto" ]; then
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/mac/corewlan "CoreWlan" $L_FLAGS $I_FLAGS $l_FLAGS; then
+ CFG_COREWLAN=yes
+ else
+ CFG_COREWLAN=no
+ fi
+ fi
fi
# QWS
@@ -5898,6 +5908,14 @@ if [ "$CFG_ALSA" = "auto" ]; then
fi
fi
+if [ "$CFG_NETWORKMANAGER" = "auto" ]; then
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/networkmanager "NetworkManager" $L_FLAGS $I_FLAGS $l_FLAGS; then
+ CFG_NETWORKMANAGER=yes
+ else
+ CFG_NETWORKMANAGER=no
+ fi
+fi
+
if [ -f "$relpath/src/declarative/declarative.pro" ]; then
if [ "$CFG_DECLARATIVE" = "auto" ]; then
CFG_DECLARATIVE=yes
@@ -6384,6 +6402,14 @@ if [ "$CFG_ALSA" = "yes" ]; then
QT_CONFIG="$QT_CONFIG alsa"
fi
+if [ "$CFG_NETWORKMANAGER" = "yes" ]; then
+ QT_CONFIG="$QT_CONFIG networkmanager"
+fi
+
+if [ "$CFG_COREWLAN" = "yes" ]; then
+ QT_CONFIG="$QT_CONFIG corewlan"
+fi
+
#
# Some Qt modules are too advanced in C++ for some old compilers
# Detect here the platforms where they are known to work.
@@ -7088,6 +7114,8 @@ fi
[ "$CFG_XRANDR" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XRANDR"
[ "$CFG_XINPUT" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XINPUT"
[ "$CFG_ALSA" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ALSA"
+[ "$CFG_NETWORKMANAGER" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NETWORKMANAGER"
+[ "$CFG_COREWLAN" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_COREWLAN"
# sort QCONFIG_FLAGS for neatness if we can
[ '!' -z "$AWK" ] && QCONFIG_FLAGS=`echo $QCONFIG_FLAGS | $AWK '{ gsub(" ", "\n"); print }' | sort | uniq`
@@ -7423,163 +7451,163 @@ fi
if [ "$OPT_VERBOSE" = "yes" ]; then
if echo '\c' | grep '\c' >/dev/null; then
- echo -n "qmake vars .......... "
+ echo -n "qmake vars ............. "
else
- echo "qmake vars .......... \c"
+ echo "qmake vars ............. \c"
fi
cat "$QMAKE_VARS_FILE" | tr '\n' ' '
- echo "qmake switches ...... $QMAKE_SWITCHES"
+ echo "qmake switches ......... $QMAKE_SWITCHES"
fi
-[ "$CFG_INCREMENTAL" = "yes" ] && [ '!' -z "$INCREMENTAL" ] && echo "Incremental ......... $INCREMENTAL"
-echo "Build ............... $CFG_BUILD_PARTS"
-echo "Configuration ....... $QMAKE_CONFIG $QT_CONFIG"
+[ "$CFG_INCREMENTAL" = "yes" ] && [ '!' -z "$INCREMENTAL" ] && echo "Incremental ............ $INCREMENTAL"
+echo "Build .................. $CFG_BUILD_PARTS"
+echo "Configuration .......... $QMAKE_CONFIG $QT_CONFIG"
if [ "$CFG_DEBUG_RELEASE" = "yes" ]; then
- echo "Debug ............... yes (combined)"
+ echo "Debug .................. yes (combined)"
if [ "$CFG_DEBUG" = "yes" ]; then
- echo "Default Link ........ debug"
+ echo "Default Link ........... debug"
else
- echo "Default Link ........ release"
+ echo "Default Link ........... release"
fi
else
- echo "Debug ............... $CFG_DEBUG"
-fi
-echo "Qt 3 compatibility .. $CFG_QT3SUPPORT"
-[ "$CFG_DBUS" = "no" ] && echo "QtDBus module ....... no"
-[ "$CFG_DBUS" = "yes" ] && echo "QtDBus module ....... yes (run-time)"
-[ "$CFG_DBUS" = "linked" ] && echo "QtDBus module ....... yes (linked)"
-echo "QtConcurrent code.... $CFG_CONCURRENT"
-echo "QtScript module ..... $CFG_SCRIPT"
-echo "QtScriptTools module $CFG_SCRIPTTOOLS"
-echo "QtXmlPatterns module $CFG_XMLPATTERNS"
-echo "Phonon module ....... $CFG_PHONON"
-echo "Multimedia module ... $CFG_MULTIMEDIA"
-echo "SVG module .......... $CFG_SVG"
-echo "WebKit module ....... $CFG_WEBKIT"
+ echo "Debug .................. $CFG_DEBUG"
+fi
+echo "Qt 3 compatibility ..... $CFG_QT3SUPPORT"
+[ "$CFG_DBUS" = "no" ] && echo "QtDBus module .......... no"
+[ "$CFG_DBUS" = "yes" ] && echo "QtDBus module .......... yes (run-time)"
+[ "$CFG_DBUS" = "linked" ] && echo "QtDBus module .......... yes (linked)"
+echo "QtConcurrent code ...... $CFG_CONCURRENT"
+echo "QtScript module ........ $CFG_SCRIPT"
+echo "QtScriptTools module ... $CFG_SCRIPTTOOLS"
+echo "QtXmlPatterns module ... $CFG_XMLPATTERNS"
+echo "Phonon module .......... $CFG_PHONON"
+echo "Multimedia module ...... $CFG_MULTIMEDIA"
+echo "SVG module ............. $CFG_SVG"
+echo "WebKit module .......... $CFG_WEBKIT"
if [ "$CFG_WEBKIT" = "yes" ]; then
if [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then
- echo "JavaScriptCore JIT .. To be decided by JavaScriptCore"
+ echo "JavaScriptCore JIT ..... To be decided by JavaScriptCore"
else
- echo "JavaScriptCore JIT .. $CFG_JAVASCRIPTCORE_JIT"
+ echo "JavaScriptCore JIT ..... $CFG_JAVASCRIPTCORE_JIT"
fi
fi
-echo "Declarative module .. $CFG_DECLARATIVE"
-echo "STL support ......... $CFG_STL"
-echo "PCH support ......... $CFG_PRECOMPILE"
-echo "MMX/3DNOW/SSE/SSE2.. ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}"
+echo "Declarative module ..... $CFG_DECLARATIVE"
+echo "STL support ............ $CFG_STL"
+echo "PCH support ............ $CFG_PRECOMPILE"
+echo "MMX/3DNOW/SSE/SSE2 ..... ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}"
if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then
- echo "iWMMXt support ...... ${CFG_IWMMXT}"
- echo "NEON support ........ ${CFG_NEON}"
-fi
-[ "${PLATFORM_QWS}" != "yes" ] && echo "Graphics System ..... $CFG_GRAPHICS_SYSTEM"
-echo "IPv6 support ........ $CFG_IPV6"
-echo "IPv6 ifname support . $CFG_IPV6IFNAME"
-echo "getaddrinfo support . $CFG_GETADDRINFO"
-echo "getifaddrs support .. $CFG_GETIFADDRS"
-echo "Accessibility ....... $CFG_ACCESSIBILITY"
-echo "NIS support ......... $CFG_NIS"
-echo "CUPS support ........ $CFG_CUPS"
-echo "Iconv support ....... $CFG_ICONV"
-echo "Glib support ........ $CFG_GLIB"
-echo "GStreamer support ... $CFG_GSTREAMER"
-echo "Large File support .. $CFG_LARGEFILE"
-echo "GIF support ......... $CFG_GIF"
+ echo "iWMMXt support ......... ${CFG_IWMMXT}"
+ echo "NEON support ........... ${CFG_NEON}"
+fi
+[ "${PLATFORM_QWS}" != "yes" ] && echo "Graphics System ........ $CFG_GRAPHICS_SYSTEM"
+echo "IPv6 support ........... $CFG_IPV6"
+echo "IPv6 ifname support .... $CFG_IPV6IFNAME"
+echo "getaddrinfo support .... $CFG_GETADDRINFO"
+echo "getifaddrs support ..... $CFG_GETIFADDRS"
+echo "Accessibility .......... $CFG_ACCESSIBILITY"
+echo "NIS support ............ $CFG_NIS"
+echo "CUPS support ........... $CFG_CUPS"
+echo "Iconv support .......... $CFG_ICONV"
+echo "Glib support ........... $CFG_GLIB"
+echo "GStreamer support ...... $CFG_GSTREAMER"
+echo "Large File support ..... $CFG_LARGEFILE"
+echo "GIF support ............ $CFG_GIF"
if [ "$CFG_TIFF" = "no" ]; then
- echo "TIFF support ........ $CFG_TIFF"
+ echo "TIFF support ........... $CFG_TIFF"
else
- echo "TIFF support ........ $CFG_TIFF ($CFG_LIBTIFF)"
+ echo "TIFF support ........... $CFG_TIFF ($CFG_LIBTIFF)"
fi
if [ "$CFG_JPEG" = "no" ]; then
- echo "JPEG support ........ $CFG_JPEG"
+ echo "JPEG support ........... $CFG_JPEG"
else
- echo "JPEG support ........ $CFG_JPEG ($CFG_LIBJPEG)"
+ echo "JPEG support ........... $CFG_JPEG ($CFG_LIBJPEG)"
fi
if [ "$CFG_PNG" = "no" ]; then
- echo "PNG support ......... $CFG_PNG"
+ echo "PNG support ............ $CFG_PNG"
else
- echo "PNG support ......... $CFG_PNG ($CFG_LIBPNG)"
+ echo "PNG support ............ $CFG_PNG ($CFG_LIBPNG)"
fi
if [ "$CFG_MNG" = "no" ]; then
- echo "MNG support ......... $CFG_MNG"
+ echo "MNG support ............ $CFG_MNG"
else
- echo "MNG support ......... $CFG_MNG ($CFG_LIBMNG)"
+ echo "MNG support ............ $CFG_MNG ($CFG_LIBMNG)"
fi
-echo "zlib support ........ $CFG_ZLIB"
-echo "Session management .. $CFG_SM"
+echo "zlib support ........... $CFG_ZLIB"
+echo "Session management ..... $CFG_SM"
if [ "$PLATFORM_QWS" = "yes" ]; then
- echo "Embedded support .... $CFG_EMBEDDED"
+ echo "Embedded support ....... $CFG_EMBEDDED"
if [ "$CFG_QWS_FREETYPE" = "auto" ]; then
- echo "Freetype2 support ... $CFG_QWS_FREETYPE ($CFG_LIBFREETYPE)"
+ echo "Freetype2 support ...... $CFG_QWS_FREETYPE ($CFG_LIBFREETYPE)"
else
- echo "Freetype2 support ... $CFG_QWS_FREETYPE"
+ echo "Freetype2 support ...... $CFG_QWS_FREETYPE"
fi
# Normalize the decoration output first
CFG_GFX_ON=`echo ${CFG_GFX_ON}`
CFG_GFX_PLUGIN=`echo ${CFG_GFX_PLUGIN}`
- echo "Graphics (qt) ....... ${CFG_GFX_ON}"
- echo "Graphics (plugin) ... ${CFG_GFX_PLUGIN}"
+ echo "Graphics (qt) .......... ${CFG_GFX_ON}"
+ echo "Graphics (plugin) ...... ${CFG_GFX_PLUGIN}"
CFG_DECORATION_ON=`echo ${CFG_DECORATION_ON}`
CFG_DECORATION_PLUGIN=`echo ${CFG_DECORATION_PLUGIN}`
- echo "Decorations (qt) .... $CFG_DECORATION_ON"
- echo "Decorations (plugin) $CFG_DECORATION_PLUGIN"
+ echo "Decorations (qt) ....... $CFG_DECORATION_ON"
+ echo "Decorations (plugin) ... $CFG_DECORATION_PLUGIN"
CFG_KBD_ON=`echo ${CFG_KBD_ON}`
CFG_KBD_PLUGIN=`echo ${CFG_KBD_PLUGIN}`
- echo "Keyboard driver (qt). ${CFG_KBD_ON}"
- echo "Keyboard driver (plugin) ${CFG_KBD_PLUGIN}"
+ echo "Keyboard driver (qt) ... ${CFG_KBD_ON}"
+ echo "Keyboard driver (plugin) .. ${CFG_KBD_PLUGIN}"
CFG_MOUSE_ON=`echo ${CFG_MOUSE_ON}`
CFG_MOUSE_PLUGIN=`echo ${CFG_MOUSE_PLUGIN}`
- echo "Mouse driver (qt) ... $CFG_MOUSE_ON"
- echo "Mouse driver (plugin) $CFG_MOUSE_PLUGIN"
+ echo "Mouse driver (qt) ...... $CFG_MOUSE_ON"
+ echo "Mouse driver (plugin) .. $CFG_MOUSE_PLUGIN"
fi
if [ "$CFG_OPENGL" = "desktop" ]; then
- echo "OpenGL support ...... yes (Desktop OpenGL)"
+ echo "OpenGL support ......... yes (Desktop OpenGL)"
elif [ "$CFG_OPENGL" = "es1" ]; then
- echo "OpenGL support ...... yes (OpenGL ES 1.x Common profile)"
+ echo "OpenGL support ......... yes (OpenGL ES 1.x Common profile)"
elif [ "$CFG_OPENGL" = "es2" ]; then
- echo "OpenGL support ...... yes (OpenGL ES 2.x)"
+ echo "OpenGL support ......... yes (OpenGL ES 2.x)"
else
- echo "OpenGL support ...... no"
+ echo "OpenGL support ......... no"
fi
if [ "$CFG_EGL" != "no" ]; then
if [ "$CFG_EGL_GLES_INCLUDES" != "no" ]; then
- echo "EGL support ......... yes <GLES/egl.h>"
+ echo "EGL support ............ yes <GLES/egl.h>"
else
- echo "EGL support ......... yes <EGL/egl.h>"
+ echo "EGL support ............ yes <EGL/egl.h>"
fi
fi
if [ "$CFG_OPENVG" ]; then
if [ "$CFG_OPENVG_SHIVA" = "yes" ]; then
- echo "OpenVG support ...... ShivaVG"
+ echo "OpenVG support ......... ShivaVG"
else
- echo "OpenVG support ...... $CFG_OPENVG"
+ echo "OpenVG support ......... $CFG_OPENVG"
fi
fi
if [ "$PLATFORM_X11" = "yes" ]; then
- echo "NAS sound support ... $CFG_NAS"
- echo "XShape support ...... $CFG_XSHAPE"
- echo "XVideo support ...... $CFG_XVIDEO"
- echo "XSync support ....... $CFG_XSYNC"
- echo "Xinerama support .... $CFG_XINERAMA"
- echo "Xcursor support ..... $CFG_XCURSOR"
- echo "Xfixes support ...... $CFG_XFIXES"
- echo "Xrandr support ...... $CFG_XRANDR"
- echo "Xrender support ..... $CFG_XRENDER"
- echo "Xi support .......... $CFG_XINPUT"
- echo "MIT-SHM support ..... $CFG_MITSHM"
- echo "FontConfig support .. $CFG_FONTCONFIG"
- echo "XKB Support ......... $CFG_XKB"
- echo "immodule support .... $CFG_IM"
- echo "GTK theme support ... $CFG_QGTKSTYLE"
-fi
-[ "$CFG_SQL_mysql" != "no" ] && echo "MySQL support ....... $CFG_SQL_mysql"
-[ "$CFG_SQL_psql" != "no" ] && echo "PostgreSQL support .. $CFG_SQL_psql"
-[ "$CFG_SQL_odbc" != "no" ] && echo "ODBC support ........ $CFG_SQL_odbc"
-[ "$CFG_SQL_oci" != "no" ] && echo "OCI support ......... $CFG_SQL_oci"
-[ "$CFG_SQL_tds" != "no" ] && echo "TDS support ......... $CFG_SQL_tds"
-[ "$CFG_SQL_db2" != "no" ] && echo "DB2 support ......... $CFG_SQL_db2"
-[ "$CFG_SQL_ibase" != "no" ] && echo "InterBase support ... $CFG_SQL_ibase"
-[ "$CFG_SQL_sqlite2" != "no" ] && echo "SQLite 2 support .... $CFG_SQL_sqlite2"
-[ "$CFG_SQL_sqlite" != "no" ] && echo "SQLite support ...... $CFG_SQL_sqlite ($CFG_SQLITE)"
+ echo "NAS sound support ...... $CFG_NAS"
+ echo "XShape support ......... $CFG_XSHAPE"
+ echo "XVideo support ......... $CFG_XVIDEO"
+ echo "XSync support .......... $CFG_XSYNC"
+ echo "Xinerama support ....... $CFG_XINERAMA"
+ echo "Xcursor support ........ $CFG_XCURSOR"
+ echo "Xfixes support ......... $CFG_XFIXES"
+ echo "Xrandr support ......... $CFG_XRANDR"
+ echo "Xrender support ........ $CFG_XRENDER"
+ echo "Xi support ............. $CFG_XINPUT"
+ echo "MIT-SHM support ........ $CFG_MITSHM"
+ echo "FontConfig support ..... $CFG_FONTCONFIG"
+ echo "XKB Support ............ $CFG_XKB"
+ echo "immodule support ....... $CFG_IM"
+ echo "GTK theme support ...... $CFG_QGTKSTYLE"
+fi
+[ "$CFG_SQL_mysql" != "no" ] && echo "MySQL support .......... $CFG_SQL_mysql"
+[ "$CFG_SQL_psql" != "no" ] && echo "PostgreSQL support ..... $CFG_SQL_psql"
+[ "$CFG_SQL_odbc" != "no" ] && echo "ODBC support ........... $CFG_SQL_odbc"
+[ "$CFG_SQL_oci" != "no" ] && echo "OCI support ............ $CFG_SQL_oci"
+[ "$CFG_SQL_tds" != "no" ] && echo "TDS support ............ $CFG_SQL_tds"
+[ "$CFG_SQL_db2" != "no" ] && echo "DB2 support ............ $CFG_SQL_db2"
+[ "$CFG_SQL_ibase" != "no" ] && echo "InterBase support ...... $CFG_SQL_ibase"
+[ "$CFG_SQL_sqlite2" != "no" ] && echo "SQLite 2 support ....... $CFG_SQL_sqlite2"
+[ "$CFG_SQL_sqlite" != "no" ] && echo "SQLite support ......... $CFG_SQL_sqlite ($CFG_SQLITE)"
OPENSSL_LINKAGE=""
if [ "$CFG_OPENSSL" = "yes" ]; then
@@ -7587,11 +7615,15 @@ if [ "$CFG_OPENSSL" = "yes" ]; then
elif [ "$CFG_OPENSSL" = "linked" ]; then
OPENSSL_LINKAGE="(linked)"
fi
-echo "OpenSSL support ..... $CFG_OPENSSL $OPENSSL_LINKAGE"
-echo "Alsa support ........ $CFG_ALSA"
+echo "OpenSSL support ........ $CFG_OPENSSL $OPENSSL_LINKAGE"
+echo "Alsa support ........... $CFG_ALSA"
+echo "NetworkManager support . $CFG_NETWORKMANAGER"
+if [ "$PLATFORM_MAC" = "yes" ]; then
+ echo "CoreWlan support ....... $CFG_COREWLAN"
+fi
echo
-[ "$CFG_PTMALLOC" != "no" ] && echo "Use ptmalloc ........ $CFG_PTMALLOC"
+[ "$CFG_PTMALLOC" != "no" ] && echo "Use ptmalloc ........... $CFG_PTMALLOC"
# complain about not being able to use dynamic plugins if we are using a static build
if [ "$CFG_SHARED" = "no" ]; then
diff --git a/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp b/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp
index 643d0dd2f5..5db6676036 100644
--- a/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp
+++ b/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp
@@ -60,3 +60,12 @@ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(slotSslErrors(QList<QSslError>)));
//! [1]
+
+//! [2]
+QNetworkConfigurationManager manager;
+networkAccessManager->setConfiguration(manager.defaultConfiguration());
+//! [2]
+
+//! [3]
+networkAccessManager->setConfiguration(QNetworkConfiguration());
+//! [3]
diff --git a/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp b/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp
new file mode 100644
index 0000000000..e2cc4dfc64
--- /dev/null
+++ b/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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 documentation 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$
+**
+****************************************************************************/
+
+//! [0]
+QNetworkConfigurationManager mgr;
+QList<QNetworkConfiguration> activeConfigs = mgr.allConfigurations(QNetworkConfiguration::Active)
+if (activeConfigs.count() > 0)
+ Q_ASSERT(mgr.isOnline())
+else
+ Q_ASSERT(!mgr.isOnline())
+//! [0]
diff --git a/examples/network/bearercloud/bearercloud.cpp b/examples/network/bearercloud/bearercloud.cpp
new file mode 100644
index 0000000000..27a296d10d
--- /dev/null
+++ b/examples/network/bearercloud/bearercloud.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 "bearercloud.h"
+#include "cloud.h"
+
+#include <QGraphicsTextItem>
+#include <QTimer>
+#include <QDateTime>
+#include <QHostInfo>
+
+#include <QDebug>
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+//! [0]
+BearerCloud::BearerCloud(QObject *parent)
+: QGraphicsScene(parent), timerId(0)
+{
+ setSceneRect(-300, -300, 600, 600);
+
+ qsrand(QDateTime::currentDateTime().toTime_t());
+
+ offset[QNetworkConfiguration::Active] = 2 * M_PI * qrand() / RAND_MAX;
+ offset[QNetworkConfiguration::Discovered] = offset[QNetworkConfiguration::Active] + M_PI / 6;
+ offset[QNetworkConfiguration::Defined] = offset[QNetworkConfiguration::Discovered] - M_PI / 6;
+ offset[QNetworkConfiguration::Undefined] = offset[QNetworkConfiguration::Undefined] + M_PI / 6;
+
+ thisDevice = new QGraphicsTextItem(QHostInfo::localHostName());
+ thisDevice->setData(0, QLatin1String("This Device"));
+ thisDevice->setPos(thisDevice->boundingRect().width() / -2,
+ thisDevice->boundingRect().height() / -2);
+ addItem(thisDevice);
+
+ qreal radius = Cloud::getRadiusForState(QNetworkConfiguration::Active);
+ QGraphicsEllipseItem *orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius);
+ orbit->setPen(QColor(Qt::green));
+ addItem(orbit);
+ radius = Cloud::getRadiusForState(QNetworkConfiguration::Discovered);
+ orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius);
+ orbit->setPen(QColor(Qt::blue));
+ addItem(orbit);
+ radius = Cloud::getRadiusForState(QNetworkConfiguration::Defined);
+ orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius);
+ orbit->setPen(QColor(Qt::darkGray));
+ addItem(orbit);
+ radius = Cloud::getRadiusForState(QNetworkConfiguration::Undefined);
+ orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius);
+ orbit->setPen(QColor(Qt::lightGray));
+ addItem(orbit);
+
+ connect(&manager, SIGNAL(configurationAdded(QNetworkConfiguration)),
+ this, SLOT(configurationAdded(QNetworkConfiguration)));
+ connect(&manager, SIGNAL(configurationRemoved(QNetworkConfiguration)),
+ this, SLOT(configurationRemoved(QNetworkConfiguration)));
+ connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SLOT(configurationChanged(QNetworkConfiguration)));
+
+ QTimer::singleShot(0, this, SLOT(updateConfigurations()));
+}
+//! [0]
+
+BearerCloud::~BearerCloud()
+{
+}
+
+void BearerCloud::cloudMoved()
+{
+ if (!timerId)
+ timerId = startTimer(1000 / 25);
+}
+
+void BearerCloud::timerEvent(QTimerEvent *)
+{
+ QList<Cloud *> clouds;
+ foreach (QGraphicsItem *item, items()) {
+ if (Cloud *cloud = qgraphicsitem_cast<Cloud *>(item))
+ clouds << cloud;
+ }
+
+ foreach (Cloud *cloud, clouds)
+ cloud->calculateForces();
+
+ bool cloudsMoved = false;
+ foreach (Cloud *cloud, clouds)
+ cloudsMoved |= cloud->advance();
+
+ if (!cloudsMoved) {
+ killTimer(timerId);
+ timerId = 0;
+ }
+}
+
+//! [2]
+void BearerCloud::configurationAdded(const QNetworkConfiguration &config)
+{
+ const QNetworkConfiguration::StateFlags state = config.state();
+
+ configStates.insert(state, config.identifier());
+
+ const qreal radius = Cloud::getRadiusForState(state);
+ const int count = configStates.count(state);
+ const qreal angle = 2 * M_PI / count;
+
+ Cloud *item = new Cloud(config);
+ configurations.insert(config.identifier(), item);
+
+ item->setPos(radius * cos((count-1) * angle + offset[state]),
+ radius * sin((count-1) * angle + offset[state]));
+
+ addItem(item);
+
+ cloudMoved();
+}
+//! [2]
+
+//! [3]
+void BearerCloud::configurationRemoved(const QNetworkConfiguration &config)
+{
+ foreach (const QNetworkConfiguration::StateFlags &state, configStates.uniqueKeys())
+ configStates.remove(state, config.identifier());
+
+ Cloud *item = configurations.take(config.identifier());
+
+ item->setFinalScale(0.0);
+ item->setDeleteAfterAnimation(true);
+
+ cloudMoved();
+}
+//! [3]
+
+//! [4]
+void BearerCloud::configurationChanged(const QNetworkConfiguration &config)
+{
+ foreach (const QNetworkConfiguration::StateFlags &state, configStates.uniqueKeys())
+ configStates.remove(state, config.identifier());
+
+ configStates.insert(config.state(), config.identifier());
+
+ cloudMoved();
+}
+//! [4]
+
+//! [1]
+void BearerCloud::updateConfigurations()
+{
+ QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations();
+
+ while (!allConfigurations.isEmpty())
+ configurationAdded(allConfigurations.takeFirst());
+
+ cloudMoved();
+}
+//! [1]
+
diff --git a/examples/network/bearercloud/bearercloud.h b/examples/network/bearercloud/bearercloud.h
new file mode 100644
index 0000000000..f09cb535f1
--- /dev/null
+++ b/examples/network/bearercloud/bearercloud.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 <qnetworkconfigmanager.h>
+
+#include <QGraphicsScene>
+#include <QMap>
+#include <QHash>
+
+QT_USE_NAMESPACE
+
+class Cloud;
+
+class BearerCloud : public QGraphicsScene
+{
+ Q_OBJECT
+
+public:
+ BearerCloud(QObject *parent = 0);
+ ~BearerCloud();
+
+ void cloudMoved();
+
+ void timerEvent(QTimerEvent *event);
+
+private Q_SLOTS:
+ void configurationAdded(const QNetworkConfiguration &config);
+ void configurationRemoved(const QNetworkConfiguration &config);
+ void configurationChanged(const QNetworkConfiguration &config);
+ void updateConfigurations();
+
+private:
+ QNetworkConfigurationManager manager;
+
+ QGraphicsTextItem *thisDevice;
+ QHash<QString, Cloud *> configurations;
+
+ QMap<QNetworkConfiguration::StateFlags, qreal> offset;
+ QMultiMap<QNetworkConfiguration::StateFlags, QString> configStates;
+
+ int timerId;
+};
+
diff --git a/examples/network/bearercloud/bearercloud.pro b/examples/network/bearercloud/bearercloud.pro
new file mode 100644
index 0000000000..c07626a341
--- /dev/null
+++ b/examples/network/bearercloud/bearercloud.pro
@@ -0,0 +1,16 @@
+HEADERS = bearercloud.h \
+ cloud.h
+
+SOURCES = main.cpp \
+ bearercloud.cpp \
+ cloud.cpp
+
+RESOURCES = icons.qrc
+
+TARGET = bearercloud
+
+QT = core gui network svg
+
+CONFIG += console
+
+symbian:TARGET.CAPABILITY = NetworkServices ReadUserData
diff --git a/examples/network/bearercloud/cloud.cpp b/examples/network/bearercloud/cloud.cpp
new file mode 100644
index 0000000000..81e13a6e66
--- /dev/null
+++ b/examples/network/bearercloud/cloud.cpp
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 "cloud.h"
+#include "bearercloud.h"
+
+#include <qnetworksession.h>
+
+#include <QGraphicsTextItem>
+#include <QGraphicsSvgItem>
+#include <QGraphicsSceneMouseEvent>
+#include <QSvgRenderer>
+#include <QPainter>
+
+#include <QDebug>
+
+#include <math.h>
+
+static QMap<QString, QSvgRenderer *> svgCache;
+
+//! [0]
+Cloud::Cloud(const QNetworkConfiguration &config, QGraphicsItem *parent)
+: QGraphicsItem(parent), configuration(config), deleteAfterAnimation(false)
+{
+ session = new QNetworkSession(configuration, this);
+ connect(session, SIGNAL(newConfigurationActivated()),
+ this, SLOT(newConfigurationActivated()));
+ connect(session, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SLOT(stateChanged(QNetworkSession::State)));
+
+ setFlag(ItemIsMovable);
+#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
+ setFlag(ItemSendsGeometryChanges);
+#endif
+ setZValue(1);
+
+ icon = new QGraphicsSvgItem(this);
+ text = new QGraphicsTextItem(this);
+
+ currentScale = 0;
+ finalScale = 1;
+ setTransform(QTransform::fromScale(currentScale, currentScale), false);
+ setOpacity(0);
+
+ newConfigurationActivated();
+}
+//! [0]
+
+Cloud::~Cloud()
+{
+}
+
+void Cloud::setFinalScale(qreal factor)
+{
+ finalScale = factor;
+}
+
+void Cloud::setDeleteAfterAnimation(bool deleteAfter)
+{
+ deleteAfterAnimation = deleteAfter;
+}
+
+void Cloud::calculateForces()
+{
+ if (!scene() || scene()->mouseGrabberItem() == this) {
+ newPos = pos();
+ return;
+ }
+
+ // sum up all the forces push this item away
+ qreal xvel = 0;
+ qreal yvel = 0;
+ QLineF orbitForce;
+ foreach (QGraphicsItem *item, scene()->items()) {
+ // other clouds
+ Cloud *cloud = qgraphicsitem_cast<Cloud *>(item);
+ if (!cloud && item->data(0) != QLatin1String("This Device"))
+ continue;
+
+ qreal factor = 1.0;
+
+ QLineF line(cloud ? item->mapToScene(0, 0) : QPointF(0, 0), mapToScene(0, 0));
+ if (item->data(0) == QLatin1String("This Device"))
+ orbitForce = line;
+
+ if (cloud)
+ factor = cloud->currentScale;
+
+ qreal dx = line.dx();
+ qreal dy = line.dy();
+ double l = 2.0 * (dx * dx + dy * dy);
+ if (l > 0) {
+ xvel += factor * dx * 200.0 / l;
+ yvel += factor * dy * 200.0 / l;
+ }
+ }
+
+ // tendency to stay at a fixed orbit
+ qreal orbit = getRadiusForState(configuration.state());
+ qreal distance = orbitForce.length();
+
+ QLineF unit = orbitForce.unitVector();
+
+ orbitForce.setLength(xvel * unit.dx() + yvel * unit.dy());
+
+ qreal w = 2 - exp(-pow(distance-orbit, 2)/(2 * 50));
+
+ if (distance < orbit) {
+ xvel += orbitForce.dx() * w;
+ yvel += orbitForce.dy() * w;
+ } else {
+ xvel -= orbitForce.dx() * w;
+ yvel -= orbitForce.dy() * w;
+ }
+
+ if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
+ xvel = yvel = 0;
+
+ QRectF sceneRect = scene()->sceneRect();
+ newPos = pos() + QPointF(xvel, yvel);
+ newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
+ newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
+}
+
+bool Cloud::advance()
+{
+ static const qreal scaleDelta = 0.01;
+
+ bool animated = false;
+
+ if (currentScale < finalScale) {
+ animated = true;
+ currentScale = qMin<qreal>(currentScale + scaleDelta, finalScale);
+ setTransform(QTransform::fromScale(currentScale, currentScale), false);
+ } else if (currentScale > finalScale) {
+ animated = true;
+ currentScale = qMax<qreal>(currentScale - scaleDelta, finalScale);
+ setTransform(QTransform::fromScale(currentScale, currentScale), false);
+ }
+
+ if (newPos != pos()) {
+ setPos(newPos);
+ animated = true;
+ }
+
+ if (opacity() != finalOpacity) {
+ animated = true;
+ if (qAbs(finalScale - currentScale) > 0.0) {
+ // use scale as reference
+ setOpacity(opacity() + scaleDelta * (finalOpacity - opacity()) /
+ qAbs(finalScale - currentScale));
+ } else {
+ setOpacity(finalOpacity);
+ }
+ }
+
+ if (!animated && deleteAfterAnimation)
+ deleteLater();
+
+ return animated;
+}
+
+QRectF Cloud::boundingRect() const
+{
+ return childrenBoundingRect();
+}
+
+void Cloud::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
+{
+}
+
+//! [4]
+QVariant Cloud::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ switch (change) {
+ case ItemPositionHasChanged:
+ if (BearerCloud *bearercloud = qobject_cast<BearerCloud *>(scene()))
+ bearercloud->cloudMoved();
+ default:
+ ;
+ };
+
+ return QGraphicsItem::itemChange(change, value);
+}
+//! [4]
+
+//! [3]
+void Cloud::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ if (session->isOpen())
+ session->close();
+ else
+ session->open();
+
+ event->accept();
+ }
+}
+//! [3]
+
+//! [2]
+void Cloud::stateChanged(QNetworkSession::State state)
+{
+ if (configuration.name().isEmpty())
+ finalOpacity = qreal(0.1);
+ else if (session->state() == QNetworkSession::NotAvailable)
+ finalOpacity = 0.5;
+ else
+ finalOpacity = 1.0;
+
+ QString tooltip;
+
+ if (configuration.name().isEmpty())
+ tooltip += tr("<b>HIDDEN NETWORK</b><br>");
+ else
+ tooltip += tr("<b>%1</b><br>").arg(configuration.name());
+
+ const QNetworkInterface interface = session->interface();
+ if (interface.isValid())
+ tooltip += tr("<br>Interface: %1").arg(interface.humanReadableName());
+ tooltip += tr("<br>Id: %1").arg(configuration.identifier());
+
+ const QString bearerName = configuration.bearerName();
+ if (!bearerName.isEmpty())
+ tooltip += tr("<br>Bearer: %1").arg(bearerName);
+
+ QString s = tr("<br>State: %1 (%2)");
+ switch (state) {
+ case QNetworkSession::Invalid:
+ s = s.arg(tr("Invalid"));
+ break;
+ case QNetworkSession::NotAvailable:
+ s = s.arg(tr("Not Available"));
+ break;
+ case QNetworkSession::Connecting:
+ s = s.arg(tr("Connecting"));
+ break;
+ case QNetworkSession::Connected:
+ s = s.arg(tr("Connected"));
+ break;
+ case QNetworkSession::Closing:
+ s = s.arg(tr("Closing"));
+ break;
+ case QNetworkSession::Disconnected:
+ s = s.arg(tr("Disconnected"));
+ break;
+ case QNetworkSession::Roaming:
+ s = s.arg(tr("Roaming"));
+ break;
+ default:
+ s = s.arg(tr("Unknown"));
+ }
+
+ if (session->isOpen())
+ s = s.arg(tr("Open"));
+ else
+ s = s.arg(tr("Closed"));
+
+ tooltip += s;
+
+ tooltip += tr("<br><br>Active time: %1 seconds").arg(session->activeTime());
+ tooltip += tr("<br>Received data: %1 bytes").arg(session->bytesReceived());
+ tooltip += tr("<br>Sent data: %1 bytes").arg(session->bytesWritten());
+
+ setToolTip(tooltip);
+}
+//! [2]
+
+//! [1]
+void Cloud::newConfigurationActivated()
+{
+ const QString bearerName = configuration.bearerName();
+ if (!svgCache.contains(bearerName)) {
+ if (bearerName == QLatin1String("WLAN"))
+ svgCache.insert(bearerName, new QSvgRenderer(QLatin1String(":wlan.svg")));
+ else if (bearerName == QLatin1String("Ethernet"))
+ svgCache.insert(bearerName, new QSvgRenderer(QLatin1String(":lan.svg")));
+ else
+ svgCache.insert(bearerName, new QSvgRenderer(QLatin1String(":unknown.svg")));
+ }
+
+ icon->setSharedRenderer(svgCache[bearerName]);
+
+ if (configuration.name().isEmpty()) {
+ text->setPlainText(tr("HIDDEN NETWORK"));
+ } else {
+ if (configuration.type() == QNetworkConfiguration::ServiceNetwork)
+ text->setHtml("<b>" + configuration.name() + "</b>");
+ else
+ text->setPlainText(configuration.name());
+ }
+
+ const qreal height = icon->boundingRect().height() + text->boundingRect().height();
+
+ icon->setPos(icon->boundingRect().width() / -2, height / -2);
+
+ text->setPos(text->boundingRect().width() / -2,
+ height / 2 - text->boundingRect().height());
+
+ stateChanged(session->state());
+}
+//! [1]
+
+qreal Cloud::getRadiusForState(QNetworkConfiguration::StateFlags state)
+{
+ switch (state) {
+ case QNetworkConfiguration::Active:
+ return 100;
+ break;
+ case QNetworkConfiguration::Discovered:
+ return 150;
+ break;
+ case QNetworkConfiguration::Defined:
+ return 200;
+ break;
+ case QNetworkConfiguration::Undefined:
+ return 250;
+ break;
+ default:
+ return 300;
+ }
+}
+
diff --git a/examples/network/bearercloud/cloud.h b/examples/network/bearercloud/cloud.h
new file mode 100644
index 0000000000..38f8aff6f4
--- /dev/null
+++ b/examples/network/bearercloud/cloud.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 <qnetworkconfiguration.h>
+#include <qnetworksession.h>
+
+#include <QGraphicsItem>
+QT_USE_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+class QGraphicsTextItem;
+class QGraphicsSvgItem;
+QT_END_NAMESPACE
+
+class Cloud : public QObject, public QGraphicsItem
+{
+ Q_OBJECT
+ Q_INTERFACES(QGraphicsItem)
+
+public:
+ Cloud(const QNetworkConfiguration &config, QGraphicsItem *parent = 0);
+ ~Cloud();
+
+ enum { Type = UserType + 1 };
+ int type() const { return Type; }
+
+ void setFinalScale(qreal factor);
+ void setDeleteAfterAnimation(bool deleteAfter);
+
+ void calculateForces();
+
+ bool advance();
+ QRectF boundingRect() const;
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+ static qreal getRadiusForState(QNetworkConfiguration::StateFlags state);
+
+protected:
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+
+private Q_SLOTS:
+ void stateChanged(QNetworkSession::State state);
+ void newConfigurationActivated();
+
+private:
+ QNetworkConfiguration configuration;
+ QNetworkSession *session;
+
+ QGraphicsTextItem *text;
+ QGraphicsSvgItem *icon;
+
+ qreal finalOpacity;
+ qreal finalScale;
+ qreal currentScale;
+
+ QPointF newPos;
+
+ bool deleteAfterAnimation;
+};
+
diff --git a/examples/network/bearercloud/icons.qrc b/examples/network/bearercloud/icons.qrc
new file mode 100644
index 0000000000..84a8939db3
--- /dev/null
+++ b/examples/network/bearercloud/icons.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>wlan.svg</file>
+ <file>lan.svg</file>
+ <file>unknown.svg</file>
+</qresource>
+</RCC>
diff --git a/examples/network/bearercloud/lan.svg b/examples/network/bearercloud/lan.svg
new file mode 100644
index 0000000000..3cce805197
--- /dev/null
+++ b/examples/network/bearercloud/lan.svg
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="25.000002"
+ height="9.6406126"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="lan.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="19.416667"
+ inkscape:cx="15.244635"
+ inkscape:cy="11.639485"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1459"
+ inkscape:window-height="964"
+ inkscape:window-x="453"
+ inkscape:window-y="166" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-4.0978193e-8,-19.359387)">
+ <text
+ xml:space="preserve"
+ style="font-size:13.99289513px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="-1.1205248"
+ y="29"
+ id="text3239"><tspan
+ sodipodi:role="line"
+ id="tspan3241"
+ x="-1.1205248"
+ y="29">LAN</tspan></text>
+ </g>
+</svg>
diff --git a/examples/network/bearercloud/main.cpp b/examples/network/bearercloud/main.cpp
new file mode 100644
index 0000000000..86ef46ffc0
--- /dev/null
+++ b/examples/network/bearercloud/main.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 "bearercloud.h"
+
+#include <QApplication>
+#include <QGraphicsView>
+
+class CloudView : public QGraphicsView
+{
+ Q_OBJECT
+
+public:
+ CloudView(QGraphicsScene *scene);
+ ~CloudView() { }
+
+protected:
+ void resizeEvent(QResizeEvent *) {
+ fitInView(sceneRect(), Qt::KeepAspectRatio);
+ }
+#ifdef Q_OS_WINCE
+ void hideEvent(QHideEvent *) {
+ qApp->quit();
+ }
+#endif
+};
+
+CloudView::CloudView(QGraphicsScene *scene)
+: QGraphicsView(scene)
+{
+ setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing |
+ QPainter::SmoothPixmapTransform);
+#if defined (Q_OS_SYMBIAN) || defined (Q_OS_WINCE)
+ setWindowState(Qt::WindowMaximized);
+#endif
+}
+
+#include "main.moc"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ BearerCloud bearerCloud;
+
+ CloudView view(&bearerCloud);
+ view.show();
+
+ return app.exec();
+}
+
diff --git a/examples/network/bearercloud/unknown.svg b/examples/network/bearercloud/unknown.svg
new file mode 100644
index 0000000000..fd10298326
--- /dev/null
+++ b/examples/network/bearercloud/unknown.svg
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="25"
+ height="9.0681238"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="unknown.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="19.416667"
+ inkscape:cx="15.244635"
+ inkscape:cy="11.639485"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1459"
+ inkscape:window-height="964"
+ inkscape:window-x="453"
+ inkscape:window-y="166" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-6.891787e-8,-19.931876)">
+ <text
+ xml:space="preserve"
+ style="font-size:13.16195393px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="-1.0539845"
+ y="29"
+ id="text3239"><tspan
+ sodipodi:role="line"
+ id="tspan3241"
+ x="-1.0539845"
+ y="29">NET</tspan></text>
+ </g>
+</svg>
diff --git a/examples/network/bearercloud/wlan.svg b/examples/network/bearercloud/wlan.svg
new file mode 100644
index 0000000000..8b86089c6a
--- /dev/null
+++ b/examples/network/bearercloud/wlan.svg
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="27"
+ height="29"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="wlan.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="19.416667"
+ inkscape:cx="23.665236"
+ inkscape:cy="11.639485"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1912"
+ inkscape:window-height="1130"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g6334"
+ transform="translate(1.0000001,0)">
+ <path
+ id="path2393"
+ d="M 12.500248,9.499893 L 12.500248,28.500095"
+ style="fill:none;fill-rule:evenodd;stroke:#3bb3ff;stroke-width:0.99981093;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.1887902"
+ sodipodi:start="2.0943951"
+ transform="matrix(1.0216765,0,0,1.0324764,0.4493163,-22.692096)"
+ d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513"
+ sodipodi:ry="3.9141631"
+ sodipodi:rx="3.9141631"
+ sodipodi:cy="30.695278"
+ sodipodi:cx="10.815451"
+ id="path3171"
+ style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.97365081;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.1887902"
+ sodipodi:start="2.0943951"
+ transform="matrix(1.6055152,0,0,1.6224868,-7.5798083,-40.80263)"
+ d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513"
+ sodipodi:ry="3.9141631"
+ sodipodi:rx="3.9141631"
+ sodipodi:cy="30.695278"
+ sodipodi:cx="10.815451"
+ id="path3175"
+ style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.61958688;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.1887902"
+ sodipodi:start="2.0943951"
+ transform="matrix(2.4812855,0,0,2.5075146,-17.62358,-67.968804)"
+ d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513"
+ sodipodi:ry="3.9141631"
+ sodipodi:rx="3.9141631"
+ sodipodi:cy="30.695278"
+ sodipodi:cx="10.815451"
+ id="path3177"
+ style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.40090355;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.1887902"
+ sodipodi:start="2.0943951"
+ transform="matrix(-1.0216765,0,0,1.0324764,24.550388,-22.692096)"
+ d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513"
+ sodipodi:ry="3.9141631"
+ sodipodi:rx="3.9141631"
+ sodipodi:cy="30.695278"
+ sodipodi:cx="10.815451"
+ id="path3179"
+ style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.97365081;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.1887902"
+ sodipodi:start="2.0943951"
+ transform="matrix(-1.6055152,0,0,1.6224868,32.580246,-40.80263)"
+ d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513"
+ sodipodi:ry="3.9141631"
+ sodipodi:rx="3.9141631"
+ sodipodi:cy="30.695278"
+ sodipodi:cx="10.815451"
+ id="path3181"
+ style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.61958688;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.1887902"
+ sodipodi:start="2.0943951"
+ transform="matrix(-2.4812855,0,0,2.5075146,42.623143,-67.968804)"
+ d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513"
+ sodipodi:ry="3.9141631"
+ sodipodi:rx="3.9141631"
+ sodipodi:cy="30.695278"
+ sodipodi:cx="10.815451"
+ id="path3183"
+ style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.40090355;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+</svg>
diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp
new file mode 100644
index 0000000000..5b2bad12e7
--- /dev/null
+++ b/examples/network/bearermonitor/bearermonitor.cpp
@@ -0,0 +1,395 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 "bearermonitor.h"
+#include "sessionwidget.h"
+
+#include <QDebug>
+
+#ifdef Q_OS_WIN
+#include <winsock2.h>
+#undef interface
+
+#ifndef NS_NLA
+#define NS_NLA 15
+#endif
+#endif
+
+BearerMonitor::BearerMonitor(QWidget *parent)
+: QWidget(parent)
+{
+ setupUi(this);
+ delete tabWidget->currentWidget();
+ sessionGroup->hide();
+#if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE)
+ setWindowState(Qt::WindowMaximized);
+#endif
+ updateConfigurations();
+
+ onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty());
+
+ QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
+ for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem *item = treeWidget->topLevelItem(i);
+
+ if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) {
+ treeWidget->setCurrentItem(item);
+ showConfigurationFor(item);
+ break;
+ }
+ }
+
+ connect(&manager, SIGNAL(configurationAdded(const QNetworkConfiguration&)),
+ this, SLOT(configurationAdded(const QNetworkConfiguration&)));
+ connect(&manager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)),
+ this, SLOT(configurationRemoved(const QNetworkConfiguration&)));
+ connect(&manager, SIGNAL(configurationChanged(const QNetworkConfiguration&)),
+ this, SLOT(configurationChanged(const QNetworkConfiguration)));
+ connect(&manager, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations()));
+ connect(&manager, SIGNAL(onlineStateChanged(bool)), this ,SLOT(onlineStateChanged(bool)));
+
+#ifdef Q_OS_WIN
+ connect(registerButton, SIGNAL(clicked()), this, SLOT(registerNetwork()));
+ connect(unregisterButton, SIGNAL(clicked()), this, SLOT(unregisterNetwork()));
+#else
+ nlaGroup->hide();
+#endif
+
+ connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
+ this, SLOT(createSessionFor(QTreeWidgetItem*)));
+
+ connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(showConfigurationFor(QTreeWidgetItem*)));
+
+ connect(newSessionButton, SIGNAL(clicked()),
+ this, SLOT(createNewSession()));
+ connect(deleteSessionButton, SIGNAL(clicked()),
+ this, SLOT(deleteSession()));
+
+ connect(scanButton, SIGNAL(clicked()),
+ this, SLOT(performScan()));
+}
+
+BearerMonitor::~BearerMonitor()
+{
+}
+
+static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config)
+{
+ item->setText(0, config.name());
+ item->setData(0, Qt::UserRole, config.identifier());
+
+ QFont font = item->font(1);
+ font.setBold((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active);
+ item->setFont(0, font);
+}
+
+void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem;
+ updateItem(item, config);
+
+ if (parent)
+ parent->addChild(item);
+ else
+ treeWidget->addTopLevelItem(item);
+
+ if (config.type() == QNetworkConfiguration::ServiceNetwork) {
+ foreach (const QNetworkConfiguration &child, config.children())
+ configurationAdded(child, item);
+ }
+}
+
+void BearerMonitor::configurationRemoved(const QNetworkConfiguration &config)
+{
+ for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem *item = treeWidget->topLevelItem(i);
+
+ if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
+ delete item;
+ break;
+ }
+ }
+}
+
+void BearerMonitor::configurationChanged(const QNetworkConfiguration &config)
+{
+ for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem *item = treeWidget->topLevelItem(i);
+
+ if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
+ updateItem(item, config);
+
+ if (config.type() == QNetworkConfiguration::ServiceNetwork)
+ updateSnapConfiguration(item, config);
+
+ if (item == treeWidget->currentItem())
+ showConfigurationFor(item);
+
+ break;
+ }
+ }
+}
+
+void BearerMonitor::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap)
+{
+ QMap<QString, QTreeWidgetItem *> itemMap;
+ for (int i = 0; i < parent->childCount(); ++i) {
+ QTreeWidgetItem *item = parent->child(i);
+ itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
+ }
+
+ QList<QNetworkConfiguration> allConfigurations = snap.children();
+
+ while (!allConfigurations.isEmpty()) {
+ QNetworkConfiguration config = allConfigurations.takeFirst();
+
+ QTreeWidgetItem *item = itemMap.take(config.identifier());
+ if (item) {
+ updateItem(item, config);
+
+ if (config.type() == QNetworkConfiguration::ServiceNetwork)
+ updateSnapConfiguration(item, config);
+ } else {
+ configurationAdded(config, parent);
+ }
+ }
+
+ foreach (const QString &id, itemMap.keys())
+ delete itemMap.value(id);
+
+ itemMap.clear();
+}
+
+void BearerMonitor::updateConfigurations()
+{
+ progressBar->hide();
+ scanButton->show();
+
+ QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard);
+ QMap<QString, QTreeWidgetItem *> itemMap;
+ while (!items.isEmpty()) {
+ QTreeWidgetItem *item = items.takeFirst();
+ itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
+ }
+
+ QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations();
+
+ while (!allConfigurations.isEmpty()) {
+ QNetworkConfiguration config = allConfigurations.takeFirst();
+
+ QTreeWidgetItem *item = itemMap.take(config.identifier());
+ if (item) {
+ updateItem(item, config);
+
+ if (config.type() == QNetworkConfiguration::ServiceNetwork)
+ updateSnapConfiguration(item, config);
+ } else {
+ configurationAdded(config);
+ }
+ }
+
+ foreach (const QString &id, itemMap.keys())
+ delete itemMap.value(id);
+}
+
+void BearerMonitor::onlineStateChanged(bool isOnline)
+{
+ if (isOnline)
+ onlineState->setText(tr("Online"));
+ else
+ onlineState->setText(tr("Offline"));
+}
+
+#ifdef Q_OS_WIN
+void BearerMonitor::registerNetwork()
+{
+ QTreeWidgetItem *item = treeWidget->currentItem();
+
+ QNetworkConfiguration configuration =
+ manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
+
+ const QString name = configuration.name();
+
+ qDebug() << "Registering" << name << "with system";
+
+ WSAQUERYSET networkInfo;
+ memset(&networkInfo, 0, sizeof(networkInfo));
+ networkInfo.dwSize = sizeof(networkInfo);
+ networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
+ networkInfo.dwNameSpace = NS_NLA;
+
+ if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
+ qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError();
+}
+
+void BearerMonitor::unregisterNetwork()
+{
+ QTreeWidgetItem *item = treeWidget->currentItem();
+
+ QNetworkConfiguration configuration =
+ manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
+
+ const QString name = configuration.name();
+
+ qDebug() << "Unregistering" << name << "with system";
+
+ WSAQUERYSET networkInfo;
+ memset(&networkInfo, 0, sizeof(networkInfo));
+ networkInfo.dwSize = sizeof(networkInfo);
+ networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
+ networkInfo.dwNameSpace = NS_NLA;
+
+ if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
+ qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError();
+}
+#endif
+
+void BearerMonitor::showConfigurationFor(QTreeWidgetItem *item)
+{
+ QString identifier;
+
+ if (item)
+ identifier = item->data(0, Qt::UserRole).toString();
+
+ QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);
+
+ switch (conf.state()) {
+ case QNetworkConfiguration::Active:
+ configurationState->setText(tr("Active"));
+ break;
+ case QNetworkConfiguration::Discovered:
+ configurationState->setText(tr("Discovered"));
+ break;
+ case QNetworkConfiguration::Defined:
+ configurationState->setText(tr("Defined"));
+ break;
+ case QNetworkConfiguration::Undefined:
+ configurationState->setText(tr("Undefined"));
+ break;
+ default:
+ configurationState->setText(QString());
+ }
+
+ switch (conf.type()) {
+ case QNetworkConfiguration::InternetAccessPoint:
+ configurationType->setText(tr("Internet Access Point"));
+ break;
+ case QNetworkConfiguration::ServiceNetwork:
+ configurationType->setText(tr("Service Network"));
+ break;
+ case QNetworkConfiguration::UserChoice:
+ configurationType->setText(tr("User Choice"));
+ break;
+ case QNetworkConfiguration::Invalid:
+ configurationType->setText(tr("Invalid"));
+ break;
+ default:
+ configurationType->setText(QString());
+ }
+
+ switch (conf.purpose()) {
+ case QNetworkConfiguration::UnknownPurpose:
+ configurationPurpose->setText(tr("Unknown"));
+ break;
+ case QNetworkConfiguration::PublicPurpose:
+ configurationPurpose->setText(tr("Public"));
+ break;
+ case QNetworkConfiguration::PrivatePurpose:
+ configurationPurpose->setText(tr("Private"));
+ break;
+ case QNetworkConfiguration::ServiceSpecificPurpose:
+ configurationPurpose->setText(tr("Service Specific"));
+ break;
+ default:
+ configurationPurpose->setText(QString());
+ }
+
+ configurationIdentifier->setText(conf.identifier());
+
+ configurationRoaming->setText(conf.isRoamingAvailable() ? tr("Available") : tr("Not available"));
+
+ configurationChildren->setText(QString::number(conf.children().count()));
+
+ configurationName->setText(conf.name());
+}
+
+void BearerMonitor::createSessionFor(QTreeWidgetItem *item)
+{
+ const QString identifier = item->data(0, Qt::UserRole).toString();
+
+ QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);
+
+ SessionWidget *session = new SessionWidget(conf);
+
+ tabWidget->addTab(session, conf.name());
+
+ sessionGroup->show();
+
+ sessionWidgets.append(session);
+}
+
+void BearerMonitor::createNewSession()
+{
+ QTreeWidgetItem *item = treeWidget->currentItem();
+
+ createSessionFor(item);
+}
+
+void BearerMonitor::deleteSession()
+{
+ SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget());
+ if (session) {
+ sessionWidgets.removeAll(session);
+
+ delete session;
+
+ if (tabWidget->count() == 0)
+ sessionGroup->hide();
+ }
+}
+
+void BearerMonitor::performScan()
+{
+ scanButton->hide();
+ progressBar->show();
+ manager.updateConfigurations();
+}
diff --git a/examples/network/bearermonitor/bearermonitor.h b/examples/network/bearermonitor/bearermonitor.h
new file mode 100644
index 0000000000..d7025dd327
--- /dev/null
+++ b/examples/network/bearermonitor/bearermonitor.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 BEARERMONITOR_H
+#define BEARERMONITOR_H
+
+#include <qnetworkconfigmanager.h>
+#include <qnetworksession.h>
+#if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE)
+#include "ui_bearermonitor_240_320.h"
+#else
+#include "ui_bearermonitor_640_480.h"
+#endif
+
+QT_USE_NAMESPACE
+
+class SessionWidget;
+
+class BearerMonitor : public QWidget, public Ui_BearerMonitor
+{
+ Q_OBJECT
+
+public:
+ BearerMonitor(QWidget *parent = 0);
+ ~BearerMonitor();
+
+private slots:
+ void configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent = 0);
+ void configurationRemoved(const QNetworkConfiguration &config);
+ void configurationChanged(const QNetworkConfiguration &config);
+ void updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap);
+ void updateConfigurations();
+
+ void onlineStateChanged(bool isOnline);
+
+#ifdef Q_OS_WIN
+ void registerNetwork();
+ void unregisterNetwork();
+#endif
+
+ void showConfigurationFor(QTreeWidgetItem *item);
+
+ void createSessionFor(QTreeWidgetItem *item);
+ void createNewSession();
+ void deleteSession();
+
+ void performScan();
+
+private:
+ QNetworkConfigurationManager manager;
+ QList<SessionWidget *> sessionWidgets;
+};
+
+#endif //BEARERMONITOR_H
diff --git a/examples/network/bearermonitor/bearermonitor.pro b/examples/network/bearermonitor/bearermonitor.pro
new file mode 100644
index 0000000000..4b86187442
--- /dev/null
+++ b/examples/network/bearermonitor/bearermonitor.pro
@@ -0,0 +1,26 @@
+HEADERS = sessionwidget.h \
+ bearermonitor.h
+
+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
+ }
+}
+
+CONFIG += console
+
+symbian:TARGET.CAPABILITY = NetworkServices ReadUserData
diff --git a/examples/network/bearermonitor/bearermonitor_240_320.ui b/examples/network/bearermonitor/bearermonitor_240_320.ui
new file mode 100644
index 0000000000..ce9c2d1d12
--- /dev/null
+++ b/examples/network/bearermonitor/bearermonitor_240_320.ui
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BearerMonitor</class>
+ <widget class="QWidget" name="BearerMonitor">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>240</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>-274</y>
+ <width>206</width>
+ <height>576</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="systemState">
+ <property name="title">
+ <string>System State</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="onlineStateLayout">
+ <item>
+ <widget class="QLabel" name="onlineStateLabel">
+ <property name="text">
+ <string>Online State:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="onlineState">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Configurations</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="configurationNameLayout">
+ <item>
+ <widget class="QLabel" name="configurationNameLabel">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationName">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationStateLayout">
+ <item>
+ <widget class="QLabel" name="configurationStateLabel">
+ <property name="text">
+ <string>State:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationState">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationTypeLayout">
+ <item>
+ <widget class="QLabel" name="configurationTypeLabel">
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationType">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Invalid</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationPurposeLayout">
+ <item>
+ <widget class="QLabel" name="configurationPurposeLabel">
+ <property name="text">
+ <string>Purpose:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationPurpose">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Unknown</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationIdentifierLayout">
+ <item>
+ <widget class="QLabel" name="configurationIdentifierLabel">
+ <property name="text">
+ <string>Identifier:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationIdentifier">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationRoamingLayout">
+ <item>
+ <widget class="QLabel" name="configurationRoamingLabel">
+ <property name="text">
+ <string>Roaming:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationRoaming">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationChildrenLayout">
+ <item>
+ <widget class="QLabel" name="configurationChildrenLabel">
+ <property name="text">
+ <string>Children:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationChildren">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="nlaGroup">
+ <property name="title">
+ <string>Network Location Awareness</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="registerButton">
+ <property name="text">
+ <string>Register</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="unregisterButton">
+ <property name="text">
+ <string>Unregister</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newSessionButton">
+ <property name="text">
+ <string>New Session</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteSessionButton">
+ <property name="text">
+ <string>Delete Session</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="scanButton">
+ <property name="text">
+ <string>Scan</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ <property name="invertedAppearance">
+ <bool>false</bool>
+ </property>
+ <property name="format">
+ <string>%p%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="sessionGroup">
+ <property name="title">
+ <string>Sessions</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Session 1</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/network/bearermonitor/bearermonitor_640_480.ui b/examples/network/bearermonitor/bearermonitor_640_480.ui
new file mode 100644
index 0000000000..941eaa0282
--- /dev/null
+++ b/examples/network/bearermonitor/bearermonitor_640_480.ui
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BearerMonitor</class>
+ <widget class="QWidget" name="BearerMonitor">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>640</width>
+ <height>515</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="systemState">
+ <property name="title">
+ <string>System State</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="onlineStateLayout">
+ <item>
+ <widget class="QLabel" name="onlineStateLabel">
+ <property name="text">
+ <string>Online State:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="onlineState">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Configurations</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="configurationNameLayout">
+ <item>
+ <widget class="QLabel" name="configurationNameLabel">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationName">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationStateLayout">
+ <item>
+ <widget class="QLabel" name="configurationStateLabel">
+ <property name="text">
+ <string>State:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationState">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationTypeLayout">
+ <item>
+ <widget class="QLabel" name="configurationTypeLabel">
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationType">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Invalid</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationPurposeLayout">
+ <item>
+ <widget class="QLabel" name="configurationPurposeLabel">
+ <property name="text">
+ <string>Purpose:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationPurpose">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Unknown</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationIdentifierLayout">
+ <item>
+ <widget class="QLabel" name="configurationIdentifierLabel">
+ <property name="text">
+ <string>Identifier:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationIdentifier">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationRoamingLayout">
+ <item>
+ <widget class="QLabel" name="configurationRoamingLabel">
+ <property name="text">
+ <string>Roaming:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationRoaming">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationChildrenLayout">
+ <item>
+ <widget class="QLabel" name="configurationChildrenLabel">
+ <property name="text">
+ <string>Children:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configurationChildren">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="nlaGroup">
+ <property name="title">
+ <string>Network Location Awareness</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="registerButton">
+ <property name="text">
+ <string>Register</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="unregisterButton">
+ <property name="text">
+ <string>Unregister</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newSessionButton">
+ <property name="text">
+ <string>New Session</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteSessionButton">
+ <property name="text">
+ <string>Delete Session</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="scanButton">
+ <property name="text">
+ <string>Scan</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ <property name="invertedAppearance">
+ <bool>false</bool>
+ </property>
+ <property name="format">
+ <string>%p%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QGroupBox" name="sessionGroup">
+ <property name="title">
+ <string>Sessions</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Session 1</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/network/bearermonitor/main.cpp b/examples/network/bearermonitor/main.cpp
new file mode 100644
index 0000000000..b7ac4feb96
--- /dev/null
+++ b/examples/network/bearermonitor/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 <QApplication>
+
+#include "bearermonitor.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ BearerMonitor monitor;
+ monitor.show();
+
+ return app.exec();
+}
+
diff --git a/examples/network/bearermonitor/sessionwidget.cpp b/examples/network/bearermonitor/sessionwidget.cpp
new file mode 100644
index 0000000000..46ffb20d31
--- /dev/null
+++ b/examples/network/bearermonitor/sessionwidget.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** 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 examples 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 "sessionwidget.h"
+#include "qnetworkconfigmanager.h"
+
+SessionWidget::SessionWidget(const QNetworkConfiguration &config, QWidget *parent)
+: QWidget(parent), statsTimer(-1)
+{
+ setupUi(this);
+
+ session = new QNetworkSession(config, this);
+
+ connect(session, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SLOT(updateSession()));
+ connect(session, SIGNAL(error(QNetworkSession::SessionError)),
+ this, SLOT(updateSession()));
+
+ updateSession();
+
+ sessionId->setText(QString("0x%1").arg(qulonglong(session), 8, 16, QChar('0')));
+
+ configuration->setText(session->configuration().name());
+
+ connect(openSessionButton, SIGNAL(clicked()),
+ this, SLOT(openSession()));
+ connect(openSyncSessionButton, SIGNAL(clicked()),
+ this, SLOT(openSyncSession()));
+ connect(closeSessionButton, SIGNAL(clicked()),
+ this, SLOT(closeSession()));
+ connect(stopSessionButton, SIGNAL(clicked()),
+ this, SLOT(stopSession()));
+}
+
+SessionWidget::~SessionWidget()
+{
+ delete session;
+}
+
+void SessionWidget::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == statsTimer) {
+ rxData->setText(QString::number(session->bytesReceived()));
+ txData->setText(QString::number(session->bytesWritten()));
+ activeTime->setText(QString::number(session->activeTime()));
+ }
+}
+
+void SessionWidget::updateSession()
+{
+ updateSessionState(session->state());
+ updateSessionError(session->error());
+
+ if (session->state() == QNetworkSession::Connected)
+ statsTimer = startTimer(1000);
+ else
+ killTimer(statsTimer);
+
+ if (session->configuration().type() == QNetworkConfiguration::InternetAccessPoint)
+ bearer->setText(session->configuration().bearerName());
+ else {
+ QNetworkConfigurationManager mgr;
+ QNetworkConfiguration c = mgr.configurationFromIdentifier(session->sessionProperty("ActiveConfiguration").toString());
+ bearer->setText(c.bearerName());
+ }
+
+ interfaceName->setText(session->interface().humanReadableName());
+ interfaceGuid->setText(session->interface().name());
+}
+
+void SessionWidget::openSession()
+{
+ session->open();
+ updateSession();
+}
+
+void SessionWidget::openSyncSession()
+{
+ session->open();
+ session->waitForOpened();
+ updateSession();
+}
+
+void SessionWidget::closeSession()
+{
+ session->close();
+ updateSession();
+}
+
+void SessionWidget::stopSession()
+{
+ session->stop();
+ updateSession();
+}
+
+void SessionWidget::updateSessionState(QNetworkSession::State state)
+{
+ QString s = tr("%1 (%2)");
+
+ switch (state) {
+ case QNetworkSession::Invalid:
+ s = s.arg(tr("Invalid"));
+ break;
+ case QNetworkSession::NotAvailable:
+ s = s.arg(tr("Not Available"));
+ break;
+ case QNetworkSession::Connecting:
+ s = s.arg(tr("Connecting"));
+ break;
+ case QNetworkSession::Connected:
+ s = s.arg(tr("Connected"));
+ break;
+ case QNetworkSession::Closing:
+ s = s.arg(tr("Closing"));
+ break;
+ case QNetworkSession::Disconnected:
+ s = s.arg(tr("Disconnected"));
+ break;
+ case QNetworkSession::Roaming:
+ s = s.arg(tr("Roaming"));
+ break;
+ default:
+ s = s.arg(tr("Unknown"));
+ }
+
+ if (session->isOpen())
+ s = s.arg(tr("Open"));
+ else
+ s = s.arg(tr("Closed"));
+
+ sessionState->setText(s);
+}
+
+void SessionWidget::updateSessionError(QNetworkSession::SessionError error)
+{
+ lastError->setText(QString::number(error));
+ errorString->setText(session->errorString());
+}
+
diff --git a/examples/network/bearermonitor/sessionwidget.h b/examples/network/bearermonitor/sessionwidget.h
new file mode 100644
index 0000000000..cc9c067335
--- /dev/null
+++ b/examples/network/bearermonitor/sessionwidget.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 examples 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 SESSIONWIDGET_H
+#define SESSIONWIDGET_H
+
+#include "ui_sessionwidget.h"
+
+#include <qnetworksession.h>
+
+QT_USE_NAMESPACE
+
+class SessionWidget : public QWidget, public Ui_SessionWidget
+{
+ Q_OBJECT
+
+public:
+ SessionWidget(const QNetworkConfiguration &config, QWidget *parent = 0);
+ ~SessionWidget();
+
+ void timerEvent(QTimerEvent *);
+
+private:
+ void updateSessionState(QNetworkSession::State state);
+ void updateSessionError(QNetworkSession::SessionError error);
+
+private Q_SLOTS:
+ void openSession();
+ void openSyncSession();
+ void closeSession();
+ void stopSession();
+ void updateSession();
+
+private:
+ QNetworkSession *session;
+ int statsTimer;
+};
+
+#endif
+
diff --git a/examples/network/bearermonitor/sessionwidget.ui b/examples/network/bearermonitor/sessionwidget.ui
new file mode 100644
index 0000000000..45135f543a
--- /dev/null
+++ b/examples/network/bearermonitor/sessionwidget.ui
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SessionWidget</class>
+ <widget class="QWidget" name="SessionWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>276</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="sessionIdLayout">
+ <item>
+ <widget class="QLabel" name="sessionIdLabel">
+ <property name="text">
+ <string>Session ID:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="sessionId">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="sessionStateLayout">
+ <item>
+ <widget class="QLabel" name="sessionStateLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Session State:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="sessionState">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Invalid</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="configurationLayout">
+ <item>
+ <widget class="QLabel" name="configurationLabel">
+ <property name="text">
+ <string>Configuration:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="configuration">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="bearerLayout">
+ <item>
+ <widget class="QLabel" name="bearerLabel">
+ <property name="text">
+ <string>Bearer:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="bearer">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="interfaceNameLayout">
+ <item>
+ <widget class="QLabel" name="interfaceNameLabel">
+ <property name="text">
+ <string>Interface Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="interfaceName">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="interfaceGuidLayout">
+ <item>
+ <widget class="QLabel" name="interfaceGuidLabel">
+ <property name="text">
+ <string>Interface GUID:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="interfaceGuid">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="lastErrorLayout">
+ <item>
+ <widget class="QLabel" name="lastErrorLabel">
+ <property name="text">
+ <string>Last Error:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lastError">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="errorStringLayout">
+ <item>
+ <widget class="QLabel" name="errorStringLabel">
+ <property name="text">
+ <string>Error String</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="errorString">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="rxData">
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="txData">
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Active Time:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="activeTime">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>0 seconds</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="openSessionButton">
+ <property name="text">
+ <string>Open</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="openSyncSessionButton">
+ <property name="text">
+ <string>Blocking Open</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="closeSessionButton">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stopSessionButton">
+ <property name="text">
+ <string>Stop</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/network/network.pro b/examples/network/network.pro
index c5a97fb62b..bd632b8b3c 100644
--- a/examples/network/network.pro
+++ b/examples/network/network.pro
@@ -11,7 +11,9 @@ SUBDIRS = blockingfortuneclient \
loopback \
threadedfortuneserver \
googlesuggest \
- torrent
+ torrent \
+ bearercloud \
+ bearermonitor
# no QProcess
!vxworks:!qnx:SUBDIRS += network-chat
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 5e3190d196..c101626817 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -10,7 +10,9 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \
mingw_make.o option.o winmakefile.o projectgenerator.o \
meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
borland_bmake.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \
- symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o
+ symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \
+ registry.o \
+ epocroot.o
#qt code
QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
@@ -32,6 +34,8 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
generators/makefiledeps.cpp option.cpp generators/win32/mingw_make.cpp generators/makefile.cpp \
generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \
generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \
+ $(SOURCE_PATH)/tools/shared/windows/registry.cpp \
+ $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp \
generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
$(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \
@@ -62,6 +66,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
CPPFLAGS = -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac -Igenerators/symbian \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \
-I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \
+ -I$(SOURCE_PATH)/tools/shared \
-DQT_NO_PCRE \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \
@@ -278,6 +283,12 @@ symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp
initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp
$(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp
+registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+
+epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+
projectgenerator.o: generators/projectgenerator.cpp
$(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp
@@ -286,6 +297,7 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
+
#default rules
.cpp.o:
$(CXX) -c -o $@ $(CXXFLAGS) $<
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 1f3092ae40..a598350073 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -34,6 +34,7 @@ CFLAGS = -c -Fo$@ \
-I$(BUILD_PATH)\src\corelib\global \
-I$(BUILD_PATH)\src\corelib\xml \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
+ -I$(SOURCE_PATH)\tools\shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \
-DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \
-DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED \
@@ -59,6 +60,7 @@ CFLAGS = -c -o$@ \
-I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore \
-I$(BUILD_PATH)\src\corelib\global \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
+ -I$(SOURCE_PATH)\tools\shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \
-DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \
-DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT
@@ -75,6 +77,8 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw
makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \
borland_bmake.obj msvc_nmake.obj msvc_vcproj.obj \
msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \
+ registry.obj \
+ epocroot.obj \
symmake_abld.obj symmake_sbsv2.obj
!IFDEF QMAKE_OPENSOURCE_EDITION
@@ -197,6 +201,8 @@ clean::
-del symmake_abld.obj
-del symmake_sbsv2.obj
-del initprojectdeploy_symbian.obj
+ -del registry.obj
+ -del epocroot.obj
-del pbuilder_pbx.obj
-del qxmlstream.obj
-del qxmlutils.obj
@@ -393,6 +399,12 @@ symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp
initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp
$(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp
+registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+ $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+
+epocroot.obj: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+ $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+
md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp
$(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp
diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++
index 41a1d8c25a..d4d6e0ebbb 100644
--- a/qmake/Makefile.win32-g++
+++ b/qmake/Makefile.win32-g++
@@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \
-I$(BUILD_PATH)/src/corelib/global \
-I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
+ -I$(SOURCE_PATH)/tools/shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \
-DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \
-DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
@@ -38,6 +39,8 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \
makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
borland_bmake.o msvc_nmake.o msvc_vcproj.o \
msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \
+ registry.o \
+ epocroot.o \
symmake_abld.o symmake_sbsv2.o
ifdef QMAKE_OPENSOURCE_EDITION
@@ -275,6 +278,12 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp
initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp
$(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp
+registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+ $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+
+epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+ $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+
project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
$(CXX) $(CXXFLAGS) project.cpp
diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh
index 0b08320ec3..5061089e0e 100644
--- a/qmake/Makefile.win32-g++-sh
+++ b/qmake/Makefile.win32-g++-sh
@@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \
-I$(BUILD_PATH)/src/corelib/global \
-I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
+ -I$(SOURCE_PATH)/tools/shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \
-DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \
-DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
@@ -38,6 +39,8 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \
makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
borland_bmake.o msvc_nmake.o msvc_vcproj.o \
msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \
+ registry.o \
+ epocroot.o \
symmake_abld.o symmake_sbsv2.o
ifdef QMAKE_OPENSOURCE_EDITION
@@ -274,6 +277,12 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp
initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp
$(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp
+registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+ $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+
+epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+ $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp
+
project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
$(CXX) $(CXXFLAGS) project.cpp
diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp
index 7279a4c796..0d501129ef 100644
--- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp
+++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp
@@ -46,105 +46,15 @@
#include <qsettings.h>
#include <qdebug.h>
+// Included from tools/shared
+#include <symbian/epocroot.h>
+
#define SYSBIN_DIR "\\sys\\bin"
#define SUFFIX_DLL "dll"
#define SUFFIX_EXE "exe"
#define SUFFIX_QTPLUGIN "qtplugin"
-static void fixEpocRootStr(QString& path)
-{
- path.replace("\\", "/");
-
- if (path.size() > 1 && path[1] == QChar(':')) {
- path = path.mid(2);
- }
-
- if (!path.size() || path[path.size()-1] != QChar('/')) {
- path += QChar('/');
- }
-}
-
-#define SYMBIAN_SDKS_KEY "HKEY_LOCAL_MACHINE\\Software\\Symbian\\EPOC SDKs"
-
-static QString epocRootStr;
-
-QString epocRoot()
-{
- if (!epocRootStr.isEmpty()) {
- return epocRootStr;
- }
-
- // First, check the env variable
- epocRootStr = qgetenv("EPOCROOT");
-
- if (epocRootStr.isEmpty()) {
- // No EPOCROOT set, check the default device
- // First check EPOCDEVICE env variable
- QString defaultDevice = qgetenv("EPOCDEVICE");
-
- // Check the windows registry via QSettings for devices.xml path
- QSettings settings(SYMBIAN_SDKS_KEY, QSettings::NativeFormat);
- QString devicesXmlPath = settings.value("CommonPath").toString();
-
- if (!devicesXmlPath.isEmpty()) {
- // Parse xml for correct device
- devicesXmlPath += "/devices.xml";
- QFile devicesFile(devicesXmlPath);
- if (devicesFile.open(QIODevice::ReadOnly)) {
- QXmlStreamReader xml(&devicesFile);
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.isStartElement() && xml.name() == "devices") {
- if (xml.attributes().value("version") == "1.0") {
- // Look for correct device
- while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) {
- xml.readNext();
- if (xml.isStartElement() && xml.name() == "device") {
- if ((defaultDevice.isEmpty() && xml.attributes().value("default") == "yes") ||
- (!defaultDevice.isEmpty() && (xml.attributes().value("id").toString() + QString(":") + xml.attributes().value("name").toString()) == defaultDevice)) {
- // Found the correct device
- while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) {
- xml.readNext();
- if (xml.isStartElement() && xml.name() == "epocroot") {
- epocRootStr = xml.readElementText();
- fixEpocRootStr(epocRootStr);
- return epocRootStr;
- }
- }
- xml.raiseError("No epocroot element found");
- }
- }
- }
- } else {
- xml.raiseError("Invalid 'devices' element version");
- }
- }
- }
- if (xml.hasError()) {
- fprintf(stderr, "ERROR: \"%s\" when parsing devices.xml\n", qPrintable(xml.errorString()));
- }
- } else {
- fprintf(stderr, "Could not open devices.xml (%s)\n", qPrintable(devicesXmlPath));
- }
- } else {
- fprintf(stderr, "Could not retrieve " SYMBIAN_SDKS_KEY " setting\n");
- }
-
- fprintf(stderr, "Failed to determine epoc root.\n");
- if (!defaultDevice.isEmpty())
- fprintf(stderr, "The device indicated by EPOCDEVICE environment variable (%s) could not be found.\n", qPrintable(defaultDevice));
- fprintf(stderr, "Either set EPOCROOT or EPOCDEVICE environment variable to a valid value, or provide a default Symbian device.\n");
-
- // No valid device found; set epocroot to "/"
- epocRootStr = QLatin1String("/");
- }
-
- fixEpocRootStr(epocRootStr);
- return epocRootStr;
-}
-
-
static bool isPlugin(const QFileInfo& info, const QString& devicePath)
{
// Libraries are plugins if deployment path is something else than
diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h
index e23e6a9ae2..b409225a04 100644
--- a/qmake/generators/symbian/initprojectdeploy_symbian.h
+++ b/qmake/generators/symbian/initprojectdeploy_symbian.h
@@ -50,8 +50,6 @@
#include <qfile.h>
#include <stdlib.h>
-#include "epocroot.h"
-
#define PLUGIN_STUB_DIR "qmakepluginstubs"
struct CopyItem
diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp
index 6854084457..ac4bca342d 100644
--- a/qmake/generators/symbian/symmake.cpp
+++ b/qmake/generators/symbian/symmake.cpp
@@ -49,6 +49,9 @@
#include <stdlib.h>
#include <qdebug.h>
+// Included from tools/shared
+#include <symbian/epocroot.h>
+
#define RESOURCE_DIRECTORY_MMP "/resource/apps"
#define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
#define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp
index 9b7ae3ebd0..81165f5ca1 100644
--- a/qmake/generators/symbian/symmake_abld.cpp
+++ b/qmake/generators/symbian/symmake_abld.cpp
@@ -48,6 +48,9 @@
#include <qdatetime.h>
#include <qdebug.h>
+// Included from tools/shared
+#include <symbian/epocroot.h>
+
#define DO_NOTHING_TARGET "do_nothing"
#define CREATE_TEMPS_TARGET "create_temps"
#define EXTENSION_CLEAN "extension_clean"
diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp
index f61018193b..4366f0e265 100644
--- a/qmake/generators/symbian/symmake_sbsv2.cpp
+++ b/qmake/generators/symbian/symmake_sbsv2.cpp
@@ -48,6 +48,9 @@
#include <qdatetime.h>
#include <qdebug.h>
+// Included from tools/shared
+#include <symbian/epocroot.h>
+
SymbianSbsv2MakefileGenerator::SymbianSbsv2MakefileGenerator() : SymbianMakefileGenerator() { }
SymbianSbsv2MakefileGenerator::~SymbianSbsv2MakefileGenerator() { }
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 3536a029c2..f1777e1d1c 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -67,6 +67,7 @@ QT_END_NAMESPACE
#ifdef Q_OS_WIN32
#include <qt_windows.h>
+#include <windows/registry.h>
QT_BEGIN_NAMESPACE
@@ -93,102 +94,6 @@ struct {
{NETUnknown, "", ""},
};
-static QString keyPath(const QString &rKey)
-{
- int idx = rKey.lastIndexOf(QLatin1Char('\\'));
- if (idx == -1)
- return QString();
- return rKey.left(idx + 1);
-}
-
-static QString keyName(const QString &rKey)
-{
- int idx = rKey.lastIndexOf(QLatin1Char('\\'));
- if (idx == -1)
- return rKey;
-
- QString res(rKey.mid(idx + 1));
- if (res == "Default" || res == ".")
- res = "";
- return res;
-}
-
-static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey)
-{
-
- QString rSubkeyName = keyName(rSubkey);
- QString rSubkeyPath = keyPath(rSubkey);
-
- HKEY handle = 0;
- LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle);
-
- if (res != ERROR_SUCCESS)
- return QString();
-
- // get the size and type of the value
- DWORD dataType;
- DWORD dataSize;
- res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
- if (res != ERROR_SUCCESS) {
- RegCloseKey(handle);
- return QString();
- }
-
- // get the value
- QByteArray data(dataSize, 0);
- res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0,
- reinterpret_cast<unsigned char*>(data.data()), &dataSize);
- if (res != ERROR_SUCCESS) {
- RegCloseKey(handle);
- return QString();
- }
-
- QString result;
- switch (dataType) {
- case REG_EXPAND_SZ:
- case REG_SZ: {
- result = QString::fromWCharArray(((const wchar_t *)data.constData()));
- break;
- }
-
- case REG_MULTI_SZ: {
- QStringList l;
- int i = 0;
- for (;;) {
- QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
- i += s.length() + 1;
-
- if (s.isEmpty())
- break;
- l.append(s);
- }
- result = l.join(", ");
- break;
- }
-
- case REG_NONE:
- case REG_BINARY: {
- result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
- break;
- }
-
- case REG_DWORD_BIG_ENDIAN:
- case REG_DWORD: {
- Q_ASSERT(data.size() == sizeof(int));
- int i;
- memcpy((char*)&i, data.constData(), sizeof(int));
- result = QString::number(i);
- break;
- }
-
- default:
- qWarning("QSettings: unknown data %d type in windows registry", dataType);
- break;
- }
-
- RegCloseKey(handle);
- return result;
-}
QT_END_NAMESPACE
#endif
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 887115260e..41931633fd 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -44,8 +44,6 @@
#include "option.h"
#include "cachekeys.h"
-#include "epocroot.h"
-
#include <qdatetime.h>
#include <qfile.h>
#include <qfileinfo.h>
@@ -64,6 +62,9 @@
#include <stdio.h>
#include <stdlib.h>
+// Included from tools/shared
+#include <symbian/epocroot.h>
+
#ifdef Q_OS_WIN32
#define QT_POPEN _popen
#define QT_PCLOSE _pclose
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index 17d9518961..0821f00e75 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -17,7 +17,9 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \
generators/symbian/symmake.cpp \
generators/symbian/symmake_abld.cpp \
generators/symbian/symmake_sbsv2.cpp \
- generators/symbian/initprojectdeploy_symbian.cpp
+ generators/symbian/initprojectdeploy_symbian.cpp \
+ windows/registry.cpp \
+ symbian/epocroot.cpp
HEADERS += project.h property.h generators/makefile.h \
generators/unix/unixmake.h meta.h option.h cachekeys.h \
@@ -29,8 +31,9 @@ HEADERS += project.h property.h generators/makefile.h \
generators/symbian/symmake.h \
generators/symbian/symmake_abld.h \
generators/symbian/symmake_sbsv2.h \
- generators/symbian/epocroot.h \
- generators/symbian/initprojectdeploy_symbian.h
+ generators/symbian/initprojectdeploy_symbian.h \
+ windows/registry.h \
+ symbian/epocroot.h
contains(QT_EDITION, OpenSource) {
DEFINES += QMAKE_OPENSOURCE_EDITION
diff --git a/qmake/qmake.pro b/qmake/qmake.pro
index 00dcbcea00..f3f9d5386d 100644
--- a/qmake/qmake.pro
+++ b/qmake/qmake.pro
@@ -27,5 +27,9 @@ INCPATH += generators \
$$QT_SOURCE_TREE/include \
$$QT_SOURCE_TREE/include/QtCore \
$$QT_SOURCE_TREE/qmake
+
+VPATH += $$QT_SOURCE_TREE/tools/shared
+INCPATH += $$QT_SOURCE_TREE/tools/shared
+
include(qmake.pri)
diff --git a/src/declarative/qml/qmllist.h b/src/declarative/qml/qmllist.h
index cedc35bbfb..5528d8d406 100644
--- a/src/declarative/qml/qmllist.h
+++ b/src/declarative/qml/qmllist.h
@@ -133,10 +133,11 @@ private:
friend class QmlListReferencePrivate;
QmlListReferencePrivate* d;
};
-Q_DECLARE_METATYPE(QmlListReference);
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QmlListReference);
+
QT_END_HEADER
#endif // QMLLIST_H
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index eee3a478af..dc96c1737c 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -38,6 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
// QtCore
#include <qdebug.h>
#include <qmath.h>
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 34d576ade3..1fcfebbf38 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -46,9 +46,11 @@
#include "qnetworkreply_p.h"
#include "QtCore/qhash.h"
#include "QtCore/qmutex.h"
+#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccesscachebackend_p.h"
#include "qabstractnetworkcache.h"
+#include "qhostinfo.h"
#include "private/qnoncontiguousbytedevice_p.h"
@@ -344,4 +346,35 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
#endif
}
+/*!
+ Starts the backend. Returns true if the backend is started. Returns false if the backend
+ could not be started due to an unopened or roaming session. The caller should recall this
+ function once the session has been opened or the roaming process has finished.
+*/
+bool QNetworkAccessBackend::start()
+{
+ if (!manager->networkSession) {
+ open();
+ return true;
+ }
+
+ // This is not ideal.
+ const QString host = reply->url.host();
+ if (host == QLatin1String("localhost") ||
+ QHostAddress(host) == QHostAddress::LocalHost ||
+ QHostAddress(host) == QHostAddress::LocalHostIPv6) {
+ // Don't need an open session for localhost access.
+ open();
+ return true;
+ }
+
+ if (manager->networkSession->isOpen() &&
+ manager->networkSession->state() == QNetworkSession::Connected) {
+ open();
+ return true;
+ }
+
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index 43d993ccfc..9bc15e5aad 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -111,6 +111,7 @@ public:
// socket).
virtual void open() = 0;
+ virtual bool start();
virtual void closeDownstreamChannel() = 0;
virtual bool waitForDownstreamReadyRead(int msecs) = 0;
@@ -160,6 +161,10 @@ public:
// This will possibly enable buffering of the upload data.
virtual bool needsResetableUploadData() { return false; }
+ // Returns true if backend is able to resume downloads.
+ virtual bool canResume() const { return false; }
+ virtual void setResumeOffset(quint64 offset) { Q_UNUSED(offset); }
+
protected:
// Create the device used for reading the upload data
QNonContiguousByteDevice* createUploadByteDevice();
@@ -190,6 +195,7 @@ private:
friend class QNetworkAccessManager;
friend class QNetworkAccessManagerPrivate;
friend class QNetworkAccessBackendUploadIODevice;
+ friend class QNetworkReplyImplPrivate;
QNetworkAccessManagerPrivate *manager;
QNetworkReplyImplPrivate *reply;
};
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index dcd4e19e27..7a48c2b16e 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -297,6 +297,7 @@ QNetworkAccessHttpBackend::QNetworkAccessHttpBackend()
#ifndef QT_NO_OPENSSL
, pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false)
#endif
+ , resumeOffset(0)
{
}
@@ -542,6 +543,28 @@ void QNetworkAccessHttpBackend::postRequest()
httpRequest.setUrl(url());
QList<QByteArray> headers = request().rawHeaderList();
+ if (resumeOffset != 0) {
+ if (headers.contains("Range")) {
+ // Need to adjust resume offset for user specified range
+
+ headers.removeOne("Range");
+
+ // We've already verified that requestRange starts with "bytes=", see canResume.
+ QByteArray requestRange = request().rawHeader("Range").mid(6);
+
+ int index = requestRange.indexOf('-');
+
+ quint64 requestStartOffset = requestRange.left(index).toULongLong();
+ quint64 requestEndOffset = requestRange.mid(index + 1).toULongLong();
+
+ requestRange = "bytes=" + QByteArray::number(resumeOffset + requestStartOffset) +
+ '-' + QByteArray::number(requestEndOffset);
+
+ httpRequest.setHeaderField("Range", requestRange);
+ } else {
+ httpRequest.setHeaderField("Range", "bytes=" + QByteArray::number(resumeOffset) + '-');
+ }
+ }
foreach (const QByteArray &header, headers)
httpRequest.setHeaderField(header, request().rawHeader(header));
@@ -1117,6 +1140,31 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
return metaData;
}
+bool QNetworkAccessHttpBackend::canResume() const
+{
+ // Only GET operation supports resuming.
+ if (operation() != QNetworkAccessManager::GetOperation)
+ return false;
+
+ // Can only resume if server/resource supports Range header.
+ if (httpReply->headerField("Accept-Ranges", "none") == "none")
+ return false;
+
+ // We only support resuming for byte ranges.
+ if (request().hasRawHeader("Range")) {
+ QByteArray range = request().rawHeader("Range");
+ if (!range.startsWith("bytes="))
+ return false;
+ }
+
+ return true;
+}
+
+void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset)
+{
+ resumeOffset = offset;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_HTTP
diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h
index 0eaf003587..e5cc0ab281 100644
--- a/src/network/access/qnetworkaccesshttpbackend_p.h
+++ b/src/network/access/qnetworkaccesshttpbackend_p.h
@@ -99,6 +99,9 @@ public:
// we return true since HTTP needs to send PUT/POST data again after having authenticated
bool needsResetableUploadData() { return true; }
+ bool canResume() const;
+ void setResumeOffset(quint64 offset);
+
private slots:
void replyReadyRead();
void replyFinished();
@@ -120,6 +123,8 @@ private:
QList<QSslError> pendingIgnoreSslErrorsList;
#endif
+ quint64 resumeOffset;
+
void disconnectFromHttp();
void setupConnection();
void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache);
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index cc4c977ee1..b9bd52ae31 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -47,6 +47,8 @@
#include "qnetworkcookie.h"
#include "qabstractnetworkcache.h"
+#include "QtNetwork/qnetworksession.h"
+
#include "qnetworkaccesshttpbackend_p.h"
#include "qnetworkaccessftpbackend_p.h"
#include "qnetworkaccessfilebackend_p.h"
@@ -59,6 +61,7 @@
#include "QtCore/qvector.h"
#include "QtNetwork/qauthenticator.h"
#include "QtNetwork/qsslconfiguration.h"
+#include "QtNetwork/qnetworkconfigmanager.h"
QT_BEGIN_NAMESPACE
@@ -163,6 +166,43 @@ static void ensureInitialized()
*/
/*!
+ \property QNetworkAccessManager::networkAccess
+ \brief states whether network access is enabled or disabled through this network access
+ manager.
+
+ \since 4.7
+
+ Network access is enabled by default.
+
+ When network access is disabled the network access manager will not process any new network
+ requests, all such requests will fail with an error. Requests with URLs with the file:// scheme
+ will still be processed.
+
+ This property can be used to enable and disable network access for all clients of a single
+ network access manager instance.
+*/
+
+/*!
+ \fn void QNetworkAccessManager::networkAccessChanged(bool enabled)
+
+ This signal is emitted when the value of the \l networkAccess property changes. If \a enabled
+ is true new requests that access the network will be processed; otherwise new network requests
+ that require network access will fail with an error.
+*/
+
+/*!
+ \fn void QNetworkAccessManager::networkSessionOnline()
+
+ \since 4.7
+
+ \internal
+
+ This signal is emitted when the status of the network session changes into a usable state.
+ It is used to signal QNetworkReply's to start or migrate their network operation once the
+ network session has been opened / roamed.
+*/
+
+/*!
\fn void QNetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
This signal is emitted whenever a proxy requests authentication
@@ -670,6 +710,110 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
/*!
\since 4.7
+ Sets the network configuration that will be used when creating the
+ \l {QNetworkSession}{network session} to \a config.
+
+ The network configuration is used to create and open a network session before any request that
+ requires network access is process. If no network configuration is explicitly set via this
+ function the network configuration returned by
+ QNetworkConfigurationManager::defaultConfiguration() will be used.
+
+ To restore the default network configuration set the network configuration to the value
+ returned from QNetworkConfigurationManager::defaultConfiguration().
+
+ \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 2
+
+ If an invalid network configuration is set, a network session will not be created. In this
+ case network requests will be processed regardless, but may fail. For example:
+
+ \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 3
+
+ \sa configuration(), QNetworkSession
+*/
+void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
+{
+ d_func()->createSession(config);
+}
+
+/*!
+ \since 4.7
+
+ Returns the network configuration that will be used to create the
+ \l {QNetworkSession}{network session} which will be used when processing network requests.
+
+ \sa setConfiguration(), activeConfiguration()
+*/
+QNetworkConfiguration QNetworkAccessManager::configuration() const
+{
+ Q_D(const QNetworkAccessManager);
+
+ if (d->networkSession)
+ return d->networkSession->configuration();
+ else
+ return QNetworkConfiguration();
+}
+
+/*!
+ \since 4.7
+
+ Returns the current active network configuration.
+
+ If the network configuration returned by configuration() is of type
+ QNetworkConfiguration::ServiceNetwork this function will return the current active child
+ network configuration of that configuration. Otherwise returns the same network configuration
+ as configuration().
+
+ Use this function to return the actual network configuration currently in use by the network
+ session.
+
+ \sa configuration()
+*/
+QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
+{
+ Q_D(const QNetworkAccessManager);
+
+ if (d->networkSession) {
+ QNetworkConfigurationManager manager;
+
+ return manager.configurationFromIdentifier(
+ d->networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
+ } else {
+ return QNetworkConfiguration();
+ }
+}
+
+/*!
+ \since 4.7
+
+ Enables network access via this QNetworkAccessManager if \a enabled is true; otherwise disables
+ access.
+*/
+void QNetworkAccessManager::setNetworkAccessEnabled(bool enabled)
+{
+ Q_D(QNetworkAccessManager);
+
+ if (d->networkAccessEnabled != enabled) {
+ d->networkAccessEnabled = enabled;
+ emit networkAccessChanged(enabled);
+ }
+}
+
+/*!
+ \since 4.7
+
+ Returns true if network access via this QNetworkAccessManager is enabled; otherwise returns
+ false.
+*/
+bool QNetworkAccessManager::networkAccessEnabled() const
+{
+ Q_D(const QNetworkAccessManager);
+
+ return d->networkAccessEnabled;
+}
+
+/*!
+ \since 4.7
+
Sends a custom request to the server identified by the URL of \a request.
It is the user's responsibility to send a \a verb to the server that is valid
@@ -722,6 +866,20 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QFileNetworkReply(this, req, op);
}
+ // Return a disabled network reply if network access is disabled.
+ // Except if the scheme is empty or file://.
+ if (!d->networkAccessEnabled && !(req.url().scheme() == QLatin1String("file") ||
+ req.url().scheme().isEmpty())) {
+ return new QDisabledNetworkReply(this, req, op);
+ }
+
+ if (d->initializeSession && !d->networkSession) {
+ QNetworkConfigurationManager manager;
+ d->createSession(manager.defaultConfiguration());
+
+ d->initializeSession = false;
+ }
+
QNetworkRequest request = req;
if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() &&
outgoingData && !outgoingData->isSequential()) {
@@ -738,6 +896,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
// first step: create the reply
QUrl url = request.url();
QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
+ if (req.url().scheme() != QLatin1String("file") && !req.url().scheme().isEmpty())
+ connect(this, SIGNAL(networkSessionOnline()), reply, SLOT(_q_networkSessionOnline()));
QNetworkReplyImplPrivate *priv = reply->d_func();
priv->manager = this;
@@ -772,6 +932,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
void QNetworkAccessManagerPrivate::_q_replyFinished()
{
Q_Q(QNetworkAccessManager);
+
QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
if (reply)
emit q->finished(reply);
@@ -1027,6 +1188,43 @@ QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
{
}
+void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &config)
+{
+ Q_Q(QNetworkAccessManager);
+
+ if (networkSession)
+ delete networkSession;
+
+ if (!config.isValid()) {
+ networkSession = 0;
+ return;
+ }
+
+ networkSession = new QNetworkSession(config, q);
+
+ QObject::connect(networkSession, SIGNAL(opened()), q, SIGNAL(networkSessionOnline()));
+ QObject::connect(networkSession, SIGNAL(newConfigurationActivated()),
+ q, SLOT(_q_networkSessionNewConfigurationActivated()));
+ QObject::connect(networkSession,
+ SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)),
+ q,
+ SLOT(_q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool)));
+}
+
+void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated()
+{
+ Q_Q(QNetworkAccessManager);
+
+ networkSession->accept();
+
+ emit q->networkSessionOnline();
+}
+
+void QNetworkAccessManagerPrivate::_q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &, bool)
+{
+ networkSession->migrate();
+}
+
QT_END_NAMESPACE
#include "moc_qnetworkaccessmanager.cpp"
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 3a8ba58744..252dfd0607 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -62,12 +62,16 @@ class QNetworkReply;
class QNetworkProxy;
class QNetworkProxyFactory;
class QSslError;
+class QNetworkConfiguration;
class QNetworkReplyImplPrivate;
class QNetworkAccessManagerPrivate;
class Q_NETWORK_EXPORT QNetworkAccessManager: public QObject
{
Q_OBJECT
+
+ Q_PROPERTY(bool networkAccess READ networkAccessEnabled WRITE setNetworkAccessEnabled NOTIFY networkAccessChanged)
+
public:
enum Operation {
HeadOperation = 1,
@@ -105,6 +109,13 @@ public:
QNetworkReply *deleteResource(const QNetworkRequest &request);
QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = 0);
+ void setConfiguration(const QNetworkConfiguration &config);
+ QNetworkConfiguration configuration() const;
+ QNetworkConfiguration activeConfiguration() const;
+
+ void setNetworkAccessEnabled(bool enabled);
+ bool networkAccessEnabled() const;
+
Q_SIGNALS:
#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
@@ -115,6 +126,10 @@ Q_SIGNALS:
void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
#endif
+ void networkSessionOnline();
+
+ void networkAccessChanged(bool enabled);
+
protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = 0);
@@ -124,6 +139,8 @@ private:
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replyFinished())
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
+ Q_PRIVATE_SLOT(d_func(), void _q_networkSessionNewConfigurationActivated())
+ Q_PRIVATE_SLOT(d_func(), void _q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool))
};
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 1749373c38..8d772f0858 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -65,6 +65,7 @@ class QAuthenticator;
class QAbstractNetworkCache;
class QNetworkAuthenticationCredential;
class QNetworkCookieJar;
+class QNetworkSession;
class QNetworkAccessManagerPrivate: public QObjectPrivate
{
@@ -74,6 +75,9 @@ public:
#ifndef QT_NO_NETWORKPROXY
proxyFactory(0),
#endif
+ networkSession(0),
+ networkAccessEnabled(true),
+ initializeSession(true),
cookieJarCreated(false)
{ }
~QNetworkAccessManagerPrivate();
@@ -99,6 +103,12 @@ public:
QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request);
+ void createSession(const QNetworkConfiguration &config);
+
+ void _q_networkSessionNewConfigurationActivated();
+ void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config,
+ bool isSeamless);
+
// this is the cache for storing downloaded files
QAbstractNetworkCache *networkCache;
@@ -110,8 +120,11 @@ public:
QNetworkProxyFactory *proxyFactory;
#endif
- bool cookieJarCreated;
+ QNetworkSession *networkSession;
+ bool networkAccessEnabled;
+ bool initializeSession;
+ bool cookieJarCreated;
// this cache can be used by individual backends to cache e.g. their TCP connections to a server
// and use the connections for multiple requests.
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index 15748fece7..c8b8c1f23c 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -125,6 +125,11 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
encrypted channel could not be established. The sslErrors() signal
should have been emitted.
+ \value TemporaryNetworkFailureError the connection was broken due
+ to disconnection from the network, however the system has initiated
+ roaming to another access point. The request should be resubmitted
+ and will be processed as soon as the connection is re-established.
+
\value ProxyConnectionRefusedError the connection to the proxy
server was refused (the proxy server is not accepting requests)
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index 5db4985f9c..acb7379a14 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -77,6 +77,7 @@ public:
TimeoutError,
OperationCanceledError,
SslHandshakeFailedError,
+ TemporaryNetworkFailureError,
UnknownNetworkError = 99,
// proxy errors (101-199):
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 59c7d76dac..2175686a96 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -46,7 +46,9 @@
#include "QtCore/qcoreapplication.h"
#include "QtCore/qdatetime.h"
#include "QtNetwork/qsslconfiguration.h"
+#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccesshttpbackend_p.h"
+#include "qnetworkaccessmanager_p.h"
#include <QtCore/QCoreApplication>
@@ -57,7 +59,7 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
copyDevice(0),
cacheEnabled(false), cacheSaveDevice(0),
notificationHandlingPaused(false),
- bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1),
+ bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), preMigrationDownloaded(-1),
httpStatusCode(0),
state(Idle)
{
@@ -82,7 +84,24 @@ void QNetworkReplyImplPrivate::_q_startOperation()
return;
}
- backend->open();
+ if (!backend->start()) {
+ // backend failed to start because the session state is not Connected.
+ // QNetworkAccessManager will call reply->backend->start() again for us when the session
+ // state changes.
+ state = WaitingForSession;
+
+ QNetworkSession *session = manager->d_func()->networkSession;
+
+ if (session) {
+ if (!session->isOpen())
+ session->open();
+ } else {
+ qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
+ }
+
+ return;
+ }
+
if (state != Finished) {
if (operation == QNetworkAccessManager::GetOperation)
pendingNotifications.append(NotifyDownstreamReadyWrite);
@@ -134,6 +153,8 @@ void QNetworkReplyImplPrivate::_q_copyReadyRead()
lastBytesDownloaded = bytesDownloaded;
QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
+ if (preMigrationDownloaded != Q_INT64_C(-1))
+ totalSize = totalSize.toLongLong() + preMigrationDownloaded;
pauseNotificationHandling();
emit q->downloadProgress(bytesDownloaded,
totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong());
@@ -206,6 +227,26 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData()
}
}
+void QNetworkReplyImplPrivate::_q_networkSessionOnline()
+{
+ Q_Q(QNetworkReplyImpl);
+
+ switch (state) {
+ case QNetworkReplyImplPrivate::Buffering:
+ case QNetworkReplyImplPrivate::Working:
+ case QNetworkReplyImplPrivate::Reconnecting:
+ // Migrate existing downloads to new network connection.
+ migrateBackend();
+ break;
+ case QNetworkReplyImplPrivate::WaitingForSession:
+ // Start waiting requests.
+ QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection);
+ break;
+ default:
+ ;
+ }
+}
+
void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req,
QIODevice *data)
{
@@ -457,6 +498,8 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data)
QPointer<QNetworkReplyImpl> qq = q;
QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
+ if (preMigrationDownloaded != Q_INT64_C(-1))
+ totalSize = totalSize.toLongLong() + preMigrationDownloaded;
pauseNotificationHandling();
emit q->downloadProgress(bytesDownloaded,
totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong());
@@ -498,14 +541,42 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
void QNetworkReplyImplPrivate::finished()
{
Q_Q(QNetworkReplyImpl);
- if (state == Finished || state == Aborted)
+
+ if (state == Finished || state == Aborted || state == WaitingForSession)
return;
+ pauseNotificationHandling();
+ QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
+ if (preMigrationDownloaded != Q_INT64_C(-1))
+ totalSize = totalSize.toLongLong() + preMigrationDownloaded;
+
+ if (!manager.isNull()) {
+ QNetworkSession *session = manager->d_func()->networkSession;
+ if (session && session->state() == QNetworkSession::Roaming &&
+ state == Working && errorCode != QNetworkReply::OperationCanceledError) {
+ // only content with a known size will fail with a temporary network failure error
+ if (!totalSize.isNull()) {
+ if (bytesDownloaded != totalSize) {
+ if (migrateBackend()) {
+ // either we are migrating or the request is finished/aborted
+ if (state == Reconnecting || state == WaitingForSession) {
+ resumeNotificationHandling();
+ return; // exit early if we are migrating.
+ }
+ } else {
+ error(QNetworkReply::TemporaryNetworkFailureError,
+ q->tr("Temporary network failure."));
+ }
+ }
+ }
+ }
+ }
+ resumeNotificationHandling();
+
state = Finished;
pendingNotifications.clear();
pauseNotificationHandling();
- QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
if (totalSize.isNull() || totalSize == -1) {
emit q->downloadProgress(bytesDownloaded, bytesDownloaded);
}
@@ -514,7 +585,9 @@ void QNetworkReplyImplPrivate::finished()
emit q->uploadProgress(0, 0);
resumeNotificationHandling();
- completeCacheSave();
+ // if we don't know the total size of or we received everything save the cache
+ if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize)
+ completeCacheSave();
// note: might not be a good idea, since users could decide to delete us
// which would delete the backend too...
@@ -722,6 +795,83 @@ bool QNetworkReplyImpl::event(QEvent *e)
return QObject::event(e);
}
+/*
+ Migrates the backend of the QNetworkReply to a new network connection if required. Returns
+ true if the reply is migrated or it is not required; otherwise returns false.
+*/
+bool QNetworkReplyImplPrivate::migrateBackend()
+{
+ Q_Q(QNetworkReplyImpl);
+
+ // Network reply is already finished or aborted, don't need to migrate.
+ if (state == Finished || state == Aborted)
+ return true;
+
+ // Backend does not support resuming download.
+ if (!backend->canResume())
+ return false;
+
+ // Request has outgoing data, not migrating.
+ if (outgoingData)
+ return false;
+
+ // Request is serviced from the cache, don't need to migrate.
+ if (copyDevice)
+ return true;
+
+ state = QNetworkReplyImplPrivate::Reconnecting;
+
+ if (backend) {
+ delete backend;
+ backend = 0;
+ }
+
+ cookedHeaders.clear();
+ rawHeaders.clear();
+
+ preMigrationDownloaded = bytesDownloaded;
+
+ backend = manager->d_func()->findBackend(operation, request);
+
+ if (backend) {
+ backend->setParent(q);
+ backend->reply = this;
+ backend->setResumeOffset(bytesDownloaded);
+ }
+
+ if (qobject_cast<QNetworkAccessHttpBackend *>(backend)) {
+ _q_startOperation();
+ } else {
+ QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection);
+ }
+
+ return true;
+}
+
+QDisabledNetworkReply::QDisabledNetworkReply(QObject *parent,
+ const QNetworkRequest &req,
+ QNetworkAccessManager::Operation op)
+: QNetworkReply(parent)
+{
+ setRequest(req);
+ setUrl(req.url());
+ setOperation(op);
+
+ qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
+
+ QString msg = QCoreApplication::translate("QNetworkAccessManager",
+ "Network access is disabled.");
+ setError(UnknownNetworkError, msg);
+
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, UnknownNetworkError));
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+}
+
+QDisabledNetworkReply::~QDisabledNetworkReply()
+{
+}
+
QT_END_NAMESPACE
#include "moc_qnetworkreplyimpl_p.cpp"
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 168e5cf147..ec413cca3b 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -98,6 +98,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished())
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_networkSessionOnline())
};
class QNetworkReplyImplPrivate: public QNetworkReplyPrivate
@@ -110,11 +111,13 @@ public:
};
enum State {
- Idle,
- Buffering,
- Working,
- Finished,
- Aborted
+ Idle, // The reply is idle.
+ Buffering, // The reply is buffering outgoing data.
+ Working, // The reply is uploading/downloading data.
+ Finished, // The reply has finished.
+ Aborted, // The reply has been aborted.
+ WaitingForSession, // The reply is waiting for the session to open before connecting.
+ Reconnecting // The reply will reconnect to once roaming has completed.
};
typedef QQueue<InternalNotifications> NotificationQueue;
@@ -128,6 +131,7 @@ public:
void _q_copyReadChannelFinished();
void _q_bufferOutgoingData();
void _q_bufferOutgoingDataFinished();
+ void _q_networkSessionOnline();
void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
QIODevice *outgoingData);
@@ -161,6 +165,8 @@ public:
QIODevice *copyDevice;
QAbstractNetworkCache *networkCache() const;
+ bool migrateBackend();
+
bool cacheEnabled;
QIODevice *cacheSaveDevice;
@@ -177,6 +183,7 @@ public:
qint64 bytesDownloaded;
qint64 lastBytesDownloaded;
qint64 bytesUploaded;
+ qint64 preMigrationDownloaded;
QString httpReasonPhrase;
int httpStatusCode;
@@ -186,6 +193,20 @@ public:
Q_DECLARE_PUBLIC(QNetworkReplyImpl)
};
+class QDisabledNetworkReply : public QNetworkReply
+{
+ Q_OBJECT
+
+public:
+ QDisabledNetworkReply(QObject *parent, const QNetworkRequest &req,
+ const QNetworkAccessManager::Operation op);
+ ~QDisabledNetworkReply();
+
+ void abort() { }
+protected:
+ qint64 readData(char *, qint64) { return -1; }
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri
new file mode 100644
index 0000000000..44e97fdef0
--- /dev/null
+++ b/src/network/bearer/bearer.pri
@@ -0,0 +1,18 @@
+# Qt network bearer management module
+
+HEADERS += bearer/qnetworkconfiguration.h \
+ bearer/qnetworksession.h \
+ bearer/qnetworkconfigmanager.h \
+ bearer/qnetworkconfigmanager_p.h \
+ bearer/qnetworkconfiguration_p.h \
+ bearer/qnetworksession_p.h \
+ bearer/qbearerengine_p.h \
+ bearer/qbearerplugin_p.h
+
+SOURCES += bearer/qnetworksession.cpp \
+ bearer/qnetworkconfigmanager.cpp \
+ bearer/qnetworkconfiguration.cpp \
+ bearer/qnetworkconfigmanager_p.cpp \
+ bearer/qbearerengine.cpp \
+ bearer/qbearerplugin.cpp
+
diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp
new file mode 100644
index 0000000000..eb851ccb2d
--- /dev/null
+++ b/src/network/bearer/qbearerengine.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbearerengine_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QBearerEngine::QBearerEngine(QObject *parent)
+: QObject(parent), mutex(QMutex::Recursive)
+{
+}
+
+QBearerEngine::~QBearerEngine()
+{
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+ for (it = snapConfigurations.begin(), end = snapConfigurations.end(); it != end; ++it) {
+ it.value()->isValid = false;
+ it.value()->id.clear();
+ }
+
+ for (it = accessPointConfigurations.begin(), end = accessPointConfigurations.end();
+ it != end; ++it) {
+ it.value()->isValid = false;
+ it.value()->id.clear();
+ }
+
+ for (it = userChoiceConfigurations.begin(), end = userChoiceConfigurations.end();
+ it != end; ++it) {
+ it.value()->isValid = false;
+ it.value()->id.clear();
+ }
+}
+
+#include "moc_qbearerengine_p.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h
new file mode 100644
index 0000000000..5e12b0fa7a
--- /dev/null
+++ b/src/network/bearer/qbearerengine_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBEARERENGINE_P_H
+#define QBEARERENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkconfiguration_p.h"
+#include "qnetworksession.h"
+#include "qnetworkconfigmanager.h"
+
+#include <QtCore/qobject.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qmutex.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkConfiguration;
+
+class Q_NETWORK_EXPORT QBearerEngine : public QObject
+{
+ Q_OBJECT
+
+ friend class QNetworkConfigurationManager;
+
+public:
+ QBearerEngine(QObject *parent = 0);
+ virtual ~QBearerEngine();
+
+ virtual bool hasIdentifier(const QString &id) = 0;
+
+ virtual void requestUpdate() = 0;
+
+ virtual QNetworkConfigurationManager::Capabilities capabilities() const = 0;
+
+ virtual QNetworkSessionPrivate *createSessionBackend() = 0;
+
+ virtual QNetworkConfigurationPrivatePointer defaultConfiguration() = 0;
+
+Q_SIGNALS:
+ void configurationAdded(QNetworkConfigurationPrivatePointer config);
+ void configurationRemoved(QNetworkConfigurationPrivatePointer config);
+ void configurationChanged(QNetworkConfigurationPrivatePointer config);
+
+ void updateCompleted();
+
+protected:
+ //this table contains an up to date list of all configs at any time.
+ //it must be updated if configurations change, are added/removed or
+ //the members of ServiceNetworks change
+ QHash<QString, QNetworkConfigurationPrivatePointer> accessPointConfigurations;
+ QHash<QString, QNetworkConfigurationPrivatePointer> snapConfigurations;
+ QHash<QString, QNetworkConfigurationPrivatePointer> userChoiceConfigurations;
+
+ mutable QMutex mutex;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/qmake/generators/symbian/epocroot.h b/src/network/bearer/qbearerplugin.cpp
index be26438e9e..4509fd02bf 100644
--- a/qmake/generators/symbian/epocroot.h
+++ b/src/network/bearer/qbearerplugin.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the qmake application of the Qt Toolkit.
+** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -39,13 +39,19 @@
**
****************************************************************************/
-#ifndef EPOCROOT_H
-#define EPOCROOT_H
+#include "qbearerplugin_p.h"
-#include <qstring.h>
+#include <QtCore/qdebug.h>
-// Implementation of epocRoot method is in initprojectdeploy_symbian.cpp
-// Defined in separate header for inclusion clarity
-extern QString epocRoot();
+QT_BEGIN_NAMESPACE
-#endif // EPOCROOT_H
+QBearerEnginePlugin::QBearerEnginePlugin(QObject *parent)
+: QObject(parent)
+{
+}
+
+QBearerEnginePlugin::~QBearerEnginePlugin()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/bearer/qbearerplugin_p.h b/src/network/bearer/qbearerplugin_p.h
new file mode 100644
index 0000000000..36709c2743
--- /dev/null
+++ b/src/network/bearer/qbearerplugin_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBEARERPLUGIN_P_H
+#define QBEARERPLUGIN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qbearerengine_p.h"
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Network)
+
+struct Q_NETWORK_EXPORT QBearerEngineFactoryInterface : public QFactoryInterface
+{
+ virtual QBearerEngine *create(const QString &key = QString()) const = 0;
+};
+
+#define QBearerEngineFactoryInterface_iid "com.trolltech.Qt.QBearerEngineFactoryInterface"
+Q_DECLARE_INTERFACE(QBearerEngineFactoryInterface, QBearerEngineFactoryInterface_iid)
+
+class Q_NETWORK_EXPORT QBearerEnginePlugin : public QObject, public QBearerEngineFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QBearerEngineFactoryInterface:QFactoryInterface)
+
+public:
+ explicit QBearerEnginePlugin(QObject *parent = 0);
+ virtual ~QBearerEnginePlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QBearerEngine *create(const QString &key = QString()) const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
new file mode 100644
index 0000000000..e960323859
--- /dev/null
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -0,0 +1,419 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkconfigmanager.h"
+
+#include "qnetworkconfigmanager_p.h"
+#include "qbearerengine_p.h"
+
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QNetworkConfigurationManagerPrivate, connManager);
+
+QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
+{
+ return connManager();
+}
+
+/*!
+ \class QNetworkConfigurationManager
+
+ \brief The QNetworkConfigurationManager class manages the network configurations provided
+ by the system.
+
+ \since 4.7
+
+ \inmodule QtNetwork
+ \ingroup bearer
+
+ QNetworkConfigurationManager provides access to the network configurations known to the system and
+ enables applications to detect the system capabilities (with regards to network sessions) at runtime.
+
+ A QNetworkConfiguration abstracts a set of configuration options describing how a
+ network interface has to be configured to connect to a particular target network.
+ QNetworkConfigurationManager maintains and updates the global list of
+ QNetworkConfigurations. Applications can access and filter this list via
+ allConfigurations(). If a new configuration is added or an existing one is removed or changed
+ the configurationAdded(), configurationRemoved() and configurationChanged() signals are emitted
+ respectively.
+
+ The defaultConfiguration() can be used when intending to immediately create a new
+ network session without caring about the particular configuration. It returns
+ a \l QNetworkConfiguration::Discovered configuration. If there are not any
+ discovered ones an invalid configuration is returned.
+
+ Some configuration updates may require some time to perform updates. A WLAN scan is
+ such an example. Unless the platform performs internal updates it may be required to
+ manually trigger configuration updates via QNetworkConfigurationManager::updateConfigurations().
+ The completion of the update process is indicted by emitting the updateCompleted()
+ signal. The update process ensures that every existing QNetworkConfiguration instance
+ is updated. There is no need to ask for a renewed configuration list via allConfigurations().
+
+ \sa QNetworkConfiguration
+*/
+
+/*!
+ \fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration& config)
+
+ This signal is emitted whenever a new network configuration is added to the system. The new
+ configuration is specified by \a config.
+*/
+
+/*!
+ \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration& configuration)
+
+ This signal is emitted when a configuration is about to be removed from the system. The removed
+ \a configuration is invalid but retains name and identifier.
+*/
+
+/*!
+ \fn void QNetworkConfigurationManager::updateCompleted()
+
+ This signal is emitted when the configuration update has been completed. Such an update can
+ be initiated via \l updateConfigurations().
+*/
+
+/*! \fn void QNetworkConfigurationManager::configurationChanged(const QNetworkConfiguration& config)
+
+ This signal is emitted when the \l {QNetworkConfiguration::state()}{state} of \a config changes.
+*/
+
+/*!
+ \fn void QNetworkConfigurationManager::onlineStateChanged(bool isOnline)
+
+ This signal is emitted when the device changes from online to offline mode or vice versa.
+ \a isOnline represents the new state of the device.
+
+ The state is considered to be online for as long as
+ \l{allConfigurations()}{allConfigurations}(QNetworkConfiguration::Active) returns a list with
+ at least one entry.
+*/
+
+/*!
+ \enum QNetworkConfigurationManager::Capability
+
+ Specifies the system capabilities of the bearer API. The possible values are:
+
+ \value CanStartAndStopInterfaces Network sessions and their underlying access points can be
+ started and stopped. If this flag is not set QNetworkSession
+ can only monitor but not influence the state of access points.
+ On some platforms this feature may require elevated user
+ permissions. This option is platform specific and may not
+ always be available.
+ \value DirectConnectionRouting Network sessions and their sockets can be bound to a
+ particular network interface. Any packet that passes through
+ the socket goes to the specified network interface and thus
+ disregards standard routing table entries. This may be useful
+ when two interfaces can reach overlapping IP ranges or an
+ application has specific needs in regards to target networks.
+ This option is platform specific and may not always be
+ available.
+ \value SystemSessionSupport If this flag is set the underlying platform ensures that a
+ network interface is not shut down until the last network
+ session has been \l{QNetworkSession::close()}{closed()}. This
+ works across multiple processes. If the platform session
+ support is missing this API can only ensure the above behavior
+ for network sessions within the same process.
+ In general mobile platforms (such as Symbian/S60) have such
+ support whereas most desktop platform lack this capability.
+ \value ApplicationLevelRoaming The system gives applications control over the systems roaming
+ behavior. Applications can initiate roaming (in case the
+ current link is not suitable) and are consulted if the system
+ has identified a more suitable access point.
+ \value ForcedRoaming The system disconnects an existing access point and reconnects
+ via a more suitable one. The application does not have any
+ control over this process and has to reconnect its active
+ sockets.
+ \value DataStatistics If this flag is set QNetworkSession can provide statistics
+ about transmitted and received data.
+*/
+
+/*!
+ Constructs a QNetworkConfigurationManager with the given \a parent.
+*/
+QNetworkConfigurationManager::QNetworkConfigurationManager( QObject* parent )
+ : QObject(parent)
+{
+ QNetworkConfigurationManagerPrivate* priv = connManager();
+ connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
+ this, SIGNAL(configurationAdded(QNetworkConfiguration)));
+ connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
+ this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
+ connect(priv, SIGNAL(configurationUpdateComplete()),
+ this, SIGNAL(updateCompleted()));
+ connect(priv, SIGNAL(onlineStateChanged(bool)),
+ this, SIGNAL(onlineStateChanged(bool)));
+ connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SIGNAL(configurationChanged(QNetworkConfiguration)));
+}
+
+/*!
+ Frees the resources associated with the QNetworkConfigurationManager object.
+*/
+QNetworkConfigurationManager::~QNetworkConfigurationManager()
+{
+}
+
+
+/*!
+ Returns the default configuration to be used. This function always returns a discovered
+ configuration; otherwise an invalid configuration.
+
+ In some cases it may be required to call updateConfigurations() and wait for the
+ updateCompleted() signal before calling this function.
+
+ \sa allConfigurations()
+*/
+QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const
+{
+ QNetworkConfigurationManagerPrivate *conPriv = connManager();
+
+ foreach (QBearerEngine *engine, conPriv->engines()) {
+ QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration();
+
+ if (ptr) {
+ QNetworkConfiguration config;
+ config.d = ptr;
+ return config;
+ }
+ }
+
+ // Engines don't have a default configuration.
+
+ // Return first active snap
+ QNetworkConfigurationPrivatePointer firstDiscovered;
+
+ foreach (QBearerEngine *engine, conPriv->engines()) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end();
+ it != end; ++it) {
+ if ((it.value()->state & QNetworkConfiguration::Active) ==
+ QNetworkConfiguration::Active) {
+ QNetworkConfiguration config;
+ config.d = it.value();
+ return config;
+ } else if ((it.value()->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ firstDiscovered = it.value();
+ }
+ }
+ }
+
+ // No Active SNAPs return first Discovered SNAP.
+ if (firstDiscovered) {
+ QNetworkConfiguration config;
+ config.d = firstDiscovered;
+ return config;
+ }
+
+ // No Active or Discovered SNAPs, do same for InternetAccessPoints.
+ firstDiscovered.reset();
+
+ foreach (QBearerEngine *engine, conPriv->engines()) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ for (it = engine->accessPointConfigurations.begin(),
+ end = engine->accessPointConfigurations.end(); it != end; ++it) {
+ if ((it.value()->state & QNetworkConfiguration::Active) ==
+ QNetworkConfiguration::Active) {
+ QNetworkConfiguration config;
+ config.d = it.value();
+ return config;
+ } else if ((it.value()->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ firstDiscovered = it.value();
+ }
+ }
+ }
+
+ // No Active InternetAccessPoint return first Discovered InternetAccessPoint.
+ if (firstDiscovered) {
+ QNetworkConfiguration config;
+ config.d = firstDiscovered;
+ return config;
+ }
+
+ return QNetworkConfiguration();
+}
+
+/*!
+ Returns the list of configurations which comply with the given \a filter.
+
+ By default this function returns all (defined and undefined) configurations.
+
+ A wireless network with a particular SSID may only be accessible in a
+ certain area despite the fact that the system has a valid configuration
+ for it. Therefore the filter flag may be used to limit the list to
+ discovered and possibly connected configurations only.
+
+ If \a filter is set to zero this function returns all possible configurations.
+
+ Note that this function returns the states for all configurations as they are known at
+ the time of this function call. If for instance a configuration of type WLAN is defined
+ the system may have to perform a WLAN scan in order to determine whether it is
+ actually available. To obtain the most accurate state updateConfigurations() should
+ be used to update each configuration's state. Note that such an update may require
+ some time. It's completion is signalled by updateCompleted(). In the absence of a
+ configuration update this function returns the best estimate at the time of the call.
+*/
+QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const
+{
+ QList<QNetworkConfiguration> result;
+ QNetworkConfigurationManagerPrivate* conPriv = connManager();
+
+ foreach (QBearerEngine *engine, conPriv->engines()) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ //find all InternetAccessPoints
+ for (it = engine->accessPointConfigurations.begin(),
+ end = engine->accessPointConfigurations.end(); it != end; ++it) {
+ if ((it.value()->state & filter) == filter) {
+ QNetworkConfiguration pt;
+ pt.d = it.value();
+ result << pt;
+ }
+ }
+
+ //find all service networks
+ for (it = engine->snapConfigurations.begin(),
+ end = engine->snapConfigurations.end(); it != end; ++it) {
+ if ((it.value()->state & filter) == filter) {
+ QNetworkConfiguration pt;
+ pt.d = it.value();
+ result << pt;
+ }
+ }
+ }
+
+ return result;
+}
+
+/*!
+ Returns the QNetworkConfiguration for \a identifier; otherwise returns an
+ invalid QNetworkConfiguration.
+
+ \sa QNetworkConfiguration::identifier()
+*/
+QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString& identifier) const
+{
+ QNetworkConfigurationManagerPrivate* conPriv = connManager();
+
+ QNetworkConfiguration item;
+
+ foreach (QBearerEngine *engine, conPriv->engines()) {
+ QMutexLocker locker(&engine->mutex);
+
+ if (engine->accessPointConfigurations.contains(identifier))
+ item.d = engine->accessPointConfigurations.value(identifier);
+ else if (engine->snapConfigurations.contains(identifier))
+ item.d = engine->snapConfigurations.value(identifier);
+ else if (engine->userChoiceConfigurations.contains(identifier))
+ item.d = engine->userChoiceConfigurations.value(identifier);
+ else
+ continue;
+
+ return item;
+ }
+
+ return item;
+}
+
+/*!
+ Returns true if the system is considered to be connected to another device via an active
+ network interface; otherwise returns false.
+
+ This is equivalent to the following code snippet:
+
+ \snippet doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp 0
+
+ \sa onlineStateChanged()
+*/
+bool QNetworkConfigurationManager::isOnline() const
+{
+ QNetworkConfigurationManagerPrivate* conPriv = connManager();
+ Q_UNUSED(conPriv);
+ QList<QNetworkConfiguration> activeConfigs = allConfigurations(QNetworkConfiguration::Active);
+ return activeConfigs.count() > 0;
+}
+
+/*!
+ Returns the capabilities supported by the current platform.
+*/
+QNetworkConfigurationManager::Capabilities QNetworkConfigurationManager::capabilities() const
+{
+ return connManager()->capFlags;
+}
+
+/*!
+ Initiates an update of all configurations. This may be used to initiate WLAN scans or other
+ time consuming updates which may be required to obtain the correct state for configurations.
+
+ This call is asynchronous. On completion of this update the updateCompleted() signal is
+ emitted. If new configurations are discovered or old ones were removed or changed the update
+ process may trigger the emission of one or multiple configurationAdded(),
+ configurationRemoved() and configurationChanged() signals.
+
+ If a configuration state changes as a result of this update all existing QNetworkConfiguration
+ instances are updated automatically.
+
+ \sa allConfigurations()
+*/
+void QNetworkConfigurationManager::updateConfigurations()
+{
+ connManager()->performAsyncConfigurationUpdate();
+}
+
+#include "moc_qnetworkconfigmanager.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h
new file mode 100644
index 0000000000..73041fe98f
--- /dev/null
+++ b/src/network/bearer/qnetworkconfigmanager.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKCONFIGURATIONMANAGER_H
+#define QNETWORKCONFIGURATIONMANAGER_H
+
+#include <QtCore/qobject.h>
+#include <QtNetwork/qnetworkconfiguration.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Network)
+
+class QNetworkConfigurationManagerPrivate;
+class Q_NETWORK_EXPORT QNetworkConfigurationManager : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum Capability {
+ CanStartAndStopInterfaces = 0x00000001,
+ DirectConnectionRouting = 0x00000002,
+ SystemSessionSupport = 0x00000004,
+ ApplicationLevelRoaming = 0x00000008,
+ ForcedRoaming = 0x00000010,
+ DataStatistics = 0x00000020
+ };
+
+ Q_DECLARE_FLAGS(Capabilities, Capability)
+
+ QNetworkConfigurationManager( QObject* parent = 0 );
+ virtual ~QNetworkConfigurationManager();
+
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkConfiguration defaultConfiguration() const;
+ QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags flags = 0) const;
+ QNetworkConfiguration configurationFromIdentifier(const QString& identifier) const;
+ void updateConfigurations();
+
+ bool isOnline() const;
+
+Q_SIGNALS:
+ void configurationAdded(const QNetworkConfiguration& config);
+ void configurationRemoved(const QNetworkConfiguration& config);
+ void configurationChanged(const QNetworkConfiguration& config);
+ void onlineStateChanged(bool isOnline);
+ void updateCompleted();
+
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QNETWORKCONFIGURATIONMANAGER_H
+
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
new file mode 100644
index 0000000000..1ac10c5c58
--- /dev/null
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkconfigmanager_p.h"
+#include "qbearerplugin_p.h"
+
+#include <QtCore/private/qfactoryloader_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/private/qcoreapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")))
+
+QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
+: capFlags(0), mutex(QMutex::Recursive), firstUpdate(true)
+{
+ updateConfigurations();
+
+ moveToThread(QCoreApplicationPrivate::mainThread());
+ foreach (QBearerEngine *engine, sessionEngines)
+ engine->moveToThread(QCoreApplicationPrivate::mainThread());
+}
+
+QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate()
+{
+ QMutexLocker locker(&mutex);
+
+ qDeleteAll(sessionEngines);
+}
+
+void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr)
+{
+ QMutexLocker locker(&mutex);
+
+ if (!firstUpdate) {
+ QNetworkConfiguration item;
+ item.d = ptr;
+ emit configurationAdded(item);
+ }
+
+ if (ptr->state == QNetworkConfiguration::Active) {
+ onlineConfigurations.insert(ptr);
+ if (!firstUpdate && onlineConfigurations.count() == 1)
+ emit onlineStateChanged(true);
+ }
+}
+
+void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigurationPrivatePointer ptr)
+{
+ QMutexLocker locker(&mutex);
+
+ ptr->isValid = false;
+
+ if (!firstUpdate) {
+ QNetworkConfiguration item;
+ item.d = ptr;
+ emit configurationRemoved(item);
+ }
+
+ onlineConfigurations.remove(ptr);
+ if (!firstUpdate && onlineConfigurations.isEmpty())
+ emit onlineStateChanged(false);
+}
+
+void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigurationPrivatePointer ptr)
+{
+ QMutexLocker locker(&mutex);
+
+ if (!firstUpdate) {
+ QNetworkConfiguration item;
+ item.d = ptr;
+ emit configurationChanged(item);
+ }
+
+ bool previous = !onlineConfigurations.isEmpty();
+
+ if (ptr->state == QNetworkConfiguration::Active)
+ onlineConfigurations.insert(ptr);
+ else
+ onlineConfigurations.remove(ptr);
+
+ bool online = !onlineConfigurations.isEmpty();
+
+ if (!firstUpdate && online != previous)
+ emit onlineStateChanged(online);
+}
+
+void QNetworkConfigurationManagerPrivate::updateConfigurations()
+{
+ QMutexLocker locker(&mutex);
+
+ if (firstUpdate) {
+ updating = false;
+
+ QFactoryLoader *l = loader();
+
+ QBearerEngine *generic = 0;
+
+ foreach (const QString &key, l->keys()) {
+ QBearerEnginePlugin *plugin = qobject_cast<QBearerEnginePlugin *>(l->instance(key));
+ if (plugin) {
+ QBearerEngine *engine = plugin->create(key);
+ if (!engine)
+ continue;
+
+ if (key == QLatin1String("generic"))
+ generic = engine;
+ else
+ sessionEngines.append(engine);
+
+ connect(engine, SIGNAL(updateCompleted()),
+ this, SLOT(updateConfigurations()));
+ connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)),
+ this, SLOT(configurationAdded(QNetworkConfigurationPrivatePointer)));
+ connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)),
+ this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)));
+ connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)),
+ this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)));
+
+ capFlags |= engine->capabilities();
+ }
+ }
+
+ if (generic)
+ sessionEngines.append(generic);
+ }
+
+ QBearerEngine *engine = qobject_cast<QBearerEngine *>(sender());
+ if (!updatingEngines.isEmpty() && engine) {
+ int index = sessionEngines.indexOf(engine);
+ if (index >= 0)
+ updatingEngines.remove(index);
+ }
+
+ if (updating && updatingEngines.isEmpty()) {
+ updating = false;
+ emit configurationUpdateComplete();
+ }
+
+ if (firstUpdate)
+ firstUpdate = false;
+}
+
+void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ if (sessionEngines.isEmpty()) {
+ emit configurationUpdateComplete();
+ return;
+ }
+
+ updating = true;
+
+ for (int i = 0; i < sessionEngines.count(); ++i) {
+ updatingEngines.insert(i);
+ sessionEngines.at(i)->requestUpdate();
+ }
+}
+
+QList<QBearerEngine *> QNetworkConfigurationManagerPrivate::engines()
+{
+ QMutexLocker locker(&mutex);
+
+ return sessionEngines;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h
new file mode 100644
index 0000000000..c7e988ef35
--- /dev/null
+++ b/src/network/bearer/qnetworkconfigmanager_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKCONFIGURATIONMANAGERPRIVATE_H
+#define QNETWORKCONFIGURATIONMANAGERPRIVATE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkconfigmanager.h"
+#include "qnetworkconfiguration_p.h"
+
+#include <QtCore/qmutex.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBearerEngine;
+
+class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QNetworkConfigurationManagerPrivate();
+ virtual ~QNetworkConfigurationManagerPrivate();
+
+ QNetworkConfiguration defaultConfiguration();
+
+ QNetworkConfigurationManager::Capabilities capFlags;
+
+ void performAsyncConfigurationUpdate();
+
+ QList<QBearerEngine *> engines();
+
+public slots:
+ void updateConfigurations();
+
+Q_SIGNALS:
+ void configurationAdded(const QNetworkConfiguration& config);
+ void configurationRemoved(const QNetworkConfiguration& config);
+ void configurationUpdateComplete();
+ void configurationChanged(const QNetworkConfiguration& config);
+ void onlineStateChanged(bool isOnline);
+
+ void abort();
+
+private:
+ QMutex mutex;
+
+ QList<QBearerEngine *> sessionEngines;
+
+ QSet<QNetworkConfigurationPrivatePointer> onlineConfigurations;
+
+ QSet<int> updatingEngines;
+ bool updating;
+
+ bool firstUpdate;
+
+private Q_SLOTS:
+ void configurationAdded(QNetworkConfigurationPrivatePointer ptr);
+ void configurationRemoved(QNetworkConfigurationPrivatePointer ptr);
+ void configurationChanged(QNetworkConfigurationPrivatePointer ptr);
+};
+
+Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate();
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKCONFIGURATIONMANAGERPRIVATE_H
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
new file mode 100644
index 0000000000..c551dc5dbc
--- /dev/null
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -0,0 +1,396 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkconfiguration.h"
+
+#include "qnetworkconfiguration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QNetworkConfiguration
+
+ \brief The QNetworkConfiguration class provides an abstraction of one or more access point configurations.
+
+ \since 4.7
+
+ \inmodule QtNetwork
+ \ingroup bearer
+
+ QNetworkConfiguration encapsulates a single access point or service network.
+ In most cases a single access point configuration can be mapped to one network
+ interface. However a single network interface may not always map to only one
+ access point configuration. Multiple configurations for the same
+ network device may enable multiple access points. An example
+ device that could exhibit such a configuration might be a
+ Smartphone which allows the user to manage multiple WLAN
+ configurations while the device itself has only one WLAN network device.
+
+ The QNetworkConfiguration also supports the concept of service networks.
+ This concept allows the grouping of multiple access point configurations
+ into one entity. Such a group is called service network and can be
+ beneficial in cases whereby a network session to a
+ particular destination network is required (e.g. a company network).
+ When using a service network the user doesn't usually care which one of the
+ connectivity options is chosen (e.g. corporate WLAN or VPN via GPRS)
+ as long as he can reach the company's target server. Depending
+ on the current position and time some of the access points that make
+ up the service network may not even be available. Furthermore
+ automated access point roaming can be enabled which enables the device
+ to change the network interface configuration dynamically while maintaining
+ the applications connection to the target network. It allows adaption
+ to the changing environment and may enable optimization with regards to
+ cost, speed or other network parameters.
+
+ Special configurations of type UserChoice provide a placeholder configuration which is
+ resolved to an actual network configuration by the platform when a
+ \l {QNetworkSession}{session} is \l {QNetworkSession::open()}{opened}. Not all platforms
+ support the concept of a user choice configuration.
+
+ \section1 Configuration states
+
+ The list of available configurations can be obtained via
+ QNetworkConfigurationManager::allConfigurations(). A configuration can have
+ multiple states. The \l Defined configuration state indicates that the configuration
+ is stored on the device. However the configuration is not yet ready to be activated
+ as e.g. a WLAN may not be available at the current time.
+
+ The \l Discovered state implies that the configuration is \l Defined and
+ the outside conditions are such that the configuration can be used immediately
+ to open a new network session. An example of such an outside condition may be
+ that the Ethernet cable is actually connected to the device or that the WLAN
+ with the specified SSID is in range.
+
+ The \l Active state implies that the configuration is \l Discovered. A configuration
+ in this state is currently being used by an application. The underlying network
+ interface has a valid IP configuration and can transfer IP packets between the
+ device and the target network.
+
+ The \l Undefined state indicates that the system has knowledge of possible target
+ networks but cannot actually use that knowledge to connect to it. An example
+ for such a state could be an encrypted WLAN that has been discovered
+ but the user hasn't actually saved a configuration including the required password
+ which would allow the device to connect to it.
+
+ Depending on the type of configuration some states are transient in nature. A GPRS/UMTS
+ connection may almost always be \l Discovered if the GSM/UMTS network is available.
+ However if the GSM/UMTS network looses the connection the associated configuration may change its state
+ from \l Discovered to \l Defined as well. A similar use case might be triggered by
+ WLAN availability. QNetworkConfigurationManager::updateConfigurations() can be used to
+ manually trigger updates of states. Note that some platforms do not require such updates
+ as they implicitly change the state once it has been discovered. If the state of a
+ configuration changes all related QNetworkConfiguration instances change their state automatically.
+
+ \sa QNetworkSession, QNetworkConfigurationManager
+*/
+
+/*!
+ \enum QNetworkConfiguration::Type
+
+ This enum describes the type of configuration.
+
+ \value InternetAccessPoint The configuration specifies the details for a single access point.
+ Note that configurations of type InternetAccessPoint may be part
+ of other QNetworkConfigurations of type ServiceNetwork.
+ \value ServiceNetwork The configuration is based on a group of QNetworkConfigurations of
+ type InternetAccessPoint. All group members can reach the same
+ target network. This type of configuration is a mandatory
+ requirement for roaming enabled network sessions. On some
+ platforms this form of configuration may also be called Service
+ Network Access Point (SNAP).
+ \value UserChoice The configuration is a placeholder which will be resolved to an
+ actual configuration by the platform when a session is opened. Depending
+ on the platform the selection may generate a popup dialog asking the user
+ for his preferred choice.
+ \value Invalid The configuration is invalid.
+*/
+
+/*!
+ \enum QNetworkConfiguration::StateFlag
+
+ Specifies the configuration states.
+
+ \value Undefined This state is used for transient configurations such as newly discovered
+ WLANs for which the user has not actually created a configuration yet.
+ \value Defined Defined configurations are known to the system but are not immediately
+ usable (e.g. a configured WLAN is not within range or the Ethernet cable
+ is currently not plugged into the machine).
+ \value Discovered A discovered configuration can be immediately used to create a new
+ QNetworkSession. An example of a discovered configuration could be a WLAN
+ which is within in range. If the device moves out of range the discovered
+ flag is dropped. A second example is a GPRS configuration which generally
+ remains discovered for as long as the device has network coverage. A
+ configuration that has this state is also in state
+ QNetworkConfiguration::Defined. If the configuration is a service network
+ this flag is set if at least one of the underlying access points
+ configurations has the Discovered state.
+ \value Active The configuration is currently used by an open network session
+ (see \l QNetworkSession::isOpen()). However this does not mean that the
+ current process is the entity that created the open session. It merely
+ indicates that if a new QNetworkSession were to be constructed based on
+ this configuration \l QNetworkSession::state() would return
+ \l QNetworkSession::Connected. This state implies the
+ QNetworkConfiguration::Discovered state.
+*/
+
+/*!
+ \enum QNetworkConfiguration::Purpose
+
+ Specifies the purpose of the configuration.
+
+ \value UnknownPurpose The configuration doesn't specify any purpose. This is the default value.
+ \value PublicPurpose The configuration can be used for general purpose internet access.
+ \value PrivatePurpose The configuration is suitable to access a private network such as an office Intranet.
+ \value ServiceSpecificPurpose The configuration can be used for operator specific services (e.g.
+ receiving MMS messages or content streaming).
+*/
+
+/*!
+ Constructs an invalid configuration object.
+
+ \sa isValid()
+*/
+QNetworkConfiguration::QNetworkConfiguration()
+ : d(0)
+{
+}
+
+/*!
+ Creates a copy of the QNetworkConfiguration object contained in \a other.
+*/
+QNetworkConfiguration::QNetworkConfiguration(const QNetworkConfiguration& other)
+ : d(other.d)
+{
+}
+
+/*!
+ Copies the content of the QNetworkConfiguration object contained in \a other into this one.
+*/
+QNetworkConfiguration& QNetworkConfiguration::operator=(const QNetworkConfiguration& other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Frees the resources associated with the QNetworkConfiguration object.
+*/
+QNetworkConfiguration::~QNetworkConfiguration()
+{
+}
+
+/*!
+ Returns true, if this configuration is the same as the \a other
+ configuration given; otherwise returns false.
+*/
+bool QNetworkConfiguration::operator==(const QNetworkConfiguration& other) const
+{
+ if (!d)
+ return !other.d;
+
+ if (!other.d)
+ return false;
+
+ return (d == other.d);
+}
+
+/*!
+ \fn bool QNetworkConfiguration::operator!=(const QNetworkConfiguration& other) const
+
+ Returns true if this configuration is not the same as the \a other
+ configuration given; otherwise returns false.
+*/
+
+/*!
+ Returns the user visible name of this configuration.
+
+ The name may either be the name of the underlying access point or the
+ name for service network that this configuration represents.
+*/
+QString QNetworkConfiguration::name() const
+{
+ return d ? d->name : QString();
+}
+
+/*!
+ Returns the unique and platform specific identifier for this network configuration;
+ otherwise an empty string.
+*/
+QString QNetworkConfiguration::identifier() const
+{
+ return d ? d->id : QString();
+}
+
+/*!
+ Returns the type of the configuration.
+
+ A configuration can represent a single access point configuration or
+ a set of access point configurations. Such a set is called service network.
+ A configuration that is based on a service network can potentially support
+ roaming of network sessions.
+*/
+QNetworkConfiguration::Type QNetworkConfiguration::type() const
+{
+ return d ? d->type : QNetworkConfiguration::Invalid;
+}
+
+/*!
+ Returns true if this QNetworkConfiguration object is valid.
+ A configuration may become invalid if the user deletes the configuration or
+ the configuration was default-constructed.
+
+ The addition and removal of configurations can be monitored via the
+ QNetworkConfigurationManager.
+
+ \sa QNetworkConfigurationManager
+*/
+bool QNetworkConfiguration::isValid() const
+{
+ return d ? d->isValid : false;
+}
+
+/*!
+ Returns the current state of the configuration.
+*/
+QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const
+{
+ return d ? d->state : QNetworkConfiguration::Undefined;
+}
+
+/*!
+ Returns the purpose of this configuration.
+
+ The purpose field may be used to programmatically determine the
+ purpose of a configuration. Such information is usually part of the
+ access point or service network meta data.
+*/
+QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const
+{
+ return d ? d->purpose : QNetworkConfiguration::UnknownPurpose;
+}
+
+/*!
+ Returns true if this configuration supports roaming; otherwise false.
+*/
+bool QNetworkConfiguration::isRoamingAvailable() const
+{
+ return d ? d->roamingSupported : false;
+}
+
+/*!
+ Returns all sub configurations of this network configuration.
+ Only network configurations of type \l ServiceNetwork can have children. Otherwise
+ this function returns an empty list.
+*/
+QList<QNetworkConfiguration> QNetworkConfiguration::children() const
+{
+ QList<QNetworkConfiguration> results;
+ if (type() != QNetworkConfiguration::ServiceNetwork || !isValid() )
+ return results;
+
+ QMutableListIterator<QNetworkConfigurationPrivatePointer> iter(d->serviceNetworkMembers);
+ while(iter.hasNext()) {
+ QNetworkConfigurationPrivatePointer p = iter.next();
+ //if we have an invalid member get rid of it -> was deleted earlier on
+ if (!p->isValid)
+ iter.remove();
+
+ QNetworkConfiguration item;
+ item.d = p;
+ results << item;
+ }
+
+ return results;
+}
+
+/*!
+ Returns the type of bearer. The string is not translated and
+ therefore can not be shown to the user. The subsequent table presents the currently known
+ bearer types:
+
+ \table
+ \header
+ \o Value
+ \o Description
+ \row
+ \o Unknown
+ \o The session is based on an unknown or unspecified bearer type.
+ \row
+ \o Ethernet
+ \o The session is based on Ethernet.
+ \row
+ \o WLAN
+ \o The session is based on Wireless LAN.
+ \row
+ \o 2G
+ \o The session uses CSD, GPRS, HSCSD, EDGE or cdmaOne.
+ \row
+ \o CDMA2000
+ \o The session uses CDMA.
+ \row
+ \o WCDMA
+ \o The session uses W-CDMA/UMTS.
+ \row
+ \o HSPA
+ \o The session uses High Speed Packet Access.
+ \row
+ \o Bluetooth
+ \o The session uses Bluetooth.
+ \row
+ \o WiMAX
+ \o The session uses WiMAX.
+ \endtable
+
+ This function returns an empty string if this is an invalid configuration,
+ a network configuration of type \l QNetworkConfiguration::ServiceNetwork or
+ \l QNetworkConfiguration::UserChoice.
+*/
+QString QNetworkConfiguration::bearerName() const
+{
+ if (!isValid())
+ return QString();
+
+ return d->bearerName();
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h
new file mode 100644
index 0000000000..dad6198214
--- /dev/null
+++ b/src/network/bearer/qnetworkconfiguration.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKCONFIGURATION_H
+#define QNETWORKCONFIGURATION_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Network)
+
+class QNetworkConfigurationPrivate;
+class Q_NETWORK_EXPORT QNetworkConfiguration
+{
+public:
+ QNetworkConfiguration();
+ QNetworkConfiguration(const QNetworkConfiguration& other);
+ QNetworkConfiguration &operator=(const QNetworkConfiguration& other);
+ ~QNetworkConfiguration();
+
+ bool operator==(const QNetworkConfiguration& cp) const;
+ inline bool operator!=(const QNetworkConfiguration& cp) const
+ { return !operator==(cp); }
+
+ enum Type {
+ InternetAccessPoint = 0,
+ ServiceNetwork,
+ UserChoice,
+ Invalid
+ };
+
+ enum Purpose {
+ UnknownPurpose = 0,
+ PublicPurpose,
+ PrivatePurpose,
+ ServiceSpecificPurpose
+ };
+
+ enum StateFlag {
+ Undefined = 0x0000001,
+ Defined = 0x0000002,
+ Discovered = 0x0000006,
+ Active = 0x000000e
+ };
+
+ Q_DECLARE_FLAGS(StateFlags, StateFlag)
+
+ StateFlags state() const;
+ Type type() const;
+ Purpose purpose() const;
+ QString bearerName() const;
+ QString identifier() const;
+ bool isRoamingAvailable() const;
+ QList<QNetworkConfiguration> children() const;
+
+ QString name() const;
+ bool isValid() const;
+
+private:
+ friend class QNetworkConfigurationPrivate;
+ friend class QNetworkConfigurationManager;
+ friend class QNetworkConfigurationManagerPrivate;
+ friend class QNetworkSessionPrivate;
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QNETWORKCONFIGURATION_H
diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h
new file mode 100644
index 0000000000..6b40946437
--- /dev/null
+++ b/src/network/bearer/qnetworkconfiguration_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKCONFIGURATIONPRIVATE_H
+#define QNETWORKCONFIGURATIONPRIVATE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkconfiguration.h"
+#include <QtCore/qshareddata.h>
+#include <QtNetwork/QNetworkInterface>
+
+QT_BEGIN_NAMESPACE
+
+typedef QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationPrivatePointer;
+class QNetworkConfigurationPrivate : public QSharedData
+{
+public:
+ QNetworkConfigurationPrivate ()
+ : isValid(false), type(QNetworkConfiguration::Invalid),
+ roamingSupported(false), purpose(QNetworkConfiguration::UnknownPurpose), internet(false)
+ {
+ }
+
+ ~QNetworkConfigurationPrivate()
+ {
+ //release pointers to member configurations
+ serviceNetworkMembers.clear();
+ }
+
+ virtual QString bearerName() const
+ {
+ return bearer;
+ }
+
+ QString bearer;
+
+ QString name;
+
+ bool isValid;
+ QString id;
+ QNetworkConfiguration::StateFlags state;
+ QNetworkConfiguration::Type type;
+ bool roamingSupported;
+ QNetworkConfiguration::Purpose purpose;
+
+ bool internet;
+
+ QList<QNetworkConfigurationPrivatePointer> serviceNetworkMembers;
+
+private:
+
+ // disallow detaching
+ QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other);
+ QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other);
+};
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKCONFIGURATIONPRIVATE_H
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
new file mode 100644
index 0000000000..6a82791ecc
--- /dev/null
+++ b/src/network/bearer/qnetworksession.cpp
@@ -0,0 +1,684 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QEventLoop>
+#include <QTimer>
+
+#include "qnetworksession.h"
+#include "qbearerengine_p.h"
+#include "qnetworkconfigmanager_p.h"
+#include "qnetworksession_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QNetworkSession
+
+ \brief The QNetworkSession class provides control over the system's access points
+ and enables session management for cases when multiple clients access the same access point.
+
+ \since 4.7
+
+ \inmodule QtNetwork
+ \ingroup bearer
+
+ A QNetworkSession enables control over the system's network interfaces. The session's configuration
+ parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the
+ type of the session (single access point or service network) a session may be linked to one or more
+ network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions
+ a developer can start and stop the systems network interfaces. If the configuration represents
+ multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported.
+
+ QNetworkSession supports session management within the same process and depending on the platform's
+ capabilities may support out-of-process sessions. If the same
+ network configuration is used by multiple open sessions the underlying network interface is only terminated once
+ the last session has been closed.
+
+ \section1 Roaming
+
+ Applications may connect to the preferredConfigurationChanged() signal in order to
+ receive notifications when a more suitable access point becomes available.
+ In response to this signal the application must either initiate the roaming via migrate()
+ or ignore() the new access point. Once the session has roamed the
+ newConfigurationActivated() signal is emitted. The application may now test the
+ carrier and must either accept() or reject() it. The session will return to the previous
+ access point if the roaming was rejected. The subsequent state diagram depicts the required
+ state transitions.
+
+ \image roaming-states.png
+
+ Some platforms may distinguish forced roaming and application level roaming (ALR).
+ ALR implies that the application controls (via migrate(), ignore(), accept() and reject())
+ whether a network session can roam from one access point to the next. Such control is useful
+ if the application maintains stateful socket connections and wants to control the transition from
+ one interface to the next. Forced roaming implies that the system automatically roams to the next network without
+ consulting the application. This has the advantage that the application can make use of roaming features
+ without actually being aware of it. It is expected that the application detects that the underlying
+ socket is broken and automatically reconnects via the new network link.
+
+ If the platform supports both modes of roaming, an application indicates its preference
+ by connecting to the preferredConfigurationChanged() signal. Connecting to this signal means that
+ the application wants to take control over the roaming behavior and therefore implies application
+ level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming
+ is used. If forced roaming is not supported the network session will not roam by default.
+
+ Some applications may want to suppress any form of roaming altogether. Possible use cases may be
+ high priority downloads or remote services which cannot handle a roaming enabled client. Clients
+ can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each
+ signal emission with ignore().
+
+ \sa QNetworkConfiguration, QNetworkConfigurationManager
+*/
+
+/*!
+ \enum QNetworkSession::State
+
+ This enum describes the connectivity state of the session. If the session is based on a
+ single access point configuration the state of the session is the same as the state of the
+ associated network interface.
+
+ \value Invalid The session is invalid due to an invalid configuration. This may
+ happen due to a removed access point or a configuration that was
+ invalid to begin with.
+ \value NotAvailable The session is based on a defined but not yet discovered QNetworkConfiguration
+ (see \l QNetworkConfiguration::StateFlag).
+ \value Connecting The network session is being established.
+ \value Connected The network session is connected. If the current process wishes to use this session
+ it has to register its interest by calling open(). A network session
+ is considered to be ready for socket operations if it isOpen() and connected.
+ \value Closing The network session is in the process of being shut down.
+ \value Disconnected The network session is not connected. The associated QNetworkConfiguration
+ has the state QNetworkConfiguration::Discovered.
+ \value Roaming The network session is roaming from one access point to another
+ access point.
+*/
+
+/*!
+ \enum QNetworkSession::SessionError
+
+ This enum describes the session errors that can occur.
+
+ \value UnknownSessionError An unidentified error occurred.
+ \value SessionAbortedError The session was aborted by the user or system.
+ \value RoamingError The session cannot roam to a new configuration.
+ \value OperationNotSupportedError The operation is not supported for current configuration.
+ \value InvalidConfigurationError The operation cannot currently be performed for the
+ current configuration.
+*/
+
+/*!
+ \fn void QNetworkSession::stateChanged(QNetworkSession::State state)
+
+ This signal is emitted whenever the state of the network session changes.
+ The \a state parameter is the new state.
+
+ \sa state()
+*/
+
+/*!
+ \fn void QNetworkSession::error(QNetworkSession::SessionError error)
+
+ This signal is emitted after an error occurred. The \a error parameter
+ describes the error that occurred.
+
+ \sa error(), errorString()
+*/
+
+/*!
+ \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless)
+
+ This signal is emitted when the preferred configuration/access point for the
+ session changes. Only sessions which are based on service network configurations
+ may emit this signal. \a config can be used to determine access point specific
+ details such as proxy settings and \a isSeamless indicates whether roaming will
+ break the sessions IP address.
+
+ As a consequence to this signal the application must either start the roaming process
+ by calling migrate() or choose to ignore() the new access point.
+
+ If the roaming process is non-seamless the IP address will change which means that
+ a socket becomes invalid. However seamless mobility can ensure that the local IP address
+ does not change. This is achieved by using a virtual IP address which is bound to the actual
+ link address. During the roaming process the virtual address is attached to the new link
+ address.
+
+ Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR).
+ Forced roaming implies that the platform may simply roam to a new configuration without
+ consulting applications. It is up to the application to detect the link layer loss and reestablish
+ its sockets. In contrast ALR provides the opportunity to prevent the system from roaming.
+ If this session is based on a configuration that supports roaming the application can choose
+ whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal
+ connection remains the session remains registered as a roaming stakeholder; otherwise roaming will
+ be enforced by the platform.
+
+ \sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable()
+*/
+
+/*!
+ \fn void QNetworkSession::newConfigurationActivated()
+
+ This signal is emitted once the session has roamed to the new access point.
+ The application may reopen its socket and test the suitability of the new network link.
+ Subsequently it must either accept() or reject() the new access point.
+
+ \sa accept(), reject()
+*/
+
+/*!
+ \fn void QNetworkSession::opened()
+
+ This signal is emitted when the network session has been opened.
+
+ The underlying network interface will not be shut down as long as the session remains open.
+ Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}.
+*/
+
+/*!
+ \fn void QNetworkSession::closed()
+
+ This signal is emitted when the network session has been closed.
+*/
+
+/*!
+ Constructs a session based on \a connectionConfig with the given \a parent.
+
+ \sa QNetworkConfiguration
+*/
+QNetworkSession::QNetworkSession(const QNetworkConfiguration& connectionConfig, QObject* parent)
+: QObject(parent), d(0)
+{
+ foreach (QBearerEngine *engine, qNetworkConfigurationManagerPrivate()->engines()) {
+ if (engine->hasIdentifier(connectionConfig.identifier())) {
+ d = engine->createSessionBackend();
+ d->q = this;
+ d->publicConfig = connectionConfig;
+ d->syncStateWithInterface();
+ connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened()));
+ connect(d, SIGNAL(error(QNetworkSession::SessionError)),
+ this, SIGNAL(error(QNetworkSession::SessionError)));
+ connect(d, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SIGNAL(stateChanged(QNetworkSession::State)));
+ connect(d, SIGNAL(closed()), this, SIGNAL(closed()));
+ connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)),
+ this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)));
+ connect(d, SIGNAL(newConfigurationActivated()),
+ this, SIGNAL(newConfigurationActivated()));
+ break;
+ }
+ }
+}
+
+/*!
+ Frees the resources associated with the QNetworkSession object.
+*/
+QNetworkSession::~QNetworkSession()
+{
+ delete d;
+}
+
+/*!
+ Creates an open session which increases the session counter on the underlying network interface.
+ The system will not terminate a network interface until the session reference counter reaches zero.
+ Therefore an open session allows an application to register its use of the interface.
+
+ As a result of calling open() the interface will be started if it is not connected/up yet.
+ Some platforms may not provide support for out-of-process sessions. On such platforms the session
+ counter ignores any sessions held by another process. The platform capabilities can be
+ detected via QNetworkConfigurationManager::capabilities().
+
+ Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
+ by connecting to the stateChanged(), opened() or error() signals.
+
+ It is not a requirement to open a session in order to monitor the underlying network interface.
+
+ \sa close(), stop(), isOpen()
+*/
+void QNetworkSession::open()
+{
+ if (d)
+ d->open();
+}
+
+/*!
+ Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this
+ function returns true; otherwise it returns false. In the case where it returns false, you can call error()
+ to determine the cause of the error.
+
+ The following example waits up to one second for the session to be opened:
+
+ \code
+ session->open();
+ if (session->waitForOpened(1000))
+ qDebug("Open!");
+ \endcode
+
+ If \a msecs is -1, this function will not time out.
+
+ \sa open(), error()
+*/
+bool QNetworkSession::waitForOpened(int msecs)
+{
+ if (!d)
+ return false;
+
+ if (d->isOpen)
+ return true;
+
+ if (d->state != Connecting)
+ return false;
+
+ QEventLoop* loop = new QEventLoop(this);
+ QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()),
+ loop, SLOT(quit()));
+
+ //final call
+ if (msecs>=0)
+ QTimer::singleShot(msecs, loop, SLOT(quit()));
+
+ loop->exec();
+ loop->disconnect();
+ loop->deleteLater();
+
+ return d->isOpen;
+}
+
+/*!
+ Decreases the session counter on the associated network configuration. If the session counter reaches zero
+ the active network interface is shut down. This also means that state() will only change from \l Connected to
+ \l Disconnected if the current session was the last open session.
+
+ If the platform does not support out-of-process sessions calling this function does not stop the
+ interface. In this case \l{stop()} has to be used to force a shut down.
+ The platform capabilities can be detected via QNetworkConfigurationManager::capabilities().
+
+ Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
+ by connecting to the stateChanged(), opened() or error() signals.
+
+ \sa open(), stop(), isOpen()
+*/
+void QNetworkSession::close()
+{
+ if (d)
+ d->close();
+}
+
+/*!
+ Invalidates all open sessions against the network interface and therefore stops the
+ underlying network interface. This function always changes the session's state() flag to
+ \l Disconnected.
+
+ On Symbian platform, a 'NetworkControl' capability is required for
+ full interface-level stop (without the capability, only the current session is stopped).
+
+ \sa open(), close()
+*/
+void QNetworkSession::stop()
+{
+ if (d)
+ d->stop();
+}
+
+/*!
+ Returns the QNetworkConfiguration that this network session object is based on.
+
+ \sa QNetworkConfiguration
+*/
+QNetworkConfiguration QNetworkSession::configuration() const
+{
+ return d ? d->publicConfig : QNetworkConfiguration();
+}
+
+/*!
+ Returns the network interface that is used by this session.
+
+ This function only returns a valid QNetworkInterface when this session is \l Connected.
+
+ The returned interface may change as a result of a roaming process.
+
+ Note: this function does not work in Symbian emulator due to the way the
+ connectivity is emulated on Windows.
+
+ \sa state()
+*/
+QNetworkInterface QNetworkSession::interface() const
+{
+ return d ? d->currentInterface() : QNetworkInterface();
+}
+
+/*!
+ Returns true if this session is open. If the number of all open sessions is greater than
+ zero the underlying network interface will remain connected/up.
+
+ The session can be controlled via open() and close().
+*/
+bool QNetworkSession::isOpen() const
+{
+ return d ? d->isOpen : false;
+}
+
+/*!
+ Returns the state of the session.
+
+ If the session is based on a single access point configuration the state of the
+ session is the same as the state of the associated network interface. Therefore
+ a network session object can be used to monitor network interfaces.
+
+ A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children
+ and therefore returns the \l Connected state if at least one of the service network's
+ \l {QNetworkConfiguration::children()}{children()} configurations is active.
+
+ Note that it is not required to hold an open session in order to obtain the network interface state.
+ A connected but closed session may be used to monitor network interfaces whereas an open and connected
+ session object may prevent the network interface from being shut down.
+
+ \sa error(), stateChanged()
+*/
+QNetworkSession::State QNetworkSession::state() const
+{
+ return d ? d->state : QNetworkSession::Invalid;
+}
+
+/*!
+ Returns the type of error that last occurred.
+
+ \sa state(), errorString()
+*/
+QNetworkSession::SessionError QNetworkSession::error() const
+{
+ return d ? d->error() : InvalidConfigurationError;
+}
+
+/*!
+ Returns a human-readable description of the last device error that
+ occurred.
+
+ \sa error()
+*/
+QString QNetworkSession::errorString() const
+{
+ return d ? d->errorString() : tr("Invalid configuration.");
+}
+
+/*!
+ Returns the value for property \a key.
+
+ A network session can have properties attached which may describe the session in more details.
+ This function can be used to gain access to those properties.
+
+ The following property keys are guaranteed to be specified on all platforms:
+
+ \table
+ \header
+ \o Key \o Description
+ \row
+ \o ActiveConfiguration
+ \o If the session \l isOpen() this property returns the identifier of the
+ QNetworkConfiguration that is used by this session; otherwise an empty string.
+
+ The main purpose of this key is to determine which Internet access point is used
+ if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}.
+ The following code snippet highlights the difference:
+ \code
+ QNetworkConfigurationManager mgr;
+ QNetworkConfiguration ap = mgr.defaultConfiguration();
+ QNetworkSession* session = new QNetworkSession(ap);
+ ... //code activates session
+
+ QString ident = session->sessionProperty("ActiveConfiguration").toString();
+ if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) {
+ Q_ASSERT( ap.identifier() != ident );
+ Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) );
+ } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) {
+ Q_ASSERT( ap.identifier() == ident );
+ }
+ \endcode
+ \row
+ \o UserChoiceConfiguration
+ \o If the session \l isOpen() and is bound to a QNetworkConfiguration of type
+ UserChoice, this property returns the identifier of the QNetworkConfiguration that the
+ configuration resolved to when \l open() was called; otherwise an empty string.
+
+ The purpose of this key is to determine the real QNetworkConfiguration that the
+ session is using. This key is different to \i ActiveConfiguration in that
+ this key may return an identifier for either a
+ \l {QNetworkConfiguration::ServiceNetwork}{service network} or a
+ \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations
+ whereas \i ActiveConfiguration always returns identifiers to
+ \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations.
+ \row
+ \o ConnectInBackground
+ \o Setting this property to \i true before calling \l open() implies that the connection attempt
+ is made but if no connection can be established, the user is not connsulted and asked to select
+ a suitable connection. This property is not set by default and support for it depends on the platform.
+ \endtable
+*/
+QVariant QNetworkSession::sessionProperty(const QString& key) const
+{
+ if (!d)
+ return QVariant();
+
+ if (!d->publicConfig.isValid())
+ return QVariant();
+
+ if (key == QLatin1String("ActiveConfiguration")) {
+ if (!d->isOpen)
+ return QString();
+ else
+ return d->activeConfig.identifier();
+ }
+
+ if (key == QLatin1String("UserChoiceConfiguration")) {
+ if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice)
+ return QString();
+
+ if (d->serviceConfig.isValid())
+ return d->serviceConfig.identifier();
+ else
+ return d->activeConfig.identifier();
+ }
+
+ return d->sessionProperty(key);
+}
+
+/*!
+ Sets the property \a value on the session. The property is identified using
+ \a key. Removing an already set property can be achieved by passing an
+ invalid QVariant.
+
+ Note that the \i UserChoiceConfiguration and \i ActiveConfiguration
+ properties are read only and cannot be changed using this method.
+*/
+void QNetworkSession::setSessionProperty(const QString& key, const QVariant& value)
+{
+ if (!d)
+ return;
+
+ if (key == QLatin1String("ActiveConfiguration") ||
+ key == QLatin1String("UserChoiceConfiguration")) {
+ return;
+ }
+
+ d->setSessionProperty(key, value);
+}
+
+/*!
+ Instructs the session to roam to the new access point. The old access point remains active
+ until the application calls accept().
+
+ The newConfigurationActivated() signal is emitted once roaming has been completed.
+
+ \sa accept()
+*/
+void QNetworkSession::migrate()
+{
+ if (d)
+ d->migrate();
+}
+
+/*!
+ This function indicates that the application does not wish to roam the session.
+
+ \sa migrate()
+*/
+void QNetworkSession::ignore()
+{
+ // Needed on at least Symbian platform: the roaming must be explicitly
+ // ignore()'d or migrate()'d
+ if (d)
+ d->ignore();
+}
+
+/*!
+ Instructs the session to permanently accept the new access point. Once this function
+ has been called the session may not return to the old access point.
+
+ The old access point may be closed in the process if there are no other network sessions for it.
+ Therefore any open socket that still uses the old access point
+ may become unusable and should be closed before completing the migration.
+*/
+void QNetworkSession::accept()
+{
+ if (d)
+ d->accept();
+}
+
+/*!
+ The new access point is not suitable for the application. By calling this function the
+ session returns to the previous access point/configuration. This action may invalidate
+ any socket that has been created via the not desired access point.
+
+ \sa accept()
+*/
+void QNetworkSession::reject()
+{
+ if (d)
+ d->reject();
+}
+
+
+/*!
+ Returns the amount of data sent in bytes; otherwise 0.
+
+ This field value includes the usage across all open network
+ sessions which use the same network interface.
+
+ If the session is based on a service network configuration the number of
+ sent bytes across all active member configurations are returned.
+
+ This function may not always be supported on all platforms and returns
+ 0. The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
+*/
+quint64 QNetworkSession::bytesWritten() const
+{
+ return d ? d->bytesWritten() : Q_UINT64_C(0);
+}
+
+/*!
+ Returns the amount of data received in bytes; otherwise 0.
+
+ This field value includes the usage across all open network
+ sessions which use the same network interface.
+
+ If the session is based on a service network configuration the number of
+ sent bytes across all active member configurations are returned.
+
+ This function may not always be supported on all platforms and returns
+ 0. The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
+*/
+quint64 QNetworkSession::bytesReceived() const
+{
+ return d ? d->bytesReceived() : Q_UINT64_C(0);
+}
+
+/*!
+ Returns the number of seconds that the session has been active.
+*/
+quint64 QNetworkSession::activeTime() const
+{
+ return d ? d->activeTime() : Q_UINT64_C(0);
+}
+
+/*!
+ \internal
+
+ This function is required to detect whether the client wants to control
+ the roaming process. If he connects to preferredConfigurationChanged() signal
+ he intends to influence it. Otherwise QNetworkSession always roams
+ without registering this session as a stakeholder in the roaming process.
+
+ For more details check the Forced vs ALR roaming section in the QNetworkSession
+ class description.
+*/
+void QNetworkSession::connectNotify(const char *signal)
+{
+ QObject::connectNotify(signal);
+ //check for preferredConfigurationChanged() signal connect notification
+ //This is not required on all platforms
+ if (!d)
+ return;
+
+ if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0)
+ d->setALREnabled(true);
+}
+
+/*!
+ \internal
+
+ This function is called when the client disconnects from the preferredConfigurationChanged()
+ signal.
+
+ \sa connectNotify()
+*/
+void QNetworkSession::disconnectNotify(const char *signal)
+{
+ QObject::disconnectNotify(signal);
+ //check for preferredConfigurationChanged() signal disconnect notification
+ //This is not required on all platforms
+ if (!d)
+ return;
+
+ if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0)
+ d->setALREnabled(false);
+}
+
+#include "moc_qnetworksession.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h
new file mode 100644
index 0000000000..18437f6c3e
--- /dev/null
+++ b/src/network/bearer/qnetworksession.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKSESSION_H
+#define QNETWORKSESSION_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtNetwork/qnetworkinterface.h>
+#include <QtCore/qvariant.h>
+#include <QtNetwork/qnetworkconfiguration.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Network)
+
+class QNetworkSessionPrivate;
+class Q_NETWORK_EXPORT QNetworkSession : public QObject
+{
+ Q_OBJECT
+public:
+ enum State {
+ Invalid = 0,
+ NotAvailable,
+ Connecting,
+ Connected,
+ Closing,
+ Disconnected,
+ Roaming
+ };
+
+ enum SessionError {
+ UnknownSessionError = 0,
+ SessionAbortedError,
+ RoamingError,
+ OperationNotSupportedError,
+ InvalidConfigurationError
+ };
+
+ QNetworkSession(const QNetworkConfiguration& connConfig, QObject* parent =0);
+ virtual ~QNetworkSession();
+
+ bool isOpen() const;
+ QNetworkConfiguration configuration() const;
+ QNetworkInterface interface() const;
+
+ State state() const;
+ SessionError error() const;
+ QString errorString() const;
+ QVariant sessionProperty(const QString& key) const;
+ void setSessionProperty(const QString& key, const QVariant& value);
+
+ quint64 bytesWritten() const;
+ quint64 bytesReceived() const;
+ quint64 activeTime() const;
+
+ bool waitForOpened(int msecs = 30000);
+
+public Q_SLOTS:
+ void open();
+ void close();
+ void stop();
+
+ //roaming related slots
+ void migrate();
+ void ignore();
+ void accept();
+ void reject();
+
+
+Q_SIGNALS:
+ void stateChanged(QNetworkSession::State);
+ void opened();
+ void closed();
+ void error(QNetworkSession::SessionError);
+ void preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless);
+ void newConfigurationActivated();
+
+protected:
+ virtual void connectNotify(const char *signal);
+ virtual void disconnectNotify(const char *signal);
+
+private:
+ QNetworkSessionPrivate* d;
+ friend class QNetworkSessionPrivate;
+ };
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QNETWORKSESSION_H
diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h
new file mode 100644
index 0000000000..76691b31fd
--- /dev/null
+++ b/src/network/bearer/qnetworksession_p.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKSESSIONPRIVATE_H
+#define QNETWORKSESSIONPRIVATE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworksession.h"
+#include "qnetworkconfiguration_p.h"
+
+#include <QNetworkInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q_NETWORK_EXPORT QNetworkSessionPrivate : public QObject
+{
+ Q_OBJECT
+
+ friend class QNetworkSession;
+
+public:
+ QNetworkSessionPrivate()
+ : state(QNetworkSession::Invalid), isOpen(false)
+ {
+ }
+
+ virtual ~QNetworkSessionPrivate()
+ {
+ }
+
+ //called by QNetworkSession constructor and ensures
+ //that the state is immediately updated (w/o actually opening
+ //a session). Also this function should take care of
+ //notification hooks to discover future state changes.
+ virtual void syncStateWithInterface() = 0;
+
+ virtual QNetworkInterface currentInterface() const = 0;
+ virtual QVariant sessionProperty(const QString& key) const = 0;
+ virtual void setSessionProperty(const QString& key, const QVariant& value) = 0;
+
+ virtual void open() = 0;
+ virtual void close() = 0;
+ virtual void stop() = 0;
+
+ virtual void setALREnabled(bool /*enabled*/) { }
+ virtual void migrate() = 0;
+ virtual void accept() = 0;
+ virtual void ignore() = 0;
+ virtual void reject() = 0;
+
+ virtual QString errorString() const = 0; //must return translated string
+ virtual QNetworkSession::SessionError error() const = 0;
+
+ virtual quint64 bytesWritten() const = 0;
+ virtual quint64 bytesReceived() const = 0;
+ virtual quint64 activeTime() const = 0;
+
+protected:
+ inline QNetworkConfigurationPrivatePointer privateConfiguration(const QNetworkConfiguration &config) const
+ {
+ return config.d;
+ }
+
+ inline void setPrivateConfiguration(QNetworkConfiguration &config,
+ QNetworkConfigurationPrivatePointer ptr) const
+ {
+ config.d = ptr;
+ }
+
+Q_SIGNALS:
+ //releases any pending waitForOpened() calls
+ void quitPendingWaitsForOpened();
+
+ void error(QNetworkSession::SessionError error);
+ void stateChanged(QNetworkSession::State state);
+ void closed();
+ void newConfigurationActivated();
+ void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless);
+
+protected:
+ // The config set on QNetworkSession.
+ QNetworkConfiguration publicConfig;
+
+ // If publicConfig is a ServiceNetwork this is a copy of publicConfig.
+ // If publicConfig is an UserChoice that is resolved to a ServiceNetwork this is the actual
+ // ServiceNetwork configuration.
+ QNetworkConfiguration serviceConfig;
+
+ // This is the actual active configuration currently in use by the session.
+ // Either a copy of publicConfig or one of serviceConfig.children().
+ QNetworkConfiguration activeConfig;
+
+ QNetworkSession::State state;
+ bool isOpen;
+
+ QNetworkSession *q;
+};
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKSESSIONPRIVATE_H
+
diff --git a/src/network/network.pro b/src/network/network.pro
index e890b94715..8582d8ad56 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -17,6 +17,7 @@ unix:QMAKE_PKGCONFIG_REQUIRES = QtCore
include(../qbase.pri)
include(access/access.pri)
+include(bearer/bearer.pri)
include(kernel/kernel.pri)
include(socket/socket.pri)
include(ssl/ssl.pri)
diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro
new file mode 100644
index 0000000000..7ba62b3870
--- /dev/null
+++ b/src/plugins/bearer/bearer.pro
@@ -0,0 +1,14 @@
+TEMPLATE = subdirs
+
+!maemo:contains(QT_CONFIG, dbus):contains(QT_CONFIG, networkmanager) {
+ SUBDIRS += networkmanager generic
+}
+#win32:SUBDIRS += nla
+win32:SUBDIRS += generic
+win32:!wince*:SUBDIRS += nativewifi
+macx:SUBDIRS += corewlan
+macx:SUBDIRS += generic
+symbian:SUBDIRS += symbian
+maemo6:contains(QT_CONFIG, dbus):SUBDIRS += icd
+
+isEmpty(SUBDIRS):SUBDIRS += generic
diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro
new file mode 100644
index 0000000000..50c72b2450
--- /dev/null
+++ b/src/plugins/bearer/corewlan/corewlan.pro
@@ -0,0 +1,24 @@
+TARGET = qcorewlanbearer
+include(../../qpluginbase.pri)
+
+QT += network
+LIBS += -framework Foundation -framework SystemConfiguration
+
+contains(QT_CONFIG, corewlan) {
+ isEmpty(QMAKE_MAC_SDK)|contains(QMAKE_MAC_SDK, "/Developer/SDKs/MacOSX10.6.sdk") {
+ LIBS += -framework CoreWLAN
+ DEFINES += MAC_SDK_10_6
+ }
+}
+
+HEADERS += qcorewlanengine.h \
+ ../qnetworksession_impl.h \
+ ../qbearerengine_impl.h
+
+SOURCES += main.cpp \
+ qcorewlanengine.mm \
+ ../qnetworksession_impl.cpp
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/corewlan/main.cpp b/src/plugins/bearer/corewlan/main.cpp
new file mode 100644
index 0000000000..5be8c0ee40
--- /dev/null
+++ b/src/plugins/bearer/corewlan/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcorewlanengine.h"
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCoreWlanEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QCoreWlanEnginePlugin();
+ ~QCoreWlanEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QCoreWlanEnginePlugin::QCoreWlanEnginePlugin()
+{
+}
+
+QCoreWlanEnginePlugin::~QCoreWlanEnginePlugin()
+{
+}
+
+QStringList QCoreWlanEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("corewlan");
+}
+
+QBearerEngine *QCoreWlanEnginePlugin::create(const QString &key) const
+{
+ if (key == QLatin1String("corewlan"))
+ return new QCoreWlanEngine;
+ else
+ return 0;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QCoreWlanEnginePlugin)
+Q_EXPORT_PLUGIN2(qcorewlanbearer, QCoreWlanEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h
new file mode 100644
index 0000000000..044b43313c
--- /dev/null
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 QCOREWLANENGINE_H
+#define QCOREWLANENGINE_H
+
+#include "../qbearerengine_impl.h"
+
+#include <QMap>
+#include <QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkConfigurationPrivate;
+
+class QCoreWlanEngine : public QBearerEngineImpl
+{
+ Q_OBJECT
+
+public:
+ QCoreWlanEngine(QObject *parent = 0);
+ ~QCoreWlanEngine();
+
+ QString getInterfaceFromId(const QString &id);
+ bool hasIdentifier(const QString &id);
+
+ QString bearerName(const QString &id);
+
+ void connectToId(const QString &id);
+ void disconnectFromId(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkSession::State sessionStateForId(const QString &id);
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+ bool getAllScInterfaces();
+
+private Q_SLOTS:
+ void doRequestUpdate();
+
+private:
+ bool isWifiReady(const QString &dev);
+ QMap<QString, QString> configurationInterface;
+ QTimer pollTimer;
+ QStringList scanForSsids(const QString &interfaceName);
+
+ bool isKnownSsid(const QString &interfaceName, const QString &ssid);
+ QList<QNetworkConfigurationPrivate *> foundConfigurations;
+
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
new file mode 100644
index 0000000000..a5384d1fe8
--- /dev/null
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -0,0 +1,553 @@
+/****************************************************************************
+**
+** 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 "qcorewlanengine.h"
+#include "../qnetworksession_impl.h"
+
+#include <QtNetwork/private/qnetworkconfiguration_p.h>
+
+#include <QtCore/qthread.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtCore/qdebug.h>
+
+#if defined(MAC_SDK_10_6) //not much functionality without this
+#include <CoreWLAN/CoreWLAN.h>
+#include <CoreWLAN/CWInterface.h>
+#include <CoreWLAN/CWNetwork.h>
+#include <CoreWLAN/CWNetwork.h>
+#endif
+
+#include <Foundation/NSEnumerator.h>
+#include <Foundation/NSKeyValueObserving.h>
+#include <Foundation/NSAutoreleasePool.h>
+
+#include <SystemConfiguration/SCNetworkConfiguration.h>
+QMap <QString, QString> networkInterfaces;
+
+QT_BEGIN_NAMESPACE
+
+inline QString cfstringRefToQstring(CFStringRef cfStringRef) {
+// return QString([cfStringRef UTF8String]);
+ QString retVal;
+ CFIndex maxLength = 2 * CFStringGetLength(cfStringRef) + 1/*zero term*/; // max UTF8
+ char *cstring = new char[maxLength];
+ if (CFStringGetCString(CFStringRef(cfStringRef), cstring, maxLength, kCFStringEncodingUTF8)) {
+ retVal = QString::fromUtf8(cstring);
+ }
+ delete[] cstring;
+ return retVal;
+}
+
+inline CFStringRef qstringToCFStringRef(const QString &string)
+{
+ return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(string.unicode()),
+ string.length());
+}
+
+inline NSString *qstringToNSString(const QString &qstr)
+{ return [reinterpret_cast<const NSString *>(qstringToCFStringRef(qstr)) autorelease]; }
+
+inline QString nsstringToQString(const NSString *nsstr)
+{ return cfstringRefToQstring(reinterpret_cast<const CFStringRef>(nsstr)); }
+
+inline QStringList nsarrayToQStringList(void *nsarray)
+{
+ QStringList result;
+ NSArray *array = static_cast<NSArray *>(nsarray);
+ for (NSUInteger i=0; i<[array count]; ++i)
+ result << nsstringToQString([array objectAtIndex:i]);
+ return result;
+}
+
+static QString qGetInterfaceType(const QString &interfaceString)
+{
+ return networkInterfaces.value(interfaceString, QLatin1String("Unknown"));
+}
+
+QCoreWlanEngine::QCoreWlanEngine(QObject *parent)
+: QBearerEngineImpl(parent)
+{
+ connect(&pollTimer, SIGNAL(timeout()), this, SLOT(doRequestUpdate()));
+ pollTimer.setInterval(10000);
+ doRequestUpdate();
+}
+
+QCoreWlanEngine::~QCoreWlanEngine()
+{
+ while (!foundConfigurations.isEmpty())
+ delete foundConfigurations.takeFirst();
+}
+
+QString QCoreWlanEngine::getInterfaceFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return configurationInterface.value(id);
+}
+
+bool QCoreWlanEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return configurationInterface.contains(id);
+}
+
+void QCoreWlanEngine::connectToId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QString interfaceString = getInterfaceFromId(id);
+
+ if(networkInterfaces.value(interfaceString) == "WLAN") {
+#if defined(MAC_SDK_10_6)
+ CWInterface *wifiInterface = [CWInterface interfaceWithName: qstringToNSString(interfaceString)];
+ CWConfiguration *userConfig = [ wifiInterface configuration];
+
+ NSSet *remNets = [userConfig rememberedNetworks]; //CWWirelessProfile
+
+ NSEnumerator *enumerator = [remNets objectEnumerator];
+ CWWirelessProfile *wProfile;
+ NSUInteger index=0;
+ CWNetwork *apNetwork;
+ NSDictionary *parametersDict;
+ NSArray* apArray;
+
+ CW8021XProfile *user8021XProfile;
+ NSError *err;
+ NSMutableDictionary *params;
+
+ while ((wProfile = [enumerator nextObject])) { //CWWirelessProfile
+
+ if(id == nsstringToQString([wProfile ssid])) {
+ user8021XProfile = nil;
+ user8021XProfile = [ wProfile user8021XProfile];
+
+ err = nil;
+ params = [NSMutableDictionary dictionaryWithCapacity:0];
+
+ if(user8021XProfile) {
+ [params setValue: user8021XProfile forKey:kCWAssocKey8021XProfile];
+ } else {
+ [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase];
+ }
+
+ parametersDict = nil;
+ apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]];
+
+ if(!err) {
+
+ for(uint row=0; row < [apArray count]; row++ ) {
+ apNetwork = [apArray objectAtIndex:row];
+ if([[apNetwork ssid] compare:[wProfile ssid]] == NSOrderedSame) {
+
+ bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
+
+ if(!result) {
+ qWarning() <<"ERROR"<< nsstringToQString([err localizedDescription ]);
+ emit connectionError(id, ConnectError);
+ } else {
+ [apNetwork release];
+ [autoreleasepool release];
+ return;
+ }
+ }
+ }
+ }
+ }
+ index++;
+ }
+ [apNetwork release];
+
+ emit connectionError(id, InterfaceLookupError);
+#endif
+ } else {
+ // not wifi
+ }
+ emit connectionError(id, OperationNotSupported);
+ [autoreleasepool release];
+}
+
+void QCoreWlanEngine::disconnectFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QString interfaceString = getInterfaceFromId(id);
+ if(networkInterfaces.value(getInterfaceFromId(id)) == "WLAN") { //wifi only for now
+#if defined(MAC_SDK_10_6)
+ NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ CWInterface *wifiInterface = [CWInterface interfaceWithName: qstringToNSString(interfaceString)];
+ [wifiInterface disassociate];
+ if([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) {
+ emit connectionError(id, DisconnectionError);
+ }
+ [autoreleasepool release];
+ return;
+#endif
+ } else {
+
+ }
+ emit connectionError(id, OperationNotSupported);
+}
+
+void QCoreWlanEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ pollTimer.stop();
+ QTimer::singleShot(0, this, SLOT(doRequestUpdate()));
+}
+
+void QCoreWlanEngine::doRequestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ getAllScInterfaces();
+
+ QStringList previous = accessPointConfigurations.keys();
+
+ QMapIterator<QString, QString> i(networkInterfaces);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value() == QLatin1String("WLAN")) {
+ QStringList added = scanForSsids(i.key());
+ while (!added.isEmpty()) {
+ previous.removeAll(added.takeFirst());
+ }
+ }
+
+ QNetworkInterface interface = QNetworkInterface::interfaceFromName(i.key());
+
+ if (!interface.isValid())
+ continue;
+
+ uint identifier;
+ if (interface.index())
+ identifier = qHash(QLatin1String("corewlan:") + QString::number(interface.index()));
+ else
+ identifier = qHash(QLatin1String("corewlan:") + interface.hardwareAddress());
+
+ const QString id = QString::number(identifier);
+
+ previous.removeAll(id);
+
+ QString name = interface.humanReadableName();
+ if (name.isEmpty())
+ name = interface.name();
+
+ QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+
+ if (interface.flags() && QNetworkInterface::IsRunning)
+ state = QNetworkConfiguration::Defined;
+
+ if (!interface.addressEntries().isEmpty())
+ state = QNetworkConfiguration::Active;
+
+ if (accessPointConfigurations.contains(id)) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ bool changed = false;
+
+ if (!ptr->isValid) {
+ ptr->isValid = true;
+ changed = true;
+ }
+
+ if (ptr->name != name) {
+ ptr->name = name;
+ changed = true;
+ }
+
+ if (ptr->id != id) {
+ ptr->id = id;
+ changed = true;
+ }
+
+ if (ptr->state != state) {
+ ptr->state = state;
+ changed = true;
+ }
+
+ if (changed)
+ emit configurationChanged(ptr);
+ } else {
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+
+ ptr->name = name;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->state = state;
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->bearer = qGetInterfaceType(interface.name());
+
+ accessPointConfigurations.insert(id, ptr);
+ configurationInterface.insert(id, interface.name());
+
+ emit configurationAdded(ptr);
+ }
+ }
+
+ while (!previous.isEmpty()) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst());
+
+ configurationInterface.remove(ptr->id);
+ emit configurationRemoved(ptr);
+ }
+
+ pollTimer.start();
+
+ emit updateCompleted();
+}
+
+QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
+{
+ QMutexLocker locker(&mutex);
+
+ QStringList found;
+
+#if defined(MAC_SDK_10_6)
+ NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+
+ CWInterface *currentInterface = [CWInterface interfaceWithName:qstringToNSString(interfaceName)];
+ NSError *err = nil;
+ NSDictionary *parametersDict = nil;
+ NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
+
+ CWNetwork *apNetwork;
+ if (!err) {
+ for(uint row=0; row < [apArray count]; row++ ) {
+ NSAutoreleasePool *looppool = [[NSAutoreleasePool alloc] init];
+
+ apNetwork = [apArray objectAtIndex:row];
+
+ const QString networkSsid = nsstringToQString([apNetwork ssid]);
+
+ const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
+ found.append(id);
+
+ QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+
+ if ([currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if (networkSsid == nsstringToQString([currentInterface ssid]))
+ state = QNetworkConfiguration::Active;
+ } else {
+ if (isKnownSsid(interfaceName, networkSsid))
+ state = QNetworkConfiguration::Discovered;
+ else
+ state = QNetworkConfiguration::Defined;
+ }
+
+ if (accessPointConfigurations.contains(id)) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ bool changed = false;
+
+ if (!ptr->isValid) {
+ ptr->isValid = true;
+ changed = true;
+ }
+
+ if (ptr->name != networkSsid) {
+ ptr->name = networkSsid;
+ changed = true;
+ }
+
+ if (ptr->id != id) {
+ ptr->id = id;
+ changed = true;
+ }
+
+ if (ptr->state != state) {
+ ptr->state = state;
+ changed = true;
+ }
+
+ if (changed)
+ emit configurationChanged(ptr);
+ } else {
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+
+ ptr->name = networkSsid;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->state = state;
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->bearer = QLatin1String("WLAN");
+
+ accessPointConfigurations.insert(id, ptr);
+ configurationInterface.insert(id, interfaceName);
+
+ emit configurationAdded(ptr);
+ }
+ [looppool release];
+ }
+ } else {
+ qWarning() << "ERROR scanning for ssids" << nsstringToQString([err localizedDescription])
+ <<nsstringToQString([err domain]);
+ }
+
+ [autoreleasepool drain];
+#else
+ Q_UNUSED(interfaceName);
+#endif
+ return found;
+}
+
+bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
+{
+ QMutexLocker locker(&mutex);
+
+#if defined(MAC_SDK_10_6)
+ CWInterface *defaultInterface = [CWInterface interfaceWithName: qstringToNSString(wifiDeviceName)];
+ if([defaultInterface power])
+ return true;
+#else
+ Q_UNUSED(wifiDeviceName);
+#endif
+ return false;
+}
+
+bool QCoreWlanEngine::isKnownSsid(const QString &interfaceName, const QString &ssid)
+{
+ QMutexLocker locker(&mutex);
+
+#if defined(MAC_SDK_10_6)
+ CWInterface *wifiInterface = [CWInterface interfaceWithName: qstringToNSString(interfaceName)];
+ CWConfiguration *userConfig = [wifiInterface configuration];
+ NSSet *remNets = [userConfig rememberedNetworks];
+ for (CWWirelessProfile *wProfile in remNets) {
+ if(ssid == nsstringToQString([wProfile ssid]))
+ return true;
+ }
+#else
+ Q_UNUSED(interfaceName);
+ Q_UNUSED(ssid);
+#endif
+ return false;
+}
+
+bool QCoreWlanEngine::getAllScInterfaces()
+{
+ QMutexLocker locker(&mutex);
+
+ networkInterfaces.clear();
+ NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+
+ CFArrayRef interfaces = SCNetworkInterfaceCopyAll();
+ if (interfaces != NULL) {
+ CFIndex interfaceCount;
+ CFIndex interfaceIndex;
+ interfaceCount = CFArrayGetCount(interfaces);
+ for (interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) {
+ NSAutoreleasePool *looppool = [[NSAutoreleasePool alloc] init];
+
+ CFStringRef bsdName;
+ CFTypeRef thisInterface = CFArrayGetValueAtIndex(interfaces, interfaceIndex);
+ bsdName = SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)thisInterface);
+ QString interfaceName = cfstringRefToQstring(bsdName);
+ QString typeStr;
+ CFStringRef type = SCNetworkInterfaceGetInterfaceType((SCNetworkInterfaceRef)thisInterface);
+ if ( CFEqual(type, kSCNetworkInterfaceTypeIEEE80211)) {
+ typeStr = "WLAN";
+// } else if (CFEqual(type, kSCNetworkInterfaceTypeBluetooth)) {
+// typeStr = "Bluetooth";
+ } else if(CFEqual(type, kSCNetworkInterfaceTypeEthernet)) {
+ typeStr = "Ethernet";
+ } else if(CFEqual(type, kSCNetworkInterfaceTypeFireWire)) {
+ typeStr = "Ethernet"; //ok a bit fudged
+ }
+ if(!networkInterfaces.contains(interfaceName) && !typeStr.isEmpty()) {
+ networkInterfaces.insert(interfaceName,typeStr);
+ }
+ [looppool release];
+ }
+ }
+ CFRelease(interfaces);
+
+ [autoreleasepool drain];
+ return true;
+}
+
+QNetworkSession::State QCoreWlanEngine::sessionStateForId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ if (!ptr)
+ return QNetworkSession::Invalid;
+
+ if (!ptr->isValid) {
+ return QNetworkSession::Invalid;
+ } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ return QNetworkSession::Connected;
+ } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ return QNetworkSession::Disconnected;
+ } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+ return QNetworkSession::NotAvailable;
+ } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
+ QNetworkConfiguration::Undefined) {
+ return QNetworkSession::NotAvailable;
+ }
+
+ return QNetworkSession::Invalid;
+}
+
+QNetworkConfigurationManager::Capabilities QCoreWlanEngine::capabilities() const
+{
+ return QNetworkConfigurationManager::ForcedRoaming;
+}
+
+QNetworkSessionPrivate *QCoreWlanEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl;
+}
+
+QNetworkConfigurationPrivatePointer QCoreWlanEngine::defaultConfiguration()
+{
+ return QNetworkConfigurationPrivatePointer();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/generic/generic.pro b/src/plugins/bearer/generic/generic.pro
new file mode 100644
index 0000000000..1d141fd732
--- /dev/null
+++ b/src/plugins/bearer/generic/generic.pro
@@ -0,0 +1,16 @@
+TARGET = qgenericbearer
+include(../../qpluginbase.pri)
+
+QT += network
+
+HEADERS += qgenericengine.h \
+ ../qnetworksession_impl.h \
+ ../qbearerengine_impl.h \
+ ../platformdefs_win.h
+SOURCES += qgenericengine.cpp \
+ ../qnetworksession_impl.cpp \
+ main.cpp
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/generic/main.cpp b/src/plugins/bearer/generic/main.cpp
new file mode 100644
index 0000000000..ba85d9389d
--- /dev/null
+++ b/src/plugins/bearer/generic/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgenericengine.h"
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGenericEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QGenericEnginePlugin();
+ ~QGenericEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QGenericEnginePlugin::QGenericEnginePlugin()
+{
+}
+
+QGenericEnginePlugin::~QGenericEnginePlugin()
+{
+}
+
+QStringList QGenericEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("generic");
+}
+
+QBearerEngine *QGenericEnginePlugin::create(const QString &key) const
+{
+ if (key == QLatin1String("generic"))
+ return new QGenericEngine;
+ else
+ return 0;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QGenericEnginePlugin)
+Q_EXPORT_PLUGIN2(qgenericbearer, QGenericEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
new file mode 100644
index 0000000000..a95b14bbf9
--- /dev/null
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** 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 "qgenericengine.h"
+#include "../qnetworksession_impl.h"
+
+#include <QtNetwork/private/qnetworkconfiguration_p.h>
+
+#include <QtCore/qthread.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtCore/qdebug.h>
+
+#ifdef Q_OS_WIN
+#include "../platformdefs_win.h"
+#endif
+
+#ifdef Q_OS_LINUX
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#endif
+
+
+static QString qGetInterfaceType(const QString &interface)
+{
+#ifdef Q_OS_WIN32
+ unsigned long oid;
+ DWORD bytesWritten;
+
+ NDIS_MEDIUM medium;
+ NDIS_PHYSICAL_MEDIUM physicalMedium;
+
+ HANDLE handle = CreateFile((TCHAR *)QString("\\\\.\\%1").arg(interface).utf16(), 0,
+ FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if (handle == INVALID_HANDLE_VALUE)
+ return QLatin1String("Unknown");
+
+ oid = OID_GEN_MEDIA_SUPPORTED;
+ bytesWritten = 0;
+ bool result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid),
+ &medium, sizeof(medium), &bytesWritten, 0);
+ if (!result) {
+ CloseHandle(handle);
+ return QLatin1String("Unknown");
+ }
+
+ oid = OID_GEN_PHYSICAL_MEDIUM;
+ bytesWritten = 0;
+ result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid),
+ &physicalMedium, sizeof(physicalMedium), &bytesWritten, 0);
+ if (!result) {
+ CloseHandle(handle);
+
+ if (medium == NdisMedium802_3)
+ return QLatin1String("Ethernet");
+ else
+ return QLatin1String("Unknown");
+ }
+
+ CloseHandle(handle);
+
+ if (medium == NdisMedium802_3) {
+ switch (physicalMedium) {
+ case NdisPhysicalMediumWirelessLan:
+ return QLatin1String("WLAN");
+ case NdisPhysicalMediumBluetooth:
+ return QLatin1String("Bluetooth");
+ case NdisPhysicalMediumWiMax:
+ return QLatin1String("WiMAX");
+ default:
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Physical Medium" << physicalMedium;
+#endif
+ return QLatin1String("Ethernet");
+ }
+ }
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << medium << physicalMedium;
+#endif
+#elif defined(Q_OS_LINUX)
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ifreq request;
+ strncpy(request.ifr_name, interface.toLocal8Bit().data(), sizeof(request.ifr_name));
+ if (ioctl(sock, SIOCGIFHWADDR, &request) >= 0) {
+ switch (request.ifr_hwaddr.sa_family) {
+ case ARPHRD_ETHER:
+ return QLatin1String("Ethernet");
+ }
+ }
+
+ close(sock);
+#else
+ Q_UNUSED(interface);
+#endif
+
+ return QLatin1String("Unknown");
+}
+
+QGenericEngine::QGenericEngine(QObject *parent)
+: QBearerEngineImpl(parent)
+{
+ connect(&pollTimer, SIGNAL(timeout()), this, SLOT(doRequestUpdate()));
+ pollTimer.setInterval(10000);
+ doRequestUpdate();
+}
+
+QGenericEngine::~QGenericEngine()
+{
+}
+
+QString QGenericEngine::getInterfaceFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return configurationInterface.value(id);
+}
+
+bool QGenericEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return configurationInterface.contains(id);
+}
+
+void QGenericEngine::connectToId(const QString &id)
+{
+ emit connectionError(id, OperationNotSupported);
+}
+
+void QGenericEngine::disconnectFromId(const QString &id)
+{
+ emit connectionError(id, OperationNotSupported);
+}
+
+void QGenericEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ pollTimer.stop();
+ QTimer::singleShot(0, this, SLOT(doRequestUpdate()));
+}
+
+void QGenericEngine::doRequestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ // Immediately after connecting with a wireless access point
+ // QNetworkInterface::allInterfaces() will sometimes return an empty list. Calling it again a
+ // second time results in a non-empty list. If we loose interfaces we will end up removing
+ // network configurations which will break current sessions.
+ QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
+ if (interfaces.isEmpty())
+ interfaces = QNetworkInterface::allInterfaces();
+
+ QStringList previous = accessPointConfigurations.keys();
+
+ // create configuration for each interface
+ while (!interfaces.isEmpty()) {
+ QNetworkInterface interface = interfaces.takeFirst();
+
+ if (!interface.isValid())
+ continue;
+
+ // ignore loopback interface
+ if (interface.flags() & QNetworkInterface::IsLoopBack)
+ continue;
+
+ // ignore WLAN interface handled in seperate engine
+ if (qGetInterfaceType(interface.name()) == QLatin1String("WLAN"))
+ continue;
+
+ uint identifier;
+ if (interface.index())
+ identifier = qHash(QLatin1String("generic:") + QString::number(interface.index()));
+ else
+ identifier = qHash(QLatin1String("generic:") + interface.hardwareAddress());
+
+ const QString id = QString::number(identifier);
+
+ previous.removeAll(id);
+
+ QString name = interface.humanReadableName();
+ if (name.isEmpty())
+ name = interface.name();
+
+ QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Discovered;
+ if (interface.flags() & QNetworkInterface::IsUp)
+ state |= QNetworkConfiguration::Active;
+
+ if (accessPointConfigurations.contains(id)) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ bool changed = false;
+
+ if (!ptr->isValid) {
+ ptr->isValid = true;
+ changed = true;
+ }
+
+ if (ptr->name != name) {
+ ptr->name = name;
+ changed = true;
+ }
+
+ if (ptr->id != id) {
+ ptr->id = id;
+ changed = true;
+ }
+
+ if (ptr->state != state) {
+ ptr->state = state;
+ changed = true;
+ }
+
+ if (changed)
+ emit configurationChanged(ptr);
+ } else {
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+
+ ptr->name = name;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->state = state;
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->bearer = qGetInterfaceType(interface.name());
+
+ accessPointConfigurations.insert(id, ptr);
+ configurationInterface.insert(id, interface.name());
+
+ emit configurationAdded(ptr);
+ }
+ }
+
+ while (!previous.isEmpty()) {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.take(previous.takeFirst());
+
+ configurationInterface.remove(ptr->id);
+ emit configurationRemoved(ptr);
+ }
+
+ pollTimer.start();
+
+ emit updateCompleted();
+}
+
+QNetworkSession::State QGenericEngine::sessionStateForId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ if (!ptr)
+ return QNetworkSession::Invalid;
+
+ if (!ptr->isValid) {
+ return QNetworkSession::Invalid;
+ } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ return QNetworkSession::Connected;
+ } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ return QNetworkSession::Disconnected;
+ } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+ return QNetworkSession::NotAvailable;
+ } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
+ QNetworkConfiguration::Undefined) {
+ return QNetworkSession::NotAvailable;
+ }
+
+ return QNetworkSession::Invalid;
+}
+
+QNetworkConfigurationManager::Capabilities QGenericEngine::capabilities() const
+{
+ return QNetworkConfigurationManager::ForcedRoaming;
+}
+
+QNetworkSessionPrivate *QGenericEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl;
+}
+
+QNetworkConfigurationPrivatePointer QGenericEngine::defaultConfiguration()
+{
+ return QNetworkConfigurationPrivatePointer();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h
new file mode 100644
index 0000000000..cd9a976ce9
--- /dev/null
+++ b/src/plugins/bearer/generic/qgenericengine.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QGENERICENGINE_H
+#define QGENERICENGINE_H
+
+#include "../qbearerengine_impl.h"
+
+#include <QMap>
+#include <QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkConfigurationPrivate;
+class QNetworkSessionPrivate;
+
+class QGenericEngine : public QBearerEngineImpl
+{
+ Q_OBJECT
+
+public:
+ QGenericEngine(QObject *parent = 0);
+ ~QGenericEngine();
+
+ QString getInterfaceFromId(const QString &id);
+ bool hasIdentifier(const QString &id);
+
+ QString bearerName(const QString &id);
+
+ void connectToId(const QString &id);
+ void disconnectFromId(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkSession::State sessionStateForId(const QString &id);
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+private Q_SLOTS:
+ void doRequestUpdate();
+
+private:
+ QMap<QString, QString> configurationInterface;
+ QTimer pollTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/plugins/bearer/icd/icd.pro b/src/plugins/bearer/icd/icd.pro
new file mode 100644
index 0000000000..5eaf5af458
--- /dev/null
+++ b/src/plugins/bearer/icd/icd.pro
@@ -0,0 +1,22 @@
+TARGET = qicdbearer
+include(../../qpluginbase.pri)
+
+QT += network dbus
+
+CONFIG += link_pkgconfig
+PKGCONFIG += glib-2.0 dbus-glib-1 gconf-2.0 osso-ic conninet
+
+HEADERS += qicdengine.h \
+ monitor.h \
+ qnetworksession_impl.h
+
+SOURCES += main.cpp \
+ qicdengine.cpp \
+ monitor.cpp \
+ qnetworksession_impl.cpp
+
+#DEFINES += BEARER_MANAGEMENT_DEBUG
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/icd/main.cpp b/src/plugins/bearer/icd/main.cpp
new file mode 100644
index 0000000000..ad1a918644
--- /dev/null
+++ b/src/plugins/bearer/icd/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qicdengine.h"
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIcdEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QIcdEnginePlugin();
+ ~QIcdEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QIcdEnginePlugin::QIcdEnginePlugin()
+{
+}
+
+QIcdEnginePlugin::~QIcdEnginePlugin()
+{
+}
+
+QStringList QIcdEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("icd");
+}
+
+QBearerEngine *QIcdEnginePlugin::create(const QString &key) const
+{
+ if (key == QLatin1String("icd"))
+ return new QIcdEngine;
+ else
+ return 0;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QIcdEnginePlugin)
+Q_EXPORT_PLUGIN2(qicdbearer, QIcdEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/icd/monitor.cpp b/src/plugins/bearer/icd/monitor.cpp
new file mode 100644
index 0000000000..0ff45d2e36
--- /dev/null
+++ b/src/plugins/bearer/icd/monitor.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "monitor.h"
+#include "qicdengine.h"
+
+#include <wlancond.h>
+#include <libicd-network-wlan-dev.h>
+#include <maemo_icd.h>
+#include <iapconf.h>
+
+#define IAP "/system/osso/connectivity/IAP"
+
+static int iap_prefix_len;
+
+/* Notify func that is called when IAP is added or deleted */
+void notify_iap(GConfClient *, guint, GConfEntry *entry, gpointer user_data)
+{
+ const char *key = gconf_entry_get_key(entry);
+ if (key && g_str_has_prefix(key, IAP)) {
+ IapMonitor *ptr = (IapMonitor *)user_data;
+ if (gconf_entry_get_value(entry)) {
+ ptr->iapAdded(key, entry);
+ } else {
+ ptr->iapDeleted(key, entry);
+ }
+ }
+}
+
+
+void IapMonitor::setup(QIcdEngine *d_ptr)
+{
+ if (first_call) {
+ d = d_ptr;
+ iap_prefix_len = strlen(IAP);
+ iap = new Maemo::IAPMonitor(notify_iap, (gpointer)this);
+ first_call = false;
+ }
+}
+
+
+void IapMonitor::cleanup()
+{
+ if (!first_call) {
+ delete iap;
+ timers.removeAll();
+ first_call = true;
+ }
+}
+
+
+void IapMonitor::iapAdded(const char *key, GConfEntry * /*entry*/)
+{
+ //qDebug("Notify called for added element: %s=%s",
+ // gconf_entry_get_key(entry), gconf_value_to_string(gconf_entry_get_value(entry)));
+
+ /* We cannot know when the IAP is fully added to gconf, so a timer is
+ * installed instead. When the timer expires we hope that IAP is added ok.
+ */
+ QString iap_id = QString(key + iap_prefix_len + 1).section('/',0,0);
+ timers.add(iap_id, d);
+}
+
+
+void IapMonitor::iapDeleted(const char *key, GConfEntry * /*entry*/)
+{
+ //qDebug("Notify called for deleted element: %s", gconf_entry_get_key(entry));
+
+ /* We are only interested in IAP deletions so we skip the config entries
+ */
+ if (strstr(key + iap_prefix_len + 1, "/")) {
+ //qDebug("Deleting IAP config %s", key+iap_prefix_len);
+ return;
+ }
+
+ QString iap_id = key + iap_prefix_len + 1;
+ d->deleteConfiguration(iap_id);
+}
diff --git a/src/plugins/bearer/icd/monitor.h b/src/plugins/bearer/icd/monitor.h
new file mode 100644
index 0000000000..82b0f36d1d
--- /dev/null
+++ b/src/plugins/bearer/icd/monitor.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MONITOR_H
+#define MONITOR_H
+
+#include <QtCore/qhash.h>
+#include <QtCore/qtimer.h>
+
+#include <gconf/gconf.h>
+#include <gconf/gconf-client.h>
+
+#include <iapmonitor.h>
+
+class QIcdEngine;
+
+/* The IapAddTimer is a helper class that makes sure we update
+ * the configuration only after all gconf additions to certain
+ * iap are finished (after a certain timeout)
+ */
+class _IapAddTimer : public QObject
+{
+ Q_OBJECT
+
+public:
+ _IapAddTimer() {}
+ ~_IapAddTimer()
+ {
+ if (timer.isActive()) {
+ QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.stop();
+ }
+ }
+
+ void add(QString& iap_id, QIcdEngine *d);
+
+ QString iap_id;
+ QTimer timer;
+ QIcdEngine *d;
+
+public Q_SLOTS:
+ void timeout();
+};
+
+class IapAddTimer {
+ QHash<QString, _IapAddTimer* > timers;
+
+public:
+ IapAddTimer() {}
+ ~IapAddTimer() {}
+
+ void add(QString& iap_id, QIcdEngine *d);
+ void del(QString& iap_id);
+ void removeAll();
+};
+
+class IapMonitor
+{
+public:
+ IapMonitor() : first_call(true) { }
+ friend void notify_iap(GConfClient *, guint,
+ GConfEntry *entry, gpointer user_data);
+
+ void setup(QIcdEngine *d);
+ void cleanup();
+
+private:
+ bool first_call;
+
+ void iapAdded(const char *key, GConfEntry *entry);
+ void iapDeleted(const char *key, GConfEntry *entry);
+
+ Maemo::IAPMonitor *iap;
+ QIcdEngine *d;
+ IapAddTimer timers;
+};
+
+#endif // MONITOR_H
diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp
new file mode 100644
index 0000000000..f10042a611
--- /dev/null
+++ b/src/plugins/bearer/icd/qicdengine.cpp
@@ -0,0 +1,426 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qicdengine.h"
+#include "monitor.h"
+#include "qnetworksession_impl.h"
+
+#include <libicd-network-wlan-dev.h>
+#include <maemo_icd.h>
+#include <iapconf.h>
+
+QT_BEGIN_NAMESPACE
+
+IcdNetworkConfigurationPrivate::IcdNetworkConfigurationPrivate()
+: network_attrs(0), service_attrs(0)
+{
+}
+
+IcdNetworkConfigurationPrivate::~IcdNetworkConfigurationPrivate()
+{
+}
+
+QString IcdNetworkConfigurationPrivate::bearerName() const
+{
+ if (iap_type == QLatin1String("WLAN_INFRA") ||
+ iap_type == QLatin1String("WLAN_ADHOC")) {
+ return QLatin1String("WLAN");
+ } else if (iap_type == QLatin1String("GPRS")) {
+ return QLatin1String("HSPA");
+ } else {
+ return iap_type;
+ }
+}
+
+static inline QString network_attrs_to_security(uint network_attrs)
+{
+ uint cap = 0;
+ nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */
+ if (cap & WLANCOND_OPEN)
+ return "NONE";
+ else if (cap & WLANCOND_WEP)
+ return "WEP";
+ else if (cap & WLANCOND_WPA_PSK)
+ return "WPA_PSK";
+ else if (cap & WLANCOND_WPA_EAP)
+ return "WPA_EAP";
+ return "";
+}
+
+QIcdEngine::QIcdEngine(QObject *parent)
+: QBearerEngine(parent), iapMonitor(new IapMonitor)
+{
+ /* Turn on IAP monitoring */
+ iapMonitor->setup(this);
+
+ doRequestUpdate();
+}
+
+QIcdEngine::~QIcdEngine()
+{
+}
+
+bool QIcdEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return accessPointConfigurations.contains(id) ||
+ snapConfigurations.contains(id) ||
+ userChoiceConfigurations.contains(id);
+}
+
+void QIcdEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ QTimer::singleShot(0, this, SLOT(doRequestUpdate()));
+}
+
+static uint32_t getNetworkAttrs(bool is_iap_id,
+ QString& iap_id,
+ QString& iap_type,
+ QString security_method)
+{
+ guint network_attr = 0;
+ dbus_uint32_t cap = 0;
+
+ if (iap_type == "WLAN_INFRA")
+ cap |= WLANCOND_INFRA;
+ else if (iap_type == "WLAN_ADHOC")
+ cap |= WLANCOND_ADHOC;
+
+ if (security_method.isEmpty() && (cap & (WLANCOND_INFRA | WLANCOND_ADHOC))) {
+ Maemo::IAPConf saved_ap(iap_id);
+ security_method = saved_ap.value("wlan_security").toString();
+ }
+
+ if (!security_method.isEmpty()) {
+ if (security_method == "WEP")
+ cap |= WLANCOND_WEP;
+ else if (security_method == "WPA_PSK")
+ cap |= WLANCOND_WPA_PSK;
+ else if (security_method == "WPA_EAP")
+ cap |= WLANCOND_WPA_EAP;
+ else if (security_method == "NONE")
+ cap |= WLANCOND_OPEN;
+
+ if (cap & (WLANCOND_WPA_PSK | WLANCOND_WPA_EAP)) {
+ Maemo::IAPConf saved_iap(iap_id);
+ bool wpa2_only = saved_iap.value("EAP_wpa2_only_mode").toBool();
+ if (wpa2_only) {
+ cap |= WLANCOND_WPA2;
+ }
+ }
+ }
+
+ cap2nwattr(cap, &network_attr);
+ if (is_iap_id)
+ network_attr |= ICD_NW_ATTR_IAPNAME;
+
+ return (uint32_t)network_attr;
+}
+
+void QIcdEngine::doRequestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ QStringList previous = accessPointConfigurations.keys();
+
+ /* All the scanned access points */
+ QList<Maemo::IcdScanResult> scanned;
+
+ /* We create a default configuration which is a pseudo config */
+ if (!userChoiceConfigurations.contains(OSSO_IAP_ANY)) {
+ QNetworkConfigurationPrivatePointer ptr(new IcdNetworkConfigurationPrivate);
+
+ ptr->name = QLatin1String("UserChoice");
+ ptr->state = QNetworkConfiguration::Discovered;
+ ptr->isValid = true;
+ ptr->id = OSSO_IAP_ANY;
+ ptr->type = QNetworkConfiguration::UserChoice;
+ ptr->purpose = QNetworkConfiguration::UnknownPurpose;
+ ptr->roamingSupported = false;
+
+ userChoiceConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+ }
+
+ /* We return currently configured IAPs in the first run and do the WLAN
+ * scan in subsequent runs.
+ */
+ QList<QString> all_iaps;
+ Maemo::IAPConf::getAll(all_iaps);
+
+ foreach (QString escaped_iap_id, all_iaps) {
+ QByteArray ssid;
+
+ /* The key that is returned by getAll() needs to be unescaped */
+ gchar *unescaped_id = gconf_unescape_key(escaped_iap_id.toUtf8().data(), -1);
+ QString iap_id = QString((char *)unescaped_id);
+ g_free(unescaped_id);
+
+ previous.removeAll(iap_id);
+
+ Maemo::IAPConf saved_ap(iap_id);
+ bool is_temporary = saved_ap.value("temporary").toBool();
+ if (is_temporary) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "IAP" << iap_id << "is temporary, skipping it.";
+#endif
+ continue;
+ }
+
+ QString iap_type = saved_ap.value("type").toString();
+ if (iap_type.startsWith("WLAN")) {
+ ssid = saved_ap.value("wlan_ssid").toByteArray();
+ if (ssid.isEmpty()) {
+ qWarning() << "Cannot get ssid for" << iap_id;
+ continue;
+ }
+
+ QString security_method = saved_ap.value("wlan_security").toString();
+ } else if (iap_type.isEmpty()) {
+ qWarning() << "IAP" << iap_id << "network type is not set! Skipping it";
+ continue;
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "IAP" << iap_id << "network type is" << iap_type;
+#endif
+ ssid.clear();
+ }
+
+ if (!accessPointConfigurations.contains(iap_id)) {
+ IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate;
+
+ cpPriv->name = saved_ap.value("name").toString();
+ if (cpPriv->name.isEmpty())
+ if (!ssid.isEmpty() && ssid.size() > 0)
+ cpPriv->name = ssid.data();
+ else
+ cpPriv->name = iap_id;
+ cpPriv->isValid = true;
+ cpPriv->id = iap_id;
+ cpPriv->network_id = ssid;
+ cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString());
+ cpPriv->iap_type = iap_type;
+ cpPriv->service_id = saved_ap.value("service_id").toString();
+ cpPriv->service_type = saved_ap.value("service_type").toString();
+ cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
+ cpPriv->state = QNetworkConfiguration::Defined;
+
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ accessPointConfigurations.insert(iap_id, ptr);
+ emit configurationAdded(ptr);
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug("IAP: %s, name: %s, ssid: %s, added to known list",
+ iap_id.toAscii().data(), ptr->name.toAscii().data(),
+ !ssid.isEmpty() ? ssid.data() : "-");
+#endif
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug("IAP: %s, ssid: %s, already exists in the known list",
+ iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-");
+#endif
+ }
+ }
+
+ if (sender()) {
+ QStringList scannedNetworkTypes;
+ QStringList networkTypesToScan;
+ QString error;
+ Maemo::Icd icd(ICD_SHORT_SCAN_TIMEOUT);
+
+ scannedNetworkTypes = icd.scan(ICD_SCAN_REQUEST_ACTIVE,
+ networkTypesToScan,
+ scanned,
+ error);
+ if (!error.isEmpty()) {
+ qWarning() << "Network scanning failed" << error;
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ if (!scanned.isEmpty())
+ qDebug() << "Scan returned" << scanned.size() << "networks";
+ else
+ qDebug() << "Scan returned nothing.";
+#endif
+ }
+ }
+
+ /* This is skipped in the first update as scanned size is zero */
+ if (!scanned.isEmpty()) {
+ for (int i=0; i<scanned.size(); ++i) {
+ const Maemo::IcdScanResult ap = scanned.at(i);
+
+ QByteArray scanned_ssid = ap.scan.network_id;
+
+ if (ap.scan.network_attrs & ICD_NW_ATTR_IAPNAME) {
+ /* The network_id is IAP id, so the IAP is a known one */
+ QString iapid = ap.scan.network_id.data();
+
+ previous.removeAll(iapid);
+
+ if (accessPointConfigurations.contains(iapid)) {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.value(iapid);
+
+ bool changed = false;
+
+ if (!ptr->isValid) {
+ ptr->isValid = true;
+ changed = true;
+ }
+
+ if (ptr->state != QNetworkConfiguration::Discovered) {
+ ptr->state = QNetworkConfiguration::Discovered;
+ changed = true;
+ }
+
+ toIcdConfig(ptr)->network_attrs = ap.scan.network_attrs;
+ toIcdConfig(ptr)->service_id = ap.scan.service_id;
+ toIcdConfig(ptr)->service_type = ap.scan.service_type;
+ toIcdConfig(ptr)->service_attrs = ap.scan.service_attrs;
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug("IAP: %s, ssid: %s, discovered",
+ iapid.toAscii().data(), scanned_ssid.data());
+#endif
+
+ if (changed)
+ emit configurationChanged(ptr);
+
+ if (!ap.scan.network_type.startsWith("WLAN"))
+ continue; // not a wlan AP
+ }
+ } else {
+ IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate;
+
+ QString hrs = scanned_ssid.data();
+
+ cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name;
+ cpPriv->isValid = true;
+ // Note: id is now ssid, it should be set to IAP id if the IAP is saved
+ cpPriv->id = scanned_ssid.data();
+ cpPriv->network_id = scanned_ssid;
+ cpPriv->iap_type = ap.scan.network_type;
+ if (cpPriv->iap_type.isEmpty())
+ cpPriv->iap_type = QLatin1String("WLAN");
+ cpPriv->network_attrs = ap.scan.network_attrs;
+ cpPriv->service_id = ap.scan.service_id;
+ cpPriv->service_type = ap.scan.service_type;
+ cpPriv->service_attrs = ap.scan.service_attrs;
+
+ cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
+ cpPriv->state = QNetworkConfiguration::Undefined;
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan.";
+#endif
+
+ previous.removeAll(cpPriv->id);
+
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ accessPointConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+ }
+ }
+ }
+
+ while (!previous.isEmpty()) {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.take(previous.takeFirst());
+
+ emit configurationRemoved(ptr);
+ }
+
+ if (sender())
+ emit updateCompleted();
+}
+
+void QIcdEngine::deleteConfiguration(const QString &iap_id)
+{
+ QMutexLocker locker(&mutex);
+
+ /* Called when IAPs are deleted in gconf, in this case we do not scan
+ * or read all the IAPs from gconf because it might take too much power
+ * (multiple applications would need to scan and read all IAPs from gconf)
+ */
+ if (accessPointConfigurations.contains(iap_id)) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(iap_id);
+
+ if (ptr) {
+ ptr->isValid = false;
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "IAP" << iap_id << "was removed from storage.";
+#endif
+
+ emit configurationRemoved(ptr);
+ } else {
+ qWarning("Configuration not found for IAP %s", iap_id.toAscii().data());
+ }
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data());
+#endif
+ }
+}
+
+QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const
+{
+ return QNetworkConfigurationManager::CanStartAndStopInterfaces |
+ QNetworkConfigurationManager::DataStatistics |
+ QNetworkConfigurationManager::ForcedRoaming;
+}
+
+QNetworkSessionPrivate *QIcdEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl(this);
+}
+
+QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration()
+{
+ 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);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h
new file mode 100644
index 0000000000..6ebe40d1b3
--- /dev/null
+++ b/src/plugins/bearer/icd/qicdengine.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QICDENGINE_H
+#define QICDENGINE_H
+
+#include <QtNetwork/private/qbearerengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkConfigurationPrivate;
+class IapMonitor;
+
+class IcdNetworkConfigurationPrivate : public QNetworkConfigurationPrivate
+{
+public:
+ IcdNetworkConfigurationPrivate();
+ ~IcdNetworkConfigurationPrivate();
+
+ QString bearerName() const;
+
+ // In Maemo the id field (defined in QNetworkConfigurationPrivate)
+ // is the IAP id (which typically is UUID)
+ QByteArray network_id; // typically WLAN ssid or similar
+ QString iap_type; // is this one WLAN or GPRS
+
+ // Network attributes for this IAP, this is the value returned by icd and
+ // passed to it when connecting.
+ uint32_t network_attrs;
+
+ QString service_type;
+ QString service_id;
+ uint32_t service_attrs;
+};
+
+inline IcdNetworkConfigurationPrivate *toIcdConfig(QNetworkConfigurationPrivatePointer ptr)
+{
+ return static_cast<IcdNetworkConfigurationPrivate *>(ptr.data());
+}
+
+class QIcdEngine : public QBearerEngine
+{
+ Q_OBJECT
+
+public:
+ QIcdEngine(QObject *parent = 0);
+ ~QIcdEngine();
+
+ bool hasIdentifier(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+ void deleteConfiguration(const QString &iap_id);
+
+ inline QNetworkConfigurationPrivatePointer configuration(const QString &id)
+ {
+ QMutexLocker locker(&mutex);
+
+ return accessPointConfigurations.value(id);
+ }
+
+ inline void addSessionConfiguration(QNetworkConfigurationPrivatePointer ptr)
+ {
+ QMutexLocker locker(&mutex);
+
+ accessPointConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+ }
+
+ inline void changedSessionConfiguration(QNetworkConfigurationPrivatePointer ptr)
+ {
+ QMutexLocker locker(&mutex);
+
+ emit configurationChanged(ptr);
+ }
+
+private Q_SLOTS:
+ void doRequestUpdate();
+
+private:
+ IapMonitor *iapMonitor;
+};
+
+QT_END_NAMESPACE
+
+#endif // QICDENGINE_H
diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp
new file mode 100644
index 0000000000..a9e93e06a4
--- /dev/null
+++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp
@@ -0,0 +1,1104 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworksession_impl.h"
+#include "qicdengine.h"
+
+#include <QHash>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <maemo_icd.h>
+#include <iapconf.h>
+
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+QT_BEGIN_NAMESPACE
+
+static QHash<QString, QVariant> properties;
+
+static QString get_network_interface();
+static DBusConnection *dbus_connection;
+static DBusHandlerResult signal_handler(DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
+#define ICD_DBUS_MATCH "type='signal'," \
+ "interface='" ICD_DBUS_INTERFACE "'," \
+ "path='" ICD_DBUS_PATH "'"
+
+
+static inline DBusConnection *get_dbus_conn(DBusError *error)
+{
+ DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error);
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn);
+#endif
+
+ return conn;
+}
+
+
+/* Helper class that monitors the Icd status messages and
+ * can change the IAP status accordingly. This is a singleton.
+ */
+class IcdListener : public QObject
+{
+ Q_OBJECT
+
+public:
+ IcdListener() : first_call(true) { }
+ friend DBusHandlerResult signal_handler(DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+ void setup(QNetworkSessionPrivateImpl *d);
+ void cleanup();
+ void cleanupSession(QNetworkSessionPrivateImpl *ptr);
+
+ enum IapConnectionStatus {
+ /* The IAP was connected */
+ CONNECTED = 0,
+ /* The IAP was disconnected */
+ DISCONNECTED,
+ /* The IAP is disconnecting */
+ DISCONNECTING,
+ /* The IAP has a network address, but is not yet fully connected */
+ NETWORK_UP
+ };
+
+private:
+ void icdSignalReceived(QString&, QString&, QString&);
+ bool first_call;
+ QHash<QString, QNetworkSessionPrivateImpl *> sessions;
+};
+
+Q_GLOBAL_STATIC(IcdListener, icdListener);
+
+
+static DBusHandlerResult signal_handler(DBusConnection *,
+ DBusMessage *message,
+ void *user_data)
+{
+ if (dbus_message_is_signal(message,
+ ICD_DBUS_INTERFACE,
+ ICD_STATUS_CHANGED_SIG)) {
+
+ IcdListener *icd = (IcdListener *)user_data;
+ DBusError error;
+ dbus_error_init(&error);
+
+ char *iap_id = 0;
+ char *network_type = 0;
+ char *state = 0;
+
+ if (dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &iap_id,
+ DBUS_TYPE_STRING, &network_type,
+ DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_INVALID) == FALSE) {
+ qWarning() << QString("Failed to parse icd status signal: %1").arg(error.message);
+ } else {
+ QString _iap_id(iap_id);
+ QString _network_type(network_type);
+ QString _state(state);
+
+ icd->icdSignalReceived(_iap_id, _network_type, _state);
+ }
+
+ dbus_error_free(&error);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+void IcdListener::setup(QNetworkSessionPrivateImpl *d)
+{
+ if (first_call) {
+ // We use the old Icd dbus interface like in ConIC
+ DBusError error;
+ dbus_error_init(&error);
+
+ dbus_connection = get_dbus_conn(&error);
+ if (dbus_error_is_set(&error)) {
+ qWarning() << "Cannot get dbus connection.";
+ dbus_error_free(&error);
+ return;
+ }
+
+ static struct DBusObjectPathVTable icd_vtable;
+ icd_vtable.message_function = signal_handler;
+
+ dbus_bus_add_match(dbus_connection, ICD_DBUS_MATCH, &error);
+ if (dbus_error_is_set(&error)) {
+ qWarning() << "Cannot add match" << ICD_DBUS_MATCH;
+ dbus_error_free(&error);
+ return;
+ }
+
+ if (dbus_connection_register_object_path(dbus_connection,
+ ICD_DBUS_PATH,
+ &icd_vtable,
+ (void*)this) == FALSE) {
+ qWarning() << "Cannot register dbus signal handler, interface"<< ICD_DBUS_INTERFACE << "path" << ICD_DBUS_PATH;
+ dbus_error_free(&error);
+ return;
+ }
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE;
+#endif
+ first_call = false;
+ dbus_error_free(&error);
+ }
+
+ QString id = d->activeConfig.identifier();
+ if (!sessions.contains(id)) {
+ QNetworkSessionPrivateImpl *ptr = d;
+ sessions.insert(id, ptr);
+ }
+}
+
+
+void IcdListener::icdSignalReceived(QString& iap_id,
+#ifdef BEARER_MANAGEMENT_DEBUG
+ QString& network_type,
+#else
+ QString&,
+#endif
+ QString& state)
+{
+ if (iap_id == OSSO_IAP_SCAN) // icd sends scan status signals which we will ignore
+ return;
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Status received:" << iap_id << "type" << network_type << "state" << state;
+#endif
+
+ if (!sessions.contains(iap_id)) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "No session for IAP" << iap_id;
+#endif
+ return;
+ }
+
+ QNetworkSessionPrivateImpl *session = sessions.value(iap_id);
+ QNetworkConfiguration ap_conf =
+ QNetworkConfigurationManager().configurationFromIdentifier(iap_id);
+ if (!ap_conf.isValid()) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Unknown IAP" << iap_id;
+#endif
+ return;
+ }
+
+ IapConnectionStatus status;
+
+ if (state == "IDLE") {
+ status = DISCONNECTED;
+ } else if (state == "CONNECTED") {
+ status = CONNECTED;
+ } else if (state == "NETWORKUP") {
+ status = NETWORK_UP;
+ } else {
+ //qDebug() << "Unknown state" << state;
+ return;
+ }
+
+ if (status == DISCONNECTED) {
+ if (ap_conf.state() == QNetworkConfiguration::Active) {
+ /* The IAP was just disconnected by Icd */
+ session->updateState(QNetworkSession::Disconnected);
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Got a network disconnect when in state" << ap_conf.state();
+#endif
+ }
+ } else if (status == CONNECTED) {
+ /* The IAP was just connected by Icd */
+ session->updateState(QNetworkSession::Connected);
+ session->updateIdentifier(iap_id);
+
+ if (session->publicConfig.identifier() == OSSO_IAP_ANY) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "IAP" << iap_id << "connected when connecting to" << OSSO_IAP_ANY;
+#endif
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "IAP" << iap_id << "connected";
+#endif
+ }
+ }
+
+ return;
+}
+
+
+void IcdListener::cleanup()
+{
+ if (!first_call) {
+ dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL);
+ dbus_connection_unref(dbus_connection);
+ }
+}
+
+
+void IcdListener::cleanupSession(QNetworkSessionPrivateImpl *ptr)
+{
+ if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice)
+ (void)sessions.take(ptr->activeConfig.identifier());
+ else
+ (void)sessions.take(ptr->publicConfig.identifier());
+}
+
+
+void QNetworkSessionPrivateImpl::cleanupSession(void)
+{
+ icdListener()->cleanupSession(this);
+}
+
+
+void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState)
+{
+ if (newState == state)
+ return;
+
+ state = newState;
+
+ if (state == QNetworkSession::Disconnected) {
+ isOpen = false;
+ currentNetworkInterface.clear();
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice)
+ privateConfiguration(activeConfig)->state = QNetworkConfiguration::Defined;
+ privateConfiguration(publicConfig)->state = QNetworkConfiguration::Defined;
+
+ } else if (state == QNetworkSession::Connected) {
+ isOpen = true;
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ privateConfiguration(activeConfig)->state = QNetworkConfiguration::Active;
+ privateConfiguration(activeConfig)->type = QNetworkConfiguration::InternetAccessPoint;
+ }
+ privateConfiguration(publicConfig)->state = QNetworkConfiguration::Active;
+ }
+
+ emit stateChanged(newState);
+}
+
+
+void QNetworkSessionPrivateImpl::updateIdentifier(QString &newId)
+{
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ toIcdConfig(privateConfiguration(activeConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ privateConfiguration(activeConfig)->id = newId;
+ } else {
+ toIcdConfig(privateConfiguration(publicConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ if (privateConfiguration(publicConfig)->id != newId) {
+ qWarning() << "Your config id changed from" << privateConfiguration(publicConfig)->id
+ << "to" << newId;
+ privateConfiguration(publicConfig)->id = newId;
+ }
+ }
+}
+
+
+quint64 QNetworkSessionPrivateImpl::getStatistics(bool sent) const
+{
+ /* This could be also implemented by using the Maemo::Icd::statistics()
+ * that gets the statistics data for a specific IAP. Change if
+ * necessary.
+ */
+ Maemo::Icd icd;
+ QList<Maemo::IcdStatisticsResult> stats_results;
+ quint64 counter_rx = 0, counter_tx = 0;
+
+ if (!icd.statistics(stats_results)) {
+ return 0;
+ }
+
+ foreach (Maemo::IcdStatisticsResult res, stats_results) {
+ if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) {
+ /* network_id is the IAP UUID */
+ if (QString(res.params.network_id.data()) == activeConfig.identifier()) {
+ counter_tx = res.bytes_sent;
+ counter_rx = res.bytes_received;
+ }
+ } else {
+ /* We probably will never get to this branch */
+ if (res.params.network_id == toIcdConfig(privateConfiguration(activeConfig))->network_id) {
+ counter_tx = res.bytes_sent;
+ counter_rx = res.bytes_received;
+ }
+ }
+ }
+
+ if (sent)
+ return counter_tx;
+ else
+ return counter_rx;
+}
+
+
+quint64 QNetworkSessionPrivateImpl::bytesWritten() const
+{
+ return getStatistics(true);
+}
+
+quint64 QNetworkSessionPrivateImpl::bytesReceived() const
+{
+ return getStatistics(false);
+}
+
+quint64 QNetworkSessionPrivateImpl::activeTime() const
+{
+ if (startTime.isNull()) {
+ return 0;
+ }
+ return startTime.secsTo(QDateTime::currentDateTime());
+}
+
+
+QNetworkConfiguration& QNetworkSessionPrivateImpl::copyConfig(QNetworkConfiguration &fromConfig,
+ QNetworkConfiguration &toConfig,
+ bool deepCopy)
+{
+ IcdNetworkConfigurationPrivate *cpPriv;
+ if (deepCopy) {
+ cpPriv = new IcdNetworkConfigurationPrivate;
+ setPrivateConfiguration(toConfig, QNetworkConfigurationPrivatePointer(cpPriv));
+ } else {
+ cpPriv = toIcdConfig(privateConfiguration(toConfig));
+ }
+
+ cpPriv->name = privateConfiguration(fromConfig)->name;
+ cpPriv->isValid = privateConfiguration(fromConfig)->isValid;
+ // Note that we do not copy id field here as the publicConfig does
+ // not contain a valid IAP id.
+ cpPriv->state = privateConfiguration(fromConfig)->state;
+ cpPriv->type = privateConfiguration(fromConfig)->type;
+ cpPriv->roamingSupported = privateConfiguration(fromConfig)->roamingSupported;
+ cpPriv->purpose = privateConfiguration(fromConfig)->purpose;
+ cpPriv->network_id = toIcdConfig(privateConfiguration(fromConfig))->network_id;
+ cpPriv->iap_type = toIcdConfig(privateConfiguration(fromConfig))->iap_type;
+ cpPriv->network_attrs = toIcdConfig(privateConfiguration(fromConfig))->network_attrs;
+ cpPriv->service_type = toIcdConfig(privateConfiguration(fromConfig))->service_type;
+ cpPriv->service_id = toIcdConfig(privateConfiguration(fromConfig))->service_id;
+ cpPriv->service_attrs = toIcdConfig(privateConfiguration(fromConfig))->service_attrs;
+
+ return toConfig;
+}
+
+
+/* This is called by QNetworkSession constructor and it updates the current
+ * state of the configuration.
+ */
+void QNetworkSessionPrivateImpl::syncStateWithInterface()
+{
+ /* Start to listen Icd status messages. */
+ icdListener()->setup(this);
+
+ /* Initially we are not active although the configuration might be in
+ * connected state.
+ */
+ isOpen = false;
+ opened = false;
+
+ connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged()));
+
+ connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SLOT(configurationChanged(QNetworkConfiguration)));
+
+ state = QNetworkSession::Invalid;
+ lastError = QNetworkSession::UnknownSessionError;
+
+ switch (publicConfig.type()) {
+ case QNetworkConfiguration::InternetAccessPoint:
+ activeConfig = publicConfig;
+ break;
+ case QNetworkConfiguration::ServiceNetwork:
+ serviceConfig = publicConfig;
+ break;
+ case QNetworkConfiguration::UserChoice:
+ // active config will contain correct data after open() has succeeded
+ copyConfig(publicConfig, activeConfig);
+
+ /* We create new configuration that holds the actual configuration
+ * returned by icd. This way publicConfig still contains the
+ * original user specified configuration.
+ *
+ * Note that the new activeConfig configuration is not inserted
+ * to configurationManager as manager class will get the newly
+ * connected configuration from gconf when the IAP is saved.
+ * This configuration manager update is done by IapMonitor class.
+ * If the ANY connection fails in open(), then the configuration
+ * data is not saved to gconf and will not be added to
+ * configuration manager IAP list.
+ */
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug()<<"New configuration created for" << publicConfig.identifier();
+#endif
+ break;
+ default:
+ /* Invalid configuration, no point continuing */
+ return;
+ }
+
+ if (!activeConfig.isValid())
+ return;
+
+ /* Get the initial state from icd */
+ Maemo::Icd icd;
+ QList<Maemo::IcdStateResult> state_results;
+
+ /* Update the active config from first connection, this is ok as icd
+ * supports only one connection anyway.
+ */
+ if (icd.state(state_results) && !state_results.isEmpty()) {
+
+ /* If we did not get full state back, then we are not
+ * connected and can skip the next part.
+ */
+ if (!(state_results.first().params.network_attrs == 0 &&
+ state_results.first().params.network_id.isEmpty())) {
+
+ /* If we try to connect to specific IAP and we get results back
+ * that tell the icd is actually connected to another IAP,
+ * then do not update current state etc.
+ */
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice ||
+ privateConfiguration(publicConfig)->id == state_results.first().params.network_id) {
+
+ switch (state_results.first().state) {
+ case ICD_STATE_DISCONNECTED:
+ state = QNetworkSession::Disconnected;
+ if (privateConfiguration(activeConfig))
+ privateConfiguration(activeConfig)->isValid = true;
+ break;
+ case ICD_STATE_CONNECTING:
+ state = QNetworkSession::Connecting;
+ if (privateConfiguration(activeConfig))
+ privateConfiguration(activeConfig)->isValid = true;
+ break;
+ case ICD_STATE_CONNECTED:
+ {
+ if (!state_results.first().error.isEmpty())
+ break;
+
+ const QString id = state_results.first().params.network_id;
+
+ QNetworkConfiguration config = manager.configurationFromIdentifier(id);
+ if (config.isValid()) {
+ //we don't want the copied data if the config is already known by the manager
+ //just reuse it so that existing references to the old data get the same update
+ setPrivateConfiguration(activeConfig, privateConfiguration(config));
+ }
+
+ QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig);
+
+ state = QNetworkSession::Connected;
+ toIcdConfig(ptr)->network_id = state_results.first().params.network_id;
+ ptr->id = toIcdConfig(ptr)->network_id;
+ toIcdConfig(ptr)->network_attrs = state_results.first().params.network_attrs;
+ toIcdConfig(ptr)->iap_type = state_results.first().params.network_type;
+ toIcdConfig(ptr)->service_type = state_results.first().params.service_type;
+ toIcdConfig(ptr)->service_id = state_results.first().params.service_id;
+ toIcdConfig(ptr)->service_attrs = state_results.first().params.service_attrs;
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->state = QNetworkConfiguration::Active;
+ ptr->isValid = true;
+ currentNetworkInterface = get_network_interface();
+
+ Maemo::IAPConf iap_name(privateConfiguration(activeConfig)->id);
+ QString name_value = iap_name.value("name").toString();
+ if (!name_value.isEmpty())
+ privateConfiguration(activeConfig)->name = name_value;
+ else
+ privateConfiguration(activeConfig)->name = privateConfiguration(activeConfig)->id;
+
+
+ // Add the new active configuration to manager or update the old config
+ if (!engine->hasIdentifier(privateConfiguration(activeConfig)->id))
+ engine->addSessionConfiguration(privateConfiguration(activeConfig));
+ else
+ engine->changedSessionConfiguration(privateConfiguration(activeConfig));
+ }
+ break;
+
+ case ICD_STATE_DISCONNECTING:
+ state = QNetworkSession::Closing;
+ if (privateConfiguration(activeConfig))
+ privateConfiguration(activeConfig)->isValid = true;
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "status_req tells icd is not connected";
+#endif
+ }
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "status_req did not return any results from icd";
+#endif
+ }
+
+ networkConfigurationsChanged();
+}
+
+
+void QNetworkSessionPrivateImpl::networkConfigurationsChanged()
+{
+ if (serviceConfig.isValid())
+ updateStateFromServiceNetwork();
+ else
+ updateStateFromActiveConfig();
+}
+
+
+void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork()
+{
+ QNetworkSession::State oldState = state;
+
+ foreach (const QNetworkConfiguration &config, serviceConfig.children()) {
+ if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active)
+ continue;
+
+ if (activeConfig != config) {
+ activeConfig = config;
+ emit newConfigurationActivated();
+ }
+
+ state = QNetworkSession::Connected;
+ if (state != oldState)
+ emit stateChanged(state);
+
+ return;
+ }
+
+ if (serviceConfig.children().isEmpty())
+ state = QNetworkSession::NotAvailable;
+ else
+ state = QNetworkSession::Disconnected;
+
+ if (state != oldState)
+ emit stateChanged(state);
+}
+
+
+void QNetworkSessionPrivateImpl::clearConfiguration(QNetworkConfiguration &config)
+{
+ toIcdConfig(privateConfiguration(config))->network_id.clear();
+ toIcdConfig(privateConfiguration(config))->iap_type.clear();
+ toIcdConfig(privateConfiguration(config))->network_attrs = 0;
+ toIcdConfig(privateConfiguration(config))->service_type.clear();
+ toIcdConfig(privateConfiguration(config))->service_id.clear();
+ toIcdConfig(privateConfiguration(config))->service_attrs = 0;
+}
+
+
+void QNetworkSessionPrivateImpl::updateStateFromActiveConfig()
+{
+ QNetworkSession::State oldState = state;
+
+ bool newActive = false;
+
+ if (!privateConfiguration(activeConfig))
+ return;
+
+ if (!activeConfig.isValid()) {
+ state = QNetworkSession::Invalid;
+ clearConfiguration(activeConfig);
+ } else if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ state = QNetworkSession::Connected;
+ newActive = opened;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
+ state = QNetworkSession::Disconnected;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+ state = QNetworkSession::NotAvailable;
+ } else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) {
+ state = QNetworkSession::NotAvailable;
+ //clearConfiguration(activeConfig);
+ }
+
+ bool oldActive = isOpen;
+ isOpen = newActive;
+
+ if (!oldActive && isOpen)
+ emit quitPendingWaitsForOpened();
+
+ if (oldActive && !isOpen)
+ emit closed();
+
+ if (oldState != state) {
+ emit stateChanged(state);
+
+ if (state == QNetworkSession::Disconnected) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ //qDebug()<<"session aborted error emitted for"<<activeConfig.identifier();
+#endif
+ lastError = QNetworkSession::SessionAbortedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ }
+ }
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ //qDebug()<<"oldState ="<<oldState<<" state ="<<state<<" oldActive ="<<oldActive<<" newActive ="<<newActive<<" opened ="<<opened;
+#endif
+}
+
+
+void QNetworkSessionPrivateImpl::configurationChanged(const QNetworkConfiguration &config)
+{
+ if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig))
+ updateStateFromServiceNetwork();
+ else if (config == activeConfig)
+ updateStateFromActiveConfig();
+}
+
+
+static QString get_network_interface()
+{
+ Maemo::Icd icd;
+ QList<Maemo::IcdAddressInfoResult> addr_results;
+ uint ret;
+ QString iface;
+
+ ret = icd.addrinfo(addr_results);
+ if (ret == 0) {
+ /* No results */
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Cannot get addrinfo from icd, are you connected or is icd running?";
+#endif
+ return iface;
+ }
+
+ const char *address = addr_results.first().ip_info.first().address.toAscii().constData();
+ struct in_addr addr;
+ if (inet_aton(address, &addr) == 0) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "address" << address << "invalid";
+#endif
+ return iface;
+ }
+
+ struct ifaddrs *ifaddr, *ifa;
+ int family;
+
+ if (getifaddrs(&ifaddr) == -1) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "getifaddrs() failed";
+#endif
+ return iface;
+ }
+
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ family = ifa->ifa_addr->sa_family;
+ if (family != AF_INET) {
+ continue; /* Currently only IPv4 is supported by icd dbus interface */
+ }
+ if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) {
+ iface = QString(ifa->ifa_name);
+ break;
+ }
+ }
+
+ freeifaddrs(ifaddr);
+ return iface;
+}
+
+
+void QNetworkSessionPrivateImpl::open()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ } else if (!isOpen) {
+
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ /* Caller is trying to connect to default IAP.
+ * At this time we will not know the IAP details so we just
+ * connect and update the active config when the IAP is
+ * connected.
+ */
+ opened = true;
+ state = QNetworkSession::Connecting;
+ emit stateChanged(state);
+ QTimer::singleShot(0, this, SLOT(do_open()));
+ return;
+ }
+
+ /* User is connecting to one specific IAP. If that IAP is not
+ * in discovered state we cannot continue.
+ */
+ if ((activeConfig.state() & QNetworkConfiguration::Discovered) !=
+ QNetworkConfiguration::Discovered) {
+ lastError =QNetworkSession::InvalidConfigurationError;
+ emit QNetworkSessionPrivate::error(lastError);
+ return;
+ }
+ opened = true;
+
+ if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) {
+ state = QNetworkSession::Connecting;
+ emit stateChanged(state);
+
+ QTimer::singleShot(0, this, SLOT(do_open()));
+ return;
+ }
+
+ isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
+ if (isOpen)
+ emit quitPendingWaitsForOpened();
+ } else {
+ /* We seem to be active so inform caller */
+ emit quitPendingWaitsForOpened();
+ }
+}
+
+
+void QNetworkSessionPrivateImpl::do_open()
+{
+ icd_connection_flags flags = connectFlags;
+ bool st;
+ QString result;
+ QString iap = publicConfig.identifier();
+
+ if (state == QNetworkSession::Connected) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Already connected to" << activeConfig.identifier();
+#endif
+ emit stateChanged(QNetworkSession::Connected);
+ emit quitPendingWaitsForOpened();
+ return;
+ }
+
+ Maemo::IcdConnectResult connect_result;
+ Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT);
+ QNetworkConfiguration config;
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice)
+ config = activeConfig;
+ else
+ config = publicConfig;
+
+ if (iap == OSSO_IAP_ANY) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "connecting to default IAP" << iap;
+#endif
+ st = icd.connect(flags, connect_result);
+
+ } else {
+
+ QList<Maemo::ConnectParams> params;
+ Maemo::ConnectParams param;
+ param.connect.service_type = toIcdConfig(privateConfiguration(config))->service_type;
+ param.connect.service_attrs = toIcdConfig(privateConfiguration(config))->service_attrs;
+ param.connect.service_id = toIcdConfig(privateConfiguration(config))->service_id;
+ param.connect.network_type = toIcdConfig(privateConfiguration(config))->iap_type;
+ param.connect.network_attrs = toIcdConfig(privateConfiguration(config))->network_attrs;
+ if (toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)
+ param.connect.network_id = QByteArray(iap.toLatin1());
+ else
+ param.connect.network_id = toIcdConfig(privateConfiguration(config))->network_id;
+ params.append(param);
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s",
+ param.connect.network_id.data(),
+ param.connect.network_type.toAscii().constData(),
+ param.connect.network_attrs,
+ param.connect.service_type.toAscii().constData(),
+ param.connect.service_attrs,
+ param.connect.service_id.toAscii().constData());
+#endif
+ st = icd.connect(flags, params, connect_result);
+ }
+
+ if (st) {
+ result = connect_result.connect.network_id.data();
+ QString connected_iap = result;
+
+ if (connected_iap.isEmpty()) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "connect to"<< iap << "failed, result is empty";
+#endif
+ updateState(QNetworkSession::Disconnected);
+ emit quitPendingWaitsForOpened();
+ emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError);
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice)
+ cleanupAnyConfiguration();
+ return;
+ }
+
+ /* If the user tried to connect to some specific connection (foo)
+ * and we were already connected to some other connection (bar),
+ * then we cannot activate this session although icd has a valid
+ * connection to somewhere.
+ */
+ if ((publicConfig.type() != QNetworkConfiguration::UserChoice) &&
+ (connected_iap != config.identifier())) {
+ updateState(QNetworkSession::Disconnected);
+ emit quitPendingWaitsForOpened();
+ emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError);
+ return;
+ }
+
+
+ /* Did we connect to non saved IAP? */
+ if (!(toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)) {
+ /* Because the connection succeeded, the IAP is now known.
+ */
+ toIcdConfig(privateConfiguration(config))->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ privateConfiguration(config)->id = connected_iap;
+ }
+
+ /* User might have changed the IAP name when a new IAP was saved */
+ Maemo::IAPConf iap_name(privateConfiguration(config)->id);
+ QString name = iap_name.value("name").toString();
+ if (!name.isEmpty())
+ privateConfiguration(config)->name = name;
+
+ toIcdConfig(privateConfiguration(config))->iap_type = connect_result.connect.network_type;
+
+ privateConfiguration(config)->isValid = true;
+ privateConfiguration(config)->state = QNetworkConfiguration::Active;
+ privateConfiguration(config)->type = QNetworkConfiguration::InternetAccessPoint;
+
+ startTime = QDateTime::currentDateTime();
+ updateState(QNetworkSession::Connected);
+
+ currentNetworkInterface = get_network_interface();
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "connected to" << result << config.name() << "at" << currentNetworkInterface;
+#endif
+
+ /* We first check if the configuration already exists in the manager
+ * and if it is not found there, we then insert it. Note that this
+ * is only done for user choice config only because it can be missing
+ * from config manager list.
+ */
+
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ if (!engine->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();
+
+ } else {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "connect to"<< iap << "failed, status:" << connect_result.status;
+#endif
+ updateState(QNetworkSession::Disconnected);
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice)
+ cleanupAnyConfiguration();
+ emit quitPendingWaitsForOpened();
+ emit QNetworkSessionPrivate::error(QNetworkSession::UnknownSessionError);
+ }
+}
+
+
+void QNetworkSessionPrivateImpl::cleanupAnyConfiguration()
+{
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug()<<"Removing configuration created for" << activeConfig.identifier();
+#endif
+ activeConfig = publicConfig;
+}
+
+
+void QNetworkSessionPrivateImpl::close()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ } else if (isOpen) {
+ opened = false;
+ isOpen = false;
+ emit closed();
+ }
+}
+
+
+void QNetworkSessionPrivateImpl::stop()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ } else {
+ if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ state = QNetworkSession::Closing;
+ emit stateChanged(state);
+
+ Maemo::Icd icd;
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "stopping session" << publicConfig.identifier();
+#endif
+ icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT);
+ startTime = QDateTime();
+
+ /* Note that the state will go disconnected in
+ * updateStateFromActiveConfig() which gets called after
+ * configurationChanged is emitted (below).
+ */
+
+ privateConfiguration(activeConfig)->state = QNetworkConfiguration::Discovered;
+ engine->changedSessionConfiguration(privateConfiguration(activeConfig));
+
+ opened = false;
+ isOpen = false;
+
+ } else {
+ opened = false;
+ isOpen = false;
+ emit closed();
+ }
+ }
+}
+
+
+void QNetworkSessionPrivateImpl::migrate()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+
+void QNetworkSessionPrivateImpl::accept()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+
+void QNetworkSessionPrivateImpl::ignore()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+
+void QNetworkSessionPrivateImpl::reject()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+
+QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const
+{
+ if (!publicConfig.isValid() || state != QNetworkSession::Connected)
+ return QNetworkInterface();
+
+ if (currentNetworkInterface.isEmpty())
+ return QNetworkInterface();
+
+ return QNetworkInterface::interfaceFromName(currentNetworkInterface);
+}
+
+
+void QNetworkSessionPrivateImpl::setSessionProperty(const QString& key, const QVariant& value)
+{
+ if (value.isValid()) {
+ properties.insert(key, value);
+
+ if (key == "ConnectInBackground") {
+ bool v = value.toBool();
+ if (v)
+ connectFlags = ICD_CONNECTION_FLAG_APPLICATION_EVENT;
+ else
+ connectFlags = ICD_CONNECTION_FLAG_USER_EVENT;
+ }
+ } else {
+ properties.remove(key);
+
+ /* Set default value when property is removed */
+ if (key == "ConnectInBackground")
+ connectFlags = ICD_CONNECTION_FLAG_USER_EVENT;
+ }
+}
+
+
+QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& key) const
+{
+ return properties.value(key);
+}
+
+
+QString QNetworkSessionPrivateImpl::errorString() const
+{
+ QString errorStr;
+ switch(q->error()) {
+ case QNetworkSession::RoamingError:
+ errorStr = QObject::tr("Roaming error");
+ break;
+ case QNetworkSession::SessionAbortedError:
+ errorStr = QObject::tr("Session aborted by user or system");
+ break;
+ default:
+ case QNetworkSession::UnknownSessionError:
+ errorStr = QObject::tr("Unidentified Error");
+ break;
+ }
+ return errorStr;
+}
+
+
+QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
+{
+ return QNetworkSession::UnknownSessionError;
+}
+
+#include "qnetworksession_impl.moc"
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/icd/qnetworksession_impl.h b/src/plugins/bearer/icd/qnetworksession_impl.h
new file mode 100644
index 0000000000..b7461dc022
--- /dev/null
+++ b/src/plugins/bearer/icd/qnetworksession_impl.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** 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 QNETWORKSESSION_IMPL_H
+#define QNETWORKSESSION_IMPL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtNetwork/private/qnetworksession_p.h>
+#include <QtNetwork/qnetworkconfigmanager.h>
+
+//#include "qnetworkconfigmanager_maemo_p.h"
+//#include "qnetworksession.h"
+
+//#include <qnetworksession.h>
+//#include <QNetworkInterface>
+#include <QtCore/qdatetime.h>
+
+#include <icd/dbus_api.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIcdEngine;
+
+class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate
+{
+ Q_OBJECT
+
+public:
+ QNetworkSessionPrivateImpl(QIcdEngine *engine)
+ : engine(engine), connectFlags(ICD_CONNECTION_FLAG_USER_EVENT)
+ {
+ }
+
+ ~QNetworkSessionPrivateImpl()
+ {
+ cleanupSession();
+ }
+
+ //called by QNetworkSession constructor and ensures
+ //that the state is immediately updated (w/o actually opening
+ //a session). Also this function should take care of
+ //notification hooks to discover future state changes.
+ void syncStateWithInterface();
+
+ QNetworkInterface currentInterface() const;
+ QVariant sessionProperty(const QString& key) const;
+ void setSessionProperty(const QString& key, const QVariant& value);
+
+ void open();
+ void close();
+ void stop();
+
+ void migrate();
+ void accept();
+ void ignore();
+ void reject();
+
+ QString errorString() const; //must return translated string
+ QNetworkSession::SessionError error() const;
+
+ quint64 bytesWritten() const;
+ quint64 bytesReceived() const;
+ quint64 activeTime() const;
+
+private:
+ void updateStateFromServiceNetwork();
+ void updateStateFromActiveConfig();
+
+private Q_SLOTS:
+ void do_open();
+ void networkConfigurationsChanged();
+ void configurationChanged(const QNetworkConfiguration &config);
+
+private:
+ QNetworkConfigurationManager manager;
+ QIcdEngine *engine;
+
+ QNetworkConfiguration& copyConfig(QNetworkConfiguration &fromConfig, QNetworkConfiguration &toConfig, bool deepCopy = true);
+ void clearConfiguration(QNetworkConfiguration &config);
+ void cleanupAnyConfiguration();
+
+ bool opened;
+ icd_connection_flags connectFlags;
+
+ QNetworkSession::SessionError lastError;
+
+ QDateTime startTime;
+ QString currentNetworkInterface;
+ friend class IcdListener;
+ void updateState(QNetworkSession::State);
+ void updateIdentifier(QString &newId);
+ quint64 getStatistics(bool sent) const;
+ void cleanupSession(void);
+};
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKSESSIONPRIVATE_H
+
diff --git a/src/plugins/bearer/nativewifi/main.cpp b/src/plugins/bearer/nativewifi/main.cpp
new file mode 100644
index 0000000000..d77462e6bc
--- /dev/null
+++ b/src/plugins/bearer/nativewifi/main.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** 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 "qnativewifiengine.h"
+#include "platformdefs.h"
+
+#include <QtCore/qmutex.h>
+#include <QtCore/private/qmutexpool_p.h>
+#include <QtCore/qlibrary.h>
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static void resolveLibrary()
+{
+ static volatile bool triedResolve = false;
+
+ if (!triedResolve) {
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(QMutexPool::globalInstanceGet(&local_WlanOpenHandle));
+#endif
+
+ if (!triedResolve) {
+ local_WlanOpenHandle = (WlanOpenHandleProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanOpenHandle");
+ local_WlanRegisterNotification = (WlanRegisterNotificationProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanRegisterNotification");
+ local_WlanEnumInterfaces = (WlanEnumInterfacesProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanEnumInterfaces");
+ local_WlanGetAvailableNetworkList = (WlanGetAvailableNetworkListProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanGetAvailableNetworkList");
+ local_WlanQueryInterface = (WlanQueryInterfaceProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanQueryInterface");
+ local_WlanConnect = (WlanConnectProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanConnect");
+ local_WlanDisconnect = (WlanDisconnectProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanDisconnect");
+ local_WlanScan = (WlanScanProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanScan");
+ local_WlanFreeMemory = (WlanFreeMemoryProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanFreeMemory");
+ local_WlanCloseHandle = (WlanCloseHandleProto)
+ QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanCloseHandle");
+
+ triedResolve = true;
+ }
+ }
+}
+
+class QNativeWifiEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QNativeWifiEnginePlugin();
+ ~QNativeWifiEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QNativeWifiEnginePlugin::QNativeWifiEnginePlugin()
+{
+}
+
+QNativeWifiEnginePlugin::~QNativeWifiEnginePlugin()
+{
+}
+
+QStringList QNativeWifiEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("nativewifi");
+}
+
+QBearerEngine *QNativeWifiEnginePlugin::create(const QString &key) const
+{
+ if (key != QLatin1String("nativewifi"))
+ return 0;
+
+ resolveLibrary();
+
+ // native wifi dll not available
+ if (!local_WlanOpenHandle)
+ return 0;
+
+ QNativeWifiEngine *engine = new QNativeWifiEngine;
+
+ // could not initialise subsystem
+ if (engine && !engine->available()) {
+ delete engine;
+ return 0;
+ }
+
+ return engine;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QNativeWifiEnginePlugin)
+Q_EXPORT_PLUGIN2(qnativewifibearer, QNativeWifiEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/nativewifi/nativewifi.pro b/src/plugins/bearer/nativewifi/nativewifi.pro
new file mode 100644
index 0000000000..f277a0459e
--- /dev/null
+++ b/src/plugins/bearer/nativewifi/nativewifi.pro
@@ -0,0 +1,17 @@
+TARGET = qnativewifibearer
+include(../../qpluginbase.pri)
+
+QT += network
+
+HEADERS += qnativewifiengine.h \
+ platformdefs.h \
+ ../qnetworksession_impl.h \
+ ../qbearerengine_impl.h
+
+SOURCES += main.cpp \
+ qnativewifiengine.cpp \
+ ../qnetworksession_impl.cpp
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/nativewifi/platformdefs.h b/src/plugins/bearer/nativewifi/platformdefs.h
new file mode 100644
index 0000000000..57ae852aa6
--- /dev/null
+++ b/src/plugins/bearer/nativewifi/platformdefs.h
@@ -0,0 +1,322 @@
+/****************************************************************************
+**
+** 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 PLATFORMDEFS_H
+#define PLATFORMDEFS_H
+
+#include <wtypes.h>
+#undef interface
+
+#define WLAN_MAX_NAME_LENGTH 256
+#define WLAN_MAX_PHY_TYPE_NUMBER 8
+#define WLAN_NOTIFICATION_SOURCE_ALL 0x0000ffff
+#define WLAN_AVAILABLE_NETWORK_CONNECTED 1
+#define WLAN_AVAILABLE_NETWORK_HAS_PROFILE 2
+#define DOT11_SSID_MAX_LENGTH 32
+
+struct WLAN_NOTIFICATION_DATA {
+ DWORD NotificationSource;
+ DWORD NotificationCode;
+ GUID InterfaceGuid;
+ DWORD dwDataSize;
+ PVOID pData;
+};
+
+enum WLAN_INTERFACE_STATE {
+ wlan_interface_state_not_ready = 0,
+ wlan_interface_state_connected,
+ wlan_interface_state_ad_hoc_network_formed,
+ wlan_interface_state_disconnecting,
+ wlan_interface_state_disconnected,
+ wlan_interface_state_associating,
+ wlan_interface_state_discovering,
+ wlan_interface_state_authenticating
+};
+
+struct WLAN_INTERFACE_INFO {
+ GUID InterfaceGuid;
+ WCHAR strInterfaceDescription[WLAN_MAX_NAME_LENGTH];
+ WLAN_INTERFACE_STATE isState;
+};
+
+struct WLAN_INTERFACE_INFO_LIST {
+ DWORD dwNumberOfItems;
+ DWORD dwIndex;
+ WLAN_INTERFACE_INFO InterfaceInfo[1];
+};
+
+struct DOT11_SSID {
+ ULONG uSSIDLength;
+ UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
+};
+
+struct NDIS_OBJECT_HEADER {
+ UCHAR Type;
+ UCHAR Revision;
+ USHORT Size;
+};
+
+typedef UCHAR DOT11_MAC_ADDRESS[6];
+struct DOT11_BSSID_LIST {
+ NDIS_OBJECT_HEADER Header;
+ ULONG uNumberOfEntries;
+ ULONG uTotalNumOfEntries;
+ DOT11_MAC_ADDRESS BSSIDs[1];
+};
+
+enum DOT11_BSS_TYPE {
+ dot11_BSS_type_infrastructure = 1,
+ dot11_BSS_type_independent = 2,
+ dot11_BSS_type_any = 3
+};
+
+enum DOT11_PHY_TYPE {
+ dot11_phy_type_unknown = 0,
+ dot11_phy_type_any = dot11_phy_type_unknown,
+ dot11_phy_type_fhss = 1,
+ dot11_phy_type_dsss = 2,
+ dot11_phy_type_irbaseband = 3,
+ dot11_phy_type_ofdm = 4,
+ dot11_phy_type_hrdsss = 5,
+ dot11_phy_type_erp = 6,
+ dot11_phy_type_ht = 7,
+ dot11_phy_type_IHV_start = 0x80000000,
+ dot11_phy_type_IHV_end = 0xffffffff
+};
+
+enum DOT11_AUTH_ALGORITHM {
+ DOT11_AUTH_ALGO_80211_OPEN = 1,
+ DOT11_AUTH_ALGO_80211_SHARED_KEY = 2,
+ DOT11_AUTH_ALGO_WPA = 3,
+ DOT11_AUTH_ALGO_WPA_PSK = 4,
+ DOT11_AUTH_ALGO_WPA_NONE = 5,
+ DOT11_AUTH_ALGO_RSNA = 6,
+ DOT11_AUTH_ALGO_RSNA_PSK = 7,
+ DOT11_AUTH_ALGO_IHV_START = 0x80000000,
+ DOT11_AUTH_ALGO_IHV_END = 0xffffffff
+};
+
+enum DOT11_CIPHER_ALGORITHM {
+ DOT11_CIPHER_ALGO_NONE = 0x00,
+ DOT11_CIPHER_ALGO_WEP40 = 0x01,
+ DOT11_CIPHER_ALGO_TKIP = 0x02,
+ DOT11_CIPHER_ALGO_CCMP = 0x04,
+ DOT11_CIPHER_ALGO_WEP104 = 0x05,
+ DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
+ DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
+ DOT11_CIPHER_ALGO_WEP = 0x101,
+ DOT11_CIPHER_ALGO_IHV_START = 0x80000000,
+ DOT11_CIPHER_ALGO_IHV_END = 0xffffffff
+};
+
+struct WLAN_AVAILABLE_NETWORK {
+ WCHAR strProfileName[WLAN_MAX_NAME_LENGTH];
+ DOT11_SSID dot11Ssid;
+ DOT11_BSS_TYPE dot11BssType;
+ ULONG uNumberOfBssids;
+ BOOL bNetworkConnectable;
+ DWORD wlanNotConnectableReason;
+ ULONG uNumberOfPhyTypes;
+ DOT11_PHY_TYPE dot11PhyTypes[WLAN_MAX_PHY_TYPE_NUMBER];
+ BOOL bMorePhyTypes;
+ ULONG wlanSignalQuality;
+ BOOL bSecurityEnabled;
+ DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;
+ DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;
+ DWORD dwFlags;
+ DWORD dwReserved;
+};
+
+struct WLAN_AVAILABLE_NETWORK_LIST {
+ DWORD dwNumberOfItems;
+ DWORD dwIndex;
+ WLAN_AVAILABLE_NETWORK Network[1];
+};
+
+enum WLAN_INTF_OPCODE {
+ wlan_intf_opcode_autoconf_start = 0x000000000,
+ wlan_intf_opcode_autoconf_enabled,
+ wlan_intf_opcode_background_scan_enabled,
+ wlan_intf_opcode_media_streaming_mode,
+ wlan_intf_opcode_radio_state,
+ wlan_intf_opcode_bss_type,
+ wlan_intf_opcode_interface_state,
+ wlan_intf_opcode_current_connection,
+ wlan_intf_opcode_channel_number,
+ wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs,
+ wlan_intf_opcode_supported_adhoc_auth_cipher_pairs,
+ wlan_intf_opcode_supported_country_or_region_string_list,
+ wlan_intf_opcode_current_operation_mode,
+ wlan_intf_opcode_supported_safe_mode,
+ wlan_intf_opcode_certified_safe_mode,
+ wlan_intf_opcode_autoconf_end = 0x0fffffff,
+ wlan_intf_opcode_msm_start = 0x10000100,
+ wlan_intf_opcode_statistics,
+ wlan_intf_opcode_rssi,
+ wlan_intf_opcode_msm_end = 0x1fffffff,
+ wlan_intf_opcode_security_start = 0x20010000,
+ wlan_intf_opcode_security_end = 0x2fffffff,
+ wlan_intf_opcode_ihv_start = 0x30000000,
+ wlan_intf_opcode_ihv_end = 0x3fffffff
+};
+
+enum WLAN_OPCODE_VALUE_TYPE {
+ wlan_opcode_value_type_query_only = 0,
+ wlan_opcode_value_type_set_by_group_policy,
+ wlan_opcode_value_type_set_by_user,
+ wlan_opcode_value_type_invalid
+};
+
+enum WLAN_CONNECTION_MODE {
+ wlan_connection_mode_profile = 0,
+ wlan_connection_mode_temporary_profile,
+ wlan_connection_mode_discovery_secure,
+ wlan_connection_mode_discovery_unsecure,
+ wlan_connection_mode_auto,
+ wlan_connection_mode_invalid
+};
+
+struct WLAN_CONNECTION_PARAMETERS {
+ WLAN_CONNECTION_MODE wlanConnectionMode;
+ LPCWSTR strProfile;
+ DOT11_SSID *pDot11Ssid;
+ DOT11_BSSID_LIST *pDesiredBssidList;
+ DOT11_BSS_TYPE dot11BssType;
+ DWORD dwFlags;
+};
+
+struct WLAN_RAW_DATA {
+ DWORD dwDataSize;
+ BYTE DataBlob[1];
+};
+
+enum WLAN_NOTIFICATION_ACM {
+ wlan_notification_acm_start = 0,
+ wlan_notification_acm_autoconf_enabled,
+ wlan_notification_acm_autoconf_disabled,
+ wlan_notification_acm_background_scan_enabled,
+ wlan_notification_acm_background_scan_disabled,
+ wlan_notification_acm_bss_type_change,
+ wlan_notification_acm_power_setting_change,
+ wlan_notification_acm_scan_complete,
+ wlan_notification_acm_scan_fail,
+ wlan_notification_acm_connection_start,
+ wlan_notification_acm_connection_complete,
+ wlan_notification_acm_connection_attempt_fail,
+ wlan_notification_acm_filter_list_change,
+ wlan_notification_acm_interface_arrival,
+ wlan_notification_acm_interface_removal,
+ wlan_notification_acm_profile_change,
+ wlan_notification_acm_profile_name_change,
+ wlan_notification_acm_profiles_exhausted,
+ wlan_notification_acm_network_not_available,
+ wlan_notification_acm_network_available,
+ wlan_notification_acm_disconnecting,
+ wlan_notification_acm_disconnected,
+ wlan_notification_acm_adhoc_network_state_change,
+ wlan_notification_acm_end
+};
+
+struct WLAN_ASSOCIATION_ATTRIBUTES {
+ DOT11_SSID dot11Ssid;
+ DOT11_BSS_TYPE dot11BssType;
+ DOT11_MAC_ADDRESS dot11Bssid;
+ DOT11_PHY_TYPE dot11PhyType;
+ ULONG uDot11PhyIndex;
+ ULONG wlanSignalQuality;
+ ULONG ulRxRate;
+ ULONG ulTxRate;
+};
+
+struct WLAN_SECURITY_ATTRIBUTES {
+ BOOL bSecurityEnabled;
+ BOOL bOneXEnabled;
+ DOT11_AUTH_ALGORITHM dot11AuthAlgorithm;
+ DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm;
+};
+
+struct WLAN_CONNECTION_ATTRIBUTES {
+ WLAN_INTERFACE_STATE isState;
+ WLAN_CONNECTION_MODE wlanConnectionMode;
+ WCHAR strProfileName[WLAN_MAX_NAME_LENGTH];
+ WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;
+ WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes;
+};
+
+typedef void (WINAPI *WLAN_NOTIFICATION_CALLBACK)(WLAN_NOTIFICATION_DATA *, PVOID);
+
+typedef DWORD (WINAPI *WlanOpenHandleProto)
+ (DWORD dwClientVersion, PVOID pReserved, PDWORD pdwNegotiatedVersion, PHANDLE phClientHandle);
+typedef DWORD (WINAPI *WlanRegisterNotificationProto)
+ (HANDLE hClientHandle, DWORD dwNotifSource, BOOL bIgnoreDuplicate,
+ WLAN_NOTIFICATION_CALLBACK funcCallback, PVOID pCallbackContext,
+ PVOID pReserved, PDWORD pdwPrevNotifSource);
+typedef DWORD (WINAPI *WlanEnumInterfacesProto)
+ (HANDLE hClientHandle, PVOID pReserved, WLAN_INTERFACE_INFO_LIST **ppInterfaceList);
+typedef DWORD (WINAPI *WlanGetAvailableNetworkListProto)
+ (HANDLE hClientHandle, const GUID* pInterfaceGuid, DWORD dwFlags, PVOID pReserved,
+ WLAN_AVAILABLE_NETWORK_LIST **ppAvailableNetworkList);
+typedef DWORD (WINAPI *WlanQueryInterfaceProto)
+ (HANDLE hClientHandle, const GUID *pInterfaceGuid, WLAN_INTF_OPCODE OpCode, PVOID pReserved,
+ PDWORD pdwDataSize, PVOID *ppData, WLAN_OPCODE_VALUE_TYPE *pWlanOpcodeValueType);
+typedef DWORD (WINAPI *WlanConnectProto)
+ (HANDLE hClientHandle, const GUID *pInterfaceGuid,
+ const WLAN_CONNECTION_PARAMETERS *pConnectionParameters, PVOID pReserved);
+typedef DWORD (WINAPI *WlanDisconnectProto)
+ (HANDLE hClientHandle, const GUID *pInterfaceGuid, PVOID pReserved);
+typedef DWORD (WINAPI *WlanScanProto)
+ (HANDLE hClientHandle, const GUID *pInterfaceGuid, const DOT11_SSID *pDot11Ssid,
+ const WLAN_RAW_DATA *pIeData, PVOID pReserved);
+typedef VOID (WINAPI *WlanFreeMemoryProto)(PVOID pMemory);
+typedef DWORD (WINAPI *WlanCloseHandleProto)(HANDLE hClientHandle, PVOID pReserved);
+
+extern WlanOpenHandleProto local_WlanOpenHandle;
+extern WlanRegisterNotificationProto local_WlanRegisterNotification;
+extern WlanEnumInterfacesProto local_WlanEnumInterfaces;
+extern WlanGetAvailableNetworkListProto local_WlanGetAvailableNetworkList;
+extern WlanQueryInterfaceProto local_WlanQueryInterface;
+extern WlanConnectProto local_WlanConnect;
+extern WlanDisconnectProto local_WlanDisconnect;
+extern WlanScanProto local_WlanScan;
+extern WlanFreeMemoryProto local_WlanFreeMemory;
+extern WlanCloseHandleProto local_WlanCloseHandle;
+
+#endif // PLATFORMDEFS_H
diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp
new file mode 100644
index 0000000000..c8015d88a4
--- /dev/null
+++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp
@@ -0,0 +1,495 @@
+/****************************************************************************
+**
+** 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 "qnativewifiengine.h"
+#include "platformdefs.h"
+#include "../qnetworksession_impl.h"
+
+#include <QtNetwork/private/qnetworkconfiguration_p.h>
+
+#include <QtCore/qstringlist.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+WlanOpenHandleProto local_WlanOpenHandle = 0;
+WlanRegisterNotificationProto local_WlanRegisterNotification = 0;
+WlanEnumInterfacesProto local_WlanEnumInterfaces = 0;
+WlanGetAvailableNetworkListProto local_WlanGetAvailableNetworkList = 0;
+WlanQueryInterfaceProto local_WlanQueryInterface = 0;
+WlanConnectProto local_WlanConnect = 0;
+WlanDisconnectProto local_WlanDisconnect = 0;
+WlanScanProto local_WlanScan = 0;
+WlanFreeMemoryProto local_WlanFreeMemory = 0;
+WlanCloseHandleProto local_WlanCloseHandle = 0;
+
+void qNotificationCallback(WLAN_NOTIFICATION_DATA *data, QNativeWifiEngine *d)
+{
+ Q_UNUSED(d);
+
+ switch (data->NotificationCode) {
+ case wlan_notification_acm_connection_complete:
+ case wlan_notification_acm_disconnected:
+ QMetaObject::invokeMethod(d, "scanComplete", Qt::QueuedConnection);
+ break;
+ default:
+ ;
+ }
+}
+
+QNativeWifiEngine::QNativeWifiEngine(QObject *parent)
+: QBearerEngineImpl(parent), handle(0)
+{
+ DWORD clientVersion;
+
+ DWORD result = local_WlanOpenHandle(1, 0, &clientVersion, &handle);
+ if (result != ERROR_SUCCESS) {
+ if (result != ERROR_SERVICE_NOT_ACTIVE)
+ qWarning("%s: WlanOpenHandle failed with error %ld\n", __FUNCTION__, result);
+
+ return;
+ }
+
+ result = local_WlanRegisterNotification(handle, WLAN_NOTIFICATION_SOURCE_ALL, true,
+ WLAN_NOTIFICATION_CALLBACK(qNotificationCallback),
+ this, 0, 0);
+ if (result != ERROR_SUCCESS)
+ qWarning("%s: WlanRegisterNotification failed with error %ld\n", __FUNCTION__, result);
+
+ // On Windows XP SP2 and SP3 only connection and disconnection notifications are available.
+ // We need to poll for changes in available wireless networks.
+ connect(&pollTimer, SIGNAL(timeout()), this, SLOT(scanComplete()));
+ pollTimer.setInterval(10000);
+ scanComplete();
+}
+
+QNativeWifiEngine::~QNativeWifiEngine()
+{
+ local_WlanCloseHandle(handle, 0);
+}
+
+void QNativeWifiEngine::scanComplete()
+{
+ QMutexLocker locker(&mutex);
+
+ QStringList previous = accessPointConfigurations.keys();
+
+ // enumerate interfaces
+ WLAN_INTERFACE_INFO_LIST *interfaceList;
+ DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
+ return;
+ }
+
+ for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
+ const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
+
+ WLAN_AVAILABLE_NETWORK_LIST *networkList;
+ result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
+ 3, 0, &networkList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n",
+ __FUNCTION__, result);
+ continue;
+ }
+
+ QStringList seenNetworks;
+
+ for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
+ WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];
+
+ QString networkName;
+
+ if (network.strProfileName[0] != 0) {
+ networkName = QString::fromWCharArray(network.strProfileName);
+ } else {
+ networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID),
+ network.dot11Ssid.uSSIDLength);
+ }
+
+ const QString id = QString::number(qHash(QLatin1String("WLAN:") + networkName));
+
+ previous.removeAll(id);
+
+ QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+
+ if (!(network.dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE))
+ state = QNetworkConfiguration::Undefined;
+
+ if (network.strProfileName[0] != 0) {
+ if (network.bNetworkConnectable) {
+ if (network.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
+ state = QNetworkConfiguration::Active;
+ else
+ state = QNetworkConfiguration::Discovered;
+ } else {
+ state = QNetworkConfiguration::Defined;
+ }
+ }
+
+ if (seenNetworks.contains(networkName))
+ continue;
+ else
+ seenNetworks.append(networkName);
+
+ if (accessPointConfigurations.contains(id)) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ bool changed = false;
+
+ if (!ptr->isValid) {
+ ptr->isValid = true;
+ changed = true;
+ }
+
+ if (ptr->name != networkName) {
+ ptr->name = networkName;
+ changed = true;
+ }
+
+ if (ptr->state != state) {
+ ptr->state = state;
+ changed = true;
+ }
+
+ if (changed)
+ emit configurationChanged(ptr);
+ } else {
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+
+ ptr->name = networkName;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->state = state;
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->bearer = QLatin1String("WLAN");
+
+ accessPointConfigurations.insert(id, ptr);
+
+ emit configurationAdded(ptr);
+ }
+ }
+
+ local_WlanFreeMemory(networkList);
+ }
+
+ local_WlanFreeMemory(interfaceList);
+
+ while (!previous.isEmpty()) {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.take(previous.takeFirst());
+
+ emit configurationRemoved(ptr);
+ }
+
+ pollTimer.start();
+
+ emit updateCompleted();
+}
+
+QString QNativeWifiEngine::getInterfaceFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ // enumerate interfaces
+ WLAN_INTERFACE_INFO_LIST *interfaceList;
+ DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
+ return QString();
+ }
+
+ for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
+ const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
+
+ DWORD dataSize;
+ WLAN_CONNECTION_ATTRIBUTES *connectionAttributes;
+ result = local_WlanQueryInterface(handle, &interface.InterfaceGuid,
+ wlan_intf_opcode_current_connection, 0, &dataSize,
+ reinterpret_cast<PVOID *>(&connectionAttributes), 0);
+ if (result != ERROR_SUCCESS) {
+ if (result != ERROR_INVALID_STATE)
+ qWarning("%s: WlanQueryInterface failed with error %ld\n", __FUNCTION__, result);
+
+ continue;
+ }
+
+ if (qHash(QLatin1String("WLAN:") +
+ QString::fromWCharArray(connectionAttributes->strProfileName)) == id.toUInt()) {
+ QString guid("{%1-%2-%3-%4%5-%6%7%8%9%10%11}");
+
+ guid = guid.arg(interface.InterfaceGuid.Data1, 8, 16, QChar('0'));
+ guid = guid.arg(interface.InterfaceGuid.Data2, 4, 16, QChar('0'));
+ guid = guid.arg(interface.InterfaceGuid.Data3, 4, 16, QChar('0'));
+ for (int i = 0; i < 8; ++i)
+ guid = guid.arg(interface.InterfaceGuid.Data4[i], 2, 16, QChar('0'));
+
+ local_WlanFreeMemory(connectionAttributes);
+ local_WlanFreeMemory(interfaceList);
+
+ return guid.toUpper();
+ }
+
+ local_WlanFreeMemory(connectionAttributes);
+ }
+
+ local_WlanFreeMemory(interfaceList);
+
+ return QString();
+}
+
+bool QNativeWifiEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ // enumerate interfaces
+ WLAN_INTERFACE_INFO_LIST *interfaceList;
+ DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
+ return false;
+ }
+
+ for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
+ const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
+
+ WLAN_AVAILABLE_NETWORK_LIST *networkList;
+ result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
+ 3, 0, &networkList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n",
+ __FUNCTION__, result);
+ continue;
+ }
+
+ for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
+ WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];
+
+ QString networkName;
+
+ if (network.strProfileName[0] != 0) {
+ networkName = QString::fromWCharArray(network.strProfileName);
+ } else {
+ networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID),
+ network.dot11Ssid.uSSIDLength);
+ }
+
+ if (qHash(QLatin1String("WLAN:") + networkName) == id.toUInt()) {
+ local_WlanFreeMemory(networkList);
+ local_WlanFreeMemory(interfaceList);
+ return true;
+ }
+ }
+
+ local_WlanFreeMemory(networkList);
+ }
+
+ local_WlanFreeMemory(interfaceList);
+
+ return false;
+}
+
+/*QString QNativeWifiEngine::bearerName(const QString &)
+{
+ return QLatin1String("WLAN");
+}*/
+
+void QNativeWifiEngine::connectToId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ WLAN_INTERFACE_INFO_LIST *interfaceList;
+ DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
+ emit connectionError(id, InterfaceLookupError);
+ return;
+ }
+
+ QString profile;
+
+ for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
+ const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
+
+ WLAN_AVAILABLE_NETWORK_LIST *networkList;
+ result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
+ 3, 0, &networkList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n",
+ __FUNCTION__, result);
+ continue;
+ }
+
+ for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
+ WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];
+
+ profile = QString::fromWCharArray(network.strProfileName);
+
+ if (qHash(QLatin1String("WLAN:") + profile) == id.toUInt())
+ break;
+ else
+ profile.clear();
+ }
+
+ local_WlanFreeMemory(networkList);
+
+ if (!profile.isEmpty()) {
+ WLAN_CONNECTION_PARAMETERS parameters;
+ parameters.wlanConnectionMode = wlan_connection_mode_profile;
+ parameters.strProfile = reinterpret_cast<LPCWSTR>(profile.utf16());
+ parameters.pDot11Ssid = 0;
+ parameters.pDesiredBssidList = 0;
+ parameters.dot11BssType = dot11_BSS_type_any;
+ parameters.dwFlags = 0;
+
+ DWORD result = local_WlanConnect(handle, &interface.InterfaceGuid, &parameters, 0);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanConnect failed with error %ld\n", __FUNCTION__, result);
+ emit connectionError(id, ConnectError);
+ break;
+ }
+
+ break;
+ }
+ }
+
+ local_WlanFreeMemory(interfaceList);
+
+ if (profile.isEmpty())
+ emit connectionError(id, InterfaceLookupError);
+}
+
+void QNativeWifiEngine::disconnectFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QString interface = getInterfaceFromId(id);
+
+ if (interface.isEmpty()) {
+ emit connectionError(id, InterfaceLookupError);
+ return;
+ }
+
+ QStringList split = interface.mid(1, interface.length() - 2).split('-');
+
+ GUID guid;
+ guid.Data1 = split.at(0).toUInt(0, 16);
+ guid.Data2 = split.at(1).toUShort(0, 16);
+ guid.Data3 = split.at(2).toUShort(0, 16);
+ guid.Data4[0] = split.at(3).left(2).toUShort(0, 16);
+ guid.Data4[1] = split.at(3).right(2).toUShort(0, 16);
+ for (int i = 0; i < 6; ++i)
+ guid.Data4[i + 2] = split.at(4).mid(i*2, 2).toUShort(0, 16);
+
+ DWORD result = local_WlanDisconnect(handle, &guid, 0);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanDisconnect failed with error %ld\n", __FUNCTION__, result);
+ emit connectionError(id, DisconnectionError);
+ return;
+ }
+}
+
+void QNativeWifiEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ // enumerate interfaces
+ WLAN_INTERFACE_INFO_LIST *interfaceList;
+ DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
+ if (result != ERROR_SUCCESS) {
+ qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
+ return;
+ }
+
+ for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
+ result = local_WlanScan(handle, &interfaceList->InterfaceInfo[i].InterfaceGuid, 0, 0, 0);
+ if (result != ERROR_SUCCESS)
+ qWarning("%s: WlanScan failed with error %ld\n", __FUNCTION__, result);
+ }
+
+ local_WlanFreeMemory(interfaceList);
+}
+
+QNetworkSession::State QNativeWifiEngine::sessionStateForId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ if (!ptr)
+ return QNetworkSession::Invalid;
+
+ if (!ptr->isValid) {
+ return QNetworkSession::Invalid;
+ } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ return QNetworkSession::Connected;
+ } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ return QNetworkSession::Disconnected;
+ } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+ return QNetworkSession::NotAvailable;
+ } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
+ QNetworkConfiguration::Undefined) {
+ return QNetworkSession::NotAvailable;
+ }
+
+ return QNetworkSession::Invalid;
+}
+
+QNetworkConfigurationManager::Capabilities QNativeWifiEngine::capabilities() const
+{
+ return QNetworkConfigurationManager::ForcedRoaming |
+ QNetworkConfigurationManager::CanStartAndStopInterfaces;
+}
+
+QNetworkSessionPrivate *QNativeWifiEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl;
+}
+
+QNetworkConfigurationPrivatePointer QNativeWifiEngine::defaultConfiguration()
+{
+ return QNetworkConfigurationPrivatePointer();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.h b/src/plugins/bearer/nativewifi/qnativewifiengine.h
new file mode 100644
index 0000000000..a9a9375d4d
--- /dev/null
+++ b/src/plugins/bearer/nativewifi/qnativewifiengine.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 QNATIVEWIFIENGINE_P_H
+#define QNATIVEWIFIENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "../qbearerengine_impl.h"
+
+#include <QtCore/qtimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkConfigurationPrivate;
+struct WLAN_NOTIFICATION_DATA;
+
+class QNativeWifiEngine : public QBearerEngineImpl
+{
+ Q_OBJECT
+
+public:
+ QNativeWifiEngine(QObject *parent = 0);
+ ~QNativeWifiEngine();
+
+ QString getInterfaceFromId(const QString &id);
+ bool hasIdentifier(const QString &id);
+
+ //QString bearerName(const QString &id);
+
+ void connectToId(const QString &id);
+ void disconnectFromId(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkSession::State sessionStateForId(const QString &id);
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+ inline bool available() const { return handle != 0; }
+
+public Q_SLOTS:
+ void scanComplete();
+
+private:
+ QTimer pollTimer;
+
+ Qt::HANDLE handle;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/bearer/networkmanager/main.cpp b/src/plugins/bearer/networkmanager/main.cpp
new file mode 100644
index 0000000000..6c97a22ae7
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/main.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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 "qnetworkmanagerengine.h"
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkManagerEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QNetworkManagerEnginePlugin();
+ ~QNetworkManagerEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QNetworkManagerEnginePlugin::QNetworkManagerEnginePlugin()
+{
+}
+
+QNetworkManagerEnginePlugin::~QNetworkManagerEnginePlugin()
+{
+}
+
+QStringList QNetworkManagerEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("networkmanager");
+}
+
+QBearerEngine *QNetworkManagerEnginePlugin::create(const QString &key) const
+{
+ if (key == QLatin1String("networkmanager")) {
+ QNetworkManagerEngine *engine = new QNetworkManagerEngine;
+ if (engine->networkManagerAvailable())
+ return engine;
+ else
+ delete engine;
+ }
+
+ return 0;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QNetworkManagerEnginePlugin)
+Q_EXPORT_PLUGIN2(qnmbearer, QNetworkManagerEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro
new file mode 100644
index 0000000000..bf0d29a7bc
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/networkmanager.pro
@@ -0,0 +1,20 @@
+TARGET = qnmbearer
+include(../../qpluginbase.pri)
+
+QT += network dbus
+
+HEADERS += qnmdbushelper.h \
+ qnetworkmanagerservice.h \
+ qnetworkmanagerengine.h \
+ ../qnetworksession_impl.h \
+ ../qbearerengine_impl.h
+
+SOURCES += main.cpp \
+ qnmdbushelper.cpp \
+ qnetworkmanagerservice.cpp \
+ qnetworkmanagerengine.cpp \
+ ../qnetworksession_impl.cpp
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
new file mode 100644
index 0000000000..5c6efe3826
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -0,0 +1,847 @@
+/****************************************************************************
+**
+** 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 "qnetworkmanagerengine.h"
+#include "qnetworkmanagerservice.h"
+#include "../qnetworksession_impl.h"
+
+#include <QtNetwork/private/qnetworkconfiguration_p.h>
+
+#include <QtNetwork/qnetworksession.h>
+
+#include <QtCore/qdebug.h>
+
+#include <NetworkManager/NetworkManager.h>
+#include <QtDBus>
+#include <QDBusConnection>
+#include <QDBusError>
+#include <QDBusInterface>
+#include <QDBusMessage>
+#include <QDBusReply>
+
+QT_BEGIN_NAMESPACE
+
+QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent)
+: QBearerEngineImpl(parent),
+ interface(new QNetworkManagerInterface(this)),
+ systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE_SYSTEM_SETTINGS, this)),
+ userSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE_USER_SETTINGS, this))
+{
+ if (!interface->isValid())
+ return;
+
+ interface->setConnections();
+ connect(interface, SIGNAL(deviceAdded(QDBusObjectPath)),
+ this, SLOT(deviceAdded(QDBusObjectPath)));
+ connect(interface, SIGNAL(deviceRemoved(QDBusObjectPath)),
+ this, SLOT(deviceRemoved(QDBusObjectPath)));
+#if 0
+ connect(interface, SIGNAL(stateChanged(const QString,quint32)),
+ this, SIGNAL(configurationsChanged()));
+#endif
+ connect(interface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)),
+ this, SLOT(activationFinished(QDBusPendingCallWatcher*)));
+ connect(interface, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
+ this, SLOT(interfacePropertiesChanged(QString,QMap<QString,QVariant>)));
+
+ qDBusRegisterMetaType<QNmSettingsMap>();
+
+ systemSettings->setConnections();
+ connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)),
+ this, SLOT(newConnection(QDBusObjectPath)));
+
+ userSettings->setConnections();
+ connect(userSettings, SIGNAL(newConnection(QDBusObjectPath)),
+ this, SLOT(newConnection(QDBusObjectPath)));
+
+ // Get current list of access points.
+ foreach (const QDBusObjectPath &devicePath, interface->getDevices())
+ deviceAdded(devicePath);
+
+ // Get connections.
+ foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections())
+ newConnection(settingsPath, systemSettings);
+ foreach (const QDBusObjectPath &settingsPath, userSettings->listConnections())
+ newConnection(settingsPath, userSettings);
+
+ // Get active connections.
+ foreach (const QDBusObjectPath &acPath, interface->activeConnections()) {
+ QNetworkManagerConnectionActive *activeConnection =
+ new QNetworkManagerConnectionActive(acPath.path());
+ activeConnections.insert(acPath.path(), activeConnection);
+
+ activeConnection->setConnections();
+ connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
+ this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>)));
+ }
+}
+
+QNetworkManagerEngine::~QNetworkManagerEngine()
+{
+}
+
+bool QNetworkManagerEngine::networkManagerAvailable() const
+{
+ QMutexLocker locker(&mutex);
+
+ return interface->isValid();
+}
+
+void QNetworkManagerEngine::doRequestUpdate()
+{
+ emit updateCompleted();
+}
+
+QString QNetworkManagerEngine::getInterfaceFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ foreach (const QDBusObjectPath &acPath, interface->activeConnections()) {
+ QNetworkManagerConnectionActive activeConnection(acPath.path());
+
+ const QString identifier = QString::number(qHash(activeConnection.serviceName() + ' ' +
+ activeConnection.connection().path()));
+
+ if (id == identifier) {
+ QList<QDBusObjectPath> devices = activeConnection.devices();
+
+ if (devices.isEmpty())
+ continue;
+
+ QNetworkManagerInterfaceDevice device(devices.at(0).path());
+ return device.interface().name();
+ }
+ }
+
+ return QString();
+}
+
+bool QNetworkManagerEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ if (connectionFromId(id))
+ return true;
+
+ for (int i = 0; i < accessPoints.count(); ++i) {
+ QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i);
+
+ const QString identifier =
+ QString::number(qHash(accessPoint->connectionInterface()->path()));
+
+ if (id == identifier)
+ return true;
+ }
+
+ return false;
+}
+
+QString QNetworkManagerEngine::bearerName(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkManagerSettingsConnection *connection = connectionFromId(id);
+
+ if (!connection)
+ return QString();
+
+ QNmSettingsMap map = connection->getSettings();
+ const QString connectionType = map.value("connection").value("type").toString();
+
+ if (connectionType == "802-3-ethernet")
+ return QLatin1String("Ethernet");
+ else if (connectionType == "802-11-wireless")
+ return QLatin1String("WLAN");
+ else if (connectionType == "gsm")
+ return QLatin1String("2G");
+ else if (connectionType == "cdma")
+ return QLatin1String("CDMA2000");
+ else
+ return QString();
+}
+
+void QNetworkManagerEngine::connectToId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkManagerSettingsConnection *connection = connectionFromId(id);
+
+ if (!connection)
+ return;
+
+ QNmSettingsMap map = connection->getSettings();
+ const QString connectionType = map.value("connection").value("type").toString();
+
+ QString dbusDevicePath;
+ foreach (const QDBusObjectPath &devicePath, interface->getDevices()) {
+ QNetworkManagerInterfaceDevice device(devicePath.path());
+ if (device.deviceType() == DEVICE_TYPE_802_3_ETHERNET &&
+ connectionType == QLatin1String("802-3-ethernet")) {
+ dbusDevicePath = devicePath.path();
+ break;
+ } else if (device.deviceType() == DEVICE_TYPE_802_11_WIRELESS &&
+ connectionType == QLatin1String("802-11-wireless")) {
+ dbusDevicePath = devicePath.path();
+ break;
+ }
+ }
+
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+
+ interface->activateConnection(service, QDBusObjectPath(settingsPath),
+ QDBusObjectPath(dbusDevicePath), QDBusObjectPath("/"));
+}
+
+void QNetworkManagerEngine::disconnectFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ foreach (const QDBusObjectPath &acPath, interface->activeConnections()) {
+ QNetworkManagerConnectionActive activeConnection(acPath.path());
+
+ const QString identifier = QString::number(qHash(activeConnection.serviceName() + ' ' +
+ activeConnection.connection().path()));
+
+ if (id == identifier && accessPointConfigurations.contains(id)) {
+ interface->deactivateConnection(acPath);
+ break;
+ }
+ }
+}
+
+void QNetworkManagerEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ QTimer::singleShot(0, this, SLOT(doRequestUpdate()));
+}
+
+void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
+ const QMap<QString, QVariant> &properties)
+{
+ QMutexLocker locker(&mutex);
+
+ Q_UNUSED(path)
+
+ QMapIterator<QString, QVariant> i(properties);
+ while (i.hasNext()) {
+ i.next();
+
+ if (i.key() == QLatin1String("ActiveConnections")) {
+ // Active connections changed, update configurations.
+
+ QList<QDBusObjectPath> activeConnections =
+ qdbus_cast<QList<QDBusObjectPath> >(i.value().value<QDBusArgument>());
+
+ QStringList identifiers = accessPointConfigurations.keys();
+ foreach (const QString &id, identifiers)
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ QStringList priorActiveConnections = this->activeConnections.keys();
+
+ foreach (const QDBusObjectPath &acPath, activeConnections) {
+ priorActiveConnections.removeOne(acPath.path());
+ QNetworkManagerConnectionActive *activeConnection =
+ this->activeConnections.value(acPath.path());
+ if (!activeConnection) {
+ activeConnection = new QNetworkManagerConnectionActive(acPath.path());
+ this->activeConnections.insert(acPath.path(), activeConnection);
+
+ activeConnection->setConnections();
+ connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
+ this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>)));
+ }
+
+ const QString id = QString::number(qHash(activeConnection->serviceName() + ' ' +
+ activeConnection->connection().path()));
+
+ identifiers.removeOne(id);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+ if (ptr) {
+ if (activeConnection->state() == 2 &&
+ ptr->state != QNetworkConfiguration::Active) {
+ ptr->state = QNetworkConfiguration::Active;
+ emit configurationChanged(ptr);
+ }
+ }
+ }
+
+ while (!priorActiveConnections.isEmpty())
+ delete this->activeConnections.take(priorActiveConnections.takeFirst());
+
+ while (!identifiers.isEmpty()) {
+ // These configurations are not active
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.value(identifiers.takeFirst());
+
+ if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ ptr->state = QNetworkConfiguration::Discovered;
+ emit configurationChanged(ptr);
+ }
+ }
+ }
+ }
+}
+
+void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &path,
+ const QMap<QString, QVariant> &properties)
+{
+ QMutexLocker locker(&mutex);
+
+ Q_UNUSED(properties)
+
+ QNetworkManagerConnectionActive *activeConnection = activeConnections.value(path);
+
+ if (!activeConnection)
+ return;
+
+ const QString id = QString::number(qHash(activeConnection->serviceName() + ' ' +
+ activeConnection->connection().path()));
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+ if (ptr) {
+ if (activeConnection->state() == 2 &&
+ ptr->state != QNetworkConfiguration::Active) {
+ ptr->state = QNetworkConfiguration::Active;
+ emit configurationChanged(ptr);
+ }
+ }
+}
+
+void QNetworkManagerEngine::devicePropertiesChanged(const QString &path,
+ const QMap<QString, QVariant> &properties)
+{
+ Q_UNUSED(path);
+ Q_UNUSED(properties);
+}
+
+void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkManagerInterfaceDevice device(path.path());
+ if (device.deviceType() == DEVICE_TYPE_802_11_WIRELESS) {
+ QNetworkManagerInterfaceDeviceWireless *wirelessDevice =
+ new QNetworkManagerInterfaceDeviceWireless(device.connectionInterface()->path());
+ wirelessDevices.insert(path.path(), wirelessDevice);
+
+ wirelessDevice->setConnections();
+ connect(wirelessDevice, SIGNAL(accessPointAdded(QString,QDBusObjectPath)),
+ this, SLOT(newAccessPoint(QString,QDBusObjectPath)));
+ connect(wirelessDevice, SIGNAL(accessPointRemoved(QString,QDBusObjectPath)),
+ this, SLOT(removeAccessPoint(QString,QDBusObjectPath)));
+ connect(wirelessDevice, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
+ this, SLOT(devicePropertiesChanged(QString,QMap<QString,QVariant>)));
+
+ foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints())
+ newAccessPoint(QString(), apPath);
+ }
+}
+
+void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path)
+{
+ QMutexLocker locker(&mutex);
+
+ delete wirelessDevices.value(path.path());
+}
+
+void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path,
+ QNetworkManagerSettings *settings)
+{
+ QMutexLocker locker(&mutex);
+
+ if (!settings)
+ settings = qobject_cast<QNetworkManagerSettings *>(sender());
+
+ if (!settings)
+ return;
+
+ QNetworkManagerSettingsConnection *connection =
+ new QNetworkManagerSettingsConnection(settings->connectionInterface()->service(),
+ path.path());
+ connections.append(connection);
+
+ connect(connection, SIGNAL(removed(QString)), this, SLOT(removeConnection(QString)));
+ connect(connection, SIGNAL(updated(const QNmSettingsMap&)),
+ this, SLOT(updateConnection(const QNmSettingsMap&)));
+
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+
+ QNetworkConfigurationPrivate *cpPriv =
+ parseConnection(service, settingsPath, connection->getSettings());
+
+ // Check if connection is active.
+ foreach (const QDBusObjectPath &acPath, interface->activeConnections()) {
+ QNetworkManagerConnectionActive activeConnection(acPath.path());
+
+ if (activeConnection.serviceName() == service &&
+ activeConnection.connection().path() == settingsPath &&
+ activeConnection.state() == 2) {
+ cpPriv->state |= QNetworkConfiguration::Active;
+ break;
+ }
+ }
+
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ accessPointConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+}
+
+void QNetworkManagerEngine::removeConnection(const QString &path)
+{
+ QMutexLocker locker(&mutex);
+
+ Q_UNUSED(path)
+
+ QNetworkManagerSettingsConnection *connection =
+ qobject_cast<QNetworkManagerSettingsConnection *>(sender());
+ if (!connection)
+ return;
+
+ connections.removeAll(connection);
+
+ const QString id = QString::number(qHash(connection->connectionInterface()->service() + ' ' +
+ connection->connectionInterface()->path()));
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id);
+ ptr->isValid = false;
+ emit configurationRemoved(ptr);
+}
+
+void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkManagerSettingsConnection *connection =
+ qobject_cast<QNetworkManagerSettingsConnection *>(sender());
+ if (!connection)
+ return;
+
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+
+ QNetworkConfigurationPrivate *cpPriv = parseConnection(service, settingsPath, settings);
+
+ // Check if connection is active.
+ foreach (const QDBusObjectPath &acPath, interface->activeConnections()) {
+ QNetworkManagerConnectionActive activeConnection(acPath.path());
+
+ if (activeConnection.serviceName() == service &&
+ activeConnection.connection().path() == settingsPath &&
+ activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
+ cpPriv->state |= QNetworkConfiguration::Active;
+ break;
+ }
+ }
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id);
+
+ ptr->isValid = cpPriv->isValid;
+ ptr->name = cpPriv->name;
+ ptr->id = cpPriv->id;
+ ptr->state = cpPriv->state;
+
+ emit configurationChanged(ptr);
+ delete cpPriv;
+}
+
+void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher)
+{
+ QMutexLocker locker(&mutex);
+
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+ if (!reply.isError()) {
+ QDBusObjectPath result = reply.value();
+
+ QNetworkManagerConnectionActive activeConnection(result.path());
+
+ const QString id = QString::number(qHash(activeConnection.serviceName() + ' ' +
+ activeConnection.connection().path()));
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+ if (ptr) {
+ if (activeConnection.state() == 2 &&
+ ptr->state != QNetworkConfiguration::Active) {
+ ptr->state = QNetworkConfiguration::Active;
+ emit configurationChanged(ptr);
+ }
+ }
+ }
+}
+
+void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjectPath &objectPath)
+{
+ QMutexLocker locker(&mutex);
+
+ Q_UNUSED(path)
+
+ QNetworkManagerInterfaceAccessPoint *accessPoint =
+ new QNetworkManagerInterfaceAccessPoint(objectPath.path());
+ accessPoints.append(accessPoint);
+
+ accessPoint->setConnections();
+ connect(accessPoint, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
+ this, SLOT(updateAccessPoint(QMap<QString,QVariant>)));
+
+ // Check if configuration for this SSID already exists.
+ for (int i = 0; i < accessPoints.count(); ++i) {
+ if (accessPoint != accessPoints.at(i) &&
+ accessPoint->ssid() == accessPoints.at(i)->ssid()) {
+ return;
+ }
+ }
+
+ // Check if configuration exists for connection.
+ if (!accessPoint->ssid().isEmpty()) {
+ for (int i = 0; i < connections.count(); ++i) {
+ QNetworkManagerSettingsConnection *connection = connections.at(i);
+
+ if (accessPoint->ssid() == connection->getSsid()) {
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+ const QString connectionId = QString::number(qHash(service + ' ' + settingsPath));
+
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.value(connectionId);
+ ptr->state = QNetworkConfiguration::Discovered;
+ emit configurationChanged(ptr);
+ return;
+ }
+ }
+ }
+
+ // New access point.
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+
+ ptr->name = accessPoint->ssid();
+ ptr->isValid = true;
+ ptr->id = QString::number(qHash(objectPath.path()));
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->purpose = QNetworkConfiguration::PublicPurpose;
+ ptr->state = QNetworkConfiguration::Undefined;
+ ptr->bearer = QLatin1String("WLAN");
+
+ accessPointConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+}
+
+void QNetworkManagerEngine::removeAccessPoint(const QString &path,
+ const QDBusObjectPath &objectPath)
+{
+ QMutexLocker locker(&mutex);
+
+ Q_UNUSED(path)
+
+ for (int i = 0; i < accessPoints.count(); ++i) {
+ QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i);
+
+ if (accessPoint->connectionInterface()->path() == objectPath.path()) {
+ accessPoints.removeOne(accessPoint);
+
+ if (configuredAccessPoints.contains(accessPoint)) {
+ // find connection and change state to Defined
+ configuredAccessPoints.removeOne(accessPoint);
+ for (int i = 0; i < connections.count(); ++i) {
+ QNetworkManagerSettingsConnection *connection = connections.at(i);
+
+ if (accessPoint->ssid() == connection->getSsid()) {
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+ const QString connectionId =
+ QString::number(qHash(service + ' ' + settingsPath));
+
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.value(connectionId);
+ ptr->state = QNetworkConfiguration::Defined;
+ emit configurationChanged(ptr);
+ return;
+ }
+ }
+ } else {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.take(QString::number(qHash(objectPath.path())));
+
+ if (ptr)
+ emit configurationRemoved(ptr);
+ }
+
+ delete accessPoint;
+
+ break;
+ }
+ }
+}
+
+void QNetworkManagerEngine::updateAccessPoint(const QMap<QString, QVariant> &map)
+{
+ QMutexLocker locker(&mutex);
+
+ Q_UNUSED(map)
+
+ QNetworkManagerInterfaceAccessPoint *accessPoint =
+ qobject_cast<QNetworkManagerInterfaceAccessPoint *>(sender());
+ if (!accessPoint)
+ return;
+
+ for (int i = 0; i < connections.count(); ++i) {
+ QNetworkManagerSettingsConnection *connection = connections.at(i);
+
+ if (accessPoint->ssid() == connection->getSsid()) {
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+ const QString connectionId = QString::number(qHash(service + ' ' + settingsPath));
+
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.value(connectionId);
+ ptr->state = QNetworkConfiguration::Discovered;
+ emit configurationChanged(ptr);
+ return;
+ }
+ }
+}
+
+QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &service,
+ const QString &settingsPath,
+ const QNmSettingsMap &map)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate;
+ cpPriv->name = map.value("connection").value("id").toString();
+ cpPriv->isValid = true;
+ cpPriv->id = QString::number(qHash(service + ' ' + settingsPath));
+ cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
+
+ cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
+
+ cpPriv->state = QNetworkConfiguration::Defined;
+
+ const QString connectionType = map.value("connection").value("type").toString();
+
+ if (connectionType == QLatin1String("802-3-ethernet")) {
+ cpPriv->bearer = QLatin1String("Ethernet");
+
+ foreach (const QDBusObjectPath &devicePath, interface->getDevices()) {
+ QNetworkManagerInterfaceDevice device(devicePath.path());
+ if (device.deviceType() == DEVICE_TYPE_802_3_ETHERNET) {
+ QNetworkManagerInterfaceDeviceWired wiredDevice(device.connectionInterface()->path());
+ if (wiredDevice.carrier()) {
+ cpPriv->state |= QNetworkConfiguration::Discovered;
+ break;
+ }
+
+ }
+ }
+ } else if (connectionType == QLatin1String("802-11-wireless")) {
+ cpPriv->bearer = QLatin1String("WLAN");
+
+ const QString connectionSsid = map.value("802-11-wireless").value("ssid").toString();
+
+ for (int i = 0; i < accessPoints.count(); ++i) {
+ if (connectionSsid == accessPoints.at(i)->ssid()) {
+ cpPriv->state |= QNetworkConfiguration::Discovered;
+ if (!configuredAccessPoints.contains(accessPoints.at(i))) {
+ configuredAccessPoints.append(accessPoints.at(i));
+
+ const QString accessPointId =
+ QString::number(qHash(accessPoints.at(i)->connectionInterface()->path()));
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.take(accessPointId);
+ emit configurationRemoved(ptr);
+ }
+ break;
+ }
+ }
+ } else if (connectionType == "gsm") {
+ cpPriv->bearer = QLatin1String("2G");
+ } else if (connectionType == "cdma") {
+ cpPriv->bearer = QLatin1String("CDMA2000");
+ }
+
+ return cpPriv;
+}
+
+QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const QString &id) const
+{
+ QMutexLocker locker(&mutex);
+
+ for (int i = 0; i < connections.count(); ++i) {
+ QNetworkManagerSettingsConnection *connection = connections.at(i);
+ const QString service = connection->connectionInterface()->service();
+ const QString settingsPath = connection->connectionInterface()->path();
+
+ const QString identifier = QString::number(qHash(service + ' ' + settingsPath));
+
+ if (id == identifier)
+ return connection;
+ }
+
+ return 0;
+}
+
+QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ if (!ptr)
+ return QNetworkSession::Invalid;
+
+ if (!ptr->isValid)
+ return QNetworkSession::Invalid;
+
+ foreach (const QString &acPath, activeConnections.keys()) {
+ QNetworkManagerConnectionActive *activeConnection = activeConnections.value(acPath);
+
+ const QString identifier = QString::number(qHash(activeConnection->serviceName() + ' ' +
+ activeConnection->connection().path()));
+
+ if (id == identifier) {
+ switch (activeConnection->state()) {
+ case 0:
+ return QNetworkSession::Disconnected;
+ case 1:
+ return QNetworkSession::Connecting;
+ case 2:
+ return QNetworkSession::Connected;
+ }
+ }
+ }
+
+ if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered)
+ return QNetworkSession::Disconnected;
+ else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined)
+ return QNetworkSession::NotAvailable;
+ else if ((ptr->state & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined)
+ return QNetworkSession::NotAvailable;
+
+ return QNetworkSession::Invalid;
+}
+
+quint64 QNetworkManagerEngine::bytesWritten(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+ if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ const QString networkInterface = getInterfaceFromId(id);
+ if (!networkInterface.isEmpty()) {
+ const QString devFile = QLatin1String("/sys/class/net/") +
+ networkInterface +
+ QLatin1String("/statistics/tx_bytes");
+
+ quint64 result = Q_UINT64_C(0);
+
+ QFile tx(devFile);
+ if (tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&tx);
+ in >> result;
+ tx.close();
+ }
+
+ return result;
+ }
+ }
+
+ return Q_UINT64_C(0);
+}
+
+quint64 QNetworkManagerEngine::bytesReceived(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+ if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ const QString networkInterface = getInterfaceFromId(id);
+ if (!networkInterface.isEmpty()) {
+ const QString devFile = QLatin1String("/sys/class/net/") +
+ networkInterface +
+ QLatin1String("/statistics/rx_bytes");
+
+ quint64 result = Q_UINT64_C(0);
+
+ QFile tx(devFile);
+ if (tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&tx);
+ in >> result;
+ tx.close();
+ }
+
+ return result;
+ }
+ }
+
+ return Q_UINT64_C(0);
+}
+
+quint64 QNetworkManagerEngine::startTime(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkManagerSettingsConnection *connection = connectionFromId(id);
+ if (connection)
+ return connection->getTimestamp();
+ else
+ return Q_UINT64_C(0);
+}
+
+QNetworkConfigurationManager::Capabilities QNetworkManagerEngine::capabilities() const
+{
+ return QNetworkConfigurationManager::ForcedRoaming |
+ QNetworkConfigurationManager::CanStartAndStopInterfaces;
+}
+
+QNetworkSessionPrivate *QNetworkManagerEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl;
+}
+
+QNetworkConfigurationPrivatePointer QNetworkManagerEngine::defaultConfiguration()
+{
+ return QNetworkConfigurationPrivatePointer();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
new file mode 100644
index 0000000000..ca1f857883
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** 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 QNETWORKMANAGERENGINE_P_H
+#define QNETWORKMANAGERENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "../qbearerengine_impl.h"
+
+#include "qnetworkmanagerservice.h"
+
+#include <QMap>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkManagerEngine : public QBearerEngineImpl
+{
+ Q_OBJECT
+
+public:
+ QNetworkManagerEngine(QObject *parent = 0);
+ ~QNetworkManagerEngine();
+
+ bool networkManagerAvailable() const;
+
+ QString getInterfaceFromId(const QString &id);
+ bool hasIdentifier(const QString &id);
+
+ QString bearerName(const QString &id);
+
+ void connectToId(const QString &id);
+ void disconnectFromId(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkSession::State sessionStateForId(const QString &id);
+
+ quint64 bytesWritten(const QString &id);
+ quint64 bytesReceived(const QString &id);
+ quint64 startTime(const QString &id);
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+private Q_SLOTS:
+ void interfacePropertiesChanged(const QString &path,
+ const QMap<QString, QVariant> &properties);
+ void activeConnectionPropertiesChanged(const QString &path,
+ const QMap<QString, QVariant> &properties);
+ void devicePropertiesChanged(const QString &path,
+ const QMap<QString, QVariant> &properties);
+
+ void deviceAdded(const QDBusObjectPath &path);
+ void deviceRemoved(const QDBusObjectPath &path);
+
+ void newConnection(const QDBusObjectPath &path, QNetworkManagerSettings *settings = 0);
+ void removeConnection(const QString &path);
+ void updateConnection(const QNmSettingsMap &settings);
+ void activationFinished(QDBusPendingCallWatcher *watcher);
+
+ void newAccessPoint(const QString &path, const QDBusObjectPath &objectPath);
+ void removeAccessPoint(const QString &path, const QDBusObjectPath &objectPath);
+ void updateAccessPoint(const QMap<QString, QVariant> &map);
+
+ void doRequestUpdate();
+
+private:
+ QNetworkConfigurationPrivate *parseConnection(const QString &service,
+ const QString &settingsPath,
+ const QNmSettingsMap &map);
+ QNetworkManagerSettingsConnection *connectionFromId(const QString &id) const;
+
+private:
+ QNetworkManagerInterface *interface;
+ QNetworkManagerSettings *systemSettings;
+ QNetworkManagerSettings *userSettings;
+ QHash<QString, QNetworkManagerInterfaceDeviceWireless *> wirelessDevices;
+ QHash<QString, QNetworkManagerConnectionActive *> activeConnections;
+ QList<QNetworkManagerSettingsConnection *> connections;
+ QList<QNetworkManagerInterfaceAccessPoint *> accessPoints;
+ QList<QNetworkManagerInterfaceAccessPoint *> configuredAccessPoints;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
new file mode 100644
index 0000000000..5dc0ea459f
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
@@ -0,0 +1,1046 @@
+/****************************************************************************
+**
+** 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 <QObject>
+#include <QList>
+#include <QtDBus>
+#include <QDBusConnection>
+#include <QDBusError>
+#include <QDBusInterface>
+#include <QDBusMessage>
+#include <QDBusReply>
+#include <QDBusPendingCallWatcher>
+#include <QDBusObjectPath>
+#include <QDBusPendingCall>
+
+#include <NetworkManager/NetworkManager.h>
+
+#include "qnmdbushelper.h"
+#include "qnetworkmanagerservice.h"
+
+//Q_DECLARE_METATYPE(QList<uint>)
+QT_BEGIN_NAMESPACE
+
+static QDBusConnection dbusConnection = QDBusConnection::systemBus();
+//static QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbusConnection);
+
+class QNetworkManagerInterfacePrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ bool valid;
+};
+
+QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ d = new QNetworkManagerInterfacePrivate();
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ dbusConnection);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ return;
+ }
+ d->valid = true;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)),
+ this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>)));
+ connect(nmDBusHelper,SIGNAL(pathForStateChanged(const QString &, quint32)),
+ this, SIGNAL(stateChanged(const QString&, quint32)));
+
+}
+
+QNetworkManagerInterface::~QNetworkManagerInterface()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerInterface::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerInterface::setConnections()
+{
+ if(!isValid() )
+ return false;
+ bool allOk = false;
+ if (!dbusConnection.connect(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "PropertiesChanged",
+ nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>)))) {
+ allOk = true;
+ }
+ if (!dbusConnection.connect(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "DeviceAdded",
+ this,SIGNAL(deviceAdded(QDBusObjectPath)))) {
+ allOk = true;
+ }
+ if (!dbusConnection.connect(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "DeviceRemoved",
+ this,SIGNAL(deviceRemoved(QDBusObjectPath)))) {
+ allOk = true;
+ }
+
+ return allOk;
+}
+
+QDBusInterface *QNetworkManagerInterface::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+QList <QDBusObjectPath> QNetworkManagerInterface::getDevices() const
+{
+ QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call("GetDevices");
+ return reply.value();
+}
+
+void QNetworkManagerInterface::activateConnection( const QString &serviceName,
+ QDBusObjectPath connectionPath,
+ QDBusObjectPath devicePath,
+ QDBusObjectPath specificObject)
+{
+ QDBusPendingCall pendingCall = d->connectionInterface->asyncCall("ActivateConnection",
+ QVariant(serviceName),
+ QVariant::fromValue(connectionPath),
+ QVariant::fromValue(devicePath),
+ QVariant::fromValue(specificObject));
+
+ QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pendingCall, this);
+ connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SIGNAL(activationFinished(QDBusPendingCallWatcher*)));
+}
+
+void QNetworkManagerInterface::deactivateConnection(QDBusObjectPath connectionPath) const
+{
+ d->connectionInterface->call("DeactivateConnection", QVariant::fromValue(connectionPath));
+}
+
+bool QNetworkManagerInterface::wirelessEnabled() const
+{
+ return d->connectionInterface->property("WirelessEnabled").toBool();
+}
+
+bool QNetworkManagerInterface::wirelessHardwareEnabled() const
+{
+ return d->connectionInterface->property("WirelessHardwareEnabled").toBool();
+}
+
+QList <QDBusObjectPath> QNetworkManagerInterface::activeConnections() const
+{
+ QVariant prop = d->connectionInterface->property("ActiveConnections");
+ return prop.value<QList<QDBusObjectPath> >();
+}
+
+quint32 QNetworkManagerInterface::state()
+{
+ return d->connectionInterface->property("State").toUInt();
+}
+
+/////////////
+class QNetworkManagerInterfaceAccessPointPrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerInterfaceAccessPoint::QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ d = new QNetworkManagerInterfaceAccessPointPrivate();
+ d->path = dbusPathName;
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_ACCESS_POINT,
+ dbusConnection);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ qWarning() << "Could not find InterfaceAccessPoint";
+ return;
+ }
+ d->valid = true;
+
+}
+
+QNetworkManagerInterfaceAccessPoint::~QNetworkManagerInterfaceAccessPoint()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerInterfaceAccessPoint::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerInterfaceAccessPoint::setConnections()
+{
+ if(!isValid() )
+ return false;
+
+ bool allOk = false;
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ nmDBusHelper = 0;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)),
+ this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>)));
+
+ if(dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_ACCESS_POINT,
+ "PropertiesChanged",
+ nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>))) ) {
+ allOk = true;
+
+ }
+ return allOk;
+}
+
+QDBusInterface *QNetworkManagerInterfaceAccessPoint::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::flags() const
+{
+ return d->connectionInterface->property("Flags").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::wpaFlags() const
+{
+ return d->connectionInterface->property("WpaFlags").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::rsnFlags() const
+{
+ return d->connectionInterface->property("RsnFlags").toUInt();
+}
+
+QString QNetworkManagerInterfaceAccessPoint::ssid() const
+{
+ return d->connectionInterface->property("Ssid").toString();
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::frequency() const
+{
+ return d->connectionInterface->property("Frequency").toUInt();
+}
+
+QString QNetworkManagerInterfaceAccessPoint::hwAddress() const
+{
+ return d->connectionInterface->property("HwAddress").toString();
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::mode() const
+{
+ return d->connectionInterface->property("Mode").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::maxBitrate() const
+{
+ return d->connectionInterface->property("MaxBitrate").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceAccessPoint::strength() const
+{
+ return d->connectionInterface->property("Strength").toUInt();
+}
+
+/////////////
+class QNetworkManagerInterfaceDevicePrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ d = new QNetworkManagerInterfaceDevicePrivate();
+ d->path = deviceObjectPath;
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE,
+ dbusConnection);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ qWarning() << "Could not find NetworkManagerInterfaceDevice";
+ return;
+ }
+ d->valid = true;
+}
+
+QNetworkManagerInterfaceDevice::~QNetworkManagerInterfaceDevice()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerInterfaceDevice::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerInterfaceDevice::setConnections()
+{
+ if(!isValid() )
+ return false;
+
+ bool allOk = false;
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ nmDBusHelper = 0;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper,SIGNAL(pathForStateChanged(const QString &, quint32)),
+ this, SIGNAL(stateChanged(const QString&, quint32)));
+ if(dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE,
+ "StateChanged",
+ nmDBusHelper,SLOT(deviceStateChanged(quint32)))) {
+ allOk = true;
+ }
+ return allOk;
+}
+
+QDBusInterface *QNetworkManagerInterfaceDevice::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+QString QNetworkManagerInterfaceDevice::udi() const
+{
+ return d->connectionInterface->property("Udi").toString();
+}
+
+QNetworkInterface QNetworkManagerInterfaceDevice::interface() const
+{
+ return QNetworkInterface::interfaceFromName(d->connectionInterface->property("Interface").toString());
+}
+
+quint32 QNetworkManagerInterfaceDevice::ip4Address() const
+{
+ return d->connectionInterface->property("Ip4Address").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceDevice::state() const
+{
+ return d->connectionInterface->property("State").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceDevice::deviceType() const
+{
+ return d->connectionInterface->property("DeviceType").toUInt();
+}
+
+QDBusObjectPath QNetworkManagerInterfaceDevice::ip4config() const
+{
+ QVariant prop = d->connectionInterface->property("Ip4Config");
+ return prop.value<QDBusObjectPath>();
+}
+
+/////////////
+class QNetworkManagerInterfaceDeviceWiredPrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ d = new QNetworkManagerInterfaceDeviceWiredPrivate();
+ d->path = ifaceDevicePath;
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE_WIRED,
+ dbusConnection, parent);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ qWarning() << "Could not find InterfaceDeviceWired";
+ return;
+ }
+ d->valid = true;
+}
+
+QNetworkManagerInterfaceDeviceWired::~QNetworkManagerInterfaceDeviceWired()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerInterfaceDeviceWired::isValid()
+{
+
+ return d->valid;
+}
+
+bool QNetworkManagerInterfaceDeviceWired::setConnections()
+{
+ if(!isValid() )
+ return false;
+
+ bool allOk = false;
+
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ nmDBusHelper = 0;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)),
+ this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>)));
+ if(dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE_WIRED,
+ "PropertiesChanged",
+ nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>))) ) {
+ allOk = true;
+ }
+ return allOk;
+}
+
+QDBusInterface *QNetworkManagerInterfaceDeviceWired::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+QString QNetworkManagerInterfaceDeviceWired::hwAddress() const
+{
+ return d->connectionInterface->property("HwAddress").toString();
+}
+
+quint32 QNetworkManagerInterfaceDeviceWired::speed() const
+{
+ return d->connectionInterface->property("Speed").toUInt();
+}
+
+bool QNetworkManagerInterfaceDeviceWired::carrier() const
+{
+ return d->connectionInterface->property("Carrier").toBool();
+}
+
+/////////////
+class QNetworkManagerInterfaceDeviceWirelessPrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ d = new QNetworkManagerInterfaceDeviceWirelessPrivate();
+ d->path = ifaceDevicePath;
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+ dbusConnection, parent);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ qWarning() << "Could not find InterfaceDeviceWireless";
+ return;
+ }
+ d->valid = true;
+}
+
+QNetworkManagerInterfaceDeviceWireless::~QNetworkManagerInterfaceDeviceWireless()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerInterfaceDeviceWireless::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerInterfaceDeviceWireless::setConnections()
+{
+ if(!isValid() )
+ return false;
+
+ bool allOk = false;
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ nmDBusHelper = 0;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)),
+ this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>)));
+
+ connect(nmDBusHelper, SIGNAL(pathForAccessPointAdded(const QString &,QDBusObjectPath)),
+ this,SIGNAL(accessPointAdded(const QString &,QDBusObjectPath)));
+
+ connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(const QString &,QDBusObjectPath)),
+ this,SIGNAL(accessPointRemoved(const QString &,QDBusObjectPath)));
+
+ if(!dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+ "AccessPointAdded",
+ nmDBusHelper, SLOT(slotAccessPointAdded( QDBusObjectPath )))) {
+ allOk = true;
+ }
+
+
+ if(!dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+ "AccessPointRemoved",
+ nmDBusHelper, SLOT(slotAccessPointRemoved( QDBusObjectPath )))) {
+ allOk = true;
+ }
+
+
+ if(!dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+ "PropertiesChanged",
+ nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>)))) {
+ allOk = true;
+ }
+
+ return allOk;
+}
+
+QDBusInterface *QNetworkManagerInterfaceDeviceWireless::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+QList <QDBusObjectPath> QNetworkManagerInterfaceDeviceWireless::getAccessPoints()
+{
+ QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call("GetAccessPoints");
+ return reply.value();
+}
+
+QString QNetworkManagerInterfaceDeviceWireless::hwAddress() const
+{
+ return d->connectionInterface->property("HwAddress").toString();
+}
+
+quint32 QNetworkManagerInterfaceDeviceWireless::mode() const
+{
+ return d->connectionInterface->property("Mode").toUInt();
+}
+
+quint32 QNetworkManagerInterfaceDeviceWireless::bitrate() const
+{
+ return d->connectionInterface->property("Bitrate").toUInt();
+}
+
+QDBusObjectPath QNetworkManagerInterfaceDeviceWireless::activeAccessPoint() const
+{
+ return d->connectionInterface->property("ActiveAccessPoint").value<QDBusObjectPath>();
+}
+
+quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const
+{
+ return d->connectionInterface->property("WirelelessCapabilities").toUInt();
+}
+
+/////////////
+class QNetworkManagerSettingsPrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerSettings::QNetworkManagerSettings(const QString &settingsService, QObject *parent)
+ : QObject(parent)
+{
+ d = new QNetworkManagerSettingsPrivate();
+ d->path = settingsService;
+ d->connectionInterface = new QDBusInterface(settingsService,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_IFACE_SETTINGS,
+ dbusConnection);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ //qWarning() << "Could not find NetworkManagerSettings";
+ return;
+ }
+ d->valid = true;
+}
+
+QNetworkManagerSettings::~QNetworkManagerSettings()
+{
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerSettings::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerSettings::setConnections()
+{
+ bool allOk = false;
+
+ if (!dbusConnection.connect(d->path, NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_IFACE_SETTINGS, "NewConnection",
+ this, SIGNAL(newConnection(QDBusObjectPath)))) {
+ allOk = true;
+ }
+
+ return allOk;
+}
+
+QList <QDBusObjectPath> QNetworkManagerSettings::listConnections()
+{
+ QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call("ListConnections");
+ return reply.value();
+}
+
+QDBusInterface *QNetworkManagerSettings::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+
+/////////////
+class QNetworkManagerSettingsConnectionPrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ QString service;
+ QNmSettingsMap settingsMap;
+ bool valid;
+};
+
+QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ qDBusRegisterMetaType<QNmSettingsMap>();
+ d = new QNetworkManagerSettingsConnectionPrivate();
+ d->path = connectionObjectPath;
+ d->service = settingsService;
+ d->connectionInterface = new QDBusInterface(settingsService,
+ d->path,
+ NM_DBUS_IFACE_SETTINGS_CONNECTION,
+ dbusConnection, parent);
+ if (!d->connectionInterface->isValid()) {
+ //qWarning() << "Could not find NetworkManagerSettingsConnection";
+ d->valid = false;
+ return;
+ }
+ d->valid = true;
+ QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call("GetSettings");
+ d->settingsMap = rep.value();
+}
+
+QNetworkManagerSettingsConnection::~QNetworkManagerSettingsConnection()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerSettingsConnection::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerSettingsConnection::setConnections()
+{
+ if(!isValid() )
+ return false;
+
+ bool allOk = false;
+ if(!dbusConnection.connect(d->service, d->path,
+ NM_DBUS_IFACE_SETTINGS_CONNECTION, "Updated",
+ this, SIGNAL(updated(QNmSettingsMap)))) {
+ allOk = true;
+ } else {
+ QDBusError error = dbusConnection.lastError();
+ }
+
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ nmDBusHelper = 0;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper, SIGNAL(pathForSettingsRemoved(const QString &)),
+ this,SIGNAL(removed( const QString &)));
+
+ if (!dbusConnection.connect(d->service, d->path,
+ NM_DBUS_IFACE_SETTINGS_CONNECTION, "Removed",
+ nmDBusHelper, SIGNAL(slotSettingsRemoved()))) {
+ allOk = true;
+ }
+
+ return allOk;
+}
+//QNetworkManagerSettingsConnection::update(QNmSettingsMap map)
+//{
+// d->connectionInterface->call("Update", QVariant::fromValue(map));
+//}
+
+QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+QNmSettingsMap QNetworkManagerSettingsConnection::getSettings()
+{
+ QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call("GetSettings");
+ d->settingsMap = rep.value();
+ return d->settingsMap;
+}
+
+NMDeviceType QNetworkManagerSettingsConnection::getType()
+{
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("connection");
+ while (i != d->settingsMap.end() && i.key() == "connection") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("type");
+ while (ii != innerMap.end() && ii.key() == "type") {
+ QString devType = ii.value().toString();
+ if (devType == "802-3-ethernet") {
+ return DEVICE_TYPE_802_3_ETHERNET;
+ }
+ if (devType == "802-11-wireless") {
+ return DEVICE_TYPE_802_11_WIRELESS;
+ }
+ ii++;
+ }
+ i++;
+ }
+ return DEVICE_TYPE_UNKNOWN;
+}
+
+bool QNetworkManagerSettingsConnection::isAutoConnect()
+{
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("connection");
+ while (i != d->settingsMap.end() && i.key() == "connection") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("autoconnect");
+ while (ii != innerMap.end() && ii.key() == "autoconnect") {
+ return ii.value().toBool();
+ ii++;
+ }
+ i++;
+ }
+ return true; //default networkmanager is autoconnect
+}
+
+quint64 QNetworkManagerSettingsConnection::getTimestamp()
+{
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("connection");
+ while (i != d->settingsMap.end() && i.key() == "connection") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("timestamp");
+ while (ii != innerMap.end() && ii.key() == "timestamp") {
+ return ii.value().toUInt();
+ ii++;
+ }
+ i++;
+ }
+ return 0;
+}
+
+QString QNetworkManagerSettingsConnection::getId()
+{
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("connection");
+ while (i != d->settingsMap.end() && i.key() == "connection") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("id");
+ while (ii != innerMap.end() && ii.key() == "id") {
+ return ii.value().toString();
+ ii++;
+ }
+ i++;
+ }
+ return QString();
+}
+
+QString QNetworkManagerSettingsConnection::getUuid()
+{
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("connection");
+ while (i != d->settingsMap.end() && i.key() == "connection") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("uuid");
+ while (ii != innerMap.end() && ii.key() == "uuid") {
+ return ii.value().toString();
+ ii++;
+ }
+ i++;
+ }
+ // is no uuid, return the connection path
+ return d->connectionInterface->path();
+}
+
+QString QNetworkManagerSettingsConnection::getSsid()
+{
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("802-11-wireless");
+ while (i != d->settingsMap.end() && i.key() == "802-11-wireless") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("ssid");
+ while (ii != innerMap.end() && ii.key() == "ssid") {
+ return ii.value().toString();
+ ii++;
+ }
+ i++;
+ }
+ return QString();
+}
+
+QString QNetworkManagerSettingsConnection::getMacAddress()
+{
+ if(getType() == DEVICE_TYPE_802_3_ETHERNET) {
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("802-3-ethernet");
+ while (i != d->settingsMap.end() && i.key() == "802-3-ethernet") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("mac-address");
+ while (ii != innerMap.end() && ii.key() == "mac-address") {
+ return ii.value().toString();
+ ii++;
+ }
+ i++;
+ }
+ }
+
+ else if(getType() == DEVICE_TYPE_802_11_WIRELESS) {
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("802-11-wireless");
+ while (i != d->settingsMap.end() && i.key() == "802-11-wireless") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("mac-address");
+ while (ii != innerMap.end() && ii.key() == "mac-address") {
+ return ii.value().toString();
+ ii++;
+ }
+ i++;
+ }
+ }
+ return QString();
+}
+
+QStringList QNetworkManagerSettingsConnection::getSeenBssids()
+{
+ if(getType() == DEVICE_TYPE_802_11_WIRELESS) {
+ QNmSettingsMap::const_iterator i = d->settingsMap.find("802-11-wireless");
+ while (i != d->settingsMap.end() && i.key() == "802-11-wireless") {
+ QMap<QString,QVariant> innerMap = i.value();
+ QMap<QString,QVariant>::const_iterator ii = innerMap.find("seen-bssids");
+ while (ii != innerMap.end() && ii.key() == "seen-bssids") {
+ return ii.value().toStringList();
+ ii++;
+ }
+ i++;
+ }
+ }
+ return QStringList();
+}
+
+/////////////
+class QNetworkManagerConnectionActivePrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerConnectionActive::QNetworkManagerConnectionActive( const QString &activeConnectionObjectPath, QObject *parent)
+ : QObject(parent), nmDBusHelper(0)
+{
+ d = new QNetworkManagerConnectionActivePrivate();
+ d->path = activeConnectionObjectPath;
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ dbusConnection, parent);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ //qWarning() << "Could not find NetworkManagerSettingsConnection";
+ return;
+ }
+ d->valid = true;
+}
+
+QNetworkManagerConnectionActive::~QNetworkManagerConnectionActive()
+{
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerConnectionActive::isValid()
+{
+ return d->valid;
+}
+
+bool QNetworkManagerConnectionActive::setConnections()
+{
+ if(!isValid() )
+ return false;
+
+ bool allOk = false;
+ if (nmDBusHelper)
+ delete nmDBusHelper;
+ nmDBusHelper = 0;
+ nmDBusHelper = new QNmDBusHelper;
+ connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)),
+ this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>)));
+ if(dbusConnection.connect(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ "PropertiesChanged",
+ nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>))) ) {
+ allOk = true;
+ }
+
+ return allOk;
+}
+
+QDBusInterface *QNetworkManagerConnectionActive::connectionInterface() const
+{
+ return d->connectionInterface;
+}
+
+QString QNetworkManagerConnectionActive::serviceName() const
+{
+ return d->connectionInterface->property("ServiceName").toString();
+}
+
+QDBusObjectPath QNetworkManagerConnectionActive::connection() const
+{
+ QVariant prop = d->connectionInterface->property("Connection");
+ return prop.value<QDBusObjectPath>();
+}
+
+QDBusObjectPath QNetworkManagerConnectionActive::specificObject() const
+{
+ QVariant prop = d->connectionInterface->property("SpecificObject");
+ return prop.value<QDBusObjectPath>();
+}
+
+QList<QDBusObjectPath> QNetworkManagerConnectionActive::devices() const
+{
+ QVariant prop = d->connectionInterface->property("Devices");
+ return prop.value<QList<QDBusObjectPath> >();
+}
+
+quint32 QNetworkManagerConnectionActive::state() const
+{
+ return d->connectionInterface->property("State").toUInt();
+}
+
+bool QNetworkManagerConnectionActive::defaultRoute() const
+{
+ return d->connectionInterface->property("Default").toBool();
+}
+
+
+////
+class QNetworkManagerIp4ConfigPrivate
+{
+public:
+ QDBusInterface *connectionInterface;
+ QString path;
+ bool valid;
+};
+
+QNetworkManagerIp4Config::QNetworkManagerIp4Config( const QString &deviceObjectPath, QObject *parent)
+ : QObject(parent)
+{
+ d = new QNetworkManagerIp4ConfigPrivate();
+ d->path = deviceObjectPath;
+ d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE,
+ d->path,
+ NM_DBUS_INTERFACE_IP4_CONFIG,
+ dbusConnection, parent);
+ if (!d->connectionInterface->isValid()) {
+ d->valid = false;
+ //qWarning() << "Could not find NetworkManagerIp4Config";
+ return;
+ }
+ d->valid = true;
+}
+
+QNetworkManagerIp4Config::~QNetworkManagerIp4Config()
+{
+ delete d->connectionInterface;
+ delete d;
+}
+
+bool QNetworkManagerIp4Config::isValid()
+{
+ return d->valid;
+}
+
+QStringList QNetworkManagerIp4Config::domains() const
+{
+ return d->connectionInterface->property("Domains").toStringList();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
new file mode 100644
index 0000000000..81903ec1c1
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** 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 QNETWORKMANAGERSERVICE_H
+#define QNETWORKMANAGERSERVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <NetworkManager/NetworkManager.h>
+#include <QtDBus>
+#include <QDBusConnection>
+#include <QDBusError>
+#include <QDBusInterface>
+#include <QDBusMessage>
+#include <QDBusReply>
+#include <QNetworkInterface>
+
+
+#include <QDBusPendingCallWatcher>
+#include "qnmdbushelper.h"
+
+QT_BEGIN_NAMESPACE
+
+typedef QMap< QString, QMap<QString,QVariant> > QNmSettingsMap;
+typedef QList<quint32> ServerThing;
+
+Q_DECLARE_METATYPE(QNmSettingsMap)
+Q_DECLARE_METATYPE(ServerThing)
+
+class QNetworkManagerInterfacePrivate;
+class QNetworkManagerInterface : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ QNetworkManagerInterface(QObject *parent = 0);
+ ~QNetworkManagerInterface();
+
+ QList <QDBusObjectPath> getDevices() const;
+ void activateConnection(const QString &serviceName, QDBusObjectPath connection, QDBusObjectPath device, QDBusObjectPath specificObject);
+ void deactivateConnection(QDBusObjectPath connectionPath) const;
+
+ QDBusObjectPath path() const;
+ QDBusInterface *connectionInterface() const;
+
+ bool wirelessEnabled() const;
+ bool wirelessHardwareEnabled() const;
+ QList <QDBusObjectPath> activeConnections() const;
+ quint32 state();
+ bool setConnections();
+ bool isValid();
+
+Q_SIGNALS:
+ void deviceAdded(QDBusObjectPath);
+ void deviceRemoved(QDBusObjectPath);
+ void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void stateChanged(const QString&, quint32);
+ void activationFinished(QDBusPendingCallWatcher*);
+
+private Q_SLOTS:
+private:
+// Q_DISABLE_COPY(QNetworkManagerInterface); ??
+ QNetworkManagerInterfacePrivate *d;
+ QNmDBusHelper *nmDBusHelper;
+}; //end QNetworkManagerInterface
+
+////////
+class QNetworkManagerInterfaceAccessPointPrivate;
+class QNetworkManagerInterfaceAccessPoint : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ // NM_DEVICE_STATE
+ enum DeviceState {
+ Unknown = 0,
+ Unmanaged,
+ Unavailable,
+ Disconnected,
+ Prepare,
+ Config,
+ NeedAuthentication,
+ IpConfig,
+ Activated,
+ Failed
+ };
+
+ enum ApFlag {
+ ApNone = 0x0,
+ Privacy = 0x1
+ };
+
+ Q_DECLARE_FLAGS(ApFlags, ApFlag);
+
+ enum ApSecurityFlag {
+ ApSecurityNone = 0x0,
+ PairWep40 = 0x1,
+ PairWep104 = 0x2,
+ PairTkip = 0x4,
+ PairCcmp = 0x8,
+ GroupWep40 = 0x10,
+ GroupWep104 = 0x20,
+ GroupTkip = 0x40,
+ GroupCcmp = 0x80,
+ KeyPsk = 0x100,
+ Key8021x = 0x200
+ };
+
+ Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag);
+
+ QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0);
+ ~QNetworkManagerInterfaceAccessPoint();
+
+ QDBusInterface *connectionInterface() const;
+
+ quint32 flags() const;
+ quint32 wpaFlags() const;
+ quint32 rsnFlags() const;
+ QString ssid() const;
+ quint32 frequency() const;
+ QString hwAddress() const;
+ quint32 mode() const;
+ quint32 maxBitrate() const;
+ quint32 strength() const;
+ bool setConnections();
+ bool isValid();
+
+Q_SIGNALS:
+ void propertiesChanged(QMap <QString,QVariant>);
+ void propertiesChanged( const QString &, QMap<QString,QVariant>);
+private:
+ QNetworkManagerInterfaceAccessPointPrivate *d;
+ QNmDBusHelper *nmDBusHelper;
+
+}; //end QNetworkManagerInterfaceAccessPoint
+
+////////
+class QNetworkManagerInterfaceDevicePrivate;
+class QNetworkManagerInterfaceDevice : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = 0);
+ ~QNetworkManagerInterfaceDevice();
+
+ QString udi() const;
+ QNetworkInterface interface() const;
+ QDBusInterface *connectionInterface() const;
+ quint32 ip4Address() const;
+ quint32 state() const;
+ quint32 deviceType() const;
+
+ QDBusObjectPath ip4config() const;
+ bool setConnections();
+ bool isValid();
+
+Q_SIGNALS:
+ void stateChanged(const QString &, quint32);
+
+private:
+ QNetworkManagerInterfaceDevicePrivate *d;
+ QNmDBusHelper *nmDBusHelper;
+}; //end QNetworkManagerInterfaceDevice
+
+////////
+class QNetworkManagerInterfaceDeviceWiredPrivate;
+class QNetworkManagerInterfaceDeviceWired : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent = 0);
+ ~QNetworkManagerInterfaceDeviceWired();
+
+ QDBusInterface *connectionInterface() const;
+ QString hwAddress() const;
+ quint32 speed() const;
+ bool carrier() const;
+ bool setConnections();
+ bool isValid();
+
+Q_SIGNALS:
+ void propertiesChanged( const QString &, QMap<QString,QVariant>);
+private:
+ QNetworkManagerInterfaceDeviceWiredPrivate *d;
+ QNmDBusHelper *nmDBusHelper;
+}; // end QNetworkManagerInterfaceDeviceWired
+
+////
+class QNetworkManagerInterfaceDeviceWirelessPrivate;
+class QNetworkManagerInterfaceDeviceWireless : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum DeviceCapability {
+ None = 0x0,
+ Wep40 = 0x1,
+ Wep104 = 0x2,
+ Tkip = 0x4,
+ Ccmp = 0x8,
+ Wpa = 0x10,
+ Rsn = 0x20
+ };
+
+ QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent = 0);
+ ~QNetworkManagerInterfaceDeviceWireless();
+
+ QDBusObjectPath path() const;
+ QList <QDBusObjectPath> getAccessPoints();
+ QDBusInterface *connectionInterface() const;
+
+ QString hwAddress() const;
+ quint32 mode() const;
+ quint32 bitrate() const;
+ QDBusObjectPath activeAccessPoint() const;
+ quint32 wirelessCapabilities() const;
+ bool setConnections();
+ bool isValid();
+
+Q_SIGNALS:
+ void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void accessPointAdded(const QString &,QDBusObjectPath);
+ void accessPointRemoved(const QString &,QDBusObjectPath);
+private:
+ QNetworkManagerInterfaceDeviceWirelessPrivate *d;
+ QNmDBusHelper *nmDBusHelper;
+}; // end QNetworkManagerInterfaceDeviceWireless
+
+////
+class QNetworkManagerSettingsPrivate;
+class QNetworkManagerSettings : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ QNetworkManagerSettings(const QString &settingsService, QObject *parent = 0);
+ ~QNetworkManagerSettings();
+
+ QDBusInterface *connectionInterface() const;
+ QList <QDBusObjectPath> listConnections();
+ bool setConnections();
+ bool isValid();
+
+Q_SIGNALS:
+ void newConnection(QDBusObjectPath);
+private:
+ QNetworkManagerSettingsPrivate *d;
+}; //end QNetworkManagerSettings
+
+////
+class QNetworkManagerSettingsConnectionPrivate;
+class QNetworkManagerSettingsConnection : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent = 0);
+ ~QNetworkManagerSettingsConnection();
+
+ QDBusInterface *connectionInterface() const;
+ QNmSettingsMap getSettings();
+ // void update(QNmSettingsMap map);
+ bool setConnections();
+ NMDeviceType getType();
+ bool isAutoConnect();
+ quint64 getTimestamp();
+ QString getId();
+ QString getUuid();
+ QString getSsid();
+ QString getMacAddress();
+ QStringList getSeenBssids();
+ bool isValid();
+
+Q_SIGNALS:
+
+ void updated(const QNmSettingsMap &settings);
+ void removed(const QString &path);
+
+private:
+ QNmDBusHelper *nmDBusHelper;
+ QNetworkManagerSettingsConnectionPrivate *d;
+}; //end QNetworkManagerSettingsConnection
+
+////
+class QNetworkManagerConnectionActivePrivate;
+class QNetworkManagerConnectionActive : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum ActiveConnectionState {
+ Unknown = 0,
+ Activating = 1,
+ Activated = 2
+ };
+
+ QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = 0);
+ ~ QNetworkManagerConnectionActive();
+
+ QDBusInterface *connectionInterface() const;
+ QString serviceName() const;
+ QDBusObjectPath connection() const;
+ QDBusObjectPath specificObject() const;
+ QList<QDBusObjectPath> devices() const;
+ quint32 state() const;
+ bool defaultRoute() const;
+ bool setConnections();
+ bool isValid();
+
+
+Q_SIGNALS:
+ void propertiesChanged(QList<QDBusObjectPath>);
+ void propertiesChanged( const QString &, QMap<QString,QVariant>);
+private:
+ QNetworkManagerConnectionActivePrivate *d;
+ QNmDBusHelper *nmDBusHelper;
+}; //QNetworkManagerConnectionActive
+
+////
+class QNetworkManagerIp4ConfigPrivate;
+class QNetworkManagerIp4Config : public QObject
+{
+ Q_OBJECT
+
+public:
+ QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0);
+ ~QNetworkManagerIp4Config();
+
+ // QList<quint32> nameservers();
+ QStringList domains() const;
+ bool isValid();
+
+ private:
+ QNetworkManagerIp4ConfigPrivate *d;
+};
+////
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKMANAGERSERVICE_H
diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp
new file mode 100644
index 0000000000..d5e20f3273
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+// this class is for helping qdbus get stuff
+
+#include "qnmdbushelper.h"
+
+#include <NetworkManager/NetworkManager.h>
+
+#include <QDBusError>
+#include <QDBusInterface>
+#include <QDBusMessage>
+#include <QDBusReply>
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+void QNmDBusHelper::deviceStateChanged(quint32 state)
+ {
+ QDBusMessage msg = this->message();
+ if(state == NM_DEVICE_STATE_ACTIVATED
+ || state == NM_DEVICE_STATE_DISCONNECTED
+ || state == NM_DEVICE_STATE_UNAVAILABLE
+ || state == NM_DEVICE_STATE_FAILED) {
+ emit pathForStateChanged(msg.path(), state);
+ }
+ }
+
+void QNmDBusHelper::slotAccessPointAdded(QDBusObjectPath path)
+{
+ if(path.path().length() > 2) {
+ QDBusMessage msg = this->message();
+ emit pathForAccessPointAdded(msg.path(), path);
+ }
+}
+
+void QNmDBusHelper::slotAccessPointRemoved(QDBusObjectPath path)
+{
+ if(path.path().length() > 2) {
+ QDBusMessage msg = this->message();
+ emit pathForAccessPointRemoved(msg.path(), path);
+ }
+}
+
+void QNmDBusHelper::slotPropertiesChanged(QMap<QString,QVariant> map)
+{
+ QDBusMessage msg = this->message();
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ if( i.key() == "State") { //state only applies to device interfaces
+ quint32 state = i.value().toUInt();
+ if( state == NM_DEVICE_STATE_ACTIVATED
+ || state == NM_DEVICE_STATE_DISCONNECTED
+ || state == NM_DEVICE_STATE_UNAVAILABLE
+ || state == NM_DEVICE_STATE_FAILED) {
+ emit pathForPropertiesChanged( msg.path(), map);
+ }
+ } else if( i.key() == "ActiveAccessPoint") {
+ emit pathForPropertiesChanged(msg.path(), map);
+ // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value().value<QDBusObjectPath>().path();
+ // } else if( i.key() == "Strength")
+ // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value().toUInt();
+ // else
+ // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value();
+ } else if (i.key() == "ActiveConnections") {
+ emit pathForPropertiesChanged(msg.path(), map);
+ }
+ }
+}
+
+void QNmDBusHelper::slotSettingsRemoved()
+{
+ QDBusMessage msg = this->message();
+ emit pathForSettingsRemoved(msg.path());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.h b/src/plugins/bearer/networkmanager/qnmdbushelper.h
new file mode 100644
index 0000000000..862290c236
--- /dev/null
+++ b/src/plugins/bearer/networkmanager/qnmdbushelper.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 QNMDBUSHELPERPRIVATE_H
+#define QNMDBUSHELPERPRIVATE_H
+
+#include <QDBusObjectPath>
+#include <QDBusContext>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QNmDBusHelper: public QObject, protected QDBusContext
+ {
+ Q_OBJECT
+ public:
+
+ public slots:
+ void deviceStateChanged(quint32);
+ void slotAccessPointAdded( QDBusObjectPath );
+ void slotAccessPointRemoved( QDBusObjectPath );
+ void slotPropertiesChanged( QMap<QString,QVariant>);
+ void slotSettingsRemoved();
+
+Q_SIGNALS:
+ void pathForStateChanged(const QString &, quint32);
+ void pathForAccessPointAdded(const QString &, QDBusObjectPath );
+ void pathForAccessPointRemoved(const QString &, QDBusObjectPath );
+ void pathForPropertiesChanged(const QString &, QMap<QString,QVariant>);
+ void pathForSettingsRemoved(const QString &);
+};
+
+QT_END_NAMESPACE
+
+#endif// QNMDBUSHELPERPRIVATE_H
diff --git a/src/plugins/bearer/nla/main.cpp b/src/plugins/bearer/nla/main.cpp
new file mode 100644
index 0000000000..479a933240
--- /dev/null
+++ b/src/plugins/bearer/nla/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnlaengine.h"
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNlaEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QNlaEnginePlugin();
+ ~QNlaEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QNlaEnginePlugin::QNlaEnginePlugin()
+{
+}
+
+QNlaEnginePlugin::~QNlaEnginePlugin()
+{
+}
+
+QStringList QNlaEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("nla");
+}
+
+QBearerEngine *QNlaEnginePlugin::create(const QString &key) const
+{
+ if (key == QLatin1String("nla"))
+ return new QNlaEngine;
+ else
+ return 0;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QNlaEnginePlugin)
+Q_EXPORT_PLUGIN2(qnlabearer, QNlaEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/nla/nla.pro b/src/plugins/bearer/nla/nla.pro
new file mode 100644
index 0000000000..5148b09a22
--- /dev/null
+++ b/src/plugins/bearer/nla/nla.pro
@@ -0,0 +1,23 @@
+TARGET = qnlabearer
+include(../../qpluginbase.pri)
+
+QT += network
+
+!wince* {
+ LIBS += -lWs2_32
+} else {
+ LIBS += -lWs2
+}
+
+HEADERS += qnlaengine.h \
+ ../platformdefs_win.h \
+ ../qnetworksession_impl.h \
+ ../qbearerengine_impl.h
+
+SOURCES += main.cpp \
+ qnlaengine.cpp \
+ ../qnetworksession_impl.cpp
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/nla/qnlaengine.cpp b/src/plugins/bearer/nla/qnlaengine.cpp
new file mode 100644
index 0000000000..ff334e5518
--- /dev/null
+++ b/src/plugins/bearer/nla/qnlaengine.cpp
@@ -0,0 +1,661 @@
+/****************************************************************************
+**
+** 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 "qnlaengine.h"
+#include "../qnetworksession_impl.h"
+
+#include <QtNetwork/private/qnetworkconfiguration_p.h>
+
+#include <QtCore/qthread.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtCore/qdebug.h>
+
+#include "../platformdefs_win.h"
+
+QT_BEGIN_NAMESPACE
+
+QWindowsSockInit2::QWindowsSockInit2()
+: version(0)
+{
+ //### should we try for 2.2 on all platforms ??
+ WSAData wsadata;
+
+ // IPv6 requires Winsock v2.0 or better.
+ if (WSAStartup(MAKEWORD(2,0), &wsadata) != 0) {
+ qWarning("QBearerManagementAPI: WinSock v2.0 initialization failed.");
+ } else {
+ version = 0x20;
+ }
+}
+
+QWindowsSockInit2::~QWindowsSockInit2()
+{
+ WSACleanup();
+}
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+static void printBlob(NLA_BLOB *blob)
+{
+ qDebug() << "==== BEGIN NLA_BLOB ====";
+
+ qDebug() << "type:" << blob->header.type;
+ qDebug() << "size:" << blob->header.dwSize;
+ qDebug() << "next offset:" << blob->header.nextOffset;
+
+ switch (blob->header.type) {
+ case NLA_RAW_DATA:
+ qDebug() << "Raw Data";
+ qDebug() << '\t' << blob->data.rawData;
+ break;
+ case NLA_INTERFACE:
+ qDebug() << "Interface";
+ qDebug() << "\ttype:" << blob->data.interfaceData.dwType;
+ qDebug() << "\tspeed:" << blob->data.interfaceData.dwSpeed;
+ qDebug() << "\tadapter:" << blob->data.interfaceData.adapterName;
+ break;
+ case NLA_802_1X_LOCATION:
+ qDebug() << "802.1x Location";
+ qDebug() << '\t' << blob->data.locationData.information;
+ break;
+ case NLA_CONNECTIVITY:
+ qDebug() << "Connectivity";
+ qDebug() << "\ttype:" << blob->data.connectivity.type;
+ qDebug() << "\tinternet:" << blob->data.connectivity.internet;
+ break;
+ case NLA_ICS:
+ qDebug() << "ICS";
+ qDebug() << "\tspeed:" << blob->data.ICS.remote.speed;
+ qDebug() << "\ttype:" << blob->data.ICS.remote.type;
+ qDebug() << "\tstate:" << blob->data.ICS.remote.state;
+ qDebug() << "\tmachine name:" << blob->data.ICS.remote.machineName;
+ qDebug() << "\tshared adapter name:" << blob->data.ICS.remote.sharedAdapterName;
+ break;
+ default:
+ qDebug() << "UNKNOWN BLOB TYPE";
+ }
+
+ qDebug() << "===== END NLA_BLOB =====";
+}
+#endif
+
+static QString qGetInterfaceType(const QString &interface)
+{
+#ifdef Q_OS_WINCE
+ Q_UNUSED(interface)
+#else
+ unsigned long oid;
+ DWORD bytesWritten;
+
+ NDIS_MEDIUM medium;
+ NDIS_PHYSICAL_MEDIUM physicalMedium;
+
+ HANDLE handle = CreateFile((TCHAR *)QString(QLatin1String("\\\\.\\%1")).arg(interface).utf16(),
+ 0, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if (handle == INVALID_HANDLE_VALUE)
+ return QLatin1String("Unknown");
+
+ oid = OID_GEN_MEDIA_SUPPORTED;
+ bytesWritten = 0;
+ bool result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid),
+ &medium, sizeof(medium), &bytesWritten, 0);
+ if (!result) {
+ CloseHandle(handle);
+ return QLatin1String("Unknown");
+ }
+
+ oid = OID_GEN_PHYSICAL_MEDIUM;
+ bytesWritten = 0;
+ result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid),
+ &physicalMedium, sizeof(physicalMedium), &bytesWritten, 0);
+ if (!result) {
+ CloseHandle(handle);
+
+ if (medium == NdisMedium802_3)
+ return QLatin1String("Ethernet");
+ else
+ return QLatin1String("Unknown");
+ }
+
+ CloseHandle(handle);
+
+ if (medium == NdisMedium802_3) {
+ switch (physicalMedium) {
+ case NdisPhysicalMediumWirelessLan:
+ return QLatin1String("WLAN");
+ case NdisPhysicalMediumBluetooth:
+ return QLatin1String("Bluetooth");
+ case NdisPhysicalMediumWiMax:
+ return QLatin1String("WiMAX");
+ default:
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "Physical Medium" << physicalMedium;
+#endif
+ return QLatin1String("Ethernet");
+ }
+ }
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << medium << physicalMedium;
+#endif
+
+#endif
+
+ return QLatin1String("Unknown");
+}
+
+class QNlaThread : public QThread
+{
+ Q_OBJECT
+
+public:
+ QNlaThread(QNlaEngine *parent = 0);
+ ~QNlaThread();
+
+ QList<QNetworkConfigurationPrivate *> getConfigurations();
+
+ void forceUpdate();
+
+protected:
+ virtual void run();
+
+private:
+ void updateConfigurations(QList<QNetworkConfigurationPrivate *> &configs);
+ DWORD parseBlob(NLA_BLOB *blob, QNetworkConfigurationPrivate *cpPriv) const;
+ QNetworkConfigurationPrivate *parseQuerySet(const WSAQUERYSET *querySet) const;
+ void fetchConfigurations();
+
+signals:
+ void networksChanged();
+
+private:
+ QMutex mutex;
+ HANDLE handle;
+ bool done;
+ QList<QNetworkConfigurationPrivate *> fetchedConfigurations;
+};
+
+QNlaThread::QNlaThread(QNlaEngine *parent)
+: QThread(parent), handle(0), done(false)
+{
+}
+
+QNlaThread::~QNlaThread()
+{
+ mutex.lock();
+
+ done = true;
+
+ if (handle) {
+ /* cancel completion event */
+ if (WSALookupServiceEnd(handle) == SOCKET_ERROR)
+ qWarning("WSALookupServiceEnd error %d", WSAGetLastError());
+ }
+ mutex.unlock();
+
+ wait();
+}
+
+QList<QNetworkConfigurationPrivate *> QNlaThread::getConfigurations()
+{
+ QMutexLocker locker(&mutex);
+
+ QList<QNetworkConfigurationPrivate *> foundConfigurations = fetchedConfigurations;
+ fetchedConfigurations.clear();
+
+ return foundConfigurations;
+}
+
+void QNlaThread::forceUpdate()
+{
+ mutex.lock();
+
+ if (handle) {
+ /* cancel completion event */
+ if (WSALookupServiceEnd(handle) == SOCKET_ERROR)
+ qWarning("WSALookupServiceEnd error %d", WSAGetLastError());
+ handle = 0;
+ }
+ mutex.unlock();
+}
+
+void QNlaThread::run()
+{
+ WSAEVENT changeEvent = WSACreateEvent();
+ if (changeEvent == WSA_INVALID_EVENT) {
+ qWarning("WSACreateEvent error %d", WSAGetLastError());
+ return;
+ }
+
+ while (true) {
+ fetchConfigurations();
+
+ WSAQUERYSET qsRestrictions;
+
+ memset(&qsRestrictions, 0, sizeof(qsRestrictions));
+ qsRestrictions.dwSize = sizeof(qsRestrictions);
+ qsRestrictions.dwNameSpace = NS_NLA;
+
+ mutex.lock();
+ if (done) {
+ mutex.unlock();
+ break;
+ }
+ int result = WSALookupServiceBegin(&qsRestrictions, LUP_RETURN_ALL, &handle);
+ mutex.unlock();
+
+ if (result == SOCKET_ERROR) {
+ qWarning("%s: WSALookupServiceBegin error %d", __FUNCTION__, WSAGetLastError());
+ break;
+ }
+
+ WSACOMPLETION completion;
+ WSAOVERLAPPED overlapped;
+
+ memset(&overlapped, 0, sizeof(overlapped));
+ overlapped.hEvent = changeEvent;
+
+ memset(&completion, 0, sizeof(completion));
+ completion.Type = NSP_NOTIFY_EVENT;
+ completion.Parameters.Event.lpOverlapped = &overlapped;
+
+ DWORD bytesReturned = 0;
+ result = WSANSPIoctl(handle, SIO_NSP_NOTIFY_CHANGE, 0, 0, 0, 0,
+ &bytesReturned, &completion);
+ if (result == SOCKET_ERROR) {
+ int error = WSAGetLastError();
+ if (error != WSA_IO_PENDING) {
+ qWarning("WSANSPIoctl error %d", error);
+ break;
+ }
+ }
+
+#ifndef Q_OS_WINCE
+ // Not interested in unrelated IO completion events
+ // although we also don't want to block them
+ while (WaitForSingleObjectEx(changeEvent, WSA_INFINITE, true) != WAIT_IO_COMPLETION &&
+ handle)
+ {
+ }
+#else
+ WaitForSingleObject(changeEvent, WSA_INFINITE);
+#endif
+
+ mutex.lock();
+ if (handle) {
+ result = WSALookupServiceEnd(handle);
+ if (result == SOCKET_ERROR) {
+ qWarning("WSALookupServiceEnd error %d", WSAGetLastError());
+ mutex.unlock();
+ break;
+ }
+ handle = 0;
+ }
+ mutex.unlock();
+ }
+
+ WSACloseEvent(changeEvent);
+}
+
+void QNlaThread::updateConfigurations(QList<QNetworkConfigurationPrivate *> &configs)
+{
+ mutex.lock();
+
+ while (!fetchedConfigurations.isEmpty())
+ delete fetchedConfigurations.takeFirst();
+
+ fetchedConfigurations = configs;
+
+ mutex.unlock();
+
+ emit networksChanged();
+}
+
+DWORD QNlaThread::parseBlob(NLA_BLOB *blob, QNetworkConfigurationPrivate *cpPriv) const
+{
+#ifdef BEARER_MANAGEMENT_DEBUG
+ printBlob(blob);
+#endif
+
+ switch (blob->header.type) {
+ case NLA_RAW_DATA:
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qWarning("%s: unhandled header type NLA_RAW_DATA", __FUNCTION__);
+#endif
+ break;
+ case NLA_INTERFACE:
+ cpPriv->state = QNetworkConfiguration::Active;
+ if (QNlaEngine *engine = qobject_cast<QNlaEngine *>(parent())) {
+ engine->configurationInterface[cpPriv->id.toUInt()] =
+ QString::fromLatin1(blob->data.interfaceData.adapterName);
+ }
+ break;
+ case NLA_802_1X_LOCATION:
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qWarning("%s: unhandled header type NLA_802_1X_LOCATION", __FUNCTION__);
+#endif
+ break;
+ case NLA_CONNECTIVITY:
+ if (blob->data.connectivity.internet == NLA_INTERNET_YES)
+ cpPriv->internet = true;
+ else
+ cpPriv->internet = false;
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qWarning("%s: unhandled header type NLA_CONNECTIVITY", __FUNCTION__);
+#endif
+ break;
+ case NLA_ICS:
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qWarning("%s: unhandled header type NLA_ICS", __FUNCTION__);
+#endif
+ break;
+ default:
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qWarning("%s: unhandled header type %d", __FUNCTION__, blob->header.type);
+#endif
+ ;
+ }
+
+ return blob->header.nextOffset;
+}
+
+QNetworkConfigurationPrivate *QNlaThread::parseQuerySet(const WSAQUERYSET *querySet) const
+{
+ QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate;
+
+ cpPriv->name = QString::fromWCharArray(querySet->lpszServiceInstanceName);
+ cpPriv->isValid = true;
+ cpPriv->id = QString::number(qHash(QLatin1String("NLA:") + cpPriv->name));
+ cpPriv->state = QNetworkConfiguration::Defined;
+ cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
+
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "size:" << querySet->dwSize;
+ qDebug() << "service instance name:" << QString::fromUtf16(querySet->lpszServiceInstanceName);
+ qDebug() << "service class id:" << querySet->lpServiceClassId;
+ qDebug() << "version:" << querySet->lpVersion;
+ qDebug() << "comment:" << QString::fromUtf16(querySet->lpszComment);
+ qDebug() << "namespace:" << querySet->dwNameSpace;
+ qDebug() << "namespace provider id:" << querySet->lpNSProviderId;
+ qDebug() << "context:" << QString::fromUtf16(querySet->lpszContext);
+ qDebug() << "number of protocols:" << querySet->dwNumberOfProtocols;
+ qDebug() << "protocols:" << querySet->lpafpProtocols;
+ qDebug() << "query string:" << QString::fromUtf16(querySet->lpszQueryString);
+ qDebug() << "number of cs addresses:" << querySet->dwNumberOfCsAddrs;
+ qDebug() << "cs addresses:" << querySet->lpcsaBuffer;
+ qDebug() << "output flags:" << querySet->dwOutputFlags;
+#endif
+
+ if (querySet->lpBlob) {
+#ifdef BEARER_MANAGEMENT_DEBUG
+ qDebug() << "blob size:" << querySet->lpBlob->cbSize;
+ qDebug() << "blob data:" << querySet->lpBlob->pBlobData;
+#endif
+
+ DWORD offset = 0;
+ do {
+ NLA_BLOB *blob = reinterpret_cast<NLA_BLOB *>(querySet->lpBlob->pBlobData + offset);
+ DWORD nextOffset = parseBlob(blob, cpPriv);
+ if (nextOffset == offset)
+ break;
+ else
+ offset = nextOffset;
+ } while (offset != 0 && offset < querySet->lpBlob->cbSize);
+ }
+
+ if (QNlaEngine *engine = qobject_cast<QNlaEngine *>(parent()))
+ cpPriv->bearer = engine->bearerName(cpPriv->id);
+
+ return cpPriv;
+}
+
+void QNlaThread::fetchConfigurations()
+{
+ QList<QNetworkConfigurationPrivate *> foundConfigurations;
+
+ WSAQUERYSET qsRestrictions;
+ HANDLE hLookup = 0;
+
+ memset(&qsRestrictions, 0, sizeof(qsRestrictions));
+ qsRestrictions.dwSize = sizeof(qsRestrictions);
+ qsRestrictions.dwNameSpace = NS_NLA;
+
+ int result = WSALookupServiceBegin(&qsRestrictions, LUP_RETURN_ALL | LUP_DEEP, &hLookup);
+ if (result == SOCKET_ERROR) {
+ qWarning("%s: WSALookupServiceBegin error %d", __FUNCTION__, WSAGetLastError());
+ mutex.lock();
+ fetchedConfigurations.clear();
+ mutex.unlock();
+ }
+
+ char buffer[0x10000];
+ while (result == 0) {
+ DWORD bufferLength = sizeof(buffer);
+ result = WSALookupServiceNext(hLookup, LUP_RETURN_ALL,
+ &bufferLength, reinterpret_cast<WSAQUERYSET *>(buffer));
+
+ if (result == SOCKET_ERROR) {
+ int error = WSAGetLastError();
+
+ if (error == WSA_E_NO_MORE)
+ break;
+
+ if (error == WSAEFAULT)
+ break;
+
+ qWarning("WSALookupServiceNext error %d", WSAGetLastError());
+ break;
+ }
+
+ QNetworkConfigurationPrivate *cpPriv =
+ parseQuerySet(reinterpret_cast<WSAQUERYSET *>(buffer));
+
+ foundConfigurations.append(cpPriv);
+ }
+
+ if (hLookup) {
+ result = WSALookupServiceEnd(hLookup);
+ if (result == SOCKET_ERROR) {
+ qWarning("WSALookupServiceEnd error %d", WSAGetLastError());
+ }
+ }
+
+ updateConfigurations(foundConfigurations);
+}
+
+QNlaEngine::QNlaEngine(QObject *parent)
+: QBearerEngineImpl(parent), nlaThread(0)
+{
+ nlaThread = new QNlaThread(this);
+ connect(nlaThread, SIGNAL(networksChanged()),
+ this, SLOT(networksChanged()));
+ nlaThread->start();
+
+ qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+}
+
+QNlaEngine::~QNlaEngine()
+{
+ delete nlaThread;
+}
+
+void QNlaEngine::networksChanged()
+{
+ QMutexLocker locker(&mutex);
+
+ QStringList previous = accessPointConfigurations.keys();
+
+ QList<QNetworkConfigurationPrivate *> foundConfigurations = nlaThread->getConfigurations();
+ while (!foundConfigurations.isEmpty()) {
+ QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst();
+
+ previous.removeAll(cpPriv->id);
+
+ if (accessPointConfigurations.contains(cpPriv->id)) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id);
+
+ bool changed = false;
+
+ if (ptr->isValid != cpPriv->isValid) {
+ ptr->isValid = cpPriv->isValid;
+ changed = true;
+ }
+
+ if (ptr->name != cpPriv->name) {
+ ptr->name = cpPriv->name;
+ changed = true;
+ }
+
+ if (ptr->state != cpPriv->state) {
+ ptr->state = cpPriv->state;
+ changed = true;
+ }
+
+ if (changed)
+ emit configurationChanged(ptr);
+
+ delete cpPriv;
+ } else {
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+
+ accessPointConfigurations.insert(ptr->id, ptr);
+
+ emit configurationAdded(ptr);
+ }
+ }
+
+ while (!previous.isEmpty()) {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.take(previous.takeFirst());
+
+ emit configurationRemoved(ptr);
+ }
+
+ emit updateCompleted();
+}
+
+QString QNlaEngine::getInterfaceFromId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return configurationInterface.value(id.toUInt());
+}
+
+bool QNlaEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return configurationInterface.contains(id.toUInt());
+}
+
+QString QNlaEngine::bearerName(const QString &id)
+{
+ QString interface = getInterfaceFromId(id);
+
+ if (interface.isEmpty())
+ return QString();
+
+ return qGetInterfaceType(interface);
+}
+
+void QNlaEngine::connectToId(const QString &id)
+{
+ emit connectionError(id, OperationNotSupported);
+}
+
+void QNlaEngine::disconnectFromId(const QString &id)
+{
+ emit connectionError(id, OperationNotSupported);
+}
+
+void QNlaEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ nlaThread->forceUpdate();
+}
+
+QNetworkSession::State QNlaEngine::sessionStateForId(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+ if (!ptr)
+ return QNetworkSession::Invalid;
+
+ if (!ptr->isValid) {
+ return QNetworkSession::Invalid;
+ } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ return QNetworkSession::Connected;
+ } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ return QNetworkSession::Disconnected;
+ } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+ return QNetworkSession::NotAvailable;
+ } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
+ QNetworkConfiguration::Undefined) {
+ return QNetworkSession::NotAvailable;
+ }
+
+ return QNetworkSession::Invalid;
+}
+
+QNetworkConfigurationManager::Capabilities QNlaEngine::capabilities() const
+{
+ return QNetworkConfigurationManager::ForcedRoaming;
+}
+
+QNetworkSessionPrivate *QNlaEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl;
+}
+
+QNetworkConfigurationPrivatePointer QNlaEngine::defaultConfiguration()
+{
+ return QNetworkConfigurationPrivatePointer();
+}
+
+#include "qnlaengine.moc"
+QT_END_NAMESPACE
+
diff --git a/src/plugins/bearer/nla/qnlaengine.h b/src/plugins/bearer/nla/qnlaengine.h
new file mode 100644
index 0000000000..14c5201de7
--- /dev/null
+++ b/src/plugins/bearer/nla/qnlaengine.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** 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 QNLAENGINE_P_H
+#define QNLAENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "../qbearerengine_impl.h"
+
+#include <QtNetwork/private/qnativesocketengine_p.h>
+
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkConfigurationPrivate;
+class QNlaThread;
+
+class QWindowsSockInit2
+{
+public:
+ QWindowsSockInit2();
+ ~QWindowsSockInit2();
+ int version;
+};
+
+class QNlaEngine : public QBearerEngineImpl
+{
+ Q_OBJECT
+
+ friend class QNlaThread;
+
+public:
+ QNlaEngine(QObject *parent = 0);
+ ~QNlaEngine();
+
+ QString getInterfaceFromId(const QString &id);
+ bool hasIdentifier(const QString &id);
+
+ QString bearerName(const QString &id);
+
+ void connectToId(const QString &id);
+ void disconnectFromId(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkSession::State sessionStateForId(const QString &id);
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+private Q_SLOTS:
+ void networksChanged();
+
+private:
+ QWindowsSockInit2 winSock;
+ QNlaThread *nlaThread;
+ QMap<uint, QString> configurationInterface;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/bearer/platformdefs_win.h b/src/plugins/bearer/platformdefs_win.h
new file mode 100644
index 0000000000..37d099cb76
--- /dev/null
+++ b/src/plugins/bearer/platformdefs_win.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** 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 QPLATFORMDEFS_WIN_H
+#define QPLATFORMDEFS_WIN_H
+
+#include <winsock2.h>
+#include <mswsock.h>
+#undef interface
+#include <winioctl.h>
+
+#ifndef NS_NLA
+
+#define NS_NLA 15
+
+enum NLA_BLOB_DATA_TYPE {
+ NLA_RAW_DATA = 0,
+ NLA_INTERFACE = 1,
+ NLA_802_1X_LOCATION = 2,
+ NLA_CONNECTIVITY = 3,
+ NLA_ICS = 4
+};
+
+enum NLA_CONNECTIVITY_TYPE {
+ NLA_NETWORK_AD_HOC = 0,
+ NLA_NETWORK_MANAGED = 1,
+ NLA_NETWORK_UNMANAGED = 2,
+ NLA_NETWORK_UNKNOWN = 3
+};
+
+enum NLA_INTERNET {
+ NLA_INTERNET_UNKNOWN = 0,
+ NLA_INTERNET_NO = 1,
+ NLA_INTERNET_YES = 2
+};
+
+struct NLA_BLOB {
+ struct {
+ NLA_BLOB_DATA_TYPE type;
+ DWORD dwSize;
+ DWORD nextOffset;
+ } header;
+
+ union {
+ // NLA_RAW_DATA
+ CHAR rawData[1];
+
+ // NLA_INTERFACE
+ struct {
+ DWORD dwType;
+ DWORD dwSpeed;
+ CHAR adapterName[1];
+ } interfaceData;
+
+ // NLA_802_1X_LOCATION
+ struct {
+ CHAR information[1];
+ } locationData;
+
+ // NLA_CONNECTIVITY
+ struct {
+ NLA_CONNECTIVITY_TYPE type;
+ NLA_INTERNET internet;
+ } connectivity;
+
+ // NLA_ICS
+ struct {
+ struct {
+ DWORD speed;
+ DWORD type;
+ DWORD state;
+ WCHAR machineName[256];
+ WCHAR sharedAdapterName[256];
+ } remote;
+ } ICS;
+ } data;
+};
+#endif
+
+enum NDIS_MEDIUM {
+ NdisMedium802_3 = 0,
+};
+
+enum NDIS_PHYSICAL_MEDIUM {
+ NdisPhysicalMediumWirelessLan = 1,
+ NdisPhysicalMediumBluetooth = 10,
+ NdisPhysicalMediumWiMax = 12,
+};
+
+#define OID_GEN_MEDIA_SUPPORTED 0x00010103
+#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
+
+#define IOCTL_NDIS_QUERY_GLOBAL_STATS \
+ CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, 0, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+
+#endif
diff --git a/src/plugins/bearer/qbearerengine_impl.h b/src/plugins/bearer/qbearerengine_impl.h
new file mode 100644
index 0000000000..740def3dab
--- /dev/null
+++ b/src/plugins/bearer/qbearerengine_impl.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** 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 QBEARERENGINE_IMPL_H
+#define QBEARERENGINE_IMPL_H
+
+#include <QtNetwork/private/qbearerengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBearerEngineImpl : public QBearerEngine
+{
+ Q_OBJECT
+
+public:
+ enum ConnectionError {
+ InterfaceLookupError = 0,
+ ConnectError,
+ OperationNotSupported,
+ DisconnectionError,
+ };
+
+ QBearerEngineImpl(QObject *parent = 0) : QBearerEngine(parent) { }
+ ~QBearerEngineImpl() { }
+
+ virtual void connectToId(const QString &id) = 0;
+ virtual void disconnectFromId(const QString &id) = 0;
+
+ virtual QString getInterfaceFromId(const QString &id) = 0;
+
+ virtual QNetworkSession::State sessionStateForId(const QString &id) = 0;
+
+ virtual quint64 bytesWritten(const QString &) { return Q_UINT64_C(0); }
+ virtual quint64 bytesReceived(const QString &) { return Q_UINT64_C(0); }
+ virtual quint64 startTime(const QString &) { return Q_UINT64_C(0); }
+
+Q_SIGNALS:
+ void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp
new file mode 100644
index 0000000000..f41fdbaba4
--- /dev/null
+++ b/src/plugins/bearer/qnetworksession_impl.cpp
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworksession_impl.h"
+#include "qbearerengine_impl.h"
+
+#include <QtNetwork/qnetworksession.h>
+#include <QtNetwork/private/qnetworkconfigmanager_p.h>
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qmutex.h>
+
+#include <QtNetwork/qnetworkinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+static QBearerEngineImpl *getEngineFromId(const QString &id)
+{
+ QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
+
+ foreach (QBearerEngine *engine, priv->engines()) {
+ QBearerEngineImpl *engineImpl = qobject_cast<QBearerEngineImpl *>(engine);
+ if (engineImpl && engineImpl->hasIdentifier(id))
+ return engineImpl;
+ }
+
+ return 0;
+}
+
+class QNetworkSessionManagerPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QNetworkSessionManagerPrivate(QObject *parent = 0);
+ ~QNetworkSessionManagerPrivate();
+
+ void forceSessionClose(const QNetworkConfiguration &config);
+
+Q_SIGNALS:
+ void forcedSessionClose(const QNetworkConfiguration &config);
+};
+
+#include "qnetworksession_impl.moc"
+
+Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager);
+
+QNetworkSessionManagerPrivate::QNetworkSessionManagerPrivate(QObject *parent)
+: QObject(parent)
+{
+}
+
+QNetworkSessionManagerPrivate::~QNetworkSessionManagerPrivate()
+{
+}
+
+void QNetworkSessionManagerPrivate::forceSessionClose(const QNetworkConfiguration &config)
+{
+ emit forcedSessionClose(config);
+}
+
+void QNetworkSessionPrivateImpl::syncStateWithInterface()
+{
+ connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged()));
+ connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SLOT(configurationChanged(QNetworkConfiguration)));
+ connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)),
+ this, SLOT(forcedSessionClose(QNetworkConfiguration)));
+
+ opened = false;
+ isOpen = false;
+ state = QNetworkSession::Invalid;
+ lastError = QNetworkSession::UnknownSessionError;
+
+ qRegisterMetaType<QBearerEngineImpl::ConnectionError>
+ ("QBearerEngineImpl::ConnectionError");
+
+ switch (publicConfig.type()) {
+ case QNetworkConfiguration::InternetAccessPoint:
+ activeConfig = publicConfig;
+ engine = getEngineFromId(activeConfig.identifier());
+ if (engine) {
+ connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
+ this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)),
+ Qt::QueuedConnection);
+ }
+ break;
+ case QNetworkConfiguration::ServiceNetwork:
+ serviceConfig = publicConfig;
+ // Defer setting engine and signals until open().
+ // fall through
+ case QNetworkConfiguration::UserChoice:
+ // Defer setting serviceConfig and activeConfig until open().
+ // fall through
+ default:
+ engine = 0;
+ }
+
+ networkConfigurationsChanged();
+}
+
+void QNetworkSessionPrivateImpl::open()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ } else if (!isOpen) {
+ if ((activeConfig.state() & QNetworkConfiguration::Discovered) !=
+ QNetworkConfiguration::Discovered) {
+ lastError =QNetworkSession::InvalidConfigurationError;
+ emit QNetworkSessionPrivate::error(lastError);
+ return;
+ }
+ opened = true;
+
+ if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active &&
+ (activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
+ state = QNetworkSession::Connecting;
+ emit stateChanged(state);
+
+ engine->connectToId(activeConfig.identifier());
+ }
+
+ isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
+ if (isOpen)
+ emit quitPendingWaitsForOpened();
+ }
+}
+
+void QNetworkSessionPrivateImpl::close()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ } else if (isOpen) {
+ opened = false;
+ isOpen = false;
+ emit closed();
+ }
+}
+
+void QNetworkSessionPrivateImpl::stop()
+{
+ if (serviceConfig.isValid()) {
+ lastError = QNetworkSession::OperationNotSupportedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ } else {
+ if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ state = QNetworkSession::Closing;
+ emit stateChanged(state);
+
+ engine->disconnectFromId(activeConfig.identifier());
+
+ sessionManager()->forceSessionClose(activeConfig);
+ }
+
+ opened = false;
+ isOpen = false;
+ emit closed();
+ }
+}
+
+void QNetworkSessionPrivateImpl::migrate()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+void QNetworkSessionPrivateImpl::accept()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+void QNetworkSessionPrivateImpl::ignore()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+void QNetworkSessionPrivateImpl::reject()
+{
+ qWarning("This platform does not support roaming (%s).", __FUNCTION__);
+}
+
+QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const
+{
+ if (!publicConfig.isValid() || !engine || state != QNetworkSession::Connected)
+ return QNetworkInterface();
+
+ QString interface = engine->getInterfaceFromId(activeConfig.identifier());
+
+ if (interface.isEmpty())
+ return QNetworkInterface();
+ return QNetworkInterface::interfaceFromName(interface);
+}
+
+QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const
+{
+ return QVariant();
+}
+
+void QNetworkSessionPrivateImpl::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/)
+{
+}
+
+QString QNetworkSessionPrivateImpl::errorString() const
+{
+ switch (lastError) {
+ case QNetworkSession::UnknownSessionError:
+ return tr("Unknown session error.");
+ case QNetworkSession::SessionAbortedError:
+ return tr("The session was aborted by the user or system.");
+ case QNetworkSession::OperationNotSupportedError:
+ return tr("The requested operation is not supported by the system.");
+ case QNetworkSession::InvalidConfigurationError:
+ return tr("The specified configuration cannot be used.");
+ case QNetworkSession::RoamingError:
+ return tr("Roaming was aborted or is not possible.");
+
+ }
+
+ return QString();
+}
+
+QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
+{
+ return lastError;
+}
+
+quint64 QNetworkSessionPrivateImpl::bytesWritten() const
+{
+ if (engine && state == QNetworkSession::Connected)
+ return engine->bytesWritten(activeConfig.identifier());
+ else
+ return Q_UINT64_C(0);
+}
+
+quint64 QNetworkSessionPrivateImpl::bytesReceived() const
+{
+ if (engine && state == QNetworkSession::Connected)
+ return engine->bytesReceived(activeConfig.identifier());
+ else
+ return Q_UINT64_C(0);
+}
+
+quint64 QNetworkSessionPrivateImpl::activeTime() const
+{
+ if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0))
+ return QDateTime::currentDateTime().toTime_t() - startTime;
+ else
+ return Q_UINT64_C(0);
+}
+
+void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork()
+{
+ QNetworkSession::State oldState = state;
+
+ foreach (const QNetworkConfiguration &config, serviceConfig.children()) {
+ if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active)
+ continue;
+
+ if (activeConfig != config) {
+ if (engine) {
+ disconnect(engine,
+ SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
+ this,
+ SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)));
+ }
+
+ activeConfig = config;
+ engine = getEngineFromId(activeConfig.identifier());
+ if (engine) {
+ connect(engine,
+ SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
+ this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)),
+ Qt::QueuedConnection);
+ }
+ emit newConfigurationActivated();
+ }
+
+ state = QNetworkSession::Connected;
+ if (state != oldState)
+ emit stateChanged(state);
+
+ return;
+ }
+
+ if (serviceConfig.children().isEmpty())
+ state = QNetworkSession::NotAvailable;
+ else
+ state = QNetworkSession::Disconnected;
+
+ if (state != oldState)
+ emit stateChanged(state);
+}
+
+void QNetworkSessionPrivateImpl::updateStateFromActiveConfig()
+{
+ if (!engine)
+ return;
+
+ QNetworkSession::State oldState = state;
+
+ state = engine->sessionStateForId(activeConfig.identifier());
+
+ bool oldActive = isOpen;
+ isOpen = (state == QNetworkSession::Connected) ? opened : false;
+
+ if (!oldActive && isOpen)
+ emit quitPendingWaitsForOpened();
+ if (oldActive && !isOpen)
+ emit closed();
+
+ if (oldState != state)
+ emit stateChanged(state);
+}
+
+void QNetworkSessionPrivateImpl::networkConfigurationsChanged()
+{
+ if (serviceConfig.isValid())
+ updateStateFromServiceNetwork();
+ else
+ updateStateFromActiveConfig();
+
+ startTime = engine->startTime(activeConfig.identifier());
+}
+
+void QNetworkSessionPrivateImpl::configurationChanged(const QNetworkConfiguration &config)
+{
+ if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig))
+ updateStateFromServiceNetwork();
+ else if (config == activeConfig)
+ updateStateFromActiveConfig();
+}
+
+void QNetworkSessionPrivateImpl::forcedSessionClose(const QNetworkConfiguration &config)
+{
+ if (activeConfig == config) {
+ opened = false;
+ isOpen = false;
+
+ emit closed();
+
+ lastError = QNetworkSession::SessionAbortedError;
+ emit QNetworkSessionPrivate::error(lastError);
+ }
+}
+
+void QNetworkSessionPrivateImpl::connectionError(const QString &id,
+ QBearerEngineImpl::ConnectionError error)
+{
+ if (activeConfig.identifier() == id) {
+ networkConfigurationsChanged();
+ switch (error) {
+ case QBearerEngineImpl::OperationNotSupported:
+ lastError = QNetworkSession::OperationNotSupportedError;
+ opened = false;
+ break;
+ case QBearerEngineImpl::InterfaceLookupError:
+ case QBearerEngineImpl::ConnectError:
+ case QBearerEngineImpl::DisconnectionError:
+ default:
+ lastError = QNetworkSession::UnknownSessionError;
+ }
+
+ emit quitPendingWaitsForOpened();
+ emit QNetworkSessionPrivate::error(lastError);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h
new file mode 100644
index 0000000000..7349e772b8
--- /dev/null
+++ b/src/plugins/bearer/qnetworksession_impl.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** 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 QNETWORKSESSION_IMPL_H
+#define QNETWORKSESSION_IMPL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qbearerengine_impl.h"
+
+#include <QtNetwork/private/qnetworkconfigmanager_p.h>
+#include <QtNetwork/private/qnetworksession_p.h>
+
+#include <QtCore/qdatetime.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBearerEngineImpl;
+
+class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate
+{
+ Q_OBJECT
+public:
+ QNetworkSessionPrivateImpl()
+ : startTime(0)
+ {
+ }
+
+ ~QNetworkSessionPrivateImpl()
+ {
+ }
+
+ //called by QNetworkSession constructor and ensures
+ //that the state is immediately updated (w/o actually opening
+ //a session). Also this function should take care of
+ //notification hooks to discover future state changes.
+ void syncStateWithInterface();
+
+ QNetworkInterface currentInterface() const;
+ QVariant sessionProperty(const QString& key) const;
+ void setSessionProperty(const QString& key, const QVariant& value);
+
+ void open();
+ void close();
+ void stop();
+ void migrate();
+ void accept();
+ void ignore();
+ void reject();
+
+ QString errorString() const; //must return translated string
+ QNetworkSession::SessionError error() const;
+
+ quint64 bytesWritten() const;
+ quint64 bytesReceived() const;
+ quint64 activeTime() const;
+
+private:
+ void updateStateFromServiceNetwork();
+ void updateStateFromActiveConfig();
+
+private Q_SLOTS:
+ void networkConfigurationsChanged();
+ void configurationChanged(const QNetworkConfiguration &config);
+ void forcedSessionClose(const QNetworkConfiguration &config);
+ void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error);
+
+private:
+ QNetworkConfigurationManager manager;
+
+ bool opened;
+
+ QBearerEngineImpl *engine;
+
+ QNetworkSession::SessionError lastError;
+
+ quint64 startTime;
+};
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKSESSION_IMPL_H
+
diff --git a/src/plugins/bearer/symbian/main.cpp b/src/plugins/bearer/symbian/main.cpp
new file mode 100644
index 0000000000..0321451716
--- /dev/null
+++ b/src/plugins/bearer/symbian/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "symbianengine.h"
+
+#include <QtNetwork/private/qbearerplugin_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSymbianEnginePlugin : public QBearerEnginePlugin
+{
+public:
+ QSymbianEnginePlugin();
+ ~QSymbianEnginePlugin();
+
+ QStringList keys() const;
+ QBearerEngine *create(const QString &key) const;
+};
+
+QSymbianEnginePlugin::QSymbianEnginePlugin()
+{
+}
+
+QSymbianEnginePlugin::~QSymbianEnginePlugin()
+{
+}
+
+QStringList QSymbianEnginePlugin::keys() const
+{
+ return QStringList() << QLatin1String("symbian");
+}
+
+QBearerEngine *QSymbianEnginePlugin::create(const QString &key) const
+{
+ if (key == QLatin1String("symbian"))
+ return new SymbianEngine;
+ else
+ return 0;
+}
+
+Q_EXPORT_STATIC_PLUGIN(QSymbianEnginePlugin)
+Q_EXPORT_PLUGIN2(qsymbianbearer, QSymbianEnginePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
new file mode 100644
index 0000000000..9af1fe946c
--- /dev/null
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -0,0 +1,1135 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworksession_impl.h"
+#include "symbianengine.h"
+
+#include <es_enum.h>
+#include <es_sock.h>
+#include <in_sock.h>
+#include <stdapis/sys/socket.h>
+#include <stdapis/net/if.h>
+
+QT_BEGIN_NAMESPACE
+
+QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
+ : CActive(CActive::EPriorityStandard), engine(engine), ipConnectionNotifier(0),
+ iError(QNetworkSession::UnknownSessionError),
+ iALREnabled(0)
+{
+ 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);
+ }
+
+ TRAP_IGNORE(iConnectionMonitor.ConnectL());
+}
+
+QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
+{
+ isOpen = false;
+
+ // Cancel Connection Progress Notifications first.
+ // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start()
+ // => deleting ipConnectionNotifier results RConnection::CancelProgressNotification()
+ delete ipConnectionNotifier;
+ ipConnectionNotifier = NULL;
+
+ // Cancel possible RConnection::Start()
+ Cancel();
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ if (iMobility) {
+ delete iMobility;
+ iMobility = NULL;
+ }
+#endif
+
+ iConnection.Close();
+ iSocketServ.Close();
+ if (iDynamicSetdefaultif) {
+ iDynamicSetdefaultif(0);
+ }
+
+ iConnectionMonitor.CancelNotifications();
+ iConnectionMonitor.Close();
+
+ iOpenCLibrary.Close();
+}
+
+void QNetworkSessionPrivateImpl::syncStateWithInterface()
+{
+ if (!privateConfiguration(publicConfig))
+ return;
+
+ // Start monitoring changes in IAP states
+ TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+
+ // Check open connections to see if there is already
+ // an open connection to selected IAP or SNAP
+ TUint count;
+ TRequestStatus status;
+ iConnectionMonitor.GetConnectionCount(count, status);
+ User::WaitForRequest(status);
+ if (status.Int() != KErrNone) {
+ return;
+ }
+
+ TUint numSubConnections;
+ TUint connectionId;
+ for (TUint i = 1; i <= count; i++) {
+ TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);
+ if (ret == KErrNone) {
+ TUint apId;
+ iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ TInt connectionStatus;
+ iConnectionMonitor.GetIntAttribute(connectionId, 0, KConnectionStatus, connectionStatus, status);
+ User::WaitForRequest(status);
+ if (connectionStatus == KLinkLayerOpen) {
+ if (state != QNetworkSession::Closing) {
+ if (newState(QNetworkSession::Connected, apId)) {
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (state != QNetworkSession::Connected) {
+ // There were no open connections to used IAP or SNAP
+ if ((privateConfiguration(publicConfig)->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ newState(QNetworkSession::Disconnected);
+ } else {
+ newState(QNetworkSession::NotAvailable);
+ }
+ }
+}
+
+QNetworkInterface QNetworkSessionPrivateImpl::interface(TUint iapId) const
+{
+ QString interfaceName;
+
+ TSoInetInterfaceInfo ifinfo;
+ TPckg<TSoInetInterfaceInfo> ifinfopkg(ifinfo);
+ TSoInetIfQuery ifquery;
+ TPckg<TSoInetIfQuery> ifquerypkg(ifquery);
+
+ // Open dummy socket for interface queries
+ RSocket socket;
+ TInt retVal = socket.Open(iSocketServ, _L("udp"));
+ if (retVal != KErrNone) {
+ return QNetworkInterface();
+ }
+
+ // Start enumerating interfaces
+ socket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl);
+ while(socket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, ifinfopkg) == KErrNone) {
+ ifquery.iName = ifinfo.iName;
+ TInt err = socket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, ifquerypkg);
+ if(err == KErrNone && ifquery.iZone[1] == iapId) { // IAP ID is index 1 of iZone
+ if(ifinfo.iAddress.Address() > 0) {
+ interfaceName = QString::fromUtf16(ifinfo.iName.Ptr(),ifinfo.iName.Length());
+ break;
+ }
+ }
+ }
+
+ socket.Close();
+
+ if (interfaceName.isEmpty()) {
+ return QNetworkInterface();
+ }
+
+ return QNetworkInterface::interfaceFromName(interfaceName);
+}
+
+QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const
+{
+ if (!publicConfig.isValid() || state != QNetworkSession::Connected) {
+ return QNetworkInterface();
+ }
+
+ return activeInterface;
+}
+
+QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const
+{
+ return QVariant();
+}
+
+void QNetworkSessionPrivateImpl::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/)
+{
+}
+
+QString QNetworkSessionPrivateImpl::errorString() const
+{
+ switch (iError) {
+ case QNetworkSession::UnknownSessionError:
+ return tr("Unknown session error.");
+ case QNetworkSession::SessionAbortedError:
+ return tr("The session was aborted by the user or system.");
+ case QNetworkSession::OperationNotSupportedError:
+ return tr("The requested operation is not supported by the system.");
+ case QNetworkSession::InvalidConfigurationError:
+ return tr("The specified configuration cannot be used.");
+ case QNetworkSession::RoamingError:
+ return tr("Roaming was aborted or is not possible.");
+ }
+
+ return QString();
+}
+
+QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
+{
+ return iError;
+}
+
+void QNetworkSessionPrivateImpl::open()
+{
+ if (isOpen || !privateConfiguration(publicConfig) || (state == QNetworkSession::Connecting)) {
+ return;
+ }
+
+ // Cancel notifications from RConnectionMonitor
+ // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring
+ iConnectionMonitor.CancelNotifications();
+
+ TInt error = iSocketServ.Connect();
+ if (error != KErrNone) {
+ // Could not open RSocketServ
+ newState(QNetworkSession::Invalid);
+ iError = QNetworkSession::UnknownSessionError;
+ emit QNetworkSessionPrivate::error(iError);
+ syncStateWithInterface();
+ return;
+ }
+
+ error = iConnection.Open(iSocketServ);
+ if (error != KErrNone) {
+ // Could not open RConnection
+ iSocketServ.Close();
+ newState(QNetworkSession::Invalid);
+ iError = QNetworkSession::UnknownSessionError;
+ emit QNetworkSessionPrivate::error(iError);
+ syncStateWithInterface();
+ return;
+ }
+
+ // Use RConnection::ProgressNotification for IAP/SNAP monitoring
+ // (<=> ConnectionProgressNotifier uses RConnection::ProgressNotification)
+ if (!ipConnectionNotifier) {
+ ipConnectionNotifier = new ConnectionProgressNotifier(*this,iConnection);
+ }
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StartNotifications();
+ }
+
+ if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+ // Search through existing connections.
+ // If there is already connection which matches to given IAP
+ // try to attach to existing connection.
+ TBool connected(EFalse);
+ TConnectionInfoBuf connInfo;
+ TUint count;
+ if (iConnection.EnumerateConnections(count) == KErrNone) {
+ for (TUint i=1; i<=count; i++) {
+ // Note: GetConnectionInfo expects 1-based index.
+ if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) {
+ if (connInfo().iIapId == toSymbianConfig(privateConfiguration(publicConfig))->numericId) {
+ if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) {
+ activeConfig = publicConfig;
+ activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId);
+ 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);
+ }
+ isOpen = true;
+ // Make sure that state will be Connected
+ newState(QNetworkSession::Connected);
+ emit quitPendingWaitsForOpened();
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (!connected) {
+ TCommDbConnPref pref;
+ pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
+ pref.SetIapId(toSymbianConfig(privateConfiguration(publicConfig))->numericId);
+ iConnection.Start(pref, iStatus);
+ if (!IsActive()) {
+ SetActive();
+ }
+ newState(QNetworkSession::Connecting);
+ }
+ } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ TConnSnapPref snapPref(toSymbianConfig(privateConfiguration(publicConfig))->numericId);
+ iConnection.Start(snapPref, iStatus);
+ if (!IsActive()) {
+ SetActive();
+ }
+ newState(QNetworkSession::Connecting);
+ } else if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurationIdentifiers();
+ iConnection.Start(iStatus);
+ if (!IsActive()) {
+ SetActive();
+ }
+ newState(QNetworkSession::Connecting);
+ }
+
+ if (error != KErrNone) {
+ isOpen = false;
+ iError = QNetworkSession::UnknownSessionError;
+ emit QNetworkSessionPrivate::error(iError);
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+ syncStateWithInterface();
+ }
+}
+
+TUint QNetworkSessionPrivateImpl::iapClientCount(TUint aIAPId) const
+{
+ TRequestStatus status;
+ TUint connectionCount;
+ iConnectionMonitor.GetConnectionCount(connectionCount, status);
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ for (TUint i = 1; i <= connectionCount; i++) {
+ TUint connectionId;
+ TUint subConnectionCount;
+ iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
+ TUint apId;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ if (apId == aIAPId) {
+ TConnMonClientEnumBuf buf;
+ iConnectionMonitor.GetPckgAttribute(connectionId, 0, KClientInfo, buf, status);
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ return buf().iCount;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void QNetworkSessionPrivateImpl::close(bool allowSignals)
+{
+ if (!isOpen) {
+ return;
+ }
+
+ TUint activeIap = toSymbianConfig(privateConfiguration(activeConfig))->numericId;
+ isOpen = false;
+ activeConfig = QNetworkConfiguration();
+ serviceConfig = QNetworkConfiguration();
+
+ Cancel();
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ if (iMobility) {
+ delete iMobility;
+ iMobility = NULL;
+ }
+#endif
+
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+
+ iConnection.Close();
+ iSocketServ.Close();
+ if (iDynamicSetdefaultif) {
+ iDynamicSetdefaultif(0);
+ }
+
+#ifdef Q_CC_NOKIAX86
+ if ((allowSignals && iapClientCount(activeIap) <= 0) ||
+#else
+ if ((allowSignals && iapClientCount(activeIap) <= 1) ||
+#endif
+ (publicConfig.type() == QNetworkConfiguration::UserChoice)) {
+ newState(QNetworkSession::Closing);
+ }
+
+ syncStateWithInterface();
+ if (allowSignals) {
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ newState(QNetworkSession::Disconnected);
+ }
+ emit closed();
+ }
+}
+
+void QNetworkSessionPrivateImpl::stop()
+{
+ if (!isOpen) {
+ return;
+ }
+ isOpen = false;
+ newState(QNetworkSession::Closing);
+ iConnection.Stop(RConnection::EStopAuthoritative);
+ isOpen = true;
+ close(false);
+ emit closed();
+}
+
+void QNetworkSessionPrivateImpl::migrate()
+{
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ iMobility->MigrateToPreferredCarrier();
+#endif
+}
+
+void QNetworkSessionPrivateImpl::ignore()
+{
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ iMobility->IgnorePreferredCarrier();
+ if (!iALRUpgradingConnection) {
+ newState(QNetworkSession::Disconnected);
+ } else {
+ newState(QNetworkSession::Connected,iOldRoamingIap);
+ }
+#endif
+}
+
+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();
+ ifreq ifr;
+ strcpy(ifr.ifr_name, nameAsByteArray.constData());
+
+ iDynamicSetdefaultif(&ifr);
+ }
+ newState(QNetworkSession::Connected, iNewRoamingIap);
+#endif
+}
+
+void QNetworkSessionPrivateImpl::reject()
+{
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ iMobility->NewCarrierRejected();
+ if (!iALRUpgradingConnection) {
+ newState(QNetworkSession::Disconnected);
+ } else {
+ newState(QNetworkSession::Connected, iOldRoamingIap);
+ }
+#endif
+}
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+void QNetworkSessionPrivateImpl::PreferredCarrierAvailable(TAccessPointInfo aOldAPInfo,
+ TAccessPointInfo aNewAPInfo,
+ TBool aIsUpgrade,
+ TBool aIsSeamless)
+{
+ iOldRoamingIap = aOldAPInfo.AccessPoint();
+ iNewRoamingIap = aNewAPInfo.AccessPoint();
+ newState(QNetworkSession::Roaming);
+ if (iALREnabled > 0) {
+ iALRUpgradingConnection = aIsUpgrade;
+ QList<QNetworkConfiguration> configs = publicConfig.children();
+ for (int i=0; i < configs.count(); i++) {
+ if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == aNewAPInfo.AccessPoint()) {
+ emit preferredConfigurationChanged(configs[i], aIsSeamless);
+ }
+ }
+ } else {
+ migrate();
+ }
+}
+
+void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/)
+{
+ if (iALREnabled > 0) {
+ emit newConfigurationActivated();
+ } else {
+ accept();
+ }
+}
+
+void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
+{
+ if (isOpen) {
+ isOpen = false;
+ activeConfig = QNetworkConfiguration();
+ serviceConfig = QNetworkConfiguration();
+ iError = QNetworkSession::RoamingError;
+ emit QNetworkSessionPrivate::error(iError);
+ Cancel();
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+ syncStateWithInterface();
+ // In some cases IAP is still in Connected state when
+ // syncStateWithInterface(); is called
+ // => Following call makes sure that Session state
+ // changes immediately to Disconnected.
+ newState(QNetworkSession::Disconnected);
+ emit closed();
+ }
+}
+#endif
+
+void QNetworkSessionPrivateImpl::setALREnabled(bool enabled)
+{
+ if (enabled) {
+ iALREnabled++;
+ } else {
+ iALREnabled--;
+ }
+}
+
+QNetworkConfiguration QNetworkSessionPrivateImpl::bestConfigFromSNAP(const QNetworkConfiguration& snapConfig) const
+{
+ QNetworkConfiguration config;
+ QList<QNetworkConfiguration> subConfigurations = snapConfig.children();
+ for (int i = 0; i < subConfigurations.count(); i++ ) {
+ if (subConfigurations[i].state() == QNetworkConfiguration::Active) {
+ config = subConfigurations[i];
+ break;
+ } else if (!config.isValid() && subConfigurations[i].state() == QNetworkConfiguration::Discovered) {
+ config = subConfigurations[i];
+ }
+ }
+ if (!config.isValid() && subConfigurations.count() > 0) {
+ config = subConfigurations[0];
+ }
+ return config;
+}
+
+quint64 QNetworkSessionPrivateImpl::bytesWritten() const
+{
+ return transferredData(KUplinkData);
+}
+
+quint64 QNetworkSessionPrivateImpl::bytesReceived() const
+{
+ return transferredData(KDownlinkData);
+}
+
+quint64 QNetworkSessionPrivateImpl::transferredData(TUint dataType) const
+{
+ if (!publicConfig.isValid()) {
+ return 0;
+ }
+
+ QNetworkConfiguration config;
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ if (serviceConfig.isValid()) {
+ config = serviceConfig;
+ } else {
+ if (activeConfig.isValid()) {
+ config = activeConfig;
+ }
+ }
+ } else {
+ config = publicConfig;
+ }
+
+ if (!config.isValid()) {
+ return 0;
+ }
+
+ TUint count;
+ TRequestStatus status;
+ iConnectionMonitor.GetConnectionCount(count, status);
+ User::WaitForRequest(status);
+ if (status.Int() != KErrNone) {
+ return 0;
+ }
+
+ TUint transferredData = 0;
+ TUint numSubConnections;
+ TUint connectionId;
+ bool configFound;
+ for (TUint i = 1; i <= count; i++) {
+ TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);
+ if (ret == KErrNone) {
+ TUint apId;
+ iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ configFound = false;
+ if (config.type() == QNetworkConfiguration::ServiceNetwork) {
+ QList<QNetworkConfiguration> configs = config.children();
+ for (int i=0; i < configs.count(); i++) {
+ if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == apId) {
+ configFound = true;
+ break;
+ }
+ }
+ } else if (toSymbianConfig(privateConfiguration(config))->numericId == apId) {
+ configFound = true;
+ }
+ if (configFound) {
+ TUint tData;
+ iConnectionMonitor.GetUintAttribute(connectionId, 0, dataType, tData, status );
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ transferredData += tData;
+ }
+ }
+ }
+ }
+ }
+
+ return transferredData;
+}
+
+quint64 QNetworkSessionPrivateImpl::activeTime() const
+{
+ if (!isOpen || startTime.isNull()) {
+ return 0;
+ }
+ return startTime.secsTo(QDateTime::currentDateTime());
+}
+
+QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 iapId) const
+{
+ if (iapId == 0) {
+ _LIT(KSetting, "IAP\\Id");
+ iConnection.GetIntSetting(KSetting, iapId);
+ }
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ // Try to search IAP from the used SNAP using IAP Id
+ QList<QNetworkConfiguration> children = publicConfig.children();
+ for (int i=0; i < children.count(); i++) {
+ if (toSymbianConfig(privateConfiguration(children[i]))->numericId == iapId) {
+ return children[i];
+ }
+ }
+
+ // Given IAP Id was not found from the used SNAP
+ // => Try to search matching IAP using mappingName
+ // mappingName contains:
+ // 1. "Access point name" for "Packet data" Bearer
+ // 2. "WLAN network name" (= SSID) for "Wireless LAN" Bearer
+ // 3. "Dial-up number" for "Data call Bearer" or "High Speed (GSM)" Bearer
+ // <=> Note: It's possible that in this case reported IAP is
+ // clone of the one of the IAPs of the used SNAP
+ // => If mappingName matches, clone has been found
+ QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId)));
+ if (privateConfiguration(pt)) {
+ for (int i=0; i < children.count(); i++) {
+ if (toSymbianConfig(privateConfiguration(children[i]))->mappingName == toSymbianConfig(privateConfiguration(pt))->mappingName) {
+ return children[i];
+ }
+ }
+ } else {
+ // Given IAP Id was not found from known IAPs array
+ return QNetworkConfiguration();
+ }
+
+ // Matching IAP was not found from used SNAP
+ // => IAP from another SNAP is returned
+ // (Note: Returned IAP matches to given IAP Id)
+ return pt;
+ }
+#endif
+
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ if (engine) {
+ QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId)));
+ // Try to found User Selected IAP from known IAPs (accessPointConfigurations)
+ if (pt.isValid()) {
+ return pt;
+ } else {
+ // Check if new (WLAN) IAP was created in IAP/SNAP dialog
+ // 1. Sync internal configurations array to commsdb first
+ engine->updateConfigurations();
+ // 2. Check if new configuration was created during connection creation
+ QStringList knownConfigs = engine->accessPointConfigurationIdentifiers();
+ if (knownConfigs.count() > iKnownConfigsBeforeConnectionStart.count()) {
+ // Configuration count increased => new configuration was created
+ // => Search new, created configuration
+ QString newIapId;
+ for (int i=0; i < iKnownConfigsBeforeConnectionStart.count(); i++) {
+ if (knownConfigs[i] != iKnownConfigsBeforeConnectionStart[i]) {
+ newIapId = knownConfigs[i];
+ break;
+ }
+ }
+ if (newIapId.isEmpty()) {
+ newIapId = knownConfigs[knownConfigs.count()-1];
+ }
+ pt = QNetworkConfigurationManager().configurationFromIdentifier(newIapId);
+ if (pt.isValid())
+ return pt;
+ }
+ }
+ }
+ return QNetworkConfiguration();
+ }
+
+ return publicConfig;
+}
+
+void QNetworkSessionPrivateImpl::RunL()
+{
+ TInt statusCode = iStatus.Int();
+
+ switch (statusCode) {
+ case KErrNone: // Connection created succesfully
+ {
+ TInt error = KErrNone;
+ 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();
+ ifreq ifr;
+ strcpy(ifr.ifr_name, nameAsByteArray.constData());
+
+ error = iDynamicSetdefaultif(&ifr);
+ }
+
+ if (error != KErrNone) {
+ isOpen = false;
+ iError = QNetworkSession::UnknownSessionError;
+ emit QNetworkSessionPrivate::error(iError);
+ Cancel();
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+ syncStateWithInterface();
+ return;
+ }
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ // Activate ALR monitoring
+ iMobility = CActiveCommsMobilityApiExt::NewL(iConnection, *this);
+ }
+#endif
+ isOpen = true;
+ activeConfig = newActiveConfig;
+ activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId);
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ serviceConfig = QNetworkConfigurationManager().configurationFromIdentifier(toSymbianConfig(privateConfiguration(activeConfig))->serviceNetworkPtr->id);
+ }
+
+ startTime = QDateTime::currentDateTime();
+
+ newState(QNetworkSession::Connected);
+ emit quitPendingWaitsForOpened();
+ }
+ break;
+ case KErrNotFound: // Connection failed
+ isOpen = false;
+ activeConfig = QNetworkConfiguration();
+ serviceConfig = QNetworkConfiguration();
+ iError = QNetworkSession::InvalidConfigurationError;
+ emit QNetworkSessionPrivate::error(iError);
+ Cancel();
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+ syncStateWithInterface();
+ break;
+ case KErrCancel: // Connection attempt cancelled
+ case KErrAlreadyExists: // Connection already exists
+ default:
+ isOpen = false;
+ activeConfig = QNetworkConfiguration();
+ serviceConfig = QNetworkConfiguration();
+ iError = QNetworkSession::UnknownSessionError;
+ emit QNetworkSessionPrivate::error(iError);
+ Cancel();
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+ syncStateWithInterface();
+ break;
+ }
+}
+
+void QNetworkSessionPrivateImpl::DoCancel()
+{
+ iConnection.Close();
+}
+
+bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint accessPointId)
+{
+ // Make sure that activeConfig is always updated when SNAP is signaled to be
+ // connected.
+ if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork &&
+ newState == QNetworkSession::Connected) {
+ activeConfig = activeConfiguration(accessPointId);
+ activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId);
+#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());
+
+ iDynamicSetdefaultif(&ifr);
+ }
+#endif
+ }
+
+ // Make sure that same state is not signaled twice in a row.
+ if (state == newState) {
+ return true;
+ }
+
+ // Make sure that Connecting state does not overwrite Roaming state
+ if (state == QNetworkSession::Roaming && newState == QNetworkSession::Connecting) {
+ return false;
+ }
+
+ bool emitSessionClosed = false;
+ if (isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) {
+ // Active & Connected state should change directly to Disconnected state
+ // only when something forces connection to close (eg. when another
+ // application or session stops connection or when network drops
+ // unexpectedly).
+ isOpen = false;
+ activeConfig = QNetworkConfiguration();
+ serviceConfig = QNetworkConfiguration();
+ iError = QNetworkSession::SessionAbortedError;
+ emit QNetworkSessionPrivate::error(iError);
+ Cancel();
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ }
+ // Start monitoring changes in IAP states
+ TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+ emitSessionClosed = true; // Emit SessionClosed after state change has been reported
+ }
+
+ bool retVal = false;
+ if (accessPointId == 0) {
+ state = newState;
+ emit stateChanged(state);
+ retVal = true;
+ } else {
+ if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+ if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == accessPointId) {
+ state = newState;
+ emit stateChanged(state);
+ retVal = true;
+ }
+ } else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) {
+ if (toSymbianConfig(privateConfiguration(activeConfig))->numericId == accessPointId) {
+ state = newState;
+ emit stateChanged(state);
+ retVal = true;
+ }
+ } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
+ for (int i = 0; i < subConfigurations.count(); i++) {
+ if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == accessPointId) {
+ if (newState == QNetworkSession::Connected) {
+ // Make sure that when AccessPoint is reported to be Connected
+ // also state of the related configuration changes to Active.
+ privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Active;
+
+ state = newState;
+ emit stateChanged(state);
+ retVal = true;
+ } else {
+ if (newState == QNetworkSession::Disconnected) {
+ // Make sure that when AccessPoint is reported to be disconnected
+ // also state of the related configuration changes from Active to Defined.
+ privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Defined;
+ }
+ QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
+ if ((config.state() == QNetworkConfiguration::Defined) ||
+ (config.state() == QNetworkConfiguration::Discovered)) {
+ state = newState;
+ emit stateChanged(state);
+ retVal = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (emitSessionClosed) {
+ emit closed();
+ }
+
+ return retVal;
+}
+
+void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConnectionStatus,
+ TInt aError,
+ TUint accessPointId)
+{
+ switch (aConnectionStatus)
+ {
+ // Connection unitialised
+ case KConnectionUninitialised:
+ break;
+
+ // Starting connetion selection
+ case KStartingSelection:
+ break;
+
+ // Selection finished
+ case KFinishedSelection:
+ if (aError == KErrNone)
+ {
+ // The user successfully selected an IAP to be used
+ break;
+ }
+ else
+ {
+ // The user pressed e.g. "Cancel" and did not select an IAP
+ newState(QNetworkSession::Disconnected,accessPointId);
+ }
+ break;
+
+ // Connection failure
+ case KConnectionFailure:
+ newState(QNetworkSession::NotAvailable);
+ break;
+
+ // Prepearing connection (e.g. dialing)
+ case KPsdStartingConfiguration:
+ case KPsdFinishedConfiguration:
+ case KCsdFinishedDialling:
+ case KCsdScanningScript:
+ case KCsdGettingLoginInfo:
+ case KCsdGotLoginInfo:
+ break;
+
+ // Creating connection (e.g. GPRS activation)
+ case KCsdStartingConnect:
+ case KCsdFinishedConnect:
+ newState(QNetworkSession::Connecting,accessPointId);
+ break;
+
+ // Starting log in
+ case KCsdStartingLogIn:
+ break;
+
+ // Finished login
+ case KCsdFinishedLogIn:
+ break;
+
+ // Connection open
+ case KConnectionOpen:
+ break;
+
+ case KLinkLayerOpen:
+ newState(QNetworkSession::Connected,accessPointId);
+ break;
+
+ // Connection blocked or suspended
+ case KDataTransferTemporarilyBlocked:
+ break;
+
+ // Hangup or GRPS deactivation
+ case KConnectionStartingClose:
+ newState(QNetworkSession::Closing,accessPointId);
+ break;
+
+ // Connection closed
+ case KConnectionClosed:
+ break;
+
+ case KLinkLayerClosed:
+ newState(QNetworkSession::Disconnected,accessPointId);
+ break;
+
+ // Unhandled state
+ default:
+ break;
+ }
+}
+
+void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent)
+{
+ switch (aEvent.EventType())
+ {
+ case EConnMonConnectionStatusChange:
+ {
+ CConnMonConnectionStatusChange* realEvent;
+ realEvent = (CConnMonConnectionStatusChange*) &aEvent;
+
+ TUint connectionId = realEvent->ConnectionId();
+ TInt connectionStatus = realEvent->ConnectionStatus();
+
+ // Try to Find IAP Id using connection Id
+ TUint apId = 0;
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
+ for (int i = 0; i < subConfigurations.count(); i++ ) {
+ if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) {
+ apId = toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId;
+ break;
+ }
+ }
+ } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+ if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) {
+ apId = toSymbianConfig(privateConfiguration(publicConfig))->numericId;
+ }
+ }
+
+ if (apId > 0) {
+ handleSymbianConnectionStatusChange(connectionStatus, KErrNone, apId);
+ }
+ }
+ break;
+
+ case EConnMonCreateConnection:
+ {
+ CConnMonCreateConnection* realEvent;
+ realEvent = (CConnMonCreateConnection*) &aEvent;
+ TUint apId;
+ TUint connectionId = realEvent->ConnectionId();
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ // Store connection id to related AccessPoint Configuration
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
+ for (int i = 0; i < subConfigurations.count(); i++ ) {
+ if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == apId) {
+ toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = connectionId;
+ break;
+ }
+ }
+ } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+ if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == apId) {
+ toSymbianConfig(privateConfiguration(publicConfig))->connectionId = connectionId;
+ }
+ }
+ }
+ }
+ break;
+
+ case EConnMonDeleteConnection:
+ {
+ CConnMonDeleteConnection* realEvent;
+ realEvent = (CConnMonDeleteConnection*) &aEvent;
+ TUint connectionId = realEvent->ConnectionId();
+ // Remove connection id from related AccessPoint Configuration
+ if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+ QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
+ for (int i = 0; i < subConfigurations.count(); i++ ) {
+ if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) {
+ toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = 0;
+ break;
+ }
+ }
+ } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+ if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) {
+ toSymbianConfig(privateConfiguration(publicConfig))->connectionId = 0;
+ }
+ }
+ }
+ break;
+
+ default:
+ // For unrecognized events
+ break;
+ }
+}
+
+ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl &owner, RConnection &connection)
+ : CActive(CActive::EPriorityStandard), iOwner(owner), iConnection(connection)
+{
+ CActiveScheduler::Add(this);
+}
+
+ConnectionProgressNotifier::~ConnectionProgressNotifier()
+{
+ Cancel();
+}
+
+void ConnectionProgressNotifier::StartNotifications()
+{
+ if (!IsActive()) {
+ SetActive();
+ }
+ iConnection.ProgressNotification(iProgress, iStatus);
+}
+
+void ConnectionProgressNotifier::StopNotifications()
+{
+ Cancel();
+}
+
+void ConnectionProgressNotifier::DoCancel()
+{
+ iConnection.CancelProgressNotification();
+}
+
+void ConnectionProgressNotifier::RunL()
+{
+ if (iStatus == KErrNone) {
+ iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError);
+
+ SetActive();
+ iConnection.ProgressNotification(iProgress, iStatus);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h
new file mode 100644
index 0000000000..30f51e1269
--- /dev/null
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.h
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** 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 QNETWORKSESSION_IMPL_H
+#define QNETWORKSESSION_IMPL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtNetwork/private/qnetworksession_p.h>
+
+#include <QDateTime>
+
+#include <e32base.h>
+#include <CommDbConnPref.h>
+#include <es_sock.h>
+#include <rconnmon.h>
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ #include <comms-infras/cs_mobility_apiext.h>
+#endif
+
+typedef int(*TOpenCSetdefaultifFunction)(const struct ifreq*);
+
+QT_BEGIN_NAMESPACE
+
+class ConnectionProgressNotifier;
+class SymbianEngine;
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, public MMobilityProtocolResp,
+ public MConnectionMonitorObserver
+#else
+class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, public MConnectionMonitorObserver
+#endif
+{
+ Q_OBJECT
+public:
+ QNetworkSessionPrivateImpl(SymbianEngine *engine);
+ ~QNetworkSessionPrivateImpl();
+
+ //called by QNetworkSession constructor and ensures
+ //that the state is immediately updated (w/o actually opening
+ //a session). Also this function should take care of
+ //notification hooks to discover future state changes.
+ void syncStateWithInterface();
+
+ QNetworkInterface currentInterface() const;
+ QVariant sessionProperty(const QString& key) const;
+ void setSessionProperty(const QString& key, const QVariant& value);
+
+ void setALREnabled(bool enabled);
+
+ void open();
+ inline void close() { close(true); }
+ void close(bool allowSignals);
+ void stop();
+ void migrate();
+ void accept();
+ void ignore();
+ void reject();
+
+ QString errorString() const; //must return translated string
+ QNetworkSession::SessionError error() const;
+
+ quint64 bytesWritten() const;
+ quint64 bytesReceived() const;
+ quint64 activeTime() const;
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+public: // From MMobilityProtocolResp
+ void PreferredCarrierAvailable(TAccessPointInfo aOldAPInfo,
+ TAccessPointInfo aNewAPInfo,
+ TBool aIsUpgrade,
+ TBool aIsSeamless);
+
+ void NewCarrierActive(TAccessPointInfo aNewAPInfo, TBool aIsSeamless);
+
+ void Error(TInt aError);
+#endif
+
+protected: // From CActive
+ void RunL();
+ void DoCancel();
+
+private: // MConnectionMonitorObserver
+ void EventL(const CConnMonEventBase& aEvent);
+
+private:
+ TUint iapClientCount(TUint aIAPId) const;
+ quint64 transferredData(TUint dataType) const;
+ bool newState(QNetworkSession::State newState, TUint accessPointId = 0);
+ void handleSymbianConnectionStatusChange(TInt aConnectionStatus, TInt aError, TUint accessPointId = 0);
+ QNetworkConfiguration bestConfigFromSNAP(const QNetworkConfiguration& snapConfig) const;
+ QNetworkConfiguration activeConfiguration(TUint32 iapId = 0) const;
+ QNetworkInterface interface(TUint iapId) const;
+
+private: // data
+ SymbianEngine *engine;
+
+ mutable QNetworkInterface activeInterface;
+
+ QDateTime startTime;
+
+ RLibrary iOpenCLibrary;
+ TOpenCSetdefaultifFunction iDynamicSetdefaultif;
+
+ mutable RSocketServ iSocketServ;
+ mutable RConnection iConnection;
+ mutable RConnectionMonitor iConnectionMonitor;
+ ConnectionProgressNotifier* ipConnectionNotifier;
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ CActiveCommsMobilityApiExt* iMobility;
+#endif
+
+ QNetworkSession::SessionError iError;
+ TInt iALREnabled;
+ TBool iALRUpgradingConnection;
+
+ QList<QString> iKnownConfigsBeforeConnectionStart;
+
+ TUint32 iOldRoamingIap;
+ TUint32 iNewRoamingIap;
+
+ friend class ConnectionProgressNotifier;
+};
+
+class ConnectionProgressNotifier : public CActive
+{
+public:
+ ConnectionProgressNotifier(QNetworkSessionPrivateImpl &owner, RConnection &connection);
+ ~ConnectionProgressNotifier();
+
+ void StartNotifications();
+ void StopNotifications();
+
+protected: // From CActive
+ void RunL();
+ void DoCancel();
+
+private: // Data
+ QNetworkSessionPrivateImpl &iOwner;
+ RConnection& iConnection;
+ TNifProgressBuf iProgress;
+
+};
+
+QT_END_NAMESPACE
+
+#endif //QNETWORKSESSION_IMPL_H
+
diff --git a/src/plugins/bearer/symbian/symbian.pro b/src/plugins/bearer/symbian/symbian.pro
new file mode 100644
index 0000000000..9fd1a74125
--- /dev/null
+++ b/src/plugins/bearer/symbian/symbian.pro
@@ -0,0 +1,37 @@
+TARGET = qsymbianbearer
+include(../../qpluginbase.pri)
+
+QT += network
+
+HEADERS += symbianengine.h \
+ qnetworksession_impl.h
+
+SOURCES += symbianengine.cpp \
+ qnetworksession_impl.cpp \
+ main.cpp
+
+exists($${EPOCROOT}epoc32/release/winscw/udeb/cmmanager.lib)| \
+exists($${EPOCROOT}epoc32/release/armv5/lib/cmmanager.lib) {
+ message("Building with SNAP support")
+ DEFINES += SNAP_FUNCTIONALITY_AVAILABLE
+ LIBS += -lcmmanager
+} else {
+ message("Building without SNAP support")
+ LIBS += -lapengine
+}
+
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+
+LIBS += -lcommdb \
+ -lapsettingshandlerui \
+ -lconnmon \
+ -lcentralrepository \
+ -lesock \
+ -linsock \
+ -lecom \
+ -lefsrv \
+ -lnetmeta
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer
+target.path += $$[QT_INSTALL_PLUGINS]/bearer
+INSTALLS += target
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
new file mode 100644
index 0000000000..b3c9cb379c
--- /dev/null
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -0,0 +1,1006 @@
+/****************************************************************************
+**
+** 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 "symbianengine.h"
+#include "qnetworksession_impl.h"
+
+#include <commdb.h>
+#include <cdbcols.h>
+#include <d32dbms.h>
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ #include <cmdestination.h>
+ #include <cmconnectionmethod.h>
+ #include <cmconnectionmethoddef.h>
+ #include <cmpluginwlandef.h>
+ #include <cmpluginpacketdatadef.h>
+ #include <cmplugindialcommondefs.h>
+#else
+ #include <apaccesspointitem.h>
+ #include <apdatahandler.h>
+ #include <aputils.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static const int KValueThatWillBeAddedToSNAPId = 1000;
+static const int KUserChoiceIAPId = 0;
+
+SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate()
+: bearer(BearerUnknown), numericId(0), connectionId(0)
+{
+}
+
+SymbianNetworkConfigurationPrivate::~SymbianNetworkConfigurationPrivate()
+{
+}
+
+QString SymbianNetworkConfigurationPrivate::bearerName() const
+{
+ switch (bearer) {
+ case BearerEthernet:
+ return QLatin1String("Ethernet");
+ case BearerWLAN:
+ return QLatin1String("WLAN");
+ case Bearer2G:
+ return QLatin1String("2G");
+ case BearerCDMA2000:
+ return QLatin1String("CDMA2000");
+ case BearerWCDMA:
+ return QLatin1String("WCDMA");
+ case BearerHSPA:
+ return QLatin1String("HSPA");
+ case BearerBluetooth:
+ return QLatin1String("Bluetooth");
+ case BearerWiMAX:
+ return QLatin1String("WiMAX");
+ default:
+ return QString();
+ }
+}
+
+SymbianEngine::SymbianEngine(QObject *parent)
+: QBearerEngine(parent), CActive(CActive::EPriorityIdle), iInitOk(true)
+{
+ CActiveScheduler::Add(this);
+
+ TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP));
+ if (error != KErrNone) {
+ iInitOk = false;
+ return;
+ }
+
+ TRAP_IGNORE(iConnectionMonitor.ConnectL());
+ TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ TRAP(error, iCmManager.OpenL());
+ if (error != KErrNone) {
+ iInitOk = false;
+ return;
+ }
+#endif
+
+ SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
+ cpPriv->name = "UserChoice";
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+ cpPriv->state = QNetworkConfiguration::Discovered;
+ cpPriv->isValid = true;
+ cpPriv->id = QString::number(qHash(KUserChoiceIAPId));
+ cpPriv->numericId = KUserChoiceIAPId;
+ cpPriv->connectionId = 0;
+ cpPriv->type = QNetworkConfiguration::UserChoice;
+ cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
+ cpPriv->roamingSupported = false;
+
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ userChoiceConfigurations.insert(ptr->id, ptr);
+
+ updateConfigurations();
+ updateStatesToSnaps();
+
+ // Start monitoring IAP and/or SNAP changes in Symbian CommsDB
+ startCommsDatabaseNotifications();
+}
+
+SymbianEngine::~SymbianEngine()
+{
+ Cancel();
+
+ iConnectionMonitor.CancelNotifications();
+ iConnectionMonitor.Close();
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ iCmManager.Close();
+#endif
+
+ delete ipAccessPointsAvailabilityScanner;
+ delete ipCommsDB;
+}
+
+bool SymbianEngine::hasIdentifier(const QString &id)
+{
+ QMutexLocker locker(&mutex);
+
+ return accessPointConfigurations.contains(id) ||
+ snapConfigurations.contains(id) ||
+ userChoiceConfigurations.contains(id);
+}
+
+QNetworkConfigurationManager::Capabilities SymbianEngine::capabilities() const
+{
+ QNetworkConfigurationManager::Capabilities capFlags;
+
+ capFlags = QNetworkConfigurationManager::CanStartAndStopInterfaces |
+ QNetworkConfigurationManager::DirectConnectionRouting |
+ QNetworkConfigurationManager::SystemSessionSupport |
+ QNetworkConfigurationManager::DataStatistics;
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ capFlags |= QNetworkConfigurationManager::ApplicationLevelRoaming |
+ QNetworkConfigurationManager::ForcedRoaming;
+#endif
+
+ return capFlags;
+}
+
+QNetworkSessionPrivate *SymbianEngine::createSessionBackend()
+{
+ return new QNetworkSessionPrivateImpl(this);
+}
+
+void SymbianEngine::requestUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ if (!iInitOk || iUpdateGoingOn) {
+ return;
+ }
+ iUpdateGoingOn = true;
+
+ stopCommsDatabaseNotifications();
+ updateConfigurations(); // Synchronous call
+ updateAvailableAccessPoints(); // Asynchronous call
+}
+
+void SymbianEngine::updateConfigurations()
+{
+ QMutexLocker locker(&mutex);
+
+ if (!iInitOk) {
+ return;
+ }
+
+ TRAP_IGNORE(updateConfigurationsL());
+}
+
+void SymbianEngine::updateConfigurationsL()
+{
+ QMutexLocker locker(&mutex);
+
+ QList<QString> knownConfigs = accessPointConfigurations.keys();
+ QList<QString> knownSnapConfigs = snapConfigurations.keys();
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ // S60 version is >= Series60 3rd Edition Feature Pack 2
+ TInt error = KErrNone;
+
+ // Loop through all IAPs
+ RArray<TUint32> connectionMethods; // IAPs
+ CleanupClosePushL(connectionMethods);
+ iCmManager.ConnectionMethodL(connectionMethods);
+ for(int i = 0; i < connectionMethods.Count(); i++) {
+ RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]);
+ CleanupClosePushL(connectionMethod);
+ TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
+ QString ident = QString::number(qHash(iapId));
+ if (accessPointConfigurations.contains(ident)) {
+ knownConfigs.removeOne(ident);
+ } else {
+ SymbianNetworkConfigurationPrivate* cpPriv = NULL;
+ TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod));
+ if (error == KErrNone) {
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ accessPointConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+ }
+ }
+ CleanupStack::PopAndDestroy(&connectionMethod);
+ }
+ CleanupStack::PopAndDestroy(&connectionMethods);
+
+ // Loop through all SNAPs
+ RArray<TUint32> destinations;
+ CleanupClosePushL(destinations);
+ iCmManager.AllDestinationsL(destinations);
+ for(int i = 0; i < destinations.Count(); i++) {
+ RCmDestination destination;
+ destination = iCmManager.DestinationL(destinations[i]);
+ CleanupClosePushL(destination);
+ QString ident = QString::number(qHash(destination.Id()+KValueThatWillBeAddedToSNAPId)); //TODO: Check if it's ok to add 1000 SNAP Id to prevent SNAP ids overlapping IAP ids
+ if (snapConfigurations.contains(ident)) {
+ knownSnapConfigs.removeOne(ident);
+ } else {
+ SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
+ CleanupStack::PushL(cpPriv);
+
+ HBufC *pName = destination.NameLC();
+ cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length());
+ CleanupStack::PopAndDestroy(pName);
+ pName = NULL;
+
+ cpPriv->isValid = true;
+ cpPriv->id = ident;
+ cpPriv->numericId = destination.Id();
+ cpPriv->connectionId = 0;
+ cpPriv->state = QNetworkConfiguration::Defined;
+ cpPriv->type = QNetworkConfiguration::ServiceNetwork;
+ cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
+ cpPriv->roamingSupported = false;
+
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ snapConfigurations.insert(ident, ptr);
+ emit configurationAdded(ptr);
+
+ CleanupStack::Pop(cpPriv);
+ }
+ QNetworkConfigurationPrivatePointer privSNAP = snapConfigurations.value(ident);
+
+ for (int j=0; j < destination.ConnectionMethodCount(); j++) {
+ RCmConnectionMethod connectionMethod = destination.ConnectionMethodL(j);
+ CleanupClosePushL(connectionMethod);
+
+ TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
+ QString iface = QString::number(qHash(iapId));
+ // Check that IAP can be found from accessPointConfigurations list
+ QNetworkConfigurationPrivatePointer priv = accessPointConfigurations.value(iface);
+ if (!priv) {
+ SymbianNetworkConfigurationPrivate *cpPriv = NULL;
+ TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod));
+ if (error == KErrNone) {
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ toSymbianConfig(ptr)->serviceNetworkPtr = privSNAP;
+ accessPointConfigurations.insert(ptr->id, ptr);
+ emit configurationAdded(ptr);
+ privSNAP->serviceNetworkMembers.append(ptr);
+ }
+ } else {
+ knownConfigs.removeOne(iface);
+ // Check that IAP can be found from related SNAP's configuration list
+ bool iapFound = false;
+ for (int i = 0; i < privSNAP->serviceNetworkMembers.count(); i++) {
+ if (toSymbianConfig(privSNAP->serviceNetworkMembers[i])->numericId == iapId) {
+ iapFound = true;
+ break;
+ }
+ }
+ if (!iapFound) {
+ toSymbianConfig(priv)->serviceNetworkPtr = privSNAP;
+ privSNAP->serviceNetworkMembers.append(priv);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&connectionMethod);
+ }
+
+ if (privSNAP->serviceNetworkMembers.count() > 1) {
+ // Roaming is supported only if SNAP contains more than one IAP
+ privSNAP->roamingSupported = true;
+ }
+
+ CleanupStack::PopAndDestroy(&destination);
+ }
+ CleanupStack::PopAndDestroy(&destinations);
+
+#else
+ // S60 version is < Series60 3rd Edition Feature Pack 2
+ CCommsDbTableView* pDbTView = ipCommsDB->OpenTableLC(TPtrC(IAP));
+
+ // Loop through all IAPs
+ TUint32 apId = 0;
+ TInt retVal = pDbTView->GotoFirstRecord();
+ while (retVal == KErrNone) {
+ pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId);
+ QString ident = QString::number(qHash(apId));
+ if (accessPointConfigurations.contains(ident)) {
+ knownConfigs.removeOne(ident);
+ } else {
+ SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
+ if (readNetworkConfigurationValuesFromCommsDb(apId, cpPriv)) {
+ QNetworkConfigurationPrivatePointer ptr(cpPriv);
+ accessPointConfigurations.insert(ident, ptr);
+
+ emit configurationAdded(ptr);
+ } else {
+ delete cpPriv;
+ }
+ }
+ retVal = pDbTView->GotoNextRecord();
+ }
+ CleanupStack::PopAndDestroy(pDbTView);
+#endif
+ updateActiveAccessPoints();
+
+ foreach (const QString &oldIface, knownConfigs) {
+ //remove non existing IAP
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface);
+ emit configurationRemoved(ptr);
+
+ // Remove non existing IAP from SNAPs
+ foreach (const QString &iface, snapConfigurations.keys()) {
+ QNetworkConfigurationPrivatePointer ptr2 = snapConfigurations.value(iface);
+ // => Check if one of the IAPs of the SNAP is active
+ for (int i = 0; i < ptr2->serviceNetworkMembers.count(); ++i) {
+ if (toSymbianConfig(ptr2->serviceNetworkMembers[i])->numericId ==
+ toSymbianConfig(ptr)->numericId) {
+ ptr2->serviceNetworkMembers.removeAt(i);
+ break;
+ }
+ }
+ }
+ }
+
+ foreach (const QString &oldIface, knownSnapConfigs) {
+ //remove non existing SNAPs
+ QNetworkConfigurationPrivatePointer ptr = snapConfigurations.take(oldIface);
+ emit configurationRemoved(ptr);
+ }
+}
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL(
+ RCmConnectionMethod& connectionMethod)
+{
+ QMutexLocker locker(&mutex);
+
+ SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
+ CleanupStack::PushL(cpPriv);
+
+ TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
+ QString ident = QString::number(qHash(iapId));
+
+ HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName);
+ CleanupStack::PushL(pName);
+ cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length());
+ CleanupStack::PopAndDestroy(pName);
+ pName = NULL;
+
+ TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType);
+ switch (bearerId) {
+ case KCommDbBearerCSD:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case KCommDbBearerWcdma:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA;
+ break;
+ case KCommDbBearerLAN:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet;
+ break;
+ case KCommDbBearerVirtual:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+ break;
+ case KCommDbBearerPAN:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+ break;
+ case KCommDbBearerWLAN:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerWLAN;
+ break;
+ default:
+ cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+ break;
+ }
+
+ TInt error = KErrNone;
+ TUint32 bearerType = connectionMethod.GetIntAttributeL(CMManager::ECmBearerType);
+ switch (bearerType) {
+ case KUidPacketDataBearerType:
+ // "Packet data" Bearer => Mapping is done using "Access point name"
+ TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EPacketDataAPName));
+ break;
+ case KUidWlanBearerType:
+ // "Wireless LAN" Bearer => Mapping is done using "WLAN network name" = SSID
+ TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EWlanSSID));
+ break;
+ }
+ if (!pName) {
+ // "Data call" Bearer or "High Speed (GSM)" Bearer => Mapping is done using "Dial-up number"
+ TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EDialDefaultTelNum));
+ }
+
+ if (error == KErrNone && pName) {
+ CleanupStack::PushL(pName);
+ cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length());
+ CleanupStack::PopAndDestroy(pName);
+ pName = NULL;
+ }
+
+ cpPriv->state = QNetworkConfiguration::Defined;
+ TBool isConnected = connectionMethod.GetBoolAttributeL(CMManager::ECmConnected);
+ if (isConnected) {
+ cpPriv->state = QNetworkConfiguration::Active;
+ }
+
+ cpPriv->isValid = true;
+ cpPriv->id = ident;
+ cpPriv->numericId = iapId;
+ cpPriv->connectionId = 0;
+ cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
+ cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
+ cpPriv->roamingSupported = false;
+
+ CleanupStack::Pop(cpPriv);
+ return cpPriv;
+}
+#else
+bool SymbianEngine::readNetworkConfigurationValuesFromCommsDb(
+ TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration)
+{
+ QMutexLocker locker(&mutex);
+
+ TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration));
+ if (error != KErrNone) {
+ return false;
+ }
+ return true;
+}
+
+void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL(
+ TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration)
+{
+ QMutexLocker locker(&mutex);
+
+ CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB);
+ CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC();
+ TBuf<KCommsDbSvrMaxColumnNameLength> name;
+
+ CApUtils* pApUtils = CApUtils::NewLC(*ipCommsDB);
+ TUint32 apId = pApUtils->WapIdFromIapIdL(aApId);
+
+ pDataHandler->AccessPointDataL(apId,*pAPItem);
+ pAPItem->ReadTextL(EApIapName, name);
+ if (name.Compare(_L("Easy WLAN")) == 0) {
+ // "Easy WLAN" won't be accepted to the Configurations list
+ User::Leave(KErrNotFound);
+ }
+
+ QString ident = QString::number(qHash(aApId));
+
+ apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length());
+ apNetworkConfiguration->isValid = true;
+ apNetworkConfiguration->id = ident;
+ apNetworkConfiguration->numericId = aApId;
+ apNetworkConfiguration->connectionId = 0;
+ apNetworkConfiguration->state = (QNetworkConfiguration::Defined);
+ apNetworkConfiguration->type = QNetworkConfiguration::InternetAccessPoint;
+ apNetworkConfiguration->purpose = QNetworkConfiguration::UnknownPurpose;
+ apNetworkConfiguration->roamingSupported = false;
+ switch (pAPItem->BearerTypeL()) {
+ case EApBearerTypeCSD:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case EApBearerTypeGPRS:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case EApBearerTypeHSCSD:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+ break;
+ case EApBearerTypeCDMA:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerCDMA2000;
+ break;
+ case EApBearerTypeWLAN:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerWLAN;
+ break;
+ case EApBearerTypeLAN:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet;
+ break;
+ case EApBearerTypeLANModem:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet;
+ break;
+ default:
+ apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+ break;
+ }
+
+ CleanupStack::PopAndDestroy(pApUtils);
+ CleanupStack::PopAndDestroy(pAPItem);
+ CleanupStack::PopAndDestroy(pDataHandler);
+}
+#endif
+
+QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfiguration()
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr;
+
+ if (iInitOk) {
+ stopCommsDatabaseNotifications();
+ TRAP_IGNORE(ptr = defaultConfigurationL());
+ startCommsDatabaseNotifications();
+ }
+
+ return ptr;
+}
+
+QStringList SymbianEngine::accessPointConfigurationIdentifiers()
+{
+ QMutexLocker locker(&mutex);
+
+ return accessPointConfigurations.keys();
+}
+
+QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL()
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfigurationPrivatePointer ptr;
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ // Check Default Connection (SNAP or IAP)
+ TCmDefConnValue defaultConnectionValue;
+ iCmManager.ReadDefConnL(defaultConnectionValue);
+ if (defaultConnectionValue.iType == ECmDefConnDestination) {
+ QString iface = QString::number(qHash(defaultConnectionValue.iId+KValueThatWillBeAddedToSNAPId));
+ ptr = snapConfigurations.value(iface);
+ } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) {
+ QString iface = QString::number(qHash(defaultConnectionValue.iId));
+ ptr = accessPointConfigurations.value(iface);
+ }
+#endif
+
+ if (!ptr->isValid) {
+ QString iface = QString::number(qHash(KUserChoiceIAPId));
+ ptr = userChoiceConfigurations.value(iface);
+ }
+
+ return ptr;
+}
+
+void SymbianEngine::updateActiveAccessPoints()
+{
+ QMutexLocker locker(&mutex);
+
+ bool online = false;
+ QList<QString> inactiveConfigs = accessPointConfigurations.keys();
+
+ TRequestStatus status;
+ TUint connectionCount;
+ iConnectionMonitor.GetConnectionCount(connectionCount, status);
+ User::WaitForRequest(status);
+
+ // Go through all connections and set state of related IAPs to Active
+ TUint connectionId;
+ TUint subConnectionCount;
+ TUint apId;
+ if (status.Int() == KErrNone) {
+ for (TUint i = 1; i <= connectionCount; i++) {
+ iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ online = true;
+ inactiveConfigs.removeOne(ident);
+
+ toSymbianConfig(ptr)->connectionId = connectionId;
+
+ // Configuration is Active
+ changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
+ }
+ }
+ }
+
+ // Make sure that state of rest of the IAPs won't be Active
+ foreach (const QString &iface, inactiveConfigs) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ if (ptr) {
+ // Configuration is either Defined or Discovered
+ changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered);
+ }
+ }
+
+ if (iOnline != online) {
+ iOnline = online;
+ emit this->onlineStateChanged(iOnline);
+ }
+}
+
+void SymbianEngine::updateAvailableAccessPoints()
+{
+ QMutexLocker locker(&mutex);
+
+ if (!ipAccessPointsAvailabilityScanner) {
+ ipAccessPointsAvailabilityScanner = new AccessPointsAvailabilityScanner(*this, iConnectionMonitor);
+ }
+ if (ipAccessPointsAvailabilityScanner) {
+ // Scanning may take a while because WLAN scanning will be done (if device supports WLAN).
+ ipAccessPointsAvailabilityScanner->StartScanning();
+ }
+}
+
+void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo)
+{
+ QMutexLocker locker(&mutex);
+
+ iUpdateGoingOn = false;
+ if (scanSuccessful) {
+ QList<QString> unavailableConfigs = accessPointConfigurations.keys();
+
+ // Set state of returned IAPs to Discovered
+ // if state is not already Active
+ for(TUint i=0; i<iapInfo.iCount; i++) {
+ QString ident = QString::number(qHash(iapInfo.iIap[i].iIapId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ unavailableConfigs.removeOne(ident);
+ if (ptr->state < QNetworkConfiguration::Active) {
+ // Configuration is either Discovered or Active
+ changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered);
+ }
+ }
+ }
+
+ // Make sure that state of rest of the IAPs won't be Discovered or Active
+ foreach (const QString &iface, unavailableConfigs) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ if (ptr) {
+ // Configuration is Defined
+ changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined);
+ }
+ }
+ }
+
+ updateStatesToSnaps();
+
+ startCommsDatabaseNotifications();
+
+ emit updateCompleted();
+}
+
+void SymbianEngine::updateStatesToSnaps()
+{
+ QMutexLocker locker(&mutex);
+
+ // Go through SNAPs and set correct state to SNAPs
+ QList<QString> snapConfigIdents = snapConfigurations.keys();
+ foreach (QString iface, snapConfigIdents) {
+ bool discovered = false;
+ bool active = false;
+ QNetworkConfigurationPrivatePointer ptr = snapConfigurations.value(iface);
+ // => Check if one of the IAPs of the SNAP is discovered or active
+ // => If one of IAPs is active, also SNAP is active
+ // => If one of IAPs is discovered but none of the IAPs is active, SNAP is discovered
+ for (int i=0; i<ptr->serviceNetworkMembers.count(); i++) {
+ if ((ptr->serviceNetworkMembers[i]->state & QNetworkConfiguration::Active)
+ == QNetworkConfiguration::Active) {
+ active = true;
+ break;
+ } else if ((ptr->serviceNetworkMembers[i]->state & QNetworkConfiguration::Discovered)
+ == QNetworkConfiguration::Discovered) {
+ discovered = true;
+ }
+ }
+ if (active) {
+ changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
+ } else if (discovered) {
+ changeConfigurationStateTo(ptr, QNetworkConfiguration::Discovered);
+ } else {
+ changeConfigurationStateTo(ptr, QNetworkConfiguration::Defined);
+ }
+ }
+}
+
+bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr,
+ QNetworkConfiguration::StateFlags newState)
+{
+ QMutexLocker locker(&mutex);
+
+ if (newState != ptr->state) {
+ ptr->state = newState;
+ emit configurationChanged(ptr);
+ return true;
+ }
+ return false;
+}
+
+/* changeConfigurationStateAtMinTo function does not overwrite possible better
+ * state (e.g. Discovered state does not overwrite Active state) but
+ * makes sure that state is at minimum given state.
+*/
+bool SymbianEngine::changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr,
+ QNetworkConfiguration::StateFlags newState)
+{
+ QMutexLocker locker(&mutex);
+
+ if ((newState | ptr->state) != ptr->state) {
+ ptr->state = (ptr->state | newState);
+ emit configurationChanged(ptr);
+ return true;
+ }
+ return false;
+}
+
+/* changeConfigurationStateAtMaxTo function overwrites possible better
+ * state (e.g. Discovered state overwrites Active state) and
+ * makes sure that state is at maximum given state (e.g. Discovered state
+ * does not overwrite Defined state).
+*/
+bool SymbianEngine::changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr,
+ QNetworkConfiguration::StateFlags newState)
+{
+ QMutexLocker locker(&mutex);
+
+ if ((newState & ptr->state) != ptr->state) {
+ ptr->state = (newState & ptr->state);
+ emit configurationChanged(ptr);
+ return true;
+ }
+ return false;
+}
+
+void SymbianEngine::startCommsDatabaseNotifications()
+{
+ QMutexLocker locker(&mutex);
+
+ if (!iWaitingCommsDatabaseNotifications) {
+ iWaitingCommsDatabaseNotifications = ETrue;
+ if (!IsActive()) {
+ SetActive();
+ // Start waiting for new notification
+ ipCommsDB->RequestNotification(iStatus);
+ }
+ }
+}
+
+void SymbianEngine::stopCommsDatabaseNotifications()
+{
+ QMutexLocker locker(&mutex);
+
+ if (iWaitingCommsDatabaseNotifications) {
+ iWaitingCommsDatabaseNotifications = EFalse;
+ if (!IsActive()) {
+ SetActive();
+ // Make sure that notifier recorded events will not be returned
+ // as soon as the client issues the next RequestNotification() request.
+ ipCommsDB->RequestNotification(iStatus);
+ ipCommsDB->CancelRequestNotification();
+ } else {
+ ipCommsDB->CancelRequestNotification();
+ }
+ }
+}
+
+void SymbianEngine::RunL()
+{
+ QMutexLocker locker(&mutex);
+
+ if (iStatus != KErrCancel) {
+ RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int());
+ switch (event) {
+ case RDbNotifier::EUnlock: /** All read locks have been removed. */
+ case RDbNotifier::ECommit: /** A transaction has been committed. */
+ case RDbNotifier::ERollback: /** A transaction has been rolled back */
+ case RDbNotifier::ERecover: /** The database has been recovered */
+ // Note that if further database events occur while a client is handling
+ // a request completion, the notifier records the most significant database
+ // event and this is signalled as soon as the client issues the next
+ // RequestNotification() request.
+ // => Stop recording notifications
+ stopCommsDatabaseNotifications();
+ TRAPD(error, updateConfigurationsL());
+ if (error == KErrNone) {
+ updateStatesToSnaps();
+ }
+ iWaitingCommsDatabaseNotifications = true;
+ break;
+ default:
+ // Do nothing
+ break;
+ }
+ }
+
+ if (iWaitingCommsDatabaseNotifications) {
+ if (!IsActive()) {
+ SetActive();
+ // Start waiting for new notification
+ ipCommsDB->RequestNotification(iStatus);
+ }
+ }
+}
+
+void SymbianEngine::DoCancel()
+{
+ QMutexLocker locker(&mutex);
+
+ ipCommsDB->CancelRequestNotification();
+}
+
+
+void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
+{
+ QMutexLocker locker(&mutex);
+
+ switch (aEvent.EventType()) {
+ case EConnMonCreateConnection:
+ {
+ CConnMonCreateConnection* realEvent;
+ realEvent = (CConnMonCreateConnection*) &aEvent;
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TUint connectionId = realEvent->ConnectionId();
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ // Configuration is Active
+ if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active))
+ updateStatesToSnaps();
+
+ if (!iOnline) {
+ iOnline = true;
+ emit this->onlineStateChanged(iOnline);
+ }
+ }
+ }
+ break;
+
+ case EConnMonDeleteConnection:
+ {
+ CConnMonDeleteConnection* realEvent;
+ realEvent = (CConnMonDeleteConnection*) &aEvent;
+ TUint connectionId = realEvent->ConnectionId();
+
+ QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
+ if (ptr) {
+ toSymbianConfig(ptr)->connectionId = 0;
+ // Configuration is either Defined or Discovered
+ if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered))
+ updateStatesToSnaps();
+ }
+
+ bool online = false;
+ foreach (const QString &iface, accessPointConfigurations.keys()) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ if (ptr->state == QNetworkConfiguration::Active) {
+ online = true;
+ break;
+ }
+ }
+ if (iOnline != online) {
+ iOnline = online;
+ emit this->onlineStateChanged(iOnline);
+ }
+ }
+ break;
+
+ case EConnMonIapAvailabilityChange:
+ {
+ CConnMonIapAvailabilityChange* realEvent;
+ realEvent = (CConnMonIapAvailabilityChange*) &aEvent;
+ TConnMonIapInfo iaps = realEvent->IapAvailability();
+ QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys();
+ for ( TUint i = 0; i < iaps.Count(); i++ ) {
+ QString ident = QString::number(qHash(iaps.iIap[i].iIapId));
+
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ // Configuration is either Discovered or Active
+ changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered);
+ unDiscoveredConfigs.removeOne(ident);
+ }
+ }
+ foreach (const QString &iface, unDiscoveredConfigs) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ if (ptr) {
+ // Configuration is Defined
+ changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined);
+ }
+ }
+ }
+ break;
+
+ default:
+ // For unrecognized events
+ break;
+ }
+}
+
+QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId)
+{
+ QMutexLocker locker(&mutex);
+
+ QNetworkConfiguration item;
+
+ QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i =
+ accessPointConfigurations.constBegin();
+ while (i != accessPointConfigurations.constEnd()) {
+ QNetworkConfigurationPrivatePointer ptr = i.value();
+ if (toSymbianConfig(ptr)->connectionId == aConnectionId)
+ return ptr;
+
+ ++i;
+ }
+
+ return QNetworkConfigurationPrivatePointer();
+}
+
+AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& owner,
+ RConnectionMonitor& connectionMonitor)
+ : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor)
+{
+ CActiveScheduler::Add(this);
+}
+
+AccessPointsAvailabilityScanner::~AccessPointsAvailabilityScanner()
+{
+ Cancel();
+}
+
+void AccessPointsAvailabilityScanner::DoCancel()
+{
+ iConnectionMonitor.CancelAsyncRequest(EConnMonGetPckgAttribute);
+}
+
+void AccessPointsAvailabilityScanner::StartScanning()
+{
+ iConnectionMonitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iIapBuf, iStatus);
+ if (!IsActive()) {
+ SetActive();
+ }
+}
+
+void AccessPointsAvailabilityScanner::RunL()
+{
+ if (iStatus.Int() != KErrNone) {
+ iIapBuf().iCount = 0;
+ iOwner.accessPointScanningReady(false,iIapBuf());
+ } else {
+ iOwner.accessPointScanningReady(true,iIapBuf());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h
new file mode 100644
index 0000000000..5448813fc8
--- /dev/null
+++ b/src/plugins/bearer/symbian/symbianengine.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** 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 SYMBIANENGINE_H
+#define SYMBIANENGINE_H
+
+#include <QtCore/qstringlist.h>
+#include <QtNetwork/private/qbearerengine_p.h>
+#include <QtNetwork/qnetworkconfigmanager.h>
+
+#include <QHash>
+#include <rconnmon.h>
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ #include <cmmanager.h>
+#endif
+
+class CCommsDatabase;
+
+QT_BEGIN_NAMESPACE
+class QTimer;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkSessionPrivate;
+class AccessPointsAvailabilityScanner;
+
+class SymbianNetworkConfigurationPrivate : public QNetworkConfigurationPrivate
+{
+public:
+ enum Bearer {
+ BearerEthernet,
+ BearerWLAN,
+ Bearer2G,
+ BearerCDMA2000,
+ BearerWCDMA,
+ BearerHSPA,
+ BearerBluetooth,
+ BearerWiMAX,
+ BearerUnknown = -1
+ };
+
+ SymbianNetworkConfigurationPrivate();
+ ~SymbianNetworkConfigurationPrivate();
+
+ QString bearerName() const;
+
+ Bearer bearer;
+
+ TUint32 numericId;
+ TUint connectionId;
+
+ QNetworkConfigurationPrivatePointer serviceNetworkPtr;
+
+ QString mappingName;
+};
+
+inline SymbianNetworkConfigurationPrivate *toSymbianConfig(QNetworkConfigurationPrivatePointer ptr)
+{
+ return static_cast<SymbianNetworkConfigurationPrivate *>(ptr.data());
+}
+
+class SymbianEngine : public QBearerEngine, public CActive,
+ public MConnectionMonitorObserver
+{
+ Q_OBJECT
+
+public:
+ SymbianEngine(QObject *parent = 0);
+ virtual ~SymbianEngine();
+
+ bool hasIdentifier(const QString &id);
+
+ void requestUpdate();
+
+ QNetworkConfigurationManager::Capabilities capabilities() const;
+
+ QNetworkSessionPrivate *createSessionBackend();
+
+ QNetworkConfigurationPrivatePointer defaultConfiguration();
+
+ QStringList accessPointConfigurationIdentifiers();
+
+Q_SIGNALS:
+ void onlineStateChanged(bool isOnline);
+
+public Q_SLOTS:
+ void updateConfigurations();
+
+private:
+ void updateStatesToSnaps();
+ bool changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr,
+ QNetworkConfiguration::StateFlags newState);
+ bool changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr,
+ QNetworkConfiguration::StateFlags newState);
+ bool changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr,
+ QNetworkConfiguration::StateFlags newState);
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ SymbianNetworkConfigurationPrivate *configFromConnectionMethodL(RCmConnectionMethod& connectionMethod);
+#else
+ bool readNetworkConfigurationValuesFromCommsDb(
+ TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration);
+ void readNetworkConfigurationValuesFromCommsDbL(
+ TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration);
+#endif
+
+ void updateConfigurationsL();
+ void updateActiveAccessPoints();
+ void updateAvailableAccessPoints();
+ void accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo);
+ void startCommsDatabaseNotifications();
+ void stopCommsDatabaseNotifications();
+
+ QNetworkConfigurationPrivatePointer defaultConfigurationL();
+ TBool GetS60PlatformVersion(TUint& aMajor, TUint& aMinor) const;
+ void startMonitoringIAPData(TUint32 aIapId);
+ QNetworkConfigurationPrivatePointer dataByConnectionId(TUint aConnectionId);
+
+protected: // From CActive
+ void RunL();
+ void DoCancel();
+
+private: // MConnectionMonitorObserver
+ void EventL(const CConnMonEventBase& aEvent);
+
+private: // Data
+ CCommsDatabase* ipCommsDB;
+ RConnectionMonitor iConnectionMonitor;
+
+ TBool iWaitingCommsDatabaseNotifications;
+ TBool iOnline;
+ TBool iInitOk;
+ TBool iUpdateGoingOn;
+
+
+ AccessPointsAvailabilityScanner* ipAccessPointsAvailabilityScanner;
+
+ friend class QNetworkSessionPrivate;
+ friend class AccessPointsAvailabilityScanner;
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ RCmManager iCmManager;
+#endif
+};
+
+class AccessPointsAvailabilityScanner : public CActive
+{
+public:
+ AccessPointsAvailabilityScanner(SymbianEngine& owner,
+ RConnectionMonitor& connectionMonitor);
+ ~AccessPointsAvailabilityScanner();
+
+ void StartScanning();
+
+protected: // From CActive
+ void RunL();
+ void DoCancel();
+
+private: // Data
+ SymbianEngine& iOwner;
+ RConnectionMonitor& iConnectionMonitor;
+ TConnMonIapInfoBuf iIapBuf;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index dc2266b9a3..73686bc623 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
-SUBDIRS *= accessible imageformats sqldrivers iconengines script
+SUBDIRS *= accessible imageformats sqldrivers iconengines script bearer
unix:!symbian {
contains(QT_CONFIG,iconv)|contains(QT_CONFIG,gnu-libiconv):SUBDIRS *= codecs
} else {
diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro
index 1f3b4a6737..5d5bee9ab0 100644
--- a/src/s60installs/s60installs.pro
+++ b/src/s60installs/s60installs.pro
@@ -88,7 +88,16 @@ symbian: {
qtbackup.sources = backup_registration.xml
qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,)
- DEPLOYMENT += qtresources qtlibraries qtbackup imageformats_plugins codecs_plugins graphicssystems_plugins
+ bearer_plugins.path = c:$$QT_PLUGINS_BASE_DIR/bearer
+ bearer_plugins.sources += qsymbianbearer.dll
+
+ DEPLOYMENT += qtresources \
+ qtlibraries \
+ qtbackup \
+ imageformats_plugins \
+ codecs_plugins \
+ graphicssystems_plugins \
+ bearer_plugins
contains(QT_CONFIG, svg): {
qtlibraries.sources += QtSvg.dll
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 791d23cba5..5fd2dcaa82 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -456,7 +456,10 @@ SUBDIRS += \
qmargins \
qnetworkaddressentry \
qnetworkcachemetadata \
+ qnetworkconfigmanager \
+ qnetworkconfiguration \
qnetworkdiskcache \
+ qnetworksession \
qobjectperformance \
qpainterpathstroker \
qplugin \
diff --git a/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp b/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp
index 183f7e4675..bb978d129c 100644
--- a/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp
+++ b/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp
@@ -60,7 +60,7 @@
#define TRY_WAIT(expr) \
do { \
- for (int ii = 0; ii < 6; ++ii) { \
+ for (int ii = 0; ii < 60; ++ii) { \
if ((expr)) break; \
QTest::qWait(50); \
} \
diff --git a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp
index 503b05eaed..a25dcd209e 100644
--- a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp
+++ b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp
@@ -59,7 +59,7 @@
#define TRY_WAIT(expr) \
do { \
- for (int ii = 0; ii < 6; ++ii) { \
+ for (int ii = 0; ii < 60; ++ii) { \
if ((expr)) break; \
QTest::qWait(50); \
} \
diff --git a/tests/auto/qbearertestcommon.h b/tests/auto/qbearertestcommon.h
new file mode 100644
index 0000000000..0bfe622041
--- /dev/null
+++ b/tests/auto/qbearertestcommon.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 QBEARERTESTCOMMON_H
+#define QBEARERTESTCOMMON_H
+
+// Will try to wait for the condition while allowing event processing
+#define QTRY_VERIFY(__expr) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 90000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QVERIFY(__expr); \
+ } while(0)
+
+// Will try to wait for the condition while allowing event processing
+#define QTRY_COMPARE(__expr, __expected) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 90000; \
+ if ((__expr) != (__expected)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QCOMPARE(__expr, __expected); \
+ } while(0)
+
+#endif
+
diff --git a/tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro b/tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro
new file mode 100644
index 0000000000..30eb5f05cf
--- /dev/null
+++ b/tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro
@@ -0,0 +1,15 @@
+load(qttest_p4)
+SOURCES += tst_qnetworkconfigmanager.cpp
+HEADERS += ../qbearertestcommon.h
+
+QT = core network
+
+symbian {
+ TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData
+}
+
+maemo6 {
+ CONFIG += link_pkgconfig
+
+ PKGCONFIG += conninet
+}
diff --git a/tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp b/tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp
new file mode 100644
index 0000000000..305233094f
--- /dev/null
+++ b/tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp
@@ -0,0 +1,335 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QtTest/QtTest>
+#include "../qbearertestcommon.h"
+#include "qnetworkconfiguration.h"
+#include "qnetworkconfigmanager.h"
+
+#ifdef Q_WS_MAEMO_6
+#include <stdio.h>
+#include <iapconf.h>
+#endif
+
+QT_USE_NAMESPACE
+class tst_QNetworkConfigurationManager : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void allConfigurations();
+ void defaultConfiguration();
+ void configurationFromIdentifier();
+
+private:
+#ifdef Q_WS_MAEMO_6
+ Maemo::IAPConf *iapconf;
+ Maemo::IAPConf *iapconf2;
+ Maemo::IAPConf *gprsiap;
+#define MAX_IAPS 50
+ Maemo::IAPConf *iaps[MAX_IAPS];
+ QProcess *icd_stub;
+#endif
+};
+
+void tst_QNetworkConfigurationManager::initTestCase()
+{
+#ifdef Q_WS_MAEMO_6
+ iapconf = new Maemo::IAPConf("007");
+ iapconf->setValue("ipv4_type", "AUTO");
+ iapconf->setValue("wlan_wepkey1", "connt");
+ iapconf->setValue("wlan_wepdefkey", 1);
+ iapconf->setValue("wlan_ssid", QByteArray("JamesBond"));
+ iapconf->setValue("name", "James Bond");
+ iapconf->setValue("type", "WLAN_INFRA");
+
+ gprsiap = new Maemo::IAPConf("This-is-GPRS-IAP");
+ gprsiap->setValue("ask_password", false);
+ gprsiap->setValue("gprs_accesspointname", "internet");
+ gprsiap->setValue("gprs_password", "");
+ gprsiap->setValue("gprs_username", "");
+ gprsiap->setValue("ipv4_autodns", true);
+ gprsiap->setValue("ipv4_type", "AUTO");
+ gprsiap->setValue("sim_imsi", "244070123456789");
+ gprsiap->setValue("name", "MI6");
+ gprsiap->setValue("type", "GPRS");
+
+ iapconf2 = new Maemo::IAPConf("osso.net");
+ iapconf2->setValue("ipv4_type", "AUTO");
+ iapconf2->setValue("wlan_wepkey1", "osso.net");
+ iapconf2->setValue("wlan_wepdefkey", 1);
+ iapconf2->setValue("wlan_ssid", QByteArray("osso.net"));
+ iapconf2->setValue("name", "osso.net");
+ iapconf2->setValue("type", "WLAN_INFRA");
+ iapconf2->setValue("wlan_security", "WEP");
+
+ /* Create large number of IAPs in the gconf and see what happens */
+ fflush(stdout);
+ printf("Creating %d IAPS: ", MAX_IAPS);
+ for (int i=0; i<MAX_IAPS; i++) {
+ QString num = QString().sprintf("%d", i);
+ QString iap = "iap-" + num;
+ iaps[i] = new Maemo::IAPConf(iap);
+ iaps[i]->setValue("name", QString("test-iap-")+num);
+ iaps[i]->setValue("type", "WLAN_INFRA");
+ iaps[i]->setValue("wlan_ssid", QString(QString("test-ssid-")+num).toAscii());
+ iaps[i]->setValue("wlan_security", "WPA_PSK");
+ iaps[i]->setValue("EAP_wpa_preshared_passphrase", QString("test-passphrase-")+num);
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+ fflush(stdout);
+
+ icd_stub = new QProcess(this);
+ icd_stub->start("/usr/bin/icd2_stub.py");
+ QTest::qWait(1000);
+
+ // Add a known network to scan list that icd2 stub returns
+ QProcess dbus_send;
+ // 007 network
+ dbus_send.start("dbus-send --type=method_call --system "
+ "--dest=com.nokia.icd2 /com/nokia/icd2 "
+ "com.nokia.icd2.testing.add_available_network "
+ "string:'' uint32:0 string:'' "
+ "string:WLAN_INFRA uint32:5000011 array:byte:48,48,55");
+ dbus_send.waitForFinished();
+
+ // osso.net network
+ dbus_send.start("dbus-send --type=method_call --system "
+ "--dest=com.nokia.icd2 /com/nokia/icd2 "
+ "com.nokia.icd2.testing.add_available_network "
+ "string:'' uint32:0 string:'' "
+ "string:WLAN_INFRA uint32:83886097 array:byte:111,115,115,111,46,110,101,116");
+ dbus_send.waitForFinished();
+#endif
+}
+
+
+void tst_QNetworkConfigurationManager::cleanupTestCase()
+{
+#ifdef Q_WS_MAEMO_6
+ iapconf->clear();
+ delete iapconf;
+ iapconf2->clear();
+ delete iapconf2;
+ gprsiap->clear();
+ delete gprsiap;
+
+ printf("Deleting %d IAPS : ", MAX_IAPS);
+ for (int i=0; i<MAX_IAPS; i++) {
+ iaps[i]->clear();
+ delete iaps[i];
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+ qDebug() << "Deleted" << MAX_IAPS << "IAPs";
+
+ icd_stub->terminate();
+ icd_stub->waitForFinished();
+#endif
+}
+
+void tst_QNetworkConfigurationManager::init()
+{
+}
+
+void tst_QNetworkConfigurationManager::cleanup()
+{
+}
+
+void printConfigurationDetails(const QNetworkConfiguration& p)
+{
+ qDebug() << p.name() <<": isvalid->" <<p.isValid() << " type->"<< p.type() <<
+ " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() <<
+ " purpose->" << p.purpose() << " state->" << p.state();
+}
+
+void tst_QNetworkConfigurationManager::allConfigurations()
+{
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations();
+
+ foreach(QNetworkConfiguration c, preScanConfigs)
+ {
+ QVERIFY2(c.type()!=QNetworkConfiguration::UserChoice, "allConfiguration must not return UserChoice configs");
+ }
+
+ QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
+ manager.updateConfigurations(); //initiate scans
+ QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
+
+ QList<QNetworkConfiguration> configs = manager.allConfigurations();
+
+ int all = configs.count();
+ qDebug() << "All configurations:" << all;
+ QVERIFY(all);
+ foreach(QNetworkConfiguration p, configs) {
+ QVERIFY(p.isValid());
+ printConfigurationDetails(p);
+ QVERIFY(p.type() != QNetworkConfiguration::Invalid);
+ QVERIFY(p.type() != QNetworkConfiguration::UserChoice);
+ }
+
+ configs = manager.allConfigurations(QNetworkConfiguration::Undefined);
+ int undefined = configs.count();
+ QVERIFY(undefined <= all);
+ qDebug() << "Undefined configurations:" << undefined;
+ foreach( const QNetworkConfiguration p, configs) {
+ printConfigurationDetails(p);
+ QVERIFY(p.state() & QNetworkConfiguration::Undefined);
+ QVERIFY(!(p.state() & QNetworkConfiguration::Defined));
+ }
+
+ //get defined configs only (same as all)
+ configs = manager.allConfigurations(QNetworkConfiguration::Defined);
+ int defined = configs.count();
+ qDebug() << "Defined configurations:" << defined;
+ QVERIFY(defined <= all);
+ foreach( const QNetworkConfiguration p, configs) {
+ printConfigurationDetails(p);
+ QVERIFY(p.state() & QNetworkConfiguration::Defined);
+ QVERIFY(!(p.state() & QNetworkConfiguration::Undefined));
+ }
+
+ //get discovered configurations only
+ configs = manager.allConfigurations(QNetworkConfiguration::Discovered);
+ int discovered = configs.count();
+ //QVERIFY(discovered);
+ qDebug() << "Discovered configurations:" << discovered;
+ foreach(const QNetworkConfiguration p, configs) {
+ printConfigurationDetails(p);
+ QVERIFY(p.isValid());
+ QVERIFY(!(p.state() & QNetworkConfiguration::Undefined));
+ QVERIFY(p.state() & QNetworkConfiguration::Defined);
+ QVERIFY(p.state() & QNetworkConfiguration::Discovered);
+ }
+
+ //getactive configurations only
+ configs = manager.allConfigurations(QNetworkConfiguration::Active);
+ int active = configs.count();
+ if (active)
+ QVERIFY(manager.isOnline());
+ else
+ QVERIFY(!manager.isOnline());
+
+ //QVERIFY(active);
+ qDebug() << "Active configurations:" << active;
+ foreach(const QNetworkConfiguration p, configs) {
+ printConfigurationDetails(p);
+ QVERIFY(p.isValid());
+ QVERIFY(!(p.state() & QNetworkConfiguration::Undefined));
+ QVERIFY(p.state() & QNetworkConfiguration::Active);
+ QVERIFY(p.state() & QNetworkConfiguration::Discovered);
+ QVERIFY(p.state() & QNetworkConfiguration::Defined);
+ }
+
+ QVERIFY(all >= discovered);
+ QVERIFY(discovered >= active);
+}
+
+
+void tst_QNetworkConfigurationManager::defaultConfiguration()
+{
+ QNetworkConfigurationManager manager;
+ QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
+ manager.updateConfigurations(); //initiate scans
+ QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
+
+ QList<QNetworkConfiguration> configs = manager.allConfigurations();
+ QNetworkConfiguration defaultConfig = manager.defaultConfiguration();
+
+ bool confirm = configs.contains(defaultConfig);
+ bool isUserChoice = (defaultConfig.type() == QNetworkConfiguration::UserChoice);
+
+ //user choice config is not part of allConfigurations()
+ QVERIFY(isUserChoice != confirm);
+ if (!isUserChoice) {
+ QVERIFY(confirm || !defaultConfig.isValid());
+ QVERIFY(!(confirm && !defaultConfig.isValid()));
+ } else {
+ QVERIFY(defaultConfig.isValid());
+ QCOMPARE(defaultConfig.name(), QString("UserChoice"));
+ QCOMPARE(defaultConfig.children().count(), 0);
+ QVERIFY(!defaultConfig.isRoamingAvailable());
+ QCOMPARE(defaultConfig.state(), QNetworkConfiguration::Discovered);
+ QNetworkConfiguration copy = manager.configurationFromIdentifier(defaultConfig.identifier());
+ QVERIFY(copy == defaultConfig);
+ }
+}
+
+void tst_QNetworkConfigurationManager::configurationFromIdentifier()
+{
+ QNetworkConfigurationManager manager;
+ QSet<QString> allIdentifier;
+
+ //force an update to get maximum number of configs
+ QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
+ manager.updateConfigurations(); //initiate scans
+ QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
+
+ QList<QNetworkConfiguration> configs = manager.allConfigurations();
+
+ foreach(QNetworkConfiguration c, configs) {
+ QVERIFY(!allIdentifier.contains(c.identifier()));
+ allIdentifier.insert(c.identifier());
+
+ QNetworkConfiguration direct = manager.configurationFromIdentifier(c.identifier());
+ QVERIFY(direct.isValid());
+ QVERIFY(direct == c);
+ }
+
+ //assume that there is no item with identifier 'FooBar'
+ QVERIFY(!allIdentifier.contains("FooBar"));
+ QNetworkConfiguration invalid = manager.configurationFromIdentifier("FooBar");
+ QVERIFY(!invalid.isValid());
+}
+
+
+QTEST_MAIN(tst_QNetworkConfigurationManager)
+#include "tst_qnetworkconfigmanager.moc"
diff --git a/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro b/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro
new file mode 100644
index 0000000000..df2d2d926e
--- /dev/null
+++ b/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro
@@ -0,0 +1,15 @@
+load(qttest_p4)
+SOURCES += tst_qnetworkconfiguration.cpp
+HEADERS += ../qbearertestcommon.h
+
+QT = core network
+
+symbian {
+ TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData
+}
+
+maemo6 {
+ CONFIG += link_pkgconfig
+
+ PKGCONFIG += conninet
+}
diff --git a/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp
new file mode 100644
index 0000000000..70f44478ea
--- /dev/null
+++ b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp
@@ -0,0 +1,303 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QtTest/QtTest>
+#include "../qbearertestcommon.h"
+#include "qnetworkconfiguration.h"
+#include "qnetworkconfigmanager.h"
+
+#ifdef Q_WS_MAEMO_6
+#include <stdio.h>
+#include <iapconf.h>
+#endif
+
+QT_USE_NAMESPACE
+class tst_QNetworkConfiguration : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void invalidPoint();
+ void comparison();
+ void children();
+ void isRoamingAvailable();
+
+private:
+#ifdef Q_WS_MAEMO_6
+ Maemo::IAPConf *iapconf;
+ Maemo::IAPConf *iapconf2;
+ Maemo::IAPConf *gprsiap;
+#define MAX_IAPS 50
+ Maemo::IAPConf *iaps[MAX_IAPS];
+ QProcess *icd_stub;
+#endif
+};
+
+void tst_QNetworkConfiguration::initTestCase()
+{
+#ifdef Q_WS_MAEMO_6
+ iapconf = new Maemo::IAPConf("007");
+ iapconf->setValue("ipv4_type", "AUTO");
+ iapconf->setValue("wlan_wepkey1", "connt");
+ iapconf->setValue("wlan_wepdefkey", 1);
+ iapconf->setValue("wlan_ssid", QByteArray("JamesBond"));
+ iapconf->setValue("name", "James Bond");
+ iapconf->setValue("type", "WLAN_INFRA");
+
+ iapconf2 = new Maemo::IAPConf("osso.net");
+ iapconf2->setValue("ipv4_type", "AUTO");
+ iapconf2->setValue("wlan_wepkey1", "osso.net");
+ iapconf2->setValue("wlan_wepdefkey", 1);
+ iapconf2->setValue("wlan_ssid", QByteArray("osso.net"));
+ iapconf2->setValue("name", "osso.net");
+ iapconf2->setValue("type", "WLAN_INFRA");
+ iapconf2->setValue("wlan_security", "WEP");
+
+ gprsiap = new Maemo::IAPConf("This-is-GPRS-IAP");
+ gprsiap->setValue("ask_password", false);
+ gprsiap->setValue("gprs_accesspointname", "internet");
+ gprsiap->setValue("gprs_password", "");
+ gprsiap->setValue("gprs_username", "");
+ gprsiap->setValue("ipv4_autodns", true);
+ gprsiap->setValue("ipv4_type", "AUTO");
+ gprsiap->setValue("sim_imsi", "244070123456789");
+ gprsiap->setValue("name", "MI6");
+ gprsiap->setValue("type", "GPRS");
+
+ /* Create large number of IAPs in the gconf and see what happens */
+ fflush(stdout);
+ printf("Creating %d IAPS: ", MAX_IAPS);
+ for (int i=0; i<MAX_IAPS; i++) {
+ QString num = QString().sprintf("%d", i);
+ QString iap = "iap-" + num;
+ iaps[i] = new Maemo::IAPConf(iap);
+ iaps[i]->setValue("name", QString("test-iap-")+num);
+ iaps[i]->setValue("type", "WLAN_INFRA");
+ iaps[i]->setValue("wlan_ssid", QString(QString("test-ssid-")+num).toAscii());
+ iaps[i]->setValue("wlan_security", "WPA_PSK");
+ iaps[i]->setValue("EAP_wpa_preshared_passphrase", QString("test-passphrase-")+num);
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+ fflush(stdout);
+
+ icd_stub = new QProcess(this);
+ icd_stub->start("/usr/bin/icd2_stub.py");
+ QTest::qWait(1000);
+
+ // Add a known network to scan list that icd2 stub returns
+ QProcess dbus_send;
+ // 007 network
+ dbus_send.start("dbus-send --type=method_call --system "
+ "--dest=com.nokia.icd2 /com/nokia/icd2 "
+ "com.nokia.icd2.testing.add_available_network "
+ "string:'' uint32:0 string:'' "
+ "string:WLAN_INFRA uint32:5000011 array:byte:48,48,55");
+ dbus_send.waitForFinished();
+
+ // osso.net network
+ dbus_send.start("dbus-send --type=method_call --system "
+ "--dest=com.nokia.icd2 /com/nokia/icd2 "
+ "com.nokia.icd2.testing.add_available_network "
+ "string:'' uint32:0 string:'' "
+ "string:WLAN_INFRA uint32:83886097 array:byte:111,115,115,111,46,110,101,116");
+ dbus_send.waitForFinished();
+#endif
+}
+
+void tst_QNetworkConfiguration::cleanupTestCase()
+{
+#ifdef Q_WS_MAEMO_6
+ iapconf->clear();
+ delete iapconf;
+ iapconf2->clear();
+ delete iapconf2;
+ gprsiap->clear();
+ delete gprsiap;
+
+ printf("Deleting %d IAPS : ", MAX_IAPS);
+ for (int i=0; i<MAX_IAPS; i++) {
+ iaps[i]->clear();
+ delete iaps[i];
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+ qDebug() << "Deleted" << MAX_IAPS << "IAPs";
+
+ // Terminate icd2 stub
+ icd_stub->terminate();
+ icd_stub->waitForFinished();
+#endif
+}
+
+void tst_QNetworkConfiguration::invalidPoint()
+{
+ QNetworkConfiguration pt;
+
+ QVERIFY(pt.name().isEmpty());
+ QVERIFY(!pt.isValid());
+ QVERIFY(pt.type() == QNetworkConfiguration::Invalid);
+ QVERIFY(!(pt.state() & QNetworkConfiguration::Defined));
+ QVERIFY(!(pt.state() & QNetworkConfiguration::Discovered));
+ QVERIFY(!(pt.state() & QNetworkConfiguration::Active));
+ QVERIFY(!pt.isRoamingAvailable());
+
+ QNetworkConfiguration pt2(pt);
+ QVERIFY(pt2.name().isEmpty());
+ QVERIFY(!pt2.isValid());
+ QVERIFY(pt2.type() == QNetworkConfiguration::Invalid);
+ QVERIFY(!(pt2.state() & QNetworkConfiguration::Defined));
+ QVERIFY(!(pt2.state() & QNetworkConfiguration::Discovered));
+ QVERIFY(!(pt2.state() & QNetworkConfiguration::Active));
+ QVERIFY(!pt2.isRoamingAvailable());
+
+}
+
+void tst_QNetworkConfiguration::comparison()
+{
+ //test copy constructor and assignment operator
+ //compare invalid connection points
+ QNetworkConfiguration pt1;
+ QVERIFY(!pt1.isValid());
+ QVERIFY(pt1.type() == QNetworkConfiguration::Invalid);
+
+ QNetworkConfiguration pt2(pt1);
+ QVERIFY(pt1==pt2);
+ QVERIFY(!(pt1!=pt2));
+ QVERIFY(pt1.name() == pt2.name());
+ QVERIFY(pt1.isValid() == pt2.isValid());
+ QVERIFY(pt1.type() == pt2.type());
+ QVERIFY(pt1.state() == pt2.state());
+ QVERIFY(pt1.purpose() == pt2.purpose());
+
+
+ QNetworkConfiguration pt3;
+ pt3 = pt1;
+ QVERIFY(pt1==pt3);
+ QVERIFY(!(pt1!=pt3));
+ QVERIFY(pt1.name() == pt3.name());
+ QVERIFY(pt1.isValid() == pt3.isValid());
+ QVERIFY(pt1.type() == pt3.type());
+ QVERIFY(pt1.state() == pt3.state());
+ QVERIFY(pt1.purpose() == pt3.purpose());
+
+ //test case must run on machine that has valid connection points
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations();
+
+ QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
+ manager.updateConfigurations(); //initiate scans
+ QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
+
+ QList<QNetworkConfiguration> configs = manager.allConfigurations(QNetworkConfiguration::Discovered);
+ QVERIFY(configs.count());
+ QNetworkConfiguration defaultConfig = manager.defaultConfiguration();
+ QVERIFY(defaultConfig.isValid());
+ QVERIFY(defaultConfig.type() != QNetworkConfiguration::Invalid);
+ QVERIFY(!defaultConfig.name().isEmpty());
+
+ pt3 = defaultConfig;
+ QVERIFY(defaultConfig==pt3);
+ QVERIFY(!(defaultConfig!=pt3));
+ QVERIFY(defaultConfig.name() == pt3.name());
+ QVERIFY(defaultConfig.isValid() == pt3.isValid());
+ QVERIFY(defaultConfig.type() == pt3.type());
+ QVERIFY(defaultConfig.state() == pt3.state());
+ QVERIFY(defaultConfig.purpose() == pt3.purpose());
+}
+
+void tst_QNetworkConfiguration::children()
+{
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> configs = manager.allConfigurations();
+
+ foreach(QNetworkConfiguration c, configs)
+ {
+ if ( c.type() == QNetworkConfiguration::ServiceNetwork ) {
+ qDebug() << "found service network" << c.name() << c.children().count();
+ QVERIFY(c.isValid());
+ QList<QNetworkConfiguration> members = c.children();
+ foreach(QNetworkConfiguration child, members) {
+ QVERIFY(child.isValid());
+ QVERIFY(configs.contains(child));
+ qDebug() << "\t" << child.name();
+ }
+ }
+ }
+}
+
+void tst_QNetworkConfiguration::isRoamingAvailable()
+{
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> configs = manager.allConfigurations();
+
+ //force update to get maximum list
+ QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
+ manager.updateConfigurations(); //initiate scans
+ QTRY_VERIFY(spy.count() == 1); //wait for scan to complete
+
+ foreach(QNetworkConfiguration c, configs)
+ {
+ QVERIFY(QNetworkConfiguration::UserChoice != c.type());
+ QVERIFY(QNetworkConfiguration::Invalid != c.type());
+ if ( c.type() == QNetworkConfiguration::ServiceNetwork ) {
+ //cannot test flag as some SNAPs may not support roaming anyway
+ //QVERIFY(c.roamingavailable())
+ if ( c.children().count() <= 1 )
+ QVERIFY(!c.isRoamingAvailable());
+ foreach(QNetworkConfiguration child, c.children()) {
+ QVERIFY(QNetworkConfiguration::InternetAccessPoint == child.type());
+ QCOMPARE(child.children().count(), 0);
+ }
+ } else {
+ QVERIFY(!c.isRoamingAvailable());
+ }
+ }
+}
+
+QTEST_MAIN(tst_QNetworkConfiguration)
+#include "tst_qnetworkconfiguration.moc"
diff --git a/tests/auto/qnetworksession/lackey/lackey.pro b/tests/auto/qnetworksession/lackey/lackey.pro
new file mode 100644
index 0000000000..5db6743c65
--- /dev/null
+++ b/tests/auto/qnetworksession/lackey/lackey.pro
@@ -0,0 +1,15 @@
+SOURCES += main.cpp
+TARGET = lackey
+
+QT = core network
+
+DESTDIR = ./
+
+win32:CONFIG += console
+mac:CONFIG -= app_bundle
+
+symbian {
+ # Needed for interprocess communication and opening QNetworkSession
+ TARGET.CAPABILITY = NetworkControl NetworkServices
+}
+
diff --git a/tests/auto/qnetworksession/lackey/main.cpp b/tests/auto/qnetworksession/lackey/main.cpp
new file mode 100644
index 0000000000..41e935aec3
--- /dev/null
+++ b/tests/auto/qnetworksession/lackey/main.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** 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 test suite 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 <QCoreApplication>
+#include <QStringList>
+#include <QLocalSocket>
+#include <qnetworkconfigmanager.h>
+#include <qnetworkconfiguration.h>
+#include <qnetworksession.h>
+
+#include <QDebug>
+
+QT_USE_NAMESPACE
+
+
+#define NO_DISCOVERED_CONFIGURATIONS_ERROR 1
+#define SESSION_OPEN_ERROR 2
+
+
+int main(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+
+ // Cannot read/write to processes on WinCE or Symbian.
+ // Easiest alternative is to use sockets for IPC.
+
+ QLocalSocket oopSocket;
+
+ oopSocket.connectToServer("tst_qnetworksession");
+ oopSocket.waitForConnected(-1);
+
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> discovered =
+#if defined (Q_OS_SYMBIAN)
+ // On Symbian, on the first query (before updateConfigurations() call
+ // the discovered-states are not correct, so defined-state will do.
+ manager.allConfigurations(QNetworkConfiguration::Defined);
+#else
+ manager.allConfigurations(QNetworkConfiguration::Discovered);
+#endif
+ if (discovered.isEmpty()) {
+ return NO_DISCOVERED_CONFIGURATIONS_ERROR;
+ }
+
+ qDebug() << "Lackey started";
+
+ QNetworkSession *session = 0;
+ do {
+ if (session) {
+ delete session;
+ session = 0;
+ }
+
+ qDebug() << "Discovered configurations:" << discovered.count();
+
+ if (discovered.isEmpty()) {
+ qDebug() << "No more discovered configurations";
+ break;
+ }
+
+ qDebug() << "Taking first configuration";
+
+ QNetworkConfiguration config = discovered.takeFirst();
+
+ if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ qDebug() << config.name() << "is active, therefore skipping it (looking for configs in 'discovered' state).";
+ continue;
+ }
+
+ qDebug() << "Creating session for" << config.name() << config.identifier();
+
+ session = new QNetworkSession(config);
+
+ QString output = QString("Starting session for %1\n").arg(config.identifier());
+ oopSocket.write(output.toAscii());
+ oopSocket.waitForBytesWritten();
+ session->open();
+ session->waitForOpened();
+ } while (!(session && session->isOpen()));
+
+ qDebug() << "lackey: loop done";
+
+ if (!session) {
+ qDebug() << "Could not start session";
+
+ oopSocket.disconnectFromServer();
+ oopSocket.waitForDisconnected(-1);
+
+ return SESSION_OPEN_ERROR;
+ }
+
+ QString output = QString("Started session for %1\n").arg(session->configuration().identifier());
+ oopSocket.write(output.toAscii());
+ oopSocket.waitForBytesWritten();
+
+ oopSocket.waitForReadyRead();
+ oopSocket.readLine();
+
+ session->stop();
+
+ delete session;
+
+ oopSocket.disconnectFromServer();
+ oopSocket.waitForDisconnected(-1);
+
+ return 0;
+}
diff --git a/tests/auto/qnetworksession/qnetworksession.pro b/tests/auto/qnetworksession/qnetworksession.pro
new file mode 100644
index 0000000000..a85925bc17
--- /dev/null
+++ b/tests/auto/qnetworksession/qnetworksession.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = lackey test
diff --git a/tests/auto/qnetworksession/test/test.pro b/tests/auto/qnetworksession/test/test.pro
new file mode 100644
index 0000000000..d248b10b74
--- /dev/null
+++ b/tests/auto/qnetworksession/test/test.pro
@@ -0,0 +1,26 @@
+load(qttest_p4)
+SOURCES += tst_qnetworksession.cpp
+HEADERS += ../../qbearertestcommon.h
+
+QT = core network
+
+TARGET = tst_qnetworksession
+CONFIG(debug_and_release) {
+ CONFIG(debug, debug|release) {
+ DESTDIR = ../debug
+ } else {
+ DESTDIR = ../release
+ }
+} else {
+ DESTDIR = ..
+}
+
+symbian {
+ TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData PowerMgmt
+}
+
+maemo6 {
+ CONFIG += link_pkgconfig
+
+ PKGCONFIG += conninet
+}
diff --git a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
new file mode 100644
index 0000000000..4ef3a4fdb2
--- /dev/null
+++ b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
@@ -0,0 +1,919 @@
+/****************************************************************************
+**
+** 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 test suite 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 <QtTest/QtTest>
+#include <QLocalServer>
+#include <QLocalSocket>
+#include "../../qbearertestcommon.h"
+#include <qnetworkconfigmanager.h>
+#include <qnetworksession.h>
+
+#ifdef Q_WS_MAEMO_6
+#include <stdio.h>
+#include <iapconf.h>
+#endif
+
+QT_USE_NAMESPACE
+
+Q_DECLARE_METATYPE(QNetworkConfiguration)
+Q_DECLARE_METATYPE(QNetworkSession::State);
+Q_DECLARE_METATYPE(QNetworkSession::SessionError);
+
+class tst_QNetworkSession : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+ void outOfProcessSession();
+ void invalidSession();
+
+ void sessionProperties_data();
+ void sessionProperties();
+
+ void userChoiceSession_data();
+ void userChoiceSession();
+
+ void sessionOpenCloseStop_data();
+ void sessionOpenCloseStop();
+
+private:
+ QNetworkConfigurationManager manager;
+
+ int inProcessSessionManagementCount;
+
+#ifdef Q_WS_MAEMO_6
+ Maemo::IAPConf *iapconf;
+ Maemo::IAPConf *iapconf2;
+ Maemo::IAPConf *gprsiap;
+#define MAX_IAPS 10
+ Maemo::IAPConf *iaps[MAX_IAPS];
+ QProcess *icd_stub;
+#endif
+};
+
+void tst_QNetworkSession::initTestCase()
+{
+ qRegisterMetaType<QNetworkSession::State>("QNetworkSession::State");
+ qRegisterMetaType<QNetworkSession::SessionError>("QNetworkSession::SessionError");
+ qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration");
+
+#ifdef Q_WS_MAEMO_6
+ iapconf = new Maemo::IAPConf("007");
+ iapconf->setValue("ipv4_type", "AUTO");
+ iapconf->setValue("wlan_wepkey1", "connt");
+ iapconf->setValue("wlan_wepdefkey", 1);
+ iapconf->setValue("wlan_ssid", QByteArray("JamesBond"));
+ iapconf->setValue("name", "James Bond");
+ iapconf->setValue("type", "WLAN_INFRA");
+
+ gprsiap = new Maemo::IAPConf("This-is-GPRS-IAP");
+ gprsiap->setValue("ask_password", false);
+ gprsiap->setValue("gprs_accesspointname", "internet");
+ gprsiap->setValue("gprs_password", "");
+ gprsiap->setValue("gprs_username", "");
+ gprsiap->setValue("ipv4_autodns", true);
+ gprsiap->setValue("ipv4_type", "AUTO");
+ gprsiap->setValue("sim_imsi", "244070123456789");
+ gprsiap->setValue("name", "MI6");
+ gprsiap->setValue("type", "GPRS");
+
+ iapconf2 = new Maemo::IAPConf("osso.net");
+ iapconf2->setValue("ipv4_type", "AUTO");
+ iapconf2->setValue("wlan_wepkey1", "osso.net");
+ iapconf2->setValue("wlan_wepdefkey", 1);
+ iapconf2->setValue("wlan_ssid", QByteArray("osso.net"));
+ iapconf2->setValue("name", "osso.net");
+ iapconf2->setValue("type", "WLAN_INFRA");
+ iapconf2->setValue("wlan_security", "WEP");
+
+ /* Create large number of IAPs in the gconf and see what happens */
+ fflush(stdout);
+ printf("Creating %d IAPS: ", MAX_IAPS);
+ for (int i=0; i<MAX_IAPS; i++) {
+ QString num = QString().sprintf("%d", i);
+ QString iap = "iap-" + num;
+ iaps[i] = new Maemo::IAPConf(iap);
+ iaps[i]->setValue("name", QString("test-iap-")+num);
+ iaps[i]->setValue("type", "WLAN_INFRA");
+ iaps[i]->setValue("wlan_ssid", QString(QString("test-ssid-")+num).toAscii());
+ iaps[i]->setValue("wlan_security", "WPA_PSK");
+ iaps[i]->setValue("EAP_wpa_preshared_passphrase", QString("test-passphrase-")+num);
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+ fflush(stdout);
+
+ icd_stub = new QProcess(this);
+ icd_stub->start("/usr/bin/icd2_stub.py");
+ QTest::qWait(1000);
+
+ // Add a known network to scan list that icd2 stub returns
+ QProcess dbus_send;
+ // 007 network
+ dbus_send.start("dbus-send --type=method_call --system "
+ "--dest=com.nokia.icd2 /com/nokia/icd2 "
+ "com.nokia.icd2.testing.add_available_network "
+ "string:'' uint32:0 string:'' "
+ "string:WLAN_INFRA uint32:5000011 array:byte:48,48,55");
+ dbus_send.waitForFinished();
+
+ // osso.net network
+ dbus_send.start("dbus-send --type=method_call --system "
+ "--dest=com.nokia.icd2 /com/nokia/icd2 "
+ "com.nokia.icd2.testing.add_available_network "
+ "string:'' uint32:0 string:'' "
+ "string:WLAN_INFRA uint32:83886097 array:byte:111,115,115,111,46,110,101,116");
+ dbus_send.waitForFinished();
+#endif
+
+ inProcessSessionManagementCount = -1;
+
+ QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
+ manager.updateConfigurations();
+ QTRY_VERIFY(spy.count() == 1);
+}
+
+void tst_QNetworkSession::cleanupTestCase()
+{
+ if (!(manager.capabilities() & QNetworkConfigurationManager::SystemSessionSupport) &&
+ (manager.capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces) &&
+ inProcessSessionManagementCount == 0) {
+ qWarning("No usable configurations found to complete all possible tests in "
+ "inProcessSessionManagement()");
+ }
+
+#ifdef Q_WS_MAEMO_6
+ iapconf->clear();
+ delete iapconf;
+ iapconf2->clear();
+ delete iapconf2;
+ gprsiap->clear();
+ delete gprsiap;
+
+ printf("Deleting %d IAPS : ", MAX_IAPS);
+ for (int i=0; i<MAX_IAPS; i++) {
+ iaps[i]->clear();
+ delete iaps[i];
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+ qDebug() << "Deleted" << MAX_IAPS << "IAPs";
+
+ icd_stub->terminate();
+ icd_stub->waitForFinished();
+#endif
+}
+
+void tst_QNetworkSession::invalidSession()
+{
+ QNetworkSession session(QNetworkConfiguration(), 0);
+ QVERIFY(!session.isOpen());
+ QVERIFY(session.state() == QNetworkSession::Invalid);
+}
+
+void tst_QNetworkSession::sessionProperties_data()
+{
+ QTest::addColumn<QNetworkConfiguration>("configuration");
+
+ QTest::newRow("invalid configuration") << QNetworkConfiguration();
+
+ foreach (const QNetworkConfiguration &config, manager.allConfigurations()) {
+ const QString name = config.name().isEmpty() ? QString("<Hidden>") : config.name();
+ QTest::newRow(name.toLocal8Bit().constData()) << config;
+ }
+}
+
+void tst_QNetworkSession::sessionProperties()
+{
+ QFETCH(QNetworkConfiguration, configuration);
+
+ QNetworkSession session(configuration);
+
+ QVERIFY(session.configuration() == configuration);
+
+ QStringList validBearerNames = QStringList() << QLatin1String("Unknown")
+ << QLatin1String("Ethernet")
+ << QLatin1String("WLAN")
+ << QLatin1String("2G")
+ << QLatin1String("CDMA2000")
+ << QLatin1String("WCDMA")
+ << QLatin1String("HSPA")
+ << QLatin1String("Bluetooth")
+ << QLatin1String("WiMAX");
+
+ if (!configuration.isValid()) {
+ QVERIFY(configuration.bearerName().isEmpty());
+ } else {
+ qDebug() << "Type:" << configuration.type()
+ << "Bearer:" << configuration.bearerName();
+
+ switch (configuration.type())
+ {
+ case QNetworkConfiguration::ServiceNetwork:
+ case QNetworkConfiguration::UserChoice:
+ default:
+ QVERIFY(configuration.bearerName().isEmpty());
+ break;
+ case QNetworkConfiguration::InternetAccessPoint:
+ QVERIFY(validBearerNames.contains(configuration.bearerName()));
+ break;
+ }
+ }
+
+ // QNetworkSession::interface() should return an invalid interface unless
+ // session is in the connected state.
+ qDebug() << "Session state:" << session.state();
+ qDebug() << "Session iface:" << session.interface().isValid() << session.interface().name();
+#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
+ // On Symbian emulator, the support for data bearers is limited
+ QCOMPARE(session.state() == QNetworkSession::Connected, session.interface().isValid());
+#endif
+
+ if (!configuration.isValid()) {
+ QVERIFY(configuration.state() == QNetworkConfiguration::Undefined &&
+ session.state() == QNetworkSession::Invalid);
+ } else {
+ switch (configuration.state()) {
+ case QNetworkConfiguration::Undefined:
+ QVERIFY(session.state() == QNetworkSession::NotAvailable);
+ break;
+ case QNetworkConfiguration::Defined:
+ QVERIFY(session.state() == QNetworkSession::NotAvailable);
+ break;
+ case QNetworkConfiguration::Discovered:
+ QVERIFY(session.state() == QNetworkSession::Connecting ||
+ session.state() == QNetworkSession::Disconnected);
+ break;
+ case QNetworkConfiguration::Active:
+ QVERIFY(session.state() == QNetworkSession::Connected ||
+ session.state() == QNetworkSession::Closing ||
+ session.state() == QNetworkSession::Roaming);
+ break;
+ default:
+ QFAIL("Invalid configuration state");
+ };
+ }
+}
+
+void tst_QNetworkSession::userChoiceSession_data()
+{
+ QTest::addColumn<QNetworkConfiguration>("configuration");
+
+ QNetworkConfiguration config = manager.defaultConfiguration();
+ if (config.type() == QNetworkConfiguration::UserChoice)
+ QTest::newRow("UserChoice") << config;
+ else
+ QSKIP("Default configuration is not a UserChoice configuration.", SkipAll);
+}
+
+void tst_QNetworkSession::userChoiceSession()
+{
+ QFETCH(QNetworkConfiguration, configuration);
+
+ QVERIFY(configuration.type() == QNetworkConfiguration::UserChoice);
+
+ QNetworkSession session(configuration);
+
+ // Check that configuration was really set
+ QVERIFY(session.configuration() == configuration);
+
+ QVERIFY(!session.isOpen());
+
+ // Check that session is not active
+ QVERIFY(session.sessionProperty("ActiveConfiguration").toString().isEmpty());
+
+ // The remaining tests require the session to be not NotAvailable.
+ if (session.state() == QNetworkSession::NotAvailable)
+ QSKIP("Network is not available.", SkipSingle);
+
+ QSignalSpy sessionOpenedSpy(&session, SIGNAL(opened()));
+ QSignalSpy sessionClosedSpy(&session, SIGNAL(closed()));
+ QSignalSpy stateChangedSpy(&session, SIGNAL(stateChanged(QNetworkSession::State)));
+ QSignalSpy errorSpy(&session, SIGNAL(error(QNetworkSession::SessionError)));
+
+ // Test opening the session.
+ {
+ bool expectStateChange = session.state() != QNetworkSession::Connected;
+
+ session.open();
+
+ session.waitForOpened();
+
+ if (session.isOpen())
+ QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty());
+ if (!errorSpy.isEmpty()) {
+ QNetworkSession::SessionError error =
+ qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0));
+ if (error == QNetworkSession::OperationNotSupportedError) {
+ // The session needed to bring up the interface,
+ // but the operation is not supported.
+ QSKIP("Configuration does not support open().", SkipSingle);
+ } else if (error == QNetworkSession::InvalidConfigurationError) {
+ // The session needed to bring up the interface, but it is not possible for the
+ // specified configuration.
+ if ((session.configuration().state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ QFAIL("Failed to open session for Discovered configuration.");
+ } else {
+ QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle);
+ }
+ } else if (error == QNetworkSession::UnknownSessionError) {
+ QSKIP("Unknown session error.", SkipSingle);
+ } else {
+ QFAIL("Error opening session.");
+ }
+ } else if (!sessionOpenedSpy.isEmpty()) {
+ QCOMPARE(sessionOpenedSpy.count(), 1);
+ QVERIFY(sessionClosedSpy.isEmpty());
+ QVERIFY(errorSpy.isEmpty());
+
+ if (expectStateChange)
+ QTRY_VERIFY(!stateChangedSpy.isEmpty());
+
+ QVERIFY(session.state() == QNetworkSession::Connected);
+#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
+ // On Symbian emulator, the support for data bearers is limited
+ QVERIFY(session.interface().isValid());
+#endif
+
+ const QString userChoiceIdentifier =
+ session.sessionProperty("UserChoiceConfiguration").toString();
+
+ QVERIFY(!userChoiceIdentifier.isEmpty());
+ QVERIFY(userChoiceIdentifier != configuration.identifier());
+
+ QNetworkConfiguration userChoiceConfiguration =
+ manager.configurationFromIdentifier(userChoiceIdentifier);
+
+ QVERIFY(userChoiceConfiguration.isValid());
+ QVERIFY(userChoiceConfiguration.type() != QNetworkConfiguration::UserChoice);
+
+ const QString testIdentifier("abc");
+ //resetting UserChoiceConfiguration is ignored (read only property)
+ session.setSessionProperty("UserChoiceConfiguration", testIdentifier);
+ QVERIFY(session.sessionProperty("UserChoiceConfiguration").toString() != testIdentifier);
+
+ const QString activeIdentifier =
+ session.sessionProperty("ActiveConfiguration").toString();
+
+ QVERIFY(!activeIdentifier.isEmpty());
+ QVERIFY(activeIdentifier != configuration.identifier());
+
+ QNetworkConfiguration activeConfiguration =
+ manager.configurationFromIdentifier(activeIdentifier);
+
+ QVERIFY(activeConfiguration.isValid());
+ QVERIFY(activeConfiguration.type() == QNetworkConfiguration::InternetAccessPoint);
+
+ //resetting ActiveConfiguration is ignored (read only property)
+ session.setSessionProperty("ActiveConfiguration", testIdentifier);
+ QVERIFY(session.sessionProperty("ActiveConfiguration").toString() != testIdentifier);
+
+ if (userChoiceConfiguration.type() == QNetworkConfiguration::InternetAccessPoint) {
+ QVERIFY(userChoiceConfiguration == activeConfiguration);
+ } else {
+ QVERIFY(userChoiceConfiguration.type() == QNetworkConfiguration::ServiceNetwork);
+ QVERIFY(userChoiceConfiguration.children().contains(activeConfiguration));
+ }
+ } else {
+ QFAIL("Timeout waiting for session to open.");
+ }
+ }
+}
+
+void tst_QNetworkSession::sessionOpenCloseStop_data()
+{
+ QTest::addColumn<QNetworkConfiguration>("configuration");
+ QTest::addColumn<bool>("forceSessionStop");
+
+ foreach (const QNetworkConfiguration &config, manager.allConfigurations()) {
+ const QString name = config.name().isEmpty() ? QString("<Hidden>") : config.name();
+ QTest::newRow((name + QLatin1String(" close")).toLocal8Bit().constData())
+ << config << false;
+ QTest::newRow((name + QLatin1String(" stop")).toLocal8Bit().constData())
+ << config << true;
+ }
+
+ inProcessSessionManagementCount = 0;
+}
+
+void tst_QNetworkSession::sessionOpenCloseStop()
+{
+ QFETCH(QNetworkConfiguration, configuration);
+ QFETCH(bool, forceSessionStop);
+
+ QNetworkSession session(configuration);
+
+ // Test initial state of the session.
+ {
+ QVERIFY(session.configuration() == configuration);
+ QVERIFY(!session.isOpen());
+ // session may be invalid if configuration is removed between when
+ // sessionOpenCloseStop_data() is called and here.
+ QVERIFY((configuration.isValid() && (session.state() != QNetworkSession::Invalid)) ||
+ (!configuration.isValid() && (session.state() == QNetworkSession::Invalid)));
+ QVERIFY(session.error() == QNetworkSession::UnknownSessionError);
+ }
+
+ // The remaining tests require the session to be not NotAvailable.
+ if (session.state() == QNetworkSession::NotAvailable)
+ QSKIP("Network is not available.", SkipSingle);
+
+ QSignalSpy sessionOpenedSpy(&session, SIGNAL(opened()));
+ QSignalSpy sessionClosedSpy(&session, SIGNAL(closed()));
+ QSignalSpy stateChangedSpy(&session, SIGNAL(stateChanged(QNetworkSession::State)));
+ QSignalSpy errorSpy(&session, SIGNAL(error(QNetworkSession::SessionError)));
+
+ // Test opening the session.
+ {
+ QNetworkSession::State previousState = session.state();
+ bool expectStateChange = previousState != QNetworkSession::Connected;
+
+ session.open();
+
+ session.waitForOpened();
+
+ if (session.isOpen())
+ QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty());
+ if (!errorSpy.isEmpty()) {
+ QNetworkSession::SessionError error =
+ qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0));
+
+ QVERIFY(session.state() == previousState);
+
+ if (error == QNetworkSession::OperationNotSupportedError) {
+ // The session needed to bring up the interface,
+ // but the operation is not supported.
+ QSKIP("Configuration does not support open().", SkipSingle);
+ } else if (error == QNetworkSession::InvalidConfigurationError) {
+ // The session needed to bring up the interface, but it is not possible for the
+ // specified configuration.
+ if ((session.configuration().state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ QFAIL("Failed to open session for Discovered configuration.");
+ } else {
+ QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle);
+ }
+ } else if (error == QNetworkSession::UnknownSessionError) {
+ QSKIP("Unknown Session error.", SkipSingle);
+ } else {
+ QFAIL("Error opening session.");
+ }
+ } else if (!sessionOpenedSpy.isEmpty()) {
+ QCOMPARE(sessionOpenedSpy.count(), 1);
+ QVERIFY(sessionClosedSpy.isEmpty());
+ QVERIFY(errorSpy.isEmpty());
+
+ if (expectStateChange) {
+ QTRY_VERIFY(stateChangedSpy.count() >= 2);
+
+ QNetworkSession::State state =
+ qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0));
+ QVERIFY(state == QNetworkSession::Connecting);
+
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0));
+ QVERIFY(state == QNetworkSession::Connected);
+ }
+
+ QVERIFY(session.state() == QNetworkSession::Connected);
+#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
+ // On Symbian emulator, the support for data bearers is limited
+ QVERIFY(session.interface().isValid());
+#endif
+ } else {
+ QFAIL("Timeout waiting for session to open.");
+ }
+ }
+
+ sessionOpenedSpy.clear();
+ sessionClosedSpy.clear();
+ stateChangedSpy.clear();
+ errorSpy.clear();
+
+ QNetworkSession session2(configuration);
+
+ QSignalSpy sessionOpenedSpy2(&session2, SIGNAL(opened()));
+ QSignalSpy sessionClosedSpy2(&session2, SIGNAL(closed()));
+ QSignalSpy stateChangedSpy2(&session2, SIGNAL(stateChanged(QNetworkSession::State)));
+ QSignalSpy errorSpy2(&session2, SIGNAL(error(QNetworkSession::SessionError)));
+
+ // Test opening a second session.
+ {
+ QVERIFY(session2.configuration() == configuration);
+ QVERIFY(!session2.isOpen());
+ QVERIFY(session2.state() == QNetworkSession::Connected);
+ QVERIFY(session.error() == QNetworkSession::UnknownSessionError);
+
+ session2.open();
+
+ QTRY_VERIFY(!sessionOpenedSpy2.isEmpty() || !errorSpy2.isEmpty());
+
+ QVERIFY(session.isOpen());
+ QVERIFY(session2.isOpen());
+ QVERIFY(session.state() == QNetworkSession::Connected);
+ QVERIFY(session2.state() == QNetworkSession::Connected);
+#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
+ // On Symbian emulator, the support for data bearers is limited
+ QVERIFY(session.interface().isValid());
+#endif
+ QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress());
+ QCOMPARE(session.interface().index(), session2.interface().index());
+ }
+
+ sessionOpenedSpy2.clear();
+
+ if (forceSessionStop) {
+ // Test forcing the second session to stop the interface.
+ QNetworkSession::State previousState = session.state();
+#ifdef Q_CC_NOKIAX86
+ // For S60 emulator builds: RConnection::Stop does not work on all Emulators
+ bool expectStateChange = false;
+#else
+ bool expectStateChange = previousState != QNetworkSession::Disconnected;
+#endif
+
+ session2.stop();
+
+ QTRY_VERIFY(!sessionClosedSpy2.isEmpty() || !errorSpy2.isEmpty());
+
+ QVERIFY(!session2.isOpen());
+
+ if (!errorSpy2.isEmpty()) {
+ QVERIFY(!errorSpy.isEmpty());
+
+ // check for SessionAbortedError
+ QNetworkSession::SessionError error =
+ qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0));
+ QNetworkSession::SessionError error2 =
+ qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0));
+
+ QVERIFY(error == QNetworkSession::SessionAbortedError);
+ QVERIFY(error2 == QNetworkSession::SessionAbortedError);
+
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy2.count(), 1);
+
+ errorSpy.clear();
+ errorSpy2.clear();
+ }
+
+ QVERIFY(errorSpy.isEmpty());
+ QVERIFY(errorSpy2.isEmpty());
+
+ if (expectStateChange)
+ QTRY_VERIFY(stateChangedSpy2.count() >= 2 || !errorSpy2.isEmpty());
+
+ if (!errorSpy2.isEmpty()) {
+ QVERIFY(session2.state() == previousState);
+ QVERIFY(session.state() == previousState);
+
+ QNetworkSession::SessionError error =
+ qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0));
+ if (error == QNetworkSession::OperationNotSupportedError) {
+ // The session needed to bring down the interface,
+ // but the operation is not supported.
+ QSKIP("Configuration does not support stop().", SkipSingle);
+ } else if (error == QNetworkSession::InvalidConfigurationError) {
+ // The session needed to bring down the interface, but it is not possible for the
+ // specified configuration.
+ if ((session.configuration().state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ QFAIL("Failed to stop session for Discovered configuration.");
+ } else {
+ QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle);
+ }
+ } else {
+ QFAIL("Error stopping session.");
+ }
+ } else if (!sessionClosedSpy2.isEmpty()) {
+ if (expectStateChange) {
+ if (configuration.type() == QNetworkConfiguration::ServiceNetwork) {
+ bool roamedSuccessfully = false;
+
+ QCOMPARE(stateChangedSpy2.count(), 4);
+
+ QNetworkSession::State state =
+ qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
+ QVERIFY(state == QNetworkSession::Connecting);
+
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0));
+ QVERIFY(state == QNetworkSession::Connected);
+
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(2).at(0));
+ QVERIFY(state == QNetworkSession::Closing);
+
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(3).at(0));
+ QVERIFY(state == QNetworkSession::Disconnected);
+
+ QTRY_VERIFY(stateChangedSpy.count() > 0);
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0));
+ if (state == QNetworkSession::Roaming) {
+ QTRY_VERIFY(!errorSpy.isEmpty() || stateChangedSpy.count() > 1);
+ if (stateChangedSpy.count() > 1) {
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0));
+ if (state == QNetworkSession::Connected) {
+ roamedSuccessfully = true;
+ QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected);
+ }
+ }
+ }
+ if (roamedSuccessfully) {
+ QString configId = session.sessionProperty("ActiveConfiguration").toString();
+ QNetworkConfiguration config = manager.configurationFromIdentifier(configId);
+ QNetworkSession session3(config);
+ QSignalSpy errorSpy3(&session3, SIGNAL(error(QNetworkSession::SessionError)));
+ QSignalSpy sessionOpenedSpy3(&session3, SIGNAL(opened()));
+
+ session3.open();
+ session3.waitForOpened();
+
+ if (session.isOpen())
+ QVERIFY(!sessionOpenedSpy3.isEmpty() || !errorSpy3.isEmpty());
+
+ session.stop();
+
+ QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
+ QTRY_VERIFY(session3.state() == QNetworkSession::Disconnected);
+ }
+#ifndef Q_CC_NOKIAX86
+ if (!roamedSuccessfully)
+ QVERIFY(!errorSpy.isEmpty());
+#endif
+ } else {
+ QCOMPARE(stateChangedSpy2.count(), 2);
+
+ QNetworkSession::State state =
+ qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
+ QVERIFY(state == QNetworkSession::Closing);
+
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0));
+ QVERIFY(state == QNetworkSession::Disconnected);
+ }
+
+ QTRY_VERIFY(!sessionClosedSpy.isEmpty());
+ QVERIFY(session.state() == QNetworkSession::Disconnected);
+ QVERIFY(session2.state() == QNetworkSession::Disconnected);
+ }
+
+ QVERIFY(errorSpy2.isEmpty());
+
+ ++inProcessSessionManagementCount;
+ } else {
+ QFAIL("Timeout waiting for session to stop.");
+ }
+
+#ifndef Q_CC_NOKIAX86
+ QVERIFY(!sessionClosedSpy.isEmpty());
+#endif
+ QVERIFY(!sessionClosedSpy2.isEmpty());
+
+#ifndef Q_CC_NOKIAX86
+ QVERIFY(!session.isOpen());
+#endif
+ QVERIFY(!session2.isOpen());
+ } else {
+ // Test closing the second session.
+ {
+ int stateChangedCountBeforeClose = stateChangedSpy2.count();
+ session2.close();
+
+ QTRY_VERIFY(!sessionClosedSpy2.isEmpty());
+#ifndef Q_CC_NOKIAX86
+ QVERIFY(stateChangedSpy2.count() == stateChangedCountBeforeClose);
+#endif
+
+ QVERIFY(sessionClosedSpy.isEmpty());
+
+ QVERIFY(session.isOpen());
+ QVERIFY(!session2.isOpen());
+ QVERIFY(session.state() == QNetworkSession::Connected);
+ QVERIFY(session2.state() == QNetworkSession::Connected);
+#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
+ // On Symbian emulator, the support for data bearers is limited
+ QVERIFY(session.interface().isValid());
+#endif
+ QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress());
+ QCOMPARE(session.interface().index(), session2.interface().index());
+ }
+
+ sessionClosedSpy2.clear();
+
+ // Test closing the first session.
+ {
+#ifdef Q_CC_NOKIAX86
+ // For S60 emulator builds: RConnection::Close does not actually
+ // close network connection on all Emulators
+ bool expectStateChange = false;
+#else
+ bool expectStateChange = session.state() != QNetworkSession::Disconnected &&
+ manager.capabilities() & QNetworkConfigurationManager::SystemSessionSupport;
+#endif
+
+ session.close();
+
+ QTRY_VERIFY(!sessionClosedSpy.isEmpty() || !errorSpy.isEmpty());
+
+ QVERIFY(!session.isOpen());
+
+ if (expectStateChange)
+ QTRY_VERIFY(!stateChangedSpy.isEmpty() || !errorSpy.isEmpty());
+
+ if (!errorSpy.isEmpty()) {
+ QNetworkSession::SessionError error =
+ qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0));
+ if (error == QNetworkSession::OperationNotSupportedError) {
+ // The session needed to bring down the interface,
+ // but the operation is not supported.
+ QSKIP("Configuration does not support close().", SkipSingle);
+ } else if (error == QNetworkSession::InvalidConfigurationError) {
+ // The session needed to bring down the interface, but it is not possible for the
+ // specified configuration.
+ if ((session.configuration().state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ QFAIL("Failed to close session for Discovered configuration.");
+ } else {
+ QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle);
+ }
+ } else {
+ QFAIL("Error closing session.");
+ }
+ } else if (!sessionClosedSpy.isEmpty()) {
+ QVERIFY(sessionOpenedSpy.isEmpty());
+ QCOMPARE(sessionClosedSpy.count(), 1);
+ if (expectStateChange)
+ QVERIFY(!stateChangedSpy.isEmpty());
+ QVERIFY(errorSpy.isEmpty());
+
+ if (expectStateChange)
+ QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
+
+ ++inProcessSessionManagementCount;
+ } else {
+ QFAIL("Timeout waiting for session to close.");
+ }
+ }
+ }
+}
+
+QDebug operator<<(QDebug debug, const QList<QNetworkConfiguration> &list)
+{
+ debug.nospace() << "( ";
+ foreach (const QNetworkConfiguration &config, list)
+ debug.nospace() << config.identifier() << ", ";
+ debug.nospace() << ")\n";
+ return debug;
+}
+
+// Note: outOfProcessSession requires that at least one configuration is
+// at Discovered -state (Defined is ok for symbian as well, as long as it is possible to open).
+void tst_QNetworkSession::outOfProcessSession()
+{
+ qDebug() << "START";
+
+#if defined(Q_OS_SYMBIAN) && defined(__WINS__)
+ QSKIP("Symbian emulator does not support two [QR]PRocesses linking a dll (QtBearer.dll) with global writeable static data.", SkipAll);
+#endif
+ QNetworkConfigurationManager manager;
+ // Create a QNetworkConfigurationManager to detect configuration changes made in Lackey. This
+ // is actually the essence of this testcase - to check that platform mediates/reflects changes
+ // regardless of process boundaries. The interprocess communication is more like a way to get
+ // this test-case act correctly and timely.
+ QList<QNetworkConfiguration> before = manager.allConfigurations(QNetworkConfiguration::Active);
+ QSignalSpy spy(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)));
+
+ // Cannot read/write to processes on WinCE or Symbian.
+ // Easiest alternative is to use sockets for IPC.
+ QLocalServer oopServer;
+ // First remove possible earlier listening address which would cause listen to fail
+ // (e.g. previously abruptly ended unit test might cause this)
+ QLocalServer::removeServer("tst_qnetworksession");
+ oopServer.listen("tst_qnetworksession");
+
+ qDebug() << "starting lackey";
+ QProcess lackey;
+ lackey.start("lackey/lackey");
+ qDebug() << lackey.error() << lackey.errorString();
+ QVERIFY(lackey.waitForStarted());
+
+ qDebug() << "waiting for connection";
+ QVERIFY(oopServer.waitForNewConnection(-1));
+ QLocalSocket *oopSocket = oopServer.nextPendingConnection();
+ qDebug() << "got connection";
+ do {
+ QByteArray output;
+
+ if (oopSocket->waitForReadyRead())
+ output = oopSocket->readLine().trimmed();
+
+ if (output.startsWith("Started session ")) {
+ QString identifier = QString::fromLocal8Bit(output.mid(20).constData());
+ QNetworkConfiguration changed;
+
+ do {
+ QTRY_VERIFY(!spy.isEmpty());
+ changed = qvariant_cast<QNetworkConfiguration>(spy.takeFirst().at(0));
+ } while (changed.identifier() != identifier);
+
+ QVERIFY((changed.state() & QNetworkConfiguration::Active) ==
+ QNetworkConfiguration::Active);
+
+ QVERIFY(!before.contains(changed));
+
+ QList<QNetworkConfiguration> after =
+ manager.allConfigurations(QNetworkConfiguration::Active);
+
+ QVERIFY(after.contains(changed));
+
+ spy.clear();
+
+ oopSocket->write("stop\n");
+ oopSocket->waitForBytesWritten();
+
+ do {
+ QTRY_VERIFY(!spy.isEmpty());
+
+ changed = qvariant_cast<QNetworkConfiguration>(spy.takeFirst().at(0));
+ } while (changed.identifier() != identifier);
+
+ QVERIFY((changed.state() & QNetworkConfiguration::Active) !=
+ QNetworkConfiguration::Active);
+
+ QList<QNetworkConfiguration> afterStop =
+ manager.allConfigurations(QNetworkConfiguration::Active);
+
+ QVERIFY(!afterStop.contains(changed));
+
+ oopSocket->disconnectFromServer();
+ oopSocket->waitForDisconnected(-1);
+
+ lackey.waitForFinished();
+ }
+ // This is effected by QTBUG-4903, process will always report as running
+ //} while (lackey.state() == QProcess::Running);
+
+ // Workaround: the socket in the lackey will disconnect on exit
+ } while (oopSocket->state() == QLocalSocket::ConnectedState);
+
+ switch (lackey.exitCode()) {
+ case 0:
+ qDebug("Lackey returned exit success (0)");
+ break;
+ case 1:
+ QSKIP("No discovered configurations found.", SkipAll);
+ case 2:
+ QSKIP("Lackey could not start session.", SkipAll);
+ default:
+ QSKIP("Lackey failed", SkipAll);
+ }
+ qDebug("STOP");
+}
+
+QTEST_MAIN(tst_QNetworkSession)
+
+#include "tst_qnetworksession.moc"
+
diff --git a/tests/manual/bearerex/bearerex.cpp b/tests/manual/bearerex/bearerex.cpp
new file mode 100644
index 0000000000..19246a2931
--- /dev/null
+++ b/tests/manual/bearerex/bearerex.cpp
@@ -0,0 +1,561 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 "bearerex.h"
+
+#include <QtNetwork>
+
+Q_DECLARE_METATYPE(QNetworkConfiguration)
+
+BearerEx::BearerEx(QWidget* parent)
+ : QMainWindow(parent)
+{
+ setupUi(this);
+
+ createMenus();
+
+ connect(&m_NetworkConfigurationManager, SIGNAL(updateCompleted()), this, SLOT(configurationsUpdateCompleted()));
+ connect(&m_NetworkConfigurationManager, SIGNAL(configurationAdded(const QNetworkConfiguration&)),
+ this, SLOT(configurationAdded(const QNetworkConfiguration&)));
+ connect(&m_NetworkConfigurationManager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)),
+ this, SLOT(configurationRemoved(const QNetworkConfiguration&)));
+ connect(&m_NetworkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
+ this, SLOT(onlineStateChanged(bool)));
+ connect(&m_NetworkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration&)),
+ this, SLOT(configurationChanged(const QNetworkConfiguration&)));
+ showConfigurations();
+}
+
+void BearerEx::createMenus()
+{
+ QAction* act1 = new QAction(tr("Show Details"), this);
+ menuBar()->addAction(act1);
+ connect(act1, SIGNAL(triggered()), this, SLOT(on_showDetailsButton_clicked()));
+
+ QAction* exitAct = new QAction(tr("Exit"), this);
+ menuBar()->addAction(exitAct);
+ connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
+}
+
+void BearerEx::showConfigurations()
+{
+ listWidget->clear();
+ QListWidgetItem* listItem;
+
+ QNetworkConfiguration defaultConfig = m_NetworkConfigurationManager.defaultConfiguration();
+ if (defaultConfig.type() == QNetworkConfiguration::UserChoice) {
+ listItem = new QListWidgetItem();
+ QFont font = listItem->font();
+ font.setBold(true);
+ font.setUnderline(true);
+ listItem->setFont(font);
+ listItem->setText(" UserChoice");
+ listItem->setData(Qt::UserRole, qVariantFromValue(defaultConfig));
+ listWidget->addItem(listItem);
+ }
+
+ QList<QNetworkConfiguration> configurations = m_NetworkConfigurationManager.allConfigurations();
+ for (int i=0; i<configurations.count(); i++)
+ {
+ listItem = new QListWidgetItem();
+ QString text;
+ if (configurations[i].type() == QNetworkConfiguration::InternetAccessPoint) {
+ text.append("(IAP,");
+ } else if (configurations[i].type() == QNetworkConfiguration::ServiceNetwork) {
+ text.append("(SNAP,");
+ }
+
+ if ((configurations[i].state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ text.append("Act) ");
+ } else if ((configurations[i].state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
+ text.append("Disc) ");
+ } else {
+ text.append("Def) ");
+ }
+ text.append(configurations[i].name());
+
+ if (defaultConfig.isValid() && defaultConfig == configurations[i]) {
+ QFont font = listItem->font();
+ font.setBold(true);
+ font.setUnderline(true);
+ listItem->setFont(font);
+ }
+ listItem->setText(text);
+ listItem->setData(Qt::UserRole, qVariantFromValue(configurations[i]));
+ listWidget->addItem(listItem);
+ }
+}
+
+void BearerEx::on_updateConfigurationsButton_clicked()
+{
+ m_NetworkConfigurationManager.updateConfigurations();
+}
+
+void BearerEx::on_updateListButton_clicked()
+{
+ showConfigurations();
+}
+
+void BearerEx::on_showDetailsButton_clicked()
+{
+ QListWidgetItem* item = listWidget->currentItem();
+ if (!item) {
+ return;
+ }
+
+ QNetworkConfiguration networkConfiguration = qVariantValue<QNetworkConfiguration>(item->data(Qt::UserRole));
+ DetailedInfoDialog infoDialog(&networkConfiguration,this);
+ infoDialog.exec();
+}
+
+void BearerEx::on_createSessionButton_clicked()
+{
+ QListWidgetItem* item = listWidget->currentItem();
+ if (!item) {
+ return;
+ }
+ QNetworkConfiguration networkConfiguration = qVariantValue<QNetworkConfiguration>(item->data(Qt::UserRole));
+ int newTabIndex = mainTabWidget->count();
+ SessionTab* newTab = new SessionTab(&networkConfiguration,&m_NetworkConfigurationManager,eventListWidget,newTabIndex-1);
+ QString label = QString("S")+QString::number(newTabIndex-1);
+ mainTabWidget->insertTab(newTabIndex,newTab,label);
+ mainTabWidget->setCurrentIndex(newTabIndex);
+}
+
+void BearerEx::on_clearEventListButton_clicked()
+{
+ eventListWidget->clear();
+}
+
+void BearerEx::configurationAdded(const QNetworkConfiguration& config)
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ listItem->setText(QString("Added: ")+config.name());
+ eventListWidget->addItem(listItem);
+}
+
+void BearerEx::configurationRemoved(const QNetworkConfiguration& config)
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ listItem->setText(QString("Removed: ")+config.name());
+ eventListWidget->addItem(listItem);
+}
+
+void BearerEx::onlineStateChanged(bool isOnline)
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ QFont font = listItem->font();
+ font.setBold(true);
+ listItem->setFont(font);
+ if (isOnline) {
+ listItem->setText(QString("> Online"));
+ } else {
+ listItem->setText(QString("< Offline"));
+ }
+ eventListWidget->addItem(listItem);
+}
+
+void BearerEx::configurationChanged(const QNetworkConfiguration & config)
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ QString state;
+ switch (config.state())
+ {
+ case QNetworkConfiguration::Undefined:
+ state = "Undef : ";
+ break;
+ case QNetworkConfiguration::Defined:
+ state = "Def : ";
+ break;
+ case QNetworkConfiguration::Discovered:
+ state = "Disc : ";
+ break;
+ case QNetworkConfiguration::Active:
+ state = "Act : ";
+ break;
+ }
+ listItem->setText(state+config.name());
+ eventListWidget->addItem(listItem);
+}
+
+void BearerEx::configurationsUpdateCompleted()
+{
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Close);
+ msgBox.setText("Configurations update completed.");
+ msgBox.exec();
+}
+
+DetailedInfoDialog::DetailedInfoDialog(QNetworkConfiguration* apNetworkConfiguration, QWidget * parent)
+ : QDialog(parent)
+{
+ setupUi(this);
+
+ tableWidget->setColumnCount(2);
+ int rowCount = 2;
+
+ if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) {
+ rowCount = rowCount + apNetworkConfiguration->children().count();
+ }
+
+ tableWidget->setRowCount(rowCount);
+ tableWidget->setColumnWidth(1,250);
+ tableWidget->setItem(0, 0, new QTableWidgetItem(tr("Name")));
+ tableWidget->setItem(0, 1, new QTableWidgetItem(apNetworkConfiguration->name()));
+ tableWidget->setItem(1, 0, new QTableWidgetItem(tr("Id")));
+ tableWidget->setItem(1, 1, new QTableWidgetItem(apNetworkConfiguration->identifier()));
+ if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) {
+ for (int i=0; i<apNetworkConfiguration->children().count(); i++) {
+ tableWidget->setItem(i+2, 0, new QTableWidgetItem(QString("IAP")+QString::number(i+1)));
+ tableWidget->setItem(i+2, 1, new QTableWidgetItem(apNetworkConfiguration->children()[i].name()));
+ }
+ }
+
+ tableWidget->setFocusPolicy(Qt::NoFocus);
+
+#ifdef Q_OS_SYMBIAN
+ this->showMaximized();
+#endif
+}
+
+SessionTab::SessionTab(QNetworkConfiguration* apNetworkConfiguration,
+ QNetworkConfigurationManager* configManager,
+ QListWidget* eventListWidget,
+ int index,
+ BearerEx * parent)
+ : QWidget(parent), m_http(0), m_eventListWidget(eventListWidget),
+ m_index(index), m_httpRequestOngoing(false), m_alrEnabled (false)
+{
+ setupUi(this);
+
+ m_ConfigManager = configManager;
+ m_NetworkSession = new QNetworkSession(*apNetworkConfiguration);
+
+ // Update initial Session state to UI
+ newState(m_NetworkSession->state());
+
+ connect(m_NetworkSession, SIGNAL(newConfigurationActivated()), this, SLOT(newConfigurationActivated()));
+ connect(m_NetworkSession, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SLOT(stateChanged(QNetworkSession::State)));
+ connect(m_NetworkSession, SIGNAL(opened()), this, SLOT(opened()));
+ connect(m_NetworkSession, SIGNAL(closed()), this, SLOT(closed()));
+ connect(m_NetworkSession, SIGNAL(error(QNetworkSession::SessionError)), this, SLOT(error(QNetworkSession::SessionError)));
+
+ if (apNetworkConfiguration->type() == QNetworkConfiguration::InternetAccessPoint) {
+ snapLabel->hide();
+ snapLineEdit->hide();
+ alrButton->hide();
+ iapLineEdit->setText(apNetworkConfiguration->name()+" ("+apNetworkConfiguration->identifier()+")");
+ } else if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) {
+ snapLineEdit->setText(apNetworkConfiguration->name()+" ("+apNetworkConfiguration->identifier()+")");
+ }
+ bearerLineEdit->setText(apNetworkConfiguration->bearerName());
+ sentRecDataLineEdit->setText(QString::number(m_NetworkSession->bytesWritten())+
+ QString(" / ")+
+ QString::number(m_NetworkSession->bytesReceived()));
+ snapLineEdit->setFocusPolicy(Qt::NoFocus);
+ iapLineEdit->setFocusPolicy(Qt::NoFocus);
+ bearerLineEdit->setFocusPolicy(Qt::NoFocus);
+ sentRecDataLineEdit->setFocusPolicy(Qt::NoFocus);
+ stateLineEdit->setFocusPolicy(Qt::NoFocus);
+}
+
+SessionTab::~SessionTab()
+{
+ delete m_NetworkSession;
+ delete m_http;
+}
+
+void SessionTab::on_createQHttpButton_clicked()
+{
+ if (m_httpRequestOngoing) {
+ return;
+ }
+
+ if (m_http) {
+ disconnect(m_http, 0, 0, 0);
+ delete m_http;
+ }
+ m_http = new QHttp(this);
+ createQHttpButton->setText("Recreate QHttp");
+ connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool)));
+}
+
+void SessionTab::on_sendRequestButton_clicked()
+{
+ if (m_http) {
+ QString urlstring("http://www.google.com");
+ QUrl url(urlstring);
+ m_http->setHost(url.host(), QHttp::ConnectionModeHttp, url.port() == -1 ? 0 : url.port());
+ m_http->get(urlstring);
+ m_httpRequestOngoing = true;
+ } else {
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Close);
+ msgBox.setText("QHttp not created.\nCreate QHttp First.");
+ msgBox.exec();
+ }
+}
+
+void SessionTab::on_openSessionButton_clicked()
+{
+ m_NetworkSession->open();
+ if (m_NetworkSession->isOpen()) {
+ newState(m_NetworkSession->state());
+ }
+}
+
+void SessionTab::on_closeSessionButton_clicked()
+{
+ m_NetworkSession->close();
+ if (!m_NetworkSession->isOpen()) {
+ newState(m_NetworkSession->state());
+ }
+}
+
+void SessionTab::on_stopConnectionButton_clicked()
+{
+ m_NetworkSession->stop();
+}
+
+void SessionTab::on_alrButton_clicked()
+{
+ if (!m_alrEnabled) {
+ connect(m_NetworkSession, SIGNAL(preferredConfigurationChanged(const QNetworkConfiguration&, bool)),
+ this, SLOT(preferredConfigurationChanged(const QNetworkConfiguration&, bool)));
+ alrButton->setText("Disable ALR");
+ m_alrEnabled = true;
+ } else {
+ disconnect(m_NetworkSession, SIGNAL(preferredConfigurationChanged(const QNetworkConfiguration&, bool)), 0, 0);
+ alrButton->setText("Enable ALR");
+ m_alrEnabled = false;
+ }
+}
+
+void SessionTab::on_deleteSessionButton_clicked()
+{
+ setWindowTitle("Bearer Example");
+ delete this;
+}
+
+void SessionTab::newConfigurationActivated()
+{
+ QMessageBox msgBox;
+ msgBox.setText("New configuration activated.");
+ msgBox.setInformativeText("Do you want to accept new configuration?");
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setDefaultButton(QMessageBox::Yes);
+ if (msgBox.exec() == QMessageBox::Yes) {
+ m_NetworkSession->accept();
+ iapLineEdit->setText(m_config.name()+" ("+m_config.identifier()+")");
+ } else {
+ m_NetworkSession->reject();
+ }
+}
+
+void SessionTab::preferredConfigurationChanged(const QNetworkConfiguration& config, bool /*isSeamless*/)
+{
+ m_config = config;
+ QMessageBox msgBox;
+ msgBox.setText("Roaming to new configuration.");
+ msgBox.setInformativeText("Do you want to migrate to "+config.name()+"?");
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setDefaultButton(QMessageBox::Yes);
+ if (msgBox.exec() == QMessageBox::Yes) {
+ m_NetworkSession->migrate();
+ } else {
+ m_NetworkSession->ignore();
+ }
+}
+
+void SessionTab::opened()
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ QFont font = listItem->font();
+ font.setBold(true);
+ listItem->setFont(font);
+ listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+QString("Opened"));
+ m_eventListWidget->addItem(listItem);
+
+ QVariant identifier = m_NetworkSession->property("ActiveConfiguration");
+ if (!identifier.isNull()) {
+ QString configId = identifier.toString();
+ QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId);
+ if (config.isValid()) {
+ iapLineEdit->setText(config.name()+" ("+config.identifier()+")");
+ }
+ }
+
+ if (m_NetworkSession->configuration().type() == QNetworkConfiguration::UserChoice) {
+ QVariant identifier = m_NetworkSession->property("UserChoiceConfiguration");
+ if (!identifier.isNull()) {
+ QString configId = identifier.toString();
+ QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId);
+ if (config.isValid() && (config.type() == QNetworkConfiguration::ServiceNetwork)) {
+ snapLineEdit->setText(config.name());
+ }
+ }
+ }
+}
+
+void SessionTab::closed()
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ QFont font = listItem->font();
+ font.setBold(true);
+ listItem->setFont(font);
+ listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+QString("Closed"));
+ m_eventListWidget->addItem(listItem);
+}
+
+QString SessionTab::stateString(QNetworkSession::State state)
+{
+ QString stateString;
+ switch (state)
+ {
+ case QNetworkSession::Invalid:
+ stateString = "Invalid";
+ break;
+ case QNetworkSession::NotAvailable:
+ stateString = "NotAvailable";
+ break;
+ case QNetworkSession::Connecting:
+ stateString = "Connecting";
+ break;
+ case QNetworkSession::Connected:
+ stateString = "Connected";
+ break;
+ case QNetworkSession::Closing:
+ stateString = "Closing";
+ break;
+ case QNetworkSession::Disconnected:
+ stateString = "Disconnected";
+ break;
+ case QNetworkSession::Roaming:
+ stateString = "Roaming";
+ break;
+ }
+ return stateString;
+}
+
+void SessionTab::stateChanged(QNetworkSession::State state)
+{
+ newState(state);
+
+ QListWidgetItem* listItem = new QListWidgetItem();
+ listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+stateString(state));
+ m_eventListWidget->addItem(listItem);
+}
+
+void SessionTab::newState(QNetworkSession::State state)
+{
+ QVariant identifier = m_NetworkSession->property("ActiveConfiguration");
+ if (state == QNetworkSession::Connected && !identifier.isNull()) {
+ QString configId = identifier.toString();
+ QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId);
+ if (config.isValid()) {
+ iapLineEdit->setText(config.name()+" ("+config.identifier()+")");
+ bearerLineEdit->setText(config.bearerName());
+ }
+ } else {
+ bearerLineEdit->setText(m_NetworkSession->configuration().bearerName());
+ }
+
+ QString active;
+ if (m_NetworkSession->isOpen()) {
+ active = " (O)";
+ }
+ stateLineEdit->setText(stateString(state)+active);
+}
+
+void SessionTab::error(QNetworkSession::SessionError error)
+{
+ QListWidgetItem* listItem = new QListWidgetItem();
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Close);
+
+ QString errorString;
+ switch (error)
+ {
+ case QNetworkSession::UnknownSessionError:
+ errorString = "UnknownSessionError";
+ break;
+ case QNetworkSession::SessionAbortedError:
+ errorString = "SessionAbortedError";
+ break;
+ case QNetworkSession::RoamingError:
+ errorString = "RoamingError";
+ break;
+ case QNetworkSession::OperationNotSupportedError:
+ errorString = "OperationNotSupportedError";
+ break;
+ case QNetworkSession::InvalidConfigurationError:
+ errorString = "InvalidConfigurationError";
+ break;
+ }
+ listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+errorString);
+ m_eventListWidget->addItem(listItem);
+
+ msgBox.setText(errorString);
+ msgBox.exec();
+}
+
+void SessionTab::done(bool error)
+{
+ m_httpRequestOngoing = false;
+
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Close);
+ if (error) {
+ msgBox.setText("HTTP request failed.");
+ } else {
+ QString result(m_http->readAll());
+ msgBox.setText(QString("HTTP request finished successfully.\nReceived ")+QString::number(result.length())+QString(" bytes."));
+ }
+ msgBox.exec();
+
+ sentRecDataLineEdit->setText(QString::number(m_NetworkSession->bytesWritten())+
+ QString(" / ")+
+ QString::number(m_NetworkSession->bytesReceived()));
+}
+
+// End of file
+
diff --git a/tests/manual/bearerex/bearerex.h b/tests/manual/bearerex/bearerex.h
new file mode 100644
index 0000000000..2875d6a151
--- /dev/null
+++ b/tests/manual/bearerex/bearerex.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 ACCESSPOINTMANAGEREX_H
+#define ACCESSPOINTMANAGEREX_H
+
+#include <QtGui>
+
+#include "ui_bearerex.h"
+#include "ui_detailedinfodialog.h"
+#include "ui_sessiondialog.h"
+
+#include "qnetworkconfigmanager.h"
+#include "qnetworksession.h"
+#include "xqlistwidget.h"
+
+QT_BEGIN_NAMESPACE
+class QHttp;
+QT_END_NAMESPACE
+
+class SessionTab;
+
+QT_USE_NAMESPACE
+
+class BearerEx : public QMainWindow, public Ui::BearerExMainWindow
+{
+ Q_OBJECT
+
+public:
+ BearerEx(QWidget* parent = 0);
+ void createMenus();
+ void showConfigurations();
+
+private Q_SLOTS:
+ void on_updateConfigurationsButton_clicked();
+ void on_updateListButton_clicked();
+ void on_showDetailsButton_clicked();
+ void on_createSessionButton_clicked();
+ void on_clearEventListButton_clicked();
+
+ void configurationsUpdateCompleted();
+ void configurationAdded(const QNetworkConfiguration& config);
+ void configurationRemoved(const QNetworkConfiguration& config);
+ void onlineStateChanged(bool isOnline);
+ void configurationChanged(const QNetworkConfiguration & config);
+
+private:
+ QNetworkConfigurationManager m_NetworkConfigurationManager;
+ QAction* m_openAction;
+};
+
+class DetailedInfoDialog : public QDialog, public Ui::DetailedInfoDialog
+{
+ Q_OBJECT
+
+public:
+ DetailedInfoDialog(QNetworkConfiguration* apNetworkConfiguration = 0, QWidget* parent = 0);
+};
+
+
+class SessionTab : public QWidget, public Ui::SessionTab
+{
+ Q_OBJECT
+
+public:
+ SessionTab(QNetworkConfiguration* apNetworkConfiguration = 0, QNetworkConfigurationManager* configManager = 0,
+ QListWidget* eventListWidget = 0, int index = 0, BearerEx* parent = 0);
+ ~SessionTab();
+
+ QString stateString(QNetworkSession::State state);
+
+private Q_SLOTS:
+ void on_createQHttpButton_clicked();
+ void on_sendRequestButton_clicked();
+ void on_openSessionButton_clicked();
+ void on_closeSessionButton_clicked();
+ void on_stopConnectionButton_clicked();
+ void on_deleteSessionButton_clicked();
+ void on_alrButton_clicked();
+ void done(bool error);
+
+ void newConfigurationActivated();
+ void preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless);
+ void stateChanged(QNetworkSession::State state);
+ void newState(QNetworkSession::State state);
+ void opened();
+ void closed();
+ void error(QNetworkSession::SessionError error);
+
+private: //data
+ QHttp* m_http;
+ QNetworkSession* m_NetworkSession;
+ QNetworkConfigurationManager* m_ConfigManager;
+ QListWidget* m_eventListWidget;
+ QNetworkConfiguration m_config;
+ int m_index;
+ bool m_httpRequestOngoing;
+ bool m_alrEnabled;
+};
+
+#endif // ACCESSPOINTMANAGEREX_H
+
+// End of file
+
diff --git a/tests/manual/bearerex/bearerex.pro b/tests/manual/bearerex/bearerex.pro
new file mode 100644
index 0000000000..927f98242a
--- /dev/null
+++ b/tests/manual/bearerex/bearerex.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+TARGET = BearerEx
+
+QT += core \
+ gui \
+ network
+
+FORMS += sessiondialog.ui \
+ bearerex.ui \
+ detailedinfodialog.ui
+
+# Example headers and sources
+HEADERS += bearerex.h \
+ xqlistwidget.h
+
+SOURCES += bearerex.cpp \
+ main.cpp \
+ xqlistwidget.cpp
+
+symbian:TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData \ No newline at end of file
diff --git a/tests/manual/bearerex/bearerex.ui b/tests/manual/bearerex/bearerex.ui
new file mode 100644
index 0000000000..e5ab62f5b3
--- /dev/null
+++ b/tests/manual/bearerex/bearerex.ui
@@ -0,0 +1,95 @@
+<ui version="4.0" >
+ <class>BearerExMainWindow</class>
+ <widget class="QMainWindow" name="BearerExMainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>360</width>
+ <height>640</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Bearer Example</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QTabWidget" name="mainTabWidget" >
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>Main</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Network Configurations</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" />
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <widget class="QPushButton" name="updateConfigurationsButton" >
+ <property name="text" >
+ <string>Update Configs</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QPushButton" name="updateListButton" >
+ <property name="text" >
+ <string>Update List</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QPushButton" name="createSessionButton" >
+ <property name="text" >
+ <string>Create Session</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="showDetailsButton" >
+ <property name="text" >
+ <string>Show Details</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2" >
+ <attribute name="title" >
+ <string>Events</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <item>
+ <widget class="QListWidget" name="eventListWidget" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearEventListButton" >
+ <property name="text" >
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/bearerex/detailedinfodialog.ui b/tests/manual/bearerex/detailedinfodialog.ui
new file mode 100644
index 0000000000..c4a21faf39
--- /dev/null
+++ b/tests/manual/bearerex/detailedinfodialog.ui
@@ -0,0 +1,54 @@
+<ui version="4.0" >
+ <class>DetailedInfoDialog</class>
+ <widget class="QDialog" name="DetailedInfoDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>308</width>
+ <height>396</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Bearer Example</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Detailed information</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableWidget" name="tableWidget" />
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>DetailedInfoDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>205</x>
+ <y>371</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>223</x>
+ <y>8</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tests/manual/bearerex/main.cpp b/tests/manual/bearerex/main.cpp
new file mode 100644
index 0000000000..20b167eb4b
--- /dev/null
+++ b/tests/manual/bearerex/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QApplication>
+
+#include "bearerex.h"
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+ BearerEx bearerEx;
+#ifdef Q_OS_SYMBIAN
+ bearerEx.showMaximized();
+#else
+ bearerEx.show();
+#endif
+ return app.exec();
+}
+
+// End of file
+
diff --git a/tests/manual/bearerex/sessiondialog.ui b/tests/manual/bearerex/sessiondialog.ui
new file mode 100644
index 0000000000..fcf21368b2
--- /dev/null
+++ b/tests/manual/bearerex/sessiondialog.ui
@@ -0,0 +1,139 @@
+<ui version="4.0" >
+ <class>SessionTab</class>
+ <widget class="QWidget" name="SessionTab" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QFormLayout" name="formLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="snapLabel" >
+ <property name="text" >
+ <string>SNAP</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="snapLineEdit" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="iapLabel" >
+ <property name="text" >
+ <string>IAP</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="iapLineEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="bearerLabel" >
+ <property name="text" >
+ <string>Bearer</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="bearerLineEdit" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="sentRecDataLabel" >
+ <property name="text" >
+ <string>Sent/Rec.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QLineEdit" name="sentRecDataLineEdit" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="stateLabel" >
+ <property name="text" >
+ <string>State</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QLineEdit" name="stateLineEdit" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <widget class="QPushButton" name="openSessionButton" >
+ <property name="text" >
+ <string>Open Session</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QPushButton" name="closeSessionButton" >
+ <property name="text" >
+ <string>Close Session</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QPushButton" name="stopConnectionButton" >
+ <property name="text" >
+ <string>Stop Conn.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QPushButton" name="createQHttpButton" >
+ <property name="text" >
+ <string>Create QHttp</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QPushButton" name="sendRequestButton" >
+ <property name="text" >
+ <string>Send Test Req.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QPushButton" name="alrButton" >
+ <property name="text" >
+ <string>Enable ALR</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QPushButton" name="deleteSessionButton" >
+ <property name="text" >
+ <string>Delete Session</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/bearerex/xqlistwidget.cpp b/tests/manual/bearerex/xqlistwidget.cpp
new file mode 100644
index 0000000000..8104779d1d
--- /dev/null
+++ b/tests/manual/bearerex/xqlistwidget.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 "xqlistwidget.h"
+
+XQListWidget::XQListWidget(QWidget* parent) : QListWidget(parent)
+{
+}
+
+void XQListWidget::keyPressEvent(QKeyEvent* event)
+{
+ switch (event->key())
+ {
+ case Qt::Key_Left:
+ {
+ focusPreviousChild();
+ break;
+ }
+ case Qt::Key_Right:
+ {
+ focusNextChild();
+ break;
+ }
+ default:
+ {
+ QListWidget::keyPressEvent(event);
+ }
+ }
+}
diff --git a/tests/manual/bearerex/xqlistwidget.h b/tests/manual/bearerex/xqlistwidget.h
new file mode 100644
index 0000000000..0649c2b8d3
--- /dev/null
+++ b/tests/manual/bearerex/xqlistwidget.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 XQLISTWIDGET_H
+#define XQLISTWIDGET_H
+
+#include <QListWidget>
+#include <QKeyEvent>
+
+class XQListWidget: public QListWidget
+{
+public:
+ XQListWidget(QWidget* parent = 0);
+
+protected:
+ void keyPressEvent(QKeyEvent* event);
+};
+
+#endif // XQLISTWIDGET_H
+
+
diff --git a/tests/manual/networkmanager/README b/tests/manual/networkmanager/README
new file mode 100644
index 0000000000..4bc7171954
--- /dev/null
+++ b/tests/manual/networkmanager/README
@@ -0,0 +1,2 @@
+This application serves as prototype/test-bed for NetworkManager development. The excellent (non-existing) documentation
+for the various NetworkManager interfaces makes this harder than it should be.
diff --git a/tests/manual/networkmanager/dialog.ui b/tests/manual/networkmanager/dialog.ui
new file mode 100644
index 0000000000..13019086b6
--- /dev/null
+++ b/tests/manual/networkmanager/dialog.ui
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>919</width>
+ <height>657</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Connections</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="cons">
+ <column>
+ <property name="text">
+ <string>Path</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>State</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Id</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Settings</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Devices:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="devicesTreeWidget">
+ <column>
+ <property name="text">
+ <string>Path</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Managed</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Interface</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Driver</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>State</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>IP4 Address</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>IP4 Config</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Hostname</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Domains</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>908</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0">
+ <widget class="QTreeWidget" name="accessPointsTreeWidget">
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>SSID</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Strength</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Wpa</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Rsn</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Freq</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Hardware Address</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Mode</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Max Bitrate</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QPushButton" name="startButton">
+ <property name="text">
+ <string>Start</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stopButton">
+ <property name="text">
+ <string>Stop</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="scanButton">
+ <property name="text">
+ <string>Scan</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="updateButton">
+ <property name="text">
+ <string>Update</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/networkmanager/networkmanager.pro b/tests/manual/networkmanager/networkmanager.pro
new file mode 100644
index 0000000000..84289d3978
--- /dev/null
+++ b/tests/manual/networkmanager/networkmanager.pro
@@ -0,0 +1,9 @@
+SOURCES += networkmanagertest.cpp nmview.cpp
+HEADERS += nmview.h
+TARGET = tst_networkmanagertest
+
+QT = core network dbus gui
+
+requires(contains(QT_CONFIG,dbus))
+
+FORMS += dialog.ui
diff --git a/tests/manual/networkmanager/networkmanagertest.cpp b/tests/manual/networkmanager/networkmanagertest.cpp
new file mode 100644
index 0000000000..8a6c5fa145
--- /dev/null
+++ b/tests/manual/networkmanager/networkmanagertest.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QDBusConnection>
+#include <QDBusError>
+#include <QDBusInterface>
+#include <QDBusMessage>
+#include <QDBusReply>
+#include <QtDBus>
+#include <QHostAddress>
+#include <QDebug>
+#include <NetworkManager/NetworkManager.h>
+#include <QApplication>
+#include <QMainWindow>
+#include "nmview.h"
+
+#include <arpa/inet.h>
+
+typedef QMap< QString, QMap<QString,QVariant> > SettingsMap;
+Q_DECLARE_METATYPE(SettingsMap)
+
+void printConnectionDetails(const QString& service)
+{
+ QDBusConnection dbc = QDBusConnection::systemBus();
+ if (!dbc.isConnected()) {
+ qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+ return;
+ }
+ QDBusInterface allCons(service, NM_DBUS_PATH_SETTINGS, NM_DBUS_IFACE_SETTINGS, dbc);
+ if (allCons.isValid()) {
+ QDBusReply<QList<QDBusObjectPath> > reply = allCons.call("ListConnections");
+ if ( reply.isValid() ) {
+ qWarning() << "Known connections:";
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ qWarning() << " " << path.path();
+ QDBusInterface sysIface(NM_DBUS_SERVICE_SYSTEM_SETTINGS, path.path(), NM_DBUS_IFACE_SETTINGS_CONNECTION, dbc);
+ if (sysIface.isValid()) {
+ QDBusMessage r = sysIface.call("GetSettings");
+ QDBusReply< SettingsMap > rep = sysIface.call("GetSettings");
+ qWarning() << " GetSettings:" << r.arguments() << r.signature() << rep.isValid() << sysIface.lastError();
+ QMap< QString, QMap<QString,QVariant> > map = rep.value();
+ QList<QString> list = map.keys();
+ foreach (QString key, list) {
+ QMap<QString,QVariant> innerMap = map[key];
+ qWarning() << " Key: " << key;
+ QMap<QString,QVariant>::const_iterator i = innerMap.constBegin();
+ while (i != innerMap.constEnd()) {
+ QString k = i.key();
+ qWarning() << " Key: " << k << " Entry: " << i.value();
+ if (k == "addresses" && i.value().canConvert<QDBusArgument>()) {
+ QDBusArgument arg = i.value().value<QDBusArgument>();
+ arg.beginArray();
+ while (!arg.atEnd()) {
+ QDBusVariant addr;
+ arg >> addr;
+ uint ip = addr.variant().toUInt();
+ qWarning() << ip;
+ qWarning() << " " << QHostAddress(htonl(ip)).toString();
+ }
+
+ }
+ i++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+}
+
+void readConnectionManagerDetails()
+{
+ qDBusRegisterMetaType<SettingsMap>();
+ QDBusConnection dbc = QDBusConnection::systemBus();
+ if (!dbc.isConnected()) {
+ qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+ return;
+ }
+
+ QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc);
+ if (!iface.isValid()) {
+ qWarning() << "Could not find NetworkManager";
+ return;
+ }
+
+ uint state = iface.property("State").toUInt();
+ switch(state) {
+ case NM_STATE_UNKNOWN:
+ qWarning() << "State: Unknown"; break;
+ case NM_STATE_ASLEEP:
+ qWarning() << "State: Asleep"; break;
+ case NM_STATE_CONNECTING:
+ qWarning() << "State: Connecting"; break;
+ case NM_STATE_CONNECTED:
+ qWarning() << "State: Connected"; break;
+ case NM_STATE_DISCONNECTED:
+ qWarning() << "State: Disconnected"; break;
+ }
+ //get list of network devices
+ QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices");
+ if ( reply.isValid() ) {
+ qWarning() << "Current devices:";
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ qWarning() << " " << path.path();
+ QDBusInterface devIface(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_DEVICE, dbc);
+ if (devIface.isValid()) {
+ qWarning() << " Managed: " << devIface.property("Managed").toBool();
+ qWarning() << " Interface: " << devIface.property("Interface").toString();
+ qWarning() << " HAL UDI: " << devIface.property("Udi").toString();
+ qWarning() << " Driver: " << devIface.property("Driver").toString();
+ QVariant v = devIface.property("DeviceType");
+ switch(v.toUInt()) {
+ case DEVICE_TYPE_UNKNOWN:
+ qWarning() << " DeviceType: Unknown" ;
+ break;
+ case DEVICE_TYPE_802_3_ETHERNET:
+ qWarning() << " DeviceType: Ethernet" ;
+ break;
+ case DEVICE_TYPE_802_11_WIRELESS:
+ qWarning() << " DeviceType: Wireless" ;
+ break;
+ case DEVICE_TYPE_GSM:
+ qWarning() << " DeviceType: GSM" ;
+ break;
+ case DEVICE_TYPE_CDMA:
+ qWarning() << " DeviceType: CDMA" ;
+ break;
+
+ }
+ v = devIface.property("State");
+ switch(v.toUInt()) {
+ case NM_DEVICE_STATE_UNKNOWN:
+ qWarning() << " State: Unknown" ; break;
+ case NM_DEVICE_STATE_UNMANAGED:
+ qWarning() << " State: Unmanaged" ; break;
+ case NM_DEVICE_STATE_UNAVAILABLE:
+ qWarning() << " State: Unavailable" ; break;
+ case NM_DEVICE_STATE_DISCONNECTED:
+ qWarning() << " State: Disconnected" ; break;
+ case NM_DEVICE_STATE_PREPARE:
+ qWarning() << " State: Preparing" ; break;
+ case NM_DEVICE_STATE_CONFIG:
+ qWarning() << " State: Being configured" ; break;
+ case NM_DEVICE_STATE_NEED_AUTH:
+ qWarning() << " State: Awaiting secrets" ; break;
+ case NM_DEVICE_STATE_IP_CONFIG:
+ qWarning() << " State: IP requested" ; break;
+ case NM_DEVICE_STATE_ACTIVATED:
+ qWarning() << " State: Activated" ; break;
+ case NM_DEVICE_STATE_FAILED:
+ qWarning() << " State: FAILED" ; break;
+ }
+ quint32 ip = devIface.property("Ip4Address").toUInt();
+ qWarning() << " IP4Address: " << QHostAddress(htonl(ip)).toString();
+ if (v.toUInt() == NM_DEVICE_STATE_ACTIVATED) {
+ QString path = devIface.property("Ip4Config").value<QDBusObjectPath>().path();
+ qWarning() << " IP4Config: " << path;
+ QDBusInterface ipIface(NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE_IP4_CONFIG, dbc);
+ if (ipIface.isValid()) {
+ qWarning() << " Hostname: " << ipIface.property("Hostname").toString();
+ qWarning() << " Domains: " << ipIface.property("Domains").toStringList();
+ qWarning() << " NisDomain: " << ipIface.property("NisDomain").toString();
+ QDBusArgument arg= ipIface.property("Addresses").value<QDBusArgument>();
+ //qWarning() << " " << arg.currentType();
+ qWarning() << " Addresses: " << ipIface.property("Addresses");
+ qWarning() << " Nameservers: " << ipIface.property("Nameservers");
+ qWarning() << " NisServers: " << ipIface.property("NisServers");
+ }
+
+ }
+
+ }
+ }
+ }
+
+ //get list of active connections
+ QVariant prop = iface.property("ActiveConnections");
+ QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >();
+ QString activePath;
+ if ( connections.count() )
+ qWarning() << "Active connections:";
+ foreach(QDBusObjectPath path, connections) {
+ qWarning() << " " << path.path();
+ activePath = path.path();
+ QString serviceName;
+ QDBusInterface conIface(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_ACTIVE_CONNECTION, dbc);
+ if (conIface.isValid()) {
+ qWarning() << " default connection: " << conIface.property("Default").toBool();
+ serviceName = conIface.property("ServiceName").toString();
+ qWarning() << " service name: " << serviceName;
+ qWarning() << " connection path: " << conIface.property("Connection").value<QDBusObjectPath>().path();
+ qWarning() << " specific object:" << conIface.property("SpecificObject").value<QDBusObjectPath>().path();
+ qWarning() << " sharedServiceName: " << conIface.property("SharedServiceName").toString();
+ QList<QDBusObjectPath> devs = conIface.property("Devices").value<QList<QDBusObjectPath> >();
+ qWarning() << " devices: ";
+ foreach(QDBusObjectPath p, devs)
+ qWarning() << " " << path.path();
+ QVariant v = conIface.property("State");
+ switch (v.toInt()) {
+ case NM_ACTIVE_CONNECTION_STATE_UNKNOWN:
+ qWarning()<< " State: unknown"; break;
+ case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
+ qWarning()<< " State: activating"; break;
+ case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
+ qWarning()<< " State: activated"; break;
+ }
+ } else {
+ qWarning() << conIface.lastError();
+ }
+
+ }
+
+ printConnectionDetails(NM_DBUS_SERVICE_SYSTEM_SETTINGS);
+ printConnectionDetails(NM_DBUS_SERVICE_USER_SETTINGS);
+
+
+ //turn active connection off
+ /*QDBusObjectPath dbop("/org/freedesktop/NetworkManager/ActiveConnection/1");
+ QVariant asd = QVariant::fromValue(dbop);
+ iface.call(QLatin1String("DeactivateConnection"), asd);
+ qWarning() << iface.lastError();*/
+
+ /*QDBusObjectPath p1device("/org/freedesktop/Hal/devices/net_00_60_6e_82_02_65");
+ QVariant p1v = QVariant::fromValue(p1device);
+ QDBusObjectPath p1con("/org/freedesktop/NetworkManagerSettings/0");
+ QVariant p1c = QVariant::fromValue(p1con);
+ QDBusObjectPath p1sp("");
+ QVariant p1sp1 = QVariant::fromValue(p1sp);
+ iface.call(QLatin1String("ActivateConnection"),
+ QString("/org/freedesktop/NetworkManagerSystemSettings"), p1c,p1v, p1v );
+ qWarning() << iface.lastError();
+ */
+}
+
+int main( int argc, char** argv)
+{
+ QApplication app(argc, argv);
+ //readConnectionManagerDetails();
+ QMainWindow main;
+ NMView view;
+ main.setCentralWidget(&view);
+ main.show();
+ return app.exec();
+
+}
diff --git a/tests/manual/networkmanager/nmview.cpp b/tests/manual/networkmanager/nmview.cpp
new file mode 100644
index 0000000000..9e28ff0469
--- /dev/null
+++ b/tests/manual/networkmanager/nmview.cpp
@@ -0,0 +1,1028 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 "nmview.h"
+
+#include <QLabel>
+#include <QLayout>
+#include <QListWidget>
+#include <QDebug>
+#include <QPushButton>
+
+#include <QtDBus>
+#include <QtNetwork>
+#include <NetworkManager/NetworkManager.h>
+#include <arpa/inet.h>
+
+#include <QDBusConnection>
+#include <QDBusError>
+#include <QDBusInterface>
+#include <QDBusMessage>
+#include <QDBusReply>
+
+#include <QHostAddress>
+#include <QNetworkInterface>
+#include <QTreeWidgetItem>
+#include <QMessageBox>
+
+//#include "ui_dialog.h"
+
+#include <qnetworkconfiguration.h>
+#include <qnetworkconfigmanager.h>
+#include <qnetworksession.h>
+#include <QtNetwork/private/qnetworkmanagerservice_p.h>
+
+//static QDBusConnection dbc = QDBusConnection::systemBus();
+//typedef QMap< QString, QMap<QString,QVariant> > SettingsMap;
+//Q_DECLARE_METATYPE(SettingsMap)
+
+
+NMView::NMView(QDialog* parent)
+ : QDialog(parent, 0), dbc(QDBusConnection::systemBus())
+{
+ init();
+
+ if (!dbc.isConnected()) {
+ qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+ return;
+ }
+ updateConnections();
+ getDevices();
+}
+
+NMView::~NMView()
+{
+}
+void NMView::init()
+{
+ setupUi(this);
+ sess = 0;
+// readSettings();
+ connect(startButton, SIGNAL(clicked()), this, SLOT(activate()));
+ connect(stopButton, SIGNAL(clicked()), this, SLOT(deactivate()));
+ connect(scanButton, SIGNAL(clicked()), this, SLOT(findAccessPoints()));
+ connect(updateButton, SIGNAL(clicked()), this, SLOT(update()));
+
+ connect(cons, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
+ this,SLOT(connectionItemActivated(QTreeWidgetItem*, int)));
+
+
+ connect(devicesTreeWidget, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
+ this, SLOT(deviceItemActivated(QTreeWidgetItem*, int)));
+
+ cons->header()->setResizeMode(QHeaderView::ResizeToContents);
+ devicesTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
+ accessPointsTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
+// accessPointsTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
+
+ manager = new QNetworkConfigurationManager(this);
+
+ connect(manager, SIGNAL(updateCompleted()), this, SLOT(updateCompleted()));
+
+ connect(manager, SIGNAL(configurationAdded(const QNetworkConfiguration &)),
+ this, SLOT(configurationAdded(const QNetworkConfiguration&)));
+
+ devicesTreeWidget->header()->hideSection(0);
+ devicesTreeWidget->header()->hideSection(1);
+ devicesTreeWidget->header()->hideSection(3);
+ devicesTreeWidget->header()->hideSection(5);
+ devicesTreeWidget->header()->hideSection(6);
+ devicesTreeWidget->header()->hideSection(7);
+ devicesTreeWidget->header()->hideSection(8);
+ devicesTreeWidget->header()->hideSection(9);
+}
+
+void NMView::updateConnections()
+{
+ cons->clear();
+ manager->updateConfigurations();
+ QList<QNetworkConfiguration> configs = manager->allConfigurations();
+ foreach(QNetworkConfiguration p, configs) {
+ QStringList strlist;
+ strlist << p.name();
+ strlist << stateToString(p.state());
+ strlist << p.identifier();
+ strlist << typeToString(p.type());
+ QTreeWidgetItem *item;
+ item = new QTreeWidgetItem(strlist);
+ cons->insertTopLevelItem(0, item);
+ }
+ cons->sortItems ( 1, Qt::AscendingOrder);
+}
+
+void NMView::getActiveConnections()
+{
+ QList<QNetworkConfiguration> configs = manager->allConfigurations(QNetworkConfiguration::Active);
+ foreach(QNetworkConfiguration p, configs) {
+ qWarning() << __FUNCTION__ << p.name() << p.identifier();
+ }
+
+// QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc);
+// if (!iface.isValid()) {
+// qWarning() << "Could not find NetworkManager";
+// return;
+// }
+
+// QVariant prop = iface.property("ActiveConnections");
+// QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >();
+// foreach(QDBusObjectPath path, connections) {
+// QDBusInterface conDetails(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_ACTIVE_CONNECTION, dbc);
+// if (conDetails.isValid()) {
+// QString desc = path.path();
+// conDetails.property("Connection Path").value<QDBusObjectPath>().path();
+
+// QList<QDBusObjectPath> devices = conDetails.property("Devices").value<QList<QDBusObjectPath> >();
+//
+// foreach(QDBusObjectPath devpath, devices) {
+// QDBusInterface devIface(NM_DBUS_SERVICE, devpath.path(), NM_DBUS_INTERFACE_DEVICE, dbc);
+// desc += " "+devIface.property("Interface").toString();
+// desc += " "+QHostAddress(htonl(devIface.property("Ip4Address").toUInt())).toString();
+
+// }
+
+// qWarning() << conDetails.property("Connection").value<QDBusObjectPath>().path() << path.path();
+
+// QListWidgetItem* item = new QListWidgetItem(desc, activeCons);
+// item->setData(Qt::UserRole, path.path());
+// }
+// }
+}
+
+void NMView::update()
+{
+// QNetworkManagerInterface *dbIface;
+// dbIface = new QNetworkManagerInterface;
+// QList <QDBusObjectPath> connections = dbIface->activeConnections();
+//
+// foreach(QDBusObjectPath conpath, connections) {
+// QNetworkManagerConnectionActive *aConn;
+// aConn = new QNetworkManagerConnectionActive(conpath.path());
+// // in case of accesspoint, specificObject will hold the accessPOintObjectPath
+// qWarning() << aConn->connection().path() << aConn->specificObject().path() << aConn->devices().count();
+// QList <QDBusObjectPath> devs = aConn->devices();
+// foreach(QDBusObjectPath device, devs) {
+// qWarning() << " " << device.path();
+// }
+// }
+
+ QStringList connectionServices;
+ connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS;
+ connectionServices << NM_DBUS_SERVICE_USER_SETTINGS;
+ foreach (QString service, connectionServices) {
+ QDBusInterface allCons(service,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_IFACE_SETTINGS,
+ dbc);
+ if (allCons.isValid()) {
+ QDBusReply<QList<QDBusObjectPath> > reply = allCons.call("ListConnections");
+ if ( reply.isValid() ) {
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ QDBusInterface sysIface(service,
+ path.path(),
+ NM_DBUS_IFACE_SETTINGS_CONNECTION,
+ dbc);
+ if (sysIface.isValid()) {
+ qWarning() << "";
+ qWarning() << path.path();
+
+ // QDBusMessage r = sysIface.call("GetSettings");
+ QDBusReply< QNmSettingsMap > rep = sysIface.call("GetSettings");
+
+ QMap< QString, QMap<QString,QVariant> > map = rep.value();
+ QList<QString> list = map.keys();
+ foreach (QString key, list) {
+ QMap<QString,QVariant> innerMap = map[key];
+ qWarning() << " Key: " << key;
+ QMap<QString,QVariant>::const_iterator i = innerMap.constBegin();
+
+ while (i != innerMap.constEnd()) {
+ QString k = i.key();
+ qWarning() << " Key: " << k << " Entry: " << i.value();
+ i++;
+ }//end innerMap
+ }//end foreach key
+ }//end settings connection
+ } // foreach path
+ } //end ListConnections
+ } //end settingsInterface
+ }// end services
+ QDBusInterface iface(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ dbc);
+ if (iface.isValid()) {
+ QVariant prop = iface.property("ActiveConnections");
+ QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >();
+ foreach(QDBusObjectPath conpath, connections) {
+ qWarning() << "Active connection" << conpath.path();
+ QDBusInterface conDetails(NM_DBUS_SERVICE,
+ conpath.path(),
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ dbc);
+ if (conDetails.isValid()) {
+
+ QVariant prop = conDetails.property("Connection");
+ QDBusObjectPath connection = prop.value<QDBusObjectPath>();
+ qWarning() << conDetails.property("Default").toBool() << connection.path();
+
+// QVariant Sprop = conDetails.property("Devices");
+// QList<QDBusObjectPath> so = Sprop.value<QList<QDBusObjectPath> >();
+// foreach(QDBusObjectPath device, so) {
+// if(device.path() == devicePath) {
+// path = connection.path();
+// }
+// break;
+// }
+ }
+ }
+ }
+qWarning() << "";
+}
+
+void NMView::deactivate()
+{
+ QList<QNetworkConfiguration> configs = manager->allConfigurations(QNetworkConfiguration::Active);
+ foreach(QNetworkConfiguration p, configs) {
+ qWarning() << "Active cons" << p.name();
+ if(p.name() == cons->currentItem()->text(0)
+ && p.identifier() == cons->currentItem()->text(2)) {
+ qWarning() <<__FUNCTION__<< p.name();
+ if(!sess) {
+ sess = new QNetworkSession(p);
+
+ connect(sess, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SLOT(stateChanged(QNetworkSession::State)));
+
+ connect(sess, SIGNAL(error(QNetworkSession::SessionError)),
+ this, SLOT(networkSessionError(QNetworkSession::SessionError)));
+ }
+ sess->close();
+ delete sess;
+ sess = 0;
+ }
+ }
+}
+
+void NMView::activate()
+{
+ qWarning() << __FUNCTION__ << cons->currentItem()->text(0);
+
+ QList<QNetworkConfiguration> configs = manager->allConfigurations();
+ foreach(QNetworkConfiguration p, configs) {
+ if(p.name() == cons->currentItem()->text(0)) {
+
+ sess = new QNetworkSession(p);
+
+ connect(sess, SIGNAL(newConfigurationActivated()),
+ this, SLOT(getActiveConnections()));
+
+ connect(sess, SIGNAL(stateChanged(QNetworkSession::State)),
+ this, SLOT(stateChanged(QNetworkSession::State)));
+
+ connect(sess, SIGNAL(error(QNetworkSession::SessionError)),
+ this, SLOT(networkSessionError(QNetworkSession::SessionError)));
+
+ sess->open();
+ }
+ }
+}
+
+void NMView::getDevices()
+{
+ qWarning() << "";
+ qWarning() << __FUNCTION__;
+ devicesTreeWidget->clear();
+ //qDBusRegisterMetaType<SettingsMap>();
+
+ if (!dbc.isConnected()) {
+ qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+ return;
+ }
+ QDBusInterface iface(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ dbc);
+//NetworkManager interface
+ if (!iface.isValid()) {
+ qWarning() << "Could not find NetworkManager";
+ return;
+ }
+
+// uint state = iface.property("State").toUInt();
+// switch(state) {
+// case NM_STATE_UNKNOWN:
+// qWarning() << "State: Unknown"; break;
+// case NM_STATE_ASLEEP:
+// qWarning() << "State: Asleep"; break;
+// case NM_STATE_CONNECTING:
+// qWarning() << "State: Connecting"; break;
+// case NM_STATE_CONNECTED:
+// qWarning() << "State: Connected"; break;
+// case NM_STATE_DISCONNECTED:
+// qWarning() << "State: Disconnected"; break;
+// }
+
+ //get list of network devices
+ QTreeWidgetItem *item;
+ QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices");
+ if ( reply.isValid() ) {
+// qWarning() << "Current devices:";
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ QStringList devicesList;
+ qWarning() << " " << path.path();
+ devicesList << path.path();
+
+ QDBusInterface devIface(NM_DBUS_SERVICE,
+ path.path(),
+ NM_DBUS_INTERFACE_DEVICE,
+ dbc);
+ if (devIface.isValid()) {
+
+
+
+ ////// connect the dbus signal
+// /*if(*/dbc.connect(NM_DBUS_SERVICE,
+// path.path(),
+// NM_DBUS_INTERFACE_DEVICE,
+// "StateChanged",
+// this,SLOT(deviceStateChanged(quint32)));
+// {
+// qWarning() << "XXXXXXXXXX dbus connect successful" << path.path();
+// }
+
+
+ // qWarning() << " Managed: " << devIface.property("Managed").toBool();
+ devicesList << devIface.property("Managed").toString();
+ // qWarning() << " Interface: " << devIface.property("Interface").toString();
+ devicesList << devIface.property("Interface").toString();
+ // qWarning() << " HAL UDI: " << devIface.property("Udi").toString();
+ // qWarning() << " Driver: " << devIface.property("Driver").toString();
+ devicesList << devIface.property("Driver").toString();
+
+ QString x = deviceTypeToString(devIface.property("DeviceType").toUInt());
+ // qWarning() << " Type:" << x;
+ devicesList << x;
+
+ if( devIface.property("DeviceType").toUInt() == DEVICE_TYPE_802_11_WIRELESS) {
+ qWarning() << "Device is WIFI";
+ // // findAccessPoints(path.path());
+ }
+
+ QVariant v = devIface.property("State");
+ x = deviceStateToString(v.toUInt());
+// qWarning() << " State:" << x;
+ devicesList << x;
+
+ quint32 ip = devIface.property("Ip4Address").toUInt();
+// qWarning() << " IP4Address: " << QHostAddress(htonl(ip)).toString();
+ devicesList << QHostAddress(htonl(ip)).toString();
+
+
+ if (v.toUInt() == NM_DEVICE_STATE_ACTIVATED) {
+ QString path = devIface.property("Ip4Config").value<QDBusObjectPath>().path();
+// qWarning() << " IP4Config: " << path;
+ devicesList << path;
+ QDBusInterface ipIface(NM_DBUS_SERVICE,
+ path,
+ NM_DBUS_INTERFACE_IP4_CONFIG,
+ dbc);
+ if (ipIface.isValid()) {
+ // qWarning() << " Hostname: " << ipIface.property("Hostname").toString();
+ devicesList << ipIface.property("Hostname").toString();
+// qWarning() << " Domains: " << ipIface.property("Domains").toStringList();
+ devicesList << ipIface.property("Domains").toStringList().join(", ");
+// qWarning() << " NisDomain: " << ipIface.property("NisDomain").toString();
+ QDBusArgument arg= ipIface.property("Addresses").value<QDBusArgument>();
+// qWarning() << " Addresses: " << ipIface.property("Addresses");
+// qWarning() << " Nameservers: " << ipIface.property("Nameservers");
+// qWarning() << " NisServers: " << ipIface.property("NisServers");
+ }
+
+ }
+
+ }
+ item = new QTreeWidgetItem(devicesList);
+ devicesTreeWidget->insertTopLevelItem(0, item);
+ }
+ }
+
+
+// netconfig();
+
+}
+
+void NMView::readSettings()
+{
+ QDBusInterface settingsiface(NM_DBUS_SERVICE_SYSTEM_SETTINGS,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_IFACE_SETTINGS,
+ dbc);
+ //NetworkManagerSettings interface
+ if (settingsiface.isValid()) {
+ QDBusReply<QList<QDBusObjectPath> > reply = settingsiface.call("ListConnections");
+ if ( reply.isValid() ) {
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ qWarning() <<__FUNCTION__ << path.path();
+
+ }
+ }
+ }
+
+ QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc);
+ if (!iface.isValid()) {
+ qWarning() << "Could not find NetworkManager";
+ return;
+ }
+
+ // QStringList list = item->text().split(" -> ");
+
+ QVariant prop = iface.property("ActiveConnections");
+ QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >();
+ foreach(QDBusObjectPath path, connections) {
+ QDBusInterface conDetails(NM_DBUS_SERVICE,
+ path.path(),
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ dbc);
+
+ if (conDetails.isValid()) {
+ QString desc = path.path();
+ qWarning() << desc;
+ //if ( item->text(0) == conDetails.property("Connection").value<QDBusObjectPath>().path() ) {
+ // QListWidgetItem* item = new QTreeWidgetItem( desc,
+ // cons);
+ // item->setData(Qt::UserRole, desc);
+ // activeItemActivated( item );
+ //}
+ }
+ }
+}
+
+void NMView::printConnectionDetails(const QString& service)
+{
+ Q_UNUSED(service);
+
+//
+// qWarning() << __FUNCTION__ << service;
+//
+// QDBusConnection dbc = QDBusConnection::systemBus();
+// if (!dbc.isConnected()) {
+// qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+// return;
+// }
+// QDBusInterface allCons(service,
+// NM_DBUS_PATH_SETTINGS,
+// NM_DBUS_IFACE_SETTINGS,
+// dbc);
+//
+// if (allCons.isValid()) {
+// QDBusReply<QList<QDBusObjectPath> > reply = allCons.call("ListConnections");
+//
+// if ( reply.isValid() ) {
+// qWarning() << "Known connections:";
+// QList<QDBusObjectPath> list = reply.value();
+//
+// foreach(QDBusObjectPath path, list) {
+// qWarning() << " " << path.path();
+//
+// QDBusInterface sysIface(NM_DBUS_SERVICE_SYSTEM_SETTINGS,
+// path.path(),
+// NM_DBUS_IFACE_SETTINGS_CONNECTION,
+// dbc);
+//
+// if (sysIface.isValid()) {
+// QDBusMessage r = sysIface.call("GetSettings");
+// QDBusReply< QSettingsMap > rep = sysIface.call("GetSettings");
+//
+// qWarning() << " GetSettings:" << r.arguments() << r.signature() << rep.isValid() << sysIface.lastError();
+//
+// QMap< QString, QMap<QString,QVariant> > map = rep.value();
+// QList<QString> list = map.keys();
+//
+// foreach (QString key, list) {
+// QMap<QString,QVariant> innerMap = map[key];
+// qWarning() << " Key: " << key;
+// QMap<QString,QVariant>::const_iterator i = innerMap.constBegin();
+//
+// while (i != innerMap.constEnd()) {
+// QString k = i.key();
+// qWarning() << " Key: " << k << " Entry: " << i.value();
+//
+// if (k == "addresses" && i.value().canConvert<QDBusArgument>()) {
+// QDBusArgument arg = i.value().value<QDBusArgument>();
+// arg.beginArray();
+//
+// while (!arg.atEnd()) {
+// QDBusVariant addr;
+// arg >> addr;
+// uint ip = addr.variant().toUInt();
+// qWarning() << ip;
+// qWarning() << " " << QHostAddress(htonl(ip)).toString();
+// }
+//
+// }
+// i++;
+// }
+// }
+// }
+// }
+// }
+// }
+ qWarning() << "";
+}
+
+void NMView::getNetworkDevices()
+{
+
+}
+
+void NMView::connectionItemActivated( QTreeWidgetItem * item, int col )
+{
+ Q_UNUSED(col);
+
+ qWarning() <<__FUNCTION__<< item->text(0);
+ QDBusInterface iface(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ dbc);
+ if (!iface.isValid()) {
+ qWarning() << "Could not find NetworkManager";
+ return;
+ }
+ QVariant prop = iface.property("ActiveConnections");
+ QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >();
+ foreach(QDBusObjectPath path, connections) {
+ QDBusInterface conDetails(NM_DBUS_SERVICE,
+ path.path(),
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ dbc);
+
+ if (conDetails.isValid()) {
+ QString desc = path.path();
+ qWarning() << desc;
+ if ( item->text(0) == conDetails.property("Connection").value<QDBusObjectPath>().path() ) {
+// QListWidgetItem* item = new QTreeWidgetItem( desc,
+// cons);
+// item->setData(Qt::UserRole, desc);
+// activeItemActivated( item );
+ }
+ }
+ }
+}
+
+
+
+void NMView::deviceItemActivated( QTreeWidgetItem * item , int section)
+{
+ Q_UNUSED(item);
+ Q_UNUSED(section);
+
+ // qWarning() << item->text(section) << item->text(4);
+ //if(item->text(4) == "Wireless") findAccessPoints(item->text(0));
+}
+
+
+void NMView::netconfig()
+{
+// qWarning() << __FUNCTION__;
+
+// qDBusRegisterMetaType<SettingsMap>();
+ QDBusConnection dbc = QDBusConnection::systemBus();
+ if (!dbc.isConnected()) {
+ qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+ return;
+ }
+
+ QDBusInterface iface(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_IFACE_SETTINGS_CONNECTION,
+ dbc);
+ if (!iface.isValid()) {
+ qWarning() << "Could not find NetworkManager Settings";
+ return;
+ } else {
+ QDBusReply<QList<QDBusObjectPath> > reply = iface.call("ListConnections");
+ QList<QDBusObjectPath> list = reply.value();
+// qWarning() << reply.value();
+ foreach(QDBusObjectPath path, list) {
+ qWarning() << " " << path.path();
+ }
+ }
+}
+
+
+void NMView::findAccessPoints()
+{
+ accessPointsTreeWidget->clear();
+
+ QDBusInterface iface(NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ dbc);
+
+ QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices");
+ if ( reply.isValid() ) {
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ QDBusInterface devIface(NM_DBUS_SERVICE,
+ path.path(),
+ NM_DBUS_INTERFACE_DEVICE,
+ dbc);
+ if (devIface.isValid()) {
+
+ if( devIface.property("DeviceType").toUInt() == DEVICE_TYPE_802_11_WIRELESS) {
+
+// qWarning() <<"deviface"<< devIface.path();
+ QDBusInterface wififace(NM_DBUS_SERVICE,
+ devIface.path(),
+ NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+ dbc);
+ if (!wififace.isValid()) {
+ qWarning() << "Could not find NetworkManager wireless interface";
+ return;
+ }
+
+/////////////////////////
+// if(dbc.connect(NM_DBUS_SERVICE,
+// path.path(),
+// NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+// "PropertiesChanged",
+// this,SLOT(aPPropertiesChanged( QMap<QString,QVariant>))) ) {
+// qWarning() << "PropertiesChanged connect";
+// } else {
+// qWarning() << "NOT connect";
+
+// }
+/////////////////////////
+ qWarning() <<"wififace"<< wififace.path();
+ QDBusReply<QList<QDBusObjectPath> > reply2 = wififace.call("GetAccessPoints");
+ if ( reply2.isValid() ) {
+ QTreeWidgetItem *item;
+ QList<QDBusObjectPath> list2 = reply2.value();
+ foreach(QDBusObjectPath path2, list2) {
+ QDBusInterface accessPointIface(NM_DBUS_SERVICE,
+ path2.path(),
+ NM_DBUS_INTERFACE_ACCESS_POINT,
+ dbc);
+ if (accessPointIface.isValid()) {
+//// qWarning() <<"path2" << path2.path();
+
+// if(dbc.connect(NM_DBUS_SERVICE, //signal strength
+// path2.path(),
+// NM_DBUS_INTERFACE_ACCESS_POINT,
+// "PropertiesChanged",
+// this,SLOT(aPPropertiesChanged( QMap<QString,QVariant>))) ) {
+// qWarning() << "PropertiesChanged connect";
+// } else {
+// qWarning() << "NOT connect";
+//
+// }
+
+ QStringList accessPoints;
+ accessPoints << accessPointIface.property("Ssid").toString();
+ accessPoints << QString::number(accessPointIface.property("Strength").toInt());
+ accessPoints << securityCapabilitiesToString(accessPointIface.property("WpaFlags" ).toInt());
+ accessPoints << securityCapabilitiesToString(accessPointIface.property("RsnFlags" ).toInt());
+ accessPoints << accessPointIface.property("Frequency" ).toString();
+ accessPoints << accessPointIface.property("HwAddress" ).toString();
+ accessPoints << deviceModeToString(accessPointIface.property("Mode" ).toInt());
+ accessPoints << accessPointIface.property("MaxBitrate" ).toString();
+ //HwAddress
+ // if(accessPointIface.property("Flags" ).toInt() == NM_802_11_AP_FLAGS_PRIVACY ) {
+ // qWarning() << "Secure";
+ // }
+ item = new QTreeWidgetItem(accessPoints);
+ accessPointsTreeWidget->insertTopLevelItem(0, item);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+QString NMView::deviceStateToString(int state)
+{
+ QString ret;
+ switch(state) {
+ case NM_DEVICE_STATE_UNKNOWN:
+ ret = "Unknown";
+ break;
+ case NM_DEVICE_STATE_UNMANAGED:
+ ret = "Unmanaged";
+ break;
+ case NM_DEVICE_STATE_UNAVAILABLE:
+ ret = "Unavailable";
+ break;
+ case NM_DEVICE_STATE_DISCONNECTED:
+ ret = "Disconnected";
+ break;
+ case NM_DEVICE_STATE_PREPARE:
+ ret = "Preparing to connect";
+ break;
+ case NM_DEVICE_STATE_CONFIG:
+ ret = "Being configured";
+ break;
+ case NM_DEVICE_STATE_NEED_AUTH:
+ ret = "Awaiting secrets";
+ break;
+ case NM_DEVICE_STATE_IP_CONFIG:
+ ret = "IP requested";
+ break;
+ case NM_DEVICE_STATE_ACTIVATED:
+ ret = "Activated";
+ break;
+ case NM_DEVICE_STATE_FAILED:
+ ret = "FAILED";
+ break;
+ };
+ return ret;
+}
+
+QString NMView::deviceTypeToString(int device)
+{
+ QString ret;
+ switch(device) {
+ case DEVICE_TYPE_UNKNOWN:
+ ret = "Unknown";
+ break;
+ case DEVICE_TYPE_802_3_ETHERNET:
+ ret = "Ethernet";
+ break;
+ case DEVICE_TYPE_802_11_WIRELESS:
+ ret = "Wireless";
+ break;
+ case DEVICE_TYPE_GSM:
+ ret = "GSM";
+ break;
+ case DEVICE_TYPE_CDMA:
+ ret = "CDMA";
+ break;
+ };
+ return ret;
+}
+
+QString NMView::securityCapabilitiesToString(int caps)
+{
+ int check = caps;
+// qWarning() << __FUNCTION__<< caps;
+ QString ret;
+ if( check == 0 )
+ ret += "None.";
+ if( (check & NM_802_11_AP_SEC_PAIR_WEP40))
+ ret += " 40-bit WEP encryption. ";
+ if( (check & NM_802_11_AP_SEC_PAIR_WEP104) )
+ ret += " 104-bit WEP encryption. ";
+ if( (check & NM_802_11_AP_SEC_PAIR_TKIP) )
+ ret += " TKIP encryption. ";
+ if( (check & NM_802_11_AP_SEC_PAIR_CCMP) )
+ ret += " CCMP encryption. ";
+ if( (check & NM_802_11_AP_SEC_GROUP_WEP40))
+ ret += " 40-bit WEP cipher. ";
+ if( (check & NM_802_11_AP_SEC_GROUP_WEP104))
+ ret += " 104-bit WEP cipher. ";
+ if( (check & NM_802_11_AP_SEC_GROUP_TKIP) )
+ ret += " TKIP cipher. ";
+ if( (check & NM_802_11_AP_SEC_GROUP_CCMP) )
+ ret += " CCMP cipher. ";
+ if( (check & NM_802_11_AP_SEC_KEY_MGMT_PSK))
+ ret += " PSK key management. ";
+ if( (check & NM_802_11_AP_SEC_KEY_MGMT_802_1X) )
+ ret += " 802.1x key management. ";
+ return ret;
+}
+
+QString NMView::deviceModeToString(int mode)
+{
+ QString ret;
+ switch (mode) {
+ case NM_802_11_MODE_UNKNOWN:
+ ret = "Unknown";
+ break;
+ case NM_802_11_MODE_ADHOC:
+ ret = " (Adhoc).";
+ break;
+ case NM_802_11_MODE_INFRA:
+ ret = " (Infrastructure)";
+ };
+ return ret;
+}
+
+void NMView::netManagerState(quint32 state)
+{
+ qWarning() << __FUNCTION__ << state;// << old << reason;
+ switch(state) {
+ case NM_STATE_UNKNOWN:
+ qWarning() << "The NetworkManager daemon is in an unknown state. ";
+ break;
+ case NM_STATE_ASLEEP:
+ qWarning() << "The NetworkManager daemon is asleep and all interfaces managed by it are inactive. ";
+ break;
+ case NM_STATE_CONNECTING:
+ qWarning() << "The NetworkManager daemon is connecting a device. FIXME: What does this mean when one device is active and another is connecting? ";
+ break;
+ case NM_STATE_CONNECTED:
+ qWarning() <<"The NetworkManager daemon is connected. ";
+ break;
+ case NM_STATE_DISCONNECTED:
+ qWarning() << "The NetworkManager daemon is disconnected.";
+ break;
+
+ };
+}
+
+void NMView::deviceStateChanged(quint32 state)
+{
+ qWarning() << __FUNCTION__ << state;
+ switch(state) {
+ case NM_DEVICE_STATE_UNKNOWN :
+ qWarning() <<"The device is in an unknown state. ";
+ break;
+ case NM_DEVICE_STATE_UNMANAGED:
+ qWarning() <<"The device is not managed by NetworkManager.";
+ break;
+ case NM_DEVICE_STATE_UNAVAILABLE:
+ qWarning() <<"The device cannot be used (carrier off, rfkill, etc).";
+ break;
+ case NM_DEVICE_STATE_DISCONNECTED:
+ qWarning() <<"The device is not connected.";
+ break;
+ case NM_DEVICE_STATE_PREPARE:
+ qWarning() <<"The device is preparing to connect.";
+ break;
+ case NM_DEVICE_STATE_CONFIG:
+ qWarning() <<"The device is being configured.";
+ break;
+ case NM_DEVICE_STATE_NEED_AUTH:
+ qWarning() <<"The device is awaiting secrets necessary to continue connection.";
+ break;
+ case NM_DEVICE_STATE_IP_CONFIG:
+ qWarning() <<"The IP settings of the device are being requested and configured.";
+ break;
+ case NM_DEVICE_STATE_ACTIVATED:
+ qWarning() <<"The device is active.";
+ break;
+ case NM_DEVICE_STATE_FAILED:
+ qWarning() <<"The device is in a failure state following an attempt to activate it.";
+ break;
+ };
+}
+
+void NMView::updateCompleted()
+{
+ qWarning() << __FUNCTION__;
+}
+
+void NMView::newConfigurationActivated()
+{
+ qWarning() << __FUNCTION__;
+ getActiveConnections();
+}
+
+void NMView::stateChanged(QNetworkSession::State state)
+{
+ // QString stateStringstr;
+ switch (state) {
+ case QNetworkSession::Invalid:
+ stateString = "Invalid session";
+ break;
+ case QNetworkSession::NotAvailable:
+ stateString = "Session is defined but not yet discovered";
+ break;
+ case QNetworkSession::Connecting:
+ stateString = "Session is being established";
+ break;
+ case QNetworkSession::Connected:
+ stateString = "Session is active and can be used for socket operations";
+ cons->currentItem()->setText(1, "Active");
+ break;
+ case QNetworkSession::Closing:
+ stateString = "Session is being shutdown";
+ break;
+ case QNetworkSession::Disconnected:
+ qWarning() << __FUNCTION__;
+ manager->updateConfigurations();
+ stateString = "Session disconnected";
+ cons->currentItem()->setText(1,"Discovered") ;
+ break;
+ case QNetworkSession::Roaming:
+ stateString = "session is roaming from one AP to another";
+ break;
+ };
+ qWarning() << __FUNCTION__ << state << stateString;
+}
+
+QString NMView::stateToString(int state)
+{
+ switch (state) {
+ case QNetworkConfiguration::Undefined:
+ return "Undefined";
+ break;
+ case QNetworkConfiguration::Defined:
+ return "Defined";
+ break;
+ case QNetworkConfiguration::Discovered:
+ return "Discovered";
+ break;
+ case QNetworkConfiguration::Active:
+ return "Active";
+ break;
+ };
+ return "";
+}
+
+void NMView::configurationAdded(const QNetworkConfiguration &config)
+{
+ qWarning() << __FUNCTION__<< config.name() << config.identifier();
+}
+
+QString NMView::typeToString(int type)
+{
+ switch(type) {
+ case QNetworkConfiguration::InternetAccessPoint:
+ return "Internet AccessPoint";
+ break;
+ case QNetworkConfiguration::ServiceNetwork:
+ return "Service Network";
+ break;
+ };
+ return QString();
+}
+
+void NMView::aPPropertiesChanged( QMap<QString,QVariant> map)
+{
+ //QMap<QString, QVariant>::const_iterator iterator = d->values.find(type + QLatin1String("Path"))
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ if( i.key() == "State") {
+ qWarning() << __FUNCTION__ << i.key() << ": " << i.value().toUInt();
+// deviceStateChanged(i.value().toUInt());
+ } else if( i.key() == "ActiveAccessPoint") {
+ qWarning() << __FUNCTION__ << i.key() << ": " << i.value().value<QDBusObjectPath>().path();
+ } else if( i.key() == "Strength")
+ qWarning() << __FUNCTION__ << i.key() << ": " << i.value().toUInt();
+ else
+ qWarning() << __FUNCTION__ << i.key() << ": " << i.value();
+ }
+}
+
+void NMView::networkSessionError(QNetworkSession::SessionError error)
+{
+ QString errorStr;
+ switch(error) {
+ case QNetworkSession::RoamingError:
+ errorStr = "Roaming error";
+ break;
+ case QNetworkSession::SessionAbortedError:
+ errorStr = "Session aborted by user or system";
+ break;
+ default:
+ case QNetworkSession::UnknownSessionError:
+ errorStr = "Unidentified Error";
+ break;
+ };
+
+ QMessageBox::warning(this, tr("NMView"), errorStr, QMessageBox::Ok);
+}
diff --git a/tests/manual/networkmanager/nmview.h b/tests/manual/networkmanager/nmview.h
new file mode 100644
index 0000000000..41ee04f5bf
--- /dev/null
+++ b/tests/manual/networkmanager/nmview.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QWidget>
+#include <QDBusConnection>
+#include <qnetworkconfigmanager.h>
+#include <qnetworksession.h>
+#include <qnetworkconfiguration.h>
+
+#include "ui_dialog.h"
+
+QT_USE_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+class QListWidget;
+class QTreeWidget;
+class QTreeWidgetItem;
+QT_END_NAMESPACE
+
+class NMView : public QDialog, private Ui::Dialog
+{
+ Q_OBJECT
+public:
+ NMView(QDialog* parent = 0);
+ virtual ~NMView();
+
+private:
+ void init();
+ QString stateString;
+
+ QDBusConnection dbc;
+ void printConnectionDetails(const QString&);
+
+ QString deviceStateToString(int state);
+ QString deviceTypeToString(int device);
+ QString securityCapabilitiesToString(int caps);
+ QString deviceModeToString(int mode);
+//QDBusInterface getInterface();
+ QNetworkConfigurationManager *manager;
+ QNetworkSession *sess;
+ QString stateToString(int state);
+ QString typeToString(int type);
+
+private slots:
+ void update();
+ void deactivate();
+ void activate();
+ void getActiveConnections();
+ void updateConnections();
+ void getDevices();
+ // void readConnectionManagerDetails();
+ void getNetworkDevices();
+ void connectionItemActivated( QTreeWidgetItem *, int);
+// void activeItemActivated( QListWidgetItem *);
+ void deviceItemActivated( QTreeWidgetItem *, int);
+ void netconfig();
+ void findAccessPoints();
+
+ void netManagerState(quint32);
+ void readSettings();
+ void updateCompleted();
+ void newConfigurationActivated();
+
+ void stateChanged(QNetworkSession::State);
+ void deviceStateChanged(quint32 state);
+
+ void configurationAdded(const QNetworkConfiguration &config);
+ void aPPropertiesChanged( QMap<QString,QVariant> map);
+ void networkSessionError(QNetworkSession::SessionError);
+
+};
diff --git a/tests/manual/networkmanager/startdlg.cpp b/tests/manual/networkmanager/startdlg.cpp
new file mode 100644
index 0000000000..e34b5e9c05
--- /dev/null
+++ b/tests/manual/networkmanager/startdlg.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 "startdlg.h"
+#include <NetworkManager/NetworkManager.h>
+
+
+StartDialog::StartDialog(QWidget * parent)
+ :QDialog(parent)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ box = new QComboBox();
+ layout->addWidget(box);
+
+ QHBoxLayout* hbox = new QHBoxLayout();
+ QPushButton* start = new QPushButton("Start");
+ connect(start, SIGNAL(clicked()), this, SLOT(accept()));
+ QPushButton* cancel = new QPushButton("Cancel");
+ connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
+
+
+ hbox->addWidget(start);
+ hbox->addWidget(cancel);
+
+ layout->addLayout(hbox);
+
+ QDBusConnection dbc = QDBusConnection::systemBus();
+ if (!dbc.isConnected()) {
+ qWarning() << "Unable to connect to D-Bus:" << dbc.lastError();
+ return;
+ }
+ QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc);
+ if (!iface.isValid()) {
+ qWarning() << "Could not find NetworkManager";
+ return;
+ }
+ QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices");
+ if ( reply.isValid() ) {
+ QList<QDBusObjectPath> list = reply.value();
+ foreach(QDBusObjectPath path, list) {
+ QDBusInterface devIface(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_DEVICE, dbc);
+ if ( devIface.isValid() ) {
+ box->addItem(devIface.property("Interface").toString(), QVariant(path.path()));
+ }
+ }
+ }
+}
+
+QString StartDialog::device() const
+{
+ return dev;
+}
+
+void StartDialog::accept()
+{
+ dev = box->itemData(box->currentIndex(), Qt::UserRole).toString();
+ QDialog::accept();
+}
diff --git a/tests/manual/networkmanager/startdlg.h b/tests/manual/networkmanager/startdlg.h
new file mode 100644
index 0000000000..32c8557c98
--- /dev/null
+++ b/tests/manual/networkmanager/startdlg.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QDialog>
+#include <QtDBus>
+#include <QtGui>
+
+class StartDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ StartDialog(QWidget* parent = 0);
+
+ QString device() const;
+
+public slots:
+ void accept();
+private:
+ QString dev;
+ QComboBox* box;
+};
diff --git a/tools/shared/symbian/epocroot.cpp b/tools/shared/symbian/epocroot.cpp
new file mode 100644
index 0000000000..071477d43a
--- /dev/null
+++ b/tools/shared/symbian/epocroot.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** 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 qmake application 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 <iostream>
+
+#include <QtCore/qdir.h>
+#include <QtCore/qxmlstream.h>
+
+#include "epocroot.h"
+#include "../windows/registry.h"
+
+// Registry key under which the location of the Symbian devices.xml file is
+// stored.
+// Note that, on 64-bit machines, this key is located under the 32-bit
+// compatibility key:
+// HKEY_LOCAL_MACHINE\Software\Wow6432Node
+#define SYMBIAN_SDKS_REG_SUBKEY "Software\\Symbian\\EPOC SDKs\\CommonPath"
+
+#ifdef Q_OS_WIN32
+# define SYMBIAN_SDKS_REG_HANDLE HKEY_LOCAL_MACHINE
+#else
+# define SYMBIAN_SDKS_REG_HANDLE 0
+#endif
+
+// Value which is populated and returned by the epocRoot() function.
+// Stored as a static value in order to avoid unnecessary re-evaluation.
+static QString epocRootValue;
+
+#ifdef QT_BUILD_QMAKE
+std::ostream &operator<<(std::ostream &s, const QString &val) {
+ s << val.toLocal8Bit().data();
+ return s;
+}
+#else
+// Operator implemented in configureapp.cpp
+std::ostream &operator<<(std::ostream &s, const QString &val);
+#endif
+
+QString getDevicesXmlPath()
+ {
+ // Note that the following call will return a null string on platforms other
+ // than Windows. If support is required on other platforms for devices.xml,
+ // an alternative mechanism for retrieving the location of this file will
+ // be required.
+ return readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, SYMBIAN_SDKS_REG_SUBKEY);
+ }
+
+/**
+ * Checks whether epocRootValue points to an existent directory.
+ * If not, epocRootValue is set to an empty string and an error message is printed.
+ */
+void checkEpocRootExists(const QString &source)
+{
+ if (!epocRootValue.isEmpty()) {
+ QDir dir(epocRootValue);
+ if (!dir.exists()) {
+ std::cerr << "Warning: " << source << " is set to an invalid path: " << epocRootValue << std::endl;
+ epocRootValue = QString();
+ }
+ }
+}
+
+/**
+ * Translate path from Windows to Qt format.
+ */
+static void fixEpocRoot(QString &path)
+{
+ path.replace("\\", "/");
+
+ if (path.size() > 1 && path[1] == QChar(':')) {
+ path = path.mid(2);
+ }
+
+ if (!path.size() || path[path.size()-1] != QChar('/')) {
+ path += QChar('/');
+ }
+}
+
+/**
+ * Determine the epoc root for the currently active SDK.
+ */
+QString epocRoot()
+{
+ if (epocRootValue.isEmpty()) {
+ // 1. If environment variable EPOCROOT is set and points to an existent
+ // directory, this is returned.
+ epocRootValue = qgetenv("EPOCROOT");
+ checkEpocRootExists("EPOCROOT");
+
+ if (epocRootValue.isEmpty()) {
+ // 2. The location of devices.xml is specified by a registry key. If this
+ // file exists, it is parsed.
+ QString devicesXmlPath = getDevicesXmlPath();
+ if (devicesXmlPath.isEmpty()) {
+ std::cerr << "Error: Symbian SDK registry key not found" << std::endl;
+ } else {
+ devicesXmlPath += "/devices.xml";
+ QFile devicesFile(devicesXmlPath);
+ if (devicesFile.open(QIODevice::ReadOnly)) {
+
+ // 3. If the EPOCDEVICE environment variable is set and a corresponding
+ // entry is found in devices.xml, and its epocroot value points to an
+ // existent directory, it is returned.
+ // 4. If a device element marked as default is found in devices.xml and its
+ // epocroot value points to an existent directory, this is returned.
+
+ const QString epocDeviceValue = qgetenv("EPOCDEVICE");
+ bool epocDeviceFound = false;
+
+ QXmlStreamReader xml(&devicesFile);
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.isStartElement() && xml.name() == "devices") {
+ if (xml.attributes().value("version") == "1.0") {
+ while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) {
+ xml.readNext();
+ if (xml.isStartElement() && xml.name() == "device") {
+ const bool isDefault = xml.attributes().value("default") == "yes";
+ const QString id = xml.attributes().value("id").toString();
+ const QString name = xml.attributes().value("name").toString();
+ const bool epocDeviceMatch = (id + ":" + name) == epocDeviceValue;
+ epocDeviceFound |= epocDeviceMatch;
+
+ if((epocDeviceValue.isEmpty() && isDefault) || epocDeviceMatch) {
+ // Found a matching device
+ while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) {
+ xml.readNext();
+ if (xml.isStartElement() && xml.name() == "epocroot") {
+ epocRootValue = xml.readElementText();
+ const QString deviceSource = epocDeviceValue.isEmpty()
+ ? "default device"
+ : "EPOCDEVICE (" + epocDeviceValue + ")";
+ checkEpocRootExists(deviceSource);
+ }
+ }
+
+ if (epocRootValue.isEmpty())
+ xml.raiseError("No epocroot element found");
+ }
+ }
+ }
+ } else {
+ xml.raiseError("Invalid 'devices' element version");
+ }
+ }
+ }
+ if (xml.hasError()) {
+ std::cerr << "Error: \"" << xml.errorString() << "\" when parsing devices.xml" << std::endl;
+ } else {
+ if (epocRootValue.isEmpty()) {
+ if (!epocDeviceValue.isEmpty()) {
+ if (epocDeviceFound) {
+ std::cerr << "Error: missing or invalid epocroot attribute "
+ << "in device '" << epocDeviceValue << "'";
+ } else {
+ std::cerr << "Error: no device matching EPOCDEVICE ("
+ << epocDeviceValue << ")";
+ }
+ } else {
+ if (epocDeviceFound) {
+ std::cerr << "Error: missing or invalid epocroot attribute "
+ << "in default device";
+ } else {
+ std::cerr << "Error: no default device";
+ }
+ }
+ std::cerr << " found in devices.xml file." << std::endl;
+ }
+ }
+ } else {
+ std::cerr << "Error: could not open file " << devicesXmlPath << std::endl;
+ }
+ }
+ }
+
+ if (epocRootValue.isEmpty()) {
+ // 5. An empty string is returned.
+ std::cerr << "Error: failed to find epoc root" << std::endl
+ << "Either" << std::endl
+ << " 1. Set EPOCROOT environment variable to a valid value" << std::endl
+ << " or 2. Ensure that the HKEY_LOCAL_MACHINE\\" SYMBIAN_SDKS_REG_SUBKEY
+ " registry key is set, and then" << std::endl
+ << " a. Set EPOCDEVICE environment variable to a valid device" << std::endl
+ << " or b. Specify a default device in the devices.xml file." << std::endl;
+ } else {
+ fixEpocRoot(epocRootValue);
+ }
+ }
+
+ return epocRootValue;
+}
+
diff --git a/tools/shared/symbian/epocroot.h b/tools/shared/symbian/epocroot.h
new file mode 100644
index 0000000000..9846485aab
--- /dev/null
+++ b/tools/shared/symbian/epocroot.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 qmake application 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 SYMBIAN_EPOCROOT_H
+#define SYMBIAN_EPOCROOT_H
+
+#include <QtCore/qstring.h>
+
+/**
+ * Determine the epoc root for the currently active SDK.
+ *
+ * The algorithm used is as follows:
+ * 1. If environment variable EPOCROOT is set and points to an existent
+ * directory, this is returned.
+ * 2. The location of devices.xml is specified by a registry key. If this
+ * file exists, it is parsed.
+ * 3. If the EPOCDEVICE environment variable is set and a corresponding
+ * entry is found in devices.xml, and its epocroot value points to an
+ * existent directory, it is returned.
+ * 4. If a device element marked as default is found in devices.xml and its
+ * epocroot value points to an existent directory, this is returned.
+ * 5. An empty string is returned.
+ *
+ * Any return value other than the empty string therefore is guaranteed to
+ * point to an existent directory.
+ */
+QString epocRoot();
+
+#endif // EPOCROOT_H
diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp
new file mode 100644
index 0000000000..d342d781ae
--- /dev/null
+++ b/tools/shared/windows/registry.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** 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 qmake application 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 <QtCore/qstringlist.h>
+#include "registry.h"
+
+/*!
+ Returns the path part of a registry key.
+ e.g.
+ For a key
+ "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"
+ it returns
+ "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\"
+*/
+static QString keyPath(const QString &rKey)
+{
+ int idx = rKey.lastIndexOf(QLatin1Char('\\'));
+ if (idx == -1)
+ return QString();
+ return rKey.left(idx + 1);
+}
+
+/*!
+ Returns the name part of a registry key.
+ e.g.
+ For a key
+ "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"
+ it returns
+ "ProductDir"
+*/
+static QString keyName(const QString &rKey)
+{
+ int idx = rKey.lastIndexOf(QLatin1Char('\\'));
+ if (idx == -1)
+ return rKey;
+
+ QString res(rKey.mid(idx + 1));
+ if (res == "Default" || res == ".")
+ res = "";
+ return res;
+}
+
+QString readRegistryKey(HKEY parentHandle, const QString &rSubkey)
+{
+ QString result;
+
+#ifdef Q_OS_WIN32
+ QString rSubkeyName = keyName(rSubkey);
+ QString rSubkeyPath = keyPath(rSubkey);
+
+ HKEY handle = 0;
+ LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle);
+
+ if (res != ERROR_SUCCESS)
+ return QString();
+
+ // get the size and type of the value
+ DWORD dataType;
+ DWORD dataSize;
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
+ if (res != ERROR_SUCCESS) {
+ RegCloseKey(handle);
+ return QString();
+ }
+
+ // get the value
+ QByteArray data(dataSize, 0);
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0,
+ reinterpret_cast<unsigned char*>(data.data()), &dataSize);
+ if (res != ERROR_SUCCESS) {
+ RegCloseKey(handle);
+ return QString();
+ }
+
+ switch (dataType) {
+ case REG_EXPAND_SZ:
+ case REG_SZ: {
+ result = QString::fromWCharArray(((const wchar_t *)data.constData()));
+ break;
+ }
+
+ case REG_MULTI_SZ: {
+ QStringList l;
+ int i = 0;
+ for (;;) {
+ QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
+ i += s.length() + 1;
+
+ if (s.isEmpty())
+ break;
+ l.append(s);
+ }
+ result = l.join(", ");
+ break;
+ }
+
+ case REG_NONE:
+ case REG_BINARY: {
+ result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
+ break;
+ }
+
+ case REG_DWORD_BIG_ENDIAN:
+ case REG_DWORD: {
+ Q_ASSERT(data.size() == sizeof(int));
+ int i;
+ memcpy((char*)&i, data.constData(), sizeof(int));
+ result = QString::number(i);
+ break;
+ }
+
+ default:
+ qWarning("QSettings: unknown data %d type in windows registry", dataType);
+ break;
+ }
+
+ RegCloseKey(handle);
+#endif
+
+ return result;
+}
+
+
diff --git a/tools/shared/windows/registry.h b/tools/shared/windows/registry.h
new file mode 100644
index 0000000000..3896527cb2
--- /dev/null
+++ b/tools/shared/windows/registry.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** 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 qmake application 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 WINDOWS_REGISTRY_H
+#define WINDOWS_REGISTRY_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN32
+ #include <QtCore/qt_windows.h>
+#else
+ typedef void* HKEY;
+#endif
+
+#include <QtCore/qstring.h>
+
+/**
+ * Read a value from the Windows registry.
+ *
+ * If the key is not found, or the registry cannot be accessed (for example
+ * if this code is compiled for a platform other than Windows), a null
+ * string is returned.
+ */
+QString readRegistryKey(HKEY parentHandle, const QString &rSubkey);
+
+#endif // WINDOWS_REGISTRY_H