diff --git a/src/appcommands.cpp b/src/appcommands.cpp
index 39fc7d5..0de30af 100644
--- a/src/appcommands.cpp
+++ b/src/appcommands.cpp
@@ -1,375 +1,375 @@
-/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-#include "xyz/openbmc_project/Common/error.hpp"
-
-#include <fstream>
-#include <ipmid/api.hpp>
-#include <ipmid/utils.hpp>
-#include <nlohmann/json.hpp>
-#include <phosphor-logging/log.hpp>
-#include <regex>
-#include <xyz/openbmc_project/Software/Activation/server.hpp>
-#include <xyz/openbmc_project/Software/Version/server.hpp>
-#include <xyz/openbmc_project/State/BMC/server.hpp>
-
-namespace ipmi
-{
-
-static void registerAPPFunctions() __attribute__((constructor));
-
-namespace Log = phosphor::logging;
-namespace Error = sdbusplus::xyz::openbmc_project::Common::Error;
-using Version = sdbusplus::xyz::openbmc_project::Software::server::Version;
-using Activation =
-    sdbusplus::xyz::openbmc_project::Software::server::Activation;
-using BMC = sdbusplus::xyz::openbmc_project::State::server::BMC;
-
-constexpr auto bmc_state_interface = "xyz.openbmc_project.State.BMC";
-constexpr auto bmc_state_property = "CurrentBMCState";
-
-namespace
-{
-static constexpr auto redundancyIntf =
-    "xyz.openbmc_project.Software.RedundancyPriority";
-static constexpr auto versionIntf = "xyz.openbmc_project.Software.Version";
-static constexpr auto activationIntf =
-    "xyz.openbmc_project.Software.Activation";
-static constexpr auto softwareRoot = "/xyz/openbmc_project/software";
-
-bool getCurrentBmcState()
-{
-    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
-
-    // Get the Inventory object implementing the BMC interface
-    ipmi::DbusObjectInfo bmcObject =
-        ipmi::getDbusObject(bus, bmc_state_interface);
-    auto variant =
-        ipmi::getDbusProperty(bus, bmcObject.second, bmcObject.first,
-                              bmc_state_interface, bmc_state_property);
-
-    return std::holds_alternative<std::string>(variant) &&
-           BMC::convertBMCStateFromString(std::get<std::string>(variant)) ==
-               BMC::BMCState::Ready;
-}
-
-bool getCurrentBmcStateWithFallback(const bool fallbackAvailability)
-{
-    try
-    {
-        return getCurrentBmcState();
-    }
-    catch (...)
-    {
-        // Nothing provided the BMC interface, therefore return whatever was
-        // configured as the default.
-        return fallbackAvailability;
-    }
-}
-/**
- * @brief Returns the Version info from primary s/w object
- *
- * Get the Version info from the active s/w object which is having high
- * "Priority" value(a smaller number is a higher priority) and "Purpose"
- * is "BMC" from the list of all s/w objects those are implementing
- * RedundancyPriority interface from the given softwareRoot path.
- *
- * @return On success returns the Version info from primary s/w object.
- *
- */
-std::string getActiveSoftwareVersionInfo()
-{
-    auto busp = getSdBus();
-
-    std::string revision{};
-    ipmi::ObjectTree objectTree;
-    try
-    {
-        objectTree =
-            ipmi::getAllDbusObjects(*busp, softwareRoot, redundancyIntf);
-    }
-    catch (sdbusplus::exception::SdBusError& e)
-    {
-        Log::log<Log::level::ERR>("Failed to fetch redundancy object from dbus",
-                                  Log::entry("INTERFACE=%s", redundancyIntf),
-                                  Log::entry("ERRMSG=%s", e.what()));
-    }
-
-    auto objectFound = false;
-    for (auto& softObject : objectTree)
-    {
-        auto service =
-            ipmi::getService(*busp, redundancyIntf, softObject.first);
-        auto objValueTree =
-            ipmi::getManagedObjects(*busp, service, softwareRoot);
-
-        auto minPriority = 0xFF;
-        for (const auto& objIter : objValueTree)
-        {
-            try
-            {
-                auto& intfMap = objIter.second;
-                auto& redundancyPriorityProps = intfMap.at(redundancyIntf);
-                auto& versionProps = intfMap.at(versionIntf);
-                auto& activationProps = intfMap.at(activationIntf);
-                auto priority =
-                    std::get<uint8_t>(redundancyPriorityProps.at("Priority"));
-                auto purpose =
-                    std::get<std::string>(versionProps.at("Purpose"));
-                auto activation =
-                    std::get<std::string>(activationProps.at("Activation"));
-                auto version =
-                    std::get<std::string>(versionProps.at("Version"));
-                if ((Version::convertVersionPurposeFromString(purpose) ==
-                     Version::VersionPurpose::BMC) &&
-                    (Activation::convertActivationsFromString(activation) ==
-                     Activation::Activations::Active))
-                {
-                    if (priority < minPriority)
-                    {
-                        minPriority = priority;
-                        objectFound = true;
-                        revision = std::move(version);
-                    }
-                }
-            }
-            catch (const std::exception& e)
-            {
-                Log::log<Log::level::ERR>(e.what());
-            }
-        }
-    }
-
-    if (!objectFound)
-    {
-        Log::log<Log::level::ERR>("Could not found an BMC software Object");
-    }
-
-    return revision;
-}
-
-typedef struct
-{
-    std::string platform;
-    uint8_t major;
-    uint8_t minor;
-    uint32_t buildNo;
-    std::string openbmcHash;
-    std::string metaHash;
-    std::string buildType;
-} MetaRevision;
-
-// Support both 2 solutions:
-// 1.Current solution  2.7.0-dev-533-g14dc00e79-5e7d997
-//   openbmcTag  2.7.0-dev
-//   BuildNo     533
-//   openbmcHash g14dc00e79
-//   MetaHasg    5e7d997
-//
-// 2.New solution  whtref-0.1-45-023125-a1295e-release
-//   IdStr        whtref
-//   Major        0
-//   Minor        1
-//   buildNo      45
-//   openbmcHash  023125
-//   MetaHash     a1295e
-//   BuildType    release/CI/<devloperId>
-std::optional<MetaRevision> convertIntelVersion(std::string& s)
-{
-    std::smatch results;
-    MetaRevision rev;
-    std::regex pattern1("(\\d+?).(\\d+?).\\d+?-\\w*?-(\\d+?)-(\\w+?)-(\\w+?)");
-    constexpr size_t matchedPhosphor = 6;
-    if (std::regex_match(s, results, pattern1))
-    {
-        if (results.size() == matchedPhosphor)
-        {
-            rev.platform = "whtref";
-            rev.major = static_cast<uint8_t>(std::stoi(results[1]));
-            rev.minor = static_cast<uint8_t>(std::stoi(results[2]));
-            rev.buildNo = static_cast<uint32_t>(std::stoi(results[3]));
-            rev.openbmcHash = results[4];
-            rev.metaHash = results[5];
-            rev.buildType = "release";
-            std::string versionString =
-                rev.platform + ":" + std::to_string(rev.major) + ":" +
-                std::to_string(rev.minor) + ":" + std::to_string(rev.buildNo) +
-                ":" + rev.openbmcHash + ":" + rev.metaHash + ":" +
-                rev.buildType;
-            phosphor::logging::log<phosphor::logging::level::INFO>(
-                versionString.c_str());
-            return rev;
-        }
-    }
-    constexpr size_t matchedIntel = 8;
-    std::regex pattern2(
-        "(\\w+?)-(\\d+?).(\\d+?)-(\\d+?)-(\\w+?)-(\\w+?)-(\\w+?)");
-    if (std::regex_match(s, results, pattern2))
-    {
-        if (results.size() == matchedIntel)
-        {
-            rev.platform = results[1];
-            rev.major = static_cast<uint8_t>(std::stoi(results[2]));
-            rev.minor = static_cast<uint8_t>(std::stoi(results[3]));
-            rev.buildNo = static_cast<uint32_t>(std::stoi(results[4]));
-            rev.openbmcHash = results[5];
-            rev.metaHash = results[6];
-            rev.buildType = results[7];
-            std::string versionString =
-                rev.platform + ":" + std::to_string(rev.major) + ":" +
-                std::to_string(rev.minor) + ":" + std::to_string(rev.buildNo) +
-                ":" + rev.openbmcHash + ":" + rev.metaHash + ":" +
-                rev.buildType;
-            phosphor::logging::log<phosphor::logging::level::INFO>(
-                versionString.c_str());
-            return rev;
-        }
-    }
-
-    return std::nullopt;
-}
-} // namespace
-auto ipmiAppGetDeviceId() -> ipmi::RspType<uint8_t, // Device ID
-                                           uint8_t, // Device Revision
-                                           uint8_t, // Firmware Revision Major
-                                           uint8_t, // Firmware Revision minor
-                                           uint8_t, // IPMI version
-                                           uint8_t, // Additional device support
-                                           uint24_t, // MFG ID
-                                           uint16_t, // Product ID
-                                           uint32_t  // AUX info
-                                           >
-{
-    std::optional<MetaRevision> rev;
-    static struct
-    {
-        uint8_t id;
-        uint8_t revision;
-        uint8_t fw[2];
-        uint8_t ipmiVer;
-        uint8_t addnDevSupport;
-        uint24_t manufId;
-        uint16_t prodId;
-        uint32_t aux;
-    } devId;
-    static bool dev_id_initialized = false;
-    static bool defaultActivationSetting = true;
-    const char* filename = "/usr/share/ipmi-providers/dev_id.json";
-    constexpr auto ipmiDevIdStateShift = 7;
-    constexpr auto ipmiDevIdFw1Mask = ~(1 << ipmiDevIdStateShift);
-
-    if (!dev_id_initialized)
-    {
-        try
-        {
-            auto version = getActiveSoftwareVersionInfo();
-            rev = convertIntelVersion(version);
-        }
-        catch (const std::exception& e)
-        {
-            Log::log<Log::level::ERR>(e.what());
-        }
-
-        if (rev.has_value())
-        {
-            // bit7 identifies if the device is available
-            // 0=normal operation
-            // 1=device firmware, SDR update,
-            // or self-initialization in progress.
-            // The availability may change in run time, so mask here
-            // and initialize later.
-            MetaRevision revision = rev.value();
-            devId.fw[0] = revision.major & ipmiDevIdFw1Mask;
-
-            revision.minor = (revision.minor > 99 ? 99 : revision.minor);
-            devId.fw[1] = revision.minor % 10 + (revision.minor / 10) * 16;
-            devId.aux = revision.buildNo;
-        }
-
-        // IPMI Spec version 2.0
-        devId.ipmiVer = 2;
-
-        std::ifstream devIdFile(filename);
-        if (devIdFile.is_open())
-        {
-            auto data = nlohmann::json::parse(devIdFile, nullptr, false);
-            if (!data.is_discarded())
-            {
-                devId.id = data.value("id", 0);
-                devId.revision = data.value("revision", 0);
-                devId.addnDevSupport = data.value("addn_dev_support", 0);
-                devId.manufId = data.value("manuf_id", 0);
-
-                try
-                {
-                    auto busp = getSdBus();
-                    const ipmi::DbusObjectInfo& object = ipmi::getDbusObject(
-                        *busp, "xyz.openbmc_project.Inventory.Item.Board",
-                        "/xyz/openbmc_project/inventory/system/board/",
-                        "Baseboard");
-                    const ipmi::Value& propValue = ipmi::getDbusProperty(
-                        *busp, object.second, object.first,
-                        "xyz.openbmc_project.Inventory.Item.Board",
-                        "ProductId");
-                    devId.prodId =
-                        static_cast<uint8_t>(std::get<uint64_t>(propValue));
-                }
-                catch (std::exception& e)
-                {
-                    devId.prodId = data.value("prod_id", 0);
-                }
-
-                // Set the availablitity of the BMC.
-                defaultActivationSetting = data.value("availability", true);
-
-                // Don't read the file every time if successful
-                dev_id_initialized = true;
-            }
-            else
-            {
-                Log::log<Log::level::ERR>("Device ID JSON parser failure");
-                return ipmi::responseUnspecifiedError();
-            }
-        }
-        else
-        {
-            Log::log<Log::level::ERR>("Device ID file not found");
-            return ipmi::responseUnspecifiedError();
-        }
-    }
-
-    // Set availability to the actual current BMC state
-    devId.fw[0] &= ipmiDevIdFw1Mask;
-    if (!getCurrentBmcStateWithFallback(defaultActivationSetting))
-    {
-        devId.fw[0] |= (1 << ipmiDevIdStateShift);
-    }
-
-    return ipmi::responseSuccess(
-        devId.id, devId.revision, devId.fw[0], devId.fw[1], devId.ipmiVer,
-        devId.addnDevSupport, devId.manufId, devId.prodId, devId.aux);
-}
-
-static void registerAPPFunctions(void)
-{
-    Log::log<Log::level::INFO>("Registering App commands");
-    // <Get Device ID>
-    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnApp,
-                          ipmi::app::cmdGetDeviceId, ipmi::Privilege::User,
-                          ipmiAppGetDeviceId);
-    return;
-}
-
-} // namespace ipmi
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <fstream>
+#include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/log.hpp>
+#include <regex>
+#include <xyz/openbmc_project/Software/Activation/server.hpp>
+#include <xyz/openbmc_project/Software/Version/server.hpp>
+#include <xyz/openbmc_project/State/BMC/server.hpp>
+
+namespace ipmi
+{
+
+static void registerAPPFunctions() __attribute__((constructor));
+
+namespace Log = phosphor::logging;
+namespace Error = sdbusplus::xyz::openbmc_project::Common::Error;
+using Version = sdbusplus::xyz::openbmc_project::Software::server::Version;
+using Activation =
+    sdbusplus::xyz::openbmc_project::Software::server::Activation;
+using BMC = sdbusplus::xyz::openbmc_project::State::server::BMC;
+
+constexpr auto bmc_state_interface = "xyz.openbmc_project.State.BMC";
+constexpr auto bmc_state_property = "CurrentBMCState";
+
+namespace
+{
+static constexpr auto redundancyIntf =
+    "xyz.openbmc_project.Software.RedundancyPriority";
+static constexpr auto versionIntf = "xyz.openbmc_project.Software.Version";
+static constexpr auto activationIntf =
+    "xyz.openbmc_project.Software.Activation";
+static constexpr auto softwareRoot = "/xyz/openbmc_project/software";
+
+bool getCurrentBmcState()
+{
+    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+    // Get the Inventory object implementing the BMC interface
+    ipmi::DbusObjectInfo bmcObject =
+        ipmi::getDbusObject(bus, bmc_state_interface);
+    auto variant =
+        ipmi::getDbusProperty(bus, bmcObject.second, bmcObject.first,
+                              bmc_state_interface, bmc_state_property);
+
+    return std::holds_alternative<std::string>(variant) &&
+           BMC::convertBMCStateFromString(std::get<std::string>(variant)) ==
+               BMC::BMCState::Ready;
+}
+
+bool getCurrentBmcStateWithFallback(const bool fallbackAvailability)
+{
+    try
+    {
+        return getCurrentBmcState();
+    }
+    catch (...)
+    {
+        // Nothing provided the BMC interface, therefore return whatever was
+        // configured as the default.
+        return fallbackAvailability;
+    }
+}
+/**
+ * @brief Returns the Version info from primary s/w object
+ *
+ * Get the Version info from the active s/w object which is having high
+ * "Priority" value(a smaller number is a higher priority) and "Purpose"
+ * is "BMC" from the list of all s/w objects those are implementing
+ * RedundancyPriority interface from the given softwareRoot path.
+ *
+ * @return On success returns the Version info from primary s/w object.
+ *
+ */
+std::string getActiveSoftwareVersionInfo()
+{
+    auto busp = getSdBus();
+
+    std::string revision{};
+    ipmi::ObjectTree objectTree;
+    try
+    {
+        objectTree =
+            ipmi::getAllDbusObjects(*busp, softwareRoot, redundancyIntf);
+    }
+    catch (sdbusplus::exception::SdBusError& e)
+    {
+        Log::log<Log::level::ERR>("Failed to fetch redundancy object from dbus",
+                                  Log::entry("INTERFACE=%s", redundancyIntf),
+                                  Log::entry("ERRMSG=%s", e.what()));
+    }
+
+    auto objectFound = false;
+    for (auto& softObject : objectTree)
+    {
+        auto service =
+            ipmi::getService(*busp, redundancyIntf, softObject.first);
+        auto objValueTree =
+            ipmi::getManagedObjects(*busp, service, softwareRoot);
+
+        auto minPriority = 0xFF;
+        for (const auto& objIter : objValueTree)
+        {
+            try
+            {
+                auto& intfMap = objIter.second;
+                auto& redundancyPriorityProps = intfMap.at(redundancyIntf);
+                auto& versionProps = intfMap.at(versionIntf);
+                auto& activationProps = intfMap.at(activationIntf);
+                auto priority =
+                    std::get<uint8_t>(redundancyPriorityProps.at("Priority"));
+                auto purpose =
+                    std::get<std::string>(versionProps.at("Purpose"));
+                auto activation =
+                    std::get<std::string>(activationProps.at("Activation"));
+                auto version =
+                    std::get<std::string>(versionProps.at("Version"));
+                if ((Version::convertVersionPurposeFromString(purpose) ==
+                     Version::VersionPurpose::BMC) &&
+                    (Activation::convertActivationsFromString(activation) ==
+                     Activation::Activations::Active))
+                {
+                    if (priority < minPriority)
+                    {
+                        minPriority = priority;
+                        objectFound = true;
+                        revision = std::move(version);
+                    }
+                }
+            }
+            catch (const std::exception& e)
+            {
+                Log::log<Log::level::ERR>(e.what());
+            }
+        }
+    }
+
+    if (!objectFound)
+    {
+        Log::log<Log::level::ERR>("Could not found an BMC software Object");
+    }
+
+    return revision;
+}
+
+typedef struct
+{
+    std::string platform;
+    uint8_t major;
+    uint8_t minor;
+    uint32_t buildNo;
+    std::string openbmcHash;
+    std::string metaHash;
+    std::string buildType;
+} MetaRevision;
+
+// Support both 2 solutions:
+// 1.Current solution  2.7.0-dev-533-g14dc00e79-5e7d997
+//   openbmcTag  2.7.0-dev
+//   BuildNo     533
+//   openbmcHash g14dc00e79
+//   MetaHasg    5e7d997
+//
+// 2.New solution  whtref-0.1-45-023125-a1295e-release
+//   IdStr        whtref
+//   Major        0
+//   Minor        1
+//   buildNo      45
+//   openbmcHash  023125
+//   MetaHash     a1295e
+//   BuildType    release/CI/<devloperId>
+std::optional<MetaRevision> convertIntelVersion(std::string& s)
+{
+    std::smatch results;
+    MetaRevision rev;
+    std::regex pattern1("(\\d+?).(\\d+?).\\d+?-\\w*?-(\\d+?)-(\\w+?)-(\\w+?)");
+    constexpr size_t matchedPhosphor = 6;
+    if (std::regex_match(s, results, pattern1))
+    {
+        if (results.size() == matchedPhosphor)
+        {
+            rev.platform = "whtref";
+            rev.major = static_cast<uint8_t>(std::stoi(results[1]));
+            rev.minor = static_cast<uint8_t>(std::stoi(results[2]));
+            rev.buildNo = static_cast<uint32_t>(std::stoi(results[3]));
+            rev.openbmcHash = results[4];
+            rev.metaHash = results[5];
+            rev.buildType = "release";
+            std::string versionString =
+                rev.platform + ":" + std::to_string(rev.major) + ":" +
+                std::to_string(rev.minor) + ":" + std::to_string(rev.buildNo) +
+                ":" + rev.openbmcHash + ":" + rev.metaHash + ":" +
+                rev.buildType;
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                versionString.c_str());
+            return rev;
+        }
+    }
+    constexpr size_t matchedIntel = 8;
+    std::regex pattern2(
+        "(\\w+?)-(\\d+?).(\\d+?)-(\\d+?)-(\\w+?)-(\\w+?)-(\\w+?)");
+    if (std::regex_match(s, results, pattern2))
+    {
+        if (results.size() == matchedIntel)
+        {
+            rev.platform = results[1];
+            rev.major = static_cast<uint8_t>(std::stoi(results[2]));
+            rev.minor = static_cast<uint8_t>(std::stoi(results[3]));
+            rev.buildNo = static_cast<uint32_t>(std::stoi(results[4]));
+            rev.openbmcHash = results[5];
+            rev.metaHash = results[6];
+            rev.buildType = results[7];
+            std::string versionString =
+                rev.platform + ":" + std::to_string(rev.major) + ":" +
+                std::to_string(rev.minor) + ":" + std::to_string(rev.buildNo) +
+                ":" + rev.openbmcHash + ":" + rev.metaHash + ":" +
+                rev.buildType;
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                versionString.c_str());
+            return rev;
+        }
+    }
+
+    return std::nullopt;
+}
+} // namespace
+auto ipmiAppGetDeviceId() -> ipmi::RspType<uint8_t, // Device ID
+                                           uint8_t, // Device Revision
+                                           uint8_t, // Firmware Revision Major
+                                           uint8_t, // Firmware Revision minor
+                                           uint8_t, // IPMI version
+                                           uint8_t, // Additional device support
+                                           uint24_t, // MFG ID
+                                           uint16_t, // Product ID
+                                           uint32_t  // AUX info
+                                           >
+{
+    std::optional<MetaRevision> rev;
+    static struct
+    {
+        uint8_t id;
+        uint8_t revision;
+        uint8_t fw[2];
+        uint8_t ipmiVer;
+        uint8_t addnDevSupport;
+        uint24_t manufId;
+        uint16_t prodId;
+        uint32_t aux;
+    } devId;
+    static bool dev_id_initialized = false;
+    static bool defaultActivationSetting = true;
+    const char* filename = "/usr/share/ipmi-providers/dev_id.json";
+    constexpr auto ipmiDevIdStateShift = 7;
+    constexpr auto ipmiDevIdFw1Mask = ~(1 << ipmiDevIdStateShift);
+
+    if (!dev_id_initialized)
+    {
+        try
+        {
+            auto version = getActiveSoftwareVersionInfo();
+            rev = convertIntelVersion(version);
+        }
+        catch (const std::exception& e)
+        {
+            Log::log<Log::level::ERR>(e.what());
+        }
+
+        if (rev.has_value())
+        {
+            // bit7 identifies if the device is available
+            // 0=normal operation
+            // 1=device firmware, SDR update,
+            // or self-initialization in progress.
+            // The availability may change in run time, so mask here
+            // and initialize later.
+            MetaRevision revision = rev.value();
+            devId.fw[0] = revision.major & ipmiDevIdFw1Mask;
+
+            revision.minor = (revision.minor > 99 ? 99 : revision.minor);
+            devId.fw[1] = revision.minor % 10 + (revision.minor / 10) * 16;
+            devId.aux = revision.buildNo;
+        }
+
+        // IPMI Spec version 2.0
+        devId.ipmiVer = 2;
+
+        std::ifstream devIdFile(filename);
+        if (devIdFile.is_open())
+        {
+            auto data = nlohmann::json::parse(devIdFile, nullptr, false);
+            if (!data.is_discarded())
+            {
+                devId.id = data.value("id", 0);
+                devId.revision = data.value("revision", 0);
+                devId.addnDevSupport = data.value("addn_dev_support", 0);
+                devId.manufId = data.value("manuf_id", 0);
+
+                try
+                {
+                    auto busp = getSdBus();
+                    const ipmi::DbusObjectInfo& object = ipmi::getDbusObject(
+                        *busp, "xyz.openbmc_project.Inventory.Item.Board",
+                        "/xyz/openbmc_project/inventory/system/board/",
+                        "Baseboard");
+                    const ipmi::Value& propValue = ipmi::getDbusProperty(
+                        *busp, object.second, object.first,
+                        "xyz.openbmc_project.Inventory.Item.Board",
+                        "ProductId");
+                    devId.prodId =
+                        static_cast<uint8_t>(std::get<uint64_t>(propValue));
+                }
+                catch (std::exception& e)
+                {
+                    devId.prodId = data.value("prod_id", 0);
+                }
+
+                // Set the availablitity of the BMC.
+                defaultActivationSetting = data.value("availability", true);
+
+                // Don't read the file every time if successful
+                dev_id_initialized = true;
+            }
+            else
+            {
+                Log::log<Log::level::ERR>("Device ID JSON parser failure");
+                return ipmi::responseUnspecifiedError();
+            }
+        }
+        else
+        {
+            Log::log<Log::level::ERR>("Device ID file not found");
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+
+    // Set availability to the actual current BMC state
+    devId.fw[0] &= ipmiDevIdFw1Mask;
+    if (!getCurrentBmcStateWithFallback(defaultActivationSetting))
+    {
+        devId.fw[0] |= (1 << ipmiDevIdStateShift);
+    }
+
+    return ipmi::responseSuccess(
+        devId.id, devId.revision, devId.fw[0], devId.fw[1], devId.ipmiVer,
+        devId.addnDevSupport, devId.manufId, devId.prodId, devId.aux);
+}
+
+static void registerAPPFunctions(void)
+{
+    Log::log<Log::level::INFO>("Registering App commands");
+    // <Get Device ID>
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetDeviceId, ipmi::Privilege::User,
+                          ipmiAppGetDeviceId);
+    return;
+}
+
+} // namespace ipmi
