Qt 4.8
qcorewlanengine.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qcorewlanengine.h"
43 #include "../qnetworksession_impl.h"
44 
45 #include <QtNetwork/private/qnetworkconfiguration_p.h>
46 
47 #include <QtCore/qthread.h>
48 #include <QtCore/qmutex.h>
49 #include <QtCore/qcoreapplication.h>
50 #include <QtCore/qstringlist.h>
51 
52 #include <QtCore/qdebug.h>
53 
54 #include <QDir>
55 
56 extern "C" { // Otherwise it won't find CWKeychain* symbols at link time
57 #import <CoreWLAN/CoreWLAN.h>
58 }
59 
60 #include "private/qcore_mac_p.h"
61 
62 #include <net/if.h>
63 #include <ifaddrs.h>
64 
65 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
66 
67 @interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject
68 {
69  NSNotificationCenter *notificationCenter;
70  CWInterface *currentInterface;
71  QCoreWlanEngine *engine;
72  NSLock *locker;
73 }
74 - (void)notificationHandler:(NSNotification *)notification;
75 - (void)remove;
76 - (void)setEngine:(QCoreWlanEngine *)coreEngine;
77 - (QCoreWlanEngine *)engine;
78 - (void)dealloc;
79 
80 @property (assign) QCoreWlanEngine* engine;
81 
82 @end
83 
84 @implementation QT_MANGLE_NAMESPACE(QNSListener)
85 
86 - (id) init
87 {
88  [locker lock];
89  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
90  notificationCenter = [NSNotificationCenter defaultCenter];
91  currentInterface = [CWInterface interfaceWithName:nil];
92  [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:CWPowerDidChangeNotification object:nil];
93  [locker unlock];
94  [autoreleasepool release];
95  return self;
96 }
97 
98 -(void)dealloc
99 {
100  [super dealloc];
101 }
102 
103 -(void)setEngine:(QCoreWlanEngine *)coreEngine
104 {
105  [locker lock];
106  if(!engine)
107  engine = coreEngine;
108  [locker unlock];
109 }
110 
111 -(QCoreWlanEngine *)engine
112 {
113  return engine;
114 }
115 
116 -(void)remove
117 {
118  [locker lock];
119  [notificationCenter removeObserver:self];
120  [locker unlock];
121 }
122 
123 - (void)notificationHandler:(NSNotification *)notification
124 {
125  Q_UNUSED(notification);
126  engine->requestUpdate();
127 }
128 @end
129 
131 
133 
134 void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info)
135 {
136  for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) {
137 
138  QString changed = QCFString::toQString((CFStringRef)CFArrayGetValueAtIndex(changedKeys, i));
139  if( changed.contains("/Network/Global/IPv4")) {
140  QCoreWlanEngine* wlanEngine = static_cast<QCoreWlanEngine*>(info);
141  wlanEngine->requestUpdate();
142  }
143  }
144  return;
145 }
146 
147 
149  :QThread(parent)
150 {
151 }
152 
154 {
155 }
156 
157 void QScanThread::quit()
158 {
159  wait();
160 }
161 
162 void QScanThread::run()
163 {
164  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
165  QStringList found;
166  mutex.lock();
167  CWInterface *currentInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceName)];
168  mutex.unlock();
169 
170  if (currentInterface.powerOn) {
171  NSError *err = nil;
172 
173  NSSet* apSet = [currentInterface scanForNetworksWithName:nil error:&err];
174 
175  if (!err) {
176  for (CWNetwork *apNetwork in apSet) {
177  const QString networkSsid = QCFString::toQString(CFStringRef([apNetwork ssid]));
178  const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
179  found.append(id);
180 
181  QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
182  bool known = isKnownSsid(networkSsid);
183  if (currentInterface.serviceActive) {
184  if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
186  }
187  }
188  if (state == QNetworkConfiguration::Undefined) {
189  if(known) {
191  } else {
193  }
194  }
196  if ([apNetwork supportsSecurity:kCWSecurityNone]) {
198  } else {
200  }
201 
202  found.append(foundNetwork(id, networkSsid, state, interfaceName, purpose));
203 
204  }
205  }
206  }
207  // add known configurations that are not around.
208  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
209  while (i.hasNext()) {
210  i.next();
211 
212  QString networkName = i.key();
213  const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName));
214 
215  if(!found.contains(id)) {
216  QString networkSsid = getSsidFromNetworkName(networkName);
217  const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
218  QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
220  QMapIterator<QString, QString> ij(i.value());
221  while (ij.hasNext()) {
222  ij.next();
223  interfaceName = ij.value();
224  }
225 
226  if (currentInterface.serviceActive) {
227  if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
229  }
230  }
231  if(state == QNetworkConfiguration::Undefined) {
232  if( userProfiles.contains(networkName)
233  && found.contains(ssidId)) {
235  }
236  }
237 
238  if(state == QNetworkConfiguration::Undefined) {
240  }
241 
242  found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose));
243  }
244  }
246  [autoreleasepool release];
247 }
248 
249 QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
250 {
251  QStringList found;
252  QMutexLocker locker(&mutex);
254 
255  ptr->name = name;
256  ptr->isValid = true;
257  ptr->id = id;
258  ptr->state = state;
261  ptr->purpose = purpose;
262 
264  configurationInterface.insert(ptr->id, interfaceName);
265 
266  locker.unlock();
267  locker.relock();
268  found.append(id);
269  return found;
270 }
271 
273 {
274  QMutexLocker locker(&mutex);
275 
278 
279  return foundConfigurations;
280 }
281 
283 {
284  QMutexLocker locker(&mutex);
285 
286  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
288 
289  NSSet *wifiInterfaces = [CWInterface interfaceNames];
290  for (NSString *ifName in wifiInterfaces) {
291 
292  CWInterface *wifiInterface = [CWInterface interfaceWithName: ifName];
293  if (!wifiInterface.powerOn)
294  continue;
295 
296  NSString *nsInterfaceName = wifiInterface.ssid;
297 // add user configured system networks
298  SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil);
299  NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]);
300  CFRelease(dynRef);
301  if(airportPlist != nil) {
302  NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
303 
304  NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
305  for (NSString *ssidkey in thisSsidarray) {
306  QString thisSsid = QCFString::toQString(CFStringRef(ssidkey));
307  if(!userProfiles.contains(thisSsid)) {
309  map.insert(thisSsid, QCFString::toQString(CFStringRef(nsInterfaceName)));
310  userProfiles.insert(thisSsid, map);
311  }
312  }
313  CFRelease(airportPlist);
314  }
315 
316  // 802.1X user profiles
317  QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
318  NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile: (NSString *)QCFString::toCFStringRef(userProfilePath)] autorelease];
319  if(eapDict != nil) {
320  NSString *profileStr= @"Profiles";
321  NSString *nameStr = @"UserDefinedName";
322  NSString *networkSsidStr = @"Wireless Network";
323  for (id profileKey in eapDict) {
324  if ([profileStr isEqualToString:profileKey]) {
325  NSDictionary *itemDict = [eapDict objectForKey:profileKey];
326  for (id itemKey in itemDict) {
327 
328  NSInteger dictSize = [itemKey count];
329  id objects[dictSize];
330  id keys[dictSize];
331 
332  [itemKey getObjects:objects andKeys:keys];
333  QString networkName;
334  QString ssid;
335  for(int i = 0; i < dictSize; i++) {
336  if([nameStr isEqualToString:keys[i]]) {
337  networkName = QCFString::toQString(CFStringRef(objects[i]));
338  }
339  if([networkSsidStr isEqualToString:keys[i]]) {
340  ssid = QCFString::toQString(CFStringRef(objects[i]));
341  }
342  if(!userProfiles.contains(networkName)
343  && !ssid.isEmpty()) {
345  map.insert(ssid, QCFString::toQString(CFStringRef(nsInterfaceName)));
346  userProfiles.insert(networkName, map);
347  }
348  }
349  }
350  }
351  }
352  }
353  }
354  [autoreleasepool release];
355 }
356 
358 {
359  QMutexLocker locker(&mutex);
360 
361  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
362  while (i.hasNext()) {
363  i.next();
364  QMap<QString,QString> map = i.value();
365  QMapIterator<QString, QString> ij(i.value());
366  while (ij.hasNext()) {
367  ij.next();
368  const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key()));
369  if(name == i.key() || name == networkNameHash) {
370  return ij.key();
371  }
372  }
373  }
374  return QString();
375 }
376 
378 {
379  QMutexLocker locker(&mutex);
380 
381  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
382  while (i.hasNext()) {
383  i.next();
384  QMap<QString,QString> map = i.value();
385  QMapIterator<QString, QString> ij(i.value());
386  while (ij.hasNext()) {
387  ij.next();
388  if(ij.key() == ssid) {
389  return i.key();
390  }
391  }
392  }
393  return QString();
394 }
395 
396 bool QScanThread::isKnownSsid(const QString &ssid)
397 {
398  QMutexLocker locker(&mutex);
399 
400  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
401  while (i.hasNext()) {
402  i.next();
403  QMap<QString,QString> map = i.value();
404  if(map.keys().contains(ssid)) {
405  return true;
406  }
407  }
408  return false;
409 }
410 
411 
413 : QBearerEngineImpl(parent), scanThread(0)
414 {
415  scanThread = new QScanThread(this);
416  connect(scanThread, SIGNAL(networksChanged()),
417  this, SLOT(networksChanged()));
418 }
419 
421 {
422  while (!foundConfigurations.isEmpty())
423  delete foundConfigurations.takeFirst();
424  [listener remove];
425  [listener release];
426 }
427 
429 {
430  QMutexLocker locker(&mutex);
431  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
432 
433  if ([[CWInterface interfaceNames] count] > 0 && !listener) {
434  listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init];
435  listener.engine = this;
436  hasWifi = true;
437  } else {
438  hasWifi = false;
439  }
440  storeSession = NULL;
441 
442  startNetworkChangeLoop();
443  [autoreleasepool release];
444 }
445 
446 
448 {
449  QMutexLocker locker(&mutex);
450 
451  return scanThread->configurationInterface.value(id);
452 }
453 
455 {
456  QMutexLocker locker(&mutex);
457 
458  return scanThread->configurationInterface.contains(id);
459 }
460 
462 {
463  QMutexLocker locker(&mutex);
464  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
465  QString interfaceString = getInterfaceFromId(id);
466 
467  CWInterface *wifiInterface =
468  [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
469 
470  if (wifiInterface.powerOn) {
471  NSError *err = nil;
472  QString wantedSsid;
473  QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
474 
475  const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name));
476  const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name)));
477 
478  QString wantedNetwork;
479  QMapIterator<QString, QMap<QString, QString> > i(scanThread->userProfiles);
480  while (i.hasNext()) {
481  i.next();
482  wantedNetwork = i.key();
483  const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork));
484  if (id == networkNameHash) {
485  wantedSsid = scanThread->getSsidFromNetworkName(wantedNetwork);
486  break;
487  }
488  }
489 
490  NSSet *scanSet = [wifiInterface scanForNetworksWithName:(NSString *)QCFString::toCFStringRef(wantedSsid) error:&err];
491 
492  if(!err) {
493  for (CWNetwork *apNetwork in scanSet) {
494  CFDataRef ssidData = (CFDataRef)[apNetwork ssidData];
495  bool result = false;
496 
497  SecIdentityRef identity = 0;
498  // Check first whether we require IEEE 802.1X authentication for the wanted SSID
499  if (CWKeychainCopyEAPIdentity(ssidData, &identity) == errSecSuccess) {
500  CFStringRef username = 0;
501  CFStringRef password = 0;
502  if (CWKeychainCopyEAPUsernameAndPassword(ssidData, &username, &password) == errSecSuccess) {
503  result = [wifiInterface associateToEnterpriseNetwork:apNetwork
504  identity:identity username:(NSString *)username password:(NSString *)password
505  error:&err];
506  CFRelease(username);
507  CFRelease(password);
508  }
509  CFRelease(identity);
510  } else {
511  CFStringRef password = 0;
512  if (CWKeychainCopyPassword(ssidData, &password) == errSecSuccess) {
513  result = [wifiInterface associateToNetwork:apNetwork password:(NSString *)password error:&err];
514  CFRelease(password);
515  }
516  }
517 
518  if (!err) {
519  if (!result) {
520  emit connectionError(id, ConnectError);
521  } else {
522  return;
523  }
524  } else {
525  qDebug() <<"associate ERROR"<< QCFString::toQString(CFStringRef([err localizedDescription ]));
526  }
527  } //end scan network
528  } else {
529  qDebug() <<"scan ERROR"<< QCFString::toQString(CFStringRef([err localizedDescription ]));
530  }
531  emit connectionError(id, InterfaceLookupError);
532  }
533 
534  locker.unlock();
535  emit connectionError(id, InterfaceLookupError);
536  [autoreleasepool release];
537 }
538 
540 {
541  QMutexLocker locker(&mutex);
542 
543  QString interfaceString = getInterfaceFromId(id);
544  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
545 
546  CWInterface *wifiInterface =
547  [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
548 
549  [wifiInterface disassociate];
550  if (wifiInterface.serviceActive) {
551  locker.unlock();
552  emit connectionError(id, DisconnectionError);
553  locker.relock();
554  }
555  [autoreleasepool release];
556 }
557 
559 {
560  scanThread->getUserConfigurations();
561  doRequestUpdate();
562 }
563 
565 {
566  QMutexLocker locker(&mutex);
567 
568  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
569 
570  NSSet *wifiInterfaces = [CWInterface interfaceNames];
571  for (NSString *ifName in wifiInterfaces) {
572  scanThread->interfaceName = QCFString::toQString(CFStringRef(ifName));
573  scanThread->start();
574  }
575  locker.unlock();
576  if ([wifiInterfaces count] == 0)
577  networksChanged();
578  [autoreleasepool release];
579 }
580 
581 bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
582 {
583  QMutexLocker locker(&mutex);
584  bool haswifi = false;
585  if(hasWifi) {
586  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
587  CWInterface *defaultInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(wifiDeviceName)];
588  if (defaultInterface.powerOn) {
589  haswifi = true;
590  }
591  [autoreleasepool release];
592  }
593  return haswifi;
594 }
595 
596 
598 {
599  QMutexLocker locker(&mutex);
600  QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
601 
602  if (!ptr)
604 
605  if (!ptr->isValid) {
609  } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
614  } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
617  }
618 
620 }
621 
622 QNetworkConfigurationManager::Capabilities QCoreWlanEngine::capabilities() const
623 {
625 }
626 
628 {
629 
630  SCDynamicStoreContext dynStoreContext = { 0, this/*(void *)storeSession*/, NULL, NULL, NULL };
631  storeSession = SCDynamicStoreCreate(NULL,
632  CFSTR("networkChangeCallback"),
634  &dynStoreContext);
635  if (!storeSession ) {
636  qWarning() << "could not open dynamic store: error:" << SCErrorString(SCError());
637  return;
638  }
639 
640  CFMutableArrayRef notificationKeys;
641  notificationKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
642  CFMutableArrayRef patternsArray;
643  patternsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
644 
645  CFStringRef storeKey;
646  storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
647  kSCDynamicStoreDomainState,
648  kSCEntNetIPv4);
649  CFArrayAppendValue(notificationKeys, storeKey);
650  CFRelease(storeKey);
651 
652  storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
653  kSCDynamicStoreDomainState,
654  kSCCompAnyRegex,
655  kSCEntNetIPv4);
656  CFArrayAppendValue(patternsArray, storeKey);
657  CFRelease(storeKey);
658 
659  if (!SCDynamicStoreSetNotificationKeys(storeSession , notificationKeys, patternsArray)) {
660  qWarning() << "register notification error:"<< SCErrorString(SCError());
661  CFRelease(storeSession );
662  CFRelease(notificationKeys);
663  CFRelease(patternsArray);
664  return;
665  }
666  CFRelease(notificationKeys);
667  CFRelease(patternsArray);
668 
669  runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0);
670  if (!runloopSource) {
671  qWarning() << "runloop source error:"<< SCErrorString(SCError());
672  CFRelease(storeSession );
673  return;
674  }
675 
676  CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
677  return;
678 }
679 
681 {
682  return new QNetworkSessionPrivateImpl;
683 }
684 
686 {
688 }
689 
691 {
692  return true;
693 }
694 
696 {
697  QMutexLocker locker(&mutex);
698 
699  QStringList previous = accessPointConfigurations.keys();
700 
701  QList<QNetworkConfigurationPrivate *> foundConfigurations = scanThread->getConfigurations();
702  while (!foundConfigurations.isEmpty()) {
703  QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst();
704 
705  previous.removeAll(cpPriv->id);
706 
707  if (accessPointConfigurations.contains(cpPriv->id)) {
708  QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id);
709 
710  bool changed = false;
711 
712  ptr->mutex.lock();
713 
714  if (ptr->isValid != cpPriv->isValid) {
715  ptr->isValid = cpPriv->isValid;
716  changed = true;
717  }
718 
719  if (ptr->name != cpPriv->name) {
720  ptr->name = cpPriv->name;
721  changed = true;
722  }
723 
724  if (ptr->bearerType != cpPriv->bearerType) {
725  ptr->bearerType = cpPriv->bearerType;
726  changed = true;
727  }
728 
729  if (ptr->state != cpPriv->state) {
730  ptr->state = cpPriv->state;
731  changed = true;
732  }
733 
734  ptr->mutex.unlock();
735 
736  if (changed) {
737  locker.unlock();
738  emit configurationChanged(ptr);
739  locker.relock();
740  }
741 
742  delete cpPriv;
743  } else {
745 
746  accessPointConfigurations.insert(ptr->id, ptr);
747 
748  locker.unlock();
749  emit configurationAdded(ptr);
750  locker.relock();
751  }
752  }
753 
754  while (!previous.isEmpty()) {
756  accessPointConfigurations.take(previous.takeFirst());
757 
758  locker.unlock();
759  emit configurationRemoved(ptr);
760  locker.relock();
761  }
762 
763  locker.unlock();
764  emit updateCompleted();
765 
766 }
767 
769 {
770  QMutexLocker locker(&mutex);
771  const QString interfaceStr = getInterfaceFromId(id);
772  return getBytes(interfaceStr,false);
773 }
774 
776 {
777  QMutexLocker locker(&mutex);
778  const QString interfaceStr = getInterfaceFromId(id);
779  return getBytes(interfaceStr,true);
780 }
781 
782 quint64 QCoreWlanEngine::startTime(const QString &identifier)
783 {
784  QMutexLocker locker(&mutex);
785  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
786  quint64 timestamp = 0;
787 
788  NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist";
789  NSDictionary* plistDict = [[[NSDictionary alloc] initWithContentsOfFile:filePath] autorelease];
790  if(plistDict == nil)
791  return timestamp;
792  NSString *input = @"KnownNetworks";
793  NSString *timeStampStr = @"_timeStamp";
794 
795  NSString *ssidStr = @"SSID_STR";
796 
797  for (id key in plistDict) {
798  if ([input isEqualToString:key]) {
799 
800  NSDictionary *knownNetworksDict = [plistDict objectForKey:key];
801  if(knownNetworksDict == nil)
802  return timestamp;
803  for (id networkKey in knownNetworksDict) {
804  bool isFound = false;
805  NSDictionary *itemDict = [knownNetworksDict objectForKey:networkKey];
806  if(itemDict == nil)
807  return timestamp;
808  NSInteger dictSize = [itemDict count];
809  id objects[dictSize];
810  id keys[dictSize];
811 
812  [itemDict getObjects:objects andKeys:keys];
813  bool ok = false;
814  for(int i = 0; i < dictSize; i++) {
815  if([ssidStr isEqualToString:keys[i]]) {
816  const QString ident = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef(objects[i]))));
817  if(ident == identifier) {
818  ok = true;
819  }
820  }
821  if(ok && [timeStampStr isEqualToString:keys[i]]) {
822  timestamp = (quint64)[objects[i] timeIntervalSince1970];
823  isFound = true;
824  break;
825  }
826  }
827  if(isFound)
828  break;
829  }
830  }
831  }
832  [autoreleasepool release];
833  return timestamp;
834 }
835 
836 quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b)
837 {
838  struct ifaddrs *ifAddressList, *ifAddress;
839  struct if_data *if_data;
840 
841  quint64 bytes = 0;
842  ifAddressList = nil;
843  if(getifaddrs(&ifAddressList) == 0) {
844  for(ifAddress = ifAddressList; ifAddress; ifAddress = ifAddress->ifa_next) {
845  if(interfaceName == ifAddress->ifa_name) {
846  if_data = (struct if_data*)ifAddress->ifa_data;
847  if(b) {
848  bytes = if_data->ifi_ibytes;
849  break;
850  } else {
851  bytes = if_data->ifi_obytes;
852  break;
853  }
854  }
855  }
856  freeifaddrs(ifAddressList);
857  }
858  return bytes;
859 }
860 
862 
863 #else // QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE
864 #include "qcorewlanengine_10_6.mm"
865 #endif
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
bool requiresPolling() const
uint qHash(const QProcEnvKey &key)
Definition: qprocess_p.h:96
const struct __CFString * CFStringRef
Purpose
Specifies the purpose of the configuration.
static mach_timebase_info_data_t info
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void lock()
Locks the mutex.
Definition: qmutex.cpp:151
void disconnectFromId(const QString &id)
QList< QNetworkConfigurationPrivate * > getConfigurations()
bool hasIdentifier(const QString &id)
QNetworkConfiguration::StateFlags state
QScanThread(QObject *parent=0)
Q_INVOKABLE void initialize()
#define SLOT(a)
Definition: qobjectdefs.h:226
quint64 bytesWritten(const QString &id)
static QString toQString(CFStringRef cfstr)
Definition: qcore_mac.cpp:47
State
This enum describes the connectivity state of the session.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QString getSsidFromNetworkName(const QString &name)
quint64 bytesReceived(const QString &id)
The QString class provides a Unicode character string.
Definition: qstring.h:83
quint64 startTime(const QString &id)
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QNetworkConfiguration::BearerType bearerType
QStringList keys
QCoreWlanEngine(QObject *parent=0)
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
Q_CORE_EXPORT void qDebug(const char *,...)
#define SIGNAL(a)
Definition: qobjectdefs.h:227
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QList< QNetworkConfigurationPrivate * > fetchedConfigurations
QFuture< void > map(Sequence &sequence, MapFunction function)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
QNetworkConfigurationPrivatePointer defaultConfiguration()
unsigned __int64 quint64
Definition: qglobal.h:943
T takeFirst()
Removes the first item in the list and returns it.
Definition: qlist.h:489
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QMap< QString, QMap< QString, QString > > userProfiles
static bool init
const char * name
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
#define emit
Definition: qobjectdefs.h:76
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
Q_CORE_EXPORT void qWarning(const char *,...)
QNetworkSessionPrivate * createSessionBackend()
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
void connectToId(const QString &id)
const T * ptr(const T &t)
QList< Key > keys() const
Returns a list containing all the keys in the map in ascending order.
Definition: qmap.h:818
void clear()
Removes all items from the list.
Definition: qlist.h:764
QString getInterfaceFromId(const QString &id)
void unlock()
Unlocks the mutex.
Definition: qmutex.cpp:296
QMap< QString, QString > configurationInterface
QString getNetworkNameFromSsid(const QString &ssid)
bool isWifiReady(const QString &dev)
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
QNetworkConfiguration::Purpose purpose
void run()
The starting point for the thread.
QExplicitlySharedDataPointer< QNetworkConfigurationPrivate > QNetworkConfigurationPrivatePointer
void networksChanged()
Q_INVOKABLE void requestUpdate()
QNetworkConfiguration::Type type
#define QT_MANGLE_NAMESPACE(name)
Definition: qglobal.h:106
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
bool isKnownSsid(const QString &ssid)
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
bool wait(unsigned long time=ULONG_MAX)
Blocks the thread until either of these conditions is met:
int key
quint64 getBytes(const QString &interfaceName, bool b)
void networkChangeCallback(SCDynamicStoreRef, CFArrayRef changedKeys, void *info)
bool contains(const Key &key) const
Returns true if the map contains an item with key key; otherwise returns false.
Definition: qmap.h:553
QNetworkSession::State sessionStateForId(const QString &id)
QString interfaceName
QStringList foundNetwork(const QString &id, const QString &ssid, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
static QNSListener * listener
QNetworkConfigurationManager::Capabilities capabilities() const
const struct __CFArray * CFArrayRef
The QThread class provides a platform-independent way to manage threads.
Definition: qthread.h:59
QCoreWlanEngine * engine
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void clear()
Removes all items from the map.
Definition: qmap.h:444
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
static QString homePath()
Returns the absolute path of the user&#39;s home directory.
Definition: qdir.cpp:1942