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