diff --git a/oem/example/apphandler.cpp b/oem/example/apphandler.cpp
new file mode 100644
index 0000000..678f71a
--- /dev/null
+++ b/oem/example/apphandler.cpp
@@ -0,0 +1,431 @@
+#include "config.h"
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Software/Activation/server.hpp>
+#include <xyz/openbmc_project/Software/Version/server.hpp>
+#include <xyz/openbmc_project/State/BMC/server.hpp>
+
+#include <algorithm>
+#include <array>
+#include <charconv>
+#include <cstddef>
+#include <cstdint>
+#include <filesystem>
+#include <fstream>
+#include <memory>
+#include <regex>
+#include <string>
+#include <string_view>
+#include <tuple>
+#include <vector>
+
+constexpr auto bmcStateInterface = "xyz.openbmc_project.State.BMC";
+constexpr auto bmcStateProperty = "CurrentBMCState";
+
+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";
+
+void registerNetFnAppFunctions() __attribute__((constructor));
+
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+using Version = sdbusplus::server::xyz::openbmc_project::software::Version;
+using Activation =
+    sdbusplus::server::xyz::openbmc_project::software::Activation;
+using BMC = sdbusplus::server::xyz::openbmc_project::state::BMC;
+namespace fs = std::filesystem;
+
+/**
+ * @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(ipmi::Context::ptr ctx)
+{
+    std::string revision{};
+    ipmi::ObjectTree objectTree;
+    try
+    {
+        objectTree =
+            ipmi::getAllDbusObjects(*ctx->bus, softwareRoot, redundancyIntf);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to fetch redundancy object from dbus, "
+                   "interface: {INTERFACE},  error: {ERROR}",
+                   "INTERFACE", redundancyIntf, "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    auto objectFound = false;
+    for (auto& softObject : objectTree)
+    {
+        auto service =
+            ipmi::getService(*ctx->bus, redundancyIntf, softObject.first);
+        auto objValueTree =
+            ipmi::getManagedObjects(*ctx->bus, 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)
+            {
+                lg2::error("error message: {ERROR}", "ERROR", e);
+            }
+        }
+    }
+
+    if (!objectFound)
+    {
+        lg2::error("Could not found an BMC software Object");
+        elog<InternalFailure>();
+    }
+
+    return revision;
+}
+
+bool getCurrentBmcStateWithFallback(ipmi::Context::ptr& ctx,
+                                    const bool fallbackAvailability)
+{
+    // Get the Inventory object implementing the BMC interface
+    ipmi::DbusObjectInfo bmcObject{};
+    boost::system::error_code ec =
+        ipmi::getDbusObject(ctx, bmcStateInterface, bmcObject);
+    std::string bmcState{};
+    if (ec.value())
+    {
+        return fallbackAvailability;
+    }
+    ec = ipmi::getDbusProperty(ctx, bmcObject.second, bmcObject.first,
+                               bmcStateInterface, bmcStateProperty, bmcState);
+    if (!ec.value())
+    {
+        return fallbackAvailability;
+    }
+    return BMC::convertBMCStateFromString(bmcState) == BMC::BMCState::Ready;
+}
+
+typedef struct
+{
+    char major;
+    char minor;
+    uint8_t aux[4];
+} Revision;
+
+/* Use regular expression searching matched pattern X.Y, and convert it to  */
+/* Major (X) and Minor (Y) version.                                         */
+/* Example:                                                                 */
+/* version = 2.14.0-dev                                                     */
+/*           ^ ^                                                            */
+/*           | |---------------- Minor                                      */
+/*           |------------------ Major                                      */
+/*                                                                          */
+/* Default regex string only tries to match Major and Minor version.        */
+/*                                                                          */
+/* To match more firmware version info, platforms need to define it own     */
+/* regex string to match more strings, and assign correct mapping index in  */
+/* matches array.                                                           */
+/*                                                                          */
+/* matches[0]: matched index for major ver                                  */
+/* matches[1]: matched index for minor ver                                  */
+/* matches[2]: matched index for aux[0] (set 0 to skip)                     */
+/* matches[3]: matched index for aux[1] (set 0 to skip)                     */
+/* matches[4]: matched index for aux[2] (set 0 to skip)                     */
+/* matches[5]: matched index for aux[3] (set 0 to skip)                     */
+/* Example:                                                                 */
+/* regex = "([\d]+).([\d]+).([\d]+)-dev-([\d]+)-g([0-9a-fA-F]{2})           */
+/*          ([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})"               */
+/* matches = {1,2,5,6,7,8}                                                  */
+/* version = 2.14.0-dev-750-g37a7c5ad1-dirty                                */
+/*           ^ ^  ^     ^    ^ ^ ^ ^                                        */
+/*           | |  |     |    | | | |                                        */
+/*           | |  |     |    | | | |-- Aux byte 3 (0xAD), index 8           */
+/*           | |  |     |    | | |---- Aux byte 2 (0xC5), index 7           */
+/*           | |  |     |    | |------ Aux byte 1 (0xA7), index 6           */
+/*           | |  |     |    |-------- Aux byte 0 (0x37), index 5           */
+/*           | |  |     |------------- Not used, index 4                    */
+/*           | |  |------------------- Not used, index 3                    */
+/*           | |---------------------- Minor (14), index 2                  */
+/*           |------------------------ Major (2), index 1                   */
+int convertVersion(std::string s, Revision& rev)
+{
+    static const std::vector<size_t> matches = {
+        MAJOR_MATCH_INDEX, MINOR_MATCH_INDEX, AUX_0_MATCH_INDEX,
+        AUX_1_MATCH_INDEX, AUX_2_MATCH_INDEX, AUX_3_MATCH_INDEX};
+    std::regex fw_regex(FW_VER_REGEX);
+    std::smatch m;
+    Revision r = {0};
+    size_t val;
+
+    if (std::regex_search(s, m, fw_regex))
+    {
+        if (m.size() < *std::max_element(matches.begin(), matches.end()))
+        { // max index higher than match count
+            return -1;
+        }
+
+        // convert major
+        {
+            std::string str = m[matches[0]].str();
+            const auto& [ptr, ec] =
+                std::from_chars(str.data(), str.data() + str.size(), val);
+            if (ec != std::errc() || ptr != str.data() + str.size())
+            { // failed to convert major string
+                return -1;
+            }
+
+            if (val >= 2000)
+            { // For the platforms use year as major version, it would expect to
+              // have major version between 0 - 99. If the major version is
+              // greater than or equal to 2000, it is treated as a year and
+              // converted to 0 - 99.
+                r.major = val % 100;
+            }
+            else
+            {
+                r.major = val & 0x7F;
+            }
+        }
+
+        // convert minor
+        {
+            std::string str = m[matches[1]].str();
+            const auto& [ptr, ec] =
+                std::from_chars(str.data(), str.data() + str.size(), val);
+            if (ec != std::errc() || ptr != str.data() + str.size())
+            { // failed to convert minor string
+                return -1;
+            }
+            r.minor = val & 0xFF;
+        }
+
+        // convert aux bytes
+        {
+            size_t i;
+            for (i = 0; i < 4; i++)
+            {
+                if (matches[i + 2] == 0)
+                {
+                    continue;
+                }
+
+                std::string str = m[matches[i + 2]].str();
+                const char* cstr = str.c_str();
+                auto [ptr,
+                      ec] = std::from_chars(cstr, cstr + str.size(), val, 16);
+                if (ec != std::errc() || ptr != cstr + str.size())
+                { // failed to convert aux byte string
+                    break;
+                }
+
+                r.aux[i] = val & 0xFF;
+            }
+
+            if (i != 4)
+            { // something wrong durign converting aux bytes
+                return -1;
+            }
+        }
+
+        // all matched
+        rev = r;
+        return 0;
+    }
+
+    return -1;
+}
+
+/* @brief: Implement the Get Device ID IPMI command per the IPMI spec
+ *  @param[in] ctx - shared_ptr to an IPMI context struct
+ *
+ *  @returns IPMI completion code plus response data
+ *   - Device ID (manufacturer defined)
+ *   - Device revision[4 bits]; reserved[3 bits]; SDR support[1 bit]
+ *   - FW revision major[7 bits] (binary encoded); available[1 bit]
+ *   - FW Revision minor (BCD encoded)
+ *   - IPMI version (0x02 for IPMI 2.0)
+ *   - device support (bitfield of supported options)
+ *   - MFG IANA ID (3 bytes)
+ *   - product ID (2 bytes)
+ *   - AUX info (4 bytes)
+ */
+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
+              >
+    ipmiAppGetDeviceId([[maybe_unused]] ipmi::Context::ptr ctx)
+{
+    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);
+
+    static bool haveBMCVersion = false;
+    if (!haveBMCVersion || !dev_id_initialized)
+    {
+        int r = -1;
+        Revision rev = {0, 0, {0, 0, 0, 0}};
+        try
+        {
+            auto version = getActiveSoftwareVersionInfo(ctx);
+            r = convertVersion(version, rev);
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("error message: {ERROR}", "ERROR", e);
+        }
+
+        if (r >= 0)
+        {
+            // 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.
+            devId.fw[0] = rev.major & ipmiDevIdFw1Mask;
+
+            rev.minor = (rev.minor > 99 ? 99 : rev.minor);
+            devId.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
+            std::memcpy(&devId.aux, rev.aux, sizeof(rev.aux));
+            haveBMCVersion = true;
+        }
+    }
+    if (!dev_id_initialized)
+    {
+        // 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);
+                devId.prodId = data.value("prod_id", 0);
+                if (!(AUX_0_MATCH_INDEX || AUX_1_MATCH_INDEX ||
+                      AUX_2_MATCH_INDEX || AUX_3_MATCH_INDEX))
+                {
+                    devId.aux = data.value("aux", 0);
+                }
+
+                if (data.contains("firmware_revision"))
+                {
+                    const auto& firmwareRevision = data.at("firmware_revision");
+                    if (firmwareRevision.contains("major"))
+                    {
+                        firmwareRevision.at("major").get_to(devId.fw[0]);
+                    }
+                    if (firmwareRevision.contains("minor"))
+                    {
+                        firmwareRevision.at("minor").get_to(devId.fw[1]);
+                    }
+                }
+
+                // 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
+            {
+                lg2::error("Device ID JSON parser failure");
+                return ipmi::responseUnspecifiedError();
+            }
+        }
+        else
+        {
+            lg2::error("Device ID file not found");
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+
+    // Set availability to the actual current BMC state
+    devId.fw[0] &= ipmiDevIdFw1Mask;
+    if (!getCurrentBmcStateWithFallback(ctx, 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);
+}
+
+void registerNetFnAppFunctions()
+{
+    // OEM libraries should use ipmi::prioOemBase to override default
+    // implementation of IPMI commands that use ipmi::prioOpenBmcBase
+
+    // <Get Device ID>
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetDeviceId, ipmi::Privilege::User,
+                          ipmiAppGetDeviceId);
+}
