qtmobility/src/systeminfo/qsysteminfo_mac.mm
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
--- a/qtmobility/src/systeminfo/qsysteminfo_mac.mm	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/src/systeminfo/qsysteminfo_mac.mm	Mon May 03 13:18:40 2010 +0300
@@ -58,6 +58,7 @@
 #include <QDir>
 #include <QNetworkInterface>
 #include <QString>
+#include <QHostInfo>
 
 #include <locale.h>
 
@@ -72,6 +73,7 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFLocale.h>
 #include <ScreenSaver/ScreenSaverDefaults.h>
+#include <dns_sd.h>
 
 #include <QTKit/QTKit.h>
 
@@ -90,6 +92,7 @@
 #include <IOKit/hid/IOHIDLib.h>
 
 #include <CoreServices/CoreServices.h>
+
 #include <qabstracteventdispatcher.h>
 
 #include <QtCore/qthread.h>
@@ -120,8 +123,6 @@
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 
-//
-////////
 static QString stringFromCFString(CFStringRef value) {
     QString retVal;
     if(CFStringGetLength(value) > 1) {
@@ -172,7 +173,7 @@
 
 #ifdef MAC_SDK_10_6
 
-@interface QNSListener : NSObject
+@interface QtMNSListener : NSObject
 {
     NSNotificationCenter *center;
     CWInterface * currentInterface;
@@ -181,12 +182,12 @@
 - (void)remove;
 @end
 
-@implementation QNSListener
+@implementation QtMNSListener
 - (id) init
 {
    [super init];
     center = [NSNotificationCenter defaultCenter];
-    currentInterface = [CWInterface interface];
+    currentInterface = [CWInterface interfaceWithName:nil];
 
     [center addObserver:self selector:@selector(notificationHandler:) name:kCWModeDidChangeNotification object:nil];
     [center addObserver:self selector:@selector(notificationHandler:) name:kCWSSIDDidChangeNotification object:nil];
@@ -202,7 +203,6 @@
 -(void)dealloc
 {
    [center release];
-   [currentInterface release];
    [super dealloc];
 }
 
@@ -213,12 +213,12 @@
 
 - (void)notificationHandler:(NSNotification *)notification
 {
-    QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->networkChanged( nsstringToQString([notification name]), nsstringToQString([[notification object]name]));
+    QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->wifiNetworkChanged( nsstringToQString([notification name]), nsstringToQString([[notification object]name]));
 }
 @end
 
 
-@interface QLangListener : NSObject
+@interface QtMLangListener : NSObject
 {
     NSNotificationCenter *center;
     QString currentLanguage;
@@ -230,7 +230,7 @@
 
 
 
-@implementation QLangListener
+@implementation QtMLangListener
 - (id) init
 {
     [super init];
@@ -272,7 +272,37 @@
 @end
 
 
+@interface RemoteDeviceRSSIHostControllerDelegate : NSObject
+{
+}
+// See IOBluetoothHostControllerDelegate
+- (void)readRSSIForDeviceComplete:(id)controller device:(IOBluetoothDevice*)device info:(BluetoothHCIRSSIInfo*)info error:(IOReturn)error;
+@end
+
+@implementation RemoteDeviceRSSIHostControllerDelegate
+- (id) init
+{
+   [super init];
+   return self;
+}
+
+- (void)readRSSIForDeviceComplete:(id)controller device:(IOBluetoothDevice*)device info:(BluetoothHCIRSSIInfo*)info error:(IOReturn)error
+{
+    Q_UNUSED(controller);
+    Q_UNUSED(device);
+
+    if ((error != kIOReturnSuccess) || (info == NULL)) {
+        qWarning() << "ERROR: readRSSIForDeviceComplete return error";
+
+    } else if (info->handle == kBluetoothConnectionHandleNone) {
+        qWarning() << "ERROR: readRSSIForDeviceComplete no connection";
+    } else {
+        NSLog(@"Rssi value: %@", info->RSSIValue);
+    }
+}
+@end
 #endif
+NSObject* delegate;
 
 QTM_BEGIN_NAMESPACE
 
@@ -281,16 +311,16 @@
 QSystemInfoPrivate::QSystemInfoPrivate(QObject *parent)
  : QObject(parent)
 {
-    langloopThread = new QLangLoopThread(this);
-    langloopThread->start();
     if(!self)
         self = this;
 }
 
 QSystemInfoPrivate::~QSystemInfoPrivate()
 {
-    langloopThread->quit();
-    langloopThread->wait();
+    if(langloopThread->isRunning()) {
+        langloopThread->quit();
+        langloopThread->wait();
+    }
 }
 
 QString QSystemInfoPrivate::currentLanguage() const
@@ -304,6 +334,7 @@
 
 QStringList QSystemInfoPrivate::availableLanguages() const
 {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
     NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
     NSArray* languages = [defs objectForKey:@"AppleLanguages"];
@@ -315,6 +346,7 @@
      if(!returnList.contains(language))
          returnList << language;
     }
+    [pool drain];
     return returnList;
 }
 
@@ -323,6 +355,23 @@
     Q_EMIT currentLanguageChanged(lang);
 }
 
+void QSystemInfoPrivate::connectNotify(const char *signal)
+{
+    if (QLatin1String(signal) == SIGNAL(currentLanguageChanged(QString))) {
+        langloopThread = new QLangLoopThread(this);
+        langloopThread->start();
+    }
+}
+
+void QSystemInfoPrivate::disconnectNotify(const char *signal)
+{
+    if (QLatin1String(signal) == SIGNAL(currentLanguageChanged(QString))) {
+        if(langloopThread->isRunning()) {
+            langloopThread->quit();
+            langloopThread->wait();
+        }
+    }
+}
 
 QString QSystemInfoPrivate::version(QSystemInfo::Version type,  const QString &parameter)
 {
@@ -397,32 +446,35 @@
         break;
     case QSystemInfo::MemcardFeature:
         {
-
+// IOSCSIPeripheralDeviceType0E
+            if(hasIOServiceMatching("IOUSBMassStorageClass")) {
+                featureSupported = true;
+            }
         }
         break;
     case QSystemInfo::UsbFeature:
         {
-            if(hasIOServiceMatching(kIOUSBDeviceClassName)) {
+            if(hasIOServiceMatching("AppleUSBOHCI")) {
+                featureSupported = true;
+            }
+            if(hasIOServiceMatching("AppleUSBEHCI")) {
                 featureSupported = true;
             }
         }
         break;
     case QSystemInfo::VibFeature:
         {
-
         }
         break;
     case QSystemInfo::WlanFeature:
         {
             if(!QSystemNetworkInfoPrivate::instance()->interfaceForMode(QSystemNetworkInfo::WlanMode).name().isEmpty()) {
                 featureSupported = true;
-
             }
         }
         break;
     case QSystemInfo::SimFeature:
         {
-
         }
         break;
     case QSystemInfo::LocationFeature:
@@ -438,7 +490,10 @@
         break;
     case QSystemInfo::VideoOutFeature:
         {
-
+            ComponentDescription description = {'vout', 0, 0, 0L, 1L << 0};
+            if( ::CountComponents(&description) > 0) {
+                featureSupported = true;
+            }
         }
         break;
     case QSystemInfo::HapticsFeature:
@@ -453,9 +508,17 @@
 QSystemNetworkInfoPrivate *QSystemNetworkInfoPrivate::self = 0;
 
 
-void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef /*changedKeys*/, void */*info*/)
+void networkChangeCallback(SCDynamicStoreRef /*dynamicStore*/, CFArrayRef changedKeys, void */*networkConfigurationManagerPrivate*/)
 {
-    QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->getDefaultInterface();
+// NSLog(@"changed keys %@", changedKeys);
+    QStringList keyList = nsarrayToQStringList((void*)changedKeys);
+    if(keyList.contains("State:/Network/Global/DNS")) {
+    }
+    if(keyList.contains("State:/Network/Global/IPv4")) {
+        QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->ethernetChanged();
+        QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->getDefaultInterface();
+    }
+
     return;
 }
 
@@ -485,19 +548,21 @@
     mutex.unlock();
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
-    QLangListener *listener;
-    listener = [[QLangListener alloc] init];
+    QtMLangListener *listener;
+    listener = [[QtMLangListener alloc] init];
 
     NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
     while (keepRunning &&
         [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: loopUntil]) {
         loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
     }
-  //  [listener release]; //crash
     [pool release];
 #endif
 }
 
+#ifdef MAC_SDK_10_6
+QtMNSListener *listener;
+#endif
 
 QRunLoopThread::QRunLoopThread(QObject *parent)
     :QThread(parent)
@@ -506,38 +571,40 @@
 
 QRunLoopThread::~QRunLoopThread()
 {
-    CFRelease(storeSession);
-    CFRelease(runloopSource);
+#ifdef MAC_SDK_10_6
+    [listener dealloc];
+#endif
 }
 
 void QRunLoopThread::quit()
 {
-
+    CFRelease(runloopSource);
     mutex.lock();
     keepRunning = false;
     mutex.unlock();
+    CFRelease(storeSession);
 }
 
+
 void QRunLoopThread::run()
 {
 #ifdef MAC_SDK_10_6
 
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     startNetworkChangeLoop();
+    delegate = [[RemoteDeviceRSSIHostControllerDelegate alloc] init];
 
     mutex.lock();
     keepRunning = true;
     mutex.unlock();
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
-    QNSListener *listener;
-    listener = [[QNSListener alloc] init];
+    listener = [[QtMNSListener alloc] init];
 
     NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
     while (keepRunning &&
         [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: loopUntil]) {
         loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
     }
-  //  [listener release]; //crash
     [pool release];
 #endif
 }
@@ -546,8 +613,8 @@
 {
     storeSession = NULL;
 
-    SCDynamicStoreContext dynStoreContext = { 0, (void *)storeSession, NULL, NULL, NULL };
-    storeSession  = SCDynamicStoreCreate(NULL,
+    SCDynamicStoreContext dynStoreContext = { 0, this /*(void *)storeSession*/, NULL, NULL, NULL };
+    storeSession = SCDynamicStoreCreate(NULL,
                                  CFSTR("networkChangeCallback"),
                                  networkChangeCallback,
                                  &dynStoreContext);
@@ -562,6 +629,33 @@
     patternsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
     CFStringRef storeKey;
+
+    storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                     kSCDynamicStoreDomainState,
+                                                     kSCEntNetLink);
+    CFArrayAppendValue(notificationKeys, storeKey);
+    CFRelease(storeKey);
+
+    storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                      kSCDynamicStoreDomainState,
+                                                      kSCCompAnyRegex,
+                                                      kSCEntNetLink);
+    CFArrayAppendValue(patternsArray, storeKey);
+    CFRelease(storeKey);
+
+    storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                     kSCDynamicStoreDomainState,
+                                                     kSCEntNetDNS);
+    CFArrayAppendValue(notificationKeys, storeKey);
+    CFRelease(storeKey);
+
+    storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                      kSCDynamicStoreDomainState,
+                                                      kSCCompAnyRegex,
+                                                      kSCEntNetDNS);
+    CFArrayAppendValue(patternsArray, storeKey);
+    CFRelease(storeKey);
+
     storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
                                                      kSCDynamicStoreDomainState,
                                                      kSCEntNetIPv4);
@@ -588,7 +682,7 @@
     runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0);
     if (!runloopSource) {
         qWarning() << "runloop source error:"<< SCErrorString(SCError());
-        CFRelease(storeSession );
+        CFRelease(storeSession);
         return;
     }
 
@@ -604,12 +698,14 @@
     qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
     qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
 #ifdef MAC_SDK_10_6
-    runloopThread = new QRunLoopThread(this);
-    runloopThread->start();
+if([[CWInterface supportedInterfaces] count] > 0 ) {
+        hasWifi = true;
+    } else {
+        hasWifi = false;
+    }
 #endif
     rssiTimer = new QTimer(this);
 
-    connect(rssiTimer, SIGNAL(timeout()), this, SLOT(rssiTimeout()));
     if(!self)
         self = this;
     QTimer::singleShot(200, this, SLOT(primaryInterface()));
@@ -618,8 +714,11 @@
 QSystemNetworkInfoPrivate::~QSystemNetworkInfoPrivate()
 {
 #ifdef MAC_SDK_10_6
-    runloopThread->quit();
-    runloopThread->wait();
+    if(hasWifi && runloopThread->isRunning()) {
+        runloopThread->quit();
+        runloopThread->wait();
+        [delegate release];
+    }
 #endif
 }
 
@@ -628,6 +727,41 @@
     defaultInterface = getDefaultInterface();
 }
 
+void QSystemNetworkInfoPrivate::connectNotify(const char *signal)
+{
+    if (QLatin1String(signal) == SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int))) {
+        connect(rssiTimer, SIGNAL(timeout()), this, SLOT(rssiTimeout()));
+        rssiTimer->start(5000);
+    }
+    if (QLatin1String(signal) == SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString))
+        || QLatin1String(signal) == SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode, QSystemNetworkInfo::NetworkStatus))) {
+#ifdef MAC_SDK_10_6
+        if(hasWifi) {
+            runloopThread = new QRunLoopThread(this);
+            runloopThread->start();
+        }
+#endif
+    }
+}
+
+void QSystemNetworkInfoPrivate::disconnectNotify(const char *signal)
+{
+    if (QLatin1String(signal) == SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int))) {
+        rssiTimer->stop();
+        disconnect(rssiTimer, SIGNAL(timeout()), this, SLOT(rssiTimeout()));
+    }
+    if (QLatin1String(signal) == SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString))
+        || QLatin1String(signal) == SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode, QSystemNetworkInfo::NetworkStatus))) {
+#ifdef MAC_SDK_10_6
+        if(hasWifi && runloopThread->isRunning()) {
+            runloopThread->quit();
+            runloopThread->wait();
+            [delegate release];
+        }
+#endif
+    }
+}
+
 QSystemNetworkInfo::NetworkMode QSystemNetworkInfoPrivate::modeForInterface(QString interfaceName)
 {
     QSystemNetworkInfo::NetworkMode mode = QSystemNetworkInfo::UnknownMode;
@@ -690,17 +824,15 @@
              defaultInterface = interfaceName;
         }
     }
-//    qWarning() << __FUNCTION__ << interfaceName;
+
     return interfaceName;
 }
 
 void QSystemNetworkInfoPrivate::rssiTimeout()
 {
-    networkStatus(QSystemNetworkInfo::WlanMode);
     networkSignalStrength(QSystemNetworkInfo::WlanMode);
 }
 
-
 bool QSystemNetworkInfoPrivate::isInterfaceActive(const char* netInterface)
 {
     struct ifmediareq ifm;
@@ -715,6 +847,21 @@
     return false;
 }
 
+void QSystemNetworkInfoPrivate::ethernetChanged()
+{
+    QSystemNetworkInfo::NetworkStatus status = QSystemNetworkInfo::NoNetworkAvailable;
+    int carrier = 0;
+
+    if(isInterfaceActive(interfaceForMode(QSystemNetworkInfo::EthernetMode).name().toLocal8Bit())) {
+        status = QSystemNetworkInfo::Connected;
+        carrier = 100;
+    }
+    Q_EMIT networkStatusChanged(QSystemNetworkInfo::EthernetMode,status);
+    Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::EthernetMode,carrier);
+    Q_EMIT networkNameChanged(QSystemNetworkInfo::EthernetMode, networkName(QSystemNetworkInfo::EthernetMode));
+    Q_EMIT networkModeChanged(modeForInterface(getDefaultInterface()));
+}
+
 QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoPrivate::networkStatus(QSystemNetworkInfo::NetworkMode mode)
 {
     QSystemNetworkInfo::NetworkStatus status = QSystemNetworkInfo::NoNetworkAvailable;
@@ -728,31 +875,34 @@
     case QSystemNetworkInfo::WlanMode:
         {
 #ifdef MAC_SDK_10_6
-            NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
-            CWInterface *wifiInterface = [CWInterface interfaceWithName:  qstringToNSString(interfaceForMode(mode).name())];
+            if(hasWifi) {
+                NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+                CWInterface *wifiInterface = [CWInterface interfaceWithName:  qstringToNSString(interfaceForMode(mode).name())];
+
+                if([wifiInterface power]) {
+                    if(!rssiTimer->isActive())
+                        rssiTimer->start(5000);
+                }  else {
+                    if(rssiTimer->isActive())
+                        rssiTimer->stop();
+                }
 
-            if([wifiInterface power]) {
-                if(!rssiTimer->isActive())
-                    rssiTimer->start(1000);
-            }  else {
-                if(rssiTimer->isActive())
-                    rssiTimer->stop();
+                switch([[wifiInterface interfaceState]intValue]) {
+                case  kCWInterfaceStateInactive:
+                    status = QSystemNetworkInfo::NoNetworkAvailable;
+                    break;
+                case kCWInterfaceStateScanning:
+                case kCWInterfaceStateAuthenticating:
+                case kCWInterfaceStateAssociating:
+                    status = QSystemNetworkInfo::Searching;
+                    break;
+                case kCWInterfaceStateRunning:
+                    status = QSystemNetworkInfo::Connected;
+                    break;
+                };
+                [autoreleasepool release];
             }
 
-            switch([[wifiInterface interfaceState]intValue]) {
-            case  kCWInterfaceStateInactive:
-                status = QSystemNetworkInfo::NoNetworkAvailable;
-                break;
-            case kCWInterfaceStateScanning:
-            case kCWInterfaceStateAuthenticating:
-            case kCWInterfaceStateAssociating:
-                status = QSystemNetworkInfo::Searching;
-                break;
-            case kCWInterfaceStateRunning:
-                status = QSystemNetworkInfo::Connected;
-                break;
-            };
-            [autoreleasepool release];
 #else
             if(isInterfaceActive(interfaceForMode(mode).name().toLatin1())) {
                 status = QSystemNetworkInfo::Connected;
@@ -762,7 +912,7 @@
         break;
     case QSystemNetworkInfo::EthernetMode:
         {
-            if(networkSignalStrength(mode) == 100) {
+            if(isInterfaceActive(interfaceForMode(mode).name().toLatin1())) {
                 return QSystemNetworkInfo::Connected;
             } else {
                 return QSystemNetworkInfo::NoNetworkAvailable;
@@ -794,41 +944,43 @@
     case QSystemNetworkInfo::WlanMode:
         {
             int signalQuality = 0;
+            if(hasWifi) {
 #ifdef MAC_SDK_10_6
-            NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
-            QString name = interfaceForMode(mode).name();
-            CWInterface *wifiInterface = [CWInterface interfaceWithName:qstringToNSString(name)];
+                NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+                QString name = interfaceForMode(mode).name();
+                CWInterface *wifiInterface = [CWInterface interfaceWithName:qstringToNSString(name)];
 
-            if([wifiInterface power]) {
-                if(!rssiTimer->isActive())
-                    rssiTimer->start(1000);
-            }  else {
-                if(rssiTimer->isActive())
-                    rssiTimer->stop();
-            }
+                if([wifiInterface power]) {
+                    if(!rssiTimer->isActive())
+                        rssiTimer->start(5000);
+                }  else {
+                    if(rssiTimer->isActive())
+                        rssiTimer->stop();
+                }
 
-            int rssiSignal = [[wifiInterface rssi] intValue];
+                int rssiSignal = [[wifiInterface rssi] intValue];
 
-            if(rssiSignal !=0 ) {
-                int maxRssi = -40;
-                int minRssi = [[wifiInterface noise] intValue];
-                signalQuality = ( 100 * (maxRssi - minRssi) * (maxRssi - minRssi) - (maxRssi - rssiSignal) *
-                                  (15 * (maxRssi - minRssi) + 62 * (maxRssi - rssiSignal)) ) /
-                                ((maxRssi - minRssi) * (maxRssi - minRssi));
+                if(rssiSignal !=0 ) {
+                    int maxRssi = -40;
+                    int minRssi = [[wifiInterface noise] intValue];
+                    signalQuality = ( 100 * (maxRssi - minRssi) * (maxRssi - minRssi) - (maxRssi - rssiSignal) *
+                                      (15 * (maxRssi - minRssi) + 62 * (maxRssi - rssiSignal)) ) /
+                                    ((maxRssi - minRssi) * (maxRssi - minRssi));
 
-            } else {
-                signalQuality = 0;
+                } else {
+                    signalQuality = 0;
+                }
+
+                if(signalStrengthCache != signalQuality) {
+                    if(signalStrengthCache == 0) {
+                        networkStatus(QSystemNetworkInfo::WlanMode);
+                    }
+                    signalStrengthCache = signalQuality;
+                    Q_EMIT networkSignalStrengthChanged(mode, signalQuality);
+                }
+                [autoreleasepool release];
+#endif
             }
-
-            if(signalStrengthCache != signalQuality) {
-                if(signalStrengthCache == 0) {
-                    networkStatus(QSystemNetworkInfo::WlanMode);
-                }
-                signalStrengthCache = signalQuality;
-                Q_EMIT networkSignalStrengthChanged(mode, signalQuality);
-            }
-            [autoreleasepool release];
-#endif
             return signalQuality;
         }
         break;
@@ -839,9 +991,32 @@
         }
         break;
     case QSystemNetworkInfo::BluetoothMode:
-        // link quality for which device?
-        // [controller readRSSIForDevice: blah?];
-        break;
+        {
+#ifdef  MAC_SDK_10_6
+            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+            IOBluetoothHostController* controller = IOBluetoothHostController.defaultController;
+            if (controller != NULL) {
+
+                NSArray *devices = [IOBluetoothDevice recentDevices:0];
+                for ( IOBluetoothDevice *btDevice in devices ) {
+                    if([btDevice isConnected]) {
+                        qWarning() <<"IOBluetoothDevice connected"<< nsstringToQString([btDevice getName]);
+//                        delegate = [[RemoteDeviceRSSIHostControllerDelegate alloc] init];
+                        [delegate retain];
+                        [controller setDelegate:delegate];
+                        IOReturn rc = [controller readRSSIForDevice:btDevice];
+                        if (rc != noErr) {
+                            qWarning() << "ERROR: call readRSSIForDevice failed";
+                        }
+//[delegate release];
+                    }
+                }
+//              [devices release];
+  //  [controller release];
+            }
+            [pool release];
+#endif
+        }
     case QSystemNetworkInfo::WimaxMode:
         break;
     default:
@@ -862,7 +1037,16 @@
 
 QString QSystemNetworkInfoPrivate::currentMobileCountryCode()
 {
-    return "";
+    QString cmcc;
+#if defined(MAC_SDK_10_6)
+    if(hasWifi) {
+        CWInterface *primary = [CWInterface interfaceWithName:nil];
+        if([primary power]) {
+            cmcc = nsstringToQString([primary countryCode]);
+        }
+    }
+#endif
+    return cmcc;
 }
 
 QString QSystemNetworkInfoPrivate::currentMobileNetworkCode()
@@ -882,6 +1066,9 @@
 
 QString QSystemNetworkInfoPrivate::networkName(QSystemNetworkInfo::NetworkMode mode)
 {
+    if(networkStatus(mode) == QSystemNetworkInfo::NoNetworkAvailable) {
+        return "";
+    }
     switch(mode) {
         case QSystemNetworkInfo::GsmMode:
         break;
@@ -891,16 +1078,32 @@
         break;
     case QSystemNetworkInfo::WlanMode:
         {
+            QString name = interfaceForMode(mode).name();
 #ifdef MAC_SDK_10_6
-            QString name = interfaceForMode(mode).name();
-            CWInterface *wifiInterface = [CWInterface interfaceWithName:qstringToNSString(name)];
-            return nsstringToQString([wifiInterface ssid]);
+            if(hasWifi) {
+                CWInterface *wifiInterface = [CWInterface interfaceWithName:qstringToNSString(name)];
+                return nsstringToQString([wifiInterface ssid]);
+            }
 #else
+            SCDynamicStoreRef theDynamicStore;
+            theDynamicStore = SCDynamicStoreCreate(nil, CFSTR("FindCurrentInterfaceAndIP"), nil, nil);
+
+            NSMutableString *interfaceName = [NSMutableString string];
+            NSString *airportPath = [NSString stringWithFormat:@"State:/Network/Interface/%@/AirPort", qstringToNSString(name)];
+
+            CFDictionaryRef airportPlist = (const __CFDictionary*)SCDynamicStoreCopyValue(theDynamicStore, (CFStringRef)airportPath);
+
+            CFRelease(theDynamicStore);
+
+            return nsstringToQString([(NSDictionary *)airportPlist valueForKey:@"SSID_STR"]);
 #endif
         }
         break;
     case QSystemNetworkInfo::EthernetMode:
         {
+            if(isInterfaceActive(interfaceForMode(mode).name().toLocal8Bit())) {
+                return QHostInfo::localDomainName();
+            }
         }
         break;
     case QSystemNetworkInfo::BluetoothMode:
@@ -915,39 +1118,37 @@
 
 QString QSystemNetworkInfoPrivate::macAddress(QSystemNetworkInfo::NetworkMode mode)
 {
-    QString mac;
-#ifdef  MAC_SDK_10_6
-    if(mode == QSystemNetworkInfo::BluetoothMode) {
-        NSString *addy;
-        IOBluetoothHostController* controller = [IOBluetoothHostController defaultController];
-        if (controller != NULL) {
-            addy = [controller addressAsString];
-            mac = QLatin1String([addy UTF8String]);
-            mac.replace("-",":");
-        }
-        return mac;
-    }
-#endif
-    mac = interfaceForMode(mode).hardwareAddress();
-    return mac;
+    return interfaceForMode(mode).hardwareAddress();
 }
 
 QNetworkInterface QSystemNetworkInfoPrivate::interfaceForMode(QSystemNetworkInfo::NetworkMode mode)
 {
     QNetworkInterface netInterface;
-
     CFArrayRef interfaceArray = SCNetworkInterfaceCopyAll(); //10.4
     CFStringRef iName;
     CFStringRef type;
-
     for ( long i = 0; i < CFArrayGetCount(interfaceArray); i++) {
         SCNetworkInterfaceRef thisInterface =  (SCNetworkInterfaceRef ) CFArrayGetValueAtIndex(interfaceArray, i);
         type = SCNetworkInterfaceGetInterfaceType(thisInterface);
         iName = SCNetworkInterfaceGetBSDName(thisInterface);
+
         if (type != NULL) {
             if (CFEqual(type, kSCNetworkInterfaceTypeBluetooth) && mode == QSystemNetworkInfo::BluetoothMode) {
                 netInterface = QNetworkInterface::interfaceFromName(stringFromCFString(iName));
-                break;
+                // workaround for null MAC from SCNetworkInterfaceGetHardwareAddressString and bogus BSD name here
+#ifdef  MAC_SDK_10_6
+                IOBluetoothHostController* controller = IOBluetoothHostController.defaultController;
+                QString macbtMac = nsstringToQString([controller addressAsString]).replace("-",":").toUpper();
+                if(!macbtMac.isEmpty()) {
+                    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
+                    foreach(const QNetworkInterface thisNetInterface, interfaces) {
+                        if( thisNetInterface.hardwareAddress() == macbtMac) {
+                            netInterface = thisNetInterface;
+                            break;
+                        }
+                    }
+                }
+#endif
             } else if (CFEqual(type, kSCNetworkInterfaceTypeEthernet) && mode == QSystemNetworkInfo::EthernetMode) {
                 netInterface = QNetworkInterface::interfaceFromName(stringFromCFString(iName));
                 break;
@@ -961,10 +1162,9 @@
     return netInterface;
 }
 
-void QSystemNetworkInfoPrivate::networkChanged(const QString &notification, const QString interfaceName)
+void QSystemNetworkInfoPrivate::wifiNetworkChanged(const QString &notification, const QString interfaceName)
 {
-    qWarning() << __FUNCTION__ << notification;
-   // runloopThread->stopLoop();
+    getDefaultInterface();
 
     if(notification == QLatin1String("SSID_CHANGED_NOTIFICATION")) {
         Q_EMIT networkNameChanged(QSystemNetworkInfo::WlanMode, networkName(QSystemNetworkInfo::WlanMode));
@@ -979,20 +1179,25 @@
         CWInterface *wifiInterface = [CWInterface interfaceWithName:  qstringToNSString(interfaceName)];
         if([wifiInterface power]) {
             if(!rssiTimer->isActive()) {
-                qWarning() << __FUNCTION__ << "start timer";
-                rssiTimer->start(1000);
+                rssiTimer->start(5000);
+
             }
         }  else {
             if(rssiTimer->isActive()) {
-                qWarning() << __FUNCTION__ << "stop timer";
-            rssiTimer->stop();
-        }
+                rssiTimer->stop();
+            }
+            Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::WlanMode, 0);
         }
 #endif
     }
- //   runloopThread->start();
 }
 
+QSystemNetworkInfo::NetworkMode QSystemNetworkInfoPrivate::currentMode()
+{
+    return modeForInterface(getDefaultInterface());
+}
+
+
 QSystemDisplayInfoPrivate::QSystemDisplayInfoPrivate(QObject *parent)
         : QObject(parent)
 {
@@ -1122,8 +1327,9 @@
                 if (volumeParmeters.vMServerAdr == 0) { //local drive
                     io_service_t ioService;
                     ioService = IOServiceGetMatchingService(kIOMasterPortDefault,
-                                                            IOBSDNameMatching(kIOMasterPortDefault, 0,
-                                                                              (char *)volumeParmeters.vMDeviceID));
+                                                            IOBSDNameMatching(kIOMasterPortDefault,
+                                                            0,
+                                                            (char *)volumeParmeters.vMDeviceID));
 
                     if (IOObjectConformsTo(ioService, kIOMediaClass)) {
                         CFTypeRef wholeMedia;
@@ -1134,12 +1340,16 @@
                                                                      0);
 
                         if((volumeParmeters.vMExtendedAttributes & (1L << bIsRemovable))) {
+                            IOObjectRelease(ioService);
                             CFRelease(wholeMedia);
                             return QSystemStorageInfo::RemovableDrive;
                         } else {
+                            IOObjectRelease(ioService);
+                            CFRelease(wholeMedia);
                             return QSystemStorageInfo::InternalDrive;
                         }
                     }
+                    IOObjectRelease(ioService);
                 } else {
                     return QSystemStorageInfo::RemoteDrive;
                 }
@@ -1267,12 +1477,12 @@
 
 QString QSystemDeviceInfoPrivate::imei()
 {
-        return "Sim Not Available";
+    return "";
 }
 
 QString QSystemDeviceInfoPrivate::imsi()
 {
-        return "Sim Not Available";
+    return "";
 }
 
 QString QSystemDeviceInfoPrivate::manufacturer()
@@ -1322,7 +1532,7 @@
     }
 
     CFRelease(powerSourcesInfoBlob);
-    CFRelease(powerSourcesList);    
+    CFRelease(powerSourcesList);
 
     if(batteryLevelCache != level) {
         batteryLevelCache = level;