--- a/qtmobility/src/bearer/qnetworksession_s60_p.cpp Thu Apr 01 08:30:34 2010 +0300
+++ b/qtmobility/src/bearer/qnetworksession_s60_p.cpp Thu Apr 15 08:16:03 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) {