--- a/src/plugins/bearer/symbian/symbianengine.cpp Tue Jul 06 15:10:48 2010 +0300
+++ b/src/plugins/bearer/symbian/symbianengine.cpp Wed Aug 18 10:37:55 2010 +0300
@@ -46,7 +46,6 @@
#include <cdbcols.h>
#include <d32dbms.h>
#include <nifvar.h>
-#include <QEventLoop>
#include <QTimer>
#include <QTime> // For randgen seeding
#include <QtCore> // For randgen seeding
@@ -64,18 +63,15 @@
#include <cmpluginpacketdatadef.h>
#include <cmplugindialcommondefs.h>
#else
- #include <apaccesspointitem.h>
- #include <apdatahandler.h>
- #include <aputils.h>
+ #include <ApAccessPointItem.h>
+ #include <ApDataHandler.h>
+ #include <ApUtils.h>
#endif
#ifndef QT_NO_BEARERMANAGEMENT
QT_BEGIN_NAMESPACE
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- static const int KValueThatWillBeAddedToSNAPId = 1000;
-#endif
static const int KUserChoiceIAPId = 0;
SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate()
@@ -114,14 +110,19 @@
}
SymbianEngine::SymbianEngine(QObject *parent)
-: QBearerEngine(parent), CActive(CActive::EPriorityIdle), iFirstUpdate(true), iInitOk(true),
- iIgnoringUpdates(false), iTimeToWait(0), iIgnoreEventLoop(0)
+: QBearerEngine(parent), CActive(CActive::EPriorityHigh), iFirstUpdate(true), iInitOk(true),
+ iUpdatePending(false)
{
+}
+
+void SymbianEngine::initialize()
+{
+ QMutexLocker locker(&mutex);
+
CActiveScheduler::Add(this);
// Seed the randomgenerator
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid());
- iIgnoreEventLoop = new QEventLoop(this);
TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP));
if (error != KErrNone) {
@@ -130,20 +131,18 @@
}
TRAP_IGNORE(iConnectionMonitor.ConnectL());
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ TRAP_IGNORE(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1));
+#endif
TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
TRAP(error, iCmManager.OpenL());
if (error != KErrNone) {
iInitOk = false;
return;
}
#endif
-}
-
-void SymbianEngine::initialize()
-{
- QMutexLocker locker(&mutex);
SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
cpPriv->name = "UserChoice";
@@ -190,6 +189,28 @@
delete cleanup;
}
+void SymbianEngine::delayedConfigurationUpdate()
+{
+ QMutexLocker locker(&mutex);
+
+ if (iUpdatePending) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug("QNCM delayed configuration update (ECommit or ERecover occurred).");
+#endif
+ TRAPD(error, updateConfigurationsL());
+ if (error == KErrNone) {
+ updateStatesToSnaps();
+ }
+ iUpdatePending = false;
+ // Start monitoring again.
+ if (!IsActive()) {
+ SetActive();
+ // Start waiting for new notification
+ ipCommsDB->RequestNotification(iStatus);
+ }
+ }
+}
+
bool SymbianEngine::hasIdentifier(const QString &id)
{
QMutexLocker locker(&mutex);
@@ -238,19 +259,14 @@
void SymbianEngine::updateConfigurations()
{
- QMutexLocker locker(&mutex);
-
- if (!iInitOk) {
+ if (!iInitOk)
return;
- }
TRAP_IGNORE(updateConfigurationsL());
}
void SymbianEngine::updateConfigurationsL()
{
- QMutexLocker locker(&mutex);
-
QList<QString> knownConfigs = accessPointConfigurations.keys();
QList<QString> knownSnapConfigs = snapConfigurations.keys();
@@ -266,7 +282,7 @@
RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]);
CleanupClosePushL(connectionMethod);
TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
- QString ident = QString::number(qHash(iapId));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
if (accessPointConfigurations.contains(ident)) {
knownConfigs.removeOne(ident);
} else {
@@ -276,9 +292,13 @@
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
- locker.unlock();
- emit configurationAdded(ptr);
- locker.relock();
+ mutex.unlock();
+ // Emit configuration added. Connected slots may throw execptions
+ // which propagate here --> must be converted to leaves (standard
+ // std::exception would cause any TRAP trapping this function to terminate
+ // program).
+ QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+ mutex.lock();
}
}
CleanupStack::PopAndDestroy(&connectionMethod);
@@ -293,15 +313,15 @@
RCmDestination destination;
destination = iCmManager.DestinationL(destinations[i]);
CleanupClosePushL(destination);
- QString ident = QString::number(qHash(destination.Id()+KValueThatWillBeAddedToSNAPId)); //TODO: Check if it's ok to add 1000 SNAP Id to prevent SNAP ids overlapping IAP ids
+ QString ident = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX +
+ QString::number(qHash(destination.Id()));
if (snapConfigurations.contains(ident)) {
knownSnapConfigs.removeOne(ident);
} else {
SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
- CleanupStack::PushL(cpPriv);
HBufC *pName = destination.NameLC();
- cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length());
+ QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
CleanupStack::PopAndDestroy(pName);
pName = NULL;
@@ -317,60 +337,61 @@
QNetworkConfigurationPrivatePointer ptr(cpPriv);
snapConfigurations.insert(ident, ptr);
- locker.unlock();
- emit configurationAdded(ptr);
- locker.relock();
-
- CleanupStack::Pop(cpPriv);
+ mutex.unlock();
+ QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+ mutex.lock();
}
- QNetworkConfigurationPrivatePointer privSNAP = snapConfigurations.value(ident);
-
+
+ // Loop through all connection methods in this SNAP
+ QMap<unsigned int, QNetworkConfigurationPrivatePointer> connections;
for (int j=0; j < destination.ConnectionMethodCount(); j++) {
RCmConnectionMethod connectionMethod = destination.ConnectionMethodL(j);
CleanupClosePushL(connectionMethod);
-
+
TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
- QString iface = QString::number(qHash(iapId));
+ QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
// Check that IAP can be found from accessPointConfigurations list
- QNetworkConfigurationPrivatePointer priv = accessPointConfigurations.value(iface);
- if (!priv) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ if (ptr) {
+ knownConfigs.removeOne(iface);
+ } else {
SymbianNetworkConfigurationPrivate *cpPriv = NULL;
TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod));
if (error == KErrNone) {
- QNetworkConfigurationPrivatePointer ptr(cpPriv);
- toSymbianConfig(ptr)->serviceNetworkPtr = privSNAP;
+ ptr = QNetworkConfigurationPrivatePointer(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
- locker.unlock();
- emit configurationAdded(ptr);
- locker.relock();
-
- privSNAP->serviceNetworkMembers.append(ptr);
- }
- } else {
- knownConfigs.removeOne(iface);
- // Check that IAP can be found from related SNAP's configuration list
- bool iapFound = false;
- for (int i = 0; i < privSNAP->serviceNetworkMembers.count(); i++) {
- if (toSymbianConfig(privSNAP->serviceNetworkMembers[i])->numericId == iapId) {
- iapFound = true;
- break;
- }
- }
- if (!iapFound) {
- toSymbianConfig(priv)->serviceNetworkPtr = privSNAP;
- privSNAP->serviceNetworkMembers.append(priv);
+ mutex.unlock();
+ QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+ mutex.lock();
}
}
-
+
+ if (ptr) {
+ unsigned int priority;
+ TRAPD(error, priority = destination.PriorityL(connectionMethod));
+ if (!error)
+ connections.insert(priority, ptr);
+ }
+
CleanupStack::PopAndDestroy(&connectionMethod);
}
-
- if (privSNAP->serviceNetworkMembers.count() > 1) {
+
+ QNetworkConfigurationPrivatePointer privSNAP = snapConfigurations.value(ident);
+ QMutexLocker snapConfigLocker(&privSNAP->mutex);
+
+ if (privSNAP->serviceNetworkMembers != connections) {
+ privSNAP->serviceNetworkMembers = connections;
+
// Roaming is supported only if SNAP contains more than one IAP
- privSNAP->roamingSupported = true;
+ privSNAP->roamingSupported = privSNAP->serviceNetworkMembers.count() > 1;
+
+ snapConfigLocker.unlock();
+ mutex.unlock();
+ QT_TRYCATCH_LEAVING(emit configurationChanged(privSNAP));
+ mutex.lock();
}
-
+
CleanupStack::PopAndDestroy(&destination);
}
CleanupStack::PopAndDestroy(&destinations);
@@ -384,7 +405,7 @@
TInt retVal = pDbTView->GotoFirstRecord();
while (retVal == KErrNone) {
pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId);
- QString ident = QString::number(qHash(apId));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
if (accessPointConfigurations.contains(ident)) {
knownConfigs.removeOne(ident);
} else {
@@ -393,9 +414,9 @@
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ident, ptr);
- locker.unlock();
- emit configurationAdded(ptr);
- locker.relock();
+ mutex.unlock();
+ QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
+ mutex.lock();
} else {
delete cpPriv;
}
@@ -404,24 +425,29 @@
}
CleanupStack::PopAndDestroy(pDbTView);
#endif
- updateActiveAccessPoints();
+ QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
foreach (const QString &oldIface, knownConfigs) {
//remove non existing IAP
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface);
- locker.unlock();
+ mutex.unlock();
emit configurationRemoved(ptr);
- locker.relock();
+ QT_TRYCATCH_LEAVING(emit configurationRemoved(ptr));
+ mutex.lock();
// Remove non existing IAP from SNAPs
foreach (const QString &iface, snapConfigurations.keys()) {
QNetworkConfigurationPrivatePointer ptr2 = snapConfigurations.value(iface);
// => Check if one of the IAPs of the SNAP is active
- for (int i = 0; i < ptr2->serviceNetworkMembers.count(); ++i) {
- if (toSymbianConfig(ptr2->serviceNetworkMembers[i])->numericId ==
- toSymbianConfig(ptr)->numericId) {
- ptr2->serviceNetworkMembers.removeAt(i);
+ QMutexLocker snapConfigLocker(&ptr2->mutex);
+ QMutableMapIterator<unsigned int, QNetworkConfigurationPrivatePointer> i(ptr2->serviceNetworkMembers);
+ while (i.hasNext()) {
+ i.next();
+
+ if (toSymbianConfig(i.value())->numericIdentifier() ==
+ toSymbianConfig(ptr)->numericIdentifier()) {
+ i.remove();
break;
}
}
@@ -432,27 +458,29 @@
//remove non existing SNAPs
QNetworkConfigurationPrivatePointer ptr = snapConfigurations.take(oldIface);
- locker.unlock();
+ mutex.unlock();
emit configurationRemoved(ptr);
- locker.relock();
+ QT_TRYCATCH_LEAVING(emit configurationRemoved(ptr));
+ mutex.lock();
}
+
+ // find default configuration.
+ stopCommsDatabaseNotifications();
+ TRAP_IGNORE(defaultConfig = defaultConfigurationL());
+ startCommsDatabaseNotifications();
}
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL(
RCmConnectionMethod& connectionMethod)
{
- QMutexLocker locker(&mutex);
-
SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
- CleanupStack::PushL(cpPriv);
-
TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
- QString ident = QString::number(qHash(iapId));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName);
CleanupStack::PushL(pName);
- cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length());
+ QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
CleanupStack::PopAndDestroy(pName);
pName = NULL;
@@ -500,7 +528,7 @@
if (error == KErrNone && pName) {
CleanupStack::PushL(pName);
- cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length());
+ QT_TRYCATCH_LEAVING(cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length()));
CleanupStack::PopAndDestroy(pName);
pName = NULL;
}
@@ -518,16 +546,12 @@
cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
cpPriv->roamingSupported = false;
-
- CleanupStack::Pop(cpPriv);
return cpPriv;
}
#else
bool SymbianEngine::readNetworkConfigurationValuesFromCommsDb(
TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration)
{
- QMutexLocker locker(&mutex);
-
TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration));
if (error != KErrNone) {
return false;
@@ -538,8 +562,6 @@
void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL(
TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration)
{
- QMutexLocker locker(&mutex);
-
CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB);
CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC();
TBuf<KCommsDbSvrMaxColumnNameLength> name;
@@ -554,9 +576,9 @@
User::Leave(KErrNotFound);
}
- QString ident = QString::number(qHash(aApId));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(aApId));
- apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length());
+ QT_TRYCATCH_LEAVING(apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length()));
apNetworkConfiguration->isValid = true;
apNetworkConfiguration->id = ident;
apNetworkConfiguration->numericId = aApId;
@@ -602,15 +624,7 @@
{
QMutexLocker locker(&mutex);
- QNetworkConfigurationPrivatePointer ptr;
-
- if (iInitOk) {
- stopCommsDatabaseNotifications();
- TRAP_IGNORE(ptr = defaultConfigurationL());
- startCommsDatabaseNotifications();
- }
-
- return ptr;
+ return defaultConfig;
}
QStringList SymbianEngine::accessPointConfigurationIdentifiers()
@@ -622,8 +636,6 @@
QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL()
{
- QMutexLocker locker(&mutex);
-
QNetworkConfigurationPrivatePointer ptr;
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
@@ -631,26 +643,28 @@
TCmDefConnValue defaultConnectionValue;
iCmManager.ReadDefConnL(defaultConnectionValue);
if (defaultConnectionValue.iType == ECmDefConnDestination) {
- QString iface = QString::number(qHash(defaultConnectionValue.iId+KValueThatWillBeAddedToSNAPId));
+ QString iface = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX +
+ QString::number(qHash(defaultConnectionValue.iId));
ptr = snapConfigurations.value(iface);
} else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) {
- QString iface = QString::number(qHash(defaultConnectionValue.iId));
+ QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
+ QString::number(qHash(defaultConnectionValue.iId));
ptr = accessPointConfigurations.value(iface);
}
#endif
- if (!ptr || !ptr->isValid) {
- QString iface = QString::number(qHash(KUserChoiceIAPId));
- ptr = userChoiceConfigurations.value(iface);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ if (ptr->isValid)
+ return ptr;
}
-
- return ptr;
+
+ QString iface = QString::number(qHash(KUserChoiceIAPId));
+ return userChoiceConfigurations.value(iface);
}
void SymbianEngine::updateActiveAccessPoints()
{
- QMutexLocker locker(&mutex);
-
bool online = false;
QList<QString> inactiveConfigs = accessPointConfigurations.keys();
@@ -672,8 +686,14 @@
iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
- QString ident = QString::number(qHash(apId));
+ 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);
@@ -681,8 +701,9 @@
online = true;
inactiveConfigs.removeOne(ident);
- QMutexLocker configLocker(&ptr->mutex);
+ ptr->mutex.lock();
toSymbianConfig(ptr)->connectionId = connectionId;
+ ptr->mutex.unlock();
// Configuration is Active
changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
@@ -702,16 +723,14 @@
if (iOnline != online) {
iOnline = online;
- locker.unlock();
- emit this->onlineStateChanged(iOnline);
- locker.relock();
+ mutex.unlock();
+ emit this->onlineStateChanged(online);
+ mutex.lock();
}
}
void SymbianEngine::updateAvailableAccessPoints()
{
- QMutexLocker locker(&mutex);
-
if (!ipAccessPointsAvailabilityScanner) {
ipAccessPointsAvailabilityScanner = new AccessPointsAvailabilityScanner(*this, iConnectionMonitor);
}
@@ -723,8 +742,6 @@
void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo)
{
- QMutexLocker locker(&mutex);
-
iUpdateGoingOn = false;
if (scanSuccessful) {
QList<QString> unavailableConfigs = accessPointConfigurations.keys();
@@ -732,10 +749,13 @@
// Set state of returned IAPs to Discovered
// if state is not already Active
for(TUint i=0; i<iapInfo.iCount; i++) {
- QString ident = QString::number(qHash(iapInfo.iIap[i].iIapId));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
+ QString::number(qHash(iapInfo.iIap[i].iIapId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
if (ptr) {
unavailableConfigs.removeOne(ident);
+
+ QMutexLocker configLocker(&ptr->mutex);
if (ptr->state < QNetworkConfiguration::Active) {
// Configuration is either Discovered or Active
changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered);
@@ -757,31 +777,38 @@
if (!iFirstUpdate) {
startCommsDatabaseNotifications();
- locker.unlock();
+ mutex.unlock();
emit updateCompleted();
- locker.relock();
+ mutex.lock();
}
}
void SymbianEngine::updateStatesToSnaps()
{
- QMutexLocker locker(&mutex);
-
// Go through SNAPs and set correct state to SNAPs
foreach (const QString &iface, snapConfigurations.keys()) {
bool discovered = false;
bool active = false;
QNetworkConfigurationPrivatePointer ptr = snapConfigurations.value(iface);
+
+ QMutexLocker snapConfigLocker(&ptr->mutex);
+
// => Check if one of the IAPs of the SNAP is discovered or active
// => If one of IAPs is active, also SNAP is active
// => If one of IAPs is discovered but none of the IAPs is active, SNAP is discovered
- for (int i=0; i<ptr->serviceNetworkMembers.count(); i++) {
- if ((ptr->serviceNetworkMembers[i]->state & QNetworkConfiguration::Active)
- == QNetworkConfiguration::Active) {
+ QMapIterator<unsigned int, QNetworkConfigurationPrivatePointer> i(ptr->serviceNetworkMembers);
+ while (i.hasNext()) {
+ i.next();
+
+ const QNetworkConfigurationPrivatePointer child = i.value();
+
+ QMutexLocker configLocker(&child->mutex);
+
+ if ((child->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
active = true;
break;
- } else if ((ptr->serviceNetworkMembers[i]->state & QNetworkConfiguration::Discovered)
- == QNetworkConfiguration::Discovered) {
+ } else if ((child->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
discovered = true;
}
}
@@ -795,19 +822,70 @@
}
}
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+void SymbianEngine::updateMobileBearerToConfigs(TConnMonBearerInfo bearerInfo)
+{
+ QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i =
+ accessPointConfigurations.constBegin();
+ while (i != accessPointConfigurations.constEnd()) {
+ QNetworkConfigurationPrivatePointer ptr = i.value();
+
+ QMutexLocker locker(&ptr->mutex);
+
+ SymbianNetworkConfigurationPrivate *p = toSymbianConfig(ptr);
+
+ if (p->bearer >= SymbianNetworkConfigurationPrivate::Bearer2G &&
+ p->bearer <= SymbianNetworkConfigurationPrivate::BearerHSPA) {
+ switch (bearerInfo) {
+ case EBearerInfoCSD:
+ p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case EBearerInfoWCDMA:
+ p->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA;
+ break;
+ case EBearerInfoCDMA2000:
+ p->bearer = SymbianNetworkConfigurationPrivate::BearerCDMA2000;
+ break;
+ case EBearerInfoGPRS:
+ p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case EBearerInfoHSCSD:
+ p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case EBearerInfoEdgeGPRS:
+ p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G;
+ break;
+ case EBearerInfoWcdmaCSD:
+ p->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA;
+ break;
+ case EBearerInfoHSDPA:
+ p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+ break;
+ case EBearerInfoHSUPA:
+ p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+ break;
+ case EBearerInfoHSxPA:
+ p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA;
+ break;
+ }
+ }
+
+ ++i;
+ }
+}
+#endif
+
bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr,
QNetworkConfiguration::StateFlags newState)
{
- QMutexLocker locker(&mutex);
-
ptr->mutex.lock();
if (newState != ptr->state) {
ptr->state = newState;
ptr->mutex.unlock();
- locker.unlock();
+ mutex.unlock();
emit configurationChanged(ptr);
- locker.relock();
+ mutex.lock();
return true;
} else {
@@ -823,16 +901,14 @@
bool SymbianEngine::changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr,
QNetworkConfiguration::StateFlags newState)
{
- QMutexLocker locker(&mutex);
-
ptr->mutex.lock();
if ((newState | ptr->state) != ptr->state) {
ptr->state = (ptr->state | newState);
ptr->mutex.unlock();
- locker.unlock();
+ mutex.unlock();
emit configurationChanged(ptr);
- locker.relock();
+ mutex.lock();
return true;
} else {
@@ -849,16 +925,14 @@
bool SymbianEngine::changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr,
QNetworkConfiguration::StateFlags newState)
{
- QMutexLocker locker(&mutex);
-
ptr->mutex.lock();
if ((newState & ptr->state) != ptr->state) {
ptr->state = (newState & ptr->state);
ptr->mutex.unlock();
- locker.unlock();
+ mutex.unlock();
emit configurationChanged(ptr);
- locker.relock();
+ mutex.lock();
return true;
} else {
@@ -869,8 +943,6 @@
void SymbianEngine::startCommsDatabaseNotifications()
{
- QMutexLocker locker(&mutex);
-
if (!iWaitingCommsDatabaseNotifications) {
iWaitingCommsDatabaseNotifications = ETrue;
if (!IsActive()) {
@@ -883,19 +955,9 @@
void SymbianEngine::stopCommsDatabaseNotifications()
{
- QMutexLocker locker(&mutex);
-
if (iWaitingCommsDatabaseNotifications) {
iWaitingCommsDatabaseNotifications = EFalse;
- if (!IsActive()) {
- SetActive();
- // Make sure that notifier recorded events will not be returned
- // as soon as the client issues the next RequestNotification() request.
- ipCommsDB->RequestNotification(iStatus);
- ipCommsDB->CancelRequestNotification();
- } else {
- ipCommsDB->CancelRequestNotification();
- }
+ Cancel();
}
}
@@ -903,48 +965,25 @@
{
QMutexLocker locker(&mutex);
- if (iIgnoringUpdates) {
-#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) {
+ // 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::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::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
- iIgnoringUpdates = true;
- // Other events than ECommit get lower priority. In practice with those events,
- // we delay_before_updating methods, whereas
- // with ECommit we _update_before_delaying the reaction to next event.
- // Few important notes: 1) listening to only ECommit does not seem to be adequate,
- // but updates will be missed. Hence other events are reacted upon too.
- // 2) RDbNotifier records the most significant event, and that will be returned once
- // we issue new RequestNotification, and hence updates will not be missed even
- // when we are 'not reacting to them' for few seconds.
- if (event == RDbNotifier::ECommit) {
- TRAPD(error, updateConfigurationsL());
- if (error == KErrNone) {
- updateStatesToSnaps();
- }
- waitRandomTime();
- } else {
- waitRandomTime();
- TRAPD(error, updateConfigurationsL());
- if (error == KErrNone) {
- updateStatesToSnaps();
- }
+ // 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) {
+ iUpdatePending = true;
+ iWaitingCommsDatabaseNotifications = false;
+ // Update after random time, so that many processes won't
+ // start updating simultaneously
+ updateConfigurationsAfterRandomTime();
}
- iIgnoringUpdates = false; // Wait time done, allow updating again
- iWaitingCommsDatabaseNotifications = true;
break;
default:
// Do nothing
@@ -973,6 +1012,20 @@
QMutexLocker locker(&mutex);
switch (aEvent.EventType()) {
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ case EConnMonBearerInfoChange:
+ {
+ CConnMonBearerInfoChange* realEvent;
+ realEvent = (CConnMonBearerInfoChange*) &aEvent;
+ TUint connectionId = realEvent->ConnectionId();
+ if (connectionId == EBearerIdAll) {
+ //Network level event
+ TConnMonBearerInfo bearerInfo = (TConnMonBearerInfo)realEvent->BearerInfo();
+ updateMobileBearerToConfigs(bearerInfo);
+ }
+ break;
+ }
+#endif
case EConnMonConnectionStatusChange:
{
CConnMonConnectionStatusChange* realEvent;
@@ -988,12 +1041,23 @@
TRequestStatus status;
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
- QString ident = QString::number(qHash(apId));
+
+ 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) {
- QMutexLocker configLocker(&ptr->mutex);
+ ptr->mutex.lock();
toSymbianConfig(ptr)->connectionId = connectionId;
- emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Connecting);
+ ptr->mutex.unlock();
+ QT_TRYCATCH_LEAVING(
+ emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
+ connectionId, QNetworkSession::Connecting)
+ );
}
} else if (connectionStatus == KLinkLayerOpen) {
// Connection has been successfully opened
@@ -1003,27 +1067,41 @@
TRequestStatus status;
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
- QString ident = QString::number(qHash(apId));
+ 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) {
- QMutexLocker configLocker(&ptr->mutex);
+ ptr->mutex.lock();
toSymbianConfig(ptr)->connectionId = connectionId;
+ ptr->mutex.unlock();
+
// 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);
- }
+ QT_TRYCATCH_LEAVING(
+ if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) {
+ updateStatesToSnaps();
+ }
+ emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
+ connectionId, QNetworkSession::Connected);
+
+ if (!iOnline) {
+ iOnline = true;
+ emit this->onlineStateChanged(iOnline);
+ }
+ );
}
} 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);
+ QT_TRYCATCH_LEAVING(
+ emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
+ connectionId, QNetworkSession::Closing)
+ );
}
} else if (connectionStatus == KLinkLayerClosed ||
connectionStatus == KConnectionClosed) {
@@ -1033,12 +1111,13 @@
QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
if (ptr) {
// Configuration is either Defined or Discovered
- if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
- updateStatesToSnaps();
- }
-
- QMutexLocker configLocker(&ptr->mutex);
- emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Disconnected);
+ QT_TRYCATCH_LEAVING(
+ if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
+ emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
+ connectionId, QNetworkSession::Disconnected);
+ );
}
bool online = false;
@@ -1052,7 +1131,7 @@
}
if (iOnline != online) {
iOnline = online;
- emit this->onlineStateChanged(iOnline);
+ QT_TRYCATCH_LEAVING(emit this->onlineStateChanged(iOnline));
}
}
}
@@ -1065,12 +1144,13 @@
TConnMonIapInfo iaps = realEvent->IapAvailability();
QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys();
for ( TUint i = 0; i < iaps.Count(); i++ ) {
- QString ident = QString::number(qHash(iaps.iIap[i].iIapId));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
+ QString::number(qHash(iaps.iIap[i].iIapId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
if (ptr) {
// Configuration is either Discovered or Active
- changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered);
+ QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered));
unDiscoveredConfigs.removeOne(ident);
}
}
@@ -1078,7 +1158,7 @@
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
if (ptr) {
// Configuration is Defined
- changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined);
+ QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined));
}
}
}
@@ -1095,8 +1175,14 @@
TRequestStatus status;
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
- QString ident = QString::number(qHash(apId));
+ 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
@@ -1112,6 +1198,43 @@
}
}
+#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,
@@ -1121,13 +1244,16 @@
// manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome.
void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState)
{
+ QMutexLocker locker(&mutex);
+
#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));
+ QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
+ QString::number(qHash(accessPointId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
if (ptr) {
// Configuration is either Defined or Discovered
@@ -1135,10 +1261,11 @@
updateStatesToSnaps();
}
- QMutexLocker configLocker(&ptr->mutex);
- emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId,
- toSymbianConfig(ptr)->connectionId,
- QNetworkSession::Disconnected);
+ locker.unlock();
+ emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
+ toSymbianConfig(ptr)->connectionIdentifier(),
+ QNetworkSession::Disconnected);
+ locker.relock();
}
}
break;
@@ -1148,30 +1275,23 @@
}
// Waits for 2..6 seconds.
-void SymbianEngine::waitRandomTime()
+void SymbianEngine::updateConfigurationsAfterRandomTime()
{
- iTimeToWait = (qAbs(qrand()) % 7) * 1000;
- if (iTimeToWait < 2000) {
- iTimeToWait = 2000;
- }
+ int iTimeToWait = qMax(1000, (qAbs(qrand()) % 68) * 100);
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug("QNCM waiting random time: %d ms", iTimeToWait);
#endif
- QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit()));
- iIgnoreEventLoop->exec();
+ QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate()));
}
QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId)
{
- 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)
+ if (toSymbianConfig(ptr)->connectionIdentifier() == aConnectionId)
return ptr;
++i;
@@ -1182,7 +1302,7 @@
AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& owner,
RConnectionMonitor& connectionMonitor)
- : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor)
+ : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor)
{
CActiveScheduler::Add(this);
}
@@ -1218,11 +1338,13 @@
void AccessPointsAvailabilityScanner::RunL()
{
+ QMutexLocker locker(&iOwner.mutex);
+
if (iStatus.Int() != KErrNone) {
iIapBuf().iCount = 0;
- iOwner.accessPointScanningReady(false,iIapBuf());
+ QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(false,iIapBuf()));
} else {
- iOwner.accessPointScanningReady(true,iIapBuf());
+ QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(true,iIapBuf()));
}
}