summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorn Potter <lorn.potter@nokia.com>2010-03-12 05:05:05 (GMT)
committerLorn Potter <lorn.potter@nokia.com>2010-03-12 05:05:05 (GMT)
commit837e6acbda362da0e0130b784c90f765d6cd8c8e (patch)
treec32f9e6558daba6247ebd869be2c563e67973c0e
parentaa4ab19776a67f882b901b488de8664811df8ae5 (diff)
downloadQt-837e6acbda362da0e0130b784c90f765d6cd8c8e.zip
Qt-837e6acbda362da0e0130b784c90f765d6cd8c8e.tar.gz
Qt-837e6acbda362da0e0130b784c90f765d6cd8c8e.tar.bz2
get known wifi networks a more complicated way, but without accessing
the keychain. Users will still see the keychain prompt when attempting to connect/associate with a wifi network.
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.h10
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm357
2 files changed, 265 insertions, 102 deletions
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h
index f6d5b7a..76574a8 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.h
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.h
@@ -90,15 +90,21 @@ private:
QMap<QString, QString> configurationInterface;
QStringList scanForSsids(const QString &interfaceName);
- bool isKnownSsid(const QString &interfaceName, const QString &ssid);
+ bool isKnownSsid(const QString &ssid);
QList<QNetworkConfigurationPrivate *> foundConfigurations;
SCDynamicStoreRef storeSession;
CFRunLoopSourceRef runloopSource;
- void startNetworkChangeLoop();
bool hasWifi;
+protected:
+ QMap<QString, QMap<QString,QString> > userProfiles;
+
+ void startNetworkChangeLoop();
+ void getUserConfigurations();
+ QString getNetworkNameFromSsid(const QString &ssid);
+ QString getSsidFromNetworkName(const QString &name);
};
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index 84dd6a5..392e24c 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -50,13 +50,11 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
-
-#if defined(MAC_SDK_10_6) //not much functionality without this
+#include <QDir>
#include <CoreWLAN/CoreWLAN.h>
#include <CoreWLAN/CWInterface.h>
#include <CoreWLAN/CWNetwork.h>
#include <CoreWLAN/CWNetwork.h>
-#endif
#include <Foundation/NSEnumerator.h>
#include <Foundation/NSKeyValueObserving.h>
@@ -69,16 +67,14 @@
QMap <QString, QString> networkInterfaces;
-#ifdef MAC_SDK_10_6
@interface QNSListener : NSObject
{
NSNotificationCenter *center;
CWInterface *currentInterface;
QCoreWlanEngine *engine;
- NSAutoreleasePool *autoreleasepool;
NSLock *locker;
}
-- (void)notificationHandler:(NSNotification *)notification;
+- (void)notificationHandler;//:(NSNotification *)notification;
- (void)remove;
- (void)setEngine:(QCoreWlanEngine *)coreEngine;
- (void)dealloc;
@@ -91,7 +87,7 @@ QMap <QString, QString> networkInterfaces;
- (id) init
{
[locker lock];
- autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacCocoaAutoReleasePool pool;
center = [NSNotificationCenter defaultCenter];
currentInterface = [CWInterface interface];
// [center addObserver:self selector:@selector(notificationHandler:) name:kCWLinkDidChangeNotification object:nil];
@@ -102,7 +98,6 @@ QMap <QString, QString> networkInterfaces;
-(void)dealloc
{
- [autoreleasepool release];
[super dealloc];
}
@@ -121,7 +116,7 @@ QMap <QString, QString> networkInterfaces;
[locker unlock];
}
-- (void)notificationHandler:(NSNotification *)notification
+- (void)notificationHandler//:(NSNotification *)notification
{
engine->requestUpdate();
}
@@ -129,14 +124,12 @@ QMap <QString, QString> networkInterfaces;
QNSListener *listener = 0;
-#endif
-
QT_BEGIN_NAMESPACE
static QString qGetInterfaceType(const QString &interfaceString)
{
- return networkInterfaces.value(interfaceString, QLatin1String("Unknown"));
+ return networkInterfaces.value(interfaceString, QLatin1String("WLAN"));
}
void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info)
@@ -157,7 +150,7 @@ QCoreWlanEngine::QCoreWlanEngine(QObject *parent)
{
startNetworkChangeLoop();
-#if defined(MAC_SDK_10_6)
+ QMacCocoaAutoReleasePool pool;
if([[CWInterface supportedInterfaces] count] > 0 && !listener) {
listener = [[QNSListener alloc] init];
listener.engine = this;
@@ -165,17 +158,16 @@ QCoreWlanEngine::QCoreWlanEngine(QObject *parent)
} else {
hasWifi = false;
}
-#endif
+ getUserConfigurations();
+ requestUpdate();
}
QCoreWlanEngine::~QCoreWlanEngine()
{
while (!foundConfigurations.isEmpty())
delete foundConfigurations.takeFirst();
-#if defined(MAC_SDK_10_6)
[listener remove];
[listener release];
-#endif
}
QString QCoreWlanEngine::getInterfaceFromId(const QString &id)
@@ -195,79 +187,88 @@ bool QCoreWlanEngine::hasIdentifier(const QString &id)
void QCoreWlanEngine::connectToId(const QString &id)
{
QMutexLocker locker(&mutex);
-
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacCocoaAutoReleasePool pool;
QString interfaceString = getInterfaceFromId(id);
if(networkInterfaces.value(interfaceString) == "WLAN") {
-#if defined(MAC_SDK_10_6)
CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)];
- CWConfiguration *userConfig = [ wifiInterface configuration];
-
- NSSet *remNets = [userConfig rememberedNetworks]; //CWWirelessProfile
- NSEnumerator *enumerator = [remNets objectEnumerator];
- CWWirelessProfile *wProfile;
- NSUInteger index=0;
- NSDictionary *parametersDict;
- NSArray* apArray;
-
- CW8021XProfile *user8021XProfile;
- NSError *err;
- NSMutableDictionary *params;
+ if([wifiInterface power]) {
+ NSError *err = nil;
+ NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
+
+ NSString *wantedSsid = 0;
+ bool okToProceed = true;
+ if(getNetworkNameFromSsid(id) != id) {
+ NSArray *array = [CW8021XProfile allUser8021XProfiles];
+ for (NSUInteger i=0; i<[array count]; ++i) {
+ const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] userDefinedName])));
+ const QString idCheck2 = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] ssid])));
+
+ if(id == idCheck
+ || id == idCheck2) {
+ QString thisName = getSsidFromNetworkName(id);
+ if(thisName.isEmpty()) {
+ wantedSsid = qt_mac_QStringToNSString(id);
+ } else {
+ wantedSsid = qt_mac_QStringToNSString(thisName);
+ }
+ okToProceed = false;
+ [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile];
+ break;
+ }
+ }
+ }
- while ((wProfile = [enumerator nextObject])) { //CWWirelessProfile
+ if(okToProceed) {
+ NSUInteger index = 0;
- if(id == QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([wProfile ssid])))) {
- user8021XProfile = nil;
- user8021XProfile = [ wProfile user8021XProfile];
+ CWConfiguration *userConfig = [ wifiInterface configuration];
+ NSSet *remNets = [userConfig rememberedNetworks];
+ NSEnumerator *enumerator = [remNets objectEnumerator];
+ CWWirelessProfile *wProfile;
- err = nil;
- params = [NSMutableDictionary dictionaryWithCapacity:0];
+ while ((wProfile = [enumerator nextObject])) {
+ const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([wProfile ssid])));
- if(user8021XProfile) {
- [params setValue: user8021XProfile forKey:kCWAssocKey8021XProfile];
- } else {
- [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase];
+ if(id == idCheck) {
+ wantedSsid = [wProfile ssid];
+ [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase];
+ break;
+ }
+ index++;
}
+ }
- parametersDict = nil;
- apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]];
-
- if(!err) {
-
- for(uint row=0; row < [apArray count]; row++ ) {
- CWNetwork *apNetwork = [apArray objectAtIndex:row];
- if([[apNetwork ssid] compare:[wProfile ssid]] == NSOrderedSame) {
+ NSDictionary *parametersDict = nil;
+ NSArray *apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]];
- bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
+ if(!err) {
+ for(uint row=0; row < [apArray count]; row++ ) {
+ CWNetwork *apNetwork = [apArray objectAtIndex:row];
+ if([[apNetwork ssid] compare:wantedSsid] == NSOrderedSame) {
+ bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
- if(!result) {
- locker.unlock();
- emit connectionError(id, ConnectError);
- locker.relock();
- } else {
- [autoreleasepool release];
- return;
- }
+ if(!result) {
+ emit connectionError(id, ConnectError);
+ } else {
+ return;
}
}
}
+ } else {
+ qDebug() <<"ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]);
}
- index++;
- }
+ emit connectionError(id, InterfaceLookupError);
+ } else {
+ // not wifi
+ }
locker.unlock();
emit connectionError(id, InterfaceLookupError);
locker.relock();
-#endif
- } else {
- // not wifi
}
-
- locker.unlock();
emit connectionError(id, OperationNotSupported);
- [autoreleasepool release];
}
void QCoreWlanEngine::disconnectFromId(const QString &id)
@@ -277,7 +278,7 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
QString interfaceString = getInterfaceFromId(id);
if(networkInterfaces.value(getInterfaceFromId(id)) == "WLAN") { //wifi only for now
#if defined(MAC_SDK_10_6)
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacCocoaAutoReleasePool pool;
CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)];
[wifiInterface disassociate];
if([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) {
@@ -285,7 +286,6 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
emit connectionError(id, DisconnectionError);
locker.relock();
}
- [autoreleasepool release];
return;
#endif
} else {
@@ -403,20 +403,20 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
QStringList found;
-#if defined(MAC_SDK_10_6)
if(!hasWifi) {
return found;
}
-
QMacCocoaAutoReleasePool pool;
CWInterface *currentInterface = [CWInterface interfaceWithName:qt_mac_QStringToNSString(interfaceName)];
+ QStringList addedConfigs;
+
if([currentInterface power]) {
NSError *err = nil;
NSDictionary *parametersDict = nil;
NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
-
CWNetwork *apNetwork;
+
if (!err) {
for(uint row=0; row < [apArray count]; row++ ) {
@@ -428,15 +428,18 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
found.append(id);
QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
-
- if ([currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
- if (networkSsid == qt_mac_NSStringToQString([currentInterface ssid]))
+ bool known = isKnownSsid(networkSsid);
+ if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if( networkSsid == qt_mac_NSStringToQString( [currentInterface ssid])) {
state = QNetworkConfiguration::Active;
- } else {
- if (isKnownSsid(interfaceName, networkSsid))
+ }
+ }
+ if(state == QNetworkConfiguration::Undefined) {
+ if(known) {
state = QNetworkConfiguration::Discovered;
- else
- state = QNetworkConfiguration::Defined;
+ } else {
+ state = QNetworkConfiguration::Undefined;
+ }
}
if (accessPointConfigurations.contains(id)) {
@@ -473,9 +476,11 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
emit configurationChanged(ptr);
locker.relock();
}
+ addedConfigs << networkSsid;
} else {
QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+ found.append(id);
ptr->name = networkSsid;
ptr->isValid = true;
ptr->id = id;
@@ -483,19 +488,60 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
ptr->type = QNetworkConfiguration::InternetAccessPoint;
ptr->bearer = QLatin1String("WLAN");
- accessPointConfigurations.insert(id, ptr);
- configurationInterface.insert(id, interfaceName);
+ accessPointConfigurations.insert(ptr->id, ptr);
+ configurationInterface.insert(ptr->id, interfaceName);
locker.unlock();
emit configurationAdded(ptr);
locker.relock();
+ addedConfigs << networkSsid;
}
}
}
}
-#else
- Q_UNUSED(interfaceName);
-#endif
+
+ // 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();
+ }
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+ const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName));
+ found.append(id);
+
+ ptr->name = networkName;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->bearer = QLatin1String("WLAN");
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ QString ssid = getSsidFromNetworkName(networkName);
+
+ if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if( ssid == qt_mac_NSStringToQString([currentInterface ssid])) {
+ ptr->state = QNetworkConfiguration::Active;
+ }
+ }
+
+ if(!ptr->state) {
+ if( addedConfigs.contains(ssid)) {
+ ptr->state = QNetworkConfiguration::Discovered;
+ }
+ }
+
+ if(!ptr->state) {
+ ptr->state = QNetworkConfiguration::Defined;
+ }
+ accessPointConfigurations.insert(ptr->id, ptr);
+ configurationInterface.insert(ptr->id, interfaceName);
+ }
+ }
return found;
}
@@ -503,35 +549,27 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
{
QMutexLocker locker(&mutex);
-#if defined(MAC_SDK_10_6)
if(hasWifi) {
+ QMacCocoaAutoReleasePool pool;
CWInterface *defaultInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(wifiDeviceName)];
if([defaultInterface power])
return true;
}
-#else
- Q_UNUSED(wifiDeviceName);
-#endif
return false;
}
-bool QCoreWlanEngine::isKnownSsid(const QString &interfaceName, const QString &ssid)
+bool QCoreWlanEngine::isKnownSsid(const QString &ssid)
{
QMutexLocker locker(&mutex);
-#if defined(MAC_SDK_10_6)
- if(!hasWifi) { return false; }
- CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceName)];
- CWConfiguration *userConfig = [wifiInterface configuration];
- NSSet *remNets = [userConfig rememberedNetworks];
- for (CWWirelessProfile *wProfile in remNets) {
- if(ssid == qt_mac_NSStringToQString([wProfile ssid]))
+ 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(interfaceName);
- Q_UNUSED(ssid);
-#endif
return false;
}
@@ -546,7 +584,6 @@ bool QCoreWlanEngine::getWifiInterfaces()
for(uint row=0; row < [wifiInterfaces count]; row++ ) {
networkInterfaces.insert( qt_mac_NSStringToQString([wifiInterfaces objectAtIndex:row]),"WLAN");
}
-
return true;
}
@@ -650,4 +687,124 @@ bool QCoreWlanEngine::requiresPolling() const
return true;
}
+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();
+ const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") +i.key()));
+ if(name == i.key() || name == idCheck) {
+ 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 map.key(ssid);
+ }
+ return QString();
+}
+
+
+void QCoreWlanEngine::getUserConfigurations()
+{
+ QMacCocoaAutoReleasePool pool;
+ userProfiles.clear();
+
+ NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
+ for(uint row=0; row < [wifiInterfaces count]; row++ ) {
+
+ CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
+
+// add user configured system networks
+ NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist";
+ NSDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
+ NSString *input = @"KnownNetworks";
+ NSString *ssidStr = @"SSID_STR";
+
+ for (id key in plistDict) {
+ if ([input isEqualToString:key]) {
+
+ NSDictionary *knownNetworksDict = [plistDict objectForKey:key];
+ for (id networkKey in knownNetworksDict) {
+
+ NSDictionary *itemDict = [knownNetworksDict objectForKey:networkKey];
+ NSInteger dictSize = [itemDict count];
+ id objects[dictSize];
+ id keys[dictSize];
+
+ [itemDict getObjects:objects andKeys:keys];
+
+ for(int i = 0; i < dictSize; i++) {
+ if([ssidStr isEqualToString:keys[i]]) {
+ QString thisSsid = qt_mac_NSStringToQString(objects[i]);
+ if(!userProfiles.contains(thisSsid)) {
+ QMap <QString,QString> map;
+ map.insert(thisSsid, qt_mac_NSStringToQString([wifiInterface name]));
+ userProfiles.insert(thisSsid, map);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 802.1X user profiles
+ QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
+ NSDictionary* eapDict = [[NSMutableDictionary alloc] initWithContentsOfFile:qt_mac_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 = qt_mac_NSStringToQString(objects[i]);
+ }
+ if([networkSsidStr isEqualToString:keys[i]]) {
+ ssid = qt_mac_NSStringToQString(objects[i]);
+ }
+ if(!userProfiles.contains(networkName)
+ && !ssid.isEmpty()) {
+ QMap<QString,QString> map;
+ map.insert(ssid, qt_mac_NSStringToQString([wifiInterface name]));
+ userProfiles.insert(networkName, map);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
QT_END_NAMESPACE