|
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 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_s60_p.h" |
|
43 |
|
44 #include <commdb.h> |
|
45 #include <cdbcols.h> |
|
46 #include <d32dbms.h> |
|
47 #include <nifvar.h> |
|
48 #include <QTimer> |
|
49 #include <QTime> // For randgen seeding |
|
50 #include <QtCore> // For randgen seeding |
|
51 |
|
52 |
|
53 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
54 #include <QDebug> |
|
55 #endif |
|
56 |
|
57 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
58 #include <cmdestination.h> |
|
59 #include <cmconnectionmethod.h> |
|
60 #include <cmconnectionmethoddef.h> |
|
61 #include <cmpluginwlandef.h> |
|
62 #include <cmpluginpacketdatadef.h> |
|
63 #include <cmplugindialcommondefs.h> |
|
64 #else |
|
65 #include <apaccesspointitem.h> |
|
66 #include <apdatahandler.h> |
|
67 #include <aputils.h> |
|
68 #endif |
|
69 |
|
70 QTM_BEGIN_NAMESPACE |
|
71 |
|
72 static const int KUserChoiceIAPId = 0; |
|
73 |
|
74 QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() |
|
75 : QObject(0), CActive(CActive::EPriorityHigh), capFlags(0), |
|
76 iFirstUpdate(true), iInitOk(true), iUpdatePending(false), |
|
77 iTimeToWait(0) |
|
78 { |
|
79 CActiveScheduler::Add(this); |
|
80 |
|
81 // Seed the randomgenerator |
|
82 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid()); |
|
83 |
|
84 registerPlatformCapabilities(); |
|
85 TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP)); |
|
86 if (error != KErrNone) { |
|
87 iInitOk = false; |
|
88 return; |
|
89 } |
|
90 |
|
91 TRAP_IGNORE(iConnectionMonitor.ConnectL()); |
|
92 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
93 TRAP_IGNORE(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1)); |
|
94 #endif |
|
95 TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this)); |
|
96 |
|
97 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
98 TRAP(error, iCmManager.OpenL()); |
|
99 if (error != KErrNone) { |
|
100 iInitOk = false; |
|
101 return; |
|
102 } |
|
103 #endif |
|
104 |
|
105 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
106 cpPriv->name = "UserChoice"; |
|
107 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
108 cpPriv->state = QNetworkConfiguration::Discovered; |
|
109 cpPriv->isValid = true; |
|
110 cpPriv->id = QString::number(qHash(KUserChoiceIAPId)); |
|
111 cpPriv->numericId = KUserChoiceIAPId; |
|
112 cpPriv->connectionId = 0; |
|
113 cpPriv->type = QNetworkConfiguration::UserChoice; |
|
114 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
115 cpPriv->roamingSupported = false; |
|
116 cpPriv->manager = this; |
|
117 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
118 userChoiceConfigurations.insert(cpPriv->id, ptr); |
|
119 updateConfigurations(); |
|
120 updateStatesToSnaps(); |
|
121 updateAvailableAccessPoints(); // On first time updates synchronously (without WLAN scans) |
|
122 // Start monitoring IAP and/or SNAP changes in Symbian CommsDB |
|
123 startCommsDatabaseNotifications(); |
|
124 iFirstUpdate = false; |
|
125 } |
|
126 |
|
127 QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() |
|
128 { |
|
129 Cancel(); |
|
130 |
|
131 foreach (const QString &oldIface, snapConfigurations.keys()) { |
|
132 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.take(oldIface); |
|
133 priv->isValid = false; |
|
134 priv->id.clear(); |
|
135 } |
|
136 |
|
137 foreach (const QString &oldIface, accessPointConfigurations.keys()) { |
|
138 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(oldIface); |
|
139 priv->isValid = false; |
|
140 priv->id.clear(); |
|
141 } |
|
142 |
|
143 foreach (const QString &oldIface, userChoiceConfigurations.keys()) { |
|
144 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = userChoiceConfigurations.take(oldIface); |
|
145 priv->isValid = false; |
|
146 priv->id.clear(); |
|
147 priv->manager = 0; |
|
148 } |
|
149 |
|
150 iConnectionMonitor.CancelNotifications(); |
|
151 iConnectionMonitor.Close(); |
|
152 |
|
153 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
154 iCmManager.Close(); |
|
155 #endif |
|
156 |
|
157 delete ipAccessPointsAvailabilityScanner; |
|
158 |
|
159 // CCommsDatabase destructor uses cleanup stack. Since QNetworkConfigurationManager |
|
160 // is a global static, but the time we are here, E32Main() has been exited already and |
|
161 // the thread's default cleanup stack has been deleted. Without this line, a |
|
162 // 'E32USER-CBase 69' -panic will occur. |
|
163 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
164 delete ipCommsDB; |
|
165 delete cleanup; |
|
166 } |
|
167 |
|
168 void QNetworkConfigurationManagerPrivate::delayedConfigurationUpdate() |
|
169 { |
|
170 if (iUpdatePending) { |
|
171 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
172 qDebug("QNCM delayed configuration update (ECommit or ERecover occurred)."); |
|
173 #endif |
|
174 TRAPD(error, updateConfigurationsL()); |
|
175 if (error == KErrNone) { |
|
176 updateStatesToSnaps(); |
|
177 } |
|
178 iUpdatePending = false; |
|
179 // Start monitoring again. |
|
180 if (!IsActive()) { |
|
181 SetActive(); |
|
182 // Start waiting for new notification |
|
183 ipCommsDB->RequestNotification(iStatus); |
|
184 } |
|
185 } |
|
186 } |
|
187 |
|
188 void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities() |
|
189 { |
|
190 capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces; |
|
191 capFlags |= QNetworkConfigurationManager::DirectConnectionRouting; |
|
192 capFlags |= QNetworkConfigurationManager::SystemSessionSupport; |
|
193 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
194 capFlags |= QNetworkConfigurationManager::ApplicationLevelRoaming; |
|
195 capFlags |= QNetworkConfigurationManager::ForcedRoaming; |
|
196 #endif |
|
197 capFlags |= QNetworkConfigurationManager::DataStatistics; |
|
198 capFlags |= QNetworkConfigurationManager::NetworkSessionRequired; |
|
199 } |
|
200 |
|
201 void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() |
|
202 { |
|
203 if (!iInitOk || iUpdateGoingOn) { |
|
204 return; |
|
205 } |
|
206 iUpdateGoingOn = true; |
|
207 |
|
208 stopCommsDatabaseNotifications(); |
|
209 updateConfigurations(); // Synchronous call |
|
210 updateAvailableAccessPoints(); // Asynchronous call |
|
211 } |
|
212 |
|
213 void QNetworkConfigurationManagerPrivate::updateConfigurations() |
|
214 { |
|
215 if (!iInitOk) { |
|
216 return; |
|
217 } |
|
218 TRAP_IGNORE(updateConfigurationsL()); |
|
219 } |
|
220 |
|
221 void QNetworkConfigurationManagerPrivate::updateConfigurationsL() |
|
222 { |
|
223 QList<QString> knownConfigs = accessPointConfigurations.keys(); |
|
224 QList<QString> knownSnapConfigs = snapConfigurations.keys(); |
|
225 |
|
226 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
227 // S60 version is >= Series60 3rd Edition Feature Pack 2 |
|
228 TInt error = KErrNone; |
|
229 |
|
230 // Loop through all IAPs |
|
231 RArray<TUint32> connectionMethods; // IAPs |
|
232 CleanupClosePushL(connectionMethods); |
|
233 iCmManager.ConnectionMethodL(connectionMethods); |
|
234 for(int i = 0; i < connectionMethods.Count(); i++) { |
|
235 RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]); |
|
236 CleanupClosePushL(connectionMethod); |
|
237 TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); |
|
238 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); |
|
239 if (accessPointConfigurations.contains(ident)) { |
|
240 knownConfigs.removeOne(ident); |
|
241 } else { |
|
242 QNetworkConfigurationPrivate* cpPriv = NULL; |
|
243 TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod)); |
|
244 if (error == KErrNone) { |
|
245 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
246 accessPointConfigurations.insert(cpPriv->id, ptr); |
|
247 if (!iFirstUpdate) { |
|
248 QNetworkConfiguration item; |
|
249 item.d = ptr; |
|
250 // Emit configuration added. Connected slots may throw execptions |
|
251 // which propagate here --> must be converted to leaves (standard |
|
252 // std::exception would cause any TRAP trapping this function to terminate |
|
253 // program). |
|
254 QT_TRYCATCH_LEAVING(updateActiveAccessPoints()); |
|
255 updateStatesToSnaps(); |
|
256 QT_TRYCATCH_LEAVING(emit configurationAdded(item)); |
|
257 } |
|
258 } |
|
259 } |
|
260 CleanupStack::PopAndDestroy(&connectionMethod); |
|
261 } |
|
262 CleanupStack::PopAndDestroy(&connectionMethods); |
|
263 |
|
264 // Loop through all SNAPs |
|
265 RArray<TUint32> destinations; |
|
266 CleanupClosePushL(destinations); |
|
267 iCmManager.AllDestinationsL(destinations); |
|
268 for(int i = 0; i < destinations.Count(); i++) { |
|
269 RCmDestination destination; |
|
270 |
|
271 // Some destinatsions require ReadDeviceData -capability (MMS/WAP) |
|
272 // The below function will leave in these cases. Don't. Proceed to |
|
273 // next destination (if any). |
|
274 TRAPD(error, destination = iCmManager.DestinationL(destinations[i])); |
|
275 if (error == KErrPermissionDenied) { |
|
276 continue; |
|
277 } else { |
|
278 User::LeaveIfError(error); |
|
279 } |
|
280 |
|
281 CleanupClosePushL(destination); |
|
282 QString ident = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX+QString::number(qHash(destination.Id())); |
|
283 if (snapConfigurations.contains(ident)) { |
|
284 knownSnapConfigs.removeOne(ident); |
|
285 } else { |
|
286 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
287 HBufC *pName = destination.NameLC(); |
|
288 QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length())); |
|
289 CleanupStack::PopAndDestroy(pName); |
|
290 pName = NULL; |
|
291 cpPriv->isValid = true; |
|
292 cpPriv->id = ident; |
|
293 cpPriv->numericId = destination.Id(); |
|
294 cpPriv->connectionId = 0; |
|
295 cpPriv->state = QNetworkConfiguration::Defined; |
|
296 cpPriv->type = QNetworkConfiguration::ServiceNetwork; |
|
297 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
298 cpPriv->roamingSupported = false; |
|
299 cpPriv->manager = this; |
|
300 |
|
301 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
302 snapConfigurations.insert(ident, ptr); |
|
303 if (!iFirstUpdate) { |
|
304 QNetworkConfiguration item; |
|
305 item.d = ptr; |
|
306 QT_TRYCATCH_LEAVING(updateActiveAccessPoints()); |
|
307 updateStatesToSnaps(); |
|
308 QT_TRYCATCH_LEAVING(emit configurationAdded(item)); |
|
309 } |
|
310 } |
|
311 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> privSNAP = snapConfigurations.value(ident); |
|
312 |
|
313 for (int j=0; j < destination.ConnectionMethodCount(); j++) { |
|
314 RCmConnectionMethod connectionMethod = destination.ConnectionMethodL(j); |
|
315 CleanupClosePushL(connectionMethod); |
|
316 |
|
317 TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); |
|
318 QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); |
|
319 // Check that IAP can be found from accessPointConfigurations list |
|
320 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
321 if (priv.data() == 0) { |
|
322 QNetworkConfigurationPrivate* cpPriv = NULL; |
|
323 TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod)); |
|
324 if (error == KErrNone) { |
|
325 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
326 ptr.data()->serviceNetworkPtr = privSNAP; |
|
327 accessPointConfigurations.insert(cpPriv->id, ptr); |
|
328 privSNAP->serviceNetworkMembers.append(ptr); |
|
329 if (!iFirstUpdate) { |
|
330 QNetworkConfiguration item; |
|
331 item.d = ptr; |
|
332 QT_TRYCATCH_LEAVING(updateActiveAccessPoints()); |
|
333 updateStatesToSnaps(); |
|
334 QT_TRYCATCH_LEAVING(emit configurationAdded(item)); |
|
335 } |
|
336 } |
|
337 } else { |
|
338 knownConfigs.removeOne(iface); |
|
339 // Check that IAP can be found from related SNAP's configuration list |
|
340 bool iapFound = false; |
|
341 for (int i=0; i<privSNAP->serviceNetworkMembers.count(); i++) { |
|
342 if (privSNAP->serviceNetworkMembers[i]->numericId == iapId) { |
|
343 iapFound = true; |
|
344 break; |
|
345 } |
|
346 } |
|
347 if (!iapFound) { |
|
348 priv.data()->serviceNetworkPtr = privSNAP; |
|
349 privSNAP->serviceNetworkMembers.append(priv); |
|
350 } |
|
351 } |
|
352 CleanupStack::PopAndDestroy(&connectionMethod); |
|
353 } |
|
354 if (privSNAP->serviceNetworkMembers.count() > 1) { |
|
355 // Roaming is supported only if SNAP contains more than one IAP |
|
356 privSNAP->roamingSupported = true; |
|
357 } |
|
358 CleanupStack::PopAndDestroy(&destination); |
|
359 } |
|
360 CleanupStack::PopAndDestroy(&destinations); |
|
361 |
|
362 #else |
|
363 // S60 version is < Series60 3rd Edition Feature Pack 2 |
|
364 CCommsDbTableView* pDbTView = ipCommsDB->OpenTableLC(TPtrC(IAP)); |
|
365 |
|
366 // Loop through all IAPs |
|
367 TUint32 apId = 0; |
|
368 TInt retVal = pDbTView->GotoFirstRecord(); |
|
369 while (retVal == KErrNone) { |
|
370 pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId); |
|
371 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); |
|
372 if (accessPointConfigurations.contains(ident)) { |
|
373 knownConfigs.removeOne(ident); |
|
374 } else { |
|
375 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
376 if (readNetworkConfigurationValuesFromCommsDb(apId, cpPriv)) { |
|
377 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
378 accessPointConfigurations.insert(ident, ptr); |
|
379 if (!iFirstUpdate) { |
|
380 QNetworkConfiguration item; |
|
381 item.d = ptr; |
|
382 QT_TRYCATCH_LEAVING(updateActiveAccessPoints()); |
|
383 updateStatesToSnaps(); |
|
384 QT_TRYCATCH_LEAVING(emit configurationAdded(item)); |
|
385 } |
|
386 } else { |
|
387 delete cpPriv; |
|
388 } |
|
389 } |
|
390 retVal = pDbTView->GotoNextRecord(); |
|
391 } |
|
392 CleanupStack::PopAndDestroy(pDbTView); |
|
393 #endif |
|
394 |
|
395 QT_TRYCATCH_LEAVING(updateActiveAccessPoints()); |
|
396 |
|
397 foreach (const QString &oldIface, knownConfigs) { |
|
398 //remove non existing IAP |
|
399 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(oldIface); |
|
400 priv->isValid = false; |
|
401 if (!iFirstUpdate) { |
|
402 QNetworkConfiguration item; |
|
403 item.d = priv; |
|
404 QT_TRYCATCH_LEAVING(emit configurationRemoved(item)); |
|
405 } |
|
406 // Remove non existing IAP from SNAPs |
|
407 foreach (const QString &iface, snapConfigurations.keys()) { |
|
408 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv2 = snapConfigurations.value(iface); |
|
409 // => Check if one of the IAPs of the SNAP is active |
|
410 for (int i=0; i<priv2->serviceNetworkMembers.count(); i++) { |
|
411 if (priv2->serviceNetworkMembers[i]->numericId == priv->numericId) { |
|
412 priv2->serviceNetworkMembers.removeAt(i); |
|
413 break; |
|
414 } |
|
415 } |
|
416 } |
|
417 } |
|
418 foreach (const QString &oldIface, knownSnapConfigs) { |
|
419 //remove non existing SNAPs |
|
420 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.take(oldIface); |
|
421 priv->isValid = false; |
|
422 if (!iFirstUpdate) { |
|
423 QNetworkConfiguration item; |
|
424 item.d = priv; |
|
425 QT_TRYCATCH_LEAVING(emit configurationRemoved(item)); |
|
426 } |
|
427 } |
|
428 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
429 updateStatesToSnaps(); |
|
430 #endif |
|
431 } |
|
432 |
|
433 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
434 QNetworkConfigurationPrivate* QNetworkConfigurationManagerPrivate::configFromConnectionMethodL( |
|
435 RCmConnectionMethod& connectionMethod) |
|
436 { |
|
437 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
438 TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); |
|
439 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); |
|
440 |
|
441 HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName); |
|
442 CleanupStack::PushL(pName); |
|
443 QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length())); |
|
444 CleanupStack::PopAndDestroy(pName); |
|
445 pName = NULL; |
|
446 |
|
447 TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType); |
|
448 switch (bearerId) { |
|
449 case KCommDbBearerCSD: |
|
450 cpPriv->bearer = QNetworkConfigurationPrivate::Bearer2G; |
|
451 break; |
|
452 case KCommDbBearerWcdma: |
|
453 cpPriv->bearer = QNetworkConfigurationPrivate::BearerWCDMA; |
|
454 break; |
|
455 case KCommDbBearerLAN: |
|
456 cpPriv->bearer = QNetworkConfigurationPrivate::BearerEthernet; |
|
457 break; |
|
458 case KCommDbBearerVirtual: |
|
459 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
460 break; |
|
461 case KCommDbBearerPAN: |
|
462 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
463 break; |
|
464 case KCommDbBearerWLAN: |
|
465 cpPriv->bearer = QNetworkConfigurationPrivate::BearerWLAN; |
|
466 break; |
|
467 default: |
|
468 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
469 break; |
|
470 } |
|
471 |
|
472 TInt error = KErrNone; |
|
473 TUint32 bearerType = connectionMethod.GetIntAttributeL(CMManager::ECmBearerType); |
|
474 switch (bearerType) { |
|
475 case KUidPacketDataBearerType: |
|
476 // "Packet data" Bearer => Mapping is done using "Access point name" |
|
477 TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EPacketDataAPName)); |
|
478 break; |
|
479 case KUidWlanBearerType: |
|
480 // "Wireless LAN" Bearer => Mapping is done using "WLAN network name" = SSID |
|
481 TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EWlanSSID)); |
|
482 break; |
|
483 } |
|
484 if (!pName) { |
|
485 // "Data call" Bearer or "High Speed (GSM)" Bearer => Mapping is done using "Dial-up number" |
|
486 TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EDialDefaultTelNum)); |
|
487 } |
|
488 |
|
489 if (error == KErrNone && pName) { |
|
490 CleanupStack::PushL(pName); |
|
491 QT_TRYCATCH_LEAVING(cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length())); |
|
492 CleanupStack::PopAndDestroy(pName); |
|
493 pName = NULL; |
|
494 } |
|
495 |
|
496 cpPriv->state = QNetworkConfiguration::Defined; |
|
497 TBool isConnected = connectionMethod.GetBoolAttributeL(CMManager::ECmConnected); |
|
498 if (isConnected) { |
|
499 cpPriv->state = QNetworkConfiguration::Active; |
|
500 } |
|
501 |
|
502 cpPriv->isValid = true; |
|
503 cpPriv->id = ident; |
|
504 cpPriv->numericId = iapId; |
|
505 cpPriv->connectionId = 0; |
|
506 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
|
507 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
508 cpPriv->roamingSupported = false; |
|
509 cpPriv->manager = this; |
|
510 return cpPriv; |
|
511 } |
|
512 #else |
|
513 bool QNetworkConfigurationManagerPrivate::readNetworkConfigurationValuesFromCommsDb( |
|
514 TUint32 aApId, QNetworkConfigurationPrivate* apNetworkConfiguration) |
|
515 { |
|
516 TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration)); |
|
517 if (error != KErrNone) { |
|
518 return false; |
|
519 } |
|
520 return true; |
|
521 } |
|
522 |
|
523 void QNetworkConfigurationManagerPrivate::readNetworkConfigurationValuesFromCommsDbL( |
|
524 TUint32 aApId, QNetworkConfigurationPrivate* apNetworkConfiguration) |
|
525 { |
|
526 CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB); |
|
527 CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC(); |
|
528 TBuf<KCommsDbSvrMaxColumnNameLength> name; |
|
529 |
|
530 CApUtils* pApUtils = CApUtils::NewLC(*ipCommsDB); |
|
531 TUint32 apId = pApUtils->WapIdFromIapIdL(aApId); |
|
532 |
|
533 pDataHandler->AccessPointDataL(apId,*pAPItem); |
|
534 pAPItem->ReadTextL(EApIapName, name); |
|
535 if (name.Compare(_L("Easy WLAN")) == 0) { |
|
536 // "Easy WLAN" won't be accepted to the Configurations list |
|
537 User::Leave(KErrNotFound); |
|
538 } |
|
539 |
|
540 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(aApId)); |
|
541 |
|
542 QT_TRYCATCH_LEAVING(apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length())); |
|
543 apNetworkConfiguration->isValid = true; |
|
544 apNetworkConfiguration->id = ident; |
|
545 apNetworkConfiguration->numericId = aApId; |
|
546 apNetworkConfiguration->connectionId = 0; |
|
547 apNetworkConfiguration->state = (QNetworkConfiguration::Defined); |
|
548 apNetworkConfiguration->type = QNetworkConfiguration::InternetAccessPoint; |
|
549 apNetworkConfiguration->purpose = QNetworkConfiguration::UnknownPurpose; |
|
550 apNetworkConfiguration->roamingSupported = false; |
|
551 switch (pAPItem->BearerTypeL()) { |
|
552 case EApBearerTypeCSD: |
|
553 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::Bearer2G; |
|
554 break; |
|
555 case EApBearerTypeGPRS: |
|
556 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::Bearer2G; |
|
557 break; |
|
558 case EApBearerTypeHSCSD: |
|
559 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerHSPA; |
|
560 break; |
|
561 case EApBearerTypeCDMA: |
|
562 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerCDMA2000; |
|
563 break; |
|
564 case EApBearerTypeWLAN: |
|
565 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerWLAN; |
|
566 break; |
|
567 case EApBearerTypeLAN: |
|
568 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerEthernet; |
|
569 break; |
|
570 case EApBearerTypeLANModem: |
|
571 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerEthernet; |
|
572 break; |
|
573 default: |
|
574 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
575 break; |
|
576 } |
|
577 apNetworkConfiguration->manager = this; |
|
578 |
|
579 CleanupStack::PopAndDestroy(pApUtils); |
|
580 CleanupStack::PopAndDestroy(pAPItem); |
|
581 CleanupStack::PopAndDestroy(pDataHandler); |
|
582 } |
|
583 #endif |
|
584 |
|
585 QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() |
|
586 { |
|
587 QNetworkConfiguration config; |
|
588 |
|
589 if (iInitOk) { |
|
590 stopCommsDatabaseNotifications(); |
|
591 TRAP_IGNORE(config = defaultConfigurationL()); |
|
592 startCommsDatabaseNotifications(); |
|
593 } |
|
594 return config; |
|
595 } |
|
596 |
|
597 QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfigurationL() |
|
598 { |
|
599 QNetworkConfiguration item; |
|
600 |
|
601 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
602 // Check Default Connection (SNAP or IAP) |
|
603 TCmDefConnValue defaultConnectionValue; |
|
604 iCmManager.ReadDefConnL(defaultConnectionValue); |
|
605 if (defaultConnectionValue.iType == ECmDefConnDestination) { |
|
606 QString iface = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX+QString::number(qHash(defaultConnectionValue.iId)); |
|
607 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.value(iface); |
|
608 if (priv.data() != 0) { |
|
609 item.d = priv; |
|
610 } |
|
611 } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) { |
|
612 QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(defaultConnectionValue.iId)); |
|
613 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
614 if (priv.data() != 0) { |
|
615 item.d = priv; |
|
616 } |
|
617 } |
|
618 #endif |
|
619 |
|
620 if (!item.isValid()) { |
|
621 QString iface = QString::number(qHash(KUserChoiceIAPId)); |
|
622 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = userChoiceConfigurations.value(iface); |
|
623 if (priv.data() != 0) { |
|
624 item.d = priv; |
|
625 } |
|
626 } |
|
627 |
|
628 return item; |
|
629 } |
|
630 |
|
631 void QNetworkConfigurationManagerPrivate::updateActiveAccessPoints() |
|
632 { |
|
633 bool online = false; |
|
634 QList<QString> inactiveConfigs = accessPointConfigurations.keys(); |
|
635 |
|
636 TRequestStatus status; |
|
637 TUint connectionCount; |
|
638 iConnectionMonitor.GetConnectionCount(connectionCount, status); |
|
639 User::WaitForRequest(status); |
|
640 |
|
641 // Go through all connections and set state of related IAPs to Active. |
|
642 // Status needs to be checked carefully, because ConnMon lists also e.g. |
|
643 // WLAN connections that are being currently tried --> we don't want to |
|
644 // state these as active. |
|
645 TUint connectionId; |
|
646 TUint subConnectionCount; |
|
647 TUint apId; |
|
648 TInt connectionStatus; |
|
649 if (status.Int() == KErrNone) { |
|
650 for (TUint i = 1; i <= connectionCount; i++) { |
|
651 iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); |
|
652 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
653 User::WaitForRequest(status); |
|
654 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); |
|
655 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
656 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
|
657 if (!priv.data()) { |
|
658 // If IAP was not found, check if the update was about EasyWLAN |
|
659 priv = configurationFromEasyWlan(apId, connectionId); |
|
660 // Change the ident correspondingly |
|
661 if (priv.data()) { |
|
662 ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(priv.data()->numericId)); |
|
663 } |
|
664 } |
|
665 #endif |
|
666 if (priv.data()) { |
|
667 iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status); |
|
668 User::WaitForRequest(status); |
|
669 |
|
670 if (connectionStatus == KLinkLayerOpen) { |
|
671 online = true; |
|
672 inactiveConfigs.removeOne(ident); |
|
673 priv.data()->connectionId = connectionId; |
|
674 // Configuration is Active |
|
675 changeConfigurationStateTo(priv, QNetworkConfiguration::Active); |
|
676 } |
|
677 } |
|
678 } |
|
679 } |
|
680 |
|
681 // Make sure that state of rest of the IAPs won't be Active |
|
682 foreach (const QString &iface, inactiveConfigs) { |
|
683 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
684 if (priv.data()) { |
|
685 // Configuration is either Defined or Discovered |
|
686 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered); |
|
687 } |
|
688 } |
|
689 |
|
690 if (iOnline != online) { |
|
691 iOnline = online; |
|
692 emit this->onlineStateChanged(online); |
|
693 } |
|
694 } |
|
695 |
|
696 void QNetworkConfigurationManagerPrivate::updateAvailableAccessPoints() |
|
697 { |
|
698 if (!ipAccessPointsAvailabilityScanner) { |
|
699 ipAccessPointsAvailabilityScanner = new AccessPointsAvailabilityScanner(*this, iConnectionMonitor); |
|
700 } |
|
701 if (ipAccessPointsAvailabilityScanner) { |
|
702 // Scanning may take a while because WLAN scanning will be done (if device supports WLAN). |
|
703 ipAccessPointsAvailabilityScanner->StartScanning(); |
|
704 } |
|
705 } |
|
706 |
|
707 void QNetworkConfigurationManagerPrivate::accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo) |
|
708 { |
|
709 iUpdateGoingOn = false; |
|
710 if (scanSuccessful) { |
|
711 QList<QString> unavailableConfigs = accessPointConfigurations.keys(); |
|
712 |
|
713 // Set state of returned IAPs to Discovered |
|
714 // if state is not already Active |
|
715 for(TUint i=0; i<iapInfo.iCount; i++) { |
|
716 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapInfo.iIap[i].iIapId)); |
|
717 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
718 if (priv.data()) { |
|
719 unavailableConfigs.removeOne(ident); |
|
720 if (priv.data()->state < QNetworkConfiguration::Active) { |
|
721 // Configuration is either Discovered or Active |
|
722 changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered); |
|
723 } |
|
724 } |
|
725 } |
|
726 |
|
727 // Make sure that state of rest of the IAPs won't be Active |
|
728 foreach (const QString &iface, unavailableConfigs) { |
|
729 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
730 if (priv.data()) { |
|
731 // Configuration is Defined |
|
732 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered); |
|
733 } |
|
734 } |
|
735 } |
|
736 |
|
737 updateStatesToSnaps(); |
|
738 |
|
739 if (!iFirstUpdate) { |
|
740 startCommsDatabaseNotifications(); |
|
741 emit this->configurationUpdateComplete(); |
|
742 } |
|
743 } |
|
744 |
|
745 void QNetworkConfigurationManagerPrivate::updateStatesToSnaps() |
|
746 { |
|
747 // Go through SNAPs and set correct state to SNAPs |
|
748 foreach (const QString &iface, snapConfigurations.keys()) { |
|
749 bool discovered = false; |
|
750 bool active = false; |
|
751 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.value(iface); |
|
752 // => Check if one of the IAPs of the SNAP is discovered or active |
|
753 // => If one of IAPs is active, also SNAP is active |
|
754 // => If one of IAPs is discovered but none of the IAPs is active, SNAP is discovered |
|
755 for (int i=0; i<priv->serviceNetworkMembers.count(); i++) { |
|
756 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv2 = priv->serviceNetworkMembers[i]; |
|
757 if ((priv->serviceNetworkMembers[i]->state & QNetworkConfiguration::Active) |
|
758 == QNetworkConfiguration::Active) { |
|
759 active = true; |
|
760 break; |
|
761 } else if ((priv->serviceNetworkMembers[i]->state & QNetworkConfiguration::Discovered) |
|
762 == QNetworkConfiguration::Discovered) { |
|
763 discovered = true; |
|
764 } |
|
765 } |
|
766 if (active) { |
|
767 changeConfigurationStateTo(priv, QNetworkConfiguration::Active); |
|
768 } else if (discovered) { |
|
769 changeConfigurationStateTo(priv, QNetworkConfiguration::Discovered); |
|
770 } else { |
|
771 changeConfigurationStateTo(priv, QNetworkConfiguration::Defined); |
|
772 } |
|
773 } |
|
774 } |
|
775 |
|
776 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
777 void QNetworkConfigurationManagerPrivate::updateMobileBearerToConfigs(TConnMonBearerInfo bearerInfo) |
|
778 { |
|
779 foreach (const QString &ii, accessPointConfigurations.keys()) { |
|
780 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> p = |
|
781 accessPointConfigurations.value(ii); |
|
782 if (p->bearer >= QNetworkConfigurationPrivate::Bearer2G && |
|
783 p->bearer <= QNetworkConfigurationPrivate::BearerHSPA) { |
|
784 switch (bearerInfo) { |
|
785 case EBearerInfoCSD: p->bearer = QNetworkConfigurationPrivate::Bearer2G; break; |
|
786 case EBearerInfoWCDMA: p->bearer = QNetworkConfigurationPrivate::BearerWCDMA; break; |
|
787 case EBearerInfoCDMA2000: p->bearer = QNetworkConfigurationPrivate::BearerCDMA2000; break; |
|
788 case EBearerInfoGPRS: p->bearer = QNetworkConfigurationPrivate::Bearer2G; break; |
|
789 case EBearerInfoHSCSD: p->bearer = QNetworkConfigurationPrivate::Bearer2G; break; |
|
790 case EBearerInfoEdgeGPRS: p->bearer = QNetworkConfigurationPrivate::Bearer2G; break; |
|
791 case EBearerInfoWcdmaCSD: p->bearer = QNetworkConfigurationPrivate::BearerWCDMA; break; |
|
792 case EBearerInfoHSDPA: p->bearer = QNetworkConfigurationPrivate::BearerHSPA; break; |
|
793 case EBearerInfoHSUPA: p->bearer = QNetworkConfigurationPrivate::BearerHSPA; break; |
|
794 case EBearerInfoHSxPA: p->bearer = QNetworkConfigurationPrivate::BearerHSPA; break; |
|
795 } |
|
796 } |
|
797 } |
|
798 } |
|
799 #endif |
|
800 |
|
801 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData, |
|
802 QNetworkConfiguration::StateFlags newState) |
|
803 { |
|
804 if (newState != sharedData.data()->state) { |
|
805 sharedData.data()->state = newState; |
|
806 QNetworkConfiguration item; |
|
807 item.d = sharedData; |
|
808 if (!iFirstUpdate) { |
|
809 emit configurationChanged(item); |
|
810 } |
|
811 return true; |
|
812 } |
|
813 return false; |
|
814 } |
|
815 |
|
816 /* changeConfigurationStateAtMinTo function does not overwrite possible better |
|
817 * state (e.g. Discovered state does not overwrite Active state) but |
|
818 * makes sure that state is at minimum given state. |
|
819 */ |
|
820 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateAtMinTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData, |
|
821 QNetworkConfiguration::StateFlags newState) |
|
822 { |
|
823 if ((newState | sharedData.data()->state) != sharedData.data()->state) { |
|
824 sharedData.data()->state = (sharedData.data()->state | newState); |
|
825 QNetworkConfiguration item; |
|
826 item.d = sharedData; |
|
827 if (!iFirstUpdate) { |
|
828 emit configurationChanged(item); |
|
829 } |
|
830 return true; |
|
831 } |
|
832 return false; |
|
833 } |
|
834 |
|
835 /* changeConfigurationStateAtMaxTo function overwrites possible better |
|
836 * state (e.g. Discovered state overwrites Active state) and |
|
837 * makes sure that state is at maximum given state (e.g. Discovered state |
|
838 * does not overwrite Defined state). |
|
839 */ |
|
840 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateAtMaxTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData, |
|
841 QNetworkConfiguration::StateFlags newState) |
|
842 { |
|
843 if ((newState & sharedData.data()->state) != sharedData.data()->state) { |
|
844 sharedData.data()->state = (newState & sharedData.data()->state); |
|
845 QNetworkConfiguration item; |
|
846 item.d = sharedData; |
|
847 if (!iFirstUpdate) { |
|
848 emit configurationChanged(item); |
|
849 } |
|
850 return true; |
|
851 } |
|
852 return false; |
|
853 } |
|
854 |
|
855 void QNetworkConfigurationManagerPrivate::startCommsDatabaseNotifications() |
|
856 { |
|
857 if (!iWaitingCommsDatabaseNotifications) { |
|
858 iWaitingCommsDatabaseNotifications = ETrue; |
|
859 if (!IsActive()) { |
|
860 SetActive(); |
|
861 // Start waiting for new notification |
|
862 ipCommsDB->RequestNotification(iStatus); |
|
863 } |
|
864 } |
|
865 } |
|
866 |
|
867 void QNetworkConfigurationManagerPrivate::stopCommsDatabaseNotifications() |
|
868 { |
|
869 if (iWaitingCommsDatabaseNotifications) { |
|
870 iWaitingCommsDatabaseNotifications = EFalse; |
|
871 if (!IsActive()) { |
|
872 SetActive(); |
|
873 // Make sure that notifier recorded events will not be returned |
|
874 // as soon as the client issues the next RequestNotification() request. |
|
875 ipCommsDB->RequestNotification(iStatus); |
|
876 ipCommsDB->CancelRequestNotification(); |
|
877 } else { |
|
878 ipCommsDB->CancelRequestNotification(); |
|
879 } |
|
880 } |
|
881 } |
|
882 |
|
883 void QNetworkConfigurationManagerPrivate::RunL() |
|
884 { |
|
885 if (iStatus != KErrCancel) { |
|
886 // By default, start relistening notifications. Stop only if interesting event occured. |
|
887 iWaitingCommsDatabaseNotifications = true; |
|
888 RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); |
|
889 switch (event) { |
|
890 case RDbNotifier::ECommit: /** A transaction has been committed. */ |
|
891 case RDbNotifier::ERecover: /** The database has been recovered */ |
|
892 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
893 qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); |
|
894 #endif |
|
895 // Mark that there is update pending. No need to ask more events, |
|
896 // as we know we will be updating anyway when the timer expires. |
|
897 if (!iUpdatePending) { |
|
898 iUpdatePending = true; |
|
899 iWaitingCommsDatabaseNotifications = false; |
|
900 // Update after random time, so that many processes won't |
|
901 // start updating simultaneously |
|
902 updateConfigurationsAfterRandomTime(); |
|
903 } |
|
904 break; |
|
905 default: |
|
906 // Do nothing |
|
907 break; |
|
908 } |
|
909 } |
|
910 if (iWaitingCommsDatabaseNotifications) { |
|
911 if (!IsActive()) { |
|
912 SetActive(); |
|
913 // Start waiting for new notification |
|
914 ipCommsDB->RequestNotification(iStatus); |
|
915 } |
|
916 } |
|
917 } |
|
918 |
|
919 void QNetworkConfigurationManagerPrivate::DoCancel() |
|
920 { |
|
921 ipCommsDB->CancelRequestNotification(); |
|
922 } |
|
923 |
|
924 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent) |
|
925 { |
|
926 switch (aEvent.EventType()) { |
|
927 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
928 case EConnMonBearerInfoChange: |
|
929 { |
|
930 CConnMonBearerInfoChange* realEvent; |
|
931 realEvent = (CConnMonBearerInfoChange*) &aEvent; |
|
932 TUint connectionId = realEvent->ConnectionId(); |
|
933 if (connectionId == EBearerIdAll) { |
|
934 //Network level event |
|
935 TConnMonBearerInfo bearerInfo = (TConnMonBearerInfo)realEvent->BearerInfo(); |
|
936 updateMobileBearerToConfigs(bearerInfo); |
|
937 } |
|
938 break; |
|
939 } |
|
940 #endif |
|
941 case EConnMonConnectionStatusChange: |
|
942 { |
|
943 CConnMonConnectionStatusChange* realEvent; |
|
944 realEvent = (CConnMonConnectionStatusChange*) &aEvent; |
|
945 TInt connectionStatus = realEvent->ConnectionStatus(); |
|
946 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
947 qDebug() << "QNCM Connection status : " << QString::number(connectionStatus) << " , connection monitor Id : " << realEvent->ConnectionId(); |
|
948 #endif |
|
949 if (connectionStatus == KConfigDaemonStartingRegistration) { |
|
950 TUint connectionId = realEvent->ConnectionId(); |
|
951 TUint subConnectionCount = 0; |
|
952 TUint apId; |
|
953 TRequestStatus status; |
|
954 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
955 User::WaitForRequest(status); |
|
956 |
|
957 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); |
|
958 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
959 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
|
960 if (!priv.data()) { |
|
961 // Check if status was regarding EasyWLAN |
|
962 priv = configurationFromEasyWlan(apId, connectionId); |
|
963 } |
|
964 #endif |
|
965 if (priv.data()) { |
|
966 priv.data()->connectionId = connectionId; |
|
967 QT_TRYCATCH_LEAVING(emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connecting)); |
|
968 } |
|
969 } else if (connectionStatus == KLinkLayerOpen) { |
|
970 // Connection has been successfully opened |
|
971 TUint connectionId = realEvent->ConnectionId(); |
|
972 TUint subConnectionCount = 0; |
|
973 TUint apId; |
|
974 TRequestStatus status; |
|
975 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
976 User::WaitForRequest(status); |
|
977 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); |
|
978 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
979 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
|
980 if (!priv.data()) { |
|
981 // Check for EasyWLAN |
|
982 priv = configurationFromEasyWlan(apId, connectionId); |
|
983 } |
|
984 #endif |
|
985 if (priv.data()) { |
|
986 priv.data()->connectionId = connectionId; |
|
987 // Configuration is Active |
|
988 QT_TRYCATCH_LEAVING( |
|
989 if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) { |
|
990 updateStatesToSnaps(); |
|
991 } |
|
992 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connected); |
|
993 if (!iOnline) { |
|
994 iOnline = true; |
|
995 emit this->onlineStateChanged(iOnline); |
|
996 } |
|
997 ); |
|
998 } |
|
999 } else if (connectionStatus == KConfigDaemonStartingDeregistration) { |
|
1000 TUint connectionId = realEvent->ConnectionId(); |
|
1001 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId); |
|
1002 if (priv.data()) { |
|
1003 QT_TRYCATCH_LEAVING(emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Closing)); |
|
1004 } |
|
1005 } else if (connectionStatus == KLinkLayerClosed || |
|
1006 connectionStatus == KConnectionClosed) { |
|
1007 // Connection has been closed. Which of the above events is reported, depends on the Symbian |
|
1008 // platform. |
|
1009 TUint connectionId = realEvent->ConnectionId(); |
|
1010 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId); |
|
1011 if (priv.data()) { |
|
1012 // Configuration is either Defined or Discovered |
|
1013 QT_TRYCATCH_LEAVING( |
|
1014 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) { |
|
1015 updateStatesToSnaps(); |
|
1016 } |
|
1017 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Disconnected); |
|
1018 ); |
|
1019 } |
|
1020 |
|
1021 bool online = false; |
|
1022 foreach (const QString &iface, accessPointConfigurations.keys()) { |
|
1023 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
1024 if (priv.data()->state == QNetworkConfiguration::Active) { |
|
1025 online = true; |
|
1026 break; |
|
1027 } |
|
1028 } |
|
1029 if (iOnline != online) { |
|
1030 iOnline = online; |
|
1031 QT_TRYCATCH_LEAVING(emit this->onlineStateChanged(iOnline)); |
|
1032 } |
|
1033 } |
|
1034 } |
|
1035 break; |
|
1036 |
|
1037 case EConnMonIapAvailabilityChange: |
|
1038 { |
|
1039 CConnMonIapAvailabilityChange* realEvent; |
|
1040 realEvent = (CConnMonIapAvailabilityChange*) &aEvent; |
|
1041 TConnMonIapInfo iaps = realEvent->IapAvailability(); |
|
1042 QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys(); |
|
1043 for ( TUint i = 0; i < iaps.Count(); i++ ) { |
|
1044 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iaps.iIap[i].iIapId)); |
|
1045 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
1046 if (priv.data()) { |
|
1047 // Configuration is either Discovered or Active |
|
1048 QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered)); |
|
1049 unDiscoveredConfigs.removeOne(ident); |
|
1050 } |
|
1051 } |
|
1052 foreach (const QString &iface, unDiscoveredConfigs) { |
|
1053 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
1054 if (priv.data()) { |
|
1055 // Configuration is Defined |
|
1056 QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined)); |
|
1057 } |
|
1058 } |
|
1059 // Something has in IAPs, update states to SNAPs |
|
1060 updateStatesToSnaps(); |
|
1061 } |
|
1062 break; |
|
1063 |
|
1064 case EConnMonCreateConnection: |
|
1065 { |
|
1066 // This event is caught to keep connection monitor IDs up-to-date. |
|
1067 CConnMonCreateConnection* realEvent; |
|
1068 realEvent = (CConnMonCreateConnection*) &aEvent; |
|
1069 TUint subConnectionCount = 0; |
|
1070 TUint apId; |
|
1071 TUint connectionId = realEvent->ConnectionId(); |
|
1072 TRequestStatus status; |
|
1073 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
1074 User::WaitForRequest(status); |
|
1075 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); |
|
1076 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
1077 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
|
1078 if (!priv.data()) { |
|
1079 // If IAP was not found, check if the update was about EasyWLAN |
|
1080 priv = configurationFromEasyWlan(apId, connectionId); |
|
1081 } |
|
1082 #endif |
|
1083 if (priv.data()) { |
|
1084 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1085 qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << priv.data()->connectionId << connectionId << priv->name; |
|
1086 #endif |
|
1087 priv.data()->connectionId = connectionId; |
|
1088 } |
|
1089 } |
|
1090 break; |
|
1091 default: |
|
1092 // For unrecognized events |
|
1093 break; |
|
1094 } |
|
1095 } |
|
1096 |
|
1097 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
|
1098 // Tries to derive configuration from EasyWLAN. |
|
1099 // First checks if the interface brought up was EasyWLAN, then derives the real SSID, |
|
1100 // and looks up configuration based on that one. |
|
1101 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::configurationFromEasyWlan(TUint32 apId, TUint connectionId) |
|
1102 { |
|
1103 if (apId == iCmManager.EasyWlanIdL()) { |
|
1104 TRequestStatus status; |
|
1105 TBuf<50> easyWlanNetworkName; |
|
1106 iConnectionMonitor.GetStringAttribute( connectionId, 0, KNetworkName, |
|
1107 easyWlanNetworkName, status ); |
|
1108 User::WaitForRequest(status); |
|
1109 if (status.Int() == KErrNone) { |
|
1110 QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(), easyWlanNetworkName.Length()); |
|
1111 |
|
1112 // Browser through all items and check their name for match |
|
1113 QNetworkConfiguration item; |
|
1114 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
|
1115 accessPointConfigurations.constBegin(); |
|
1116 while (i != accessPointConfigurations.constEnd()) { |
|
1117 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value(); |
|
1118 if (priv.data()->name == realSSID) { |
|
1119 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1120 qDebug() << "QNCM EasyWlan uses real SSID: " << realSSID; |
|
1121 #endif |
|
1122 return priv; |
|
1123 } |
|
1124 ++i; |
|
1125 } |
|
1126 } |
|
1127 } |
|
1128 return QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>(); |
|
1129 } |
|
1130 |
|
1131 bool QNetworkConfigurationManagerPrivate::easyWlanTrueIapId(TUint32& trueIapId) |
|
1132 { |
|
1133 // Check if this is easy wlan id in the first place |
|
1134 if (trueIapId != iCmManager.EasyWlanIdL()) { |
|
1135 return false; |
|
1136 } |
|
1137 // Loop through all connections that connection monitor is aware |
|
1138 // and check for IAPs based on easy WLAN |
|
1139 TRequestStatus status; |
|
1140 TUint connectionCount; |
|
1141 iConnectionMonitor.GetConnectionCount(connectionCount, status); |
|
1142 User::WaitForRequest(status); |
|
1143 TUint connectionId; |
|
1144 TUint subConnectionCount; |
|
1145 TUint apId; |
|
1146 if (status.Int() == KErrNone) { |
|
1147 for (TUint i = 1; i <= connectionCount; i++) { |
|
1148 iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); |
|
1149 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
1150 User::WaitForRequest(status); |
|
1151 if (apId == trueIapId) { |
|
1152 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = |
|
1153 configurationFromEasyWlan(apId, connectionId); |
|
1154 if (priv.data()) { |
|
1155 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1156 qDebug() << "QNCM easyWlanTrueIapId(), found true IAP ID: " << priv.data()->numericId; |
|
1157 #endif |
|
1158 trueIapId = priv.data()->numericId; |
|
1159 return true; |
|
1160 } |
|
1161 } |
|
1162 } |
|
1163 } |
|
1164 return false; |
|
1165 } |
|
1166 |
|
1167 #endif |
|
1168 |
|
1169 // Sessions may use this function to report configuration state changes, |
|
1170 // because on some Symbian platforms (especially Symbian^3) all state changes are not |
|
1171 // reported by the RConnectionMonitor, in particular in relation to stop() call, |
|
1172 // whereas they _are_ reported on RConnection progress notifier used by sessions --> centralize |
|
1173 // this data here so that other sessions may benefit from it too (not all sessions necessarily have |
|
1174 // RConnection progress notifiers available but they relay on having e.g. disconnected information from |
|
1175 // manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome. |
|
1176 void QNetworkConfigurationManagerPrivate::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState) |
|
1177 { |
|
1178 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1179 qDebug() << "QNCM A session reported state change for IAP ID: " << accessPointId << " whose new state is: " << newState; |
|
1180 #endif |
|
1181 switch (newState) { |
|
1182 case QNetworkSession::Disconnected: |
|
1183 { |
|
1184 QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(accessPointId)); |
|
1185 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
1186 if (priv.data()) { |
|
1187 // Configuration is either Defined or Discovered |
|
1188 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) { |
|
1189 updateStatesToSnaps(); |
|
1190 } |
|
1191 emit this->configurationStateChanged( |
|
1192 priv.data()->numericId, priv.data()->connectionId, QNetworkSession::Disconnected); |
|
1193 } |
|
1194 } |
|
1195 break; |
|
1196 default: |
|
1197 break; |
|
1198 } |
|
1199 } |
|
1200 |
|
1201 // Waits for 2..6 seconds. |
|
1202 void QNetworkConfigurationManagerPrivate::updateConfigurationsAfterRandomTime() |
|
1203 { |
|
1204 iTimeToWait = (qAbs(qrand()) % 68) * 100; |
|
1205 if (iTimeToWait < 1000) { |
|
1206 iTimeToWait = 1000; |
|
1207 } |
|
1208 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1209 qDebug("QNCM waiting random time: %d ms", iTimeToWait); |
|
1210 #endif |
|
1211 QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate())); |
|
1212 } |
|
1213 |
|
1214 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId) |
|
1215 { |
|
1216 QNetworkConfiguration item; |
|
1217 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
|
1218 accessPointConfigurations.constBegin(); |
|
1219 while (i != accessPointConfigurations.constEnd()) { |
|
1220 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value(); |
|
1221 if (priv.data()->connectionId == aConnectionId) { |
|
1222 return priv; |
|
1223 } |
|
1224 ++i; |
|
1225 } |
|
1226 return QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>(); |
|
1227 } |
|
1228 |
|
1229 AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(QNetworkConfigurationManagerPrivate& owner, |
|
1230 RConnectionMonitor& connectionMonitor) |
|
1231 : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor) |
|
1232 { |
|
1233 CActiveScheduler::Add(this); |
|
1234 } |
|
1235 |
|
1236 AccessPointsAvailabilityScanner::~AccessPointsAvailabilityScanner() |
|
1237 { |
|
1238 Cancel(); |
|
1239 } |
|
1240 |
|
1241 void AccessPointsAvailabilityScanner::DoCancel() |
|
1242 { |
|
1243 iConnectionMonitor.CancelAsyncRequest(EConnMonGetPckgAttribute); |
|
1244 } |
|
1245 |
|
1246 void AccessPointsAvailabilityScanner::StartScanning() |
|
1247 { |
|
1248 if (iOwner.iFirstUpdate) { |
|
1249 // On first update (the mgr is being instantiated) update only those bearers who |
|
1250 // don't need time-consuming scans (WLAN). |
|
1251 // Note: EBearerIdWCDMA covers also GPRS bearer |
|
1252 iConnectionMonitor.GetPckgAttribute(EBearerIdWCDMA, 0, KIapAvailability, iIapBuf, iStatus); |
|
1253 User::WaitForRequest(iStatus); |
|
1254 if (iStatus.Int() == KErrNone) { |
|
1255 iOwner.accessPointScanningReady(true,iIapBuf()); |
|
1256 } |
|
1257 } else { |
|
1258 iConnectionMonitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iIapBuf, iStatus); |
|
1259 if (!IsActive()) { |
|
1260 SetActive(); |
|
1261 } |
|
1262 } |
|
1263 } |
|
1264 |
|
1265 void AccessPointsAvailabilityScanner::RunL() |
|
1266 { |
|
1267 if (iStatus.Int() != KErrNone) { |
|
1268 iIapBuf().iCount = 0; |
|
1269 QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(false,iIapBuf())); |
|
1270 } else { |
|
1271 QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(true,iIapBuf())); |
|
1272 } |
|
1273 } |
|
1274 #include "moc_qnetworkconfigmanager_s60_p.cpp" |
|
1275 QTM_END_NAMESPACE |