qtmobility/src/bearer/qnetworksession_s60_p.cpp
changeset 4 90517678cc4f
parent 0 cfcbf08528c4
child 5 453da2cfceef
--- a/qtmobility/src/bearer/qnetworksession_s60_p.cpp	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/src/bearer/qnetworksession_s60_p.cpp	Mon May 03 13:18:40 2010 +0300
@@ -54,16 +54,10 @@
 QNetworkSessionPrivate::QNetworkSessionPrivate()
     : CActive(CActive::EPriorityStandard), state(QNetworkSession::Invalid),
       isOpen(false), ipConnectionNotifier(0), iError(QNetworkSession::UnknownSessionError),
-      iALREnabled(0)
+      iALREnabled(0), iConnectInBackground(false)
 {
     CActiveScheduler::Add(this);
     
-    // Try to load "Open C" dll dynamically and
-    // try to attach to setdefaultif function dynamically.
-    if (iOpenCLibrary.Load(_L("libc")) == KErrNone) {
-        iDynamicSetdefaultif = (TOpenCSetdefaultifFunction)iOpenCLibrary.Lookup(564);
-    }
-
     TRAP_IGNORE(iConnectionMonitor.ConnectL());
 }
 
@@ -89,14 +83,12 @@
 
     iConnection.Close();
     iSocketServ.Close();
-    if (iDynamicSetdefaultif) {
-        iDynamicSetdefaultif(0);
-    }
+    
+    // Close global 'Open C' RConnection
+    setdefaultif(0);
 
     iConnectionMonitor.CancelNotifications();
     iConnectionMonitor.Close();
-
-    iOpenCLibrary.Close();
 }
 
 void QNetworkSessionPrivate::syncStateWithInterface()
@@ -202,13 +194,24 @@
     return activeInterface;
 }
 
-QVariant QNetworkSessionPrivate::sessionProperty(const QString& /*key*/) const
+QVariant QNetworkSessionPrivate::sessionProperty(const QString& key) const
 {
+    if (key == "ConnectInBackground") {
+        return QVariant(iConnectInBackground);
+    }
     return QVariant();
 }
 
-void QNetworkSessionPrivate::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/)
+void QNetworkSessionPrivate::setSessionProperty(const QString& key, const QVariant& value)
 {
+    // Valid value means adding property, invalid means removing it.
+    if (key == "ConnectInBackground") {
+        if (value.isValid()) {
+            iConnectInBackground = value.toBool();
+        } else {
+            iConnectInBackground = EFalse;
+        }
+    }
 }
 
 QString QNetworkSessionPrivate::errorString() const
@@ -244,15 +247,24 @@
     // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring
     iConnectionMonitor.CancelNotifications();
 
-    // Configuration must be at least in Discovered - state for connecting purposes.
-    if ((publicConfig.state() & QNetworkConfiguration::Discovered) !=
-                QNetworkConfiguration::Discovered) {
+    // Configuration may have been invalidated after session creation by platform
+    // (e.g. configuration has been deleted).
+    if (!publicConfig.isValid()) {
         newState(QNetworkSession::Invalid);
         iError = QNetworkSession::InvalidConfigurationError;
         emit q->error(iError);
         syncStateWithInterface();
         return;
     }
+    // If opening a (un)defined configuration, session emits error and enters
+    // NotAvailable -state.
+    if (publicConfig.state() == QNetworkConfiguration::Undefined ||
+        publicConfig.state() == QNetworkConfiguration::Defined) {
+        newState(QNetworkSession::NotAvailable);
+        iError = QNetworkSession::InvalidConfigurationError;
+        emit q->error(iError);
+        return;
+    }
     
     TInt error = iSocketServ.Connect();
     if (error != KErrNone) {
@@ -301,14 +313,12 @@
                             activeInterface = interface(activeConfig.d.data()->numericId);
                             connected = ETrue;
                             startTime = QDateTime::currentDateTime();
-                            if (iDynamicSetdefaultif) {
-                                // Use name of the IAP to set default IAP
-                                QByteArray nameAsByteArray = publicConfig.name().toUtf8();
-                                ifreq ifr;
-                                strcpy(ifr.ifr_name, nameAsByteArray.constData());
-
-                                error = iDynamicSetdefaultif(&ifr);
-                            }
+                            // Use name of the IAP to open global 'Open C' RConnection
+                            QByteArray nameAsByteArray = publicConfig.name().toUtf8();
+                            ifreq ifr;
+                            memset(&ifr, 0, sizeof(struct ifreq));
+                            strcpy(ifr.ifr_name, nameAsByteArray.constData());
+                            error = setdefaultif(&ifr);
                             isOpen = true;
                             // Make sure that state will be Connected
                             newState(QNetworkSession::Connected);
@@ -320,9 +330,21 @@
             }
         }
         if (!connected) {
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+            // With One Click Connectivity (Symbian^3 onwards) it is possible
+            // to connect silently, without any popups.
+            TConnPrefList pref;
+            TExtendedConnPref prefs;
+            prefs.SetIapId(publicConfig.d.data()->numericId);
+            if (iConnectInBackground) {
+                prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent );
+            }
+            pref.AppendL(&prefs);
+#else
             TCommDbConnPref pref;
             pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
             pref.SetIapId(publicConfig.d.data()->numericId);
+#endif
             iConnection.Start(pref, iStatus);
             if (!IsActive()) {
                 SetActive();
@@ -330,7 +352,17 @@
             newState(QNetworkSession::Connecting);
         }
     } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+        TConnPrefList snapPref;
+        TExtendedConnPref prefs;
+        prefs.SetSnapId(publicConfig.d.data()->numericId);
+        if (iConnectInBackground) {
+            prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent );
+        }
+        snapPref.AppendL(&prefs);
+#else
         TConnSnapPref snapPref(publicConfig.d.data()->numericId);
+#endif
         iConnection.Start(snapPref, iStatus);
         if (!IsActive()) {
             SetActive();
@@ -408,9 +440,9 @@
     
     iConnection.Close();
     iSocketServ.Close();
-    if (iDynamicSetdefaultif) {
-        iDynamicSetdefaultif(0);
-    }
+    
+    // Close global 'Open C' RConnection
+    setdefaultif(0);
 
 #ifdef Q_CC_NOKIAX86
     if ((allowSignals && iapClientCount(activeIap) <= 0) ||
@@ -432,20 +464,53 @@
 
 void QNetworkSessionPrivate::stop()
 {
-    if (!isOpen) {
-        return;
+    if (!isOpen &&
+        publicConfig.isValid() &&
+        publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+        // If the publicConfig is type of IAP, enumerate through connections at
+        // connection monitor. If publicConfig is active in that list, stop it.
+        // Otherwise there is nothing to stop. Note: because this QNetworkSession is not open,
+        // activeConfig is not usable.
+        TUint count;
+        TRequestStatus status;
+        iConnectionMonitor.GetConnectionCount(count, status);
+        User::WaitForRequest(status);
+        if (status.Int() != KErrNone) {
+            return;
+        }
+        TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
+        TUint connectionId;
+        for (TInt i = 1; i <= count; ++i) {
+            // Get (connection monitor's assigned) connection ID
+            TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);            
+            if (ret == KErrNone) {
+                // See if connection Id matches with our Id. If so, stop() it.
+                if (publicConfig.d.data()->connectionId == connectionId) {
+                    ret = iConnectionMonitor.SetBoolAttribute(connectionId,
+                                                              0, // subConnectionId don't care
+                                                              KConnectionStop,
+                                                              ETrue);
+                }
+            }
+        }
+    } else if (isOpen) {
+        // Since we are open, use RConnection to stop the interface
+        isOpen = false;
+        newState(QNetworkSession::Closing);
+        iConnection.Stop(RConnection::EStopAuthoritative);
+        isOpen = true;
+        close(false);
+        emit q->closed();
     }
-    isOpen = false;
-    newState(QNetworkSession::Closing);
-    iConnection.Stop(RConnection::EStopAuthoritative);
-    isOpen = true;
-    close(false);
-    emit q->closed();
 }
 
 void QNetworkSessionPrivate::migrate()
 {
 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
+    // Close global 'Open C' RConnection
+    setdefaultif(0);
+    
+    // Start migrating to new IAP
     iMobility->MigrateToPreferredCarrier();
 #endif
 }
@@ -466,14 +531,16 @@
 {
 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
     iMobility->NewCarrierAccepted();
-    if (iDynamicSetdefaultif) {
-        // Use name of the IAP to set default IAP
-        QByteArray nameAsByteArray = activeConfig.name().toUtf8();
-        ifreq ifr;
-        strcpy(ifr.ifr_name, nameAsByteArray.constData());
+    
+    QNetworkConfiguration newActiveConfig = activeConfiguration(iNewRoamingIap);
 
-        iDynamicSetdefaultif(&ifr);
-    }
+    // Use name of the new IAP to open global 'Open C' RConnection
+    QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
+    ifreq ifr;
+    memset(&ifr, 0, sizeof(struct ifreq));
+    strcpy(ifr.ifr_name, nameAsByteArray.constData());
+    setdefaultif(&ifr);
+    
     newState(QNetworkSession::Connected, iNewRoamingIap);
 #endif
 }
@@ -482,9 +549,19 @@
 {
 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
     iMobility->NewCarrierRejected();
+
     if (!iALRUpgradingConnection) {
         newState(QNetworkSession::Disconnected);
     } else {
+        QNetworkConfiguration newActiveConfig = activeConfiguration(iOldRoamingIap);
+
+        // Use name of the old IAP to open global 'Open C' RConnection
+        QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
+        ifreq ifr;
+        memset(&ifr, 0, sizeof(struct ifreq));
+        strcpy(ifr.ifr_name, nameAsByteArray.constData());
+        setdefaultif(&ifr);
+
         newState(QNetworkSession::Connected, iOldRoamingIap);
     }
 #endif
@@ -748,19 +825,19 @@
     TInt statusCode = iStatus.Int();
 
     switch (statusCode) {
-        case KErrNone: // Connection created succesfully
+        case KErrNone: // Connection created successfully
             {
             TInt error = KErrNone;
             QNetworkConfiguration newActiveConfig = activeConfiguration();
             if (!newActiveConfig.isValid()) {
                 error = KErrGeneral;
-            } else if (iDynamicSetdefaultif) {
-                // Use name of the IAP to set default IAP
-                QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
+            } else {
+                // Use name of the IAP to open global 'Open C' RConnection
                 ifreq ifr;
+                memset(&ifr, 0, sizeof(struct ifreq));
+                QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
                 strcpy(ifr.ifr_name, nameAsByteArray.constData());
-
-                error = iDynamicSetdefaultif(&ifr);
+                error = setdefaultif(&ifr);
             }
             
             if (error != KErrNone) {