Binary file qtmobility/data/qtmobility.sisx has changed
--- a/qtmobility/src/bearer/qcorewlanengine_mac.mm Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qcorewlanengine_mac.mm Wed Jun 09 10:36:00 2010 +0300
@@ -43,6 +43,7 @@
#include "qnetworkconfiguration_p.h"
#include <QtCore/qthread.h>
+#include <QThread>
#include <QtCore/qmutex.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qstringlist.h>
@@ -105,6 +106,8 @@
QTM_NAMESPACE::QCoreWlanEngine::instance()->requestUpdate();
}
@end
+
+QNSListener *listener = 0;
#endif
QTM_BEGIN_NAMESPACE
@@ -143,11 +146,6 @@
return result;
}
-static QString qGetInterfaceType(const QString &interfaceString)
-{
- return networkInterfaces.value(interfaceString, QLatin1String("Unknown"));
-}
-
void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info)
{
for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) {
@@ -161,23 +159,314 @@
return;
}
+QScanThread::QScanThread(QObject *parent)
+ :QThread(parent), interfaceName(nil)
+{
+}
+
+QScanThread::~QScanThread()
+{
+}
+
+void QScanThread::quit()
+{
+ wait();
+}
+
+void QScanThread::run()
+{
+#if defined(MAC_SDK_10_6)
+ getUserProfiles();
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ QStringList found;
+ mutex.lock();
+ CWInterface *currentInterface;
+ if(interfaceName.isEmpty()) {
+ currentInterface = [CWInterface interfaceWithName:nil];
+ interfaceName = nsstringToQString([currentInterface name]);
+ } else {
+ currentInterface = [CWInterface interfaceWithName:qstringToNSString(interfaceName)];
+ }
+ mutex.unlock();
+
+ if([currentInterface power]) {
+ NSError *err = nil;
+ NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:YES], kCWScanKeyMerge,
+ [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil];
+
+ NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
+ CWNetwork *apNetwork;
+
+ if (!err) {
+ for(uint row=0; row < [apArray count]; row++ ) {
+ apNetwork = [apArray objectAtIndex:row];
+
+ const QString networkSsid = nsstringToQString([apNetwork ssid]);
+ found.append(networkSsid);
+
+ QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+
+ bool known = isKnownSsid(networkSsid);
+ if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if( networkSsid == nsstringToQString( [currentInterface ssid])) {
+ state = QNetworkConfiguration::Active;
+ }
+ }
+ if(state == QNetworkConfiguration::Undefined) {
+ if(known) {
+ state = QNetworkConfiguration::Discovered;
+ } else {
+ state = QNetworkConfiguration::Undefined;
+ }
+ }
+
+ QNetworkConfiguration::Purpose purpose = QNetworkConfiguration::UnknownPurpose;
+ if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) {
+ purpose = QNetworkConfiguration::PublicPurpose;
+ } else {
+ purpose = QNetworkConfiguration::PrivatePurpose;
+ }
+
+ found.append(foundNetwork(networkSsid, networkSsid, state, interfaceName, purpose));
+
+ } //end row
+ }//end error
+ }// endwifi power
+
+// add known configurations that are not around.
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+
+ QString networkName = i.key();
+ const QString id = networkName;
+
+ if(!found.contains(id)) {
+ QString networkSsid = getSsidFromNetworkName(networkName);
+ const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
+ QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+ QString interfaceName;
+ QMapIterator<QString, QString> ij(i.value());
+ while (ij.hasNext()) {
+ ij.next();
+ interfaceName = ij.value();
+ }
+
+ if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if( networkSsid == nsstringToQString([currentInterface ssid])) {
+ state = QNetworkConfiguration::Active;
+ }
+ }
+ if(state == QNetworkConfiguration::Undefined) {
+ if( userProfiles.contains(networkName)
+ && found.contains(ssidId)) {
+ state = QNetworkConfiguration::Discovered;
+ }
+ }
+
+ if(state == QNetworkConfiguration::Undefined) {
+ state = QNetworkConfiguration::Defined;
+ }
+
+ found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose));
+ }
+ }
+ emit networksChanged();
+ [pool release];
+#endif
+}
+
+QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
+{
+ QStringList found;
+ QMutexLocker locker(&mutex);
+ QNetworkConfigurationPrivate *ptr = new QNetworkConfigurationPrivate;
+
+ ptr->name = name;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->state = state;
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ ptr->bearer = QLatin1String("WLAN");
+ ptr->purpose = purpose;
+ ptr->internet = true;
+ ptr->serviceInterface = QNetworkInterface::interfaceFromName(interfaceName);
+
+ fetchedConfigurations.append( ptr);
+ configurationInterface[name] = interfaceName;
+
+ locker.unlock();
+ locker.relock();
+ found.append(id);
+ return found;
+}
+
+QList<QNetworkConfigurationPrivate *> QScanThread::getConfigurations()
+{
+ QMutexLocker locker(&mutex);
+
+ QList<QNetworkConfigurationPrivate *> foundConfigurations;
+
+ for (int i = 0; i < fetchedConfigurations.count(); ++i) {
+ QNetworkConfigurationPrivate *config = new QNetworkConfigurationPrivate;
+ config->name = fetchedConfigurations.at(i)->name;
+ config->isValid = fetchedConfigurations.at(i)->isValid;
+ config->id = fetchedConfigurations.at(i)->id;
+ config->state = fetchedConfigurations.at(i)->state;
+
+ config->type = fetchedConfigurations.at(i)->type;
+ config->roamingSupported = fetchedConfigurations.at(i)->roamingSupported;
+ config->purpose = fetchedConfigurations.at(i)->purpose;
+ config->internet = fetchedConfigurations.at(i)->internet;
+ foundConfigurations.append(config);
+ }
+
+ return foundConfigurations;
+}
+
+void QScanThread::getUserProfiles()
+{
+#if defined(MAC_SDK_10_6)
+ QMutexLocker locker(&mutex);
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ userProfiles.clear();
+
+ NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
+ for(uint row=0; row < [wifiInterfaces count]; row++ ) {
+
+ CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
+ NSString *nsInterfaceName = [wifiInterface name];
+// add user configured system networks
+ SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil);
+ NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]);
+ CFRelease(dynRef);
+
+ NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
+
+ NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
+ NSEnumerator *ssidEnumerator = [thisSsidarray objectEnumerator];
+ NSString *ssidkey;
+ while ((ssidkey = [ssidEnumerator nextObject])) {
+ QString thisSsid = nsstringToQString(ssidkey);
+ if(!userProfiles.contains(thisSsid)) {
+ QMap <QString,QString> map;
+ map.insert(thisSsid, nsstringToQString(nsInterfaceName));
+ userProfiles.insert(thisSsid, map);
+ }
+ }
+ CFRelease(airportPlist);
+
+ // 802.1X user profiles
+ QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
+ NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile:qstringToNSString(userProfilePath)] autorelease];
+ NSString *profileStr= @"Profiles";
+ NSString *nameStr = @"UserDefinedName";
+ NSString *networkSsidStr = @"Wireless Network";
+
+ id profileKey;
+ NSEnumerator *dictEnumerator = [eapDict objectEnumerator];
+ while ((profileKey = [dictEnumerator nextObject])) {
+
+ if ([profileStr isEqualToString:profileKey]) {
+ NSDictionary *itemDict = [eapDict objectForKey:profileKey];
+ id itemKey;
+ NSEnumerator *dictEnumerator = [thisSsidarray objectEnumerator];
+ while ((itemKey = [dictEnumerator nextObject])) {
+
+ NSInteger dictSize = [itemKey count];
+ id objects[dictSize];
+ id keys[dictSize];
+
+ [itemKey getObjects:objects andKeys:keys];
+ QString networkName;
+ QString ssid;
+ for(int i = 0; i < dictSize; i++) {
+ if([nameStr isEqualToString:keys[i]]) {
+ networkName = nsstringToQString(objects[i]);
+ }
+ if([networkSsidStr isEqualToString:keys[i]]) {
+ ssid = nsstringToQString(objects[i]);
+ }
+ if(!userProfiles.contains(networkName)
+ && !ssid.isEmpty()) {
+ QMap<QString,QString> map;
+ map.insert(ssid, nsstringToQString(nsInterfaceName));
+ userProfiles.insert(networkName, map);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ [pool release];
+#endif
+}
+
+QString QScanThread::getSsidFromNetworkName(const QString &name)
+{
+ QMutexLocker locker(&mutex);
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QMap<QString,QString> map = i.value();
+ QMapIterator<QString, QString> ij(i.value());
+ while (ij.hasNext()) {
+ ij.next();
+ const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key()));
+ if(name == i.key() || name == networkNameHash) {
+ return ij.key();
+ }
+ }
+ }
+ return QString();
+}
+
+QString QScanThread::getNetworkNameFromSsid(const QString &ssid)
+{
+ QMutexLocker locker(&mutex);
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QMap<QString,QString> map = i.value();
+ QMapIterator<QString, QString> ij(i.value());
+ while (ij.hasNext()) {
+ ij.next();
+ if(ij.key() == ssid) {
+ return i.key();
+ }
+ }
+ }
+ return QString();
+}
+
+bool QScanThread::isKnownSsid(const QString &ssid)
+{
+ QMutexLocker locker(&mutex);
+
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QMap<QString,QString> map = i.value();
+ if(map.keys().contains(ssid)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
QCoreWlanEngine::QCoreWlanEngine(QObject *parent)
: QNetworkSessionEngine(parent)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
getAllScInterfaces();
- startNetworkChangeLoop();
-#ifdef MAC_SDK_10_6
- if([[CWInterface supportedInterfaces] count] > 0 ) {
- QNSListener *listener;
- listener = [[QNSListener alloc] init];
- hasWifi = true;
- } else {
- hasWifi = false;
- }
-#endif
- getUserConfigurations();
- requestUpdate();
+ scanThread = new QScanThread(this);
+ connect(scanThread, SIGNAL(networksChanged()),
+ this, SIGNAL(configurationsChanged()));
+
+ QTimer::singleShot(0,this,SLOT(init()));
[pool release];
}
@@ -191,82 +480,65 @@
}
}
+void QCoreWlanEngine::init()
+{
+#ifdef MAC_SDK_10_6
+ if([[CWInterface supportedInterfaces] count] > 0 && !listener) {
+ listener = [[QNSListener alloc] init];
+ hasWifi = true;
+ } else {
+ hasWifi = false;
+ }
+#endif
+ storeSession = NULL;
+ scanThread->start();
+
+ startNetworkChangeLoop();
+}
+
+
QList<QNetworkConfigurationPrivate *> QCoreWlanEngine::getConfigurations(bool *ok)
{
if (ok)
*ok = true;
foundConfigurations.clear();
- uint identifier;
- QMapIterator<QString, QString> i(networkInterfaces);
QNetworkConfigurationPrivate* cpPriv = 0;
- while (i.hasNext()) {
- i.next();
- if (i.value() == "WLAN") {
- QList<QNetworkConfigurationPrivate *> fetchedConfigurations = scanForSsids(i.key());
- for (int i = 0; i < fetchedConfigurations.count(); ++i) {
-
- QNetworkConfigurationPrivate *config = new QNetworkConfigurationPrivate();
- cpPriv = fetchedConfigurations.at(i);
- config->name = cpPriv->name;
- config->isValid = cpPriv->isValid;
- config->id = cpPriv->id;
+ QMutexLocker locker(&mutex);
+ QList<QNetworkConfigurationPrivate *> fetchedConfigurations = scanThread->getConfigurations();
+locker.unlock();
- config->state = cpPriv->state;
- config->type = cpPriv->type;
- config->roamingSupported = cpPriv->roamingSupported;
- config->purpose = cpPriv->purpose;
- config->internet = cpPriv->internet;
- config->serviceInterface = cpPriv->serviceInterface;
- config->bearer = cpPriv->bearer;
-
- identifier = config->name.toUInt();
- configurationInterface[identifier] = config->serviceInterface.name();
- foundConfigurations.append(config);
- delete cpPriv;
- }
- }
+ for (int i = 0; i < fetchedConfigurations.count(); ++i) {
- QNetworkInterface interface = QNetworkInterface::interfaceFromName(i.key());
- QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate();
- const QString humanReadableName = interface.humanReadableName();
- cpPriv->name = humanReadableName.isEmpty() ? interface.name() : humanReadableName;
- cpPriv->isValid = true;
-
- if (interface.index())
- identifier = interface.index();
- else
- identifier = qHash(interface.hardwareAddress());
-
- cpPriv->id = QString::number(identifier);
- cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
- cpPriv->state = QNetworkConfiguration::Undefined;
+ QNetworkConfigurationPrivate *config = new QNetworkConfigurationPrivate();
+ cpPriv = fetchedConfigurations.at(i);
+ config->name = cpPriv->name;
+ config->isValid = cpPriv->isValid;
+ config->id = cpPriv->id;
+ config->state = cpPriv->state;
+ config->type = cpPriv->type;
+ config->roamingSupported = cpPriv->roamingSupported;
+ config->purpose = cpPriv->purpose;
+ config->internet = cpPriv->internet;
+ config->serviceInterface = cpPriv->serviceInterface;
+ config->bearer = cpPriv->bearer;
- if (interface.flags() & QNetworkInterface::IsRunning) {
- cpPriv->state = QNetworkConfiguration::Defined;
- cpPriv->internet = true;
- }
- if ( !interface.addressEntries().isEmpty()) {
- cpPriv->state |= QNetworkConfiguration::Active;
- cpPriv->internet = true;
- }
- configurationInterface[identifier] = interface.name();
- cpPriv->bearer = interface.name().isEmpty()? QLatin1String("Unknown") : qGetInterfaceType(interface.name());
- foundConfigurations.append(cpPriv);
- }
+ foundConfigurations.append(config);
+ delete cpPriv;
+ }
- pollTimer.start();
- return foundConfigurations;
+
+ return foundConfigurations;
}
QString QCoreWlanEngine::getInterfaceFromId(const QString &id)
{
- return configurationInterface.value(id.toUInt());
+ return scanThread->configurationInterface.value(id);
}
bool QCoreWlanEngine::hasIdentifier(const QString &id)
{
- return configurationInterface.contains(id.toUInt());
+ return scanThread->configurationInterface.contains(id);
}
void QCoreWlanEngine::connectToId(const QString &id)
@@ -285,13 +557,13 @@
QString wantedSsid = 0;
bool using8021X = false;
- if(getNetworkNameFromSsid(id) != id) {
+ if(scanThread->getNetworkNameFromSsid(id) != id) {
NSArray *array = [CW8021XProfile allUser8021XProfiles];
for (NSUInteger i=0; i<[array count]; ++i) {
if(id == nsstringToQString([[array objectAtIndex:i] userDefinedName])
|| id == nsstringToQString([[array objectAtIndex:i] ssid]) ) {
- QString thisName = getSsidFromNetworkName(id);
+ QString thisName = scanThread->getSsidFromNetworkName(id);
if(thisName.isEmpty()) {
wantedSsid = id;
} else {
@@ -306,12 +578,12 @@
if(!using8021X) {
QString wantedNetwork;
- QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ QMapIterator<QString, QMap<QString,QString> > i(scanThread->userProfiles);
while (i.hasNext()) {
i.next();
wantedNetwork = i.key();
if(id == wantedNetwork) {
- wantedSsid = getSsidFromNetworkName(wantedNetwork);
+ wantedSsid = scanThread->getSsidFromNetworkName(wantedNetwork);
break;
}
}
@@ -319,12 +591,12 @@
NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCWScanKeyMerge,
+ [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
[NSNumber numberWithInteger:100], kCWScanKeyRestTime,
qstringToNSString(wantedSsid), kCWScanKeySSID,
nil];
-
- NSArray *scanArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]];
+ NSArray *scanArray = [wifiInterface scanForNetworksWithParameters:parametersDict error:&err];
if(!err) {
for(uint row=0; row < [scanArray count]; row++ ) {
CWNetwork *apNetwork = [scanArray objectAtIndex:row];
@@ -353,11 +625,13 @@
SecKeychainSearchRef searchRef;
OSErr result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef);
-
+Q_UNUSED(result);
NSString *password = @"";
SecKeychainItemRef searchItem;
+ OSStatus resultStatus;
+ resultStatus = SecKeychainSearchCopyNext(searchRef, &searchItem);
- if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) {
+ if (resultStatus == errSecSuccess) {
UInt32 realPasswordLength;
SecKeychainAttribute attributesW[8];
attributesW[0].tag = kSecAccountItemAttr;
@@ -380,7 +654,7 @@
CFRelease(searchItem);
SecKeychainItemFreeContent(&listW, realPassword);
} else {
- qDebug() << "SecKeychainSearchCopyNext error";
+ qDebug() << "SecKeychainSearchCopyNext error" << cfstringRefToQstring(SecCopyErrorMessageString(resultStatus, NULL));
}
[params setValue: password forKey: kCWAssocKeyPassphrase];
} // end using8021X
@@ -403,6 +677,7 @@
[autoreleasepool release];
} else {
+ qDebug() << "wifi power off";
// not wifi
}
#endif
@@ -433,8 +708,8 @@
void QCoreWlanEngine::requestUpdate()
{
getAllScInterfaces();
- getUserConfigurations();
- emit configurationsChanged();
+ scanThread->getUserProfiles();
+ scanThread->start();
}
QCoreWlanEngine *QCoreWlanEngine::instance()
@@ -442,148 +717,6 @@
return coreWlanEngine();
}
-QString QCoreWlanEngine::getSsidFromNetworkName(const QString &name)
-{
- QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
- while (i.hasNext()) {
- i.next();
- QMap<QString,QString> map = i.value();
- QMapIterator<QString, QString> ij(i.value());
- while (ij.hasNext()) {
- ij.next();
- if(name == i.key()) {
- return ij.key();
- }
- }
- }
- return QString();
-}
-
-QString QCoreWlanEngine::getNetworkNameFromSsid(const QString &ssid)
-{
- QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
- while (i.hasNext()) {
- i.next();
- QMap<QString,QString> map = i.value();
- QMapIterator<QString, QString> ij(i.value());
- while (ij.hasNext()) {
- ij.next();
- if(ij.key() == ssid) {
- return i.key();
- }
- }
- }
- return QString();
-}
-
-QList<QNetworkConfigurationPrivate *> QCoreWlanEngine::scanForSsids(const QString &interfaceName)
-{
- QList<QNetworkConfigurationPrivate *> foundConfigs;
- if(!hasWifi) {
- return foundConfigs;
- }
-#if defined(MAC_SDK_10_6)
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
- CWInterface *currentInterface = [CWInterface interfaceWithName:qstringToNSString(interfaceName)];
- QStringList addedConfigs;
-
- if([currentInterface power]) {
- NSError *err = nil;
- NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:YES], kCWScanKeyMerge,
- [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType, // get the networks in the scan cache
- [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil];
- NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
- CWNetwork *apNetwork;
- if(!err) {
- for(uint row=0; row < [apArray count]; row++ ) {
- apNetwork = [apArray objectAtIndex:row];
-
- QString networkSsid = nsstringToQString([apNetwork ssid]);
-
- QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
- cpPriv->name = networkSsid;
- cpPriv->isValid = true;
- cpPriv->id = networkSsid;
- cpPriv->internet = true;
- cpPriv->bearer = QLatin1String("WLAN");
- cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
- cpPriv->serviceInterface = QNetworkInterface::interfaceFromName(interfaceName);
- bool known = isKnownSsid(networkSsid);
- if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
- if( cpPriv->name == nsstringToQString( [currentInterface ssid])) {
- cpPriv->state |= QNetworkConfiguration::Active;
- }
- }
-
- if(!cpPriv->state) {
- if(known) {
- cpPriv->state = QNetworkConfiguration::Discovered;
- } else {
- cpPriv->state = QNetworkConfiguration::Undefined;
- }
- }
- if([[apNetwork securityMode ] intValue]== kCWSecurityModeOpen)
- cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
- else
- cpPriv->purpose = QNetworkConfiguration::PrivatePurpose;
-
- foundConfigs.append(cpPriv);
- addedConfigs << networkSsid;
-
- } //end scanned row
- }
- } //end power
-
-
- // add known configurations that are not around.
- QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
- while (i.hasNext()) {
- i.next();
- QString networkName = i.key();
-
- if(!addedConfigs.contains(networkName)) {
- QString interfaceName;
- QMapIterator<QString, QString> ij(i.value());
- while (ij.hasNext()) {
- ij.next();
- interfaceName = ij.value();
- }
-
- QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
- cpPriv->name = networkName;
- cpPriv->isValid = true;
- cpPriv->id = networkName;
- cpPriv->internet = true;
- cpPriv->bearer = QLatin1String("WLAN");
- cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
- cpPriv->serviceInterface = QNetworkInterface::interfaceFromName(interfaceName);
- QString ssid = getSsidFromNetworkName(networkName);
- if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
- if( ssid == nsstringToQString( [currentInterface ssid])) {
- cpPriv->state |= QNetworkConfiguration::Active;
- }
- }
-
- if( addedConfigs.contains(ssid)) {
- cpPriv->state |= QNetworkConfiguration::Discovered;
- }
-
- if(!cpPriv->state) {
- cpPriv->state = QNetworkConfiguration::Defined;
- }
-
- foundConfigs.append(cpPriv);
- }
- }
-
- [autoreleasepool drain];
-#else
- Q_UNUSED(interfaceName);
-#endif
- return foundConfigs;
-}
-
bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
{
#if defined(MAC_SDK_10_6)
@@ -598,23 +731,6 @@
return false;
}
-bool QCoreWlanEngine::isKnownSsid( const QString &ssid)
-{
-#if defined(MAC_SDK_10_6)
- QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
- while (i.hasNext()) {
- i.next();
- QMap<QString,QString> map = i.value();
- if(map.keys().contains(ssid)) {
- return true;
- }
- }
-#else
- Q_UNUSED(ssid);
-#endif
- return false;
-}
-
bool QCoreWlanEngine::getAllScInterfaces()
{
networkInterfaces.clear();
@@ -665,7 +781,7 @@
networkChangeCallback,
&dynStoreContext);
if (!storeSession ) {
- qWarning() << "could not open dynamic store: error:" << SCErrorString(SCError());
+ qDebug() << "could not open dynamic store: error:" << SCErrorString(SCError());
return;
}
@@ -689,7 +805,7 @@
CFRelease(storeKey);
if (!SCDynamicStoreSetNotificationKeys(storeSession , notificationKeys, patternsArray)) {
- qWarning() << "register notification error:"<< SCErrorString(SCError());
+ qDebug() << "register notification error:"<< SCErrorString(SCError());
CFRelease(storeSession );
CFRelease(notificationKeys);
CFRelease(patternsArray);
@@ -700,7 +816,7 @@
runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0);
if (!runloopSource) {
- qWarning() << "runloop source error:"<< SCErrorString(SCError());
+ qDebug() << "runloop source error:"<< SCErrorString(SCError());
CFRelease(storeSession );
return;
}
@@ -708,79 +824,6 @@
CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
return;
}
-
-void QCoreWlanEngine::getUserConfigurations()
-{
-#ifdef MAC_SDK_10_6
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
- userProfiles.clear();
-
- NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
- for(uint row=0; row < [wifiInterfaces count]; row++ ) {
-
- CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
- NSString *nsInterfaceName = [wifiInterface name];
-// add user configured system networks
- SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil);
- NSDictionary *airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName] autorelease]);
- CFRelease(dynRef);
-
- NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
-
- NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
- for(NSString *ssidkey in thisSsidarray) {
- QString thisSsid = nsstringToQString(ssidkey);
- if(!userProfiles.contains(thisSsid)) {
- QMap <QString,QString> map;
- map.insert(thisSsid, nsstringToQString(nsInterfaceName));
- userProfiles.insert(thisSsid, map);
- }
- }
- CFRelease(airportPlist);
-
- // 802.1X user profiles
- QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
- NSDictionary* eapDict = [[NSDictionary alloc] initWithContentsOfFile:qstringToNSString(userProfilePath)];
- NSString *profileStr= @"Profiles";
- NSString *nameStr = @"UserDefinedName";
- NSString *networkSsidStr = @"Wireless Network";
- for (id profileKey in eapDict) {
- if ([profileStr isEqualToString:profileKey]) {
- NSDictionary *itemDict = [eapDict objectForKey:profileKey];
- for (id itemKey in itemDict) {
-
- NSInteger dictSize = [itemKey count];
- id objects[dictSize];
- id keys[dictSize];
-
- [itemKey getObjects:objects andKeys:keys];
- QString networkName;
- QString ssid;
- for(int i = 0; i < dictSize; i++) {
- if([nameStr isEqualToString:keys[i]]) {
- networkName = nsstringToQString(objects[i]);
- }
- if([networkSsidStr isEqualToString:keys[i]]) {
- ssid = nsstringToQString(objects[i]);
- }
- if(!userProfiles.contains(networkName)
- && !ssid.isEmpty()) {
- QMap<QString,QString> map;
- map.insert(ssid, nsstringToQString(nsInterfaceName));
- userProfiles.insert(networkName, map);
- }
- }
- }
- [itemDict release];
- }
- }
- [eapDict release];
- }
- [autoreleasepool release];
-#endif
-
-}
-
#include "moc_qcorewlanengine_mac_p.cpp"
QTM_END_NAMESPACE
--- a/qtmobility/src/bearer/qcorewlanengine_mac_p.h Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qcorewlanengine_mac_p.h Wed Jun 09 10:36:00 2010 +0300
@@ -54,17 +54,23 @@
//
#include "qnetworksessionengine_p.h"
+#include "qnetworkconfiguration.h"
+
#include <QMap>
#include <QTimer>
#include <SystemConfiguration/SystemConfiguration.h>
+#include <QThread>
+#include <QMutex>
QTM_BEGIN_NAMESPACE
class QNetworkConfigurationPrivate;
+class QScanThread;
class QCoreWlanEngine : public QNetworkSessionEngine
{
Q_OBJECT
+ friend class QScanThread;
public:
QCoreWlanEngine(QObject *parent = 0);
@@ -82,30 +88,62 @@
void requestUpdate();
static QCoreWlanEngine *instance();
- static bool getAllScInterfaces();
+ QString interfaceName;
private:
bool isWifiReady(const QString &dev);
- QMap<uint, QString> configurationInterface;
QTimer pollTimer;
- QList<QNetworkConfigurationPrivate *> scanForSsids(const QString &interfaceName);
-
- bool isKnownSsid(const QString &ssid);
QList<QNetworkConfigurationPrivate *> foundConfigurations;
SCDynamicStoreRef storeSession;
CFRunLoopSourceRef runloopSource;
bool hasWifi;
+ QScanThread *scanThread;
+ QMutex mutex;
+ static bool getAllScInterfaces();
+
+private Q_SLOTS:
+ void init();
protected:
- QMap<QString, QMap<QString,QString> > userProfiles;
+ void startNetworkChangeLoop();
+};
+
+class QScanThread : public QThread
+{
+ Q_OBJECT
- void startNetworkChangeLoop();
- void getUserConfigurations();
+public:
+ QScanThread(QObject *parent = 0);
+ ~QScanThread();
+
+ void quit();
+ QList<QNetworkConfigurationPrivate *> getConfigurations();
+ QString interfaceName;
+ QMap<QString, QString> configurationInterface;
+ void getUserProfiles();
QString getNetworkNameFromSsid(const QString &ssid);
QString getSsidFromNetworkName(const QString &name);
+ bool isKnownSsid(const QString &ssid);
+ QMap<QString, QMap<QString,QString> > userProfiles;
+
+signals:
+ void networksChanged();
+
+protected:
+ void run();
+
+private:
+ QList<QNetworkConfigurationPrivate *> fetchedConfigurations;
+ QMutex mutex;
+ QStringList foundNetwork(const QString &id, const QString &ssid,
+ const QNetworkConfiguration::StateFlags state,
+ const QString &interfaceName,
+ const QNetworkConfiguration::Purpose purpose);
+
};
+
QTM_END_NAMESPACE
#endif
--- a/qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp Wed Jun 09 10:36:00 2010 +0300
@@ -44,14 +44,13 @@
#include <commdb.h>
#include <cdbcols.h>
#include <d32dbms.h>
-#include <QEventLoop>
+#include <nifvar.h>
#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
@@ -70,19 +69,20 @@
QTM_BEGIN_NAMESPACE
-static const int KValueThatWillBeAddedToSNAPId = 1000;
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ static const int KValueThatWillBeAddedToSNAPId = 1000;
+#endif
static const int KUserChoiceIAPId = 0;
QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
: QObject(0), CActive(CActive::EPriorityIdle), capFlags(0),
- iFirstUpdate(true), iInitOk(true), iIgnoringUpdates(false),
- iTimeToWait(0), iIgnoreEventLoop(0)
+ iFirstUpdate(true), iInitOk(true), iUpdatePending(false),
+ iTimeToWait(0)
{
CActiveScheduler::Add(this);
// Seed the randomgenerator
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid());
- iIgnoreEventLoop = new QEventLoop(this);
registerPlatformCapabilities();
TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP));
@@ -165,6 +165,25 @@
delete cleanup;
}
+void QNetworkConfigurationManagerPrivate::delayedConfigurationUpdate()
+{
+ 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);
+ }
+ }
+}
void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities()
{
@@ -229,7 +248,11 @@
if (!iFirstUpdate) {
QNetworkConfiguration item;
item.d = ptr;
- emit configurationAdded(item);
+ // 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(item));
}
}
}
@@ -250,10 +273,9 @@
knownSnapConfigs.removeOne(ident);
} else {
QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
- 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;
@@ -272,10 +294,8 @@
if (!iFirstUpdate) {
QNetworkConfiguration item;
item.d = ptr;
- emit configurationAdded(item);
+ QT_TRYCATCH_LEAVING(emit configurationAdded(item));
}
-
- CleanupStack::Pop(cpPriv);
}
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> privSNAP = snapConfigurations.value(ident);
@@ -297,7 +317,7 @@
if (!iFirstUpdate) {
QNetworkConfiguration item;
item.d = ptr;
- emit configurationAdded(item);
+ QT_TRYCATCH_LEAVING(emit configurationAdded(item));
}
privSNAP->serviceNetworkMembers.append(ptr);
}
@@ -349,7 +369,7 @@
if (!iFirstUpdate) {
QNetworkConfiguration item;
item.d = ptr;
- emit configurationAdded(item);
+ QT_TRYCATCH_LEAVING(emit configurationAdded(item));
}
} else {
delete cpPriv;
@@ -359,7 +379,7 @@
}
CleanupStack::PopAndDestroy(pDbTView);
#endif
- updateActiveAccessPoints();
+ QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
foreach (const QString &oldIface, knownConfigs) {
//remove non existing IAP
@@ -368,7 +388,7 @@
if (!iFirstUpdate) {
QNetworkConfiguration item;
item.d = priv;
- emit configurationRemoved(item);
+ QT_TRYCATCH_LEAVING(emit configurationRemoved(item));
}
// Remove non existing IAP from SNAPs
foreach (const QString &iface, snapConfigurations.keys()) {
@@ -389,7 +409,7 @@
if (!iFirstUpdate) {
QNetworkConfiguration item;
item.d = priv;
- emit configurationRemoved(item);
+ QT_TRYCATCH_LEAVING(emit configurationRemoved(item));
}
}
}
@@ -399,14 +419,12 @@
RCmConnectionMethod& connectionMethod)
{
QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
- CleanupStack::PushL(cpPriv);
-
TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
QString ident = 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;
@@ -454,7 +472,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;
}
@@ -473,8 +491,6 @@
cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
cpPriv->roamingSupported = false;
cpPriv->manager = this;
-
- CleanupStack::Pop(cpPriv);
return cpPriv;
}
#else
@@ -507,7 +523,7 @@
QString ident = 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;
@@ -607,10 +623,14 @@
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);
@@ -619,11 +639,15 @@
QString ident = QString::number(qHash(apId));
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
if (priv.data()) {
- online = true;
- inactiveConfigs.removeOne(ident);
- priv.data()->connectionId = connectionId;
- // Configuration is Active
- changeConfigurationStateTo(priv, QNetworkConfiguration::Active);
+ iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
+ User::WaitForRequest(status);
+ if (connectionStatus == KLinkLayerOpen) {
+ online = true;
+ inactiveConfigs.removeOne(ident);
+ priv.data()->connectionId = connectionId;
+ // Configuration is Active
+ changeConfigurationStateTo(priv, QNetworkConfiguration::Active);
+ }
}
}
}
@@ -674,12 +698,12 @@
}
}
- // 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) {
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
if (priv.data()) {
// Configuration is Defined
- changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined);
+ changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered);
}
}
}
@@ -807,47 +831,26 @@
void QNetworkConfigurationManagerPrivate::RunL()
{
- if (iIgnoringUpdates) {
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
+ if (iStatus != KErrCancel) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
#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::ERecover: /** The database has been recovered */
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("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;
+ break;
default:
// Do nothing
break;
@@ -867,64 +870,91 @@
ipCommsDB->CancelRequestNotification();
}
-
void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent)
{
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));
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
- if (priv.data()) {
- priv.data()->connectionId = connectionId;
- // Configuration is Active
- if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) {
- updateStatesToSnaps();
+ 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));
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+ if (priv.data()) {
+ priv.data()->connectionId = connectionId;
+ QT_TRYCATCH_LEAVING(emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connecting));
}
- if (!iOnline) {
- iOnline = true;
- emit this->onlineStateChanged(iOnline);
+ } 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));
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+ if (priv.data()) {
+ priv.data()->connectionId = connectionId;
+ // Configuration is Active
+ QT_TRYCATCH_LEAVING(
+ if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) {
+ updateStatesToSnaps();
+ }
+ emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connected);
+ if (!iOnline) {
+ iOnline = true;
+ emit this->onlineStateChanged(iOnline);
+ }
+ );
+ }
+ } else if (connectionStatus == KConfigDaemonStartingDeregistration) {
+ TUint connectionId = realEvent->ConnectionId();
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
+ if (priv.data()) {
+ QT_TRYCATCH_LEAVING(emit this->configurationStateChanged(priv.data()->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();
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
+ if (priv.data()) {
+ // Configuration is either Defined or Discovered
+ QT_TRYCATCH_LEAVING(
+ if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
+ emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Disconnected);
+ );
+ }
+
+ bool online = false;
+ foreach (const QString &iface, accessPointConfigurations.keys()) {
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
+ if (priv.data()->state == QNetworkConfiguration::Active) {
+ online = true;
+ break;
+ }
+ }
+ if (iOnline != online) {
+ iOnline = online;
+ QT_TRYCATCH_LEAVING(emit this->onlineStateChanged(iOnline));
}
}
}
- break;
-
- case EConnMonDeleteConnection:
- {
- CConnMonDeleteConnection* realEvent;
- realEvent = (CConnMonDeleteConnection*) &aEvent;
- TUint connectionId = realEvent->ConnectionId();
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
- if (priv.data()) {
- priv.data()->connectionId = 0;
- // Configuration is either Defined or Discovered
- if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
- updateStatesToSnaps();
- }
- }
-
- bool online = false;
- foreach (const QString &iface, accessPointConfigurations.keys()) {
- QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
- if (priv.data()->state == QNetworkConfiguration::Active) {
- online = true;
- break;
- }
- }
- if (iOnline != online) {
- iOnline = online;
- emit this->onlineStateChanged(iOnline);
- }
- }
- break;
+ break;
case EConnMonIapAvailabilityChange:
{
@@ -937,7 +967,7 @@
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
if (priv.data()) {
// Configuration is either Discovered or Active
- changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered);
+ QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered));
unDiscoveredConfigs.removeOne(ident);
}
}
@@ -945,36 +975,87 @@
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
if (priv.data()) {
// Configuration is Defined
- changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined);
+ QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined));
}
}
}
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));
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+ if (priv.data()) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << priv.data()->connectionId << connectionId << priv->name;
+#endif
+ priv.data()->connectionId = connectionId;
+ }
+ }
+ break;
default:
// For unrecognized events
break;
}
}
-// Waits for 1..4 seconds.
-void QNetworkConfigurationManagerPrivate::waitRandomTime()
+// 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 QNetworkConfigurationManagerPrivate::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState)
{
- iTimeToWait = (qAbs(qrand()) % 5) * 1000;
+#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));
+ QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
+ if (priv.data()) {
+ // Configuration is either Defined or Discovered
+ if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
+ emit this->configurationStateChanged(
+ priv.data()->numericId, priv.data()->connectionId, QNetworkSession::Disconnected);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+// Waits for 2..6 seconds.
+void QNetworkConfigurationManagerPrivate::updateConfigurationsAfterRandomTime()
+{
+ iTimeToWait = (qAbs(qrand()) % 68) * 100;
if (iTimeToWait < 1000) {
iTimeToWait = 1000;
}
-#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();
+ QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate()));
}
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId)
{
QNetworkConfiguration item;
-
QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
accessPointConfigurations.constBegin();
while (i != accessPointConfigurations.constEnd()) {
@@ -990,7 +1071,7 @@
AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(QNetworkConfigurationManagerPrivate& owner,
RConnectionMonitor& connectionMonitor)
- : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor)
+ : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor)
{
CActiveScheduler::Add(this);
}
@@ -1028,9 +1109,9 @@
{
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()));
}
}
#include "moc_qnetworkconfigmanager_s60_p.cpp"
--- a/qtmobility/src/bearer/qnetworkconfigmanager_s60_p.h Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qnetworkconfigmanager_s60_p.h Wed Jun 09 10:36:00 2010 +0300
@@ -55,6 +55,7 @@
#include <qnetworkconfigmanager.h>
#include <qnetworkconfiguration_s60_p.h>
+#include <qnetworksession.h>
#include <QHash>
#include <rconnmon.h>
@@ -62,6 +63,9 @@
#include <cmmanager.h>
#endif
+// Uncomment and compile QtBearer to gain detailed state tracing
+// #define QT_BEARERMGMT_SYMBIAN_DEBUG
+
class CCommsDatabase;
class QEventLoop;
@@ -92,8 +96,12 @@
void configurationChanged(const QNetworkConfiguration& config);
void onlineStateChanged(bool isOnline);
+ void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId,
+ QNetworkSession::State newState);
+
public Q_SLOTS:
void updateConfigurations();
+ void delayedConfigurationUpdate();
private:
void registerPlatformCapabilities();
@@ -119,19 +127,24 @@
void accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo);
void startCommsDatabaseNotifications();
void stopCommsDatabaseNotifications();
- void waitRandomTime();
+ void updateConfigurationsAfterRandomTime();
QNetworkConfiguration defaultConfigurationL();
TBool GetS60PlatformVersion(TUint& aMajor, TUint& aMinor) const;
void startMonitoringIAPData(TUint32 aIapId);
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> 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);
public: // Data
//this table contains an up to date list of all configs at any time.
@@ -151,9 +164,8 @@
TBool iOnline;
TBool iInitOk;
TBool iUpdateGoingOn;
- TBool iIgnoringUpdates;
+ TBool iUpdatePending;
TUint iTimeToWait;
- QEventLoop* iIgnoreEventLoop;
AccessPointsAvailabilityScanner* ipAccessPointsAvailabilityScanner;
--- a/qtmobility/src/bearer/qnetworkconfiguration_s60_p.h Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qnetworkconfiguration_s60_p.h Wed Jun 09 10:36:00 2010 +0300
@@ -88,7 +88,18 @@
QNetworkConfigurationPrivate::Bearer bearer;
QString bearerName() const;
+ // 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;
TAny* manager;
--- a/qtmobility/src/bearer/qnetworksession_s60_p.cpp Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qnetworksession_s60_p.cpp Wed Jun 09 10:36:00 2010 +0300
@@ -52,15 +52,17 @@
QTM_BEGIN_NAMESPACE
QNetworkSessionPrivate::QNetworkSessionPrivate()
- : CActive(CActive::EPriorityStandard), state(QNetworkSession::Invalid),
- isOpen(false), ipConnectionNotifier(0), iError(QNetworkSession::UnknownSessionError),
- iALREnabled(0), iConnectInBackground(false)
+ : CActive(CActive::EPriorityUserInput), state(QNetworkSession::Invalid),
+ isOpen(false), 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());
}
@@ -89,9 +91,43 @@
// Close global 'Open C' RConnection
setdefaultif(0);
+
+ iConnectionMonitor.Close();
+}
- iConnectionMonitor.CancelNotifications();
- iConnectionMonitor.Close();
+void QNetworkSessionPrivate::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 QNetworkSessionPrivate::configurationRemoved(const QNetworkConfiguration& config)
+{
+ if (!publicConfig.d.data()) {
+ return;
+ }
+ if (config.d.data()->numericId == publicConfig.d.data()->numericId) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "configurationRemoved IAP: " << QString::number(publicConfig.d.data()->numericId) << " : going to State: Invalid";
+#endif
+ this->newState(QNetworkSession::Invalid, publicConfig.d.data()->numericId);
+ }
}
void QNetworkSessionPrivate::syncStateWithInterface()
@@ -100,8 +136,17 @@
return;
}
- // Start monitoring changes in IAP states
- TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+ if (iFirstSync && publicConfig.d.data()) {
+ QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), 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(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager),
+ SIGNAL(configurationRemoved(QNetworkConfiguration)),
+ this, SLOT(configurationRemoved(QNetworkConfiguration)));
+ }
+ // 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 +182,7 @@
}
if (state != QNetworkSession::Connected) {
- // There were no open connections to used IAP or SNAP
- if (iError == QNetworkSession::InvalidConfigurationError) {
- newState(QNetworkSession::Invalid);
- }
- else if ((publicConfig.d.data()->state & QNetworkConfiguration::Discovered) ==
+ if ((publicConfig.d.data()->state & QNetworkConfiguration::Discovered) ==
QNetworkConfiguration::Discovered) {
newState(QNetworkSession::Disconnected);
} else {
@@ -242,13 +283,18 @@
void QNetworkSessionPrivate::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).
@@ -256,19 +302,25 @@
newState(QNetworkSession::Invalid);
iError = QNetworkSession::InvalidConfigurationError;
emit q->error(iError);
- syncStateWithInterface();
return;
}
- // If opening a (un)defined configuration, session emits error and enters
- // NotAvailable -state.
- if (publicConfig.state() == QNetworkConfiguration::Undefined ||
- publicConfig.state() == QNetworkConfiguration::Defined) {
+ // 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 q->error(iError);
return;
}
-
+ // Clear possible previous states
+ iStoppedByUser = false;
+ iClosedByUser = false;
+ iDeprecatedConnectionId = 0;
+
TInt error = iSocketServ.Connect();
if (error != KErrNone) {
// Could not open RSocketServ
@@ -420,11 +472,19 @@
void QNetworkSessionPrivate::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;
- TUint activeIap = activeConfig.d.data()->numericId;
isOpen = false;
activeConfig = QNetworkConfiguration();
serviceConfig = QNetworkConfiguration();
@@ -437,8 +497,10 @@
}
#endif
- if (ipConnectionNotifier) {
+ if (ipConnectionNotifier && !iHandleStateNotificationsFromManager) {
ipConnectionNotifier->StopNotifications();
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
}
iConnection.Close();
@@ -447,29 +509,31 @@
// Close global 'Open C' RConnection
setdefaultif(0);
-#ifdef Q_CC_NOKIAX86
- if ((allowSignals && iapClientCount(activeIap) <= 0) ||
-#else
- if ((allowSignals && iapClientCount(activeIap) <= 1) ||
-#endif
- (publicConfig.type() == QNetworkConfiguration::UserChoice)) {
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
newState(QNetworkSession::Closing);
+ newState(QNetworkSession::Disconnected);
}
- syncStateWithInterface();
if (allowSignals) {
- if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
- newState(QNetworkSession::Disconnected);
- }
emit q->closed();
}
}
void QNetworkSessionPrivate::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,
@@ -483,7 +547,7 @@
}
TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
TUint connectionId;
- for (TInt i = 1; i <= count; ++i) {
+ for (TUint i = 1; i <= count; ++i) {
// Get (connection monitor's assigned) connection ID
TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);
if (ret == KErrNone) {
@@ -495,11 +559,25 @@
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);
@@ -592,7 +670,15 @@
QList<QNetworkConfiguration> configs = publicConfig.children();
for (int i=0; i < configs.count(); i++) {
if (configs[i].d.data()->numericId == aNewAPInfo.AccessPoint()) {
- emit q->preferredConfigurationChanged(configs[i],aIsSeamless);
+ // Any slot connected to the signal might throw an std::exception,
+ // which must not propagate into Symbian code (this function is a callback
+ // from platform). We could convert exception to a symbian Leave, but since the
+ // prototype of this function bans this (no trailing 'L'), we just catch
+ // and drop.
+ QT_TRY {
+ emit q->preferredConfigurationChanged(configs[i],aIsSeamless);
+ }
+ QT_CATCH (std::exception&) {}
}
}
} else {
@@ -603,7 +689,10 @@
void QNetworkSessionPrivate::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/)
{
if (iALREnabled > 0) {
- emit q->newConfigurationActivated();
+ QT_TRY {
+ emit q->newConfigurationActivated();
+ }
+ QT_CATCH (std::exception&) {}
} else {
accept();
}
@@ -611,6 +700,10 @@
void QNetworkSessionPrivate::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();
@@ -621,13 +714,24 @@
if (ipConnectionNotifier) {
ipConnectionNotifier->StopNotifications();
}
- syncStateWithInterface();
- // In some cases IAP is still in Connected state when
- // syncStateWithInterface(); is called
- // => Following call makes sure that Session state
- // changes immediately to Disconnected.
- newState(QNetworkSession::Disconnected);
- emit q->closed();
+ QT_TRY {
+ syncStateWithInterface();
+ // In some cases IAP is still in Connected state when
+ // syncStateWithInterface(); is called
+ // => Following call makes sure that Session state
+ // changes immediately to Disconnected.
+ newState(QNetworkSession::Disconnected);
+ emit q->closed();
+ }
+ QT_CATCH (std::exception&) {}
+ } 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.
+ QT_TRY {
+ newState(QNetworkSession::Disconnected);
+ }
+ QT_CATCH (std::exception&) {}
}
}
#endif
@@ -854,12 +958,12 @@
if (error != KErrNone) {
isOpen = false;
iError = QNetworkSession::UnknownSessionError;
- emit q->error(iError);
+ QT_TRYCATCH_LEAVING(emit q->error(iError));
Cancel();
if (ipConnectionNotifier) {
ipConnectionNotifier->StopNotifications();
}
- syncStateWithInterface();
+ QT_TRYCATCH_LEAVING(syncStateWithInterface());
return;
}
@@ -880,8 +984,10 @@
startTime = QDateTime::currentDateTime();
- newState(QNetworkSession::Connected);
- emit quitPendingWaitsForOpened();
+ QT_TRYCATCH_LEAVING({
+ newState(QNetworkSession::Connected);
+ emit quitPendingWaitsForOpened();
+ });
}
break;
case KErrNotFound: // Connection failed
@@ -889,12 +995,12 @@
activeConfig = QNetworkConfiguration();
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::InvalidConfigurationError;
- emit q->error(iError);
+ QT_TRYCATCH_LEAVING(emit q->error(iError));
Cancel();
if (ipConnectionNotifier) {
ipConnectionNotifier->StopNotifications();
}
- syncStateWithInterface();
+ QT_TRYCATCH_LEAVING(syncStateWithInterface());
break;
case KErrCancel: // Connection attempt cancelled
case KErrAlreadyExists: // Connection already exists
@@ -902,13 +1008,18 @@
isOpen = false;
activeConfig = QNetworkConfiguration();
serviceConfig = QNetworkConfiguration();
- iError = QNetworkSession::UnknownSessionError;
- emit q->error(iError);
+ if (publicConfig.state() == QNetworkConfiguration::Undefined ||
+ publicConfig.state() == QNetworkConfiguration::Defined) {
+ iError = QNetworkSession::InvalidConfigurationError;
+ } else {
+ iError = QNetworkSession::UnknownSessionError;
+ }
+ QT_TRYCATCH_LEAVING(emit q->error(iError));
Cancel();
if (ipConnectionNotifier) {
ipConnectionNotifier->StopNotifications();
}
- syncStateWithInterface();
+ QT_TRYCATCH_LEAVING(syncStateWithInterface());
break;
}
}
@@ -918,8 +1029,16 @@
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 QNetworkSessionPrivate::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 &&
@@ -937,9 +1056,29 @@
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
@@ -953,26 +1092,35 @@
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 q->stateChanged(state);
retVal = true;
} else {
if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
if (publicConfig.d.data()->numericId == accessPointId) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed B to: " << state;
+#endif
emit q->stateChanged(state);
retVal = true;
}
} else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) {
if (activeConfig.d.data()->numericId == accessPointId) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed C to: " << state;
+#endif
emit q->stateChanged(state);
retVal = true;
}
@@ -980,26 +1128,33 @@
QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
for (int i = 0; i < subConfigurations.count(); i++) {
if (subConfigurations[i].d.data()->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.
- subConfigurations[i].d.data()->state = QNetworkConfiguration::Active;
-
+ if (newState != QNetworkSession::Disconnected) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed D to: " << state;
+#endif
emit q->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.
- subConfigurations[i].d.data()->state = QNetworkConfiguration::Defined;
- }
QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
if ((config.state() == QNetworkConfiguration::Defined) ||
(config.state() == QNetworkConfiguration::Discovered)) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E to: " << state;
+#endif
emit q->stateChanged(state);
retVal = true;
+ } else if (config.state() == QNetworkConfiguration::Active) {
+ // Connection to used IAP was closed, but there is another
+ // IAP that's active in used SNAP
+ // => Change state back to Connected
+ state = QNetworkSession::Connected;
+ emit q->stateChanged(state);
+ retVal = true;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed F to: " << state;
+#endif
}
}
}
@@ -1010,6 +1165,13 @@
if (emitSessionClosed) {
emit q->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.
+ iDeprecatedConnectionId = publicConfig.d.data()->connectionId;
+ }
return retVal;
}
@@ -1018,6 +1180,9 @@
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
@@ -1056,6 +1221,7 @@
case KCsdGotLoginInfo:
break;
+ case KConfigDaemonStartingRegistration:
// Creating connection (e.g. GPRS activation)
case KCsdStartingConnect:
case KCsdFinishedConnect:
@@ -1082,6 +1248,7 @@
case KDataTransferTemporarilyBlocked:
break;
+ case KConfigDaemonStartingDeregistration:
// Hangup or GRPS deactivation
case KConnectionStartingClose:
newState(QNetworkSession::Closing,accessPointId);
@@ -1089,110 +1256,27 @@
// 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.d.data()) {
+ ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->configurationStateChangeReport(publicConfig.d.data()->numericId, QNetworkSession::Disconnected);
+ }
break;
-
// Unhandled state
default:
break;
}
}
-void QNetworkSessionPrivate::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++ ) {
- if (subConfigurations[i].d.data()->connectionId == connectionId) {
- apId = subConfigurations[i].d.data()->numericId;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (publicConfig.d.data()->connectionId == connectionId) {
- apId = publicConfig.d.data()->numericId;
- }
- }
-
- 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++ ) {
- if (subConfigurations[i].d.data()->numericId == apId) {
- subConfigurations[i].d.data()->connectionId = connectionId;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (publicConfig.d.data()->numericId == apId) {
- publicConfig.d.data()->connectionId = connectionId;
- }
- }
- }
- }
- 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++ ) {
- if (subConfigurations[i].d.data()->connectionId == connectionId) {
- subConfigurations[i].d.data()->connectionId = 0;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (publicConfig.d.data()->connectionId == connectionId) {
- publicConfig.d.data()->connectionId = 0;
- }
- }
- }
- break;
-
- default:
- // For unrecognized events
- break;
- }
-}
-
ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivate& owner, RConnection& connection)
- : CActive(CActive::EPriorityStandard), iOwner(owner), iConnection(connection)
+ : CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
{
CActiveScheduler::Add(this);
}
@@ -1223,7 +1307,7 @@
void ConnectionProgressNotifier::RunL()
{
if (iStatus == KErrNone) {
- iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError);
+ QT_TRYCATCH_LEAVING(iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError));
SetActive();
iConnection.ProgressNotification(iProgress, iStatus);
--- a/qtmobility/src/bearer/qnetworksession_s60_p.h Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/src/bearer/qnetworksession_s60_p.h Wed Jun 09 10:36:00 2010 +0300
@@ -72,11 +72,10 @@
class ConnectionProgressNotifier;
-class QNetworkSessionPrivate : public QObject, public CActive,
+class QNetworkSessionPrivate : public QObject, public CActive
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- public MMobilityProtocolResp,
+ , public MMobilityProtocolResp
#endif
- public MConnectionMonitorObserver
{
Q_OBJECT
public:
@@ -129,8 +128,9 @@
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(const QNetworkConfiguration& config);
private:
TUint iapClientCount(TUint aIAPId) const;
@@ -166,6 +166,13 @@
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
--- a/qtmobility/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp Wed Jun 09 10:36:00 2010 +0300
@@ -44,6 +44,13 @@
#include "../../../src/bearer/qnetworkconfiguration.h"
#include "../../../src/bearer/qnetworkconfigmanager.h"
+/*
+ Although this unit test doesn't use QNetworkAccessManager
+ this include is used to ensure that bearer continues to compile against
+ Qt 4.7+ which has a QNetworkConfiguration enabled QNetworkAccessManager
+*/
+#include <QNetworkAccessManager>
+
#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5)
#include <stdio.h>
#include <iapconf.h>
--- a/qtmobility/tests/auto/qnetworksession/lackey/main.cpp Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/tests/auto/qnetworksession/lackey/main.cpp Wed Jun 09 10:36:00 2010 +0300
@@ -46,6 +46,8 @@
#include "../../../../src/bearer/qnetworkconfiguration.h"
#include "../../../../src/bearer/qnetworksession.h"
+#include <QEventLoop>
+#include <QTimer>
#include <QDebug>
QTM_USE_NAMESPACE
@@ -59,7 +61,14 @@
{
QCoreApplication app(argc, argv);
+ // 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);
@@ -75,7 +84,6 @@
// Cannot read/write to processes on WinCE or Symbian.
// Easiest alternative is to use sockets for IPC.
-
QLocalSocket oopSocket;
oopSocket.connectToServer("tst_qnetworksession");
--- a/qtmobility/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.cpp Tue May 25 13:34:51 2010 +0300
+++ b/qtmobility/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.cpp Wed Jun 09 10:36:00 2010 +0300
@@ -1,5 +1,5 @@
/****************************************************************************
-**
+**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -96,6 +96,7 @@
private:
QNetworkConfigurationManager manager;
+ QMap<QString, bool> testsToRun;
uint inProcessSessionManagementCount;
@@ -113,6 +114,7 @@
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()
@@ -121,7 +123,19 @@
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");
@@ -234,6 +248,10 @@
// 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
@@ -241,15 +259,14 @@
testSession.accept();
testSession.ignore();
testSession.reject();
- quint64 temp;
- temp = testSession.bytesWritten();
- temp = testSession.bytesReceived();
- temp = testSession.activeTime();
}
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());
@@ -264,11 +281,24 @@
qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0));
QVERIFY(error == QNetworkSession::InvalidConfigurationError);
QVERIFY(session.state() == QNetworkSession::Invalid);
+
+#ifdef QNETWORKSESSION_MANUAL_TESTS
-#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);
@@ -277,43 +307,27 @@
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
}
@@ -331,12 +345,12 @@
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")
@@ -407,7 +421,12 @@
}
// 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);
@@ -423,13 +442,20 @@
!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
@@ -453,41 +479,11 @@
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
}
@@ -502,6 +498,9 @@
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
@@ -509,6 +508,9 @@
QFETCH(QNetworkConfiguration::Type, configurationType);
int configWaitdelayInMs = 2000;
+
+ updateConfigurations();
+ printConfigurations();
QNetworkConfiguration config = suitableConfiguration(bearerType, configurationType);
if (!config.isValid()) {
@@ -526,6 +528,9 @@
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)));
@@ -541,10 +546,18 @@
closedSessionClosedSpy.clear();
closedSessionStateChangedSpy.clear();
closedErrorSpy.clear();
+ openedSessionStateChangedSpy.clear();
+ openedSessionClosedSpy.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
+
+ // First to closing, then to disconnected
+ QVERIFY(openedSessionStateChangedSpy.count() == 2);
+ QVERIFY(!openedSessionClosedSpy.isEmpty());
QVERIFY(openedSession.state() == QNetworkSession::Disconnected);
- QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
QVERIFY(config.state() != QNetworkConfiguration::Active);
// 2. Verify that stopping a session based on non-connected configuration does nothing
@@ -570,18 +583,20 @@
// 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());
@@ -601,14 +616,19 @@
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());
@@ -640,6 +660,9 @@
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);
@@ -669,7 +692,20 @@
session.open();
+#if defined(Q_OS_SYMBIAN)
+ // Opening & closing multiple connections in a row sometimes
+ // results hanging of connection opening on Symbian devices
+ // => If first open fails, wait a moment and try again.
+ if (!session.waitForOpened()) {
+ qDebug("**** Session open Timeout - Wait 5 seconds and try once again ****");
+ session.close();
+ QTest::qWait(5000); // Wait a while before trying to open session again
+ session.open();
+ session.waitForOpened();
+ }
+#else
session.waitForOpened();
+#endif
if (session.isOpen())
QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty());
@@ -769,6 +805,9 @@
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);
@@ -801,7 +840,20 @@
session.open();
+#if defined(Q_OS_SYMBIAN)
+ // Opening & closing multiple connections in a row sometimes
+ // results hanging of connection opening on Symbian devices
+ // => If first open fails, wait a moment and try again.
+ if (!session.waitForOpened()) {
+ qDebug("**** Session open Timeout - Wait 5 seconds and try once again ****");
+ session.close();
+ QTest::qWait(5000); // Wait a while before trying to open session again
+ session.open();
+ session.waitForOpened();
+ }
+#else
session.waitForOpened();
+#endif
if (session.isOpen())
QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty());
@@ -875,24 +927,28 @@
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);
#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());
+ }
}
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
@@ -901,15 +957,17 @@
#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 =
@@ -929,9 +987,12 @@
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);
@@ -975,54 +1036,66 @@
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);
+ 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(1).at(0));
- if (state == QNetworkSession::Connected) {
- roamedSuccessfully = true;
- QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected);
- }
+ 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();
QNetworkConfiguration config = manager.configurationFromIdentifier(configId);
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());
- QVERIFY(session.state() == QNetworkSession::Disconnected);
- QVERIFY(session2.state() == QNetworkSession::Disconnected);
+ QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
}
QVERIFY(errorSpy2.isEmpty());
@@ -1041,7 +1114,7 @@
QVERIFY(!session.isOpen());
#endif
QVERIFY(!session2.isOpen());
- } else {
+ } else if (session2.isOpen()) {
// Test closing the second session.
{
int stateChangedCountBeforeClose = stateChangedSpy2.count();
@@ -1138,9 +1211,15 @@
// at Discovered -state.
void tst_QNetworkSession::outOfProcessSession()
{
+ 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
@@ -1161,6 +1240,7 @@
lackey.start("qnetworksessionlackey");
QVERIFY(lackey.waitForStarted());
+
QVERIFY(oopServer.waitForNewConnection(-1));
QLocalSocket *oopSocket = oopServer.nextPendingConnection();
@@ -1241,6 +1321,7 @@
// 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) {
@@ -1249,8 +1330,7 @@
}
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();
@@ -1287,9 +1367,23 @@
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)));
@@ -1299,43 +1393,57 @@
// 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;
}
- return true;
+ if (result == false) {
+ qDebug() << "tst_QNetworkSession::openSession() opening session failed.";
+ } else {
+ qDebug() << "tst_QNetworkSession::openSession() opening session succeeded.";
+ }
+ 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
@@ -1348,6 +1456,11 @@
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.");
@@ -1359,38 +1472,48 @@
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;
}
QTEST_MAIN(tst_QNetworkSession)