source: trunk/src/plugins/bearer/qnetworksession_impl.cpp@ 890

Last change on this file since 890 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: 14.0 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 plugins 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 "qnetworksession_impl.h"
43#include "qbearerengine_impl.h"
44
45#include <QtNetwork/qnetworksession.h>
46#include <QtNetwork/private/qnetworkconfigmanager_p.h>
47
48#include <QtCore/qstringlist.h>
49#include <QtCore/qdebug.h>
50#include <QtCore/qmutex.h>
51
52#ifndef QT_NO_BEARERMANAGEMENT
53
54QT_BEGIN_NAMESPACE
55
56static QBearerEngineImpl *getEngineFromId(const QString &id)
57{
58 QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
59
60 foreach (QBearerEngine *engine, priv->engines()) {
61 QBearerEngineImpl *engineImpl = qobject_cast<QBearerEngineImpl *>(engine);
62 if (engineImpl && engineImpl->hasIdentifier(id))
63 return engineImpl;
64 }
65
66 return 0;
67}
68
69class QNetworkSessionManagerPrivate : public QObject
70{
71 Q_OBJECT
72
73public:
74 QNetworkSessionManagerPrivate(QObject *parent = 0);
75 ~QNetworkSessionManagerPrivate();
76
77 void forceSessionClose(const QNetworkConfiguration &config);
78
79Q_SIGNALS:
80 void forcedSessionClose(const QNetworkConfiguration &config);
81};
82
83#include "qnetworksession_impl.moc"
84
85Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager);
86
87QNetworkSessionManagerPrivate::QNetworkSessionManagerPrivate(QObject *parent)
88: QObject(parent)
89{
90}
91
92QNetworkSessionManagerPrivate::~QNetworkSessionManagerPrivate()
93{
94}
95
96void QNetworkSessionManagerPrivate::forceSessionClose(const QNetworkConfiguration &config)
97{
98 emit forcedSessionClose(config);
99}
100
101void QNetworkSessionPrivateImpl::syncStateWithInterface()
102{
103 connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)),
104 this, SLOT(forcedSessionClose(QNetworkConfiguration)));
105
106 opened = false;
107 isOpen = false;
108 state = QNetworkSession::Invalid;
109 lastError = QNetworkSession::UnknownSessionError;
110
111 qRegisterMetaType<QBearerEngineImpl::ConnectionError>
112 ("QBearerEngineImpl::ConnectionError");
113
114 switch (publicConfig.type()) {
115 case QNetworkConfiguration::InternetAccessPoint:
116 activeConfig = publicConfig;
117 engine = getEngineFromId(activeConfig.identifier());
118 if (engine) {
119 qRegisterMetaType<QNetworkConfigurationPrivatePointer>("QNetworkConfigurationPrivatePointer");
120 connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)),
121 this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)),
122 Qt::QueuedConnection);
123 connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
124 this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)),
125 Qt::QueuedConnection);
126 }
127 break;
128 case QNetworkConfiguration::ServiceNetwork:
129 serviceConfig = publicConfig;
130 // Defer setting engine and signals until open().
131 // fall through
132 case QNetworkConfiguration::UserChoice:
133 // Defer setting serviceConfig and activeConfig until open().
134 // fall through
135 default:
136 engine = 0;
137 }
138
139 networkConfigurationsChanged();
140}
141
142void QNetworkSessionPrivateImpl::open()
143{
144 if (serviceConfig.isValid()) {
145 lastError = QNetworkSession::OperationNotSupportedError;
146 emit QNetworkSessionPrivate::error(lastError);
147 } else if (!isOpen) {
148 if ((activeConfig.state() & QNetworkConfiguration::Discovered) !=
149 QNetworkConfiguration::Discovered) {
150 lastError =QNetworkSession::InvalidConfigurationError;
151 state = QNetworkSession::Invalid;
152 emit stateChanged(state);
153 emit QNetworkSessionPrivate::error(lastError);
154 return;
155 }
156 opened = true;
157
158 if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active &&
159 (activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
160 state = QNetworkSession::Connecting;
161 emit stateChanged(state);
162
163 engine->connectToId(activeConfig.identifier());
164 }
165
166 isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active;
167 if (isOpen)
168 emit quitPendingWaitsForOpened();
169 }
170}
171
172void QNetworkSessionPrivateImpl::close()
173{
174 if (serviceConfig.isValid()) {
175 lastError = QNetworkSession::OperationNotSupportedError;
176 emit QNetworkSessionPrivate::error(lastError);
177 } else if (isOpen) {
178 opened = false;
179 isOpen = false;
180 emit closed();
181 }
182}
183
184void QNetworkSessionPrivateImpl::stop()
185{
186 if (serviceConfig.isValid()) {
187 lastError = QNetworkSession::OperationNotSupportedError;
188 emit QNetworkSessionPrivate::error(lastError);
189 } else {
190 if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
191 state = QNetworkSession::Closing;
192 emit stateChanged(state);
193
194 engine->disconnectFromId(activeConfig.identifier());
195
196 sessionManager()->forceSessionClose(activeConfig);
197 }
198
199 opened = false;
200 isOpen = false;
201 emit closed();
202 }
203}
204
205void QNetworkSessionPrivateImpl::migrate()
206{
207}
208
209void QNetworkSessionPrivateImpl::accept()
210{
211}
212
213void QNetworkSessionPrivateImpl::ignore()
214{
215}
216
217void QNetworkSessionPrivateImpl::reject()
218{
219}
220
221#ifndef QT_NO_NETWORKINTERFACE
222QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const
223{
224 if (!publicConfig.isValid() || !engine || state != QNetworkSession::Connected)
225 return QNetworkInterface();
226
227 QString interface = engine->getInterfaceFromId(activeConfig.identifier());
228
229 if (interface.isEmpty())
230 return QNetworkInterface();
231 return QNetworkInterface::interfaceFromName(interface);
232}
233#endif
234
235QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString &key) const
236{
237 if (key == QLatin1String("AutoCloseSessionTimeout")) {
238 if (engine && engine->requiresPolling() &&
239 !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) {
240 if (sessionTimeout >= 0)
241 return sessionTimeout * 10000;
242 else
243 return -1;
244 }
245 }
246
247 return QVariant();
248}
249
250void QNetworkSessionPrivateImpl::setSessionProperty(const QString &key, const QVariant &value)
251{
252 if (key == QLatin1String("AutoCloseSessionTimeout")) {
253 if (engine && engine->requiresPolling() &&
254 !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) {
255 int timeout = value.toInt();
256 if (timeout >= 0) {
257 connect(engine, SIGNAL(updateCompleted()),
258 this, SLOT(decrementTimeout()), Qt::UniqueConnection);
259 sessionTimeout = timeout / 10000; // convert to poll intervals
260 } else {
261 disconnect(engine, SIGNAL(updateCompleted()), this, SLOT(decrementTimeout()));
262 sessionTimeout = -1;
263 }
264 }
265 }
266}
267
268QString QNetworkSessionPrivateImpl::errorString() const
269{
270 switch (lastError) {
271 case QNetworkSession::UnknownSessionError:
272 return tr("Unknown session error.");
273 case QNetworkSession::SessionAbortedError:
274 return tr("The session was aborted by the user or system.");
275 case QNetworkSession::OperationNotSupportedError:
276 return tr("The requested operation is not supported by the system.");
277 case QNetworkSession::InvalidConfigurationError:
278 return tr("The specified configuration cannot be used.");
279 case QNetworkSession::RoamingError:
280 return tr("Roaming was aborted or is not possible.");
281
282 }
283
284 return QString();
285}
286
287QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
288{
289 return lastError;
290}
291
292quint64 QNetworkSessionPrivateImpl::bytesWritten() const
293{
294 if (engine && state == QNetworkSession::Connected)
295 return engine->bytesWritten(activeConfig.identifier());
296 else
297 return Q_UINT64_C(0);
298}
299
300quint64 QNetworkSessionPrivateImpl::bytesReceived() const
301{
302 if (engine && state == QNetworkSession::Connected)
303 return engine->bytesReceived(activeConfig.identifier());
304 else
305 return Q_UINT64_C(0);
306}
307
308quint64 QNetworkSessionPrivateImpl::activeTime() const
309{
310 if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0))
311 return QDateTime::currentDateTime().toTime_t() - startTime;
312 else
313 return Q_UINT64_C(0);
314}
315
316void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork()
317{
318 QNetworkSession::State oldState = state;
319
320 foreach (const QNetworkConfiguration &config, serviceConfig.children()) {
321 if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active)
322 continue;
323
324 if (activeConfig != config) {
325 if (engine) {
326 disconnect(engine,
327 SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
328 this,
329 SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)));
330 }
331
332 activeConfig = config;
333 engine = getEngineFromId(activeConfig.identifier());
334 if (engine) {
335 connect(engine,
336 SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)),
337 this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)),
338 Qt::QueuedConnection);
339 }
340 emit newConfigurationActivated();
341 }
342
343 state = QNetworkSession::Connected;
344 if (state != oldState)
345 emit stateChanged(state);
346
347 return;
348 }
349
350 if (serviceConfig.children().isEmpty())
351 state = QNetworkSession::NotAvailable;
352 else
353 state = QNetworkSession::Disconnected;
354
355 if (state != oldState)
356 emit stateChanged(state);
357}
358
359void QNetworkSessionPrivateImpl::updateStateFromActiveConfig()
360{
361 if (!engine)
362 return;
363
364 QNetworkSession::State oldState = state;
365
366 state = engine->sessionStateForId(activeConfig.identifier());
367
368 bool oldActive = isOpen;
369 isOpen = (state == QNetworkSession::Connected) ? opened : false;
370
371 if (!oldActive && isOpen)
372 emit quitPendingWaitsForOpened();
373 if (oldActive && !isOpen)
374 emit closed();
375
376 if (oldState != state)
377 emit stateChanged(state);
378}
379
380void QNetworkSessionPrivateImpl::networkConfigurationsChanged()
381{
382 if (serviceConfig.isValid())
383 updateStateFromServiceNetwork();
384 else
385 updateStateFromActiveConfig();
386
387 startTime = engine->startTime(activeConfig.identifier());
388}
389
390void QNetworkSessionPrivateImpl::configurationChanged(QNetworkConfigurationPrivatePointer config)
391{
392 if (serviceConfig.isValid() &&
393 (config->id == serviceConfig.identifier() || config->id == activeConfig.identifier())) {
394 updateStateFromServiceNetwork();
395 } else if (config->id == activeConfig.identifier()) {
396 updateStateFromActiveConfig();
397 }
398}
399
400void QNetworkSessionPrivateImpl::forcedSessionClose(const QNetworkConfiguration &config)
401{
402 if (activeConfig == config) {
403 opened = false;
404 isOpen = false;
405
406 emit closed();
407
408 lastError = QNetworkSession::SessionAbortedError;
409 emit QNetworkSessionPrivate::error(lastError);
410 }
411}
412
413void QNetworkSessionPrivateImpl::connectionError(const QString &id,
414 QBearerEngineImpl::ConnectionError error)
415{
416 if (activeConfig.identifier() == id) {
417 networkConfigurationsChanged();
418 switch (error) {
419 case QBearerEngineImpl::OperationNotSupported:
420 lastError = QNetworkSession::OperationNotSupportedError;
421 opened = false;
422 break;
423 case QBearerEngineImpl::InterfaceLookupError:
424 case QBearerEngineImpl::ConnectError:
425 case QBearerEngineImpl::DisconnectionError:
426 default:
427 lastError = QNetworkSession::UnknownSessionError;
428 }
429
430 emit QNetworkSessionPrivate::error(lastError);
431 }
432}
433
434void QNetworkSessionPrivateImpl::decrementTimeout()
435{
436 if (--sessionTimeout <= 0) {
437 disconnect(engine, SIGNAL(updateCompleted()), this, SLOT(decrementTimeout()));
438 sessionTimeout = -1;
439 close();
440 }
441}
442
443QT_END_NAMESPACE
444
445#endif // QT_NO_BEARERMANAGEMENT
446
Note: See TracBrowser for help on using the repository browser.