qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp
branchRCL_3
changeset 10 cd2778e5acfe
equal deleted inserted replaced
9:5d007b20cfd0 10:cd2778e5acfe
       
     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