summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@nokia.com>2010-06-10 06:23:34 (GMT)
committerAaron McCarthy <aaron.mccarthy@nokia.com>2010-06-24 02:27:55 (GMT)
commit94c64b9ae4d539e9578156a0df999de1605f858f (patch)
tree9a6e612fc9feb7a5ac3b0ca687befdab72c63fa8
parent94797fdd2e752677a5665abc9b23aa22f8a9c4db (diff)
downloadQt-94c64b9ae4d539e9578156a0df999de1605f858f.zip
Qt-94c64b9ae4d539e9578156a0df999de1605f858f.tar.gz
Qt-94c64b9ae4d539e9578156a0df999de1605f858f.tar.bz2
Cherry pick fix for MOBILITY-965 from Qt Mobility.
50de830ded2dcc1c6b4d8be71428d9a2bfed6ae7
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp84
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp70
-rw-r--r--src/plugins/bearer/symbian/symbianengine.h3
3 files changed, 147 insertions, 10 deletions
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index b90d603..940281c 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -69,6 +69,7 @@ QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
if (iOpenCLibrary.Load(_L("libc")) == KErrNone) {
iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597);
}
+
TRAP_IGNORE(iConnectionMonitor.ConnectL());
}
@@ -91,6 +92,7 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
iMobility = NULL;
}
#endif
+
iConnection.Close();
iSocketServ.Close();
@@ -433,6 +435,10 @@ void QNetworkSessionPrivateImpl::open()
toSymbianConfig(privateConfiguration(publicConfig));
#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ // On Symbian^3 if service network is not reachable, it triggers a UI (aka EasyWLAN) where
+ // user can create new IAPs. To detect this, we need to store the number of IAPs
+ // there was before connection was started.
+ iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurationIdentifiers();
TConnPrefList snapPref;
TExtendedConnPref prefs;
prefs.SetSnapId(symbianConfig->numericIdentifier());
@@ -511,7 +517,11 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
iClosedByUser = true;
isOpen = false;
+#ifndef OCC_FUNCTIONALITY_AVAILABLE
+ // On Symbian^3 we need to keep track of active configuration longer
+ // in case of empty-SNAP-triggered EasyWLAN.
activeConfig = QNetworkConfiguration();
+#endif
serviceConfig = QNetworkConfiguration();
Cancel();
@@ -906,7 +916,7 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
_LIT(KSetting, "IAP\\Id");
iConnection.GetIntSetting(KSetting, iapId);
}
-
+
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
// Try to search IAP from the used SNAP using IAP Id
@@ -943,17 +953,54 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
}
}
} else {
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ // On Symbian^3 (only, not earlier or Symbian^4) if the SNAP was not reachable, it triggers
+ // user choice type of activity (EasyWLAN). As a result, a new IAP may be created, and
+ // hence if was not found yet. Therefore update configurations and see if there is something new.
+ // 1. Update knowledge from the databases.
+ engine->requestUpdate();
+ // 2. Check if new configuration was created during connection creation
+ QList<QString> knownConfigs = engine->accessPointConfigurationIdentifiers();
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "opened configuration was not known beforehand, looking for new.";
+#endif
+ if (knownConfigs.count() > iKnownConfigsBeforeConnectionStart.count()) {
+ // Configuration count increased => new configuration was created
+ // => Search new, created configuration
+ QString newIapId;
+ for (int i=0; i < iKnownConfigsBeforeConnectionStart.count(); i++) {
+ if (knownConfigs[i] != iKnownConfigsBeforeConnectionStart[i]) {
+ newIapId = knownConfigs[i];
+ break;
+ }
+ }
+ if (newIapId.isEmpty()) {
+ newIapId = knownConfigs[knownConfigs.count()-1];
+ }
+ pt = QNetworkConfigurationManager().configurationFromIdentifier(newIapId);
+ if (pt.isValid()) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "new configuration was found, name, IAP id: " << pt.name() << pt.identifier();
+#endif
+ return pt;
+ }
+ }
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "configuration was not found, returning invalid.";
+#endif
+#endif // OCC_FUNCTIONALITY_AVAILABLE
// Given IAP Id was not found from known IAPs array
return QNetworkConfiguration();
}
-
// Matching IAP was not found from used SNAP
// => IAP from another SNAP is returned
// (Note: Returned IAP matches to given IAP Id)
return pt;
}
#endif
-
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
if (engine) {
QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(
@@ -994,6 +1041,10 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
void QNetworkSessionPrivateImpl::RunL()
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "RConnection::RunL with status code: " << iStatus.Int();
+#endif
TInt statusCode = iStatus.Int();
switch (statusCode) {
@@ -1226,7 +1277,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
if ((config.state() == QNetworkConfiguration::Defined) ||
(config.state() == QNetworkConfiguration::Discovered)) {
-
+ activeConfig = QNetworkConfiguration();
state = newState;
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E to: " << state;
@@ -1247,6 +1298,21 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
}
}
}
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ // If the retVal is not true here, it means that the status update may apply to an IAP outside of
+ // SNAP (session is based on SNAP but follows IAP outside of it), which may occur on Symbian^3 EasyWlan.
+ if (retVal == false && activeConfig.d.data() && activeConfig.d.data()->numericId == accessPointId) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed G to: " << state;
+#endif
+ if (newState == QNetworkSession::Disconnected) {
+ activeConfig = QNetworkConfiguration();
+ }
+ state = newState;
+ emit q->stateChanged(state);
+ retVal = true;
+ }
+#endif
}
}
@@ -1262,9 +1328,15 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
SymbianNetworkConfigurationPrivate *symbianConfig =
toSymbianConfig(privateConfiguration(publicConfig));
- iDeprecatedConnectionId = symbianConfig->connectionIdentifier();
- }
+ symbianConfig->mutex.lock();
+ iDeprecatedConnectionId = symbianConfig->connectionId;
+ symbianConfig->mutex.unlock();
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ // Just in case clear activeConfiguration.
+ activeConfig = QNetworkConfiguration();
+#endif
+ }
return retVal;
}
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index bda3e56..ca444c1 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -683,6 +683,12 @@ void SymbianEngine::updateActiveAccessPoints()
User::WaitForRequest(status);
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ if (!ptr) {
+ // If IAP was not found, check if the update was about EasyWLAN
+ ptr = configurationFromEasyWlan(apId, connectionId);
+ }
+#endif
if (ptr) {
iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
User::WaitForRequest(status);
@@ -713,7 +719,7 @@ void SymbianEngine::updateActiveAccessPoints()
if (iOnline != online) {
iOnline = online;
mutex.unlock();
- emit this->onlineStateChanged(iOnline);
+ emit this->onlineStateChanged(online);
mutex.lock();
}
}
@@ -951,15 +957,15 @@ void SymbianEngine::RunL()
QMutexLocker locker(&mutex);
if (iStatus != KErrCancel) {
-#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
- qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
-#endif
// By default, start relistening notifications. Stop only if interesting event occured.
iWaitingCommsDatabaseNotifications = true;
RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int());
switch (event) {
case RDbNotifier::ECommit: /** A transaction has been committed. */
case RDbNotifier::ERecover: /** The database has been recovered */
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
+#endif
// Mark that there is update pending. No need to ask more events,
// as we know we will be updating anyway when the timer expires.
if (!iUpdatePending) {
@@ -1026,8 +1032,15 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
TRequestStatus status;
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
+
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ if (!ptr) {
+ // Check if status was regarding EasyWLAN
+ ptr = configurationFromEasyWlan(apId, connectionId);
+ }
+#endif
if (ptr) {
ptr->mutex.lock();
toSymbianConfig(ptr)->connectionId = connectionId;
@@ -1047,6 +1060,12 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
User::WaitForRequest(status);
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ if (!ptr) {
+ // Check for EasyWLAN
+ ptr = configurationFromEasyWlan(apId, connectionId);
+ }
+#endif
if (ptr) {
ptr->mutex.lock();
toSymbianConfig(ptr)->connectionId = connectionId;
@@ -1149,6 +1168,12 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
User::WaitForRequest(status);
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ if (!ptr) {
+ // If IAP was not found, check if the update was about EasyWLAN
+ ptr = configurationFromEasyWlan(apId, connectionId);
+ }
+#endif
if (ptr) {
QMutexLocker configLocker(&ptr->mutex);
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
@@ -1164,6 +1189,43 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
}
}
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+// Tries to derive configuration from EasyWLAN.
+// First checks if the interface brought up was EasyWLAN, then derives the real SSID,
+// and looks up configuration based on that one.
+QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId, TUint connectionId)
+{
+ if (apId == iCmManager.EasyWlanIdL()) {
+ TRequestStatus status;
+ TBuf<50> easyWlanNetworkName;
+ iConnectionMonitor.GetStringAttribute( connectionId, 0, KNetworkName,
+ easyWlanNetworkName, status );
+ User::WaitForRequest(status);
+ if (status.Int() == KErrNone) {
+ QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(), easyWlanNetworkName.Length());
+
+ // Browser through all items and check their name for match
+ QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
+ accessPointConfigurations.constBegin();
+ while (i != accessPointConfigurations.constEnd()) {
+ QNetworkConfigurationPrivatePointer ptr = i.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if (ptr->name == realSSID) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM EasyWlan uses real SSID: " << realSSID;
+#endif
+ return ptr;
+ }
+ ++i;
+ }
+ }
+ }
+ return QNetworkConfigurationPrivatePointer();
+}
+#endif
+
// 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,
diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h
index d95d4d5..cfddc29 100644
--- a/src/plugins/bearer/symbian/symbianengine.h
+++ b/src/plugins/bearer/symbian/symbianengine.h
@@ -206,6 +206,9 @@ private:
// For QNetworkSessionPrivate to indicate about state changes
void configurationStateChangeReport(TUint32 accessPointId,
QNetworkSession::State newState);
+#ifdef OCC_FUNCTIONALITY_AVAILABLE
+ QNetworkConfigurationPrivatePointer configurationFromEasyWlan(TUint32 apId, TUint connectionId);
+#endif
private: // Data
bool iFirstUpdate;