src/network/bearer/qnetworksession.cpp
changeset 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 
       
   255 /*!
       
   256     Frees the resources associated with the QNetworkSession object.
       
   257 */
       
   258 QNetworkSession::~QNetworkSession()
       
   259 {
       
   260     delete d;
       
   261 }
       
   262 
       
   263 /*!
       
   264     Creates an open session which increases the session counter on the underlying network interface.
       
   265     The system will not terminate a network interface until the session reference counter reaches zero.
       
   266     Therefore an open session allows an application to register its use of the interface.
       
   267 
       
   268     As a result of calling open() the interface will be started if it is not connected/up yet. 
       
   269     Some platforms may not provide support for out-of-process sessions. On such platforms the session
       
   270     counter ignores any sessions held by another process. The platform capabilities can be 
       
   271     detected via QNetworkConfigurationManager::capabilities().
       
   272 
       
   273     Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired 
       
   274     by connecting to the stateChanged(), opened() or error() signals.
       
   275 
       
   276     It is not a requirement to open a session in order to monitor the underlying network interface.
       
   277 
       
   278     \sa close(), stop(), isOpen()
       
   279 */
       
   280 void QNetworkSession::open()
       
   281 {
       
   282     if (d)
       
   283         d->open();
       
   284     else
       
   285         emit error(InvalidConfigurationError);
       
   286 }
       
   287 
       
   288 /*!
       
   289     Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this
       
   290     function returns true; otherwise it returns false. In the case where it returns false, you can call error()
       
   291     to determine the cause of the error.
       
   292 
       
   293     The following example waits up to one second for the session to be opened:
       
   294 
       
   295     \code
       
   296         session->open();
       
   297         if (session->waitForOpened(1000))
       
   298             qDebug("Open!");
       
   299     \endcode
       
   300 
       
   301     If \a msecs is -1, this function will not time out.
       
   302 
       
   303     \sa open(), error()
       
   304 */
       
   305 bool QNetworkSession::waitForOpened(int msecs)
       
   306 {
       
   307     if (!d)
       
   308         return false;
       
   309 
       
   310     if (d->isOpen)
       
   311         return true;
       
   312 
       
   313     if (d->state != Connecting)
       
   314         return false;
       
   315 
       
   316     QEventLoop* loop = new QEventLoop(this);
       
   317     QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()),
       
   318                      loop, SLOT(quit()));
       
   319     QObject::connect(this, SIGNAL(error(QNetworkSession::SessionError)),
       
   320                      loop, SLOT(quit()));
       
   321 
       
   322     //final call
       
   323     if (msecs>=0)
       
   324         QTimer::singleShot(msecs, loop, SLOT(quit()));
       
   325 
       
   326     loop->exec();
       
   327     loop->disconnect();
       
   328     loop->deleteLater();
       
   329 
       
   330     return d->isOpen;
       
   331 }
       
   332 
       
   333 /*!
       
   334     Decreases the session counter on the associated network configuration. If the session counter reaches zero
       
   335     the active network interface is shut down. This also means that state() will only change from \l Connected to
       
   336     \l Disconnected if the current session was the last open session.
       
   337 
       
   338     If the platform does not support out-of-process sessions calling this function does not stop the
       
   339     interface. In this case \l{stop()} has to be used to force a shut down. 
       
   340     The platform capabilities can be detected via QNetworkConfigurationManager::capabilities().
       
   341 
       
   342     Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired 
       
   343     by connecting to the stateChanged(), opened() or error() signals.
       
   344 
       
   345     \sa open(), stop(), isOpen()
       
   346 */
       
   347 void QNetworkSession::close()
       
   348 {
       
   349     if (d)
       
   350         d->close();
       
   351 }
       
   352 
       
   353 /*!
       
   354     Invalidates all open sessions against the network interface and therefore stops the 
       
   355     underlying network interface. This function always changes the session's state() flag to
       
   356     \l Disconnected.
       
   357 
       
   358     On Symbian platform, a 'NetworkControl' capability is required for
       
   359     full interface-level stop (without the capability, only the current session is stopped).
       
   360 
       
   361     \sa open(), close()
       
   362 */
       
   363 void QNetworkSession::stop()
       
   364 {
       
   365     if (d)
       
   366         d->stop();
       
   367 }
       
   368 
       
   369 /*!
       
   370     Returns the QNetworkConfiguration that this network session object is based on.
       
   371 
       
   372     \sa QNetworkConfiguration
       
   373 */
       
   374 QNetworkConfiguration QNetworkSession::configuration() const
       
   375 {
       
   376     return d ? d->publicConfig : QNetworkConfiguration();
       
   377 }
       
   378 
       
   379 #ifndef QT_NO_NETWORKINTERFACE
       
   380 /*!
       
   381     Returns the network interface that is used by this session.
       
   382 
       
   383     This function only returns a valid QNetworkInterface when this session is \l Connected.
       
   384 
       
   385     The returned interface may change as a result of a roaming process.
       
   386 
       
   387     Note: this function does not work in Symbian emulator due to the way the
       
   388     connectivity is emulated on Windows.
       
   389 
       
   390     \sa state()
       
   391 */
       
   392 QNetworkInterface QNetworkSession::interface() const
       
   393 {
       
   394     return d ? d->currentInterface() : QNetworkInterface();
       
   395 }
       
   396 #endif
       
   397 
       
   398 /*!
       
   399     Returns true if this session is open. If the number of all open sessions is greater than
       
   400     zero the underlying network interface will remain connected/up.
       
   401 
       
   402     The session can be controlled via open() and close().
       
   403 */
       
   404 bool QNetworkSession::isOpen() const
       
   405 {
       
   406     return d ? d->isOpen : false;
       
   407 }
       
   408 
       
   409 /*!
       
   410     Returns the state of the session. 
       
   411     
       
   412     If the session is based on a single access point configuration the state of the 
       
   413     session is the same as the state of the associated network interface. Therefore
       
   414     a network session object can be used to monitor network interfaces. 
       
   415 
       
   416     A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children
       
   417     and therefore returns the \l Connected state if at least one of the service network's 
       
   418     \l {QNetworkConfiguration::children()}{children()} configurations is active. 
       
   419 
       
   420     Note that it is not required to hold an open session in order to obtain the network interface state.
       
   421     A connected but closed session may be used to monitor network interfaces whereas an open and connected
       
   422     session object may prevent the network interface from being shut down.
       
   423 
       
   424     \sa error(), stateChanged()
       
   425 */
       
   426 QNetworkSession::State QNetworkSession::state() const
       
   427 {
       
   428     return d ? d->state : QNetworkSession::Invalid;
       
   429 }
       
   430 
       
   431 /*!
       
   432     Returns the type of error that last occurred.
       
   433 
       
   434     \sa state(), errorString()
       
   435 */
       
   436 QNetworkSession::SessionError QNetworkSession::error() const
       
   437 {
       
   438     return d ? d->error() : InvalidConfigurationError;
       
   439 }
       
   440 
       
   441 /*!
       
   442     Returns a human-readable description of the last device error that 
       
   443     occurred.
       
   444 
       
   445     \sa error()
       
   446 */
       
   447 QString QNetworkSession::errorString() const
       
   448 {
       
   449     return d ? d->errorString() : tr("Invalid configuration.");
       
   450 }
       
   451 
       
   452 /*!
       
   453     Returns the value for property \a key.
       
   454 
       
   455     A network session can have properties attached which may describe the session in more details.
       
   456     This function can be used to gain access to those properties.
       
   457 
       
   458     The following property keys are guaranteed to be specified on all platforms:
       
   459 
       
   460     \table
       
   461         \header
       
   462             \o Key \o Description
       
   463         \row
       
   464             \o ActiveConfiguration
       
   465             \o If the session \l isOpen() this property returns the identifier of the
       
   466             QNetworkConfiguration that is used by this session; otherwise an empty string.
       
   467 
       
   468             The main purpose of this key is to determine which Internet access point is used
       
   469             if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}. 
       
   470             The following code snippet highlights the difference:
       
   471             \code
       
   472                     QNetworkConfigurationManager mgr;
       
   473                     QNetworkConfiguration ap = mgr.defaultConfiguration();
       
   474                     QNetworkSession* session = new QNetworkSession(ap);
       
   475                     ... //code activates session
       
   476 
       
   477                     QString ident = session->sessionProperty("ActiveConfiguration").toString();
       
   478                     if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) {
       
   479                         Q_ASSERT( ap.identifier() != ident );
       
   480                         Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) );
       
   481                     } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) {
       
   482                         Q_ASSERT( ap.identifier() == ident );
       
   483                     }
       
   484                 \endcode
       
   485         \row
       
   486             \o UserChoiceConfiguration
       
   487             \o If the session \l isOpen() and is bound to a QNetworkConfiguration of type
       
   488             UserChoice, this property returns the identifier of the QNetworkConfiguration that the
       
   489             configuration resolved to when \l open() was called; otherwise an empty string.
       
   490 
       
   491             The purpose of this key is to determine the real QNetworkConfiguration that the
       
   492             session is using. This key is different to \i ActiveConfiguration in that
       
   493             this key may return an identifier for either a
       
   494             \l {QNetworkConfiguration::ServiceNetwork}{service network} or a
       
   495             \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations
       
   496             whereas \i ActiveConfiguration always returns identifiers to 
       
   497             \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations.
       
   498         \row
       
   499             \o ConnectInBackground
       
   500             \o Setting this property to \i true before calling \l open() implies that the connection attempt
       
   501             is made but if no connection can be established, the user is not connsulted and asked to select
       
   502             a suitable connection. This property is not set by default and support for it depends on the platform.
       
   503 
       
   504         \row
       
   505             \o AutoCloseSessionTimeout
       
   506             \o If the session requires polling to keep its state up to date, this property holds
       
   507                the timeout in milliseconds before the session will automatically close. If the
       
   508                value of this property is -1 the session will not automatically close. This property
       
   509                is set to -1 by default.
       
   510 
       
   511                The purpose of this property is to minimize resource use on platforms that use
       
   512                polling to update the state of the session. Applications can set the value of this
       
   513                property to the desired timeout before the session is closed. In response to the
       
   514                closed() signal the network session should be deleted to ensure that all polling is
       
   515                stopped. The session can then be recreated once it is required again. This property
       
   516                has no effect for sessions that do not require polling.
       
   517     \endtable
       
   518 */
       
   519 QVariant QNetworkSession::sessionProperty(const QString& key) const
       
   520 {
       
   521     if (!d)
       
   522         return QVariant();
       
   523 
       
   524     if (!d->publicConfig.isValid())
       
   525         return QVariant();
       
   526 
       
   527     if (key == QLatin1String("ActiveConfiguration")) {
       
   528         if (!d->isOpen)
       
   529             return QString();
       
   530         else
       
   531             return d->activeConfig.identifier();
       
   532     }
       
   533 
       
   534     if (key == QLatin1String("UserChoiceConfiguration")) {
       
   535         if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice)
       
   536             return QString();
       
   537 
       
   538         if (d->serviceConfig.isValid())
       
   539             return d->serviceConfig.identifier();
       
   540         else
       
   541             return d->activeConfig.identifier();
       
   542     }
       
   543 
       
   544     return d->sessionProperty(key);
       
   545 }
       
   546 
       
   547 /*!
       
   548     Sets the property \a value on the session. The property is identified using
       
   549     \a key. Removing an already set  property can be achieved by passing an 
       
   550     invalid QVariant.
       
   551 
       
   552     Note that the \e UserChoiceConfiguration and \e ActiveConfiguration
       
   553     properties are read only and cannot be changed using this method.
       
   554 */
       
   555 void QNetworkSession::setSessionProperty(const QString& key, const QVariant& value)
       
   556 {
       
   557     if (!d)
       
   558         return;
       
   559 
       
   560     if (key == QLatin1String("ActiveConfiguration") ||
       
   561         key == QLatin1String("UserChoiceConfiguration")) {
       
   562         return;
       
   563     }
       
   564 
       
   565     d->setSessionProperty(key, value);
       
   566 }
       
   567 
       
   568 /*!
       
   569     Instructs the session to roam to the new access point. The old access point remains active 
       
   570     until the application calls accept().
       
   571 
       
   572    The newConfigurationActivated() signal is emitted once roaming has been completed.
       
   573 
       
   574     \sa accept()
       
   575 */
       
   576 void QNetworkSession::migrate()
       
   577 {
       
   578     if (d)
       
   579         d->migrate();
       
   580 }
       
   581 
       
   582 /*!
       
   583     This function indicates that the application does not wish to roam the session.
       
   584 
       
   585     \sa migrate()
       
   586 */
       
   587 void QNetworkSession::ignore()
       
   588 {
       
   589     // Needed on at least Symbian platform: the roaming must be explicitly 
       
   590     // ignore()'d or migrate()'d
       
   591     if (d)
       
   592         d->ignore();
       
   593 }
       
   594 
       
   595 /*!
       
   596     Instructs the session to permanently accept the new access point. Once this function 
       
   597     has been called the session may not return to the old access point.
       
   598 
       
   599     The old access point may be closed in the process if there are no other network sessions for it.
       
   600     Therefore any open socket that still uses the old access point 
       
   601     may become unusable and should be closed before completing the migration.
       
   602 */
       
   603 void QNetworkSession::accept()
       
   604 {
       
   605     if (d)
       
   606         d->accept();
       
   607 }
       
   608 
       
   609 /*!
       
   610     The new access point is not suitable for the application. By calling this function the 
       
   611     session returns to the previous access point/configuration. This action may invalidate
       
   612     any socket that has been created via the not desired access point.
       
   613 
       
   614     \sa accept()
       
   615 */
       
   616 void QNetworkSession::reject()
       
   617 {
       
   618     if (d)
       
   619         d->reject();
       
   620 }
       
   621 
       
   622 
       
   623 /*!
       
   624     Returns the amount of data sent in bytes; otherwise 0.
       
   625 
       
   626     This field value includes the usage across all open network 
       
   627     sessions which use the same network interface.
       
   628 
       
   629     If the session is based on a service network configuration the number of 
       
   630     sent bytes across all active member configurations are returned.
       
   631 
       
   632     This function may not always be supported on all platforms and returns
       
   633     0. The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
       
   634 */
       
   635 quint64 QNetworkSession::bytesWritten() const
       
   636 {
       
   637     return d ? d->bytesWritten() : Q_UINT64_C(0);
       
   638 }
       
   639 
       
   640 /*!
       
   641     Returns the amount of data received in bytes; otherwise 0.
       
   642 
       
   643     This field value includes the usage across all open network 
       
   644     sessions which use the same network interface.
       
   645 
       
   646     If the session is based on a service network configuration the number of 
       
   647     sent bytes across all active member configurations are returned.
       
   648 
       
   649     This function may not always be supported on all platforms and returns
       
   650     0. The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
       
   651 */
       
   652 quint64 QNetworkSession::bytesReceived() const
       
   653 {
       
   654     return d ? d->bytesReceived() : Q_UINT64_C(0);
       
   655 }
       
   656 
       
   657 /*!
       
   658     Returns the number of seconds that the session has been active.
       
   659 */
       
   660 quint64 QNetworkSession::activeTime() const
       
   661 {
       
   662     return d ? d->activeTime() : Q_UINT64_C(0);
       
   663 }
       
   664 
       
   665 /*!
       
   666     \internal
       
   667 
       
   668     This function is required to detect whether the client wants to control 
       
   669     the roaming process. If he connects to preferredConfigurationChanged() signal
       
   670     he intends to influence it. Otherwise QNetworkSession always roams
       
   671     without registering this session as a stakeholder in the roaming process.
       
   672 
       
   673     For more details check the Forced vs ALR roaming section in the QNetworkSession 
       
   674     class description.
       
   675 */
       
   676 void QNetworkSession::connectNotify(const char *signal)
       
   677 {
       
   678     QObject::connectNotify(signal);
       
   679     //check for preferredConfigurationChanged() signal connect notification
       
   680     //This is not required on all platforms
       
   681     if (!d)
       
   682         return;
       
   683 
       
   684     if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0)
       
   685         d->setALREnabled(true);
       
   686 }
       
   687 
       
   688 /*!
       
   689     \internal
       
   690 
       
   691     This function is called when the client disconnects from the preferredConfigurationChanged()
       
   692     signal.
       
   693 
       
   694     \sa connectNotify()
       
   695 */
       
   696 void QNetworkSession::disconnectNotify(const char *signal)
       
   697 {
       
   698     QObject::disconnectNotify(signal);
       
   699     //check for preferredConfigurationChanged() signal disconnect notification
       
   700     //This is not required on all platforms
       
   701     if (!d)
       
   702         return;
       
   703 
       
   704     if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0)
       
   705         d->setALREnabled(false);
       
   706 }
       
   707 
       
   708 #include "moc_qnetworksession.cpp"
       
   709 
       
   710 QT_END_NAMESPACE
       
   711 
       
   712 #endif // QT_NO_BEARERMANAGEMENT