Qt 4.8
qcorewlanengine_10_6.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 <SystemConfiguration/SCNetworkConfiguration.h>
43 
44 @interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject
45 {
46  NSNotificationCenter *notificationCenter;
47  CWInterface *currentInterface;
49  NSLock *locker;
50 }
51 - (void)notificationHandler:(NSNotification *)notification;
52 - (void)remove;
53 - (void)setEngine:(QCoreWlanEngine *)coreEngine;
54 - (QCoreWlanEngine *)engine;
55 - (void)dealloc;
56 
57 @property (assign) QCoreWlanEngine* engine;
58 
59 @end
60 
61 @implementation QT_MANGLE_NAMESPACE(QNSListener)
62 
63 - (id) init
64 {
65  [locker lock];
66  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
67  notificationCenter = [NSNotificationCenter defaultCenter];
68  currentInterface = [CWInterface interfaceWithName:nil];
69  [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil];
70  [locker unlock];
71  [autoreleasepool release];
72  return self;
73 }
74 
75 -(void)dealloc
76 {
77  [super dealloc];
78 }
79 
80 -(void)setEngine:(QCoreWlanEngine *)coreEngine
81 {
82  [locker lock];
83  if(!engine)
84  engine = coreEngine;
85  [locker unlock];
86 }
87 
88 -(QCoreWlanEngine *)engine
89 {
90  return engine;
91 }
92 
93 -(void)remove
94 {
95  [locker lock];
96  [notificationCenter removeObserver:self];
97  [locker unlock];
98 }
99 
100 - (void)notificationHandler:(NSNotification *)notification
101 {
102  Q_UNUSED(notification);
103  engine->requestUpdate();
104 }
105 @end
106 
108 
110 
111 void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info)
112 {
113  for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) {
114 
115  QString changed = QCFString::toQString(CFStringRef((CFStringRef)CFArrayGetValueAtIndex(changedKeys, i)));
116  if( changed.contains("/Network/Global/IPv4")) {
117  QCoreWlanEngine* wlanEngine = static_cast<QCoreWlanEngine*>(info);
118  wlanEngine->requestUpdate();
119  }
120  }
121  return;
122 }
123 
124 
126  :QThread(parent)
127 {
128 }
129 
131 {
132 }
133 
135 {
136  wait();
137 }
138 
140 {
141  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
142  QStringList found;
143  mutex.lock();
144  CWInterface *currentInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceName)];
145  mutex.unlock();
146 
147  if([currentInterface power]) {
148  NSError *err = nil;
149  NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys:
150  [NSNumber numberWithBool:YES], kCWScanKeyMerge,
151  [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
152  [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil];
153 
154  NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
155  CWNetwork *apNetwork;
156 
157  if (!err) {
158 
159  for(uint row=0; row < [apArray count]; row++ ) {
160  apNetwork = [apArray objectAtIndex:row];
161 
162  const QString networkSsid = QCFString::toQString(CFStringRef([apNetwork ssid]));
163  const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
164  found.append(id);
165 
166  QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
167  bool known = isKnownSsid(networkSsid);
168  if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
169  if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
171  }
172  }
173  if(state == QNetworkConfiguration::Undefined) {
174  if(known) {
176  } else {
178  }
179  }
181  if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) {
183  } else {
185  }
186 
187  found.append(foundNetwork(id, networkSsid, state, interfaceName, purpose));
188 
189  }
190  }
191  }
192  // add known configurations that are not around.
193  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
194  while (i.hasNext()) {
195  i.next();
196 
197  QString networkName = i.key();
198  const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName));
199 
200  if(!found.contains(id)) {
201  QString networkSsid = getSsidFromNetworkName(networkName);
202  const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
203  QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
205  QMapIterator<QString, QString> ij(i.value());
206  while (ij.hasNext()) {
207  ij.next();
208  interfaceName = ij.value();
209  }
210 
211  if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
212  if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
214  }
215  }
216  if(state == QNetworkConfiguration::Undefined) {
217  if( userProfiles.contains(networkName)
218  && found.contains(ssidId)) {
220  }
221  }
222 
223  if(state == QNetworkConfiguration::Undefined) {
225  }
226 
227  found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose));
228  }
229  }
231  [autoreleasepool release];
232 }
233 
234 QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
235 {
236  QStringList found;
237  QMutexLocker locker(&mutex);
239 
240  ptr->name = name;
241  ptr->isValid = true;
242  ptr->id = id;
243  ptr->state = state;
246  ptr->purpose = purpose;
247 
249  configurationInterface.insert(ptr->id, interfaceName);
250 
251  locker.unlock();
252  locker.relock();
253  found.append(id);
254  return found;
255 }
256 
258 {
259  QMutexLocker locker(&mutex);
260 
263 
264  return foundConfigurations;
265 }
266 
268 {
269  QMutexLocker locker(&mutex);
270 
271  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
273 
274  NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
275  for(uint row=0; row < [wifiInterfaces count]; row++ ) {
276 
277  CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
278  if ( ![wifiInterface power] )
279  continue;
280 
281  NSString *nsInterfaceName = [wifiInterface name];
282 // add user configured system networks
283  SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil);
284  NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]);
285  CFRelease(dynRef);
286  if(airportPlist != nil) {
287  NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
288 
289  NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
290  for(NSString *ssidkey in thisSsidarray) {
291  QString thisSsid = QCFString::toQString(CFStringRef(ssidkey));
292  if(!userProfiles.contains(thisSsid)) {
294  map.insert(thisSsid, QCFString::toQString(CFStringRef(nsInterfaceName)));
295  userProfiles.insert(thisSsid, map);
296  }
297  }
298  CFRelease(airportPlist);
299  }
300 
301  // 802.1X user profiles
302  QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
303  NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile: (NSString *)QCFString::toCFStringRef(userProfilePath)] autorelease];
304  if(eapDict != nil) {
305  NSString *profileStr= @"Profiles";
306  NSString *nameStr = @"UserDefinedName";
307  NSString *networkSsidStr = @"Wireless Network";
308  for (id profileKey in eapDict) {
309  if ([profileStr isEqualToString:profileKey]) {
310  NSDictionary *itemDict = [eapDict objectForKey:profileKey];
311  for (id itemKey in itemDict) {
312 
313  NSInteger dictSize = [itemKey count];
314  id objects[dictSize];
315  id keys[dictSize];
316 
317  [itemKey getObjects:objects andKeys:keys];
318  QString networkName;
319  QString ssid;
320  for(int i = 0; i < dictSize; i++) {
321  if([nameStr isEqualToString:keys[i]]) {
322  networkName = QCFString::toQString(CFStringRef(objects[i]));
323  }
324  if([networkSsidStr isEqualToString:keys[i]]) {
325  ssid = QCFString::toQString(CFStringRef(objects[i]));
326  }
327  if(!userProfiles.contains(networkName)
328  && !ssid.isEmpty()) {
330  map.insert(ssid, QCFString::toQString(CFStringRef(nsInterfaceName)));
331  userProfiles.insert(networkName, map);
332  }
333  }
334  }
335  }
336  }
337  }
338  }
339  [autoreleasepool release];
340 }
341 
343 {
344  QMutexLocker locker(&mutex);
345 
346  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
347  while (i.hasNext()) {
348  i.next();
349  QMap<QString,QString> map = i.value();
350  QMapIterator<QString, QString> ij(i.value());
351  while (ij.hasNext()) {
352  ij.next();
353  const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key()));
354  if(name == i.key() || name == networkNameHash) {
355  return ij.key();
356  }
357  }
358  }
359  return QString();
360 }
361 
363 {
364  QMutexLocker locker(&mutex);
365 
366  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
367  while (i.hasNext()) {
368  i.next();
369  QMap<QString,QString> map = i.value();
370  QMapIterator<QString, QString> ij(i.value());
371  while (ij.hasNext()) {
372  ij.next();
373  if(ij.key() == ssid) {
374  return i.key();
375  }
376  }
377  }
378  return QString();
379 }
380 
382 {
383  QMutexLocker locker(&mutex);
384 
385  QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
386  while (i.hasNext()) {
387  i.next();
388  QMap<QString,QString> map = i.value();
389  if(map.keys().contains(ssid)) {
390  return true;
391  }
392  }
393  return false;
394 }
395 
396 
398 : QBearerEngineImpl(parent), scanThread(0)
399 {
400  scanThread = new QScanThread(this);
402  this, SLOT(networksChanged()));
403 }
404 
406 {
407  while (!foundConfigurations.isEmpty())
409  [listener remove];
410  [listener release];
411 }
412 
414 {
415  QMutexLocker locker(&mutex);
416  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
417 
418  if([[CWInterface supportedInterfaces] count] > 0 && !listener) {
419  listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init];
420  listener.engine = this;
421  hasWifi = true;
422  } else {
423  hasWifi = false;
424  }
425  storeSession = NULL;
426 
428  [autoreleasepool release];
429 }
430 
431 
433 {
434  QMutexLocker locker(&mutex);
435 
437 }
438 
440 {
441  QMutexLocker locker(&mutex);
442 
444 }
445 
447 {
448  QMutexLocker locker(&mutex);
449  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
450  QString interfaceString = getInterfaceFromId(id);
451 
452  CWInterface *wifiInterface =
453  [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
454 
455  if ([wifiInterface power]) {
456  NSError *err = nil;
457  NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
458 
459  QString wantedSsid;
460 
462 
463  const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name));
464  const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name)));
465 
466  bool using8021X = false;
467  if (idHash2 != id) {
468  NSArray *array = [CW8021XProfile allUser8021XProfiles];
469 
470  for (NSUInteger i = 0; i < [array count]; ++i) {
471  const QString networkNameHashCheck = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef([[array objectAtIndex:i] userDefinedName]))));
472 
473  const QString ssidHash = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef([[array objectAtIndex:i] ssid]))));
474 
475  if (id == networkNameHashCheck || id == ssidHash) {
476  const QString thisName = scanThread->getSsidFromNetworkName(id);
477  if (thisName.isEmpty())
478  wantedSsid = id;
479  else
480  wantedSsid = thisName;
481 
482  [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile];
483  using8021X = true;
484  break;
485  }
486  }
487  }
488 
489  if (!using8021X) {
490  QString wantedNetwork;
491  QMapIterator<QString, QMap<QString,QString> > i(scanThread->userProfiles);
492  while (i.hasNext()) {
493  i.next();
494  wantedNetwork = i.key();
495  const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork));
496  if (id == networkNameHash) {
497  wantedSsid = scanThread->getSsidFromNetworkName(wantedNetwork);
498  break;
499  }
500  }
501  }
502  NSDictionary *scanParameters = [NSDictionary dictionaryWithObjectsAndKeys:
503  [NSNumber numberWithBool:YES], kCWScanKeyMerge,
504  [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
505  [NSNumber numberWithInteger:100], kCWScanKeyRestTime,
506  (NSString *)QCFString::toCFStringRef(wantedSsid), kCWScanKeySSID,
507  nil];
508 
509  NSArray *scanArray = [wifiInterface scanForNetworksWithParameters:scanParameters error:&err];
510 
511  if(!err) {
512  for(uint row=0; row < [scanArray count]; row++ ) {
513  CWNetwork *apNetwork = [scanArray objectAtIndex:row];
514 
515  if(wantedSsid == QCFString::toQString(CFStringRef([apNetwork ssid]))) {
516 
517  if(!using8021X) {
518  SecKeychainAttribute attributes[3];
519 
520  NSString *account = [apNetwork ssid];
521  NSString *keyKind = @"AirPort network password";
522  NSString *keyName = account;
523 
524  attributes[0].tag = kSecAccountItemAttr;
525  attributes[0].data = (void *)[account UTF8String];
526  attributes[0].length = [account length];
527 
528  attributes[1].tag = kSecDescriptionItemAttr;
529  attributes[1].data = (void *)[keyKind UTF8String];
530  attributes[1].length = [keyKind length];
531 
532  attributes[2].tag = kSecLabelItemAttr;
533  attributes[2].data = (void *)[keyName UTF8String];
534  attributes[2].length = [keyName length];
535 
536  SecKeychainAttributeList attributeList = {3,attributes};
537 
538  SecKeychainSearchRef searchRef;
539  SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef);
540 
541  NSString *password = @"";
542  SecKeychainItemRef searchItem;
543 
544  if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) {
545  UInt32 realPasswordLength;
546  SecKeychainAttribute attributesW[8];
547  attributesW[0].tag = kSecAccountItemAttr;
548  SecKeychainAttributeList listW = {1,attributesW};
549  char *realPassword;
550  OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword);
551 
552  if (status == noErr) {
553  if (realPassword != NULL) {
554 
555  QByteArray pBuf;
556  pBuf.resize(realPasswordLength);
557  pBuf.prepend(realPassword);
558  pBuf.insert(realPasswordLength,'\0');
559 
560  password = [NSString stringWithUTF8String:pBuf];
561  }
562  SecKeychainItemFreeContent(&listW, realPassword);
563  }
564 
565  CFRelease(searchItem);
566  } else {
567  qDebug() << "SecKeychainSearchCopyNext error";
568  }
569  [params setValue: password forKey: kCWAssocKeyPassphrase];
570  } // end using8021X
571 
572 
573  bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
574 
575  if(!err) {
576  if(!result) {
578  } else {
579  return;
580  }
581  } else {
582  qDebug() <<"associate ERROR"<< QCFString::toQString(CFStringRef([err localizedDescription ]));
583  }
584  }
585  } //end scan network
586  } else {
587  qDebug() <<"scan ERROR"<< QCFString::toQString(CFStringRef([err localizedDescription ]));
588  }
590  }
591 
592  locker.unlock();
594  [autoreleasepool release];
595 }
596 
598 {
599  QMutexLocker locker(&mutex);
600 
601  QString interfaceString = getInterfaceFromId(id);
602  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
603 
604  CWInterface *wifiInterface =
605  [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
606 
607  [wifiInterface disassociate];
608  if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) {
609  locker.unlock();
611  locker.relock();
612  }
613  [autoreleasepool release];
614 }
615 
617 {
619  doRequestUpdate();
620 }
621 
623 {
624  QMutexLocker locker(&mutex);
625 
626  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
627 
628  NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
629  for (uint row = 0; row < [wifiInterfaces count]; ++row) {
630  scanThread->interfaceName = QCFString::toQString(CFStringRef([wifiInterfaces objectAtIndex:row]));
631  scanThread->start();
632  }
633  locker.unlock();
634  if ([wifiInterfaces count] == 0)
635  networksChanged();
636  [autoreleasepool release];
637 }
638 
639 bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
640 {
641  QMutexLocker locker(&mutex);
642  bool haswifi = false;
643  if(hasWifi) {
644  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
645  CWInterface *defaultInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(wifiDeviceName)];
646  if([defaultInterface power]) {
647  haswifi = true;
648  }
649  [autoreleasepool release];
650  }
651  return haswifi;
652 }
653 
654 
656 {
657  QMutexLocker locker(&mutex);
659 
660  if (!ptr)
662 
663  if (!ptr->isValid) {
667  } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
672  } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
675  }
676 
678 }
679 
680 QNetworkConfigurationManager::Capabilities QCoreWlanEngine::capabilities() const
681 {
683 }
684 
686 {
687 
688  SCDynamicStoreContext dynStoreContext = { 0, this/*(void *)storeSession*/, NULL, NULL, NULL };
689  storeSession = SCDynamicStoreCreate(NULL,
690  CFSTR("networkChangeCallback"),
692  &dynStoreContext);
693  if (!storeSession ) {
694  qWarning() << "could not open dynamic store: error:" << SCErrorString(SCError());
695  return;
696  }
697 
698  CFMutableArrayRef notificationKeys;
699  notificationKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
700  CFMutableArrayRef patternsArray;
701  patternsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
702 
703  CFStringRef storeKey;
704  storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
705  kSCDynamicStoreDomainState,
706  kSCEntNetIPv4);
707  CFArrayAppendValue(notificationKeys, storeKey);
708  CFRelease(storeKey);
709 
710  storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
711  kSCDynamicStoreDomainState,
712  kSCCompAnyRegex,
713  kSCEntNetIPv4);
714  CFArrayAppendValue(patternsArray, storeKey);
715  CFRelease(storeKey);
716 
717  if (!SCDynamicStoreSetNotificationKeys(storeSession , notificationKeys, patternsArray)) {
718  qWarning() << "register notification error:"<< SCErrorString(SCError());
719  CFRelease(storeSession );
720  CFRelease(notificationKeys);
721  CFRelease(patternsArray);
722  return;
723  }
724  CFRelease(notificationKeys);
725  CFRelease(patternsArray);
726 
727  runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0);
728  if (!runloopSource) {
729  qWarning() << "runloop source error:"<< SCErrorString(SCError());
730  CFRelease(storeSession );
731  return;
732  }
733 
734  CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
735  return;
736 }
737 
739 {
740  return new QNetworkSessionPrivateImpl;
741 }
742 
744 {
746 }
747 
749 {
750  return true;
751 }
752 
754 {
755  QMutexLocker locker(&mutex);
756 
757  QStringList previous = accessPointConfigurations.keys();
758 
760  while (!foundConfigurations.isEmpty()) {
761  QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst();
762 
763  previous.removeAll(cpPriv->id);
764 
765  if (accessPointConfigurations.contains(cpPriv->id)) {
767 
768  bool changed = false;
769 
770  ptr->mutex.lock();
771 
772  if (ptr->isValid != cpPriv->isValid) {
773  ptr->isValid = cpPriv->isValid;
774  changed = true;
775  }
776 
777  if (ptr->name != cpPriv->name) {
778  ptr->name = cpPriv->name;
779  changed = true;
780  }
781 
782  if (ptr->bearerType != cpPriv->bearerType) {
783  ptr->bearerType = cpPriv->bearerType;
784  changed = true;
785  }
786 
787  if (ptr->state != cpPriv->state) {
788  ptr->state = cpPriv->state;
789  changed = true;
790  }
791 
792  ptr->mutex.unlock();
793 
794  if (changed) {
795  locker.unlock();
797  locker.relock();
798  }
799 
800  delete cpPriv;
801  } else {
803 
804  accessPointConfigurations.insert(ptr->id, ptr);
805 
806  locker.unlock();
808  locker.relock();
809  }
810  }
811 
812  while (!previous.isEmpty()) {
814  accessPointConfigurations.take(previous.takeFirst());
815 
816  locker.unlock();
818  locker.relock();
819  }
820 
821  locker.unlock();
823 
824 }
825 
827 {
828  QMutexLocker locker(&mutex);
829  const QString interfaceStr = getInterfaceFromId(id);
830  return getBytes(interfaceStr,false);
831 }
832 
834 {
835  QMutexLocker locker(&mutex);
836  const QString interfaceStr = getInterfaceFromId(id);
837  return getBytes(interfaceStr,true);
838 }
839 
841 {
842  QMutexLocker locker(&mutex);
843  NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
844  quint64 timestamp = 0;
845 
846  NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist";
847  NSDictionary* plistDict = [[[NSDictionary alloc] initWithContentsOfFile:filePath] autorelease];
848  if(plistDict == nil)
849  return timestamp;
850  NSString *input = @"KnownNetworks";
851  NSString *timeStampStr = @"_timeStamp";
852 
853  NSString *ssidStr = @"SSID_STR";
854 
855  for (id key in plistDict) {
856  if ([input isEqualToString:key]) {
857 
858  NSDictionary *knownNetworksDict = [plistDict objectForKey:key];
859  if(knownNetworksDict == nil)
860  return timestamp;
861  for (id networkKey in knownNetworksDict) {
862  bool isFound = false;
863  NSDictionary *itemDict = [knownNetworksDict objectForKey:networkKey];
864  if(itemDict == nil)
865  return timestamp;
866  NSInteger dictSize = [itemDict count];
867  id objects[dictSize];
868  id keys[dictSize];
869 
870  [itemDict getObjects:objects andKeys:keys];
871  bool ok = false;
872  for(int i = 0; i < dictSize; i++) {
873  if([ssidStr isEqualToString:keys[i]]) {
874  const QString ident = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef(objects[i]))));
875  if(ident == identifier) {
876  ok = true;
877  }
878  }
879  if(ok && [timeStampStr isEqualToString:keys[i]]) {
880  timestamp = (quint64)[objects[i] timeIntervalSince1970];
881  isFound = true;
882  break;
883  }
884  }
885  if(isFound)
886  break;
887  }
888  }
889  }
890  [autoreleasepool release];
891  return timestamp;
892 }
893 
894 quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b)
895 {
896  struct ifaddrs *ifAddressList, *ifAddress;
897  struct if_data *if_data;
898 
899  quint64 bytes = 0;
900  ifAddressList = nil;
901  if(getifaddrs(&ifAddressList) == 0) {
902  for(ifAddress = ifAddressList; ifAddress; ifAddress = ifAddress->ifa_next) {
903  if(interfaceName == ifAddress->ifa_name) {
904  if_data = (struct if_data*)ifAddress->ifa_data;
905  if(b) {
906  bytes = if_data->ifi_ibytes;
907  break;
908  } else {
909  bytes = if_data->ifi_obytes;
910  break;
911  }
912  }
913  }
914  freeifaddrs(ifAddressList);
915  }
916  return bytes;
917 }
918 
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
static QString keyName(const QString &rKey)
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)
void configurationChanged(QNetworkConfigurationPrivatePointer config)
CWInterface * currentInterface
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
Q_INVOKABLE void initialize()
#define SLOT(a)
Definition: qobjectdefs.h:226
quint64 bytesWritten(const QString &id)
void unlock()
Unlocks this mutex locker.
Definition: qmutex.h:117
void updateCompleted()
QScanThread * scanThread
static QString toQString(CFStringRef cfstr)
Definition: qcore_mac.cpp:47
State
This enum describes the connectivity state of the session.
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QString getSsidFromNetworkName(const QString &name)
quint64 bytesReceived(const QString &id)
NSNotificationCenter * notificationCenter
QByteArray & prepend(char c)
Prepends the character ch to this byte array.
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
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
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
void relock()
Relocks an unlocked mutex locker.
Definition: qmutex.h:125
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
QHash< QString, QNetworkConfigurationPrivatePointer > accessPointConfigurations
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
void configurationAdded(QNetworkConfigurationPrivatePointer config)
Q_CORE_EXPORT void qWarning(const char *,...)
friend class QScanThread
unsigned int uint
Definition: qglobal.h:996
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
CFRunLoopSourceRef runloopSource
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
signed long OSStatus
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)
SCDynamicStoreRef storeSession
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
void start(Priority=InheritPriority)
Begins execution of the thread by calling run().
#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 resize(int size)
Sets the size of the byte array to size bytes.
void configurationRemoved(QNetworkConfigurationPrivatePointer config)
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)
void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error)
QString interfaceName
QStringList foundNetwork(const QString &id, const QString &ssid, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
static QNSListener * listener
QList< QNetworkConfigurationPrivate * > foundConfigurations
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
QByteArray & insert(int i, char c)
Inserts character ch at index position i in the byte array.
static QString homePath()
Returns the absolute path of the user&#39;s home directory.
Definition: qdir.cpp:1942