src/plugins/bearer/symbian/symbianengine.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
--- a/src/plugins/bearer/symbian/symbianengine.cpp	Fri Sep 17 08:34:18 2010 +0300
+++ b/src/plugins/bearer/symbian/symbianengine.cpp	Mon Oct 04 01:19:32 2010 +0300
@@ -65,7 +65,7 @@
 #else
     #include <ApAccessPointItem.h>
     #include <ApDataHandler.h>
-    #include <ApUtils.h> 
+    #include <ApUtils.h>
 #endif
 
 #ifndef QT_NO_BEARERMANAGEMENT
@@ -75,7 +75,7 @@
 static const int KUserChoiceIAPId = 0;
 
 SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate()
-:   bearer(BearerUnknown), numericId(0), connectionId(0)
+:   numericId(0), connectionId(0)
 {
 }
 
@@ -83,32 +83,6 @@
 {
 }
 
-QString SymbianNetworkConfigurationPrivate::bearerName() const
-{
-    QMutexLocker locker(&mutex);
-
-    switch (bearer) {
-    case BearerEthernet:
-        return QLatin1String("Ethernet");
-    case BearerWLAN:
-        return QLatin1String("WLAN");
-    case Bearer2G:
-        return QLatin1String("2G");
-    case BearerCDMA2000:
-        return QLatin1String("CDMA2000");
-    case BearerWCDMA:
-        return QLatin1String("WCDMA");
-    case BearerHSPA:
-        return QLatin1String("HSPA");
-    case BearerBluetooth:
-        return QLatin1String("Bluetooth");
-    case BearerWiMAX:
-        return QLatin1String("WiMAX");
-    default:
-        return QString();
-    }
-}
-
 SymbianEngine::SymbianEngine(QObject *parent)
 :   QBearerEngine(parent), CActive(CActive::EPriorityHigh), iFirstUpdate(true), iInitOk(true),
     iUpdatePending(false)
@@ -146,7 +120,7 @@
 
     SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
     cpPriv->name = "UserChoice";
-    cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+    cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
     cpPriv->state = QNetworkConfiguration::Discovered;
     cpPriv->isValid = true;
     cpPriv->id = QString::number(qHash(KUserChoiceIAPId));
@@ -270,7 +244,7 @@
     QList<QString> knownConfigs = accessPointConfigurations.keys();
     QList<QString> knownSnapConfigs = snapConfigurations.keys();
 
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE    
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
     // S60 version is >= Series60 3rd Edition Feature Pack 2
     TInt error = KErrNone;
     
@@ -291,14 +265,17 @@
             if (error == KErrNone) {
                 QNetworkConfigurationPrivatePointer ptr(cpPriv);
                 accessPointConfigurations.insert(ptr->id, ptr);
-
-                mutex.unlock();
-                // 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(ptr));
-                mutex.lock();
+                if (!iFirstUpdate) {
+                    // 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(updateActiveAccessPoints());
+                    updateStatesToSnaps();
+                    mutex.unlock();
+                    QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+                    mutex.lock();
+                }
             }
         }
         CleanupStack::PopAndDestroy(&connectionMethod);
@@ -311,7 +288,17 @@
     iCmManager.AllDestinationsL(destinations);
     for(int i = 0; i < destinations.Count(); i++) {
         RCmDestination destination;
-        destination = iCmManager.DestinationL(destinations[i]);
+
+        // Some destinatsions require ReadDeviceData -capability (MMS/WAP)
+        // The below function will leave in these cases. Don't. Proceed to
+        // next destination (if any).
+        TRAPD(error, destination = iCmManager.DestinationL(destinations[i]));
+        if (error == KErrPermissionDenied) {
+            continue;
+        } else {
+            User::LeaveIfError(error);
+        }
+
         CleanupClosePushL(destination);
         QString ident = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX +
                         QString::number(qHash(destination.Id()));
@@ -319,12 +306,12 @@
             knownSnapConfigs.removeOne(ident);
         } else {
             SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
-    
+
             HBufC *pName = destination.NameLC();
             QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
             CleanupStack::PopAndDestroy(pName);
             pName = NULL;
-    
+
             cpPriv->isValid = true;
             cpPriv->id = ident;
             cpPriv->numericId = destination.Id();
@@ -336,10 +323,13 @@
 
             QNetworkConfigurationPrivatePointer ptr(cpPriv);
             snapConfigurations.insert(ident, ptr);
-
-            mutex.unlock();
-            QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
-            mutex.lock();
+            if (!iFirstUpdate) {
+                QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
+                updateStatesToSnaps();
+                mutex.unlock();
+                QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+                mutex.lock();
+            }
         }
 
         // Loop through all connection methods in this SNAP
@@ -352,19 +342,23 @@
             QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
             // Check that IAP can be found from accessPointConfigurations list
             QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
-            if (ptr) {
-                knownConfigs.removeOne(iface);
-            } else {
+            if (!ptr) {
                 SymbianNetworkConfigurationPrivate *cpPriv = NULL;
                 TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod));
                 if (error == KErrNone) {
                     ptr = QNetworkConfigurationPrivatePointer(cpPriv);
                     accessPointConfigurations.insert(ptr->id, ptr);
 
-                    mutex.unlock();
-                    QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
-                    mutex.lock();
+                    if (!iFirstUpdate) {
+                        QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
+                        updateStatesToSnaps();
+                        mutex.unlock();
+                        QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+                        mutex.lock();
+                    }
                 }
+            } else {
+                knownConfigs.removeOne(iface);
             }
 
             if (ptr) {
@@ -387,6 +381,9 @@
             privSNAP->roamingSupported = privSNAP->serviceNetworkMembers.count() > 1;
 
             snapConfigLocker.unlock();
+
+            updateStatesToSnaps();
+
             mutex.unlock();
             QT_TRYCATCH_LEAVING(emit configurationChanged(privSNAP));
             mutex.lock();
@@ -395,7 +392,6 @@
         CleanupStack::PopAndDestroy(&destination);
     }
     CleanupStack::PopAndDestroy(&destinations);
-    
 #else
     // S60 version is < Series60 3rd Edition Feature Pack 2
     CCommsDbTableView* pDbTView = ipCommsDB->OpenTableLC(TPtrC(IAP));
@@ -413,10 +409,13 @@
             if (readNetworkConfigurationValuesFromCommsDb(apId, cpPriv)) {
                 QNetworkConfigurationPrivatePointer ptr(cpPriv);
                 accessPointConfigurations.insert(ident, ptr);
-
-                mutex.unlock();
-                QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
-                mutex.lock();
+                if (!iFirstUpdate) {
+                    QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
+                    updateStatesToSnaps();
+                    mutex.unlock();
+                    QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+                    mutex.lock();
+                }
             } else {
                 delete cpPriv;
             }
@@ -425,8 +424,9 @@
     }
     CleanupStack::PopAndDestroy(pDbTView);
 #endif
+
     QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
-    
+
     foreach (const QString &oldIface, knownConfigs) {
         //remove non existing IAP
         QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface);
@@ -468,6 +468,10 @@
     stopCommsDatabaseNotifications();
     TRAP_IGNORE(defaultConfig = defaultConfigurationL());
     startCommsDatabaseNotifications();
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+    updateStatesToSnaps();
+#endif
 }
 
 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
@@ -487,25 +491,25 @@
     TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType);
     switch (bearerId) {
     case KCommDbBearerCSD:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+        cpPriv->bearerType = QNetworkConfiguration::Bearer2G;
         break;
     case KCommDbBearerWcdma:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA;
+        cpPriv->bearerType = QNetworkConfiguration::BearerWCDMA;
         break;
     case KCommDbBearerLAN:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet;
+        cpPriv->bearerType = QNetworkConfiguration::BearerEthernet;
         break;
     case KCommDbBearerVirtual:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+        cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
         break;
     case KCommDbBearerPAN:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+        cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
         break;
     case KCommDbBearerWLAN:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerWLAN;
+        cpPriv->bearerType = QNetworkConfiguration::BearerWLAN;
         break;
     default:
-        cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+        cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
         break;
     }
     
@@ -589,28 +593,28 @@
     apNetworkConfiguration->roamingSupported = false;
     switch (pAPItem->BearerTypeL()) {
     case EApBearerTypeCSD:      
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::Bearer2G;
         break;
     case EApBearerTypeGPRS:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::Bearer2G;
         break;
     case EApBearerTypeHSCSD:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerHSPA;
         break;
     case EApBearerTypeCDMA:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerCDMA2000;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerCDMA2000;
         break;
     case EApBearerTypeWLAN:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerWLAN;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerWLAN;
         break;
     case EApBearerTypeLAN:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerEthernet;
         break;
     case EApBearerTypeLANModem:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerEthernet;
         break;
     default:
-        apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown;
+        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerUnknown;
         break;
     }
     
@@ -688,15 +692,21 @@
             User::WaitForRequest(status);
             QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
             QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#ifdef OCC_FUNCTIONALITY_AVAILABLE
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
             if (!ptr) {
                 // If IAP was not found, check if the update was about EasyWLAN
                 ptr = configurationFromEasyWlan(apId, connectionId);
+                // Change the ident correspondingly
+                if (ptr) {
+                    ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
+                            QString::number(qHash(toSymbianConfig(ptr)->numericIdentifier()));
+                }
             }
 #endif
             if (ptr) {
                 iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
-                User::WaitForRequest(status);          
+                User::WaitForRequest(status);
+
                 if (connectionStatus == KLinkLayerOpen) {
                     online = true;
                     inactiveConfigs.removeOne(ident);
@@ -834,38 +844,38 @@
 
         SymbianNetworkConfigurationPrivate *p = toSymbianConfig(ptr);
 
-        if (p->bearer >= SymbianNetworkConfigurationPrivate::Bearer2G &&
-            p->bearer <= SymbianNetworkConfigurationPrivate::BearerHSPA) {
+        if (p->bearerType >= QNetworkConfiguration::Bearer2G &&
+            p->bearerType <= QNetworkConfiguration::BearerHSPA) {
             switch (bearerInfo) {
             case EBearerInfoCSD:
-                p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+                p->bearerType = QNetworkConfiguration::Bearer2G;
                 break;
             case EBearerInfoWCDMA:
-                p->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA;
+                p->bearerType = QNetworkConfiguration::BearerWCDMA;
                 break;
             case EBearerInfoCDMA2000:
-                p->bearer = SymbianNetworkConfigurationPrivate::BearerCDMA2000;
+                p->bearerType = QNetworkConfiguration::BearerCDMA2000;
                 break;
             case EBearerInfoGPRS:
-                p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+                p->bearerType = QNetworkConfiguration::Bearer2G;
                 break;
             case EBearerInfoHSCSD:
-                p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+                p->bearerType = QNetworkConfiguration::Bearer2G;
                 break;
             case EBearerInfoEdgeGPRS:
-                p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+                p->bearerType = QNetworkConfiguration::Bearer2G;
                 break;
             case EBearerInfoWcdmaCSD:
-                p->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA;
+                p->bearerType = QNetworkConfiguration::BearerWCDMA;
                 break;
             case EBearerInfoHSDPA:
-                p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+                p->bearerType = QNetworkConfiguration::BearerHSPA;
                 break;
             case EBearerInfoHSUPA:
-                p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+                p->bearerType = QNetworkConfiguration::BearerHSPA;
                 break;
             case EBearerInfoHSxPA:
-                p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+                p->bearerType = QNetworkConfiguration::BearerHSPA;
                 break;
             }
         }
@@ -1044,7 +1054,7 @@
 
             QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
             QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#ifdef OCC_FUNCTIONALITY_AVAILABLE
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
             if (!ptr) {
                 // Check if status was regarding EasyWLAN
                 ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1069,7 +1079,7 @@
             User::WaitForRequest(status);
             QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
             QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#ifdef OCC_FUNCTIONALITY_AVAILABLE
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
             if (!ptr) {
                 // Check for EasyWLAN
                 ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1161,6 +1171,8 @@
                 QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined));
             }
         }
+        // Something has in IAPs, update states to SNAPs
+        updateStatesToSnaps();
         }
         break;
 
@@ -1177,7 +1189,7 @@
         User::WaitForRequest(status);
         QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
         QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#ifdef OCC_FUNCTIONALITY_AVAILABLE
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
         if (!ptr) {
             // If IAP was not found, check if the update was about EasyWLAN
             ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1198,11 +1210,39 @@
     }
 }
 
-#ifdef OCC_FUNCTIONALITY_AVAILABLE
+/*
+    Returns the network configuration that matches the given SSID.
+*/
+QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromSsid(const QString &ssid)
+{
+    QMutexLocker locker(&mutex);
+
+    // Browser through all items and check their name for match
+    QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator i =
+        accessPointConfigurations.constBegin();
+    while (i != accessPointConfigurations.constEnd()) {
+        QNetworkConfigurationPrivatePointer ptr = i.value();
+
+        QMutexLocker configLocker(&ptr->mutex);
+
+        if (ptr->name == ssid) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+            qDebug() << "QNCM EasyWlan uses real SSID: " << ssid;
+#endif
+            return ptr;
+        }
+        ++i;
+    }
+
+    return QNetworkConfigurationPrivatePointer();
+}
+
+#ifdef SNAP_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.
-QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId, TUint connectionId)
+QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId,
+                                                                             TUint connectionId)
 {
     if (apId == iCmManager.EasyWlanIdL()) {
         TRequestStatus status;
@@ -1211,11 +1251,12 @@
                                                easyWlanNetworkName, status );
         User::WaitForRequest(status);
         if (status.Int() == KErrNone) {
-            QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(), easyWlanNetworkName.Length());
+            const QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(),
+                                                        easyWlanNetworkName.Length());
 
             // Browser through all items and check their name for match
-            QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
-                    accessPointConfigurations.constBegin();
+            QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator i =
+                accessPointConfigurations.constBegin();
             while (i != accessPointConfigurations.constEnd()) {
                 QNetworkConfigurationPrivatePointer ptr = i.value();