| 1 | /****************************************************************************
 | 
|---|
| 2 | **
 | 
|---|
| 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 | 
|---|
| 4 | ** All rights reserved.
 | 
|---|
| 5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
 | 
|---|
| 6 | **
 | 
|---|
| 7 | ** This file is part of the QtNetwork module of the Qt Toolkit.
 | 
|---|
| 8 | **
 | 
|---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$
 | 
|---|
| 10 | ** Commercial Usage
 | 
|---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
 | 
|---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
 | 
|---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in
 | 
|---|
| 14 | ** a written agreement between you and Nokia.
 | 
|---|
| 15 | **
 | 
|---|
| 16 | ** GNU Lesser General Public License Usage
 | 
|---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
 | 
|---|
| 18 | ** General Public License version 2.1 as published by the Free Software
 | 
|---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
 | 
|---|
| 20 | ** packaging of this file.  Please review the following information to
 | 
|---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
 | 
|---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
|---|
| 23 | **
 | 
|---|
| 24 | ** In addition, as a special exception, Nokia gives you certain additional
 | 
|---|
| 25 | ** rights.  These rights are described in the Nokia Qt LGPL Exception
 | 
|---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 | 
|---|
| 27 | **
 | 
|---|
| 28 | ** GNU General Public License Usage
 | 
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
 | 
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software
 | 
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
 | 
|---|
| 32 | ** packaging of this file.  Please review the following information to
 | 
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
 | 
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
 | 
|---|
| 35 | **
 | 
|---|
| 36 | ** If you have questions regarding the use of this file, please contact
 | 
|---|
| 37 | ** Nokia at qt-info@nokia.com.
 | 
|---|
| 38 | ** $QT_END_LICENSE$
 | 
|---|
| 39 | **
 | 
|---|
| 40 | ****************************************************************************/
 | 
|---|
| 41 | 
 | 
|---|
| 42 | #include <QEventLoop>
 | 
|---|
| 43 | #include <QTimer>
 | 
|---|
| 44 | 
 | 
|---|
| 45 | #include "qnetworksession.h"
 | 
|---|
| 46 | #include "qbearerengine_p.h"
 | 
|---|
| 47 | #include "qnetworkconfigmanager_p.h"
 | 
|---|
| 48 | #include "qnetworksession_p.h"
 | 
|---|
| 49 | 
 | 
|---|
| 50 | #ifndef QT_NO_BEARERMANAGEMENT
 | 
|---|
| 51 | 
 | 
|---|
| 52 | QT_BEGIN_NAMESPACE
 | 
|---|
| 53 | 
 | 
|---|
| 54 | /*!
 | 
|---|
| 55 |     \class QNetworkSession
 | 
|---|
| 56 | 
 | 
|---|
| 57 |     \brief The QNetworkSession class provides control over the system's access points
 | 
|---|
| 58 |     and enables session management for cases when multiple clients access the same access point.
 | 
|---|
| 59 | 
 | 
|---|
| 60 |     \since 4.7
 | 
|---|
| 61 | 
 | 
|---|
| 62 |     \inmodule QtNetwork
 | 
|---|
| 63 |     \ingroup network
 | 
|---|
| 64 | 
 | 
|---|
| 65 |     A QNetworkSession enables control over the system's network interfaces. The session's configuration
 | 
|---|
| 66 |     parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the 
 | 
|---|
| 67 |     type of the session (single access point or service network) a session may be linked to one or more
 | 
|---|
| 68 |     network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions 
 | 
|---|
| 69 |     a developer can start and stop the systems network interfaces. If the configuration represents 
 | 
|---|
| 70 |     multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported.
 | 
|---|
| 71 | 
 | 
|---|
| 72 |     QNetworkSession supports session management within the same process and depending on the platform's 
 | 
|---|
| 73 |     capabilities may support out-of-process sessions. If the same 
 | 
|---|
| 74 |     network configuration is used by multiple open sessions the underlying network interface is only terminated once
 | 
|---|
| 75 |     the last session has been closed.
 | 
|---|
| 76 | 
 | 
|---|
| 77 |     \section1 Roaming
 | 
|---|
| 78 | 
 | 
|---|
| 79 |     Applications may connect to the preferredConfigurationChanged() signal in order to 
 | 
|---|
| 80 |     receive notifications when a more suitable access point becomes available. 
 | 
|---|
| 81 |     In response to this signal the application must either initiate the roaming via migrate()
 | 
|---|
| 82 |     or ignore() the new access point. Once the session has roamed the 
 | 
|---|
| 83 |     newConfigurationActivated() signal is emitted. The application may now test the 
 | 
|---|
| 84 |     carrier and must either accept() or reject() it. The session will return to the previous
 | 
|---|
| 85 |     access point if the roaming was rejected. The subsequent state diagram depicts the required
 | 
|---|
| 86 |     state transitions.
 | 
|---|
| 87 |     
 | 
|---|
| 88 |     \image roaming-states.png
 | 
|---|
| 89 | 
 | 
|---|
| 90 |     Some platforms may distinguish forced roaming and application level roaming (ALR). 
 | 
|---|
| 91 |     ALR implies that the application controls (via migrate(), ignore(), accept() and reject()) 
 | 
|---|
| 92 |     whether a network session can roam from one access point to the next. Such control is useful
 | 
|---|
| 93 |     if the application maintains stateful socket connections and wants to control the transition from
 | 
|---|
| 94 |     one interface to the next. Forced roaming implies that the system automatically roams to the next network without 
 | 
|---|
| 95 |     consulting the application. This has the advantage that the application can make use of roaming features
 | 
|---|
| 96 |     without actually being aware of it. It is expected that the application detects that the underlying 
 | 
|---|
| 97 |     socket is broken and automatically reconnects via the new network link.
 | 
|---|
| 98 | 
 | 
|---|
| 99 |     If the platform supports both modes of roaming, an application indicates its preference
 | 
|---|
| 100 |     by connecting to the preferredConfigurationChanged() signal. Connecting to this signal means that
 | 
|---|
| 101 |     the application wants to take control over the roaming behavior and therefore implies application
 | 
|---|
| 102 |     level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming
 | 
|---|
| 103 |     is used. If forced roaming is not supported the network session will not roam by default.
 | 
|---|
| 104 | 
 | 
|---|
| 105 |     Some applications may want to suppress any form of roaming altogether. Possible use cases may be 
 | 
|---|
| 106 |     high priority downloads or remote services which cannot handle a roaming enabled client. Clients
 | 
|---|
| 107 |     can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each
 | 
|---|
| 108 |     signal emission with ignore().
 | 
|---|
| 109 | 
 | 
|---|
| 110 |     \sa QNetworkConfiguration, QNetworkConfigurationManager
 | 
|---|
| 111 | */
 | 
|---|
| 112 | 
 | 
|---|
| 113 | /*!
 | 
|---|
| 114 |     \enum QNetworkSession::State
 | 
|---|
| 115 | 
 | 
|---|
| 116 |     This enum describes the connectivity state of the session. If the session is based on a
 | 
|---|
| 117 |     single access point configuration the state of the session is the same as the state of the
 | 
|---|
| 118 |     associated network interface.
 | 
|---|
| 119 | 
 | 
|---|
| 120 |     \value Invalid          The session is invalid due to an invalid configuration. This may 
 | 
|---|
| 121 |                             happen due to a removed access point or a configuration that was 
 | 
|---|
| 122 |                             invalid to begin with.
 | 
|---|
| 123 |     \value NotAvailable     The session is based on a defined but not yet discovered QNetworkConfiguration
 | 
|---|
| 124 |                             (see \l QNetworkConfiguration::StateFlag).
 | 
|---|
| 125 |     \value Connecting       The network session is being established.
 | 
|---|
| 126 |     \value Connected        The network session is connected. If the current process wishes to use this session
 | 
|---|
| 127 |                             it has to register its interest by calling open(). A network session 
 | 
|---|
| 128 |                             is considered to be ready for socket operations if it isOpen() and connected.
 | 
|---|
| 129 |     \value Closing          The network session is in the process of being shut down.
 | 
|---|
| 130 |     \value Disconnected     The network session is not connected. The associated QNetworkConfiguration
 | 
|---|
| 131 |                             has the state QNetworkConfiguration::Discovered.
 | 
|---|
| 132 |     \value Roaming          The network session is roaming from one access point to another 
 | 
|---|
| 133 |                             access point.
 | 
|---|
| 134 | */
 | 
|---|
| 135 | 
 | 
|---|
| 136 | /*!
 | 
|---|
| 137 |     \enum QNetworkSession::SessionError
 | 
|---|
| 138 | 
 | 
|---|
| 139 |     This enum describes the session errors that can occur.
 | 
|---|
| 140 | 
 | 
|---|
| 141 |     \value UnknownSessionError          An unidentified error occurred.
 | 
|---|
| 142 |     \value SessionAbortedError          The session was aborted by the user or system.
 | 
|---|
| 143 |     \value RoamingError                 The session cannot roam to a new configuration.
 | 
|---|
| 144 |     \value OperationNotSupportedError   The operation is not supported for current configuration.
 | 
|---|
| 145 |     \value InvalidConfigurationError    The operation cannot currently be performed for the
 | 
|---|
| 146 |                                         current configuration.
 | 
|---|
| 147 | */
 | 
|---|
| 148 | 
 | 
|---|
| 149 | /*!
 | 
|---|
| 150 |     \fn void QNetworkSession::stateChanged(QNetworkSession::State state)
 | 
|---|
| 151 | 
 | 
|---|
| 152 |     This signal is emitted whenever the state of the network session changes.
 | 
|---|
| 153 |     The \a state parameter is the new state.
 | 
|---|
| 154 | 
 | 
|---|
| 155 |     \sa state()
 | 
|---|
| 156 | */
 | 
|---|
| 157 | 
 | 
|---|
| 158 | /*!
 | 
|---|
| 159 |     \fn void QNetworkSession::error(QNetworkSession::SessionError error)
 | 
|---|
| 160 | 
 | 
|---|
| 161 |     This signal is emitted after an error occurred. The \a error parameter
 | 
|---|
| 162 |     describes the error that occurred.
 | 
|---|
| 163 | 
 | 
|---|
| 164 |     \sa error(), errorString()
 | 
|---|
| 165 | */
 | 
|---|
| 166 | 
 | 
|---|
| 167 | /*!
 | 
|---|
| 168 |     \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless)
 | 
|---|
| 169 | 
 | 
|---|
| 170 |     This signal is emitted when the preferred configuration/access point for the
 | 
|---|
| 171 |     session changes. Only sessions which are based on service network configurations
 | 
|---|
| 172 |     may emit this signal. \a config can be used to determine access point specific
 | 
|---|
| 173 |     details such as proxy settings and \a isSeamless indicates whether roaming will
 | 
|---|
| 174 |     break the sessions IP address.
 | 
|---|
| 175 | 
 | 
|---|
| 176 |     As a consequence to this signal the application must either start the roaming process
 | 
|---|
| 177 |     by calling migrate() or choose to ignore() the new access point.
 | 
|---|
| 178 | 
 | 
|---|
| 179 |     If the roaming process is non-seamless the IP address will change which means that
 | 
|---|
| 180 |     a socket becomes invalid. However seamless mobility can ensure that the local IP address
 | 
|---|
| 181 |     does not change. This is achieved by using a virtual IP address which is bound to the actual
 | 
|---|
| 182 |     link address. During the roaming process the virtual address is attached to the new link 
 | 
|---|
| 183 |     address.
 | 
|---|
| 184 | 
 | 
|---|
| 185 |     Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR). 
 | 
|---|
| 186 |     Forced roaming implies that the platform may simply roam to a new configuration without 
 | 
|---|
| 187 |     consulting applications. It is up to the application to detect the link layer loss and reestablish
 | 
|---|
| 188 |     its sockets. In contrast ALR provides the opportunity to prevent the system from roaming. 
 | 
|---|
| 189 |     If this session is based on a configuration that supports roaming the application can choose
 | 
|---|
| 190 |     whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal 
 | 
|---|
| 191 |     connection remains the session remains registered as a roaming stakeholder; otherwise roaming will 
 | 
|---|
| 192 |     be enforced by the platform.
 | 
|---|
| 193 | 
 | 
|---|
| 194 |     \sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable()
 | 
|---|
| 195 | */
 | 
|---|
| 196 | 
 | 
|---|
| 197 | /*!
 | 
|---|
| 198 |     \fn void QNetworkSession::newConfigurationActivated()
 | 
|---|
| 199 | 
 | 
|---|
| 200 |     This signal is emitted once the session has roamed to the new access point.
 | 
|---|
| 201 |     The application may reopen its socket and test the suitability of the new network link.
 | 
|---|
| 202 |     Subsequently it must either accept() or reject() the new access point. 
 | 
|---|
| 203 | 
 | 
|---|
| 204 |     \sa accept(), reject()
 | 
|---|
| 205 | */
 | 
|---|
| 206 | 
 | 
|---|
| 207 | /*!
 | 
|---|
| 208 |     \fn void QNetworkSession::opened()
 | 
|---|
| 209 | 
 | 
|---|
| 210 |     This signal is emitted when the network session has been opened. 
 | 
|---|
| 211 |     
 | 
|---|
| 212 |     The underlying network interface will not be shut down as long as the session remains open.
 | 
|---|
| 213 |     Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}.
 | 
|---|
| 214 | */
 | 
|---|
| 215 | 
 | 
|---|
| 216 | /*!
 | 
|---|
| 217 |     \fn void QNetworkSession::closed()
 | 
|---|
| 218 | 
 | 
|---|
| 219 |     This signal is emitted when the network session has been closed.
 | 
|---|
| 220 | */
 | 
|---|
| 221 | 
 | 
|---|
| 222 | /*!
 | 
|---|
| 223 |     Constructs a session based on \a connectionConfig with the given \a parent.
 | 
|---|
| 224 | 
 | 
|---|
| 225 |     \sa QNetworkConfiguration
 | 
|---|
| 226 | */
 | 
|---|
| 227 | QNetworkSession::QNetworkSession(const QNetworkConfiguration& connectionConfig, QObject* parent)
 | 
|---|
| 228 | :   QObject(parent), d(0)
 | 
|---|
| 229 | {
 | 
|---|
| 230 |     // invalid configuration
 | 
|---|
| 231 |     if (connectionConfig.identifier().isNull())
 | 
|---|
| 232 |         return;
 | 
|---|
| 233 | 
 | 
|---|
| 234 |     foreach (QBearerEngine *engine, qNetworkConfigurationManagerPrivate()->engines()) {
 | 
|---|
| 235 |         if (engine->hasIdentifier(connectionConfig.identifier())) {
 | 
|---|
| 236 |             d = engine->createSessionBackend();
 | 
|---|
| 237 |             d->q = this;
 | 
|---|
| 238 |             d->publicConfig = connectionConfig;
 | 
|---|
| 239 |             d->syncStateWithInterface();
 | 
|---|
| 240 |             connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened()));
 | 
|---|
| 241 |             connect(d, SIGNAL(error(QNetworkSession::SessionError)),
 | 
|---|
| 242 |                     this, SIGNAL(error(QNetworkSession::SessionError)));
 | 
|---|
| 243 |             connect(d, SIGNAL(stateChanged(QNetworkSession::State)),
 | 
|---|
| 244 |                     this, SIGNAL(stateChanged(QNetworkSession::State)));
 | 
|---|
| 245 |             connect(d, SIGNAL(closed()), this, SIGNAL(closed()));
 | 
|---|
| 246 |             connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)),
 | 
|---|
| 247 |                     this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)));
 | 
|---|
| 248 |             connect(d, SIGNAL(newConfigurationActivated()),
 | 
|---|
| 249 |                     this, SIGNAL(newConfigurationActivated()));
 | 
|---|
| 250 |             break;
 | 
|---|
| 251 |         }
 | 
|---|
| 252 |     }
 | 
|---|
| 253 | 
 | 
|---|
| 254 |     qRegisterMetaType<QNetworkSession::State>();
 | 
|---|
| 255 |     qRegisterMetaType<QNetworkSession::SessionError>();
 | 
|---|
| 256 | }
 | 
|---|
| 257 | 
 | 
|---|
| 258 | /*!
 | 
|---|
| 259 |     Frees the resources associated with the QNetworkSession object.
 | 
|---|
| 260 | */
 | 
|---|
| 261 | QNetworkSession::~QNetworkSession()
 | 
|---|
| 262 | {
 | 
|---|
| 263 |     delete d;
 | 
|---|
| 264 | }
 | 
|---|
| 265 | 
 | 
|---|
| 266 | /*!
 | 
|---|
| 267 |     Creates an open session which increases the session counter on the underlying network interface.
 | 
|---|
| 268 |     The system will not terminate a network interface until the session reference counter reaches zero.
 | 
|---|
| 269 |     Therefore an open session allows an application to register its use of the interface.
 | 
|---|
| 270 | 
 | 
|---|
| 271 |     As a result of calling open() the interface will be started if it is not connected/up yet. 
 | 
|---|
| 272 |     Some platforms may not provide support for out-of-process sessions. On such platforms the session
 | 
|---|
| 273 |     counter ignores any sessions held by another process. The platform capabilities can be 
 | 
|---|
| 274 |     detected via QNetworkConfigurationManager::capabilities().
 | 
|---|
| 275 | 
 | 
|---|
| 276 |     Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired 
 | 
|---|
| 277 |     by connecting to the stateChanged(), opened() or error() signals.
 | 
|---|
| 278 | 
 | 
|---|
| 279 |     It is not a requirement to open a session in order to monitor the underlying network interface.
 | 
|---|
| 280 | 
 | 
|---|
| 281 |     \sa close(), stop(), isOpen()
 | 
|---|
| 282 | */
 | 
|---|
| 283 | void QNetworkSession::open()
 | 
|---|
| 284 | {
 | 
|---|
| 285 |     if (d)
 | 
|---|
| 286 |         d->open();
 | 
|---|
| 287 |     else
 | 
|---|
| 288 |         emit error(InvalidConfigurationError);
 | 
|---|
| 289 | }
 | 
|---|
| 290 | 
 | 
|---|
| 291 | /*!
 | 
|---|
| 292 |     Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this
 | 
|---|
| 293 |     function returns true; otherwise it returns false. In the case where it returns false, you can call error()
 | 
|---|
| 294 |     to determine the cause of the error.
 | 
|---|
| 295 | 
 | 
|---|
| 296 |     The following example waits up to one second for the session to be opened:
 | 
|---|
| 297 | 
 | 
|---|
| 298 |     \code
 | 
|---|
| 299 |         session->open();
 | 
|---|
| 300 |         if (session->waitForOpened(1000))
 | 
|---|
| 301 |             qDebug("Open!");
 | 
|---|
| 302 |     \endcode
 | 
|---|
| 303 | 
 | 
|---|
| 304 |     If \a msecs is -1, this function will not time out.
 | 
|---|
| 305 | 
 | 
|---|
| 306 |     \sa open(), error()
 | 
|---|
| 307 | */
 | 
|---|
| 308 | bool QNetworkSession::waitForOpened(int msecs)
 | 
|---|
| 309 | {
 | 
|---|
| 310 |     if (!d)
 | 
|---|
| 311 |         return false;
 | 
|---|
| 312 | 
 | 
|---|
| 313 |     if (d->isOpen)
 | 
|---|
| 314 |         return true;
 | 
|---|
| 315 | 
 | 
|---|
| 316 |     if (!(d->state == Connecting || d->state == Connected)) {
 | 
|---|
| 317 |         return false;
 | 
|---|
| 318 |     }
 | 
|---|
| 319 | 
 | 
|---|
| 320 |     QEventLoop* loop = new QEventLoop(this);
 | 
|---|
| 321 |     QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()),
 | 
|---|
| 322 |                      loop, SLOT(quit()));
 | 
|---|
| 323 |     QObject::connect(this, SIGNAL(error(QNetworkSession::SessionError)),
 | 
|---|
| 324 |                      loop, SLOT(quit()));
 | 
|---|
| 325 | 
 | 
|---|
| 326 |     //final call
 | 
|---|
| 327 |     if (msecs>=0)
 | 
|---|
| 328 |         QTimer::singleShot(msecs, loop, SLOT(quit()));
 | 
|---|
| 329 | 
 | 
|---|
| 330 |     loop->exec();
 | 
|---|
| 331 |     loop->disconnect();
 | 
|---|
| 332 |     loop->deleteLater();
 | 
|---|
| 333 | 
 | 
|---|
| 334 |     return d->isOpen;
 | 
|---|
| 335 | }
 | 
|---|
| 336 | 
 | 
|---|
| 337 | /*!
 | 
|---|
| 338 |     Decreases the session counter on the associated network configuration. If the session counter reaches zero
 | 
|---|
| 339 |     the active network interface is shut down. This also means that state() will only change from \l Connected to
 | 
|---|
| 340 |     \l Disconnected if the current session was the last open session.
 | 
|---|
| 341 | 
 | 
|---|
| 342 |     If the platform does not support out-of-process sessions calling this function does not stop the
 | 
|---|
| 343 |     interface. In this case \l{stop()} has to be used to force a shut down. 
 | 
|---|
| 344 |     The platform capabilities can be detected via QNetworkConfigurationManager::capabilities().
 | 
|---|
| 345 | 
 | 
|---|
| 346 |     Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired 
 | 
|---|
| 347 |     by connecting to the stateChanged(), opened() or error() signals.
 | 
|---|
| 348 | 
 | 
|---|
| 349 |     \sa open(), stop(), isOpen()
 | 
|---|
| 350 | */
 | 
|---|
| 351 | void QNetworkSession::close()
 | 
|---|
| 352 | {
 | 
|---|
| 353 |     if (d)
 | 
|---|
| 354 |         d->close();
 | 
|---|
| 355 | }
 | 
|---|
| 356 | 
 | 
|---|
| 357 | /*!
 | 
|---|
| 358 |     Invalidates all open sessions against the network interface and therefore stops the 
 | 
|---|
| 359 |     underlying network interface. This function always changes the session's state() flag to
 | 
|---|
| 360 |     \l Disconnected.
 | 
|---|
| 361 | 
 | 
|---|
| 362 |     On Symbian platform, a 'NetworkControl' capability is required for
 | 
|---|
| 363 |     full interface-level stop (without the capability, only the current session is stopped).
 | 
|---|
| 364 | 
 | 
|---|
| 365 |     \sa open(), close()
 | 
|---|
| 366 | */
 | 
|---|
| 367 | void QNetworkSession::stop()
 | 
|---|
| 368 | {
 | 
|---|
| 369 |     if (d)
 | 
|---|
| 370 |         d->stop();
 | 
|---|
| 371 | }
 | 
|---|
| 372 | 
 | 
|---|
| 373 | /*!
 | 
|---|
| 374 |     Returns the QNetworkConfiguration that this network session object is based on.
 | 
|---|
| 375 | 
 | 
|---|
| 376 |     \sa QNetworkConfiguration
 | 
|---|
| 377 | */
 | 
|---|
| 378 | QNetworkConfiguration QNetworkSession::configuration() const
 | 
|---|
| 379 | {
 | 
|---|
| 380 |     return d ? d->publicConfig : QNetworkConfiguration();
 | 
|---|
| 381 | }
 | 
|---|
| 382 | 
 | 
|---|
| 383 | #ifndef QT_NO_NETWORKINTERFACE
 | 
|---|
| 384 | /*!
 | 
|---|
| 385 |     Returns the network interface that is used by this session.
 | 
|---|
| 386 | 
 | 
|---|
| 387 |     This function only returns a valid QNetworkInterface when this session is \l Connected.
 | 
|---|
| 388 | 
 | 
|---|
| 389 |     The returned interface may change as a result of a roaming process.
 | 
|---|
| 390 | 
 | 
|---|
| 391 |     Note: this function does not work in Symbian emulator due to the way the
 | 
|---|
| 392 |     connectivity is emulated on Windows.
 | 
|---|
| 393 | 
 | 
|---|
| 394 |     \sa state()
 | 
|---|
| 395 | */
 | 
|---|
| 396 | QNetworkInterface QNetworkSession::interface() const
 | 
|---|
| 397 | {
 | 
|---|
| 398 |     return d ? d->currentInterface() : QNetworkInterface();
 | 
|---|
| 399 | }
 | 
|---|
| 400 | #endif
 | 
|---|
| 401 | 
 | 
|---|
| 402 | /*!
 | 
|---|
| 403 |     Returns true if this session is open. If the number of all open sessions is greater than
 | 
|---|
| 404 |     zero the underlying network interface will remain connected/up.
 | 
|---|
| 405 | 
 | 
|---|
| 406 |     The session can be controlled via open() and close().
 | 
|---|
| 407 | */
 | 
|---|
| 408 | bool QNetworkSession::isOpen() const
 | 
|---|
| 409 | {
 | 
|---|
| 410 |     return d ? d->isOpen : false;
 | 
|---|
| 411 | }
 | 
|---|
| 412 | 
 | 
|---|
| 413 | /*!
 | 
|---|
| 414 |     Returns the state of the session. 
 | 
|---|
| 415 |     
 | 
|---|
| 416 |     If the session is based on a single access point configuration the state of the 
 | 
|---|
| 417 |     session is the same as the state of the associated network interface. Therefore
 | 
|---|
| 418 |     a network session object can be used to monitor network interfaces. 
 | 
|---|
| 419 | 
 | 
|---|
| 420 |     A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children
 | 
|---|
| 421 |     and therefore returns the \l Connected state if at least one of the service network's 
 | 
|---|
| 422 |     \l {QNetworkConfiguration::children()}{children()} configurations is active. 
 | 
|---|
| 423 | 
 | 
|---|
| 424 |     Note that it is not required to hold an open session in order to obtain the network interface state.
 | 
|---|
| 425 |     A connected but closed session may be used to monitor network interfaces whereas an open and connected
 | 
|---|
| 426 |     session object may prevent the network interface from being shut down.
 | 
|---|
| 427 | 
 | 
|---|
| 428 |     \sa error(), stateChanged()
 | 
|---|
| 429 | */
 | 
|---|
| 430 | QNetworkSession::State QNetworkSession::state() const
 | 
|---|
| 431 | {
 | 
|---|
| 432 |     return d ? d->state : QNetworkSession::Invalid;
 | 
|---|
| 433 | }
 | 
|---|
| 434 | 
 | 
|---|
| 435 | /*!
 | 
|---|
| 436 |     Returns the type of error that last occurred.
 | 
|---|
| 437 | 
 | 
|---|
| 438 |     \sa state(), errorString()
 | 
|---|
| 439 | */
 | 
|---|
| 440 | QNetworkSession::SessionError QNetworkSession::error() const
 | 
|---|
| 441 | {
 | 
|---|
| 442 |     return d ? d->error() : InvalidConfigurationError;
 | 
|---|
| 443 | }
 | 
|---|
| 444 | 
 | 
|---|
| 445 | /*!
 | 
|---|
| 446 |     Returns a human-readable description of the last device error that 
 | 
|---|
| 447 |     occurred.
 | 
|---|
| 448 | 
 | 
|---|
| 449 |     \sa error()
 | 
|---|
| 450 | */
 | 
|---|
| 451 | QString QNetworkSession::errorString() const
 | 
|---|
| 452 | {
 | 
|---|
| 453 |     return d ? d->errorString() : tr("Invalid configuration.");
 | 
|---|
| 454 | }
 | 
|---|
| 455 | 
 | 
|---|
| 456 | /*!
 | 
|---|
| 457 |     Returns the value for property \a key.
 | 
|---|
| 458 | 
 | 
|---|
| 459 |     A network session can have properties attached which may describe the session in more details.
 | 
|---|
| 460 |     This function can be used to gain access to those properties.
 | 
|---|
| 461 | 
 | 
|---|
| 462 |     The following property keys are guaranteed to be specified on all platforms:
 | 
|---|
| 463 | 
 | 
|---|
| 464 |     \table
 | 
|---|
| 465 |         \header
 | 
|---|
| 466 |             \o Key \o Description
 | 
|---|
| 467 |         \row
 | 
|---|
| 468 |             \o ActiveConfiguration
 | 
|---|
| 469 |             \o If the session \l isOpen() this property returns the identifier of the
 | 
|---|
| 470 |             QNetworkConfiguration that is used by this session; otherwise an empty string.
 | 
|---|
| 471 | 
 | 
|---|
| 472 |             The main purpose of this key is to determine which Internet access point is used
 | 
|---|
| 473 |             if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}. 
 | 
|---|
| 474 |             The following code snippet highlights the difference:
 | 
|---|
| 475 |             \code
 | 
|---|
| 476 |                     QNetworkConfigurationManager mgr;
 | 
|---|
| 477 |                     QNetworkConfiguration ap = mgr.defaultConfiguration();
 | 
|---|
| 478 |                     QNetworkSession* session = new QNetworkSession(ap);
 | 
|---|
| 479 |                     ... //code activates session
 | 
|---|
| 480 | 
 | 
|---|
| 481 |                     QString ident = session->sessionProperty("ActiveConfiguration").toString();
 | 
|---|
| 482 |                     if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) {
 | 
|---|
| 483 |                         Q_ASSERT( ap.identifier() != ident );
 | 
|---|
| 484 |                         Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) );
 | 
|---|
| 485 |                     } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) {
 | 
|---|
| 486 |                         Q_ASSERT( ap.identifier() == ident );
 | 
|---|
| 487 |                     }
 | 
|---|
| 488 |                 \endcode
 | 
|---|
| 489 |         \row
 | 
|---|
| 490 |             \o UserChoiceConfiguration
 | 
|---|
| 491 |             \o If the session \l isOpen() and is bound to a QNetworkConfiguration of type
 | 
|---|
| 492 |             UserChoice, this property returns the identifier of the QNetworkConfiguration that the
 | 
|---|
| 493 |             configuration resolved to when \l open() was called; otherwise an empty string.
 | 
|---|
| 494 | 
 | 
|---|
| 495 |             The purpose of this key is to determine the real QNetworkConfiguration that the
 | 
|---|
| 496 |             session is using. This key is different from \e ActiveConfiguration in that
 | 
|---|
| 497 |             this key may return an identifier for either a
 | 
|---|
| 498 |             \l {QNetworkConfiguration::ServiceNetwork}{service network} or a
 | 
|---|
| 499 |             \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations,
 | 
|---|
| 500 |             whereas \e ActiveConfiguration always returns identifiers to 
 | 
|---|
| 501 |             \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations.
 | 
|---|
| 502 |         \row
 | 
|---|
| 503 |             \o ConnectInBackground
 | 
|---|
| 504 |             \o Setting this property to \e true before calling \l open() implies that the connection attempt
 | 
|---|
| 505 |             is made but if no connection can be established, the user is not connsulted and asked to select
 | 
|---|
| 506 |             a suitable connection. This property is not set by default and support for it depends on the platform.
 | 
|---|
| 507 | 
 | 
|---|
| 508 |         \row
 | 
|---|
| 509 |             \o AutoCloseSessionTimeout
 | 
|---|
| 510 |             \o If the session requires polling to keep its state up to date, this property holds
 | 
|---|
| 511 |                the timeout in milliseconds before the session will automatically close. If the
 | 
|---|
| 512 |                value of this property is -1 the session will not automatically close. This property
 | 
|---|
| 513 |                is set to -1 by default.
 | 
|---|
| 514 | 
 | 
|---|
| 515 |                The purpose of this property is to minimize resource use on platforms that use
 | 
|---|
| 516 |                polling to update the state of the session. Applications can set the value of this
 | 
|---|
| 517 |                property to the desired timeout before the session is closed. In response to the
 | 
|---|
| 518 |                closed() signal the network session should be deleted to ensure that all polling is
 | 
|---|
| 519 |                stopped. The session can then be recreated once it is required again. This property
 | 
|---|
| 520 |                has no effect for sessions that do not require polling.
 | 
|---|
| 521 |     \endtable
 | 
|---|
| 522 | */
 | 
|---|
| 523 | QVariant QNetworkSession::sessionProperty(const QString& key) const
 | 
|---|
| 524 | {
 | 
|---|
| 525 |     if (!d)
 | 
|---|
| 526 |         return QVariant();
 | 
|---|
| 527 | 
 | 
|---|
| 528 |     if (!d->publicConfig.isValid())
 | 
|---|
| 529 |         return QVariant();
 | 
|---|
| 530 | 
 | 
|---|
| 531 |     if (key == QLatin1String("ActiveConfiguration")) {
 | 
|---|
| 532 |         if (!d->isOpen)
 | 
|---|
| 533 |             return QString();
 | 
|---|
| 534 |         else
 | 
|---|
| 535 |             return d->activeConfig.identifier();
 | 
|---|
| 536 |     }
 | 
|---|
| 537 | 
 | 
|---|
| 538 |     if (key == QLatin1String("UserChoiceConfiguration")) {
 | 
|---|
| 539 |         if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice)
 | 
|---|
| 540 |             return QString();
 | 
|---|
| 541 | 
 | 
|---|
| 542 |         if (d->serviceConfig.isValid())
 | 
|---|
| 543 |             return d->serviceConfig.identifier();
 | 
|---|
| 544 |         else
 | 
|---|
| 545 |             return d->activeConfig.identifier();
 | 
|---|
| 546 |     }
 | 
|---|
| 547 | 
 | 
|---|
| 548 |     return d->sessionProperty(key);
 | 
|---|
| 549 | }
 | 
|---|
| 550 | 
 | 
|---|
| 551 | /*!
 | 
|---|
| 552 |     Sets the property \a value on the session. The property is identified using
 | 
|---|
| 553 |     \a key. Removing an already set  property can be achieved by passing an 
 | 
|---|
| 554 |     invalid QVariant.
 | 
|---|
| 555 | 
 | 
|---|
| 556 |     Note that the \e UserChoiceConfiguration and \e ActiveConfiguration
 | 
|---|
| 557 |     properties are read only and cannot be changed using this method.
 | 
|---|
| 558 | */
 | 
|---|
| 559 | void QNetworkSession::setSessionProperty(const QString& key, const QVariant& value)
 | 
|---|
| 560 | {
 | 
|---|
| 561 |     if (!d)
 | 
|---|
| 562 |         return;
 | 
|---|
| 563 | 
 | 
|---|
| 564 |     if (key == QLatin1String("ActiveConfiguration") ||
 | 
|---|
| 565 |         key == QLatin1String("UserChoiceConfiguration")) {
 | 
|---|
| 566 |         return;
 | 
|---|
| 567 |     }
 | 
|---|
| 568 | 
 | 
|---|
| 569 |     d->setSessionProperty(key, value);
 | 
|---|
| 570 | }
 | 
|---|
| 571 | 
 | 
|---|
| 572 | /*!
 | 
|---|
| 573 |     Instructs the session to roam to the new access point. The old access point remains active 
 | 
|---|
| 574 |     until the application calls accept().
 | 
|---|
| 575 | 
 | 
|---|
| 576 |    The newConfigurationActivated() signal is emitted once roaming has been completed.
 | 
|---|
| 577 | 
 | 
|---|
| 578 |     \sa accept()
 | 
|---|
| 579 | */
 | 
|---|
| 580 | void QNetworkSession::migrate()
 | 
|---|
| 581 | {
 | 
|---|
| 582 |     if (d)
 | 
|---|
| 583 |         d->migrate();
 | 
|---|
| 584 | }
 | 
|---|
| 585 | 
 | 
|---|
| 586 | /*!
 | 
|---|
| 587 |     This function indicates that the application does not wish to roam the session.
 | 
|---|
| 588 | 
 | 
|---|
| 589 |     \sa migrate()
 | 
|---|
| 590 | */
 | 
|---|
| 591 | void QNetworkSession::ignore()
 | 
|---|
| 592 | {
 | 
|---|
| 593 |     // Needed on at least Symbian platform: the roaming must be explicitly 
 | 
|---|
| 594 |     // ignore()'d or migrate()'d
 | 
|---|
| 595 |     if (d)
 | 
|---|
| 596 |         d->ignore();
 | 
|---|
| 597 | }
 | 
|---|
| 598 | 
 | 
|---|
| 599 | /*!
 | 
|---|
| 600 |     Instructs the session to permanently accept the new access point. Once this function 
 | 
|---|
| 601 |     has been called the session may not return to the old access point.
 | 
|---|
| 602 | 
 | 
|---|
| 603 |     The old access point may be closed in the process if there are no other network sessions for it.
 | 
|---|
| 604 |     Therefore any open socket that still uses the old access point 
 | 
|---|
| 605 |     may become unusable and should be closed before completing the migration.
 | 
|---|
| 606 | */
 | 
|---|
| 607 | void QNetworkSession::accept()
 | 
|---|
| 608 | {
 | 
|---|
| 609 |     if (d)
 | 
|---|
| 610 |         d->accept();
 | 
|---|
| 611 | }
 | 
|---|
| 612 | 
 | 
|---|
| 613 | /*!
 | 
|---|
| 614 |     The new access point is not suitable for the application. By calling this function the 
 | 
|---|
| 615 |     session returns to the previous access point/configuration. This action may invalidate
 | 
|---|
| 616 |     any socket that has been created via the not desired access point.
 | 
|---|
| 617 | 
 | 
|---|
| 618 |     \sa accept()
 | 
|---|
| 619 | */
 | 
|---|
| 620 | void QNetworkSession::reject()
 | 
|---|
| 621 | {
 | 
|---|
| 622 |     if (d)
 | 
|---|
| 623 |         d->reject();
 | 
|---|
| 624 | }
 | 
|---|
| 625 | 
 | 
|---|
| 626 | 
 | 
|---|
| 627 | /*!
 | 
|---|
| 628 |     Returns the amount of data sent in bytes; otherwise 0.
 | 
|---|
| 629 | 
 | 
|---|
| 630 |     This field value includes the usage across all open network 
 | 
|---|
| 631 |     sessions which use the same network interface.
 | 
|---|
| 632 | 
 | 
|---|
| 633 |     If the session is based on a service network configuration the number of 
 | 
|---|
| 634 |     sent bytes across all active member configurations are returned.
 | 
|---|
| 635 | 
 | 
|---|
| 636 |     This function may not always be supported on all platforms and returns 0.
 | 
|---|
| 637 |     The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
 | 
|---|
| 638 | 
 | 
|---|
| 639 |     \note On some platforms this function may run the main event loop.
 | 
|---|
| 640 | */
 | 
|---|
| 641 | quint64 QNetworkSession::bytesWritten() const
 | 
|---|
| 642 | {
 | 
|---|
| 643 |     return d ? d->bytesWritten() : Q_UINT64_C(0);
 | 
|---|
| 644 | }
 | 
|---|
| 645 | 
 | 
|---|
| 646 | /*!
 | 
|---|
| 647 |     Returns the amount of data received in bytes; otherwise 0.
 | 
|---|
| 648 | 
 | 
|---|
| 649 |     This field value includes the usage across all open network 
 | 
|---|
| 650 |     sessions which use the same network interface.
 | 
|---|
| 651 | 
 | 
|---|
| 652 |     If the session is based on a service network configuration the number of 
 | 
|---|
| 653 |     sent bytes across all active member configurations are returned.
 | 
|---|
| 654 | 
 | 
|---|
| 655 |     This function may not always be supported on all platforms and returns 0.
 | 
|---|
| 656 |     The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
 | 
|---|
| 657 | 
 | 
|---|
| 658 |     \note On some platforms this function may run the main event loop.
 | 
|---|
| 659 | */
 | 
|---|
| 660 | quint64 QNetworkSession::bytesReceived() const
 | 
|---|
| 661 | {
 | 
|---|
| 662 |     return d ? d->bytesReceived() : Q_UINT64_C(0);
 | 
|---|
| 663 | }
 | 
|---|
| 664 | 
 | 
|---|
| 665 | /*!
 | 
|---|
| 666 |     Returns the number of seconds that the session has been active.
 | 
|---|
| 667 | */
 | 
|---|
| 668 | quint64 QNetworkSession::activeTime() const
 | 
|---|
| 669 | {
 | 
|---|
| 670 |     return d ? d->activeTime() : Q_UINT64_C(0);
 | 
|---|
| 671 | }
 | 
|---|
| 672 | 
 | 
|---|
| 673 | /*!
 | 
|---|
| 674 |     \internal
 | 
|---|
| 675 | 
 | 
|---|
| 676 |     This function is required to detect whether the client wants to control 
 | 
|---|
| 677 |     the roaming process. If he connects to preferredConfigurationChanged() signal
 | 
|---|
| 678 |     he intends to influence it. Otherwise QNetworkSession always roams
 | 
|---|
| 679 |     without registering this session as a stakeholder in the roaming process.
 | 
|---|
| 680 | 
 | 
|---|
| 681 |     For more details check the Forced vs ALR roaming section in the QNetworkSession 
 | 
|---|
| 682 |     class description.
 | 
|---|
| 683 | */
 | 
|---|
| 684 | void QNetworkSession::connectNotify(const char *signal)
 | 
|---|
| 685 | {
 | 
|---|
| 686 |     QObject::connectNotify(signal);
 | 
|---|
| 687 |     //check for preferredConfigurationChanged() signal connect notification
 | 
|---|
| 688 |     //This is not required on all platforms
 | 
|---|
| 689 |     if (!d)
 | 
|---|
| 690 |         return;
 | 
|---|
| 691 | 
 | 
|---|
| 692 |     if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0)
 | 
|---|
| 693 |         d->setALREnabled(true);
 | 
|---|
| 694 | }
 | 
|---|
| 695 | 
 | 
|---|
| 696 | /*!
 | 
|---|
| 697 |     \internal
 | 
|---|
| 698 | 
 | 
|---|
| 699 |     This function is called when the client disconnects from the preferredConfigurationChanged()
 | 
|---|
| 700 |     signal.
 | 
|---|
| 701 | 
 | 
|---|
| 702 |     \sa connectNotify()
 | 
|---|
| 703 | */
 | 
|---|
| 704 | void QNetworkSession::disconnectNotify(const char *signal)
 | 
|---|
| 705 | {
 | 
|---|
| 706 |     QObject::disconnectNotify(signal);
 | 
|---|
| 707 |     //check for preferredConfigurationChanged() signal disconnect notification
 | 
|---|
| 708 |     //This is not required on all platforms
 | 
|---|
| 709 |     if (!d)
 | 
|---|
| 710 |         return;
 | 
|---|
| 711 | 
 | 
|---|
| 712 |     if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0)
 | 
|---|
| 713 |         d->setALREnabled(false);
 | 
|---|
| 714 | }
 | 
|---|
| 715 | 
 | 
|---|
| 716 | #include "moc_qnetworksession.cpp"
 | 
|---|
| 717 | 
 | 
|---|
| 718 | QT_END_NAMESPACE
 | 
|---|
| 719 | 
 | 
|---|
| 720 | #endif // QT_NO_BEARERMANAGEMENT
 | 
|---|