/**
   * @param applicationOperationDevice holds the information needs to retrieve device list.
   * @return List of devices
   * @throws MobileApplicationException
   */
  public List<Device> getDevices(ApplicationOperationDevice applicationOperationDevice)
      throws MobileApplicationException {

    List<Device> devices;
    try {
      List<org.wso2.carbon.device.mgt.common.Device> deviceList =
          MDMServiceAPIUtils.getDeviceManagementService(applicationOperationDevice.getTenantId())
              .getDevicesOfUser(applicationOperationDevice.getCurrentUser().getUsername());
      devices = new ArrayList<>(deviceList.size());
      if (log.isDebugEnabled()) {
        log.debug("device list got from mdm " + deviceList.toString());
      }
      for (org.wso2.carbon.device.mgt.common.Device commonDevice : deviceList) {
        if (MDMAppConstants.ACTIVE.equals(
            commonDevice.getEnrolmentInfo().getStatus().toString().toLowerCase())) {
          Device device = new Device();
          org.wso2.carbon.appmgt.mobile.beans.DeviceIdentifier deviceIdentifier =
              new org.wso2.carbon.appmgt.mobile.beans.DeviceIdentifier();
          deviceIdentifier.setId(commonDevice.getDeviceIdentifier());
          deviceIdentifier.setType(commonDevice.getType());
          device.setDeviceIdentifier(deviceIdentifier);
          device.setName(commonDevice.getName());
          device.setModel(commonDevice.getName());
          device.setType(MDMAppConstants.MOBILE_DEVICE);
          String imgUrl;
          if (MDMAppConstants.ANDROID.equalsIgnoreCase(commonDevice.getType())) {
            imgUrl =
                String.format(
                    applicationOperationDevice.getConfigParams().get(MDMAppConstants.IMAGE_URL),
                    MDMAppConstants.NEXUS);
          } else if (MDMAppConstants.IOS.equalsIgnoreCase(commonDevice.getType())) {
            imgUrl =
                String.format(
                    applicationOperationDevice.getConfigParams().get(MDMAppConstants.IMAGE_URL),
                    MDMAppConstants.IPHONE);
          } else {
            imgUrl =
                String.format(
                    applicationOperationDevice.getConfigParams().get(MDMAppConstants.IMAGE_URL),
                    MDMAppConstants.NONE);
          }
          device.setImage(imgUrl);
          device.setPlatform(commonDevice.getType());
          devices.add(device);
        }
      }
    } catch (DeviceManagementException e) {
      logError("Error While retrieving Device List.", e);
      throw new MobileApplicationException(e.getMessage());
    }
    return devices;
  }
  /**
   * {@inheritDoc} VirtualFirealarm device-type specific implementation to process incoming
   * messages. This is the specific method signature of the overloaded "processIncomingMessage"
   * method that gets called from the messageArrived() callback of the "MQTTTransportHandler".
   */
  @Override
  public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) {
    if (messageParams.length != 0) {
      // owner and the deviceId are extracted from the MQTT topic to which the message was received.
      // <Topic> = [ServerName/Owner/DeviceType/DeviceId/"publisher"]
      String topic = messageParams[0];
      String[] topicParams = topic.split("/");
      String deviceId = topicParams[2];
      if (log.isDebugEnabled()) {
        log.debug("Received MQTT message for: [DEVICE.ID-" + deviceId + "]");
      }

      String actualMessage;
      try {
        // the hash-code of the deviceId is used as the alias for device certificates during SCEP
        // enrollment.
        // hence, the same is used here to fetch the device-specific-certificate from the key store.
        PublicKey clientPublicKey = VirtualFireAlarmServiceUtils.getDevicePublicKey(deviceId);
        PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();

        // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":<MESSAGE>,
        // "Sig":<SIGNATURE>}
        actualMessage =
            VirtualFireAlarmServiceUtils.extractMessageFromPayload(
                mqttMessage.toString(), serverPrivateKey, clientPublicKey);
        if (log.isDebugEnabled()) {
          log.debug("MQTT: Received Message [" + actualMessage + "] topic: [" + topic + "]");
        }

        if (actualMessage.contains("PUBLISHER")) {
          float temperature = Float.parseFloat(actualMessage.split(":")[2]);
          try {
            PrivilegedCarbonContext.startTenantFlow();
            PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
            DeviceManagementProviderService deviceManagementProviderService =
                (DeviceManagementProviderService)
                    ctx.getOSGiService(DeviceManagementProviderService.class, null);
            if (deviceManagementProviderService != null) {
              DeviceIdentifier identifier =
                  new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE);
              Device device = deviceManagementProviderService.getDevice(identifier);
              if (device != null) {
                String owner = device.getEnrolmentInfo().getOwner();
                ctx.setTenantDomain(MultitenantUtils.getTenantDomain(owner), true);
                ctx.setUsername(owner);
                if (!VirtualFireAlarmServiceUtils.publishToDAS(deviceId, temperature)) {
                  log.error("MQTT Subscriber: Publishing data to DAS failed.");
                }
              }
            }
          } catch (DeviceManagementException e) {
            log.error(
                "Failed to retreive the device managment service for device type "
                    + VirtualFireAlarmConstants.DEVICE_TYPE,
                e);
          } finally {
            PrivilegedCarbonContext.endTenantFlow();
          }
          if (log.isDebugEnabled()) {
            log.debug("MQTT Subscriber: Published data to DAS successfully.");
          }

        } else if (actualMessage.contains("TEMPERATURE")) {
          String temperatureValue = actualMessage.split(":")[1];
        }
      } catch (VirtualFireAlarmException e) {
        String errorMsg =
            "CertificateManagementService failure oo Signature-Verification/Decryption was unsuccessful.";
        log.error(errorMsg, e);
      }
    } else {
      String errorMsg =
          "MQTT message ["
              + mqttMessage.toString()
              + "] was received without the topic information.";
      log.warn(errorMsg);
    }
  }