source: trunk/src/network/bearer/qnetworksession.cpp@ 1168

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 27.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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 [email protected].
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
52QT_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*/
227QNetworkSession::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*/
261QNetworkSession::~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*/
283void 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*/
308bool 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*/
351void 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*/
367void 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*/
378QNetworkConfiguration 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*/
396QNetworkInterface 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*/
408bool 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*/
430QNetworkSession::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*/
440QNetworkSession::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*/
451QString 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*/
523QVariant 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*/
559void 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*/
580void 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*/
591void 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*/
607void 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*/
620void 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*/
641quint64 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*/
660quint64 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*/
668quint64 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*/
684void 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*/
704void 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
718QT_END_NAMESPACE
719
720#endif // QT_NO_BEARERMANAGEMENT
Note: See TracBrowser for help on using the repository browser.