diff -r 2b40d63a9c3d -r 90517678cc4f qtmobility/src/bearer/qnetworksession_s60_p.cpp --- 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) {