qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
--- a/qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp	Fri Jun 11 14:26:25 2010 +0300
+++ b/qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp	Wed Jun 23 19:08:38 2010 +0300
@@ -45,7 +45,6 @@
 #include <cdbcols.h>
 #include <d32dbms.h>
 #include <nifvar.h>
-#include <QEventLoop>
 #include <QTimer>
 #include <QTime>  // For randgen seeding
 #include <QtCore> // For randgen seeding
@@ -70,21 +69,17 @@
 
 QTM_BEGIN_NAMESPACE
 
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
-    static const int KValueThatWillBeAddedToSNAPId = 1000;
-#endif
 static const int KUserChoiceIAPId = 0;
 
 QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
-    : QObject(0), CActive(CActive::EPriorityIdle), capFlags(0),
-    iFirstUpdate(true), iInitOk(true), iIgnoringUpdates(false),
-    iTimeToWait(0), iIgnoreEventLoop(0)
+    : QObject(0), CActive(CActive::EPriorityHigh), capFlags(0),
+    iFirstUpdate(true), iInitOk(true), iUpdatePending(false),
+    iTimeToWait(0)
 {
     CActiveScheduler::Add(this);
 
     // Seed the randomgenerator
     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid());
-    iIgnoreEventLoop = new QEventLoop(this);
 
     registerPlatformCapabilities();
     TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP));
@@ -94,6 +89,9 @@
     }
 
     TRAP_IGNORE(iConnectionMonitor.ConnectL());
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE    
+    TRAP_IGNORE(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1));
+#endif    
     TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
 
 #ifdef SNAP_FUNCTIONALITY_AVAILABLE    
@@ -167,6 +165,25 @@
     delete cleanup;
 }
 
+void QNetworkConfigurationManagerPrivate::delayedConfigurationUpdate()
+{
+    if (iUpdatePending) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+        qDebug("QNCM delayed configuration update (ECommit or ERecover occurred).");
+#endif
+        TRAPD(error, updateConfigurationsL());
+        if (error == KErrNone) {
+            updateStatesToSnaps();
+        }
+        iUpdatePending = false;
+        // Start monitoring again.
+        if (!IsActive()) {
+            SetActive();
+            // Start waiting for new notification
+            ipCommsDB->RequestNotification(iStatus);
+        }
+    }
+}
 
 void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities()
 {
@@ -198,7 +215,6 @@
     if (!iInitOk) {
         return;
     }
-
     TRAP_IGNORE(updateConfigurationsL());
 }
 
@@ -219,7 +235,7 @@
         RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]);
         CleanupClosePushL(connectionMethod);
         TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
-        QString ident = QString::number(qHash(iapId));
+        QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
         if (accessPointConfigurations.contains(ident)) {
             knownConfigs.removeOne(ident);
         } else {
@@ -231,7 +247,11 @@
                 if (!iFirstUpdate) {
                     QNetworkConfiguration item;
                     item.d = ptr;
-                    emit configurationAdded(item);
+                    // Emit configuration added. Connected slots may throw execptions
+                    // which propagate here --> must be converted to leaves (standard
+                    // std::exception would cause any TRAP trapping this function to terminate
+                    // program).
+                    QT_TRYCATCH_LEAVING(emit configurationAdded(item));
                 }
             }
         }
@@ -247,15 +267,14 @@
         RCmDestination destination;
         destination = iCmManager.DestinationL(destinations[i]);
         CleanupClosePushL(destination);
-        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
+        QString ident = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX+QString::number(qHash(destination.Id()));
         if (snapConfigurations.contains(ident)) {
             knownSnapConfigs.removeOne(ident);
         } else {
             QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
-            CleanupStack::PushL(cpPriv);
     
             HBufC *pName = destination.NameLC();
-            cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length());
+            QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
             CleanupStack::PopAndDestroy(pName);
             pName = NULL;
     
@@ -274,10 +293,8 @@
             if (!iFirstUpdate) {
                 QNetworkConfiguration item;
                 item.d = ptr;
-                emit configurationAdded(item);
+                QT_TRYCATCH_LEAVING(emit configurationAdded(item));
             }
-            
-            CleanupStack::Pop(cpPriv);
         }
         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> privSNAP = snapConfigurations.value(ident);
             
@@ -286,7 +303,7 @@
             CleanupClosePushL(connectionMethod);
             
             TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
-            QString iface = QString::number(qHash(iapId));
+            QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
             // Check that IAP can be found from accessPointConfigurations list
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
             if (priv.data() == 0) {
@@ -299,7 +316,7 @@
                     if (!iFirstUpdate) {
                         QNetworkConfiguration item;
                         item.d = ptr;
-                        emit configurationAdded(item);
+                        QT_TRYCATCH_LEAVING(emit configurationAdded(item));
                     }
                     privSNAP->serviceNetworkMembers.append(ptr);
                 }
@@ -340,7 +357,7 @@
     TInt retVal = pDbTView->GotoFirstRecord();
     while (retVal == KErrNone) {
         pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId);
-        QString ident = QString::number(qHash(apId));
+        QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
         if (accessPointConfigurations.contains(ident)) {
             knownConfigs.removeOne(ident);
         } else {
@@ -351,7 +368,7 @@
                 if (!iFirstUpdate) {
                     QNetworkConfiguration item;
                     item.d = ptr;
-                    emit configurationAdded(item);
+                    QT_TRYCATCH_LEAVING(emit configurationAdded(item));
                 }
             } else {
                 delete cpPriv;
@@ -361,7 +378,7 @@
     }
     CleanupStack::PopAndDestroy(pDbTView);
 #endif
-    updateActiveAccessPoints();
+    QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
     
     foreach (const QString &oldIface, knownConfigs) {
         //remove non existing IAP
@@ -370,7 +387,7 @@
         if (!iFirstUpdate) {
             QNetworkConfiguration item;
             item.d = priv;
-            emit configurationRemoved(item);
+            QT_TRYCATCH_LEAVING(emit configurationRemoved(item));
         }
         // Remove non existing IAP from SNAPs
         foreach (const QString &iface, snapConfigurations.keys()) {
@@ -391,7 +408,7 @@
         if (!iFirstUpdate) {
             QNetworkConfiguration item;
             item.d = priv;
-            emit configurationRemoved(item);
+            QT_TRYCATCH_LEAVING(emit configurationRemoved(item));
         }
     }
 }
@@ -401,14 +418,12 @@
         RCmConnectionMethod& connectionMethod)
 {
     QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
-    CleanupStack::PushL(cpPriv);
-    
     TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
-    QString ident = QString::number(qHash(iapId));
+    QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
     
     HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName);
     CleanupStack::PushL(pName);
-    cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length());
+    QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
     CleanupStack::PopAndDestroy(pName);
     pName = NULL;
     
@@ -456,7 +471,7 @@
 
     if (error == KErrNone && pName) {
         CleanupStack::PushL(pName);
-        cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length());
+        QT_TRYCATCH_LEAVING(cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length()));
         CleanupStack::PopAndDestroy(pName);
         pName = NULL;
     }
@@ -475,8 +490,6 @@
     cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
     cpPriv->roamingSupported = false;
     cpPriv->manager = this;
-    
-    CleanupStack::Pop(cpPriv);
     return cpPriv;
 }
 #else
@@ -507,9 +520,9 @@
         User::Leave(KErrNotFound);
     }
     
-    QString ident = QString::number(qHash(aApId));
+    QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(aApId));
     
-    apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length());
+    QT_TRYCATCH_LEAVING(apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length()));
     apNetworkConfiguration->isValid = true;
     apNetworkConfiguration->id = ident;
     apNetworkConfiguration->numericId = aApId;
@@ -574,13 +587,13 @@
     TCmDefConnValue defaultConnectionValue;
     iCmManager.ReadDefConnL(defaultConnectionValue);
     if (defaultConnectionValue.iType == ECmDefConnDestination) {
-        QString iface = QString::number(qHash(defaultConnectionValue.iId+KValueThatWillBeAddedToSNAPId));
+        QString iface = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX+QString::number(qHash(defaultConnectionValue.iId));
         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = snapConfigurations.value(iface);
         if (priv.data() != 0) {
             item.d = priv;
         }
     } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) {
-        QString iface = QString::number(qHash(defaultConnectionValue.iId));
+        QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(defaultConnectionValue.iId));
         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
         if (priv.data() != 0) {
             item.d = priv;
@@ -622,8 +635,14 @@
             iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
             User::WaitForRequest(status);
-            QString ident = QString::number(qHash(apId));
+            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+            if (!priv.data()) {
+                // If IAP was not found, check if the update was about EasyWLAN
+                priv = configurationFromEasyWlan(apId, connectionId);
+            }
+#endif
             if (priv.data()) {
                 iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
                 User::WaitForRequest(status);          
@@ -649,7 +668,7 @@
 
     if (iOnline != online) {
         iOnline = online;
-        emit this->onlineStateChanged(iOnline);
+        emit this->onlineStateChanged(online);
     }
 }
 
@@ -673,7 +692,7 @@
         // Set state of returned IAPs to Discovered
         // if state is not already Active
         for(TUint i=0; i<iapInfo.iCount; i++) {
-            QString ident = QString::number(qHash(iapInfo.iIap[i].iIapId));
+            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapInfo.iIap[i].iIapId));
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
             if (priv.data()) {
                 unavailableConfigs.removeOne(ident);
@@ -733,6 +752,31 @@
     }    
 }
 
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+void QNetworkConfigurationManagerPrivate::updateMobileBearerToConfigs(TConnMonBearerInfo bearerInfo)
+{
+    foreach (const QString &ii, accessPointConfigurations.keys()) {
+        QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> p = 
+            accessPointConfigurations.value(ii);
+        if (p->bearer >= QNetworkConfigurationPrivate::Bearer2G &&
+            p->bearer <= QNetworkConfigurationPrivate::BearerHSPA) {
+            switch (bearerInfo) {
+            case EBearerInfoCSD:      p->bearer = QNetworkConfigurationPrivate::Bearer2G; break;  
+            case EBearerInfoWCDMA:    p->bearer = QNetworkConfigurationPrivate::BearerWCDMA; break;
+            case EBearerInfoCDMA2000: p->bearer = QNetworkConfigurationPrivate::BearerCDMA2000; break;
+            case EBearerInfoGPRS:     p->bearer = QNetworkConfigurationPrivate::Bearer2G; break;
+            case EBearerInfoHSCSD:    p->bearer = QNetworkConfigurationPrivate::Bearer2G; break;
+            case EBearerInfoEdgeGPRS: p->bearer = QNetworkConfigurationPrivate::Bearer2G; break;
+            case EBearerInfoWcdmaCSD: p->bearer = QNetworkConfigurationPrivate::BearerWCDMA; break;
+            case EBearerInfoHSDPA:    p->bearer = QNetworkConfigurationPrivate::BearerHSPA; break;
+            case EBearerInfoHSUPA:    p->bearer = QNetworkConfigurationPrivate::BearerHSPA; break;
+            case EBearerInfoHSxPA:    p->bearer = QNetworkConfigurationPrivate::BearerHSPA; break;
+            }
+        }
+    }
+}
+#endif
+
 bool QNetworkConfigurationManagerPrivate::changeConfigurationStateTo(QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>& sharedData,
                                                                      QNetworkConfiguration::StateFlags newState)
 {
@@ -817,48 +861,26 @@
 
 void QNetworkConfigurationManagerPrivate::RunL()
 {
-    if (iIgnoringUpdates) {
-#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
-        qDebug("QNCM CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
-#endif
-        return;
-    }
     if (iStatus != KErrCancel) {
+        // By default, start relistening notifications. Stop only if interesting event occured.
+        iWaitingCommsDatabaseNotifications = true;
         RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int());
-
         switch (event) {
-        case RDbNotifier::EUnlock:   /** All read locks have been removed.  */
         case RDbNotifier::ECommit:   /** A transaction has been committed.  */ 
-        case RDbNotifier::ERollback: /** A transaction has been rolled back */
         case RDbNotifier::ERecover:  /** The database has been recovered    */
 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
             qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
 #endif
-            iIgnoringUpdates = true;
-            // Other events than ECommit get lower priority. In practice with those events,
-            // we delay_before_updating methods, whereas
-            // with ECommit we _update_before_delaying the reaction to next event.
-            // Few important notes: 1) listening to only ECommit does not seem to be adequate,
-            // but updates will be missed. Hence other events are reacted upon too.
-            // 2) RDbNotifier records the most significant event, and that will be returned once
-            // we issue new RequestNotification, and hence updates will not be missed even
-            // when we are 'not reacting to them' for few seconds.
-            if (event == RDbNotifier::ECommit) {
-                TRAPD(error, updateConfigurationsL());
-                if (error == KErrNone) {
-                    updateStatesToSnaps();
-                }
-                waitRandomTime();
-            } else {
-                waitRandomTime();
-                TRAPD(error, updateConfigurationsL());
-                if (error == KErrNone) {
-                    updateStatesToSnaps();
-                }   
+            // Mark that there is update pending. No need to ask more events,
+            // as we know we will be updating anyway when the timer expires.
+            if (!iUpdatePending) {
+                iUpdatePending = true;
+                iWaitingCommsDatabaseNotifications = false;
+                // Update after random time, so that many processes won't
+                // start updating simultaneously
+                updateConfigurationsAfterRandomTime();
             }
-            iIgnoringUpdates = false; // Wait time done, allow updating again
-            iWaitingCommsDatabaseNotifications = true;
-            break;
+            break;           
         default:
             // Do nothing
             break;
@@ -881,6 +903,20 @@
 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent)
 {
     switch (aEvent.EventType()) {
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE     
+    case EConnMonBearerInfoChange:
+        {
+        CConnMonBearerInfoChange* realEvent;
+        realEvent = (CConnMonBearerInfoChange*) &aEvent;
+        TUint connectionId = realEvent->ConnectionId();
+        if (connectionId == EBearerIdAll) {
+            //Network level event
+            TConnMonBearerInfo bearerInfo = (TConnMonBearerInfo)realEvent->BearerInfo();
+            updateMobileBearerToConfigs(bearerInfo);
+        }
+        break;
+        }
+#endif        
     case EConnMonConnectionStatusChange:
         {
         CConnMonConnectionStatusChange* realEvent;
@@ -896,11 +932,18 @@
             TRequestStatus status;
             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
             User::WaitForRequest(status);
-            QString ident = QString::number(qHash(apId));
+
+            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+            if (!priv.data()) {
+                // Check if status was regarding EasyWLAN
+                priv = configurationFromEasyWlan(apId, connectionId);
+            }
+#endif
             if (priv.data()) {
-                priv.data()->connectionId = connectionId;
-                emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connecting);
+                priv.data()->connectionId = connectionId;                
+                QT_TRYCATCH_LEAVING(emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connecting));
             }
         } else if (connectionStatus == KLinkLayerOpen) {
             // Connection has been successfully opened
@@ -910,25 +953,33 @@
             TRequestStatus status;
             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
             User::WaitForRequest(status);
-            QString ident = QString::number(qHash(apId));
+            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+            if (!priv.data()) {
+                // Check for EasyWLAN
+                priv = configurationFromEasyWlan(apId, connectionId);
+            }
+#endif
             if (priv.data()) {
                 priv.data()->connectionId = connectionId;
                 // Configuration is Active
-                if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) {
-                    updateStatesToSnaps();
-                }
-                emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connected);
-                if (!iOnline) {
-                    iOnline = true;
-                    emit this->onlineStateChanged(iOnline);
-                }
+                QT_TRYCATCH_LEAVING(
+                    if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) {
+                        updateStatesToSnaps();
+                    }
+                    emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connected);
+                    if (!iOnline) {
+                        iOnline = true;
+                        emit this->onlineStateChanged(iOnline);
+                    }
+                );
             }
         } else if (connectionStatus == KConfigDaemonStartingDeregistration) {
             TUint connectionId = realEvent->ConnectionId();
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
             if (priv.data()) {
-                emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Closing);
+                QT_TRYCATCH_LEAVING(emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Closing));
             }
         } else if (connectionStatus == KLinkLayerClosed ||
                    connectionStatus == KConnectionClosed) {
@@ -938,10 +989,12 @@
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
             if (priv.data()) {
                 // Configuration is either Defined or Discovered
-                if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
-                    updateStatesToSnaps();
-                }
-                emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Disconnected);
+                QT_TRYCATCH_LEAVING(
+                    if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
+                        updateStatesToSnaps();
+                    }
+                    emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Disconnected);
+                );
             }
             
             bool online = false;
@@ -954,7 +1007,7 @@
             }
             if (iOnline != online) {
                 iOnline = online;
-                emit this->onlineStateChanged(iOnline);
+                QT_TRYCATCH_LEAVING(emit this->onlineStateChanged(iOnline));
             }
         }
         }
@@ -967,11 +1020,11 @@
         TConnMonIapInfo iaps = realEvent->IapAvailability();
         QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys();
         for ( TUint i = 0; i < iaps.Count(); i++ ) {
-            QString ident = QString::number(qHash(iaps.iIap[i].iIapId));
+            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iaps.iIap[i].iIapId));
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
             if (priv.data()) {
                 // Configuration is either Discovered or Active 
-                changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered);
+                QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered));
                 unDiscoveredConfigs.removeOne(ident);
             }
         }
@@ -979,7 +1032,7 @@
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
             if (priv.data()) {
                 // Configuration is Defined
-                changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined);
+                QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined));
             }
         }
         }
@@ -996,8 +1049,14 @@
         TRequestStatus status;
         iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
         User::WaitForRequest(status);
-        QString ident = QString::number(qHash(apId));
+        QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+        if (!priv.data()) {
+            // If IAP was not found, check if the update was about EasyWLAN
+            priv = configurationFromEasyWlan(apId, connectionId);
+        }
+#endif
         if (priv.data()) {
 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
             qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << priv.data()->connectionId << connectionId << priv->name;
@@ -1012,6 +1071,41 @@
     }
 }
 
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+// Tries to derive configuration from EasyWLAN.
+// First checks if the interface brought up was EasyWLAN, then derives the real SSID,
+// and looks up configuration based on that one.
+QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::configurationFromEasyWlan(TUint32 apId, TUint connectionId)
+{
+    if (apId == iCmManager.EasyWlanIdL()) {
+        TRequestStatus status;
+        TBuf<50> easyWlanNetworkName;
+        iConnectionMonitor.GetStringAttribute( connectionId, 0, KNetworkName,
+                                               easyWlanNetworkName, status );
+        User::WaitForRequest(status);
+        if (status.Int() == KErrNone) {
+            QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(), easyWlanNetworkName.Length());
+
+            // Browser through all items and check their name for match
+            QNetworkConfiguration item;
+            QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
+                    accessPointConfigurations.constBegin();
+            while (i != accessPointConfigurations.constEnd()) {
+                QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value();
+                if (priv.data()->name == realSSID) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+                    qDebug() << "QNCM EasyWlan uses real SSID: " << realSSID;
+#endif
+                    return priv;
+                }
+                ++i;
+            }
+        }
+    }
+    return QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>();
+}
+#endif
+
 // Sessions may use this function to report configuration state changes,
 // because on some Symbian platforms (especially Symbian^3) all state changes are not
 // reported by the RConnectionMonitor, in particular in relation to stop() call,
@@ -1027,7 +1121,7 @@
     switch (newState) {
     case QNetworkSession::Disconnected:
         {
-            QString ident = QString::number(qHash(accessPointId));
+            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(accessPointId));
             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
             if (priv.data()) {
                 // Configuration is either Defined or Discovered
@@ -1045,17 +1139,16 @@
 }
 
 // Waits for 2..6 seconds.
-void QNetworkConfigurationManagerPrivate::waitRandomTime()
+void QNetworkConfigurationManagerPrivate::updateConfigurationsAfterRandomTime()
 {
-    iTimeToWait = (qAbs(qrand()) % 7) * 1000;
-    if (iTimeToWait < 2000) {
-        iTimeToWait = 2000;
+    iTimeToWait = (qAbs(qrand()) % 68) * 100;
+    if (iTimeToWait < 1000) {
+        iTimeToWait = 1000;
     }
 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
     qDebug("QNCM waiting random time: %d ms", iTimeToWait);
 #endif
-    QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit()));
-    iIgnoreEventLoop->exec();
+    QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate()));
 }
 
 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId)
@@ -1070,13 +1163,12 @@
         }
         ++i;
     }
-
     return QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>();
 }
 
 AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(QNetworkConfigurationManagerPrivate& owner,
                                                                RConnectionMonitor& connectionMonitor)
-    : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor)
+    : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor)
 {
     CActiveScheduler::Add(this);  
 }
@@ -1114,9 +1206,9 @@
 {
     if (iStatus.Int() != KErrNone) {
         iIapBuf().iCount = 0;
-        iOwner.accessPointScanningReady(false,iIapBuf());
+        QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(false,iIapBuf()));
     } else {
-        iOwner.accessPointScanningReady(true,iIapBuf());
+        QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(true,iIapBuf()));
     }
 }
 #include "moc_qnetworkconfigmanager_s60_p.cpp"