|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 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 Qt Mobility Components. |
|
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 "qnetworkconfigmanager_p.h" |
|
43 #include "qgenericengine_p.h" |
|
44 |
|
45 #ifdef Q_OS_WIN |
|
46 #include "qnlaengine_win_p.h" |
|
47 #endif |
|
48 #ifdef Q_OS_WIN32 |
|
49 #include "qnativewifiengine_win_p.h" |
|
50 #endif |
|
51 #if defined(BACKEND_NM) |
|
52 #include "qnmwifiengine_unix_p.h" |
|
53 #endif |
|
54 #ifdef Q_OS_DARWIN |
|
55 #include "qcorewlanengine_mac_p.h" |
|
56 #endif |
|
57 |
|
58 #include <QtCore/qdebug.h> |
|
59 #include <QtCore/qtimer.h> |
|
60 #include <QtCore/qstringlist.h> |
|
61 |
|
62 QTM_BEGIN_NAMESPACE |
|
63 |
|
64 void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities() |
|
65 { |
|
66 capFlags = QNetworkConfigurationManager::ForcedRoaming; |
|
67 } |
|
68 |
|
69 void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivate *cpPriv, QNetworkSessionEngine *engine) |
|
70 { |
|
71 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(new QNetworkConfigurationPrivate); |
|
72 |
|
73 ptr.data()->isValid = cpPriv->isValid; |
|
74 ptr.data()->name = cpPriv->name; |
|
75 ptr.data()->id = cpPriv->id; |
|
76 ptr.data()->state = cpPriv->state; |
|
77 ptr.data()->type = cpPriv->type; |
|
78 ptr.data()->roamingSupported = cpPriv->roamingSupported; |
|
79 ptr.data()->purpose = cpPriv->purpose; |
|
80 ptr.data()->internet = cpPriv->internet; |
|
81 ptr.data()->bearer = cpPriv->bearer; |
|
82 |
|
83 accessPointConfigurations.insert(cpPriv->id, ptr); |
|
84 configurationEngine.insert(cpPriv->id, engine); |
|
85 |
|
86 if (!firstUpdate) { |
|
87 QNetworkConfiguration item; |
|
88 item.d = ptr; |
|
89 emit configurationAdded(item); |
|
90 } |
|
91 |
|
92 if (ptr.data()->state == QNetworkConfiguration::Active) { |
|
93 ++onlineConfigurations; |
|
94 if (!firstUpdate && onlineConfigurations == 1) |
|
95 emit onlineStateChanged(true); |
|
96 } |
|
97 } |
|
98 |
|
99 void QNetworkConfigurationManagerPrivate::configurationRemoved(const QString &id) |
|
100 { |
|
101 if (!accessPointConfigurations.contains(id)) |
|
102 return; |
|
103 |
|
104 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = |
|
105 accessPointConfigurations.take(id); |
|
106 |
|
107 configurationEngine.remove(id); |
|
108 |
|
109 ptr.data()->isValid = false; |
|
110 |
|
111 if (!firstUpdate) { |
|
112 QNetworkConfiguration item; |
|
113 item.d = ptr; |
|
114 emit configurationRemoved(item); |
|
115 } |
|
116 |
|
117 if (ptr.data()->state == QNetworkConfiguration::Active) { |
|
118 --onlineConfigurations; |
|
119 if (!firstUpdate && onlineConfigurations == 0) |
|
120 emit onlineStateChanged(false); |
|
121 } |
|
122 } |
|
123 |
|
124 void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigurationPrivate *cpPriv) |
|
125 { |
|
126 if (!accessPointConfigurations.contains(cpPriv->id)) |
|
127 return; |
|
128 |
|
129 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = |
|
130 accessPointConfigurations.value(cpPriv->id); |
|
131 |
|
132 if (ptr.data()->isValid != cpPriv->isValid || |
|
133 ptr.data()->name != cpPriv->name || |
|
134 ptr.data()->id != cpPriv->id || |
|
135 ptr.data()->state != cpPriv->state || |
|
136 ptr.data()->type != cpPriv->type || |
|
137 ptr.data()->roamingSupported != cpPriv->roamingSupported || |
|
138 ptr.data()->purpose != cpPriv->purpose || |
|
139 ptr.data()->bearer != cpPriv->bearer || |
|
140 ptr.data()->internet != cpPriv->internet) { |
|
141 |
|
142 const QNetworkConfiguration::StateFlags oldState = ptr.data()->state; |
|
143 |
|
144 ptr.data()->isValid = cpPriv->isValid; |
|
145 ptr.data()->name = cpPriv->name; |
|
146 ptr.data()->id = cpPriv->id; |
|
147 ptr.data()->state = cpPriv->state; |
|
148 ptr.data()->type = cpPriv->type; |
|
149 ptr.data()->roamingSupported = cpPriv->roamingSupported; |
|
150 ptr.data()->purpose = cpPriv->purpose; |
|
151 ptr.data()->internet = cpPriv->internet; |
|
152 ptr.data()->bearer = cpPriv->bearer; |
|
153 |
|
154 if (!firstUpdate) { |
|
155 QNetworkConfiguration item; |
|
156 item.d = ptr; |
|
157 emit configurationChanged(item); |
|
158 } |
|
159 |
|
160 if (ptr.data()->state == QNetworkConfiguration::Active && oldState != ptr.data()->state) { |
|
161 // configuration went online |
|
162 ++onlineConfigurations; |
|
163 if (!firstUpdate && onlineConfigurations == 1) |
|
164 emit onlineStateChanged(true); |
|
165 } else if (ptr.data()->state != QNetworkConfiguration::Active && oldState == QNetworkConfiguration::Active) { |
|
166 // configuration went offline |
|
167 --onlineConfigurations; |
|
168 if (!firstUpdate && onlineConfigurations == 0) |
|
169 emit onlineStateChanged(false); |
|
170 } |
|
171 } |
|
172 } |
|
173 |
|
174 void QNetworkConfigurationManagerPrivate::updateInternetServiceConfiguration() |
|
175 { |
|
176 if (!snapConfigurations.contains(QLatin1String("Internet Service Network"))) { |
|
177 QNetworkConfigurationPrivate *serviceNetwork = new QNetworkConfigurationPrivate; |
|
178 serviceNetwork->name = tr("Internet"); |
|
179 serviceNetwork->isValid = true; |
|
180 serviceNetwork->id = QLatin1String("Internet Service Network"); |
|
181 serviceNetwork->state = QNetworkConfiguration::Defined; |
|
182 serviceNetwork->type = QNetworkConfiguration::ServiceNetwork; |
|
183 |
|
184 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(serviceNetwork); |
|
185 |
|
186 snapConfigurations.insert(serviceNetwork->id, ptr); |
|
187 |
|
188 if (!firstUpdate) { |
|
189 QNetworkConfiguration item; |
|
190 item.d = ptr; |
|
191 emit configurationAdded(item); |
|
192 } |
|
193 } |
|
194 |
|
195 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = |
|
196 snapConfigurations.value(QLatin1String("Internet Service Network")); |
|
197 |
|
198 QList<QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> > serviceNetworkMembers; |
|
199 |
|
200 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
|
201 accessPointConfigurations.constBegin(); |
|
202 |
|
203 QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined; |
|
204 while (i != accessPointConfigurations.constEnd()) { |
|
205 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> child = i.value(); |
|
206 |
|
207 if (child.data()->internet && ((child.data()->state & QNetworkConfiguration::Defined) |
|
208 == QNetworkConfiguration::Defined)) { |
|
209 serviceNetworkMembers.append(child); |
|
210 |
|
211 state |= child.data()->state; |
|
212 } |
|
213 |
|
214 ++i; |
|
215 } |
|
216 |
|
217 |
|
218 if (ptr.data()->state != state || ptr.data()->serviceNetworkMembers != serviceNetworkMembers) { |
|
219 ptr.data()->state = state; |
|
220 ptr.data()->serviceNetworkMembers = serviceNetworkMembers; |
|
221 |
|
222 QNetworkConfiguration item; |
|
223 item.d = ptr; |
|
224 emit configurationChanged(item); |
|
225 } |
|
226 } |
|
227 |
|
228 void QNetworkConfigurationManagerPrivate::updateConfigurations() |
|
229 { |
|
230 if (firstUpdate) { |
|
231 updateState = NotUpdating; |
|
232 onlineConfigurations = 0; |
|
233 |
|
234 #if defined (Q_OS_DARWIN) |
|
235 coreWifi = QCoreWlanEngine::instance(); |
|
236 if (coreWifi) { |
|
237 connect(coreWifi, SIGNAL(configurationsChanged()), |
|
238 this, SLOT(updateConfigurations())); |
|
239 } |
|
240 #else |
|
241 #if defined(BACKEND_NM) |
|
242 nmWifi = QNmWifiEngine::instance(); |
|
243 if (nmWifi) { |
|
244 connect(nmWifi, SIGNAL(configurationsChanged()), |
|
245 this, SLOT(updateConfigurations())); |
|
246 } else { |
|
247 #endif |
|
248 generic = QGenericEngine::instance(); |
|
249 if (generic) { |
|
250 connect(generic, SIGNAL(configurationsChanged()), |
|
251 this, SLOT(updateConfigurations())); |
|
252 } |
|
253 #if defined(BACKEND_NM) |
|
254 } |
|
255 #endif |
|
256 #endif |
|
257 |
|
258 #ifdef Q_OS_WIN |
|
259 nla = QNlaEngine::instance(); |
|
260 if (nla) { |
|
261 connect(nla, SIGNAL(configurationsChanged()), |
|
262 this, SLOT(updateConfigurations())); |
|
263 } |
|
264 #endif |
|
265 |
|
266 #ifdef Q_OS_WIN32 |
|
267 nativeWifi = QNativeWifiEngine::instance(); |
|
268 if (nativeWifi) { |
|
269 connect(nativeWifi, SIGNAL(configurationsChanged()), |
|
270 this, SLOT(updateConfigurations())); |
|
271 |
|
272 capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces; |
|
273 } |
|
274 #endif |
|
275 } |
|
276 |
|
277 QNetworkSessionEngine *engine = qobject_cast<QNetworkSessionEngine *>(sender()); |
|
278 if (updateState & Updating && engine) { |
|
279 #if defined (Q_OS_DARWIN) |
|
280 if (engine == coreWifi) |
|
281 updateState &= ~CoreWifiUpdating; |
|
282 #else |
|
283 #if defined(BACKEND_NM) |
|
284 if (engine == nmWifi) |
|
285 updateState &= ~NmUpdating; |
|
286 else if (engine == generic) |
|
287 updateState &= ~GenericUpdating; |
|
288 #else |
|
289 if (engine == generic) |
|
290 updateState &= ~GenericUpdating; |
|
291 #endif |
|
292 #endif |
|
293 |
|
294 #ifdef Q_OS_WIN |
|
295 else if (engine == nla) |
|
296 updateState &= ~NlaUpdating; |
|
297 #ifdef Q_OS_WIN32 |
|
298 else if (engine == nativeWifi) |
|
299 updateState &= ~NativeWifiUpdating; |
|
300 #endif |
|
301 #endif |
|
302 } |
|
303 QList<QNetworkSessionEngine *> engines; |
|
304 if (firstUpdate) { |
|
305 #if defined (Q_OS_DARWIN) |
|
306 if (coreWifi) |
|
307 engines << coreWifi; |
|
308 #else |
|
309 #if defined(BACKEND_NM) |
|
310 if (nmWifi) |
|
311 engines << nmWifi; |
|
312 else if (generic) |
|
313 engines << generic; |
|
314 #else |
|
315 if (generic) |
|
316 engines << generic; |
|
317 #endif |
|
318 #endif |
|
319 |
|
320 #ifdef Q_OS_WIN |
|
321 if (nla) |
|
322 engines << nla; |
|
323 #ifdef Q_OS_WIN32 |
|
324 if (nativeWifi) |
|
325 engines << nativeWifi; |
|
326 #endif |
|
327 #endif |
|
328 } else if (engine) { |
|
329 engines << engine; |
|
330 } |
|
331 |
|
332 while (!engines.isEmpty()) { |
|
333 engine = engines.takeFirst(); |
|
334 |
|
335 bool ok; |
|
336 QList<QNetworkConfigurationPrivate *> foundConfigurations = engine->getConfigurations(&ok); |
|
337 |
|
338 // Find removed configurations. |
|
339 QList<QString> removedIdentifiers = configurationEngine.keys(); |
|
340 for (int i = 0; i < foundConfigurations.count(); ++i) |
|
341 removedIdentifiers.removeOne(foundConfigurations.at(i)->id); |
|
342 |
|
343 // Update or add configurations. |
|
344 while (!foundConfigurations.isEmpty()) { |
|
345 QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst(); |
|
346 |
|
347 if (accessPointConfigurations.contains(cpPriv->id)) |
|
348 configurationChanged(cpPriv); |
|
349 else |
|
350 configurationAdded(cpPriv, engine); |
|
351 |
|
352 delete cpPriv; |
|
353 } |
|
354 |
|
355 // Remove configurations. |
|
356 while (!removedIdentifiers.isEmpty()) { |
|
357 const QString id = removedIdentifiers.takeFirst(); |
|
358 |
|
359 if (configurationEngine.value(id) == engine) |
|
360 configurationRemoved(id); |
|
361 } |
|
362 } |
|
363 |
|
364 updateInternetServiceConfiguration(); |
|
365 |
|
366 if (updateState == Updating) { |
|
367 updateState = NotUpdating; |
|
368 emit configurationUpdateComplete(); |
|
369 } |
|
370 |
|
371 if (firstUpdate) |
|
372 firstUpdate = false; |
|
373 } |
|
374 |
|
375 /*! |
|
376 Returns the first active configuration found, if one exists; otherwise returns the first |
|
377 discovered configuration found, if one exists; otherwise returns an empty configuration. |
|
378 |
|
379 \internal |
|
380 */ |
|
381 QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() |
|
382 { |
|
383 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> firstActive; |
|
384 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> firstDiscovered; |
|
385 |
|
386 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
|
387 accessPointConfigurations.constBegin(); |
|
388 while (i != accessPointConfigurations.constEnd()) { |
|
389 QNetworkConfigurationPrivate *priv = i.value().data(); |
|
390 |
|
391 if (!firstActive && priv->isValid && |
|
392 (priv->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) |
|
393 firstActive = i.value(); |
|
394 if (!firstDiscovered && priv->isValid && |
|
395 (priv->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) |
|
396 firstDiscovered = i.value(); |
|
397 |
|
398 ++i; |
|
399 } |
|
400 |
|
401 QNetworkConfiguration item; |
|
402 |
|
403 if (firstActive) |
|
404 item.d = firstActive; |
|
405 else if (firstDiscovered) |
|
406 item.d = firstDiscovered; |
|
407 |
|
408 return item; |
|
409 } |
|
410 |
|
411 void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() |
|
412 { |
|
413 updateState = Updating; |
|
414 #if defined (Q_OS_DARWIN) |
|
415 if (coreWifi) { |
|
416 updateState |= CoreWifiUpdating; |
|
417 coreWifi->requestUpdate(); |
|
418 } |
|
419 #else |
|
420 #if defined(BACKEND_NM) |
|
421 if (nmWifi) { |
|
422 updateState |= NmUpdating; |
|
423 nmWifi->requestUpdate(); |
|
424 } else if (generic) { |
|
425 updateState |= GenericUpdating; |
|
426 generic->requestUpdate(); |
|
427 } |
|
428 #else |
|
429 if (generic) { |
|
430 updateState |= GenericUpdating; |
|
431 generic->requestUpdate(); |
|
432 } |
|
433 #endif |
|
434 #endif |
|
435 #ifdef Q_OS_WIN |
|
436 if (nla) { |
|
437 updateState |= NlaUpdating; |
|
438 nla->requestUpdate(); |
|
439 } |
|
440 #endif |
|
441 |
|
442 #ifdef Q_OS_WIN32 |
|
443 if (nativeWifi) { |
|
444 updateState |= NativeWifiUpdating; |
|
445 nativeWifi->requestUpdate(); |
|
446 } |
|
447 #endif |
|
448 } |
|
449 |
|
450 #include "moc_qnetworkconfigmanager_p.cpp" |
|
451 |
|
452 QTM_END_NAMESPACE |
|
453 |