|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qnetworkconfigmanager_s60_p.h" |
|
43 |
|
44 #include <commdb.h> |
|
45 #include <cdbcols.h> |
|
46 #include <d32dbms.h> |
|
47 |
|
48 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
49 #include <cmdestination.h> |
|
50 #include <cmconnectionmethod.h> |
|
51 #include <cmconnectionmethoddef.h> |
|
52 #include <cmpluginwlandef.h> |
|
53 #include <cmpluginpacketdatadef.h> |
|
54 #include <cmplugindialcommondefs.h> |
|
55 #else |
|
56 #include <apaccesspointitem.h> |
|
57 #include <apdatahandler.h> |
|
58 #include <aputils.h> |
|
59 #endif |
|
60 |
|
61 QTM_BEGIN_NAMESPACE |
|
62 |
|
63 static const int KValueThatWillBeAddedToSNAPId = 1000; |
|
64 static const int KUserChoiceIAPId = 0; |
|
65 |
|
66 QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() |
|
67 : QObject(0), CActive(CActive::EPriorityIdle), capFlags(0), iFirstUpdate(true), iInitOk(true) |
|
68 { |
|
69 CActiveScheduler::Add(this); |
|
70 |
|
71 registerPlatformCapabilities(); |
|
72 TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP)); |
|
73 if (error != KErrNone) { |
|
74 iInitOk = false; |
|
75 return; |
|
76 } |
|
77 |
|
78 TRAP_IGNORE(iConnectionMonitor.ConnectL()); |
|
79 TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this)); |
|
80 |
|
81 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
82 TRAP(error, iCmManager.OpenL()); |
|
83 if (error != KErrNone) { |
|
84 iInitOk = false; |
|
85 return; |
|
86 } |
|
87 #endif |
|
88 |
|
89 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
90 cpPriv->name = "UserChoice"; |
|
91 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
92 cpPriv->state = QNetworkConfiguration::Discovered; |
|
93 cpPriv->isValid = true; |
|
94 cpPriv->id = QString::number(qHash(KUserChoiceIAPId)); |
|
95 cpPriv->numericId = KUserChoiceIAPId; |
|
96 cpPriv->connectionId = 0; |
|
97 cpPriv->type = QNetworkConfiguration::UserChoice; |
|
98 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
99 cpPriv->roamingSupported = false; |
|
100 cpPriv->manager = this; |
|
101 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
102 userChoiceConfigurations.insert(cpPriv->id, ptr); |
|
103 |
|
104 updateConfigurations(); |
|
105 updateStatesToSnaps(); |
|
106 |
|
107 updateAvailableAccessPoints(); // On first time updates synchronously (without WLAN scans) |
|
108 |
|
109 // Start monitoring IAP and/or SNAP changes in Symbian CommsDB |
|
110 startCommsDatabaseNotifications(); |
|
111 iFirstUpdate = false; |
|
112 } |
|
113 |
|
114 QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() |
|
115 { |
|
116 Cancel(); |
|
117 |
|
118 QList<QString> configIdents = snapConfigurations.keys(); |
|
119 foreach(QString oldIface, configIdents) { |
|
120 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.take(oldIface); |
|
121 priv->isValid = false; |
|
122 priv->id.clear(); |
|
123 } |
|
124 |
|
125 configIdents = accessPointConfigurations.keys(); |
|
126 foreach(QString oldIface, configIdents) { |
|
127 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(oldIface); |
|
128 priv->isValid = false; |
|
129 priv->id.clear(); |
|
130 } |
|
131 |
|
132 configIdents = userChoiceConfigurations.keys(); |
|
133 foreach(QString oldIface, configIdents) { |
|
134 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = userChoiceConfigurations.take(oldIface); |
|
135 priv->isValid = false; |
|
136 priv->id.clear(); |
|
137 priv->manager = 0; |
|
138 } |
|
139 |
|
140 iConnectionMonitor.CancelNotifications(); |
|
141 iConnectionMonitor.Close(); |
|
142 |
|
143 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
144 iCmManager.Close(); |
|
145 #endif |
|
146 |
|
147 delete ipAccessPointsAvailabilityScanner; |
|
148 |
|
149 // CCommsDatabase destructor uses cleanup stack. Since QNetworkConfigurationManager |
|
150 // is a global static, but the time we are here, E32Main() has been exited already and |
|
151 // the thread's default cleanup stack has been deleted. Without this line, a |
|
152 // 'E32USER-CBase 69' -panic will occur. |
|
153 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
154 delete ipCommsDB; |
|
155 delete cleanup; |
|
156 } |
|
157 |
|
158 |
|
159 void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities() |
|
160 { |
|
161 capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces; |
|
162 capFlags |= QNetworkConfigurationManager::DirectConnectionRouting; |
|
163 capFlags |= QNetworkConfigurationManager::SystemSessionSupport; |
|
164 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
165 capFlags |= QNetworkConfigurationManager::ApplicationLevelRoaming; |
|
166 capFlags |= QNetworkConfigurationManager::ForcedRoaming; |
|
167 #endif |
|
168 capFlags |= QNetworkConfigurationManager::DataStatistics; |
|
169 } |
|
170 |
|
171 void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() |
|
172 { |
|
173 if (!iInitOk || iUpdateGoingOn) { |
|
174 return; |
|
175 } |
|
176 iUpdateGoingOn = true; |
|
177 |
|
178 stopCommsDatabaseNotifications(); |
|
179 updateConfigurations(); // Synchronous call |
|
180 updateAvailableAccessPoints(); // Asynchronous call |
|
181 } |
|
182 |
|
183 void QNetworkConfigurationManagerPrivate::updateConfigurations() |
|
184 { |
|
185 if (!iInitOk) { |
|
186 return; |
|
187 } |
|
188 |
|
189 TRAP_IGNORE(updateConfigurationsL()); |
|
190 } |
|
191 |
|
192 void QNetworkConfigurationManagerPrivate::updateConfigurationsL() |
|
193 { |
|
194 QList<QString> knownConfigs = accessPointConfigurations.keys(); |
|
195 QList<QString> knownSnapConfigs = snapConfigurations.keys(); |
|
196 |
|
197 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
198 // S60 version is >= Series60 3rd Edition Feature Pack 2 |
|
199 TInt error = KErrNone; |
|
200 |
|
201 // Loop through all IAPs |
|
202 RArray<TUint32> connectionMethods; // IAPs |
|
203 CleanupClosePushL(connectionMethods); |
|
204 iCmManager.ConnectionMethodL(connectionMethods); |
|
205 for(int i = 0; i < connectionMethods.Count(); i++) { |
|
206 RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]); |
|
207 CleanupClosePushL(connectionMethod); |
|
208 TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); |
|
209 QString ident = QString::number(qHash(iapId)); |
|
210 if (accessPointConfigurations.contains(ident)) { |
|
211 knownConfigs.removeOne(ident); |
|
212 } else { |
|
213 QNetworkConfigurationPrivate* cpPriv = NULL; |
|
214 TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod)); |
|
215 if (error == KErrNone) { |
|
216 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
217 accessPointConfigurations.insert(cpPriv->id, ptr); |
|
218 if (!iFirstUpdate) { |
|
219 QNetworkConfiguration item; |
|
220 item.d = ptr; |
|
221 emit configurationAdded(item); |
|
222 } |
|
223 } |
|
224 } |
|
225 CleanupStack::PopAndDestroy(&connectionMethod); |
|
226 } |
|
227 CleanupStack::PopAndDestroy(&connectionMethods); |
|
228 |
|
229 // Loop through all SNAPs |
|
230 RArray<TUint32> destinations; |
|
231 CleanupClosePushL(destinations); |
|
232 iCmManager.AllDestinationsL(destinations); |
|
233 for(int i = 0; i < destinations.Count(); i++) { |
|
234 RCmDestination destination; |
|
235 destination = iCmManager.DestinationL(destinations[i]); |
|
236 CleanupClosePushL(destination); |
|
237 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 |
|
238 if (snapConfigurations.contains(ident)) { |
|
239 knownSnapConfigs.removeOne(ident); |
|
240 } else { |
|
241 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
242 CleanupStack::PushL(cpPriv); |
|
243 |
|
244 HBufC *pName = destination.NameLC(); |
|
245 cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()); |
|
246 CleanupStack::PopAndDestroy(pName); |
|
247 pName = NULL; |
|
248 |
|
249 cpPriv->isValid = true; |
|
250 cpPriv->id = ident; |
|
251 cpPriv->numericId = destination.Id(); |
|
252 cpPriv->connectionId = 0; |
|
253 cpPriv->state = QNetworkConfiguration::Defined; |
|
254 cpPriv->type = QNetworkConfiguration::ServiceNetwork; |
|
255 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
256 cpPriv->roamingSupported = false; |
|
257 cpPriv->manager = this; |
|
258 |
|
259 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
260 snapConfigurations.insert(ident, ptr); |
|
261 if (!iFirstUpdate) { |
|
262 QNetworkConfiguration item; |
|
263 item.d = ptr; |
|
264 emit configurationAdded(item); |
|
265 } |
|
266 |
|
267 CleanupStack::Pop(cpPriv); |
|
268 } |
|
269 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> privSNAP = snapConfigurations.value(ident); |
|
270 |
|
271 for (int j=0; j < destination.ConnectionMethodCount(); j++) { |
|
272 RCmConnectionMethod connectionMethod = destination.ConnectionMethodL(j); |
|
273 CleanupClosePushL(connectionMethod); |
|
274 |
|
275 TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); |
|
276 QString iface = QString::number(qHash(iapId)); |
|
277 // Check that IAP can be found from accessPointConfigurations list |
|
278 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
279 if (priv.data() == 0) { |
|
280 QNetworkConfigurationPrivate* cpPriv = NULL; |
|
281 TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod)); |
|
282 if (error == KErrNone) { |
|
283 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
284 ptr.data()->serviceNetworkPtr = privSNAP; |
|
285 accessPointConfigurations.insert(cpPriv->id, ptr); |
|
286 if (!iFirstUpdate) { |
|
287 QNetworkConfiguration item; |
|
288 item.d = ptr; |
|
289 emit configurationAdded(item); |
|
290 } |
|
291 privSNAP->serviceNetworkMembers.append(ptr); |
|
292 } |
|
293 } else { |
|
294 knownConfigs.removeOne(iface); |
|
295 // Check that IAP can be found from related SNAP's configuration list |
|
296 bool iapFound = false; |
|
297 for (int i=0; i<privSNAP->serviceNetworkMembers.count(); i++) { |
|
298 if (privSNAP->serviceNetworkMembers[i]->numericId == iapId) { |
|
299 iapFound = true; |
|
300 break; |
|
301 } |
|
302 } |
|
303 if (!iapFound) { |
|
304 priv.data()->serviceNetworkPtr = privSNAP; |
|
305 privSNAP->serviceNetworkMembers.append(priv); |
|
306 } |
|
307 } |
|
308 |
|
309 CleanupStack::PopAndDestroy(&connectionMethod); |
|
310 } |
|
311 |
|
312 if (privSNAP->serviceNetworkMembers.count() > 1) { |
|
313 // Roaming is supported only if SNAP contains more than one IAP |
|
314 privSNAP->roamingSupported = true; |
|
315 } |
|
316 |
|
317 CleanupStack::PopAndDestroy(&destination); |
|
318 } |
|
319 CleanupStack::PopAndDestroy(&destinations); |
|
320 |
|
321 #else |
|
322 // S60 version is < Series60 3rd Edition Feature Pack 2 |
|
323 CCommsDbTableView* pDbTView = ipCommsDB->OpenTableLC(TPtrC(IAP)); |
|
324 |
|
325 // Loop through all IAPs |
|
326 TUint32 apId = 0; |
|
327 TInt retVal = pDbTView->GotoFirstRecord(); |
|
328 while (retVal == KErrNone) { |
|
329 pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId); |
|
330 QString ident = QString::number(qHash(apId)); |
|
331 if (accessPointConfigurations.contains(ident)) { |
|
332 knownConfigs.removeOne(ident); |
|
333 } else { |
|
334 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
335 if (readNetworkConfigurationValuesFromCommsDb(apId, cpPriv)) { |
|
336 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
337 accessPointConfigurations.insert(ident, ptr); |
|
338 if (!iFirstUpdate) { |
|
339 QNetworkConfiguration item; |
|
340 item.d = ptr; |
|
341 emit configurationAdded(item); |
|
342 } |
|
343 } else { |
|
344 delete cpPriv; |
|
345 } |
|
346 } |
|
347 retVal = pDbTView->GotoNextRecord(); |
|
348 } |
|
349 CleanupStack::PopAndDestroy(pDbTView); |
|
350 #endif |
|
351 updateActiveAccessPoints(); |
|
352 |
|
353 foreach (QString oldIface, knownConfigs) { |
|
354 //remove non existing IAP |
|
355 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(oldIface); |
|
356 priv->isValid = false; |
|
357 if (!iFirstUpdate) { |
|
358 QNetworkConfiguration item; |
|
359 item.d = priv; |
|
360 emit configurationRemoved(item); |
|
361 } |
|
362 // Remove non existing IAP from SNAPs |
|
363 QList<QString> snapConfigIdents = snapConfigurations.keys(); |
|
364 foreach (QString iface, snapConfigIdents) { |
|
365 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv2 = snapConfigurations.value(iface); |
|
366 // => Check if one of the IAPs of the SNAP is active |
|
367 for (int i=0; i<priv2->serviceNetworkMembers.count(); i++) { |
|
368 if (priv2->serviceNetworkMembers[i]->numericId == priv->numericId) { |
|
369 priv2->serviceNetworkMembers.removeAt(i); |
|
370 break; |
|
371 } |
|
372 } |
|
373 } |
|
374 } |
|
375 foreach (QString oldIface, knownSnapConfigs) { |
|
376 //remove non existing SNAPs |
|
377 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.take(oldIface); |
|
378 priv->isValid = false; |
|
379 if (!iFirstUpdate) { |
|
380 QNetworkConfiguration item; |
|
381 item.d = priv; |
|
382 emit configurationRemoved(item); |
|
383 } |
|
384 } |
|
385 } |
|
386 |
|
387 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
388 QNetworkConfigurationPrivate* QNetworkConfigurationManagerPrivate::configFromConnectionMethodL( |
|
389 RCmConnectionMethod& connectionMethod) |
|
390 { |
|
391 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
392 CleanupStack::PushL(cpPriv); |
|
393 |
|
394 TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); |
|
395 QString ident = QString::number(qHash(iapId)); |
|
396 |
|
397 HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName); |
|
398 CleanupStack::PushL(pName); |
|
399 cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()); |
|
400 CleanupStack::PopAndDestroy(pName); |
|
401 pName = NULL; |
|
402 |
|
403 TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType); |
|
404 switch (bearerId) { |
|
405 case KCommDbBearerCSD: |
|
406 cpPriv->bearer = QNetworkConfigurationPrivate::Bearer2G; |
|
407 break; |
|
408 case KCommDbBearerWcdma: |
|
409 cpPriv->bearer = QNetworkConfigurationPrivate::BearerWCDMA; |
|
410 break; |
|
411 case KCommDbBearerLAN: |
|
412 cpPriv->bearer = QNetworkConfigurationPrivate::BearerEthernet; |
|
413 break; |
|
414 case KCommDbBearerVirtual: |
|
415 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
416 break; |
|
417 case KCommDbBearerPAN: |
|
418 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
419 break; |
|
420 case KCommDbBearerWLAN: |
|
421 cpPriv->bearer = QNetworkConfigurationPrivate::BearerWLAN; |
|
422 break; |
|
423 default: |
|
424 cpPriv->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
425 break; |
|
426 } |
|
427 |
|
428 TInt error = KErrNone; |
|
429 TUint32 bearerType = connectionMethod.GetIntAttributeL(CMManager::ECmBearerType); |
|
430 switch (bearerType) { |
|
431 case KUidPacketDataBearerType: |
|
432 // "Packet data" Bearer => Mapping is done using "Access point name" |
|
433 TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EPacketDataAPName)); |
|
434 break; |
|
435 case KUidWlanBearerType: |
|
436 // "Wireless LAN" Bearer => Mapping is done using "WLAN network name" = SSID |
|
437 TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EWlanSSID)); |
|
438 break; |
|
439 } |
|
440 if (!pName) { |
|
441 // "Data call" Bearer or "High Speed (GSM)" Bearer => Mapping is done using "Dial-up number" |
|
442 TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EDialDefaultTelNum)); |
|
443 } |
|
444 |
|
445 if (error == KErrNone && pName) { |
|
446 CleanupStack::PushL(pName); |
|
447 cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length()); |
|
448 CleanupStack::PopAndDestroy(pName); |
|
449 pName = NULL; |
|
450 } |
|
451 |
|
452 cpPriv->state = QNetworkConfiguration::Defined; |
|
453 TBool isConnected = connectionMethod.GetBoolAttributeL(CMManager::ECmConnected); |
|
454 if (isConnected) { |
|
455 cpPriv->state = QNetworkConfiguration::Active; |
|
456 } |
|
457 |
|
458 cpPriv->isValid = true; |
|
459 cpPriv->id = ident; |
|
460 cpPriv->numericId = iapId; |
|
461 cpPriv->connectionId = 0; |
|
462 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
|
463 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
464 cpPriv->roamingSupported = false; |
|
465 cpPriv->manager = this; |
|
466 |
|
467 CleanupStack::Pop(cpPriv); |
|
468 return cpPriv; |
|
469 } |
|
470 #else |
|
471 bool QNetworkConfigurationManagerPrivate::readNetworkConfigurationValuesFromCommsDb( |
|
472 TUint32 aApId, QNetworkConfigurationPrivate* apNetworkConfiguration) |
|
473 { |
|
474 TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration)); |
|
475 if (error != KErrNone) { |
|
476 return false; |
|
477 } |
|
478 return true; |
|
479 } |
|
480 |
|
481 void QNetworkConfigurationManagerPrivate::readNetworkConfigurationValuesFromCommsDbL( |
|
482 TUint32 aApId, QNetworkConfigurationPrivate* apNetworkConfiguration) |
|
483 { |
|
484 CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB); |
|
485 CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC(); |
|
486 TBuf<KCommsDbSvrMaxColumnNameLength> name; |
|
487 |
|
488 CApUtils* pApUtils = CApUtils::NewLC(*ipCommsDB); |
|
489 TUint32 apId = pApUtils->WapIdFromIapIdL(aApId); |
|
490 |
|
491 pDataHandler->AccessPointDataL(apId,*pAPItem); |
|
492 pAPItem->ReadTextL(EApIapName, name); |
|
493 if (name.Compare(_L("Easy WLAN")) == 0) { |
|
494 // "Easy WLAN" won't be accepted to the Configurations list |
|
495 User::Leave(KErrNotFound); |
|
496 } |
|
497 |
|
498 QString ident = QString::number(qHash(aApId)); |
|
499 |
|
500 apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length()); |
|
501 apNetworkConfiguration->isValid = true; |
|
502 apNetworkConfiguration->id = ident; |
|
503 apNetworkConfiguration->numericId = aApId; |
|
504 apNetworkConfiguration->connectionId = 0; |
|
505 apNetworkConfiguration->state = (QNetworkConfiguration::Defined); |
|
506 apNetworkConfiguration->type = QNetworkConfiguration::InternetAccessPoint; |
|
507 apNetworkConfiguration->purpose = QNetworkConfiguration::UnknownPurpose; |
|
508 apNetworkConfiguration->roamingSupported = false; |
|
509 switch (pAPItem->BearerTypeL()) { |
|
510 case EApBearerTypeCSD: |
|
511 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::Bearer2G; |
|
512 break; |
|
513 case EApBearerTypeGPRS: |
|
514 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::Bearer2G; |
|
515 break; |
|
516 case EApBearerTypeHSCSD: |
|
517 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerHSPA; |
|
518 break; |
|
519 case EApBearerTypeCDMA: |
|
520 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerCDMA2000; |
|
521 break; |
|
522 case EApBearerTypeWLAN: |
|
523 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerWLAN; |
|
524 break; |
|
525 case EApBearerTypeLAN: |
|
526 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerEthernet; |
|
527 break; |
|
528 case EApBearerTypeLANModem: |
|
529 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerEthernet; |
|
530 break; |
|
531 default: |
|
532 apNetworkConfiguration->bearer = QNetworkConfigurationPrivate::BearerUnknown; |
|
533 break; |
|
534 } |
|
535 apNetworkConfiguration->manager = this; |
|
536 |
|
537 CleanupStack::PopAndDestroy(pApUtils); |
|
538 CleanupStack::PopAndDestroy(pAPItem); |
|
539 CleanupStack::PopAndDestroy(pDataHandler); |
|
540 } |
|
541 #endif |
|
542 |
|
543 QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() |
|
544 { |
|
545 QNetworkConfiguration config; |
|
546 |
|
547 if (iInitOk) { |
|
548 stopCommsDatabaseNotifications(); |
|
549 TRAP_IGNORE(config = defaultConfigurationL()); |
|
550 startCommsDatabaseNotifications(); |
|
551 } |
|
552 |
|
553 return config; |
|
554 } |
|
555 |
|
556 QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfigurationL() |
|
557 { |
|
558 QNetworkConfiguration item; |
|
559 |
|
560 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
|
561 // Check Default Connection (SNAP or IAP) |
|
562 TCmDefConnValue defaultConnectionValue; |
|
563 iCmManager.ReadDefConnL(defaultConnectionValue); |
|
564 if (defaultConnectionValue.iType == ECmDefConnDestination) { |
|
565 QString iface = QString::number(qHash(defaultConnectionValue.iId+KValueThatWillBeAddedToSNAPId)); |
|
566 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.value(iface); |
|
567 if (priv.data() != 0) { |
|
568 item.d = priv; |
|
569 } |
|
570 } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) { |
|
571 QString iface = QString::number(qHash(defaultConnectionValue.iId)); |
|
572 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
573 if (priv.data() != 0) { |
|
574 item.d = priv; |
|
575 } |
|
576 } |
|
577 #endif |
|
578 |
|
579 if (!item.isValid()) { |
|
580 QString iface = QString::number(qHash(KUserChoiceIAPId)); |
|
581 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = userChoiceConfigurations.value(iface); |
|
582 if (priv.data() != 0) { |
|
583 item.d = priv; |
|
584 } |
|
585 } |
|
586 |
|
587 return item; |
|
588 } |
|
589 |
|
590 void QNetworkConfigurationManagerPrivate::updateActiveAccessPoints() |
|
591 { |
|
592 bool online = false; |
|
593 QList<QString> inactiveConfigs = accessPointConfigurations.keys(); |
|
594 |
|
595 TRequestStatus status; |
|
596 TUint connectionCount; |
|
597 iConnectionMonitor.GetConnectionCount(connectionCount, status); |
|
598 User::WaitForRequest(status); |
|
599 |
|
600 // Go through all connections and set state of related IAPs to Active |
|
601 TUint connectionId; |
|
602 TUint subConnectionCount; |
|
603 TUint apId; |
|
604 if (status.Int() == KErrNone) { |
|
605 for (TUint i = 1; i <= connectionCount; i++) { |
|
606 iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); |
|
607 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
608 User::WaitForRequest(status); |
|
609 QString ident = QString::number(qHash(apId)); |
|
610 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
611 if (priv.data()) { |
|
612 online = true; |
|
613 inactiveConfigs.removeOne(ident); |
|
614 priv.data()->connectionId = connectionId; |
|
615 // Configuration is Active |
|
616 changeConfigurationStateTo(priv, QNetworkConfiguration::Active); |
|
617 } |
|
618 } |
|
619 } |
|
620 |
|
621 // Make sure that state of rest of the IAPs won't be Active |
|
622 foreach (QString iface, inactiveConfigs) { |
|
623 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
624 if (priv.data()) { |
|
625 // Configuration is either Defined or Discovered |
|
626 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered); |
|
627 } |
|
628 } |
|
629 |
|
630 if (iOnline != online) { |
|
631 iOnline = online; |
|
632 emit this->onlineStateChanged(iOnline); |
|
633 } |
|
634 } |
|
635 |
|
636 void QNetworkConfigurationManagerPrivate::updateAvailableAccessPoints() |
|
637 { |
|
638 if (!ipAccessPointsAvailabilityScanner) { |
|
639 ipAccessPointsAvailabilityScanner = new AccessPointsAvailabilityScanner(*this, iConnectionMonitor); |
|
640 } |
|
641 if (ipAccessPointsAvailabilityScanner) { |
|
642 // Scanning may take a while because WLAN scanning will be done (if device supports WLAN). |
|
643 ipAccessPointsAvailabilityScanner->StartScanning(); |
|
644 } |
|
645 } |
|
646 |
|
647 void QNetworkConfigurationManagerPrivate::accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo) |
|
648 { |
|
649 iUpdateGoingOn = false; |
|
650 if (scanSuccessful) { |
|
651 QList<QString> unavailableConfigs = accessPointConfigurations.keys(); |
|
652 |
|
653 // Set state of returned IAPs to Discovered |
|
654 // if state is not already Active |
|
655 for(TUint i=0; i<iapInfo.iCount; i++) { |
|
656 QString ident = QString::number(qHash(iapInfo.iIap[i].iIapId)); |
|
657 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
658 if (priv.data()) { |
|
659 unavailableConfigs.removeOne(ident); |
|
660 if (priv.data()->state < QNetworkConfiguration::Active) { |
|
661 // Configuration is either Discovered or Active |
|
662 changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered); |
|
663 } |
|
664 } |
|
665 } |
|
666 |
|
667 // Make sure that state of rest of the IAPs won't be Discovered or Active |
|
668 foreach (QString iface, unavailableConfigs) { |
|
669 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
670 if (priv.data()) { |
|
671 // Configuration is Defined |
|
672 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined); |
|
673 } |
|
674 } |
|
675 } |
|
676 |
|
677 updateStatesToSnaps(); |
|
678 |
|
679 if (!iFirstUpdate) { |
|
680 startCommsDatabaseNotifications(); |
|
681 emit this->configurationUpdateComplete(); |
|
682 } |
|
683 } |
|
684 |
|
685 void QNetworkConfigurationManagerPrivate::updateStatesToSnaps() |
|
686 { |
|
687 // Go through SNAPs and set correct state to SNAPs |
|
688 QList<QString> snapConfigIdents = snapConfigurations.keys(); |
|
689 foreach (QString iface, snapConfigIdents) { |
|
690 bool discovered = false; |
|
691 bool active = false; |
|
692 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.value(iface); |
|
693 // => Check if one of the IAPs of the SNAP is discovered or active |
|
694 // => If one of IAPs is active, also SNAP is active |
|
695 // => If one of IAPs is discovered but none of the IAPs is active, SNAP is discovered |
|
696 for (int i=0; i<priv->serviceNetworkMembers.count(); i++) { |
|
697 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv2 = priv->serviceNetworkMembers[i]; |
|
698 if ((priv->serviceNetworkMembers[i]->state & QNetworkConfiguration::Active) |
|
699 == QNetworkConfiguration::Active) { |
|
700 active = true; |
|
701 break; |
|
702 } else if ((priv->serviceNetworkMembers[i]->state & QNetworkConfiguration::Discovered) |
|
703 == QNetworkConfiguration::Discovered) { |
|
704 discovered = true; |
|
705 } |
|
706 } |
|
707 if (active) { |
|
708 changeConfigurationStateTo(priv, QNetworkConfiguration::Active); |
|
709 } else if (discovered) { |
|
710 changeConfigurationStateTo(priv, QNetworkConfiguration::Discovered); |
|
711 } else { |
|
712 changeConfigurationStateTo(priv, QNetworkConfiguration::Defined); |
|
713 } |
|
714 } |
|
715 } |
|
716 |
|
717 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData, |
|
718 QNetworkConfiguration::StateFlags newState) |
|
719 { |
|
720 if (newState != sharedData.data()->state) { |
|
721 sharedData.data()->state = newState; |
|
722 QNetworkConfiguration item; |
|
723 item.d = sharedData; |
|
724 if (!iFirstUpdate) { |
|
725 emit configurationChanged(item); |
|
726 } |
|
727 return true; |
|
728 } |
|
729 return false; |
|
730 } |
|
731 |
|
732 /* changeConfigurationStateAtMinTo function does not overwrite possible better |
|
733 * state (e.g. Discovered state does not overwrite Active state) but |
|
734 * makes sure that state is at minimum given state. |
|
735 */ |
|
736 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateAtMinTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData, |
|
737 QNetworkConfiguration::StateFlags newState) |
|
738 { |
|
739 if ((newState | sharedData.data()->state) != sharedData.data()->state) { |
|
740 sharedData.data()->state = (sharedData.data()->state | newState); |
|
741 QNetworkConfiguration item; |
|
742 item.d = sharedData; |
|
743 if (!iFirstUpdate) { |
|
744 emit configurationChanged(item); |
|
745 } |
|
746 return true; |
|
747 } |
|
748 return false; |
|
749 } |
|
750 |
|
751 /* changeConfigurationStateAtMaxTo function overwrites possible better |
|
752 * state (e.g. Discovered state overwrites Active state) and |
|
753 * makes sure that state is at maximum given state (e.g. Discovered state |
|
754 * does not overwrite Defined state). |
|
755 */ |
|
756 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateAtMaxTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData, |
|
757 QNetworkConfiguration::StateFlags newState) |
|
758 { |
|
759 if ((newState & sharedData.data()->state) != sharedData.data()->state) { |
|
760 sharedData.data()->state = (newState & sharedData.data()->state); |
|
761 QNetworkConfiguration item; |
|
762 item.d = sharedData; |
|
763 if (!iFirstUpdate) { |
|
764 emit configurationChanged(item); |
|
765 } |
|
766 return true; |
|
767 } |
|
768 return false; |
|
769 } |
|
770 |
|
771 void QNetworkConfigurationManagerPrivate::startCommsDatabaseNotifications() |
|
772 { |
|
773 if (!iWaitingCommsDatabaseNotifications) { |
|
774 iWaitingCommsDatabaseNotifications = ETrue; |
|
775 if (!IsActive()) { |
|
776 SetActive(); |
|
777 // Start waiting for new notification |
|
778 ipCommsDB->RequestNotification(iStatus); |
|
779 } |
|
780 } |
|
781 } |
|
782 |
|
783 void QNetworkConfigurationManagerPrivate::stopCommsDatabaseNotifications() |
|
784 { |
|
785 if (iWaitingCommsDatabaseNotifications) { |
|
786 iWaitingCommsDatabaseNotifications = EFalse; |
|
787 if (!IsActive()) { |
|
788 SetActive(); |
|
789 // Make sure that notifier recorded events will not be returned |
|
790 // as soon as the client issues the next RequestNotification() request. |
|
791 ipCommsDB->RequestNotification(iStatus); |
|
792 ipCommsDB->CancelRequestNotification(); |
|
793 } else { |
|
794 ipCommsDB->CancelRequestNotification(); |
|
795 } |
|
796 } |
|
797 } |
|
798 |
|
799 void QNetworkConfigurationManagerPrivate::RunL() |
|
800 { |
|
801 if (iStatus != KErrCancel) { |
|
802 RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); |
|
803 switch (event) { |
|
804 // case RDbNotifier::EUnlock: /** All read locks have been removed. */ |
|
805 case RDbNotifier::ECommit: /** A transaction has been committed. */ |
|
806 case RDbNotifier::ERollback: /** A transaction has been rolled back */ |
|
807 case RDbNotifier::ERecover: /** The database has been recovered */ |
|
808 // Note that if further database events occur while a client is handling |
|
809 // a request completion, the notifier records the most significant database |
|
810 // event and this is signalled as soon as the client issues the next |
|
811 // RequestNotification() request. |
|
812 // => Stop recording notifications |
|
813 stopCommsDatabaseNotifications(); |
|
814 TRAPD(error, updateConfigurationsL()); |
|
815 if (error == KErrNone) { |
|
816 updateStatesToSnaps(); |
|
817 } |
|
818 iWaitingCommsDatabaseNotifications = true; |
|
819 break; |
|
820 default: |
|
821 // Do nothing |
|
822 break; |
|
823 } |
|
824 } |
|
825 |
|
826 if (iWaitingCommsDatabaseNotifications) { |
|
827 if (!IsActive()) { |
|
828 SetActive(); |
|
829 // Start waiting for new notification |
|
830 ipCommsDB->RequestNotification(iStatus); |
|
831 } |
|
832 } |
|
833 } |
|
834 |
|
835 void QNetworkConfigurationManagerPrivate::DoCancel() |
|
836 { |
|
837 ipCommsDB->CancelRequestNotification(); |
|
838 } |
|
839 |
|
840 |
|
841 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent) |
|
842 { |
|
843 switch (aEvent.EventType()) { |
|
844 case EConnMonCreateConnection: |
|
845 { |
|
846 CConnMonCreateConnection* realEvent; |
|
847 realEvent = (CConnMonCreateConnection*) &aEvent; |
|
848 TUint subConnectionCount = 0; |
|
849 TUint apId; |
|
850 TUint connectionId = realEvent->ConnectionId(); |
|
851 TRequestStatus status; |
|
852 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
853 User::WaitForRequest(status); |
|
854 QString ident = QString::number(qHash(apId)); |
|
855 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
856 if (priv.data()) { |
|
857 priv.data()->connectionId = connectionId; |
|
858 // Configuration is Active |
|
859 if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) { |
|
860 updateStatesToSnaps(); |
|
861 } |
|
862 if (!iOnline) { |
|
863 iOnline = true; |
|
864 emit this->onlineStateChanged(iOnline); |
|
865 } |
|
866 } |
|
867 } |
|
868 break; |
|
869 |
|
870 case EConnMonDeleteConnection: |
|
871 { |
|
872 CConnMonDeleteConnection* realEvent; |
|
873 realEvent = (CConnMonDeleteConnection*) &aEvent; |
|
874 TUint connectionId = realEvent->ConnectionId(); |
|
875 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId); |
|
876 if (priv.data()) { |
|
877 priv.data()->connectionId = 0; |
|
878 // Configuration is either Defined or Discovered |
|
879 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) { |
|
880 updateStatesToSnaps(); |
|
881 } |
|
882 } |
|
883 |
|
884 bool online = false; |
|
885 QList<QString> iapConfigs = accessPointConfigurations.keys(); |
|
886 foreach (QString iface, iapConfigs) { |
|
887 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
888 if (priv.data()->state == QNetworkConfiguration::Active) { |
|
889 online = true; |
|
890 break; |
|
891 } |
|
892 } |
|
893 if (iOnline != online) { |
|
894 iOnline = online; |
|
895 emit this->onlineStateChanged(iOnline); |
|
896 } |
|
897 } |
|
898 break; |
|
899 |
|
900 case EConnMonIapAvailabilityChange: |
|
901 { |
|
902 CConnMonIapAvailabilityChange* realEvent; |
|
903 realEvent = (CConnMonIapAvailabilityChange*) &aEvent; |
|
904 TConnMonIapInfo iaps = realEvent->IapAvailability(); |
|
905 QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys(); |
|
906 for ( TUint i = 0; i < iaps.Count(); i++ ) { |
|
907 QString ident = QString::number(qHash(iaps.iIap[i].iIapId)); |
|
908 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
909 if (priv.data()) { |
|
910 // Configuration is either Discovered or Active |
|
911 changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered); |
|
912 unDiscoveredConfigs.removeOne(ident); |
|
913 } |
|
914 } |
|
915 foreach (QString iface, unDiscoveredConfigs) { |
|
916 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
917 if (priv.data()) { |
|
918 // Configuration is Defined |
|
919 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined); |
|
920 } |
|
921 } |
|
922 } |
|
923 break; |
|
924 |
|
925 default: |
|
926 // For unrecognized events |
|
927 break; |
|
928 } |
|
929 } |
|
930 |
|
931 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId) |
|
932 { |
|
933 QNetworkConfiguration item; |
|
934 |
|
935 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
|
936 accessPointConfigurations.constBegin(); |
|
937 while (i != accessPointConfigurations.constEnd()) { |
|
938 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value(); |
|
939 if (priv.data()->connectionId == aConnectionId) { |
|
940 return priv; |
|
941 } |
|
942 ++i; |
|
943 } |
|
944 |
|
945 return QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>(); |
|
946 } |
|
947 |
|
948 AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(QNetworkConfigurationManagerPrivate& owner, |
|
949 RConnectionMonitor& connectionMonitor) |
|
950 : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor) |
|
951 { |
|
952 CActiveScheduler::Add(this); |
|
953 } |
|
954 |
|
955 AccessPointsAvailabilityScanner::~AccessPointsAvailabilityScanner() |
|
956 { |
|
957 Cancel(); |
|
958 } |
|
959 |
|
960 void AccessPointsAvailabilityScanner::DoCancel() |
|
961 { |
|
962 iConnectionMonitor.CancelAsyncRequest(EConnMonGetPckgAttribute); |
|
963 } |
|
964 |
|
965 void AccessPointsAvailabilityScanner::StartScanning() |
|
966 { |
|
967 if (iOwner.iFirstUpdate) { |
|
968 // On first update (the mgr is being instantiated) update only those bearers who |
|
969 // don't need time-consuming scans (WLAN). |
|
970 // Note: EBearerIdWCDMA covers also GPRS bearer |
|
971 iConnectionMonitor.GetPckgAttribute(EBearerIdWCDMA, 0, KIapAvailability, iIapBuf, iStatus); |
|
972 User::WaitForRequest(iStatus); |
|
973 if (iStatus.Int() == KErrNone) { |
|
974 iOwner.accessPointScanningReady(true,iIapBuf()); |
|
975 } |
|
976 } else { |
|
977 iConnectionMonitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iIapBuf, iStatus); |
|
978 if (!IsActive()) { |
|
979 SetActive(); |
|
980 } |
|
981 } |
|
982 } |
|
983 |
|
984 void AccessPointsAvailabilityScanner::RunL() |
|
985 { |
|
986 if (iStatus.Int() != KErrNone) { |
|
987 iIapBuf().iCount = 0; |
|
988 iOwner.accessPointScanningReady(false,iIapBuf()); |
|
989 } else { |
|
990 iOwner.accessPointScanningReady(true,iIapBuf()); |
|
991 } |
|
992 } |
|
993 #include "moc_qnetworkconfigmanager_s60_p.cpp" |
|
994 QTM_END_NAMESPACE |