void DeviceKitLister::DBusDeviceAdded(const QDBusObjectPath& path) {
  DeviceData data = ReadDeviceData(path);
  if (!data.suitable) return;

  {
    QMutexLocker l(&mutex_);
    device_data_[data.unique_id()] = data;
  }

  emit DeviceAdded(data.unique_id());
}
void DeviceKitLister::Init() {
  interface_.reset(new OrgFreedesktopUDisksInterface(
      OrgFreedesktopUDisksInterface::staticInterfaceName(),
      "/org/freedesktop/UDisks", QDBusConnection::systemBus()));

  // Get all the devices currently attached
  QDBusPendingReply<QList<QDBusObjectPath> > reply =
      interface_->EnumerateDevices();
  reply.waitForFinished();

  if (!reply.isValid()) {
    qLog(Warning) << "Error enumerating DeviceKit-disks devices:"
                  << reply.error().name() << reply.error().message();
    interface_.reset();
    return;
  }

  // Listen for changes
  connect(interface_.get(), SIGNAL(DeviceAdded(QDBusObjectPath)),
          SLOT(DBusDeviceAdded(QDBusObjectPath)));
  connect(interface_.get(), SIGNAL(DeviceRemoved(QDBusObjectPath)),
          SLOT(DBusDeviceRemoved(QDBusObjectPath)));
  connect(interface_.get(), SIGNAL(DeviceChanged(QDBusObjectPath)),
          SLOT(DBusDeviceChanged(QDBusObjectPath)));

  // Get information about each one
  QMap<QString, DeviceData> device_data;
  for (const QDBusObjectPath& path : reply.value()) {
    DeviceData data = ReadDeviceData(path);
    if (data.suitable) device_data[data.unique_id()] = data;
  }

  // Update the internal cache
  {
    QMutexLocker l(&mutex_);
    device_data_ = device_data;
  }

  // Notify about the changes
  for (const QString& id : device_data.keys()) {
    emit DeviceAdded(id);
  }
}
void DeviceKitLister::DBusDeviceChanged(const QDBusObjectPath &path) {
  bool already_known = false;
  {
    QMutexLocker l(&mutex_);
    already_known = !FindUniqueIdByPath(path).isNull();
  }

  DeviceData data = ReadDeviceData(path);

  if (already_known && !data.suitable)
    DBusDeviceRemoved(path);
  else if (!already_known && data.suitable)
    DBusDeviceAdded(path);
  else if (already_known && data.suitable) {
    {
      QMutexLocker l(&mutex_);
      device_data_[data.unique_id()] = data;
    }
    emit DeviceChanged(data.unique_id());
  }
}
//!  Does the following:
//!   - Loads device name from Codewarrior
//!   - Loads corresponding device data from database
//!
//!  @return error code, see \ref USBDM_ErrorCode
//!
USBDM_ErrorCode getDeviceData(DeviceData &deviceData) {
   LOGGING;
   DiReturnT       diRC = DI_OK;
   string          deviceName;
   int value;

   // Device name
   diRC = mtwksGetStringValue(processorKey, deviceName);
   if ((diRC != DI_OK) || (deviceName == emptyString)) {
      Logging::print("Device name not set\n");
      Logging::print("key = %s\n", processorKey.c_str());
      return  BDM_RC_UNKNOWN_DEVICE;
   }
   Logging::print("Device name = \'%s\'\n", (const char *)deviceName.c_str());

   DeviceDataBase deviceDataBase;
   try {
      deviceDataBase.loadDeviceData();
   }
   catch (MyException &exception) {
      Logging::print("Failed to load device database\n");
      string("Failed to load device database\nReason: ")+exception.what();
      displayDialogue((string("Failed to load device database\nReason: ")+exception.what()).c_str(),
                   "Error loading devices",
                   wxOK);
      return BDM_RC_DEVICE_DATABASE_ERROR;
   }
   catch (...){
      Logging::print("Failed to load device database\n");
      displayDialogue("Failed to load device database\n",
                      "Error loading devices",
                      wxOK);
      return BDM_RC_DEVICE_DATABASE_ERROR;
   }
   DeviceDataConstPtr dev = deviceDataBase.findDeviceFromName(deviceName);
   if (dev == NULL) {
      Logging::print("Unknown device\n");
      mtwksDisplayLine("Unrecognised device - using default settings");
      dev = deviceDataBase.getDefaultDevice();
//      return BDM_RC_UNKNOWN_DEVICE;
   }
   else {
      Logging::print("Found device \'%s\' in database\n", (const char *)dev->getTargetName().c_str());
   }
   deviceData = *dev;
   getAttribute(KeyTrimTargetClock, value, 0);
   if (value != 0) {
      getAttribute(KeyClockTrimFrequency, value, deviceData.getClockTrimFreq());
      if (value == 0) {
         value = deviceData.getClockTrimFreq();
      }
      deviceData.setClockTrimFreq(value);
      getAttribute(KeyClockTrimNVAddress, value, deviceData.getClockTrimNVAddress());
      if (value == 0) {
         value = deviceData.getClockTrimNVAddress();
      }
      deviceData.setClockTrimNVAddress(value);
   }
   else {
      deviceData.setClockTrimFreq(0);
   }
   int eraseOptions;
   getAttribute(KeyEraseMethod, eraseOptions, (int)DeviceData::eraseMass);
   deviceData.setEraseOption((DeviceData::EraseOptions)eraseOptions);

   int securityOption;
   getAttribute(KeySecurity, securityOption, (int)SEC_SMART);
   deviceData.setSecurity((SecurityOptions_t)securityOption);

   return BDM_RC_OK;
}