summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp369
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.h15
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp248
-rw-r--r--src/plugins/bearer/symbian/symbianengine.h27
-rw-r--r--tests/auto/qnetworksession/lackey/main.cpp24
-rw-r--r--tests/auto/qnetworksession/test/tst_qnetworksession.cpp361
6 files changed, 658 insertions, 386 deletions
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index 1b9c8cc..04853c4 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -53,15 +53,17 @@
QT_BEGIN_NAMESPACE
QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
- : CActive(CActive::EPriorityStandard), engine(engine), ipConnectionNotifier(0),
- iError(QNetworkSession::UnknownSessionError),
- iALREnabled(0), iConnectInBackground(false)
+ : CActive(CActive::EPriorityStandard), engine(engine),
+ ipConnectionNotifier(0), iHandleStateNotificationsFromManager(false),
+ iFirstSync(true), iStoppedByUser(false), iClosedByUser(false), iDeprecatedConnectionId(0),
+ iError(QNetworkSession::UnknownSessionError), iALREnabled(0), iConnectInBackground(false)
{
CActiveScheduler::Add(this);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
iMobility = NULL;
#endif
+
TRAP_IGNORE(iConnectionMonitor.ConnectL());
}
@@ -90,18 +92,72 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
// Close global 'Open C' RConnection
setdefaultif(0);
-
- iConnectionMonitor.CancelNotifications();
+
iConnectionMonitor.Close();
}
+void QNetworkSessionPrivateImpl::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState)
+{
+ if (iHandleStateNotificationsFromManager) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId)
+ << "configurationStateChanged connMon ID : " << QString::number(connMonId)
+ << " : to a state: " << newState
+ << " whereas my current state is: " << state;
+#endif
+ if (connMonId == iDeprecatedConnectionId) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "however status update from manager ignored because it related to already closed connection.";
+#endif
+ return;
+ }
+ this->newState(newState, accessPointId);
+ }
+}
+
+void QNetworkSessionPrivateImpl::configurationRemoved(QNetworkConfigurationPrivatePointer config)
+{
+ if (!publicConfig.isValid())
+ return;
+
+ SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(config);
+
+ symbianConfig->mutex.lock();
+ TUint32 configNumericId = symbianConfig->numericId;
+ symbianConfig->mutex.unlock();
+
+ symbianConfig = toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ TUint32 publicNumericId = symbianConfig->numericId;
+ symbianConfig->mutex.unlock();
+
+ if (configNumericId == publicNumericId) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "configurationRemoved IAP: " << QString::number(publicNumericId) << " : going to State: Invalid";
+#endif
+ this->newState(QNetworkSession::Invalid, publicNumericId);
+ }
+}
+
void QNetworkSessionPrivateImpl::syncStateWithInterface()
{
if (!publicConfig.isValid())
return;
- // Start monitoring changes in IAP states
- TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+ if (iFirstSync && publicConfig.isValid()) {
+ QObject::connect(engine, SIGNAL(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)),
+ this, SLOT(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)));
+ // Listen to configuration removals, so that in case the configuration
+ // this session is based on is removed, session knows to enter Invalid -state.
+ QObject::connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)),
+ this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)));
+ }
+ // Start listening IAP state changes from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
// Check open connections to see if there is already
// an open connection to selected IAP or SNAP
@@ -137,11 +193,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
}
if (state != QNetworkSession::Connected) {
- // There were no open connections to used IAP or SNAP
- if (iError == QNetworkSession::InvalidConfigurationError) {
- newState(QNetworkSession::Invalid);
- } else if ((publicConfig.state() & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
+ if ((publicConfig.state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
newState(QNetworkSession::Disconnected);
} else {
newState(QNetworkSession::NotAvailable);
@@ -245,13 +298,18 @@ QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
void QNetworkSessionPrivateImpl::open()
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "open() called, session state is: " << state << " and isOpen is: "
+ << isOpen;
+#endif
if (isOpen || (state == QNetworkSession::Connecting)) {
return;
}
-
- // Cancel notifications from RConnectionMonitor
+
+ // Stop handling IAP state change signals from QNetworkConfigurationManagerPrivate
// => RConnection::ProgressNotification will be used for IAP/SNAP monitoring
- iConnectionMonitor.CancelNotifications();
+ iHandleStateNotificationsFromManager = false;
// Configuration may have been invalidated after session creation by platform
// (e.g. configuration has been deleted).
@@ -259,19 +317,25 @@ void QNetworkSessionPrivateImpl::open()
newState(QNetworkSession::Invalid);
iError = QNetworkSession::InvalidConfigurationError;
emit QNetworkSessionPrivate::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) {
+ // If opening a undefined configuration, session emits error and enters
+ // NotAvailable -state. Note that we will try ones in 'defined' state to avoid excessive
+ // need for WLAN scans (via updateConfigurations()), because user may have walked
+ // into a WLAN range, but periodic background scan has not occurred yet -->
+ // we don't want to force application to make frequent updateConfigurations() calls
+ // to be able to try if e.g. home WLAN is available.
+ if (publicConfig.state() == QNetworkConfiguration::Undefined) {
newState(QNetworkSession::NotAvailable);
iError = QNetworkSession::InvalidConfigurationError;
emit QNetworkSessionPrivate::error(iError);
return;
}
-
+ // Clear possible previous states
+ iStoppedByUser = false;
+ iClosedByUser = false;
+ iDeprecatedConnectionId = 0;
+
TInt error = iSocketServ.Connect();
if (error != KErrNone) {
// Could not open RSocketServ
@@ -446,9 +510,18 @@ TUint QNetworkSessionPrivateImpl::iapClientCount(TUint aIAPId) const
void QNetworkSessionPrivateImpl::close(bool allowSignals)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "close() called, session state is: " << state << " and isOpen is : "
+ << isOpen;
+#endif
if (!isOpen) {
return;
}
+ // Mark this session as closed-by-user so that we are able to report
+ // distinguish between stop() and close() state transitions
+ // when reporting.
+ iClosedByUser = true;
SymbianNetworkConfigurationPrivate *symbianConfig =
toSymbianConfig(privateConfiguration(activeConfig));
@@ -469,8 +542,10 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
}
#endif
- if (ipConnectionNotifier) {
+ if (ipConnectionNotifier && !iHandleStateNotificationsFromManager) {
ipConnectionNotifier->StopNotifications();
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
}
iConnection.Close();
@@ -488,7 +563,6 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
newState(QNetworkSession::Closing);
}
- syncStateWithInterface();
if (allowSignals) {
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
newState(QNetworkSession::Disconnected);
@@ -499,9 +573,19 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
void QNetworkSessionPrivateImpl::stop()
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "stop() called, session state is: " << state << " and isOpen is : "
+ << isOpen;
+#endif
if (!isOpen &&
publicConfig.isValid() &&
publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "since session is not open, using RConnectionMonitor to stop() the interface";
+#endif
+ iStoppedByUser = true;
// 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,
@@ -532,11 +616,25 @@ void QNetworkSessionPrivateImpl::stop()
ETrue);
}
}
+ // Enter disconnected state right away since the session is not even open.
+ // Symbian^3 connection monitor does not emit KLinkLayerClosed when
+ // connection is stopped via connection monitor.
+ newState(QNetworkSession::Disconnected);
}
} else if (isOpen) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "since session is open, using RConnection to stop() the interface";
+#endif
// Since we are open, use RConnection to stop the interface
isOpen = false;
+ iStoppedByUser = true;
newState(QNetworkSession::Closing);
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
+ }
iConnection.Stop(RConnection::EStopAuthoritative);
isOpen = true;
close(false);
@@ -654,6 +752,10 @@ void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*
void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "roaming Error() occured";
+#endif
if (isOpen) {
isOpen = false;
activeConfig = QNetworkConfiguration();
@@ -671,6 +773,11 @@ void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
// changes immediately to Disconnected.
newState(QNetworkSession::Disconnected);
emit closed();
+ } else if (iStoppedByUser) {
+ // If the user of this session has called the stop() and
+ // configuration is based on internet SNAP, this needs to be
+ // done here because platform might roam.
+ newState(QNetworkSession::Disconnected);
}
}
#endif
@@ -975,7 +1082,12 @@ void QNetworkSessionPrivateImpl::RunL()
isOpen = false;
activeConfig = QNetworkConfiguration();
serviceConfig = QNetworkConfiguration();
- iError = QNetworkSession::UnknownSessionError;
+ if (publicConfig.state() == QNetworkConfiguration::Undefined ||
+ publicConfig.state() == QNetworkConfiguration::Defined) {
+ iError = QNetworkSession::InvalidConfigurationError;
+ } else {
+ iError = QNetworkSession::UnknownSessionError;
+ }
emit QNetworkSessionPrivate::error(iError);
Cancel();
if (ipConnectionNotifier) {
@@ -991,8 +1103,16 @@ void QNetworkSessionPrivateImpl::DoCancel()
iConnection.Close();
}
+// Enters newState if feasible according to current state.
+// AccessPointId may be given as parameter. If it is zero, state-change is assumed to
+// concern this session's configuration. If non-zero, the configuration is looked up
+// and checked if it matches the configuration this session is based on.
bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint accessPointId)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "NEW STATE, IAP ID : " << QString::number(accessPointId) << " , newState : " << QString::number(newState);
+#endif
// Make sure that activeConfig is always updated when SNAP is signaled to be
// connected.
if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork &&
@@ -1027,9 +1147,29 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (state == QNetworkSession::Roaming && newState == QNetworkSession::Connecting) {
return false;
}
+
+ // Make sure that Connected state is not reported when Connection is
+ // already Closing.
+ // Note: Stopping connection results sometimes KLinkLayerOpen
+ // to be reported first (just before KLinkLayerClosed).
+ if (state == QNetworkSession::Closing && newState == QNetworkSession::Connected) {
+ return false;
+ }
+
+ // Make sure that some lagging 'closing' state-changes do not overwrite
+ // if we are already disconnected or closed.
+ if (state == QNetworkSession::Disconnected && newState == QNetworkSession::Closing) {
+ return false;
+ }
bool emitSessionClosed = false;
- if (isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) {
+
+ // If we abruptly go down and user hasn't closed the session, we've been aborted.
+ // Note that session may be in 'closing' state and not in 'connected' state, because
+ // depending on platform the platform may report KConfigDaemonStartingDeregistration
+ // event before KLinkLayerClosed
+ if ((isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) ||
+ (isOpen && !iClosedByUser && newState == QNetworkSession::Disconnected)) {
// Active & Connected state should change directly to Disconnected state
// only when something forces connection to close (eg. when another
// application or session stops connection or when network drops
@@ -1043,14 +1183,17 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (ipConnectionNotifier) {
ipConnectionNotifier->StopNotifications();
}
- // Start monitoring changes in IAP states
- TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
emitSessionClosed = true; // Emit SessionClosed after state change has been reported
}
bool retVal = false;
if (accessPointId == 0) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed A to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
} else {
@@ -1063,6 +1206,9 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
configLocker.unlock();
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed B to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
}
@@ -1075,6 +1221,9 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
configLocker.unlock();
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed C to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
}
@@ -1088,20 +1237,13 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (symbianConfig->numericId == accessPointId) {
if (newState == QNetworkSession::Connected) {
- // Make sure that when AccessPoint is reported to be Connected
- // also state of the related configuration changes to Active.
- symbianConfig->state = QNetworkConfiguration::Active;
- configLocker.unlock();
-
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed D to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
} else {
- if (newState == QNetworkSession::Disconnected) {
- // Make sure that when AccessPoint is reported to be disconnected
- // also state of the related configuration changes from Active to Defined.
- symbianConfig->state = QNetworkConfiguration::Defined;
- }
QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
if ((config.state() == QNetworkConfiguration::Defined) ||
(config.state() == QNetworkConfiguration::Discovered)) {
@@ -1109,6 +1251,9 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
configLocker.unlock();
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
}
@@ -1121,6 +1266,19 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (emitSessionClosed) {
emit closed();
}
+ if (state == QNetworkSession::Disconnected) {
+ // The connection has gone down, and processing of status updates must be
+ // stopped. Depending on platform, there may come 'connecting/connected' states
+ // considerably later (almost a second). Connection id is an increasing
+ // number, so this does not affect next _real_ 'conneting/connected' states.
+
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ iDeprecatedConnectionId = symbianConfig->connectionId;
+ symbianConfig->mutex.unlock();
+ }
return retVal;
}
@@ -1129,6 +1287,9 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
TInt aError,
TUint accessPointId)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << QString::number(accessPointId) << " , status : " << QString::number(aConnectionStatus);
+#endif
switch (aConnectionStatus)
{
// Connection unitialised
@@ -1167,6 +1328,7 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
case KCsdGotLoginInfo:
break;
+ case KConfigDaemonStartingRegistration:
// Creating connection (e.g. GPRS activation)
case KCsdStartingConnect:
case KCsdFinishedConnect:
@@ -1193,6 +1355,7 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
case KDataTransferTemporarilyBlocked:
break;
+ case KConfigDaemonStartingDeregistration:
// Hangup or GRPS deactivation
case KConnectionStartingClose:
newState(QNetworkSession::Closing,accessPointId);
@@ -1200,136 +1363,26 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
// Connection closed
case KConnectionClosed:
- break;
-
case KLinkLayerClosed:
newState(QNetworkSession::Disconnected,accessPointId);
+ // Report manager about this to make sure this event
+ // is received by all interseted parties (mediated by
+ // manager because it does always receive all events from
+ // connection monitor).
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "reporting disconnection to manager.";
+#endif
+ if (publicConfig.isValid()) {
+ engine->configurationStateChangeReport(toSymbianConfig(privateConfiguration(publicConfig))->numericId, QNetworkSession::Disconnected);
+ }
break;
-
// Unhandled state
default:
break;
}
}
-void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent)
-{
- switch (aEvent.EventType())
- {
- case EConnMonConnectionStatusChange:
- {
- CConnMonConnectionStatusChange* realEvent;
- realEvent = (CConnMonConnectionStatusChange*) &aEvent;
-
- TUint connectionId = realEvent->ConnectionId();
- TInt connectionStatus = realEvent->ConnectionStatus();
-
- // Try to Find IAP Id using connection Id
- TUint apId = 0;
- if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
- for (int i = 0; i < subConfigurations.count(); i++ ) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(subConfigurations[i]));
-
- QMutexLocker configLocker(&symbianConfig->mutex);
-
- if (symbianConfig->connectionId == connectionId) {
- apId = symbianConfig->numericId;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(publicConfig));
-
- symbianConfig->mutex.lock();
- if (symbianConfig->connectionId == connectionId)
- apId = symbianConfig->numericId;
- symbianConfig->mutex.unlock();
- }
-
- if (apId > 0) {
- handleSymbianConnectionStatusChange(connectionStatus, KErrNone, apId);
- }
- }
- break;
-
- case EConnMonCreateConnection:
- {
- CConnMonCreateConnection* realEvent;
- realEvent = (CConnMonCreateConnection*) &aEvent;
- TUint apId;
- TUint connectionId = realEvent->ConnectionId();
- TRequestStatus status;
- iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status);
- User::WaitForRequest(status);
- if (status.Int() == KErrNone) {
- // Store connection id to related AccessPoint Configuration
- if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
- for (int i = 0; i < subConfigurations.count(); i++ ) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(subConfigurations[i]));
-
- QMutexLocker configLocker(&symbianConfig->mutex);
-
- if (symbianConfig->numericId == apId) {
- symbianConfig->connectionId = connectionId;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(publicConfig));
-
- symbianConfig->mutex.lock();
- if (symbianConfig->numericId == apId)
- symbianConfig->connectionId = connectionId;
- symbianConfig->mutex.unlock();
- }
- }
- }
- break;
-
- case EConnMonDeleteConnection:
- {
- CConnMonDeleteConnection* realEvent;
- realEvent = (CConnMonDeleteConnection*) &aEvent;
- TUint connectionId = realEvent->ConnectionId();
- // Remove connection id from related AccessPoint Configuration
- if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
- for (int i = 0; i < subConfigurations.count(); i++ ) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(subConfigurations[i]));
-
- QMutexLocker configLocker(&symbianConfig->mutex);
-
- if (symbianConfig->connectionId == connectionId) {
- symbianConfig->connectionId = 0;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(publicConfig));
-
- symbianConfig->mutex.lock();
- if (symbianConfig->connectionId == connectionId)
- symbianConfig->connectionId = 0;
- symbianConfig->mutex.unlock();
- }
- }
- break;
-
- default:
- // For unrecognized events
- break;
- }
-}
-
-ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl &owner, RConnection &connection)
+ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl& owner, RConnection& connection)
: CActive(CActive::EPriorityStandard), iOwner(owner), iConnection(connection)
{
CActiveScheduler::Add(this);
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h
index 7116519..9767293 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.h
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.h
@@ -75,9 +75,8 @@ class SymbianEngine;
class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive,
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- public MMobilityProtocolResp,
+ public MMobilityProtocolResp
#endif
- public MConnectionMonitorObserver
{
Q_OBJECT
public:
@@ -130,8 +129,9 @@ protected: // From CActive
void RunL();
void DoCancel();
-private: // MConnectionMonitorObserver
- void EventL(const CConnMonEventBase& aEvent);
+private Q_SLOTS:
+ void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState);
+ void configurationRemoved(QNetworkConfigurationPrivatePointer config);
private:
TUint iapClientCount(TUint aIAPId) const;
@@ -157,6 +157,13 @@ private: // data
mutable RConnection iConnection;
mutable RConnectionMonitor iConnectionMonitor;
ConnectionProgressNotifier* ipConnectionNotifier;
+
+ bool iHandleStateNotificationsFromManager;
+ bool iFirstSync;
+ bool iStoppedByUser;
+ bool iClosedByUser;
+ TUint32 iDeprecatedConnectionId;
+
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
CActiveCommsMobilityApiExt* iMobility;
#endif
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index 8e9675e..cea8b67 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -45,14 +45,14 @@
#include <commdb.h>
#include <cdbcols.h>
#include <d32dbms.h>
+#include <nifvar.h>
#include <QEventLoop>
#include <QTimer>
#include <QTime> // For randgen seeding
#include <QtCore> // For randgen seeding
-// #define QT_BEARERMGMT_CONFIGMGR_DEBUG
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
#include <QDebug>
#endif
@@ -73,7 +73,9 @@
QT_BEGIN_NAMESPACE
-static const int KValueThatWillBeAddedToSNAPId = 1000;
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ static const int KValueThatWillBeAddedToSNAPId = 1000;
+#endif
static const int KUserChoiceIAPId = 0;
SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate()
@@ -657,26 +659,34 @@ void SymbianEngine::updateActiveAccessPoints()
iConnectionMonitor.GetConnectionCount(connectionCount, status);
User::WaitForRequest(status);
- // Go through all connections and set state of related IAPs to Active
+ // Go through all connections and set state of related IAPs to Active.
+ // Status needs to be checked carefully, because ConnMon lists also e.g.
+ // WLAN connections that are being currently tried --> we don't want to
+ // state these as active.
TUint connectionId;
TUint subConnectionCount;
TUint apId;
+ TInt connectionStatus;
if (status.Int() == KErrNone) {
for (TUint i = 1; i <= connectionCount; i++) {
iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
QString ident = QString::number(qHash(apId));
-
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
if (ptr) {
- online = true;
- inactiveConfigs.removeOne(ident);
+ iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
+ User::WaitForRequest(status);
+ if (connectionStatus == KLinkLayerOpen) {
+ online = true;
+ inactiveConfigs.removeOne(ident);
- toSymbianConfig(ptr)->connectionId = connectionId;
+ QMutexLocker configLocker(&ptr->mutex);
+ toSymbianConfig(ptr)->connectionId = connectionId;
- // Configuration is Active
- changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
+ // Configuration is Active
+ changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
+ }
}
}
}
@@ -733,12 +743,12 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn
}
}
- // Make sure that state of rest of the IAPs won't be Discovered or Active
+ // Make sure that state of rest of the IAPs won't be Active
foreach (const QString &iface, unavailableConfigs) {
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
if (ptr) {
// Configuration is Defined
- changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined);
+ changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered);
}
}
}
@@ -894,21 +904,22 @@ void SymbianEngine::RunL()
QMutexLocker locker(&mutex);
if (iIgnoringUpdates) {
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
+#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) {
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_CONFIGMGR_DEBUG
- qDebug("CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
+#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,
@@ -957,73 +968,95 @@ void SymbianEngine::DoCancel()
ipCommsDB->CancelRequestNotification();
}
-
void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
{
QMutexLocker locker(&mutex);
switch (aEvent.EventType()) {
- case EConnMonCreateConnection:
+ case EConnMonConnectionStatusChange:
{
- CConnMonCreateConnection* realEvent;
- realEvent = (CConnMonCreateConnection*) &aEvent;
- TUint subConnectionCount = 0;
- TUint apId;
- TUint connectionId = realEvent->ConnectionId();
- TRequestStatus status;
- iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
- User::WaitForRequest(status);
- QString ident = QString::number(qHash(apId));
-
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
- if (ptr) {
- toSymbianConfig(ptr)->connectionId = connectionId;
- // Configuration is Active
- if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active))
- updateStatesToSnaps();
-
- if (!iOnline) {
- iOnline = true;
-
- locker.unlock();
- emit this->onlineStateChanged(iOnline);
- locker.relock();
+ CConnMonConnectionStatusChange* realEvent;
+ realEvent = (CConnMonConnectionStatusChange*) &aEvent;
+ TInt connectionStatus = realEvent->ConnectionStatus();
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM Connection status : " << QString::number(connectionStatus) << " , connection monitor Id : " << realEvent->ConnectionId();
+#endif
+ if (connectionStatus == KConfigDaemonStartingRegistration) {
+ TUint connectionId = realEvent->ConnectionId();
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Connecting);
}
- }
- }
- break;
-
- case EConnMonDeleteConnection:
- {
- CConnMonDeleteConnection* realEvent;
- realEvent = (CConnMonDeleteConnection*) &aEvent;
- TUint connectionId = realEvent->ConnectionId();
-
- QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
- if (ptr) {
- toSymbianConfig(ptr)->connectionId = 0;
- // Configuration is either Defined or Discovered
- if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered))
- updateStatesToSnaps();
- }
-
- bool online = false;
- foreach (const QString &iface, accessPointConfigurations.keys()) {
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
- if (ptr->state == QNetworkConfiguration::Active) {
- online = true;
- break;
+ } else if (connectionStatus == KLinkLayerOpen) {
+ // Connection has been successfully opened
+ TUint connectionId = realEvent->ConnectionId();
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ // Configuration is Active
+ if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) {
+ updateStatesToSnaps();
+ }
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Connected);
+ if (!iOnline) {
+ iOnline = true;
+ emit this->onlineStateChanged(iOnline);
+ }
}
- }
- if (iOnline != online) {
- iOnline = online;
+ } else if (connectionStatus == KConfigDaemonStartingDeregistration) {
+ TUint connectionId = realEvent->ConnectionId();
+ QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Closing);
+ }
+ } else if (connectionStatus == KLinkLayerClosed ||
+ connectionStatus == KConnectionClosed) {
+ // Connection has been closed. Which of the above events is reported, depends on the Symbian
+ // platform.
+ TUint connectionId = realEvent->ConnectionId();
+ QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
+ if (ptr) {
+ // Configuration is either Defined or Discovered
+ if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
- locker.unlock();
- emit this->onlineStateChanged(iOnline);
- locker.relock();
+ QMutexLocker configLocker(&ptr->mutex);
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Disconnected);
+ }
+
+ bool online = false;
+ foreach (const QString &iface, accessPointConfigurations.keys()) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ QMutexLocker configLocker(&ptr->mutex);
+ if (ptr->state == QNetworkConfiguration::Active) {
+ online = true;
+ break;
+ }
+ }
+ if (iOnline != online) {
+ iOnline = online;
+ emit this->onlineStateChanged(iOnline);
+ }
}
}
- break;
+ break;
case EConnMonIapAvailabilityChange:
{
@@ -1051,21 +1084,78 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
}
break;
+ case EConnMonCreateConnection:
+ {
+ // This event is caught to keep connection monitor IDs up-to-date.
+ CConnMonCreateConnection* realEvent;
+ realEvent = (CConnMonCreateConnection*) &aEvent;
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TUint connectionId = realEvent->ConnectionId();
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << toSymbianConfig(ptr)->connectionId << connectionId << ptr->name;
+#endif
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ }
+ }
+ break;
default:
// For unrecognized events
break;
}
}
-// Waits for 1..4 seconds.
+// 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,
+// whereas they _are_ reported on RConnection progress notifier used by sessions --> centralize
+// this data here so that other sessions may benefit from it too (not all sessions necessarily have
+// RConnection progress notifiers available but they relay on having e.g. disconnected information from
+// manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome.
+void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState)
+{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM A session reported state change for IAP ID: " << accessPointId << " whose new state is: " << newState;
+#endif
+ switch (newState) {
+ case QNetworkSession::Disconnected:
+ {
+ QString ident = QString::number(qHash(accessPointId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ // Configuration is either Defined or Discovered
+ if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
+
+ QMutexLocker configLocker(&ptr->mutex);
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId,
+ toSymbianConfig(ptr)->connectionId,
+ QNetworkSession::Disconnected);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+// Waits for 2..6 seconds.
void SymbianEngine::waitRandomTime()
{
- iTimeToWait = (qAbs(qrand()) % 5) * 1000;
- if (iTimeToWait < 1000) {
- iTimeToWait = 1000;
+ iTimeToWait = (qAbs(qrand()) % 7) * 1000;
+ if (iTimeToWait < 2000) {
+ iTimeToWait = 2000;
}
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("QNetworkConfigurationManager waiting random time: %d ms", iTimeToWait);
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug("QNCM waiting random time: %d ms", iTimeToWait);
#endif
QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit()));
iIgnoreEventLoop->exec();
@@ -1076,11 +1166,11 @@ QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aCon
QMutexLocker locker(&mutex);
QNetworkConfiguration item;
-
QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i =
accessPointConfigurations.constBegin();
while (i != accessPointConfigurations.constEnd()) {
QNetworkConfigurationPrivatePointer ptr = i.value();
+ QMutexLocker configLocker(&ptr->mutex);
if (toSymbianConfig(ptr)->connectionId == aConnectionId)
return ptr;
diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h
index afb37de..7d565db 100644
--- a/src/plugins/bearer/symbian/symbianengine.h
+++ b/src/plugins/bearer/symbian/symbianengine.h
@@ -52,6 +52,9 @@
#include <cmmanager.h>
#endif
+// Uncomment and compile QtBearer to gain detailed state tracing
+// #define QT_BEARERMGMT_SYMBIAN_DEBUG
+
class CCommsDatabase;
class QEventLoop;
@@ -90,7 +93,18 @@ public:
Bearer bearer;
+ // So called IAP id from the platform. Remains constant as long as the
+ // platform is aware of the configuration ie. it is stored in the databases
+ // --> does not depend on whether connections are currently open or not.
+ // In practice is the same for the lifetime of the QNetworkConfiguration.
TUint32 numericId;
+ // So called connection id, or connection monitor ID. A dynamic ID assigned
+ // by RConnectionMonitor whenever a new connection is opened. ConnectionID and
+ // numericId/IAP id have 1-to-1 mapping during the lifetime of the connection at
+ // connection monitor. Notably however it changes whenever a new connection to
+ // a given IAP is created. In a sense it is constant during the time the
+ // configuration remains between states Discovered..Active..Discovered, do not
+ // however relay on this.
TUint connectionId;
};
@@ -124,6 +138,9 @@ public:
Q_SIGNALS:
void onlineStateChanged(bool isOnline);
+ void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId,
+ QNetworkSession::State newState);
+
public Q_SLOTS:
void updateConfigurations();
@@ -157,12 +174,17 @@ private:
void startMonitoringIAPData(TUint32 aIapId);
QNetworkConfigurationPrivatePointer dataByConnectionId(TUint aConnectionId);
-protected: // From CActive
+protected:
+ // From CActive
void RunL();
void DoCancel();
-private: // MConnectionMonitorObserver
+private:
+ // MConnectionMonitorObserver
void EventL(const CConnMonEventBase& aEvent);
+ // For QNetworkSessionPrivate to indicate about state changes
+ void configurationStateChangeReport(TUint32 accessPointId,
+ QNetworkSession::State newState);
private: // Data
bool iFirstUpdate;
@@ -181,6 +203,7 @@ private: // Data
friend class QNetworkSessionPrivate;
friend class AccessPointsAvailabilityScanner;
+ friend class QNetworkSessionPrivateImpl;
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
RCmManager iCmManager;
diff --git a/tests/auto/qnetworksession/lackey/main.cpp b/tests/auto/qnetworksession/lackey/main.cpp
index 8759b52..ec2fad9 100644
--- a/tests/auto/qnetworksession/lackey/main.cpp
+++ b/tests/auto/qnetworksession/lackey/main.cpp
@@ -47,6 +47,8 @@
#include <QtNetwork/qnetworkconfigmanager.h>
#include <QtNetwork/qnetworksession.h>
+#include <QEventLoop>
+#include <QTimer>
#include <QDebug>
QT_USE_NAMESPACE
@@ -60,15 +62,14 @@ int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
- // Cannot read/write to processes on WinCE or Symbian.
- // Easiest alternative is to use sockets for IPC.
-
- QLocalSocket oopSocket;
-
- oopSocket.connectToServer("tst_qnetworksession");
- oopSocket.waitForConnected(-1);
-
+ // Update configurations so that everything is up to date for this process too.
+ // Event loop is used to wait for awhile.
QNetworkConfigurationManager manager;
+ manager.updateConfigurations();
+ QEventLoop iIgnoreEventLoop;
+ QTimer::singleShot(3000, &iIgnoreEventLoop, SLOT(quit()));
+ iIgnoreEventLoop.exec();
+
QList<QNetworkConfiguration> discovered =
manager.allConfigurations(QNetworkConfiguration::Discovered);
@@ -82,6 +83,13 @@ int main(int argc, char** argv)
return NO_DISCOVERED_CONFIGURATIONS_ERROR;
}
+ // Cannot read/write to processes on WinCE or Symbian.
+ // Easiest alternative is to use sockets for IPC.
+ QLocalSocket oopSocket;
+
+ oopSocket.connectToServer("tst_qnetworksession");
+ oopSocket.waitForConnected(-1);
+
qDebug() << "Lackey started";
QNetworkSession *session = 0;
diff --git a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
index 23cdc6a..8ab9da2 100644
--- a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
+++ b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
@@ -100,6 +100,7 @@ private slots:
private:
QNetworkConfigurationManager manager;
+ QMap<QString, bool> testsToRun;
int inProcessSessionManagementCount;
@@ -117,6 +118,7 @@ private:
bool openSession(QNetworkSession *session);
bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration = true);
void updateConfigurations();
+void printConfigurations();
QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfiguration::Type configType);
void tst_QNetworkSession::initTestCase()
@@ -125,7 +127,19 @@ void tst_QNetworkSession::initTestCase()
qRegisterMetaType<QNetworkSession::SessionError>("QNetworkSession::SessionError");
qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration");
qRegisterMetaType<QNetworkConfiguration::Type>("QNetworkConfiguration::Type");
-
+
+ // If you wish to skip tests, set value as false. This is often very convinient because tests are so lengthy.
+ // Better way still would be to make this readable from a file.
+ testsToRun["robustnessBombing"] = true;
+ testsToRun["outOfProcessSession"] = true;
+ testsToRun["invalidSession"] = true;
+ testsToRun["repeatedOpenClose"] = true;
+ testsToRun["roamingErrorCodes"] = true;
+ testsToRun["sessionStop"] = true;
+ testsToRun["sessionProperties"] = true;
+ testsToRun["userChoiceSession"] = true;
+ testsToRun["sessionOpenCloseStop"] = true;
+
#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5)
iapconf = new Maemo::IAPConf("007");
iapconf->setValue("ipv4_type", "AUTO");
@@ -238,6 +252,10 @@ void tst_QNetworkSession::cleanupTestCase()
// Robustness test for calling interfaces in nonsense order / with nonsense parameters
void tst_QNetworkSession::robustnessBombing()
{
+ if (!testsToRun["robustnessBombing"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
+
QNetworkConfigurationManager mgr;
QNetworkSession testSession(mgr.defaultConfiguration());
// Should not reset even session is not opened
@@ -253,7 +271,10 @@ void tst_QNetworkSession::robustnessBombing()
void tst_QNetworkSession::invalidSession()
-{
+{
+ if (!testsToRun["invalidSession"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
// 1. Verify that session created with invalid configuration remains in invalid state
QNetworkSession session(QNetworkConfiguration(), 0);
QVERIFY(!session.isOpen());
@@ -270,11 +291,24 @@ void tst_QNetworkSession::invalidSession()
QVERIFY(error == QNetworkSession::InvalidConfigurationError);
QVERIFY(session.error() == QNetworkSession::InvalidConfigurationError);
QVERIFY(session.state() == QNetworkSession::Invalid);
-
+
#ifdef QNETWORKSESSION_MANUAL_TESTS
+
+ QNetworkConfiguration invalidatedConfig = suitableConfiguration("WLAN",QNetworkConfiguration::InternetAccessPoint);
+ if (invalidatedConfig.isValid()) {
+ // 3. Verify that invalidating a session after its successfully configured works
+ QNetworkSession invalidatedSession(invalidatedConfig);
+ qDebug() << "Delete the WLAN IAP from phone now (waiting 60 seconds): " << invalidatedConfig.name();
+ QTest::qWait(60000);
+ QVERIFY(!invalidatedConfig.isValid());
+ QVERIFY(invalidatedSession.state() == QNetworkSession::Invalid);
+ qDebug() << "Add the WLAN IAP back (waiting 60 seconds): " << invalidatedConfig.name();
+ QTest::qWait(60000);
+ }
+
QNetworkConfiguration definedConfig = suitableConfiguration("WLAN",QNetworkConfiguration::InternetAccessPoint);
if (definedConfig.isValid()) {
- // 3. Verify that opening a session with defined configuration emits error and enters notavailable-state
+ // 4. Verify that opening a session with defined configuration emits error and enters notavailable-state
// TODO these timer waits should be changed to waiting appropriate signals, now these wait excessively
qDebug() << "Shutdown WLAN IAP (waiting 60 seconds): " << definedConfig.name();
QTest::qWait(60000);
@@ -283,43 +317,27 @@ void tst_QNetworkSession::invalidSession()
QNetworkSession definedSession(definedConfig);
QSignalSpy errorSpy(&definedSession, SIGNAL(error(QNetworkSession::SessionError)));
QNetworkSession::SessionError sessionError;
+ updateConfigurations();
definedSession.open();
+#ifdef Q_OS_SYMBIAN
+ // On symbian, the connection opening is tried even with defined state.
+ qDebug("Waiting for 10 seconds to all signals to propagate.");
+ QTest::qWait(10000);
+#endif
+ updateConfigurations();
QVERIFY(definedConfig.isValid()); // Session remains valid
QVERIFY(definedSession.state() == QNetworkSession::NotAvailable); // State is not available because WLAN is not in coverage
QVERIFY(!errorSpy.isEmpty()); // Session tells with error about invalidated configuration
sessionError = qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0));
- qDebug() << "Error code is: " << sessionError;
QVERIFY(sessionError == QNetworkSession::InvalidConfigurationError);
-
qDebug() << "Turn the WLAN IAP back on (waiting 60 seconds): " << definedConfig.name();
QTest::qWait(60000);
- updateConfigurations();
-
+ updateConfigurations();
QVERIFY(definedConfig.state() == QNetworkConfiguration::Discovered);
}
-
- QNetworkConfiguration invalidatedConfig = suitableConfiguration("WLAN",QNetworkConfiguration::InternetAccessPoint);
- if (invalidatedConfig.isValid()) {
- // 4. Verify that invalidating a session after its successfully configured works
- QNetworkSession invalidatedSession(invalidatedConfig);
- QSignalSpy errorSpy(&invalidatedSession, SIGNAL(error(QNetworkSession::SessionError)));
- QNetworkSession::SessionError sessionError;
-
- qDebug() << "Delete the WLAN IAP from phone now (waiting 60 seconds): " << invalidatedConfig.name();
- QTest::qWait(60000);
-
- invalidatedSession.open();
- QVERIFY(!invalidatedConfig.isValid());
- QVERIFY(invalidatedSession.state() == QNetworkSession::Invalid);
- QVERIFY(!errorSpy.isEmpty());
-
- sessionError = qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0));
- QVERIFY(sessionError == QNetworkSession::InvalidConfigurationError);
- qDebug() << "Add the WLAN IAP back (waiting 60 seconds): " << invalidatedConfig.name();
- QTest::qWait(60000);
- }
+
#endif
}
@@ -337,12 +355,12 @@ void tst_QNetworkSession::sessionProperties_data()
void tst_QNetworkSession::sessionProperties()
{
+ if (!testsToRun["sessionProperties"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
QFETCH(QNetworkConfiguration, configuration);
-
QNetworkSession session(configuration);
-
QVERIFY(session.configuration() == configuration);
-
QStringList validBearerNames = QStringList() << QLatin1String("Unknown")
<< QLatin1String("Ethernet")
<< QLatin1String("WLAN")
@@ -356,9 +374,6 @@ void tst_QNetworkSession::sessionProperties()
if (!configuration.isValid()) {
QVERIFY(configuration.bearerName().isEmpty());
} else {
- qDebug() << "Type:" << configuration.type()
- << "Bearer:" << configuration.bearerName();
-
switch (configuration.type())
{
case QNetworkConfiguration::ServiceNetwork:
@@ -374,9 +389,7 @@ void tst_QNetworkSession::sessionProperties()
// QNetworkSession::interface() should return an invalid interface unless
// session is in the connected state.
- qDebug() << "Session state:" << session.state();
#ifndef QT_NO_NETWORKINTERFACE
- qDebug() << "Session iface:" << session.interface().isValid() << session.interface().name();
#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
// On Symbian emulator, the support for data bearers is limited
QCOMPARE(session.state() == QNetworkSession::Connected, session.interface().isValid());
@@ -420,7 +433,12 @@ void tst_QNetworkSession::repeatedOpenClose_data() {
}
// Tests repeated-open close.
-void tst_QNetworkSession::repeatedOpenClose() {
+void tst_QNetworkSession::repeatedOpenClose()
+{
+ if (!testsToRun["repeatedOpenClose"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
+
QFETCH(QString, bearerType);
QFETCH(QNetworkConfiguration::Type, configurationType);
QFETCH(int, repeatTimes);
@@ -436,13 +454,20 @@ void tst_QNetworkSession::repeatedOpenClose() {
!closeSession(&permanentSession)) {
QSKIP("Unable to open/close session, skipping this round of repeated open-close test.", SkipSingle);
}
- for (int i = repeatTimes; i > 0; i--) {
+ for (int i = 0; i < repeatTimes; i++) {
+ qDebug() << "Opening, loop number " << i;
QVERIFY(openSession(&permanentSession));
+ qDebug() << "Closing, loop number, then waiting 5 seconds: " << i;
QVERIFY(closeSession(&permanentSession));
+ QTest::qWait(5000);
}
}
-void tst_QNetworkSession::roamingErrorCodes() {
+void tst_QNetworkSession::roamingErrorCodes()
+{
+ if (!testsToRun["roamingErrorCodes"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
#ifndef Q_OS_SYMBIAN
QSKIP("Roaming supported on Symbian.", SkipAll);
#else
@@ -466,41 +491,11 @@ void tst_QNetworkSession::roamingErrorCodes() {
adminIapSession.stop(); // requires NetworkControl capabilities
QTRY_VERIFY(!errorSpy.isEmpty()); // wait for error signals
QNetworkSession::SessionError error = qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0));
+ QTest::qWait(2000); // Wait for a moment to all platform signals to propagate
QVERIFY(error == QNetworkSession::SessionAbortedError);
QVERIFY(iapSession.state() == QNetworkSession::Disconnected);
QVERIFY(adminIapSession.state() == QNetworkSession::Disconnected);
#endif // Q_OS_SYMBIAN
-
-#ifdef QNETWORKSESSION_MANUAL_TESTS
- // Check for roaming error.
- // Case requires that you have controllable WLAN in Internet SNAP (only).
- QNetworkConfiguration snapConfig = suitableConfiguration("bearer_not_relevant_with_snaps", QNetworkConfiguration::ServiceNetwork);
- if (!snapConfig.isValid()) {
- QSKIP("No SNAP accessible, skipping test.", SkipAll);
- }
- QNetworkSession snapSession(snapConfig);
- QVERIFY(openSession(&snapSession));
- QSignalSpy errorSpySnap(&snapSession, SIGNAL(error(QNetworkSession::SessionError)));
- qDebug("Disconnect the WLAN now");
- QTRY_VERIFY(!errorSpySnap.isEmpty()); // wait for error signals
- QVERIFY(errorSpySnap.count() == 1);
- error = qvariant_cast<QNetworkSession::SessionError>(errorSpySnap.first().at(0));
- qDebug() << "Error received when turning off wlan on SNAP: " << error;
- QVERIFY(error == QNetworkSession::RoamingError);
-
- qDebug("Connect the WLAN now");
- QTest::qWait(60000); // Wait for WLAN to get up
- QNetworkConfiguration wlanIapConfig2 = suitableConfiguration("WLAN", QNetworkConfiguration::InternetAccessPoint);
- QNetworkSession iapSession2(wlanIapConfig2);
- QVERIFY(openSession(&iapSession2));
- QSignalSpy errorSpy2(&iapSession2, SIGNAL(error(QNetworkSession::SessionError)));
- qDebug("Disconnect the WLAN now");
- QTRY_VERIFY(!errorSpy2.isEmpty()); // wait for error signals
- QVERIFY(errorSpy2.count() == 1);
- error = qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0));
- QVERIFY(error == QNetworkSession::SessionAbortedError);
- QVERIFY(iapSession2.state() == QNetworkSession::Disconnected);
-#endif
}
@@ -515,6 +510,9 @@ void tst_QNetworkSession::sessionStop_data() {
void tst_QNetworkSession::sessionStop()
{
+ if (!testsToRun["sessionStop"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
#ifndef Q_OS_SYMBIAN
QSKIP("Testcase contains mainly Symbian specific checks, because it is only platform to really support interface (IAP-level) Stop.", SkipAll);
#endif
@@ -522,6 +520,9 @@ void tst_QNetworkSession::sessionStop()
QFETCH(QNetworkConfiguration::Type, configurationType);
int configWaitdelayInMs = 2000;
+
+ updateConfigurations();
+ printConfigurations();
QNetworkConfiguration config = suitableConfiguration(bearerType, configurationType);
if (!config.isValid()) {
@@ -539,6 +540,9 @@ void tst_QNetworkSession::sessionStop()
QSignalSpy closedSessionStateChangedSpy(&closedSession, SIGNAL(stateChanged(QNetworkSession::State)));
QSignalSpy closedErrorSpy(&closedSession, SIGNAL(error(QNetworkSession::SessionError)));
+ QSignalSpy openedSessionClosedSpy(&openedSession, SIGNAL(closed()));
+ QSignalSpy openedSessionStateChangedSpy(&openedSession, SIGNAL(stateChanged(QNetworkSession::State)));
+
QSignalSpy innocentSessionClosedSpy(&innocentSession, SIGNAL(closed()));
QSignalSpy innocentSessionStateChangedSpy(&innocentSession, SIGNAL(stateChanged(QNetworkSession::State)));
QSignalSpy innocentErrorSpy(&innocentSession, SIGNAL(error(QNetworkSession::SessionError)));
@@ -554,10 +558,18 @@ void tst_QNetworkSession::sessionStop()
closedSessionClosedSpy.clear();
closedSessionStateChangedSpy.clear();
closedErrorSpy.clear();
+ openedSessionStateChangedSpy.clear();
+ openedSessionClosedSpy.clear();
+
openedSession.stop();
- QVERIFY(openedSession.state() == QNetworkSession::Disconnected);
+ qDebug("Waiting for %d ms to get all configurationChange signals from platform.", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
+
+ // First to closing, then to disconnected
+ QVERIFY(openedSessionStateChangedSpy.count() == 2);
+ QVERIFY(!openedSessionClosedSpy.isEmpty());
+ QVERIFY(openedSession.state() == QNetworkSession::Disconnected);
QVERIFY(config.state() != QNetworkConfiguration::Active);
// 2. Verify that stopping a session based on non-connected configuration does nothing
@@ -583,18 +595,20 @@ void tst_QNetworkSession::sessionStop()
// 3. Check that stopping a opened session affects also other opened session based on the same configuration.
if (config.type() == QNetworkConfiguration::InternetAccessPoint) {
qDebug("----------3. Check that stopping a opened session affects also other opened session based on the same configuration.");
+
QVERIFY(openSession(&openedSession));
QVERIFY(openSession(&innocentSession));
-
+
configChangeSpy.clear();
innocentSessionClosedSpy.clear();
innocentSessionStateChangedSpy.clear();
innocentErrorSpy.clear();
-
+
openedSession.stop();
qDebug("Waiting for %d ms to get all configurationChange signals from platform.", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
-
+ QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
+
QVERIFY(!innocentSessionClosedSpy.isEmpty());
QVERIFY(!innocentSessionStateChangedSpy.isEmpty());
QVERIFY(!innocentErrorSpy.isEmpty());
@@ -614,14 +628,19 @@ void tst_QNetworkSession::sessionStop()
if (config.type() == QNetworkConfiguration::ServiceNetwork) {
qDebug("----------4. Skip for SNAP configuration.");
} else if (config.type() == QNetworkConfiguration::InternetAccessPoint) {
- qDebug("----------4. Check that stopping a non-opened session stops the other session based on the same configuration");
- QVERIFY(openSession(&innocentSession));
+ qDebug("----------4. Check that stopping a non-opened session stops the other session based on the same configuration");
+ qDebug("----------4.1 Opening innocent session");
+ QVERIFY(openSession(&innocentSession));
qDebug("Waiting for %d ms after open to make sure all platform indications are propagated", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs);
+ qDebug("----------4.2 Calling closedSession.stop()");
closedSession.stop();
qDebug("Waiting for %d ms to get all configurationChange signals from platform..", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
+ QTest::qWait(configWaitdelayInMs);
+ QTest::qWait(configWaitdelayInMs);
+
QVERIFY(!innocentSessionClosedSpy.isEmpty());
QVERIFY(!innocentSessionStateChangedSpy.isEmpty());
QVERIFY(!innocentErrorSpy.isEmpty());
@@ -653,6 +672,9 @@ void tst_QNetworkSession::userChoiceSession_data()
void tst_QNetworkSession::userChoiceSession()
{
+ if (!testsToRun["userChoiceSession"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
QFETCH(QNetworkConfiguration, configuration);
QVERIFY(configuration.type() == QNetworkConfiguration::UserChoice);
@@ -786,6 +808,9 @@ void tst_QNetworkSession::sessionOpenCloseStop_data()
void tst_QNetworkSession::sessionOpenCloseStop()
{
+ if (!testsToRun["sessionOpenCloseStop"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
QFETCH(QNetworkConfiguration, configuration);
QFETCH(bool, forceSessionStop);
@@ -894,26 +919,30 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QVERIFY(session.error() == QNetworkSession::UnknownSessionError);
session2.open();
-
+
QTRY_VERIFY(!sessionOpenedSpy2.isEmpty() || !errorSpy2.isEmpty());
+ if (errorSpy2.isEmpty()) {
+ QVERIFY(session2.isOpen());
+ QVERIFY(session2.state() == QNetworkSession::Connected);
+ }
QVERIFY(session.isOpen());
- QVERIFY(session2.isOpen());
QVERIFY(session.state() == QNetworkSession::Connected);
- QVERIFY(session2.state() == QNetworkSession::Connected);
#ifndef QT_NO_NETWORKINTERFACE
#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
// On Symbian emulator, the support for data bearers is limited
QVERIFY(session.interface().isValid());
#endif
- QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress());
- QCOMPARE(session.interface().index(), session2.interface().index());
+ if (errorSpy2.isEmpty()) {
+ QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress());
+ QCOMPARE(session.interface().index(), session2.interface().index());
+ }
#endif
}
sessionOpenedSpy2.clear();
- if (forceSessionStop) {
+ if (forceSessionStop && session2.isOpen()) {
// Test forcing the second session to stop the interface.
QNetworkSession::State previousState = session.state();
#ifdef Q_CC_NOKIAX86
@@ -922,15 +951,17 @@ void tst_QNetworkSession::sessionOpenCloseStop()
#else
bool expectStateChange = previousState != QNetworkSession::Disconnected;
#endif
-
session2.stop();
+ // QNetworkSession::stop() must result either closed() signal
+ // or error() signal
QTRY_VERIFY(!sessionClosedSpy2.isEmpty() || !errorSpy2.isEmpty());
-
QVERIFY(!session2.isOpen());
if (!errorSpy2.isEmpty()) {
- QVERIFY(!errorSpy.isEmpty());
+ // QNetworkSession::stop() resulted error() signal for session2
+ // => also session should emit error() signal
+ QTRY_VERIFY(!errorSpy.isEmpty());
// check for SessionAbortedError
QNetworkSession::SessionError error =
@@ -950,9 +981,12 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QVERIFY(errorSpy.isEmpty());
QVERIFY(errorSpy2.isEmpty());
-
+
+ // Wait for Disconnected state
+ QTRY_NOOP(session2.state() == QNetworkSession::Disconnected);
+
if (expectStateChange)
- QTRY_VERIFY(stateChangedSpy2.count() >= 2 || !errorSpy2.isEmpty());
+ QTRY_VERIFY(stateChangedSpy2.count() >= 1 || !errorSpy2.isEmpty());
if (!errorSpy2.isEmpty()) {
QVERIFY(session2.state() == previousState);
@@ -996,16 +1030,29 @@ void tst_QNetworkSession::sessionOpenCloseStop()
state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(3).at(0));
QVERIFY(state == QNetworkSession::Disconnected);
+
+ QTRY_VERIFY(session.state() == QNetworkSession::Roaming ||
+ session.state() == QNetworkSession::Connected ||
+ session.state() == QNetworkSession::Disconnected);
+
QTRY_VERIFY(stateChangedSpy.count() > 0);
- state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0));
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(stateChangedSpy.count() - 1).at(0));
+
if (state == QNetworkSession::Roaming) {
- QTRY_VERIFY(!errorSpy.isEmpty() || stateChangedSpy.count() > 1);
- if (stateChangedSpy.count() > 1 &&
- qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0)) ==
- QNetworkSession::Connected) {
- roamedSuccessfully = true;
+ QTRY_VERIFY(session.state() == QNetworkSession::Connected);
+ QTRY_VERIFY(session2.state() == QNetworkSession::Connected);
+ roamedSuccessfully = true;
+ } else if (state == QNetworkSession::Disconnected) {
+ QTRY_VERIFY(!errorSpy.isEmpty());
+ QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected);
+ } else if (state == QNetworkSession::Connected) {
+ QTRY_VERIFY(errorSpy.isEmpty());
+ if (stateChangedSpy.count() > 1) {
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(stateChangedSpy.count() - 2).at(0));
+ QVERIFY(state == QNetworkSession::Roaming);
}
- }
+ roamedSuccessfully = true;
+ }
if (roamedSuccessfully) {
QString configId = session.sessionProperty("ActiveConfiguration").toString();
@@ -1013,37 +1060,36 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QNetworkSession session3(config);
QSignalSpy errorSpy3(&session3, SIGNAL(error(QNetworkSession::SessionError)));
QSignalSpy sessionOpenedSpy3(&session3, SIGNAL(opened()));
-
session3.open();
- session3.waitForOpened();
-
+ session3.waitForOpened();
if (session.isOpen())
QVERIFY(!sessionOpenedSpy3.isEmpty() || !errorSpy3.isEmpty());
-
session.stop();
-
QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
- QTRY_VERIFY(session3.state() == QNetworkSession::Disconnected);
}
#ifndef Q_CC_NOKIAX86
if (!roamedSuccessfully)
QVERIFY(!errorSpy.isEmpty());
#endif
} else {
- QCOMPARE(stateChangedSpy2.count(), 2);
-
- QNetworkSession::State state =
- qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
- QVERIFY(state == QNetworkSession::Closing);
-
- state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0));
- QVERIFY(state == QNetworkSession::Disconnected);
+ QTest::qWait(2000); // Wait awhile to get all signals from platform
+
+ if (stateChangedSpy2.count() == 2) {
+ QNetworkSession::State state =
+ qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
+ QVERIFY(state == QNetworkSession::Closing);
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0));
+ QVERIFY(state == QNetworkSession::Disconnected);
+ } else { // Assume .count() == 1
+ QCOMPARE(stateChangedSpy2.count(), 1);
+ QNetworkSession::State state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
+ // Symbian version dependant.
+ QVERIFY(state == QNetworkSession::Disconnected);
+ }
}
QTRY_VERIFY(!sessionClosedSpy.isEmpty());
-
QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
- QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected);
}
QVERIFY(errorSpy2.isEmpty());
@@ -1062,7 +1108,7 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QVERIFY(!session.isOpen());
#endif
QVERIFY(!session2.isOpen());
- } else {
+ } else if (session2.isOpen()) {
// Test closing the second session.
{
int stateChangedCountBeforeClose = stateChangedSpy2.count();
@@ -1161,11 +1207,15 @@ QDebug operator<<(QDebug debug, const QList<QNetworkConfiguration> &list)
// at Discovered -state.
void tst_QNetworkSession::outOfProcessSession()
{
- qDebug() << "START";
-
+ if (!testsToRun["outOfProcessSession"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
#if defined(Q_OS_SYMBIAN) && defined(__WINS__)
QSKIP("Symbian emulator does not support two [QR]PRocesses linking a dll (QtBearer.dll) with global writeable static data.", SkipAll);
#endif
+ updateConfigurations();
+ QTest::qWait(2000);
+
QNetworkConfigurationManager manager;
// Create a QNetworkConfigurationManager to detect configuration changes made in Lackey. This
// is actually the essence of this testcase - to check that platform mediates/reflects changes
@@ -1182,16 +1232,15 @@ void tst_QNetworkSession::outOfProcessSession()
QLocalServer::removeServer("tst_qnetworksession");
oopServer.listen("tst_qnetworksession");
- qDebug() << "starting lackey";
QProcess lackey;
lackey.start("lackey/lackey");
qDebug() << lackey.error() << lackey.errorString();
QVERIFY(lackey.waitForStarted());
- qDebug() << "waiting for connection";
+
QVERIFY(oopServer.waitForNewConnection(-1));
QLocalSocket *oopSocket = oopServer.nextPendingConnection();
- qDebug() << "got connection";
+
do {
QByteArray output;
@@ -1258,7 +1307,6 @@ void tst_QNetworkSession::outOfProcessSession()
default:
QSKIP("Lackey failed", SkipAll);
}
- qDebug("STOP");
}
// A convinience / helper function for testcases. Return the first matching configuration.
@@ -1269,6 +1317,7 @@ QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfigur
// Refresh configurations and derive configurations matching given parameters.
QNetworkConfigurationManager mgr;
QSignalSpy updateSpy(&mgr, SIGNAL(updateCompleted()));
+
mgr.updateConfigurations();
QTRY_NOOP(updateSpy.count() == 1);
if (updateSpy.count() != 1) {
@@ -1277,8 +1326,7 @@ QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfigur
}
QList<QNetworkConfiguration> discoveredConfigs = mgr.allConfigurations(QNetworkConfiguration::Discovered);
foreach(QNetworkConfiguration config, discoveredConfigs) {
- if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
- // qDebug() << "Dumping config because is active: " << config.name();
+ if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
discoveredConfigs.removeOne(config);
} else if (config.type() != configType) {
// qDebug() << "Dumping config because type (IAP/SNAP) mismatches: " << config.name();
@@ -1315,9 +1363,23 @@ void updateConfigurations()
QTRY_NOOP(updateSpy.count() == 1);
}
+// A convinience-function: updates and prints all available confiurations and their states
+void printConfigurations()
+{
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> allConfigs =
+ manager.allConfigurations();
+ qDebug("tst_QNetworkSession::printConfigurations QNetworkConfigurationManager gives following configurations: ");
+ foreach(QNetworkConfiguration config, allConfigs) {
+ qDebug() << "Name of the configuration: " << config.name();
+ qDebug() << "State of the configuration: " << config.state();
+ }
+}
+
// A convinience function for test-cases: opens the given configuration and return
// true if it was done gracefully.
bool openSession(QNetworkSession *session) {
+ bool result = true;
QNetworkConfigurationManager mgr;
QSignalSpy openedSpy(session, SIGNAL(opened()));
QSignalSpy stateChangeSpy(session, SIGNAL(stateChanged(QNetworkSession::State)));
@@ -1327,43 +1389,57 @@ bool openSession(QNetworkSession *session) {
// active by some other session
QNetworkConfiguration::StateFlags configInitState = session->configuration().state();
QNetworkSession::State sessionInitState = session->state();
+ qDebug() << "tst_QNetworkSession::openSession() name of the configuration to be opened: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::openSession() state of the configuration to be opened: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::openSession() state of the session to be opened: " << session->state();
if (session->isOpen() ||
!session->sessionProperty("ActiveConfiguration").toString().isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: session was already open / active.");
- return false;
+ result = false;
} else {
session->open();
session->waitForOpened(120000); // Bringing interfaces up and down may take time at platform
}
+ QTest::qWait(5000); // Wait a moment to ensure all signals are propagated
// Check that connection opening went by the book. Add checks here if more strictness needed.
if (!session->isOpen()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::open() failed.");
- return false;
+ result = false;
}
if (openedSpy.count() != 1) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::opened() - signal not received.");
- return false;
+ result = false;
}
if (!errorSpy.isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::error() - signal was detected.");
- return false;
+ result = false;
}
if (sessionInitState != QNetworkSession::Connected &&
stateChangeSpy.isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::stateChanged() - signals not detected.");
- return false;
+ result = false;
}
if (configInitState != QNetworkConfiguration::Active &&
configChangeSpy.isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkConfigurationManager::configurationChanged() - signals not detected.");
- return false;
+ result = false;
}
if (session->configuration().state() != QNetworkConfiguration::Active) {
qDebug("tst_QNetworkSession::openSession() failure: session's configuration is not in 'Active' -state.");
- return false;
+ qDebug() << "tst_QNetworkSession::openSession() state is: " << session->configuration().state();
+ result = false;
+ }
+ if (result == false) {
+ qDebug() << "tst_QNetworkSession::openSession() opening session failed.";
+ } else {
+ qDebug() << "tst_QNetworkSession::openSession() opening session succeeded.";
}
- return true;
+ qDebug() << "tst_QNetworkSession::openSession() name of the configuration is: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::openSession() configuration state is: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::openSession() session state is: " << session->state();
+
+ return result;
}
// Helper function for closing opened session. Performs checks that
@@ -1376,6 +1452,11 @@ bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration) {
qDebug("tst_QNetworkSession::closeSession() failure: NULL session given");
return false;
}
+
+ qDebug() << "tst_QNetworkSession::closeSession() name of the configuration to be closed: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::closeSession() state of the configuration to be closed: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::closeSession() state of the session to be closed: " << session->state();
+
if (session->state() != QNetworkSession::Connected ||
!session->isOpen()) {
qDebug("tst_QNetworkSession::closeSession() failure: session is not opened.");
@@ -1387,38 +1468,48 @@ bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration) {
QSignalSpy sessionErrorSpy(session, SIGNAL(error(QNetworkSession::SessionError)));
QSignalSpy configChangeSpy(&mgr, SIGNAL(configurationChanged(QNetworkConfiguration)));
+ bool result = true;
session->close();
+ QTest::qWait(5000); // Wait a moment so that all signals are propagated
if (!sessionErrorSpy.isEmpty()) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession::error() received.");
- return false;
+ result = false;
}
if (sessionClosedSpy.count() != 1) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession::closed() signal not received.");
- return false;
+ result = false;
}
if (lastSessionOnConfiguration &&
sessionStateChangedSpy.isEmpty()) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession::stateChanged() signals not received.");
- return false;
+ result = false;
}
if (lastSessionOnConfiguration &&
session->state() != QNetworkSession::Disconnected) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession is not in Disconnected -state");
- return false;
+ result = false;
}
QTRY_NOOP(!configChangeSpy.isEmpty());
if (lastSessionOnConfiguration &&
configChangeSpy.isEmpty()) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkConfigurationManager::configurationChanged() - signal not detected.");
- return false;
+ result = false;
}
if (lastSessionOnConfiguration &&
session->configuration().state() == QNetworkConfiguration::Active) {
qDebug("tst_QNetworkSession::closeSession() failure: session's configuration is still in active state.");
- return false;
+ result = false;
}
- return true;
+ if (result == false) {
+ qDebug() << "tst_QNetworkSession::closeSession() closing session failed.";
+ } else {
+ qDebug() << "tst_QNetworkSession::closeSession() closing session succeeded.";
+ }
+ qDebug() << "tst_QNetworkSession::closeSession() name of the configuration is: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::closeSession() configuration state is: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::closeSession() session state is: " << session->state();
+ return result;
}
void tst_QNetworkSession::sessionAutoClose_data()