diff --git a/.build.sh b/.build.sh
new file mode 100755
index 0000000..d4e4b26
--- /dev/null
+++ b/.build.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+Dockerfile=$(cat << EOF
+FROM ubuntu:15.10
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get upgrade -yy
+RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -yy make g++ gcc libsystemd-dev libc6-dev pkg-config
+RUN groupadd -g ${GROUPS[0]} ${USER} && useradd -d ${HOME} -m -u ${UID} -g ${GROUPS[0]} ${USER}
+USER ${USER}
+ENV HOME ${HOME}
+RUN /bin/bash
+EOF
+)
+
+docker pull ubuntu:15.10
+docker build -t temp - <<< "${Dockerfile}"
+
+gcc --version
+
+docker run --cap-add=sys_admin --net=host --rm=true --user="${USER}" \
+    -w "${PWD}" -v "${HOME}":"${HOME}" -t temp make
diff --git a/.clang-tidy b/.clang-tidy
index 4b6eca0..75d64dc 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,7 +1,12 @@
 Checks: '
-    -*,
-    bugprone-unchecked-optional-access,
-    readability-identifier-naming
+-*,
+modernize-use-nullptr,
 '
+
+# Treat all warnings as errors
 WarningsAsErrors: '*'
+
+# Apply checks to all files
 HeaderFilterRegex: '(?!^subprojects).*'
+
+CheckOptions: []
diff --git a/.gitignore b/.gitignore
index 51ef08e..f0b223f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,17 @@
+# ignore vim swap files
+.*.sw*
+# failures from patch
+*.orig
+*.rej
+# backup files from some editors
+*~
+.cscope/
+
+# Meson
 /build*/
 /subprojects/*
-!subprojects/*.wrap
+!/subprojects/*.wrap
+subprojects/CLI11.wrap
+subprojects/function2.wrap
+subprojects/googletest.wrap
+subprojects/stdplus.wrap
diff --git a/.shellcheck b/.shellcheck
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.shellcheck
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..d8d6c1d
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,9 @@
+language: c
+
+sudo: required
+
+services:
+    - docker
+
+script:
+    - ./.build.sh
diff --git a/LICENSE b/LICENSE
index 8dada3e..8f71f43 100644
--- a/LICENSE
+++ b/LICENSE
@@ -199,3 +199,4 @@
    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.
+
diff --git a/OWNERS b/OWNERS
index 05f2bbe..9d16375 100644
--- a/OWNERS
+++ b/OWNERS
@@ -32,14 +32,30 @@
 # data within them will be kept sorted.
 
 owners:
+- liuxiwei@ieisystem.com
 - rushtotom@gmail.com
 - vernon.mauery@gmail.com
 
 reviewers:
+- anoo@us.ibm.com
+- deepak.kodihalli.83@gmail.com
+- ratankgupta31@gmail.com
 
 matchers:
 
 openbmc:
+- name: Adriana Kobylak
+  email: anoo@us.ibm.com
+  discord: anoo
+- name: Deepak Kodihalli
+  email: deepak.kodihalli.83@gmail.com
+  discord: dkodihal
+- name: George Liu
+  email: liuxiwei@ieisystem.com
+  discord: George Liu
+- name: Ratan Gupta
+  email: ratankgupta31@gmail.com
+  discord: rgupta
 - name: Tom Joseph
   email: rushtotom@gmail.com
   discord: tomjose
diff --git a/README.md b/README.md
index 89aba20..9c53680 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,41 @@
-# phosphor-net-ipmid
+# phosphor-host-ipmid
 
-## To Build
+## Compile ipmid with default options
 
-To build this package, do the following steps:
-
-```sh
-1. ./bootstrap.sh
-2. ./configure ${CONFIGURE_FLAGS}
-3. make
+```ascii
+meson builddir
+ninja -C builddir
 ```
 
-To clean the repository run `./bootstrap.sh clean`.
+## Compile ipmid with yocto defaults
+
+```ascii
+meson builddir -Dbuildtype=minsize -Db_lto=true -Dtests=disabled
+ninja -C builddir
+```
+
+If any of the dependencies are not found on the host system during
+configuration, meson automatically gets them via its wrap dependencies mentioned
+in `ipmid/subprojects`.
+
+## Enable/Disable meson wrap feature
+
+```ascii
+meson builddir -Dwrap_mode=nofallback
+ninja -C builddir
+```
+
+## Enable debug traces
+
+```ascii
+meson builddir -Dbuildtype=debug
+ninja -C builddir
+```
+
+## Generate test coverage report
+
+```ascii
+meson builddir -Db_coverage=true -Dtests=enabled
+ninja -C builddir test
+ninja -C builddir coverage
+```
diff --git a/app/channel.cpp b/app/channel.cpp
new file mode 100644
index 0000000..e7acf36
--- /dev/null
+++ b/app/channel.cpp
@@ -0,0 +1,180 @@
+#include "channel.hpp"
+
+#include "user_channel/channel_layer.hpp"
+
+#include <arpa/inet.h>
+
+#include <boost/process/v1/child.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <fstream>
+#include <set>
+#include <string>
+
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+
+namespace cipher
+{
+
+/** @brief Get the supported Cipher records
+ *
+ * The cipher records are read from the JSON file and converted into
+ * 1. cipher suite record format mentioned in the IPMI specification. The
+ * records can be either OEM or standard cipher. Each json entry is parsed and
+ * converted into the cipher record format and pushed into the vector.
+ * 2. Algorithms listed in vector format
+ *
+ * @return pair of vector containing 1. all the cipher suite records. 2.
+ * Algorithms supported
+ *
+ */
+std::pair<std::vector<uint8_t>, std::vector<uint8_t>> getCipherRecords()
+{
+    std::vector<uint8_t> cipherRecords;
+    std::vector<uint8_t> supportedAlgorithmRecords;
+    // create set to get the unique supported algorithms
+    std::set<uint8_t> supportedAlgorithmSet;
+
+    std::ifstream jsonFile(configFile);
+    if (!jsonFile.is_open())
+    {
+        lg2::error("Channel Cipher suites file not found");
+        elog<InternalFailure>();
+    }
+
+    auto data = Json::parse(jsonFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        lg2::error("Parsing channel cipher suites JSON failed");
+        elog<InternalFailure>();
+    }
+
+    for (const auto& record : data)
+    {
+        if (record.find(oem) != record.end())
+        {
+            // OEM cipher suite - 0xC1
+            cipherRecords.push_back(oemCipherSuite);
+            // Cipher Suite ID
+            cipherRecords.push_back(record.value(cipher, 0));
+            // OEM IANA - 3 bytes
+            cipherRecords.push_back(record.value(oem, 0));
+            cipherRecords.push_back(record.value(oem, 0) >> 8);
+            cipherRecords.push_back(record.value(oem, 0) >> 16);
+        }
+        else
+        {
+            // Standard cipher suite - 0xC0
+            cipherRecords.push_back(stdCipherSuite);
+            // Cipher Suite ID
+            cipherRecords.push_back(record.value(cipher, 0));
+        }
+
+        // Authentication algorithm number
+        cipherRecords.push_back(record.value(auth, 0));
+        supportedAlgorithmSet.insert(record.value(auth, 0));
+
+        // Integrity algorithm number
+        cipherRecords.push_back(record.value(integrity, 0) | integrityTag);
+        supportedAlgorithmSet.insert(record.value(integrity, 0) | integrityTag);
+
+        // Confidentiality algorithm number
+        cipherRecords.push_back(record.value(conf, 0) | confTag);
+        supportedAlgorithmSet.insert(record.value(conf, 0) | confTag);
+    }
+
+    // copy the set to supportedAlgorithmRecord which is vector based.
+    std::copy(supportedAlgorithmSet.begin(), supportedAlgorithmSet.end(),
+              std::back_inserter(supportedAlgorithmRecords));
+
+    return std::make_pair(cipherRecords, supportedAlgorithmRecords);
+}
+
+} // namespace cipher
+
+/** @brief this command is used to look up what authentication, integrity,
+ *  confidentiality algorithms are supported.
+ *
+ *  @ param ctx - context pointer
+ *  @ param channelNumber - channel number
+ *  @ param payloadType - payload type
+ *  @ param listIndex - list index
+ *  @ param algoSelectBit - list algorithms
+ *
+ *  @returns ipmi completion code plus response data
+ *  - rspChannel - channel number for authentication algorithm.
+ *  - rspRecords - cipher suite records.
+ **/
+ipmi::RspType<uint8_t,             // Channel Number
+              std::vector<uint8_t> // Cipher Records
+              >
+    getChannelCipherSuites(ipmi::Context::ptr ctx, uint4_t channelNumber,
+                           uint4_t reserved1, uint8_t payloadType,
+                           uint6_t listIndex, uint1_t reserved2,
+                           uint1_t algoSelectBit)
+{
+    static std::vector<uint8_t> cipherRecords;
+    static std::vector<uint8_t> supportedAlgorithms;
+    static auto recordInit = false;
+
+    uint8_t rspChannel = ipmi::convertCurrentChannelNum(
+        static_cast<uint8_t>(channelNumber), ctx->channel);
+
+    if (!ipmi::isValidChannel(rspChannel) || reserved1 != 0 || reserved2 != 0)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if (!ipmi::isValidPayloadType(static_cast<ipmi::PayloadType>(payloadType)))
+    {
+        lg2::debug("Get channel cipher suites - Invalid payload type");
+        constexpr uint8_t ccPayloadTypeNotSupported = 0x80;
+        return ipmi::response(ccPayloadTypeNotSupported);
+    }
+
+    if (!recordInit)
+    {
+        try
+        {
+            std::tie(cipherRecords, supportedAlgorithms) =
+                cipher::getCipherRecords();
+            recordInit = true;
+        }
+        catch (const std::exception& e)
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+
+    const std::vector<uint8_t>& records =
+        algoSelectBit ? cipherRecords : supportedAlgorithms;
+    static constexpr auto respSize = 16;
+
+    // Session support is available in active LAN channels.
+    if ((ipmi::getChannelSessionSupport(rspChannel) ==
+         ipmi::EChannelSessSupported::none) ||
+        !(ipmi::doesDeviceExist(rspChannel)))
+    {
+        lg2::debug("Get channel cipher suites - Device does not exist");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // List index(00h-3Fh), 0h selects the first set of 16, 1h selects the next
+    // set of 16 and so on.
+
+    // Calculate the number of record data bytes to be returned.
+    auto start =
+        std::min(static_cast<size_t>(listIndex) * respSize, records.size());
+    auto end = std::min((static_cast<size_t>(listIndex) * respSize) + respSize,
+                        records.size());
+    auto size = end - start;
+
+    std::vector<uint8_t> rspRecords;
+    std::copy_n(records.data() + start, size, std::back_inserter(rspRecords));
+
+    return ipmi::responseSuccess(rspChannel, rspRecords);
+}
diff --git a/app/channel.hpp b/app/channel.hpp
new file mode 100644
index 0000000..a6b8703
--- /dev/null
+++ b/app/channel.hpp
@@ -0,0 +1,43 @@
+#include "nlohmann/json.hpp"
+
+#include <ipmid/api.hpp>
+
+/** @brief this command is used to look up what authentication, integrity,
+ *  confidentiality algorithms are supported.
+ *
+ *  @ param ctx - context pointer
+ *  @ param channelNumber - channel number
+ *  @ param payloadType - payload type
+ *  @ param listIndex - list index
+ *  @ param algoSelectBit - list algorithms
+ *
+ *  @returns ipmi completion code plus response data
+ *  - rspChannel - channel number for authentication algorithm.
+ *  - rspRecords - cipher suite records.
+ **/
+ipmi::RspType<uint8_t,             // Channel Number
+              std::vector<uint8_t> // Cipher Records
+              >
+    getChannelCipherSuites(ipmi::Context::ptr ctx, uint4_t channelNumber,
+                           uint4_t reserved1, uint8_t payloadType,
+                           uint6_t listIndex, uint1_t reserved2,
+                           uint1_t algoSelectBit);
+
+namespace cipher
+{
+
+static constexpr auto listCipherSuite = 0x80;
+
+using Json = nlohmann::json;
+static constexpr auto configFile = "/usr/share/ipmi-providers/cipher_list.json";
+static constexpr auto cipher = "cipher";
+static constexpr auto stdCipherSuite = 0xC0;
+static constexpr auto oemCipherSuite = 0xC1;
+static constexpr auto oem = "oemiana";
+static constexpr auto auth = "authentication";
+static constexpr auto integrity = "integrity";
+static constexpr auto integrityTag = 0x40;
+static constexpr auto conf = "confidentiality";
+static constexpr auto confTag = 0x80;
+
+} // namespace cipher
diff --git a/app/meson.build b/app/meson.build
new file mode 100644
index 0000000..bc7c598
--- /dev/null
+++ b/app/meson.build
@@ -0,0 +1,14 @@
+app_inc = include_directories('.')
+
+app_pre = declare_dependency(include_directories: [root_inc, app_inc])
+
+app_lib = static_library(
+    'app',
+    'channel.cpp',
+    'watchdog.cpp',
+    'watchdog_service.cpp',
+    implicit_include_directories: false,
+    dependencies: app_pre,
+)
+
+app_dep = declare_dependency(link_with: app_lib, dependencies: app_pre)
diff --git a/app/watchdog.cpp b/app/watchdog.cpp
new file mode 100644
index 0000000..aea13fd
--- /dev/null
+++ b/app/watchdog.cpp
@@ -0,0 +1,436 @@
+#include "watchdog.hpp"
+
+#include "watchdog_service.hpp"
+
+#include <endian.h>
+
+#include <ipmid/api.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <bitset>
+#include <cstdint>
+#include <string>
+
+using phosphor::logging::commit;
+using phosphor::logging::level;
+using phosphor::logging::log;
+using sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+static bool lastCallSuccessful = false;
+
+void reportError()
+{
+    // We don't want to fill the SEL with errors if the daemon dies and doesn't
+    // come back but the watchdog keeps on ticking. Instead, we only report the
+    // error if we haven't reported one since the last successful call
+    if (!lastCallSuccessful)
+    {
+        return;
+    }
+    lastCallSuccessful = false;
+
+    // TODO: This slow down the end of the IPMI transaction waiting
+    // for the commit to finish. commit<>() can take at least 5 seconds
+    // to complete. 5s is very slow for an IPMI command and ends up
+    // congesting the IPMI channel needlessly, especially if the watchdog
+    // is ticking fairly quickly and we have some transient issues.
+    commit<InternalFailure>();
+}
+
+ipmi::RspType<> ipmiAppResetWatchdogTimer()
+{
+    try
+    {
+        WatchdogService wd_service;
+
+        // Notify the caller if we haven't initialized our timer yet
+        // so it can configure actions and timeouts
+        if (!wd_service.getInitialized())
+        {
+            lastCallSuccessful = true;
+
+            constexpr uint8_t ccWatchdogNotInit = 0x80;
+            return ipmi::response(ccWatchdogNotInit);
+        }
+
+        // The ipmi standard dictates we enable the watchdog during reset
+        wd_service.resetTimeRemaining(true);
+        lastCallSuccessful = true;
+        return ipmi::responseSuccess();
+    }
+    catch (const InternalFailure& e)
+    {
+        reportError();
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("wd_reset: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (...)
+    {
+        lg2::error("wd_reset: Unknown Error");
+        return ipmi::responseUnspecifiedError();
+    }
+}
+
+static constexpr uint8_t wd_timeout_action_mask = 0x3;
+
+static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
+static constexpr uint8_t wdTimerUseResTimer2 = 0x6;
+static constexpr uint8_t wdTimerUseResTimer3 = 0x7;
+
+static constexpr uint8_t wdTimeoutActionMax = 3;
+static constexpr uint8_t wdTimeoutInterruptTimer = 0x04;
+
+enum class IpmiAction : uint8_t
+{
+    None = 0x0,
+    HardReset = 0x1,
+    PowerOff = 0x2,
+    PowerCycle = 0x3,
+};
+
+/** @brief Converts an IPMI Watchdog Action to DBUS defined action
+ *  @param[in] ipmi_action The IPMI Watchdog Action
+ *  @return The Watchdog Action that the ipmi_action maps to
+ */
+WatchdogService::Action ipmiActionToWdAction(IpmiAction ipmi_action)
+{
+    switch (ipmi_action)
+    {
+        case IpmiAction::None:
+        {
+            return WatchdogService::Action::None;
+        }
+        case IpmiAction::HardReset:
+        {
+            return WatchdogService::Action::HardReset;
+        }
+        case IpmiAction::PowerOff:
+        {
+            return WatchdogService::Action::PowerOff;
+        }
+        case IpmiAction::PowerCycle:
+        {
+            return WatchdogService::Action::PowerCycle;
+        }
+        default:
+        {
+            throw std::domain_error("IPMI Action is invalid");
+        }
+    }
+}
+
+enum class IpmiTimerUse : uint8_t
+{
+    Reserved = 0x0,
+    BIOSFRB2 = 0x1,
+    BIOSPOST = 0x2,
+    OSLoad = 0x3,
+    SMSOS = 0x4,
+    OEM = 0x5,
+};
+
+WatchdogService::TimerUse ipmiTimerUseToWdTimerUse(IpmiTimerUse ipmiTimerUse)
+{
+    switch (ipmiTimerUse)
+    {
+        case IpmiTimerUse::Reserved:
+        {
+            return WatchdogService::TimerUse::Reserved;
+        }
+        case IpmiTimerUse::BIOSFRB2:
+        {
+            return WatchdogService::TimerUse::BIOSFRB2;
+        }
+        case IpmiTimerUse::BIOSPOST:
+        {
+            return WatchdogService::TimerUse::BIOSPOST;
+        }
+        case IpmiTimerUse::OSLoad:
+        {
+            return WatchdogService::TimerUse::OSLoad;
+        }
+        case IpmiTimerUse::SMSOS:
+        {
+            return WatchdogService::TimerUse::SMSOS;
+        }
+        case IpmiTimerUse::OEM:
+        {
+            return WatchdogService::TimerUse::OEM;
+        }
+        default:
+        {
+            return WatchdogService::TimerUse::Reserved;
+        }
+    }
+}
+
+static bool timerNotLogFlags = false;
+static std::bitset<8> timerUseExpirationFlags = 0;
+static uint3_t timerPreTimeoutInterrupt = 0;
+static constexpr uint8_t wdExpirationFlagReservedBit0 = 0x0;
+static constexpr uint8_t wdExpirationFlagReservedBit6 = 0x6;
+static constexpr uint8_t wdExpirationFlagReservedBit7 = 0x7;
+
+/**@brief The Set Watchdog Timer ipmi command.
+ *
+ * @param
+ * - timerUse
+ * - dontStopTimer
+ * - dontLog
+ * - timerAction
+ * - pretimeout
+ * - expireFlags
+ * - initialCountdown
+ *
+ * @return completion code on success.
+ **/
+ipmi::RspType<> ipmiSetWatchdogTimer(
+    uint3_t timerUse, uint3_t reserved, bool dontStopTimer, bool dontLog,
+    uint3_t timeoutAction, uint1_t reserved1, uint3_t preTimeoutInterrupt,
+    uint1_t reserved2, uint8_t preTimeoutInterval, std::bitset<8> expFlagValue,
+    uint16_t initialCountdown)
+{
+    if ((timerUse == wdTimerUseResTimer1) ||
+        (timerUse == wdTimerUseResTimer2) ||
+        (timerUse == wdTimerUseResTimer3) ||
+        (timeoutAction > wdTimeoutActionMax) ||
+        (preTimeoutInterrupt == wdTimeoutInterruptTimer) ||
+        (reserved | reserved1 | reserved2 |
+         expFlagValue.test(wdExpirationFlagReservedBit0) |
+         expFlagValue.test(wdExpirationFlagReservedBit6) |
+         expFlagValue.test(wdExpirationFlagReservedBit7)))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (preTimeoutInterval > (initialCountdown / 10))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    timerNotLogFlags = dontLog;
+    timerPreTimeoutInterrupt = preTimeoutInterrupt;
+
+    try
+    {
+        WatchdogService wd_service;
+        // Stop the timer if the don't stop bit is not set
+        if (!(dontStopTimer))
+        {
+            wd_service.setEnabled(false);
+        }
+
+        // Set the action based on the request
+        const auto ipmi_action = static_cast<IpmiAction>(
+            static_cast<uint8_t>(timeoutAction) & wd_timeout_action_mask);
+        wd_service.setExpireAction(ipmiActionToWdAction(ipmi_action));
+
+        const auto ipmiTimerUse = types::enum_cast<IpmiTimerUse>(timerUse);
+        wd_service.setTimerUse(ipmiTimerUseToWdTimerUse(ipmiTimerUse));
+
+        wd_service.setExpiredTimerUse(WatchdogService::TimerUse::Reserved);
+
+        timerUseExpirationFlags &= ~expFlagValue;
+
+        // Set the new interval and the time remaining deci -> mill seconds
+        const uint64_t interval = initialCountdown * 100;
+        wd_service.setInterval(interval);
+        wd_service.resetTimeRemaining(false);
+
+        // Mark as initialized so that future resets behave correctly
+        wd_service.setInitialized(true);
+        wd_service.setLogTimeout(!dontLog);
+
+        lastCallSuccessful = true;
+        return ipmi::responseSuccess();
+    }
+    catch (const std::domain_error&)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    catch (const InternalFailure& e)
+    {
+        reportError();
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("wd_set: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (...)
+    {
+        lg2::error("wd_set: Unknown Error");
+        return ipmi::responseUnspecifiedError();
+    }
+}
+
+/** @brief Converts a DBUS Watchdog Action to IPMI defined action
+ *  @param[in] wd_action The DBUS Watchdog Action
+ *  @return The IpmiAction that the wd_action maps to
+ */
+IpmiAction wdActionToIpmiAction(WatchdogService::Action wd_action)
+{
+    switch (wd_action)
+    {
+        case WatchdogService::Action::None:
+        {
+            return IpmiAction::None;
+        }
+        case WatchdogService::Action::HardReset:
+        {
+            return IpmiAction::HardReset;
+        }
+        case WatchdogService::Action::PowerOff:
+        {
+            return IpmiAction::PowerOff;
+        }
+        case WatchdogService::Action::PowerCycle:
+        {
+            return IpmiAction::PowerCycle;
+        }
+        default:
+        {
+            // We have no method via IPMI to signal that the action is unknown
+            // or unmappable in some way.
+            // Just ignore the error and return NONE so the host can reconcile.
+            return IpmiAction::None;
+        }
+    }
+}
+
+IpmiTimerUse wdTimerUseToIpmiTimerUse(WatchdogService::TimerUse wdTimerUse)
+{
+    switch (wdTimerUse)
+    {
+        case WatchdogService::TimerUse::Reserved:
+        {
+            return IpmiTimerUse::Reserved;
+        }
+        case WatchdogService::TimerUse::BIOSFRB2:
+        {
+            return IpmiTimerUse::BIOSFRB2;
+        }
+        case WatchdogService::TimerUse::BIOSPOST:
+        {
+            return IpmiTimerUse::BIOSPOST;
+        }
+        case WatchdogService::TimerUse::OSLoad:
+        {
+            return IpmiTimerUse::OSLoad;
+        }
+
+        case WatchdogService::TimerUse::SMSOS:
+        {
+            return IpmiTimerUse::SMSOS;
+        }
+        case WatchdogService::TimerUse::OEM:
+        {
+            return IpmiTimerUse::OEM;
+        }
+        default:
+        {
+            return IpmiTimerUse::Reserved;
+        }
+    }
+}
+
+/**@brief The getWatchdogTimer ipmi command.
+ *
+ * @return Completion code plus timer details.
+ * - timerUse
+ * - timerAction
+ * - pretimeout
+ * - expireFlags
+ * - initialCountdown
+ * - presentCountdown
+ **/
+ipmi::RspType<uint3_t,        // timerUse - timer use
+              uint3_t,        // timerUse - reserved
+              bool,           // timerUse - timer is started
+              bool,           // timerUse - don't log
+
+              uint3_t,        // timerAction - timeout action
+              uint1_t,        // timerAction - reserved
+              uint3_t,        // timerAction - pre-timeout interrupt
+              uint1_t,        // timerAction - reserved
+
+              uint8_t,        // pretimeout
+              std::bitset<8>, // expireFlags
+              uint16_t,       // initial Countdown - Little Endian (deciseconds)
+              uint16_t        // present Countdown - Little Endian (deciseconds)
+              >
+    ipmiGetWatchdogTimer()
+{
+    uint16_t presentCountdown = 0;
+    uint8_t pretimeout = 0;
+
+    try
+    {
+        WatchdogService wd_service;
+        WatchdogService::Properties wd_prop = wd_service.getProperties();
+
+        // Build and return the response
+        // Interval and timeRemaining need converted from milli -> deci seconds
+        uint16_t initialCountdown = htole16(wd_prop.interval / 100);
+
+        if (wd_prop.expiredTimerUse != WatchdogService::TimerUse::Reserved)
+        {
+            timerUseExpirationFlags.set(static_cast<uint8_t>(
+                wdTimerUseToIpmiTimerUse(wd_prop.expiredTimerUse)));
+        }
+
+        if (wd_prop.enabled)
+        {
+            presentCountdown = htole16(wd_prop.timeRemaining / 100);
+        }
+        else
+        {
+            if (wd_prop.expiredTimerUse == WatchdogService::TimerUse::Reserved)
+            {
+                presentCountdown = initialCountdown;
+            }
+            else
+            {
+                presentCountdown = 0;
+                // Automatically clear it whenever a timer expiration occurs.
+                timerNotLogFlags = false;
+            }
+        }
+
+        // TODO: Do something about having pretimeout support
+        pretimeout = 0;
+
+        lastCallSuccessful = true;
+        return ipmi::responseSuccess(
+            types::enum_cast<uint3_t>(
+                wdTimerUseToIpmiTimerUse(wd_prop.timerUse)),
+            0, wd_prop.enabled, timerNotLogFlags,
+            types::enum_cast<uint3_t>(
+                wdActionToIpmiAction(wd_prop.expireAction)),
+            0, timerPreTimeoutInterrupt, 0, pretimeout, timerUseExpirationFlags,
+            initialCountdown, presentCountdown);
+    }
+    catch (const InternalFailure& e)
+    {
+        reportError();
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("wd_get: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (...)
+    {
+        lg2::error("wd_get: Unknown Error");
+        return ipmi::responseUnspecifiedError();
+    }
+}
diff --git a/app/watchdog.hpp b/app/watchdog.hpp
new file mode 100644
index 0000000..fa53ac7
--- /dev/null
+++ b/app/watchdog.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <ipmid/api.hpp>
+
+/** @brief The RESET watchdog IPMI command.
+ */
+ipmi::RspType<> ipmiAppResetWatchdogTimer();
+
+/**@brief The setWatchdogTimer ipmi command.
+ *
+ * @param
+ * - timerUse
+ * - dontStopTimer
+ * - dontLog
+ * - timerAction
+ * - pretimeout
+ * - expireFlags
+ * - initialCountdown
+ *
+ * @return completion code on success.
+ **/
+ipmi::RspType<> ipmiSetWatchdogTimer(
+    uint3_t timerUse, uint3_t reserved, bool dontStopTimer, bool dontLog,
+    uint3_t timeoutAction, uint1_t reserved1, uint3_t preTimeoutInterrupt,
+    uint1_t reserved2, uint8_t preTimeoutInterval, std::bitset<8> expFlagValue,
+    uint16_t initialCountdown);
+
+/**@brief The getWatchdogTimer ipmi command.
+ *
+ * @return
+ * - timerUse
+ * - timerActions
+ * - pretimeout
+ * - timeruseFlags
+ * - initialCountdown
+ * - presentCountdown
+ **/
+ipmi::RspType<uint3_t, uint3_t, bool, bool,       // timerUse
+              uint3_t, uint1_t, uint3_t, uint1_t, // timerAction
+              uint8_t,                            // pretimeout
+              std::bitset<8>,                     // expireFlags
+              uint16_t, // initial Countdown - Little Endian (deciseconds)
+              uint16_t  // present Countdown - Little Endian (deciseconds)
+              >
+    ipmiGetWatchdogTimer();
diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
new file mode 100644
index 0000000..b67b5c7
--- /dev/null
+++ b/app/watchdog_service.cpp
@@ -0,0 +1,206 @@
+#include "watchdog_service.hpp"
+
+#include <ipmid/api.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/State/Watchdog/server.hpp>
+
+#include <exception>
+#include <stdexcept>
+#include <string>
+
+using phosphor::logging::elog;
+using phosphor::logging::entry;
+using phosphor::logging::level;
+using phosphor::logging::log;
+using sdbusplus::common::xyz::openbmc_project::state::convertForMessage;
+using sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+using sdbusplus::server::xyz::openbmc_project::state::Watchdog;
+
+static constexpr char wd_path[] = "/xyz/openbmc_project/watchdog/host0";
+static constexpr char wd_intf[] = "xyz.openbmc_project.State.Watchdog";
+static constexpr char prop_intf[] = "org.freedesktop.DBus.Properties";
+
+ipmi::ServiceCache WatchdogService::wd_service(wd_intf, wd_path);
+
+WatchdogService::WatchdogService() : bus(ipmid_get_sd_bus_connection()) {}
+
+void WatchdogService::resetTimeRemaining(bool enableWatchdog)
+{
+    bool wasValid = wd_service.isValid(bus);
+    auto request = wd_service.newMethodCall(bus, wd_intf, "ResetTimeRemaining");
+    request.append(enableWatchdog);
+    try
+    {
+        auto response = bus.call(request);
+    }
+    catch (const std::exception& e)
+    {
+        wd_service.invalidate();
+        if (wasValid)
+        {
+            // Retry the request once in case the cached service was stale
+            return resetTimeRemaining(enableWatchdog);
+        }
+        lg2::error("WatchdogService: Method error resetting time remaining, "
+                   "ENABLE_WATCHDOG: {ENABLE_WATCHDOG}, ERROR: {ERROR}",
+                   "ENABLE_WATCHDOG", enableWatchdog, "ERROR", e);
+        elog<InternalFailure>();
+    }
+}
+
+WatchdogService::Properties WatchdogService::getProperties()
+{
+    bool wasValid = wd_service.isValid(bus);
+    auto request = wd_service.newMethodCall(bus, prop_intf, "GetAll");
+    request.append(wd_intf);
+
+    std::map<std::string, std::variant<bool, uint64_t, std::string>> properties;
+    try
+    {
+        auto response = bus.call(request);
+        response.read(properties);
+    }
+    catch (const std::exception& e)
+    {
+        wd_service.invalidate();
+        if (wasValid)
+        {
+            // Retry the request once in case the cached service was stale
+            return getProperties();
+        }
+        lg2::error("WatchdogService: Method error getting properties: {ERROR}",
+                   "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    try
+    {
+        Properties wd_prop;
+        wd_prop.initialized = std::get<bool>(properties.at("Initialized"));
+        wd_prop.enabled = std::get<bool>(properties.at("Enabled"));
+        wd_prop.expireAction = Watchdog::convertActionFromString(
+            std::get<std::string>(properties.at("ExpireAction")));
+        wd_prop.timerUse = Watchdog::convertTimerUseFromString(
+            std::get<std::string>(properties.at("CurrentTimerUse")));
+        wd_prop.expiredTimerUse = Watchdog::convertTimerUseFromString(
+            std::get<std::string>(properties.at("ExpiredTimerUse")));
+
+        wd_prop.interval = std::get<uint64_t>(properties.at("Interval"));
+        wd_prop.timeRemaining =
+            std::get<uint64_t>(properties.at("TimeRemaining"));
+        return wd_prop;
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("WatchdogService: Decode error in get properties: {ERROR}",
+                   "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    // Needed instead of elog<InternalFailure>() since the compiler can't
+    // deduce the that elog<>() always throws
+    throw std::runtime_error(
+        "WatchdogService: Should not reach end of getProperties");
+}
+
+template <typename T>
+T WatchdogService::getProperty(const std::string& key)
+{
+    bool wasValid = wd_service.isValid(bus);
+    auto request = wd_service.newMethodCall(bus, prop_intf, "Get");
+    request.append(wd_intf, key);
+    try
+    {
+        auto response = bus.call(request);
+        std::variant<T> value;
+        response.read(value);
+        return std::get<T>(value);
+    }
+    catch (const std::exception& e)
+    {
+        wd_service.invalidate();
+        if (wasValid)
+        {
+            // Retry the request once in case the cached service was stale
+            return getProperty<T>(key);
+        }
+        lg2::error("WatchdogService: Method error getting {PROPERTY}: {ERROR}",
+                   "PROPERTY", key, "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    // Needed instead of elog<InternalFailure>() since the compiler can't
+    // deduce the that elog<>() always throws
+    throw std::runtime_error(
+        "WatchdogService: Should not reach end of getProperty");
+}
+
+template <typename T>
+void WatchdogService::setProperty(const std::string& key, const T& val)
+{
+    bool wasValid = wd_service.isValid(bus);
+    auto request = wd_service.newMethodCall(bus, prop_intf, "Set");
+    request.append(wd_intf, key, std::variant<T>(val));
+    try
+    {
+        auto response = bus.call(request);
+    }
+    catch (const std::exception& e)
+    {
+        wd_service.invalidate();
+        if (wasValid)
+        {
+            // Retry the request once in case the cached service was stale
+            setProperty(key, val);
+            return;
+        }
+        lg2::error("WatchdogService: Method error setting {PROPERTY}: {ERROR}",
+                   "PROPERTY", key, "ERROR", e);
+        elog<InternalFailure>();
+    }
+}
+
+bool WatchdogService::getInitialized()
+{
+    return getProperty<bool>("Initialized");
+}
+
+void WatchdogService::setInitialized(bool initialized)
+{
+    setProperty("Initialized", initialized);
+}
+
+void WatchdogService::setEnabled(bool enabled)
+{
+    setProperty("Enabled", enabled);
+}
+
+void WatchdogService::setLogTimeout(bool LogTimeout)
+{
+    setProperty("LogTimeout", LogTimeout);
+}
+
+void WatchdogService::setExpireAction(Action expireAction)
+{
+    setProperty("ExpireAction", convertForMessage(expireAction));
+}
+
+void WatchdogService::setTimerUse(TimerUse timerUse)
+{
+    setProperty("CurrentTimerUse", convertForMessage(timerUse));
+}
+
+void WatchdogService::setExpiredTimerUse(TimerUse timerUse)
+{
+    setProperty("ExpiredTimerUse", convertForMessage(timerUse));
+}
+
+void WatchdogService::setInterval(uint64_t interval)
+{
+    setProperty("Interval", interval);
+}
diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp
new file mode 100644
index 0000000..5717066
--- /dev/null
+++ b/app/watchdog_service.hpp
@@ -0,0 +1,122 @@
+#pragma once
+#include <ipmid/utils.hpp>
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/State/Watchdog/server.hpp>
+
+/** @class WatchdogService
+ *  @brief Access to the running OpenBMC watchdog implementation.
+ *  @details Easy accessor for servers that implement the
+ *  xyz.openbmc_project.State.Watchdog DBus API.
+ */
+class WatchdogService
+{
+  public:
+    WatchdogService();
+
+    using Action =
+        sdbusplus::server::xyz::openbmc_project::state::Watchdog::Action;
+    using TimerUse =
+        sdbusplus::server::xyz::openbmc_project::state::Watchdog::TimerUse;
+
+    /** @brief Resets the time remaining on the watchdog.
+     *         Equivalent to setTimeRemaining(getInterval()).
+     *         Optionally enables the watchdog.
+     *
+     *  @param[in] enableWatchdog - Should the call also enable the watchdog
+     */
+    void resetTimeRemaining(bool enableWatchdog);
+
+    /** @brief Contains a copy of the properties enumerated by the
+     *         watchdog service.
+     */
+    struct Properties
+    {
+        bool initialized;
+        bool enabled;
+        Action expireAction;
+        TimerUse timerUse;
+        TimerUse expiredTimerUse;
+        uint64_t interval;
+        uint64_t timeRemaining;
+    };
+
+    /** @brief Retrieves a copy of the currently set properties on the
+     *         host watchdog
+     *
+     *  @return A populated WatchdogProperties struct
+     */
+    Properties getProperties();
+
+    /** @brief Get the value of the initialized property on the host
+     *         watchdog
+     *
+     *  @return The value of the property
+     */
+    bool getInitialized();
+
+    /** @brief Sets the value of the initialized property on the host
+     *         watchdog
+     *
+     *  @param[in] initialized - The new initializedvalue
+     */
+    void setInitialized(bool initialized);
+
+    /** @brief Sets the value of the enabled property on the host watchdog
+     *
+     *  @param[in] enabled - The new enabled value
+     */
+    void setEnabled(bool enabled);
+
+    /** @brief Sets the value of the LogTimeout property on the host watchdog
+     *
+     *  @param[in] LogTimeout - The new LogTimeout value
+     */
+    void setLogTimeout(bool LogTimeout);
+
+    /** @brief Sets the value of the expireAction property on the host watchdog
+     *
+     *  @param[in] expireAction - The new expireAction value
+     */
+    void setExpireAction(Action expireAction);
+
+    /** @brief Sets the value of the timerUse property on the host watchdog
+     *
+     *  @param[in] timerUse - The new timerUse value
+     */
+    void setTimerUse(TimerUse timerUse);
+
+    /** @brief Sets the value of the ExpiredTimerUse property on the host
+     * watchdog
+     *
+     *  @param[in] timerUse - The new timerUse value
+     */
+    void setExpiredTimerUse(TimerUse timerUse);
+
+    /** @brief Sets the value of the interval property on the host watchdog
+     *
+     *  @param[in] interval - The new interval value
+     */
+    void setInterval(uint64_t interval);
+
+  private:
+    /** @brief sdbusplus handle */
+    sdbusplus::bus_t bus;
+    /** @brief The name of the mapped host watchdog service */
+    static ipmi::ServiceCache wd_service;
+
+    /** @brief Gets the value of the property on the host watchdog
+     *
+     *  @param[in] key - The name of the property
+     *  @return The value of the property
+     */
+    template <typename T>
+    T getProperty(const std::string& key);
+
+    /** @brief Sets the value of the property on the host watchdog
+     *
+     *  @param[in] key - The name of the property
+     *  @param[in] val - The new value
+     */
+    template <typename T>
+    void setProperty(const std::string& key, const T& val);
+};
diff --git a/apphandler.cpp b/apphandler.cpp
new file mode 100644
index 0000000..1e32061
--- /dev/null
+++ b/apphandler.cpp
@@ -0,0 +1,1873 @@
+#include "config.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <systemd/sd-bus.h>
+#include <unistd.h>
+
+#include <app/channel.hpp>
+#include <app/watchdog.hpp>
+#include <apphandler.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/sessiondef.hpp>
+#include <ipmid/sessionhelper.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 <sys_info_param.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Control/Power/ACPIPowerState/server.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>
+
+extern sd_bus* bus;
+
+constexpr auto bmc_state_interface = "xyz.openbmc_project.State.BMC";
+constexpr auto bmc_state_property = "CurrentBMCState";
+constexpr auto versionPurposeHostEnd = ".Host";
+
+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;
+
+#ifdef ENABLE_I2C_WHITELIST_CHECK
+typedef struct
+{
+    uint8_t busId;
+    uint8_t targetAddr;
+    uint8_t targetAddrMask;
+    std::vector<uint8_t> data;
+    std::vector<uint8_t> dataMask;
+} i2cControllerWRAllowlist;
+
+static std::vector<i2cControllerWRAllowlist>& getWRAllowlist()
+{
+    static std::vector<i2cControllerWRAllowlist> wrAllowlist;
+    return wrAllowlist;
+}
+
+static constexpr const char* i2cControllerWRAllowlistFile =
+    "/usr/share/ipmi-providers/master_write_read_white_list.json";
+
+static constexpr const char* filtersStr = "filters";
+static constexpr const char* busIdStr = "busId";
+static constexpr const char* targetAddrStr = "slaveAddr";
+static constexpr const char* targetAddrMaskStr = "slaveAddrMask";
+static constexpr const char* cmdStr = "command";
+static constexpr const char* cmdMaskStr = "commandMask";
+static constexpr int base_16 = 16;
+#endif // ENABLE_I2C_WHITELIST_CHECK
+static constexpr uint8_t oemCmdStart = 192;
+static constexpr uint8_t invalidParamSelectorStart = 8;
+static constexpr uint8_t invalidParamSelectorEnd = 191;
+
+/**
+ * @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 getCurrentBmcState()
+{
+    sdbusplus::bus_t 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;
+    }
+}
+
+namespace acpi_state
+{
+using namespace sdbusplus::server::xyz::openbmc_project::control::power;
+
+const static constexpr char* acpiInterface =
+    "xyz.openbmc_project.Control.Power.ACPIPowerState";
+const static constexpr char* sysACPIProp = "SysACPIStatus";
+const static constexpr char* devACPIProp = "DevACPIStatus";
+
+enum class PowerStateType : uint8_t
+{
+    sysPowerState = 0x00,
+    devPowerState = 0x01,
+};
+
+// Defined in 20.6 of ipmi doc
+enum class PowerState : uint8_t
+{
+    s0G0D0 = 0x00,
+    s1D1 = 0x01,
+    s2D2 = 0x02,
+    s3D3 = 0x03,
+    s4 = 0x04,
+    s5G2 = 0x05,
+    s4S5 = 0x06,
+    g3 = 0x07,
+    sleep = 0x08,
+    g1Sleep = 0x09,
+    override = 0x0a,
+    legacyOn = 0x20,
+    legacyOff = 0x21,
+    unknown = 0x2a,
+    noChange = 0x7f,
+};
+
+static constexpr uint8_t stateChanged = 0x80;
+
+std::map<ACPIPowerState::ACPI, PowerState> dbusToIPMI = {
+    {ACPIPowerState::ACPI::S0_G0_D0, PowerState::s0G0D0},
+    {ACPIPowerState::ACPI::S1_D1, PowerState::s1D1},
+    {ACPIPowerState::ACPI::S2_D2, PowerState::s2D2},
+    {ACPIPowerState::ACPI::S3_D3, PowerState::s3D3},
+    {ACPIPowerState::ACPI::S4, PowerState::s4},
+    {ACPIPowerState::ACPI::S5_G2, PowerState::s5G2},
+    {ACPIPowerState::ACPI::S4_S5, PowerState::s4S5},
+    {ACPIPowerState::ACPI::G3, PowerState::g3},
+    {ACPIPowerState::ACPI::SLEEP, PowerState::sleep},
+    {ACPIPowerState::ACPI::G1_SLEEP, PowerState::g1Sleep},
+    {ACPIPowerState::ACPI::OVERRIDE, PowerState::override},
+    {ACPIPowerState::ACPI::LEGACY_ON, PowerState::legacyOn},
+    {ACPIPowerState::ACPI::LEGACY_OFF, PowerState::legacyOff},
+    {ACPIPowerState::ACPI::Unknown, PowerState::unknown}};
+
+bool isValidACPIState(acpi_state::PowerStateType type, uint8_t state)
+{
+    if (type == acpi_state::PowerStateType::sysPowerState)
+    {
+        if ((state <= static_cast<uint8_t>(acpi_state::PowerState::override)) ||
+            (state == static_cast<uint8_t>(acpi_state::PowerState::legacyOn)) ||
+            (state ==
+             static_cast<uint8_t>(acpi_state::PowerState::legacyOff)) ||
+            (state == static_cast<uint8_t>(acpi_state::PowerState::unknown)) ||
+            (state == static_cast<uint8_t>(acpi_state::PowerState::noChange)))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    else if (type == acpi_state::PowerStateType::devPowerState)
+    {
+        if ((state <= static_cast<uint8_t>(acpi_state::PowerState::s3D3)) ||
+            (state == static_cast<uint8_t>(acpi_state::PowerState::unknown)) ||
+            (state == static_cast<uint8_t>(acpi_state::PowerState::noChange)))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    else
+    {
+        return false;
+    }
+    return false;
+}
+} // namespace acpi_state
+
+/** @brief implements Set ACPI Power State command
+ * @param sysAcpiState - ACPI system power state to set
+ * @param devAcpiState - ACPI device power state to set
+ *
+ * @return IPMI completion code on success
+ **/
+ipmi::RspType<> ipmiSetAcpiPowerState(uint8_t sysAcpiState,
+                                      uint8_t devAcpiState)
+{
+    auto s = static_cast<uint8_t>(acpi_state::PowerState::unknown);
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    auto value = acpi_state::ACPIPowerState::ACPI::Unknown;
+
+    if (sysAcpiState & acpi_state::stateChanged)
+    {
+        // set system power state
+        s = sysAcpiState & ~acpi_state::stateChanged;
+
+        if (!acpi_state::isValidACPIState(
+                acpi_state::PowerStateType::sysPowerState, s))
+        {
+            lg2::error("set_acpi_power sys invalid input, S: {S}", "S", s);
+            return ipmi::responseParmOutOfRange();
+        }
+
+        // valid input
+        if (s == static_cast<uint8_t>(acpi_state::PowerState::noChange))
+        {
+            lg2::debug("No change for system power state");
+        }
+        else
+        {
+            auto found = std::find_if(
+                acpi_state::dbusToIPMI.begin(), acpi_state::dbusToIPMI.end(),
+                [&s](const auto& iter) {
+                    return (static_cast<uint8_t>(iter.second) == s);
+                });
+
+            value = found->first;
+
+            try
+            {
+                auto acpiObject =
+                    ipmi::getDbusObject(bus, acpi_state::acpiInterface);
+                ipmi::setDbusProperty(bus, acpiObject.second, acpiObject.first,
+                                      acpi_state::acpiInterface,
+                                      acpi_state::sysACPIProp,
+                                      convertForMessage(value));
+            }
+            catch (const InternalFailure& e)
+            {
+                lg2::error("Failed in set ACPI system property: {ERROR}",
+                           "ERROR", e);
+                return ipmi::responseUnspecifiedError();
+            }
+        }
+    }
+    else
+    {
+        lg2::debug("Do not change system power state");
+    }
+
+    if (devAcpiState & acpi_state::stateChanged)
+    {
+        // set device power state
+        s = devAcpiState & ~acpi_state::stateChanged;
+        if (!acpi_state::isValidACPIState(
+                acpi_state::PowerStateType::devPowerState, s))
+        {
+            lg2::error("set_acpi_power dev invalid input, S: {S}", "S", s);
+            return ipmi::responseParmOutOfRange();
+        }
+
+        // valid input
+        if (s == static_cast<uint8_t>(acpi_state::PowerState::noChange))
+        {
+            lg2::debug("No change for device power state");
+        }
+        else
+        {
+            auto found = std::find_if(
+                acpi_state::dbusToIPMI.begin(), acpi_state::dbusToIPMI.end(),
+                [&s](const auto& iter) {
+                    return (static_cast<uint8_t>(iter.second) == s);
+                });
+
+            value = found->first;
+
+            try
+            {
+                auto acpiObject =
+                    ipmi::getDbusObject(bus, acpi_state::acpiInterface);
+                ipmi::setDbusProperty(bus, acpiObject.second, acpiObject.first,
+                                      acpi_state::acpiInterface,
+                                      acpi_state::devACPIProp,
+                                      convertForMessage(value));
+            }
+            catch (const InternalFailure& e)
+            {
+                lg2::error("Failed in set ACPI device property: {ERROR}",
+                           "ERROR", e);
+                return ipmi::responseUnspecifiedError();
+            }
+        }
+    }
+    else
+    {
+        lg2::debug("Do not change device power state");
+    }
+    return ipmi::responseSuccess();
+}
+
+/**
+ *  @brief implements the get ACPI power state command
+ *
+ *  @return IPMI completion code plus response data on success.
+ *   -  ACPI system power state
+ *   -  ACPI device power state
+ **/
+ipmi::RspType<uint8_t, // acpiSystemPowerState
+              uint8_t  // acpiDevicePowerState
+              >
+    ipmiGetAcpiPowerState()
+{
+    uint8_t sysAcpiState;
+    uint8_t devAcpiState;
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    try
+    {
+        auto acpiObject = ipmi::getDbusObject(bus, acpi_state::acpiInterface);
+
+        auto sysACPIVal = ipmi::getDbusProperty(
+            bus, acpiObject.second, acpiObject.first, acpi_state::acpiInterface,
+            acpi_state::sysACPIProp);
+        auto sysACPI = acpi_state::ACPIPowerState::convertACPIFromString(
+            std::get<std::string>(sysACPIVal));
+        sysAcpiState = static_cast<uint8_t>(acpi_state::dbusToIPMI.at(sysACPI));
+
+        auto devACPIVal = ipmi::getDbusProperty(
+            bus, acpiObject.second, acpiObject.first, acpi_state::acpiInterface,
+            acpi_state::devACPIProp);
+        auto devACPI = acpi_state::ACPIPowerState::convertACPIFromString(
+            std::get<std::string>(devACPIVal));
+        devAcpiState = static_cast<uint8_t>(acpi_state::dbusToIPMI.at(devACPI));
+    }
+    catch (const InternalFailure& e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(sysAcpiState, devAcpiState);
+}
+
+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);
+
+#ifdef GET_DBUS_ACTIVE_SOFTWARE
+    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;
+        }
+    }
+#endif
+    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);
+#ifdef GET_DBUS_ACTIVE_SOFTWARE
+                if (!(AUX_0_MATCH_INDEX || AUX_1_MATCH_INDEX ||
+                      AUX_2_MATCH_INDEX || AUX_3_MATCH_INDEX))
+#endif
+                {
+                    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(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);
+}
+
+auto ipmiAppGetSelfTestResults() -> ipmi::RspType<uint8_t, uint8_t>
+{
+    // Byte 2:
+    //  55h - No error.
+    //  56h - Self Test function not implemented in this controller.
+    //  57h - Corrupted or inaccesssible data or devices.
+    //  58h - Fatal hardware error.
+    //  FFh - reserved.
+    //  all other: Device-specific 'internal failure'.
+    //  Byte 3:
+    //      For byte 2 = 55h, 56h, FFh:     00h
+    //      For byte 2 = 58h, all other:    Device-specific
+    //      For byte 2 = 57h:   self-test error bitfield.
+    //      Note: returning 57h does not imply that all test were run.
+    //      [7] 1b = Cannot access SEL device.
+    //      [6] 1b = Cannot access SDR Repository.
+    //      [5] 1b = Cannot access BMC FRU device.
+    //      [4] 1b = IPMB signal lines do not respond.
+    //      [3] 1b = SDR Repository empty.
+    //      [2] 1b = Internal Use Area of BMC FRU corrupted.
+    //      [1] 1b = controller update 'boot block' firmware corrupted.
+    //      [0] 1b = controller operational firmware corrupted.
+    constexpr uint8_t notImplemented = 0x56;
+    constexpr uint8_t zero = 0;
+    return ipmi::responseSuccess(notImplemented, zero);
+}
+
+static constexpr size_t uuidBinaryLength = 16;
+static std::array<uint8_t, uuidBinaryLength> rfc4122ToIpmi(std::string rfc4122)
+{
+    using Argument = xyz::openbmc_project::common::InvalidArgument;
+    // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+    // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
+    // order
+    // Ex: 0x2332fc2c40e66298e511f2782395a361
+    constexpr size_t uuidHexLength = (2 * uuidBinaryLength);
+    constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
+    std::array<uint8_t, uuidBinaryLength> uuid;
+    if (rfc4122.size() == uuidRfc4122Length)
+    {
+        rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
+                      rfc4122.end());
+    }
+    if (rfc4122.size() != uuidHexLength)
+    {
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+                              Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+    }
+    for (size_t ind = 0; ind < uuidHexLength; ind += 2)
+    {
+        char v[3];
+        v[0] = rfc4122[ind];
+        v[1] = rfc4122[ind + 1];
+        v[2] = 0;
+        size_t err;
+        long b;
+        try
+        {
+            b = std::stoul(v, &err, 16);
+        }
+        catch (const std::exception& e)
+        {
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+                                  Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+        }
+        // check that exactly two ascii bytes were converted
+        if (err != 2)
+        {
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+                                  Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+        }
+        uuid[uuidBinaryLength - (ind / 2) - 1] = static_cast<uint8_t>(b);
+    }
+    return uuid;
+}
+
+auto ipmiAppGetDeviceGuid()
+    -> ipmi::RspType<std::array<uint8_t, uuidBinaryLength>>
+{
+    // return a fixed GUID based on /etc/machine-id
+    // This should match the /redfish/v1/Managers/bmc's UUID data
+
+    // machine specific application ID (for BMC ID)
+    // generated by systemd-id128 -p new as per man page
+    static constexpr sd_id128_t bmcUuidAppId = SD_ID128_MAKE(
+        e0, e1, 73, 76, 64, 61, 47, da, a5, 0c, d0, cc, 64, 12, 45, 78);
+
+    sd_id128_t bmcUuid;
+    // create the UUID from /etc/machine-id via the systemd API
+    sd_id128_get_machine_app_specific(bmcUuidAppId, &bmcUuid);
+
+    char bmcUuidCstr[SD_ID128_STRING_MAX];
+    std::string systemUuid = sd_id128_to_string(bmcUuid, bmcUuidCstr);
+
+    std::array<uint8_t, uuidBinaryLength> uuid = rfc4122ToIpmi(systemUuid);
+    return ipmi::responseSuccess(uuid);
+}
+
+auto ipmiAppGetBtCapabilities()
+    -> ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
+{
+    // Per IPMI 2.0 spec, the input and output buffer size must be the max
+    // buffer size minus one byte to allocate space for the length byte.
+    constexpr uint8_t nrOutstanding = 0x01;
+    constexpr uint8_t inputBufferSize = MAX_IPMI_BUFFER - 1;
+    constexpr uint8_t outputBufferSize = MAX_IPMI_BUFFER - 1;
+    constexpr uint8_t transactionTime = 0x0A;
+    constexpr uint8_t nrRetries = 0x01;
+
+    return ipmi::responseSuccess(nrOutstanding, inputBufferSize,
+                                 outputBufferSize, transactionTime, nrRetries);
+}
+
+auto ipmiAppGetSystemGuid(ipmi::Context::ptr& ctx)
+    -> ipmi::RspType<std::array<uint8_t, 16>>
+{
+    static constexpr auto uuidInterface = "xyz.openbmc_project.Common.UUID";
+    static constexpr auto uuidProperty = "UUID";
+
+    // Get the Inventory object implementing BMC interface
+    ipmi::DbusObjectInfo objectInfo{};
+    boost::system::error_code ec = ipmi::getDbusObject(
+        ctx, uuidInterface, ipmi::sensor::inventoryRoot, objectInfo);
+    if (ec.value())
+    {
+        lg2::error("Failed to locate System UUID object, "
+                   "interface: {INTERFACE}, error: {ERROR}",
+                   "INTERFACE", uuidInterface, "ERROR", ec.message());
+    }
+
+    // Read UUID property value from bmcObject
+    // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+    std::string rfc4122Uuid{};
+    ec = ipmi::getDbusProperty(ctx, objectInfo.second, objectInfo.first,
+                               uuidInterface, uuidProperty, rfc4122Uuid);
+    if (ec.value())
+    {
+        lg2::error("Failed to read System UUID property, "
+                   "interface: {INTERFACE}, property: {PROPERTY}, "
+                   "error: {ERROR}",
+                   "INTERFACE", uuidInterface, "PROPERTY", uuidProperty,
+                   "ERROR", ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+    std::array<uint8_t, 16> uuid;
+    try
+    {
+        // convert to IPMI format
+        uuid = rfc4122ToIpmi(rfc4122Uuid);
+    }
+    catch (const InvalidArgument& e)
+    {
+        lg2::error("Failed in parsing BMC UUID property, "
+                   "interface: {INTERFACE}, property: {PROPERTY}, "
+                   "value: {VALUE}, error: {ERROR}",
+                   "INTERFACE", uuidInterface, "PROPERTY", uuidProperty,
+                   "VALUE", rfc4122Uuid, "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+    return ipmi::responseSuccess(uuid);
+}
+
+/**
+ * @brief set the session state as teardown
+ *
+ * This function is to set the session state to tear down in progress if the
+ * state is active.
+ *
+ * @param[in] busp - Dbus obj
+ * @param[in] service - service name
+ * @param[in] obj - object path
+ *
+ * @return success completion code if it sets the session state to
+ * tearDownInProgress else return the corresponding error completion code.
+ **/
+uint8_t setSessionState(std::shared_ptr<sdbusplus::asio::connection>& busp,
+                        const std::string& service, const std::string& obj)
+{
+    try
+    {
+        uint8_t sessionState = std::get<uint8_t>(ipmi::getDbusProperty(
+            *busp, service, obj, session::sessionIntf, "State"));
+
+        if (sessionState == static_cast<uint8_t>(session::State::active))
+        {
+            ipmi::setDbusProperty(
+                *busp, service, obj, session::sessionIntf, "State",
+                static_cast<uint8_t>(session::State::tearDownInProgress));
+            return ipmi::ccSuccess;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed in getting session state property, "
+                   "service: {SERVICE}, object path: {OBJECT_PATH}, "
+                   "interface: {INTERFACE}, error: {ERROR}",
+                   "SERVICE", service, "OBJECT_PATH", obj, "INTERFACE",
+                   session::sessionIntf, "ERROR", e);
+        return ipmi::ccUnspecifiedError;
+    }
+
+    return ipmi::ccInvalidFieldRequest;
+}
+
+ipmi::RspType<> ipmiAppCloseSession(uint32_t reqSessionId,
+                                    std::optional<uint8_t> requestSessionHandle)
+{
+    auto busp = getSdBus();
+    uint8_t reqSessionHandle =
+        requestSessionHandle.value_or(session::defaultSessionHandle);
+
+    if (reqSessionId == session::sessionZero &&
+        reqSessionHandle == session::defaultSessionHandle)
+    {
+        return ipmi::response(session::ccInvalidSessionId);
+    }
+
+    if (reqSessionId == session::sessionZero &&
+        reqSessionHandle == session::invalidSessionHandle)
+    {
+        return ipmi::response(session::ccInvalidSessionHandle);
+    }
+
+    if (reqSessionId != session::sessionZero &&
+        reqSessionHandle != session::defaultSessionHandle)
+    {
+        return ipmi::response(ipmi::ccInvalidFieldRequest);
+    }
+
+    try
+    {
+        ipmi::ObjectTree objectTree = ipmi::getAllDbusObjects(
+            *busp, session::sessionManagerRootPath, session::sessionIntf);
+
+        for (auto& objectTreeItr : objectTree)
+        {
+            const std::string obj = objectTreeItr.first;
+
+            if (isSessionObjectMatched(obj, reqSessionId, reqSessionHandle))
+            {
+                auto& serviceMap = objectTreeItr.second;
+
+                // Session id and session handle are unique for each session.
+                // Session id and handler are retrived from the object path and
+                // object path will be unique for each session. Checking if
+                // multiple objects exist with same object path under multiple
+                // services.
+                if (serviceMap.size() != 1)
+                {
+                    return ipmi::responseUnspecifiedError();
+                }
+
+                auto itr = serviceMap.begin();
+                const std::string service = itr->first;
+                return ipmi::response(setSessionState(busp, service, obj));
+            }
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to fetch object from dbus, "
+                   "interface: {INTERFACE}, error: {ERROR}",
+                   "INTERFACE", session::sessionIntf, "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseInvalidFieldRequest();
+}
+
+uint8_t getTotalSessionCount()
+{
+    uint8_t count = 0, ch = 0;
+
+    while (ch < ipmi::maxIpmiChannels &&
+           count < session::maxNetworkInstanceSupported)
+    {
+        ipmi::ChannelInfo chInfo{};
+        ipmi::getChannelInfo(ch, chInfo);
+        if (static_cast<ipmi::EChannelMediumType>(chInfo.mediumType) ==
+            ipmi::EChannelMediumType::lan8032)
+        {
+            count++;
+        }
+        ch++;
+    }
+    return count * session::maxSessionCountPerChannel;
+}
+
+/**
+ * @brief get session info request data.
+ *
+ * This function validates the request data and retrive request session id,
+ * session handle.
+ *
+ * @param[in] ctx - context of current session.
+ * @param[in] sessionIndex - request session index
+ * @param[in] payload - input payload
+ * @param[in] reqSessionId - unpacked session Id will be asigned
+ * @param[in] reqSessionHandle - unpacked session handle will be asigned
+ *
+ * @return success completion code if request data is valid
+ * else return the correcponding error completion code.
+ **/
+uint8_t getSessionInfoRequestData(
+    const ipmi::Context::ptr ctx, const uint8_t sessionIndex,
+    ipmi::message::Payload& payload, uint32_t& reqSessionId,
+    uint8_t& reqSessionHandle)
+{
+    if ((sessionIndex > session::maxSessionCountPerChannel) &&
+        (sessionIndex < session::searchSessionByHandle))
+    {
+        return ipmi::ccInvalidFieldRequest;
+    }
+
+    switch (sessionIndex)
+    {
+        case session::searchCurrentSession:
+
+            ipmi::ChannelInfo chInfo;
+            ipmi::getChannelInfo(ctx->channel, chInfo);
+
+            if (static_cast<ipmi::EChannelMediumType>(chInfo.mediumType) !=
+                ipmi::EChannelMediumType::lan8032)
+            {
+                return ipmi::ccInvalidFieldRequest;
+            }
+
+            if (!payload.fullyUnpacked())
+            {
+                return ipmi::ccReqDataLenInvalid;
+            }
+            // Check if current sessionId is 0, sessionId 0 is reserved.
+            if (ctx->sessionId == session::sessionZero)
+            {
+                return session::ccInvalidSessionId;
+            }
+            reqSessionId = ctx->sessionId;
+            break;
+
+        case session::searchSessionByHandle:
+
+            if ((payload.unpack(reqSessionHandle)) ||
+                (!payload.fullyUnpacked()))
+            {
+                return ipmi::ccReqDataLenInvalid;
+            }
+
+            if ((reqSessionHandle == session::sessionZero) ||
+                ((reqSessionHandle & session::multiIntfaceSessionHandleMask) >
+                 session::maxSessionCountPerChannel))
+            {
+                return session::ccInvalidSessionHandle;
+            }
+            break;
+
+        case session::searchSessionById:
+
+            if ((payload.unpack(reqSessionId)) || (!payload.fullyUnpacked()))
+            {
+                return ipmi::ccReqDataLenInvalid;
+            }
+
+            if (reqSessionId == session::sessionZero)
+            {
+                return session::ccInvalidSessionId;
+            }
+            break;
+
+        default:
+            if (!payload.fullyUnpacked())
+            {
+                return ipmi::ccReqDataLenInvalid;
+            }
+            break;
+    }
+    return ipmi::ccSuccess;
+}
+
+uint8_t getSessionState(ipmi::Context::ptr ctx, const std::string& service,
+                        const std::string& objPath, uint8_t& sessionState)
+{
+    boost::system::error_code ec = ipmi::getDbusProperty(
+        ctx, service, objPath, session::sessionIntf, "State", sessionState);
+    if (ec)
+    {
+        lg2::error("Failed to fetch state property, service: {SERVICE}, "
+                   "object path: {OBJECTPATH}, interface: {INTERFACE}, "
+                   "error: {ERROR}",
+                   "SERVICE", service, "OBJECTPATH", objPath, "INTERFACE",
+                   session::sessionIntf, "ERROR", ec.message());
+        return ipmi::ccUnspecifiedError;
+    }
+    return ipmi::ccSuccess;
+}
+
+static constexpr uint8_t macAddrLen = 6;
+/** Alias SessionDetails - contain the optional information about an
+ *        RMCP+ session.
+ *
+ *  @param userID - uint6_t session user ID (0-63)
+ *  @param reserved - uint2_t reserved
+ *  @param privilege - uint4_t session privilege (0-5)
+ *  @param reserved - uint4_t reserved
+ *  @param channel - uint4_t session channel number
+ *  @param protocol - uint4_t session protocol
+ *  @param remoteIP - uint32_t remote IP address
+ *  @param macAddr - std::array<uint8_t, 6> mac address
+ *  @param port - uint16_t remote port
+ */
+using SessionDetails =
+    std::tuple<uint2_t, uint6_t, uint4_t, uint4_t, uint4_t, uint4_t, uint32_t,
+               std::array<uint8_t, macAddrLen>, uint16_t>;
+
+/** @brief get session details for a given session
+ *
+ *  @param[in] ctx - ipmi::Context pointer for accessing D-Bus
+ *  @param[in] service - D-Bus service name to fetch details from
+ *  @param[in] objPath - D-Bus object path for session
+ *  @param[out] sessionHandle - return session handle for session
+ *  @param[out] sessionState - return session state for session
+ *  @param[out] details - return a SessionDetails tuple containing other
+ *                        session info
+ *  @return - ipmi::Cc success or error code
+ */
+ipmi::Cc getSessionDetails(ipmi::Context::ptr ctx, const std::string& service,
+                           const std::string& objPath, uint8_t& sessionHandle,
+                           uint8_t& sessionState, SessionDetails& details)
+{
+    ipmi::PropertyMap sessionProps;
+    boost::system::error_code ec = ipmi::getAllDbusProperties(
+        ctx, service, objPath, session::sessionIntf, sessionProps);
+
+    if (ec)
+    {
+        lg2::error("Failed to fetch state property, service: {SERVICE}, "
+                   "object path: {OBJECTPATH}, interface: {INTERFACE}, "
+                   "error: {ERROR}",
+                   "SERVICE", service, "OBJECTPATH", objPath, "INTERFACE",
+                   session::sessionIntf, "ERROR", ec.message());
+        return ipmi::ccUnspecifiedError;
+    }
+
+    sessionState = ipmi::mappedVariant<uint8_t>(
+        sessionProps, "State", static_cast<uint8_t>(session::State::inactive));
+    if (sessionState == static_cast<uint8_t>(session::State::active))
+    {
+        sessionHandle =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "SessionHandle", 0);
+        std::get<0>(details) =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "UserID", 0xff);
+        // std::get<1>(details) = 0; // (default constructed to 0)
+        std::get<2>(details) =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "CurrentPrivilege", 0);
+        // std::get<3>(details) = 0; // (default constructed to 0)
+        std::get<4>(details) =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "ChannelNum", 0xff);
+        constexpr uint4_t rmcpPlusProtocol = 1;
+        std::get<5>(details) = rmcpPlusProtocol;
+        std::get<6>(details) =
+            ipmi::mappedVariant<uint32_t>(sessionProps, "RemoteIPAddr", 0);
+        // std::get<7>(details) = {{0}}; // default constructed to all 0
+        std::get<8>(details) =
+            ipmi::mappedVariant<uint16_t>(sessionProps, "RemotePort", 0);
+    }
+
+    return ipmi::ccSuccess;
+}
+
+ipmi::RspType<uint8_t, // session handle,
+              uint8_t, // total session count
+              uint8_t, // active session count
+              std::optional<SessionDetails>>
+    ipmiAppGetSessionInfo(ipmi::Context::ptr ctx, uint8_t sessionIndex,
+                          ipmi::message::Payload& payload)
+{
+    uint32_t reqSessionId = 0;
+    uint8_t reqSessionHandle = session::defaultSessionHandle;
+    // initializing state to 0xff as 0 represents state as inactive.
+    uint8_t state = 0xFF;
+
+    uint8_t completionCode = getSessionInfoRequestData(
+        ctx, sessionIndex, payload, reqSessionId, reqSessionHandle);
+
+    if (completionCode)
+    {
+        return ipmi::response(completionCode);
+    }
+    ipmi::ObjectTree objectTree;
+    boost::system::error_code ec = ipmi::getAllDbusObjects(
+        ctx, session::sessionManagerRootPath, session::sessionIntf, objectTree);
+    if (ec)
+    {
+        lg2::error("Failed to fetch object from dbus, "
+                   "interface: {INTERFACE}, error: {ERROR}",
+                   "INTERFACE", session::sessionIntf, "ERROR", ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+
+    uint8_t totalSessionCount = getTotalSessionCount();
+    uint8_t activeSessionCount = 0;
+    uint8_t sessionHandle = session::defaultSessionHandle;
+    uint8_t activeSessionHandle = 0;
+    std::optional<SessionDetails> maybeDetails;
+    uint8_t index = 0;
+    for (auto& objectTreeItr : objectTree)
+    {
+        uint32_t sessionId = 0;
+        std::string objectPath = objectTreeItr.first;
+
+        if (!parseCloseSessionInputPayload(objectPath, sessionId,
+                                           sessionHandle))
+        {
+            continue;
+        }
+        index++;
+        auto& serviceMap = objectTreeItr.second;
+        auto itr = serviceMap.begin();
+
+        if (serviceMap.size() != 1)
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+
+        std::string service = itr->first;
+        uint8_t sessionState = 0;
+        completionCode =
+            getSessionState(ctx, service, objectPath, sessionState);
+        if (completionCode)
+        {
+            return ipmi::response(completionCode);
+        }
+
+        if (sessionState == static_cast<uint8_t>(session::State::active))
+        {
+            activeSessionCount++;
+        }
+
+        if (index == sessionIndex || reqSessionId == sessionId ||
+            reqSessionHandle == sessionHandle)
+        {
+            SessionDetails details{};
+            completionCode = getSessionDetails(ctx, service, objectPath,
+                                               sessionHandle, state, details);
+
+            if (completionCode)
+            {
+                return ipmi::response(completionCode);
+            }
+            activeSessionHandle = sessionHandle;
+            maybeDetails = std::move(details);
+        }
+    }
+
+    if (state == static_cast<uint8_t>(session::State::active) ||
+        state == static_cast<uint8_t>(session::State::tearDownInProgress))
+    {
+        return ipmi::responseSuccess(activeSessionHandle, totalSessionCount,
+                                     activeSessionCount, maybeDetails);
+    }
+
+    return ipmi::responseInvalidFieldRequest();
+}
+
+std::optional<std::string> getSysFWVersion(ipmi::Context::ptr& ctx)
+{
+    /*
+     * The System Firmware version is detected via following steps:
+     * - Get all of object paths that include
+     * "xyz.openbmc_project.Software.Version" interface.
+     * - Get the Purpose property of above object paths.
+     * - If the Purpose is Host then get the Version property.
+     */
+    ipmi::ObjectTree objectTree;
+    boost::system::error_code ec =
+        ipmi::getAllDbusObjects(ctx, softwareRoot, versionIntf, objectTree);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+
+    for (const auto& [objPath, serviceMap] : objectTree)
+    {
+        for (const auto& [service, intfs] : serviceMap)
+        {
+            ipmi::PropertyMap props;
+            ec = ipmi::getAllDbusProperties(ctx, service, objPath, versionIntf,
+                                            props);
+            if (ec.value())
+            {
+                continue;
+            }
+
+            std::string purposeProp = std::string(
+                ipmi::mappedVariant<std::string>(props, "Purpose", ""));
+
+            if (!purposeProp.ends_with(versionPurposeHostEnd))
+            {
+                continue;
+            }
+
+            std::string sysFWVersion = std::string(
+                ipmi::mappedVariant<std::string>(props, "Version", ""));
+
+            if (sysFWVersion.empty())
+            {
+                return std::nullopt;
+            }
+
+            return sysFWVersion;
+        }
+    }
+
+    return std::nullopt;
+}
+
+static std::unique_ptr<SysInfoParamStore> sysInfoParamStore;
+
+static std::string sysInfoReadSystemName()
+{
+    // Use the BMC hostname as the "System Name."
+    char hostname[HOST_NAME_MAX + 1] = {};
+    if (gethostname(hostname, HOST_NAME_MAX) != 0)
+    {
+        perror("System info parameter: system name");
+    }
+    return hostname;
+}
+
+static constexpr uint8_t paramRevision = 0x11;
+static constexpr size_t configParameterLength = 16;
+
+static constexpr size_t smallChunkSize = 14;
+static constexpr size_t fullChunkSize = 16;
+static constexpr uint8_t progressMask = 0x3;
+static constexpr uint8_t maxValidEncodingData = 0x02;
+
+static constexpr uint8_t setComplete = 0x0;
+static constexpr uint8_t setInProgress = 0x1;
+static uint8_t transferStatus = setComplete;
+
+static constexpr uint8_t configDataOverhead = 2;
+
+namespace ipmi
+{
+constexpr Cc ccParmNotSupported = 0x80;
+constexpr Cc ccSetInProgressActive = 0x81;
+
+static inline auto responseParmNotSupported()
+{
+    return response(ccParmNotSupported);
+}
+static inline auto responseSetInProgressActive()
+{
+    return response(ccSetInProgressActive);
+}
+} // namespace ipmi
+
+ipmi::RspType<uint8_t,                // Parameter revision
+              std::optional<uint8_t>, // data1 / setSelector / ProgressStatus
+              std::optional<std::vector<uint8_t>>> // data2-17
+    ipmiAppGetSystemInfo(ipmi::Context::ptr ctx, uint7_t reserved,
+                         bool getRevision, uint8_t paramSelector,
+                         uint8_t setSelector, uint8_t BlockSelector)
+{
+    if (reserved || (paramSelector >= invalidParamSelectorStart &&
+                     paramSelector <= invalidParamSelectorEnd))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if (paramSelector >= oemCmdStart)
+    {
+        return ipmi::responseParmNotSupported();
+    }
+    if (getRevision)
+    {
+        return ipmi::responseSuccess(paramRevision, std::nullopt, std::nullopt);
+    }
+
+    if (paramSelector == 0)
+    {
+        return ipmi::responseSuccess(paramRevision, transferStatus,
+                                     std::nullopt);
+    }
+
+    if (BlockSelector != 0) // 00h if parameter does not require a block number
+    {
+        return ipmi::responseParmNotSupported();
+    }
+
+    if (sysInfoParamStore == nullptr)
+    {
+        sysInfoParamStore = std::make_unique<SysInfoParamStore>();
+        sysInfoParamStore->update(IPMI_SYSINFO_SYSTEM_NAME,
+                                  sysInfoReadSystemName);
+    }
+
+    if (paramSelector == IPMI_SYSINFO_SYSTEM_FW_VERSION)
+    {
+        auto fwVersion = getSysFWVersion(ctx);
+
+        if (fwVersion == std::nullopt)
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+        sysInfoParamStore->update(IPMI_SYSINFO_SYSTEM_FW_VERSION, *fwVersion);
+    }
+
+    // Parameters other than Set In Progress are assumed to be strings.
+    std::tuple<bool, std::string> ret =
+        sysInfoParamStore->lookup(paramSelector);
+    bool found = std::get<0>(ret);
+    if (!found)
+    {
+        return ipmi::responseSensorInvalid();
+    }
+    std::string& paramString = std::get<1>(ret);
+    std::vector<uint8_t> configData;
+    size_t count = 0;
+    if (setSelector == 0)
+    {                               // First chunk has only 14 bytes.
+        configData.emplace_back(0); // encoding
+        configData.emplace_back(paramString.length()); // string length
+        count = std::min(paramString.length(), smallChunkSize);
+        configData.resize(count + configDataOverhead);
+        std::copy_n(paramString.begin(), count,
+                    configData.begin() + configDataOverhead); // 14 bytes chunk
+
+        // Append zero's to remaining bytes
+        if (configData.size() < configParameterLength)
+        {
+            std::fill_n(std::back_inserter(configData),
+                        configParameterLength - configData.size(), 0x00);
+        }
+    }
+    else
+    {
+        size_t offset = (setSelector * fullChunkSize) - configDataOverhead;
+        if (offset >= paramString.length())
+        {
+            return ipmi::responseParmOutOfRange();
+        }
+        count = std::min(paramString.length() - offset, fullChunkSize);
+        configData.resize(count);
+        std::copy_n(paramString.begin() + offset, count,
+                    configData.begin()); // 16 bytes chunk
+    }
+    return ipmi::responseSuccess(paramRevision, setSelector, configData);
+}
+
+ipmi::RspType<> ipmiAppSetSystemInfo(uint8_t paramSelector, uint8_t data1,
+                                     std::vector<uint8_t> configData)
+{
+    if (paramSelector >= invalidParamSelectorStart &&
+        paramSelector <= invalidParamSelectorEnd)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if (paramSelector >= oemCmdStart)
+    {
+        return ipmi::responseParmNotSupported();
+    }
+
+    if (paramSelector == 0)
+    {
+        // attempt to set the 'set in progress' value (in parameter #0)
+        // when not in the set complete state.
+        if ((transferStatus != setComplete) && (data1 == setInProgress))
+        {
+            return ipmi::responseSetInProgressActive();
+        }
+        // only following 2 states are supported
+        if (data1 > setInProgress)
+        {
+            lg2::error("illegal SetInProgress status");
+            return ipmi::responseInvalidFieldRequest();
+        }
+
+        transferStatus = data1 & progressMask;
+        return ipmi::responseSuccess();
+    }
+
+    if (configData.size() > configParameterLength)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // Append zero's to remaining bytes
+    if (configData.size() < configParameterLength)
+    {
+        fill_n(back_inserter(configData),
+               (configParameterLength - configData.size()), 0x00);
+    }
+
+    if (!sysInfoParamStore)
+    {
+        sysInfoParamStore = std::make_unique<SysInfoParamStore>();
+        sysInfoParamStore->update(IPMI_SYSINFO_SYSTEM_NAME,
+                                  sysInfoReadSystemName);
+    }
+
+    // lookup
+    std::tuple<bool, std::string> ret =
+        sysInfoParamStore->lookup(paramSelector);
+    bool found = std::get<0>(ret);
+    std::string& paramString = std::get<1>(ret);
+    if (!found)
+    {
+        // parameter does not exist. Init new
+        paramString = "";
+    }
+
+    uint8_t setSelector = data1;
+    size_t count = 0;
+    if (setSelector == 0) // First chunk has only 14 bytes.
+    {
+        uint8_t encoding = configData.at(0);
+        if (encoding > maxValidEncodingData)
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+
+        size_t stringLen = configData.at(1); // string length
+        count = std::min(stringLen, smallChunkSize);
+        count = std::min(count, configData.size());
+        paramString.resize(stringLen); // reserve space
+        std::copy_n(configData.begin() + configDataOverhead, count,
+                    paramString.begin());
+    }
+    else
+    {
+        size_t offset = (setSelector * fullChunkSize) - configDataOverhead;
+        if (offset >= paramString.length())
+        {
+            return ipmi::responseParmOutOfRange();
+        }
+        count = std::min(paramString.length() - offset, configData.size());
+        std::copy_n(configData.begin(), count, paramString.begin() + offset);
+    }
+    sysInfoParamStore->update(paramSelector, paramString);
+    return ipmi::responseSuccess();
+}
+
+#ifdef ENABLE_I2C_WHITELIST_CHECK
+inline std::vector<uint8_t> convertStringToData(const std::string& command)
+{
+    std::istringstream iss(command);
+    std::string token;
+    std::vector<uint8_t> dataValue;
+    while (std::getline(iss, token, ' '))
+    {
+        dataValue.emplace_back(
+            static_cast<uint8_t>(std::stoul(token, nullptr, base_16)));
+    }
+    return dataValue;
+}
+
+static bool populateI2CControllerWRAllowlist()
+{
+    nlohmann::json data = nullptr;
+    std::ifstream jsonFile(i2cControllerWRAllowlistFile);
+
+    if (!jsonFile.good())
+    {
+        lg2::warning("i2c allow list file not found! file name: {FILE_NAME}",
+                     "FILE_NAME", i2cControllerWRAllowlistFile);
+        return false;
+    }
+
+    try
+    {
+        data = nlohmann::json::parse(jsonFile, nullptr, false);
+    }
+    catch (const nlohmann::json::parse_error& e)
+    {
+        lg2::error("Corrupted i2c allow list config file, "
+                   "file name: {FILE_NAME}, error: {ERROR}",
+                   "FILE_NAME", i2cControllerWRAllowlistFile, "ERROR", e);
+        return false;
+    }
+
+    try
+    {
+        // Example JSON Structure format
+        // "filters": [
+        //    {
+        //      "Description": "Allow full read - ignore first byte write value
+        //      for 0x40 to 0x4F",
+        //      "busId": "0x01",
+        //      "slaveAddr": "0x40",
+        //      "slaveAddrMask": "0x0F",
+        //      "command": "0x00",
+        //      "commandMask": "0xFF"
+        //    },
+        //    {
+        //      "Description": "Allow full read - first byte match 0x05 and
+        //      ignore second byte",
+        //      "busId": "0x01",
+        //      "slaveAddr": "0x57",
+        //      "slaveAddrMask": "0x00",
+        //      "command": "0x05 0x00",
+        //      "commandMask": "0x00 0xFF"
+        //    },]
+
+        nlohmann::json filters = data[filtersStr].get<nlohmann::json>();
+        std::vector<i2cControllerWRAllowlist>& allowlist = getWRAllowlist();
+        for (const auto& it : filters.items())
+        {
+            nlohmann::json filter = it.value();
+            if (filter.is_null())
+            {
+                lg2::error(
+                    "Corrupted I2C controller write read allowlist config file, "
+                    "file name: {FILE_NAME}",
+                    "FILE_NAME", i2cControllerWRAllowlistFile);
+                return false;
+            }
+            const std::vector<uint8_t>& writeData =
+                convertStringToData(filter[cmdStr].get<std::string>());
+            const std::vector<uint8_t>& writeDataMask =
+                convertStringToData(filter[cmdMaskStr].get<std::string>());
+            if (writeDataMask.size() != writeData.size())
+            {
+                lg2::error("I2C controller write read allowlist filter "
+                           "mismatch for command & mask size");
+                return false;
+            }
+            allowlist.push_back(
+                {static_cast<uint8_t>(std::stoul(
+                     filter[busIdStr].get<std::string>(), nullptr, base_16)),
+                 static_cast<uint8_t>(
+                     std::stoul(filter[targetAddrStr].get<std::string>(),
+                                nullptr, base_16)),
+                 static_cast<uint8_t>(
+                     std::stoul(filter[targetAddrMaskStr].get<std::string>(),
+                                nullptr, base_16)),
+                 writeData, writeDataMask});
+        }
+        if (allowlist.size() != filters.size())
+        {
+            lg2::error(
+                "I2C controller write read allowlist filter size mismatch");
+            return false;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("I2C controller write read allowlist "
+                   "unexpected exception: {ERROR}",
+                   "ERROR", e);
+        return false;
+    }
+    return true;
+}
+
+static inline bool isWriteDataAllowlisted(const std::vector<uint8_t>& data,
+                                          const std::vector<uint8_t>& dataMask,
+                                          const std::vector<uint8_t>& writeData)
+{
+    std::vector<uint8_t> processedDataBuf(data.size());
+    std::vector<uint8_t> processedReqBuf(dataMask.size());
+    std::transform(writeData.begin(), writeData.end(), dataMask.begin(),
+                   processedReqBuf.begin(), std::bit_or<uint8_t>());
+    std::transform(data.begin(), data.end(), dataMask.begin(),
+                   processedDataBuf.begin(), std::bit_or<uint8_t>());
+
+    return (processedDataBuf == processedReqBuf);
+}
+
+static bool isCmdAllowlisted(uint8_t busId, uint8_t targetAddr,
+                             std::vector<uint8_t>& writeData)
+{
+    std::vector<i2cControllerWRAllowlist>& allowList = getWRAllowlist();
+    for (const auto& wlEntry : allowList)
+    {
+        if ((busId == wlEntry.busId) &&
+            ((targetAddr | wlEntry.targetAddrMask) ==
+             (wlEntry.targetAddr | wlEntry.targetAddrMask)))
+        {
+            const std::vector<uint8_t>& dataMask = wlEntry.dataMask;
+            // Skip as no-match, if requested write data is more than the
+            // write data mask size
+            if (writeData.size() > dataMask.size())
+            {
+                continue;
+            }
+            if (isWriteDataAllowlisted(wlEntry.data, dataMask, writeData))
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+#else
+static bool populateI2CControllerWRAllowlist()
+{
+    lg2::info("I2C_WHITELIST_CHECK is disabled, do not populate allowlist");
+    return true;
+}
+#endif // ENABLE_I2C_WHITELIST_CHECK
+
+/** @brief implements controller write read IPMI command which can be used for
+ * low-level I2C/SMBus write, read or write-read access
+ *  @param isPrivateBus -to indicate private bus usage
+ *  @param busId - bus id
+ *  @param channelNum - channel number
+ *  @param reserved - skip 1 bit
+ *  @param targetAddr - target address
+ *  @param read count - number of bytes to be read
+ *  @param writeData - data to be written
+ *
+ *  @returns IPMI completion code plus response data
+ *   - readData - i2c response data
+ */
+ipmi::RspType<std::vector<uint8_t>> ipmiControllerWriteRead(
+    [[maybe_unused]] bool isPrivateBus, uint3_t busId,
+    [[maybe_unused]] uint4_t channelNum, bool reserved, uint7_t targetAddr,
+    uint8_t readCount, std::vector<uint8_t> writeData)
+{
+    if (reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    const size_t writeCount = writeData.size();
+    if (!readCount && !writeCount)
+    {
+        lg2::error("Controller write read command: Read & write count are 0");
+        return ipmi::responseInvalidFieldRequest();
+    }
+#ifdef ENABLE_I2C_WHITELIST_CHECK
+    if (!isCmdAllowlisted(static_cast<uint8_t>(busId),
+                          static_cast<uint8_t>(targetAddr), writeData))
+    {
+        lg2::error("Controller write read request blocked!, "
+                   "bus: {BUS}, addr: {ADDR}",
+                   "BUS", static_cast<uint8_t>(busId), "ADDR", lg2::hex,
+                   static_cast<uint8_t>(targetAddr));
+    }
+#endif // ENABLE_I2C_WHITELIST_CHECK
+    std::vector<uint8_t> readBuf(readCount);
+    std::string i2cBus =
+        "/dev/i2c-" + std::to_string(static_cast<uint8_t>(busId));
+
+    ipmi::Cc ret = ipmi::i2cWriteRead(i2cBus, static_cast<uint8_t>(targetAddr),
+                                      writeData, readBuf);
+    if (ret != ipmi::ccSuccess)
+    {
+        return ipmi::response(ret);
+    }
+    return ipmi::responseSuccess(readBuf);
+}
+
+void registerNetFnAppFunctions()
+{
+    // <Get Device ID>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetDeviceId, ipmi::Privilege::User,
+                          ipmiAppGetDeviceId);
+
+    // <Get BT Interface Capabilities>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetBtIfaceCapabilities,
+                          ipmi::Privilege::User, ipmiAppGetBtCapabilities);
+
+    // <Reset Watchdog Timer>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdResetWatchdogTimer,
+                          ipmi::Privilege::Operator, ipmiAppResetWatchdogTimer);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetSessionInfo, ipmi::Privilege::User,
+                          ipmiAppGetSessionInfo);
+
+    // <Set Watchdog Timer>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetWatchdogTimer,
+                          ipmi::Privilege::Operator, ipmiSetWatchdogTimer);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdCloseSession, ipmi::Privilege::Callback,
+                          ipmiAppCloseSession);
+
+    // <Get Watchdog Timer>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetWatchdogTimer, ipmi::Privilege::User,
+                          ipmiGetWatchdogTimer);
+
+    // <Get Self Test Results>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetSelfTestResults,
+                          ipmi::Privilege::User, ipmiAppGetSelfTestResults);
+
+    // <Get Device GUID>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetDeviceGuid, ipmi::Privilege::User,
+                          ipmiAppGetDeviceGuid);
+
+    // <Set ACPI Power State>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetAcpiPowerState,
+                          ipmi::Privilege::Admin, ipmiSetAcpiPowerState);
+    // <Get ACPI Power State>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetAcpiPowerState,
+                          ipmi::Privilege::User, ipmiGetAcpiPowerState);
+
+    // Note: For security reason, this command will be registered only when
+    // there are proper I2C Controller write read allowlist
+    if (populateI2CControllerWRAllowlist())
+    {
+        // Note: For security reasons, registering controller write read as
+        // admin privilege command, even though IPMI 2.0 specification allows it
+        // as operator privilege.
+        ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                              ipmi::app::cmdMasterWriteRead,
+                              ipmi::Privilege::Admin, ipmiControllerWriteRead);
+    }
+
+    // <Get System GUID Command>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetSystemGuid, ipmi::Privilege::User,
+                          ipmiAppGetSystemGuid);
+
+    // <Get Channel Cipher Suites Command>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetChannelCipherSuites,
+                          ipmi::Privilege::None, getChannelCipherSuites);
+
+    // <Get System Info Command>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetSystemInfoParameters,
+                          ipmi::Privilege::User, ipmiAppGetSystemInfo);
+    // <Set System Info Command>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetSystemInfoParameters,
+                          ipmi::Privilege::Admin, ipmiAppSetSystemInfo);
+    return;
+}
diff --git a/apphandler.hpp b/apphandler.hpp
new file mode 100644
index 0000000..56dd0f8
--- /dev/null
+++ b/apphandler.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <stdint.h>
+
+enum ipmi_app_sysinfo_params
+{
+    IPMI_SYSINFO_SET_STATE = 0x00,
+    IPMI_SYSINFO_SYSTEM_FW_VERSION = 0x01,
+    IPMI_SYSINFO_SYSTEM_NAME = 0x02,
+    IPMI_SYSINFO_PRIMARY_OS_NAME = 0x03,
+    IPMI_SYSINFO_OS_NAME = 0x04,
+    IPMI_SYSINFO_OS_VERSION = 0x05,
+    IPMI_SYSINFO_BMC_URL = 0x06,
+    IPMI_SYSINFO_OS_HYP_URL = 0x07,
+    IPMI_SYSINFO_OEM_START = 0xC0, // Start of range of OEM parameters
+};
diff --git a/chassishandler.cpp b/chassishandler.cpp
new file mode 100644
index 0000000..07e5544
--- /dev/null
+++ b/chassishandler.cpp
@@ -0,0 +1,2430 @@
+#include "config.h"
+
+#include "chassishandler.hpp"
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <limits.h>
+#include <netinet/in.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <sdbusplus/timer.hpp>
+#include <settings.hpp>
+#include <xyz/openbmc_project/Chassis/Intrusion/client.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
+#include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
+#include <xyz/openbmc_project/Control/Boot/Type/server.hpp>
+#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
+#include <xyz/openbmc_project/State/Chassis/server.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
+#include <xyz/openbmc_project/State/PowerOnHours/server.hpp>
+
+#include <array>
+#include <chrono>
+#include <cstring>
+#include <filesystem>
+#include <fstream>
+#include <future>
+#include <map>
+#include <sstream>
+#include <string>
+
+std::unique_ptr<sdbusplus::Timer> identifyTimer
+    __attribute__((init_priority(101)));
+
+static ChassisIDState chassisIDState = ChassisIDState::reserved;
+
+constexpr size_t sizeVersion = 2;
+constexpr size_t DEFAULT_IDENTIFY_TIME_OUT = 15;
+
+// PetiBoot-Specific
+static constexpr uint8_t netConfInitialBytes[] = {0x80, 0x21, 0x70, 0x62,
+                                                  0x21, 0x00, 0x01, 0x06};
+static constexpr uint8_t oemParmStart = 96;
+static constexpr uint8_t oemParmEnd = 127;
+
+static constexpr size_t cookieOffset = 1;
+static constexpr size_t versionOffset = 5;
+static constexpr size_t addrSizeOffset = 8;
+static constexpr size_t macOffset = 9;
+static constexpr size_t addrTypeOffset = 16;
+static constexpr size_t ipAddrOffset = 17;
+
+namespace ipmi
+{
+constexpr Cc ccParmNotSupported = 0x80;
+
+static inline auto responseParmNotSupported()
+{
+    return response(ccParmNotSupported);
+}
+} // namespace ipmi
+
+void registerNetFnChassisFunctions() __attribute__((constructor));
+
+// Host settings in dbus
+// Service name should be referenced by connection name got via object mapper
+const char* settings_object_name = "/org/openbmc/settings/host0";
+const char* settings_intf_name = "org.freedesktop.DBus.Properties";
+const char* identify_led_object_name =
+    "/xyz/openbmc_project/led/groups/enclosure_identify";
+
+constexpr auto SETTINGS_ROOT = "/";
+constexpr auto SETTINGS_MATCH = "host0";
+
+constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
+constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
+
+static constexpr auto chassisStateRoot = "/xyz/openbmc_project/state";
+static constexpr auto chassisPOHStateIntf =
+    "xyz.openbmc_project.State.PowerOnHours";
+static constexpr auto pohCounterProperty = "POHCounter";
+static constexpr auto match = "chassis0";
+const static constexpr char chassisCapIntf[] =
+    "xyz.openbmc_project.Control.ChassisCapabilities";
+const static constexpr char chassisIntrusionProp[] = "ChassisIntrusionEnabled";
+const static constexpr char chassisFrontPanelLockoutProp[] =
+    "ChassisFrontPanelLockoutEnabled";
+const static constexpr char chassisNMIProp[] = "ChassisNMIEnabled";
+const static constexpr char chassisPowerInterlockProp[] =
+    "ChassisPowerInterlockEnabled";
+const static constexpr char chassisFRUDevAddrProp[] = "FRUDeviceAddress";
+const static constexpr char chassisSDRDevAddrProp[] = "SDRDeviceAddress";
+const static constexpr char chassisSELDevAddrProp[] = "SELDeviceAddress";
+const static constexpr char chassisSMDevAddrProp[] = "SMDeviceAddress";
+const static constexpr char chassisBridgeDevAddrProp[] = "BridgeDeviceAddress";
+static constexpr uint8_t chassisCapAddrMask = 0xfe;
+static constexpr const char* powerButtonIntf =
+    "xyz.openbmc_project.Chassis.Buttons.Power";
+static constexpr const char* powerButtonPath =
+    "/xyz/openbmc_project/Chassis/Buttons/Power0";
+static constexpr const char* resetButtonIntf =
+    "xyz.openbmc_project.Chassis.Buttons.Reset";
+static constexpr const char* resetButtonPath =
+    "/xyz/openbmc_project/Chassis/Buttons/Reset0";
+
+// Phosphor Host State manager
+namespace State = sdbusplus::server::xyz::openbmc_project::state;
+namespace fs = std::filesystem;
+
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+using namespace sdbusplus::server::xyz::openbmc_project::control::boot;
+using Intrusion = sdbusplus::client::xyz::openbmc_project::chassis::Intrusion<>;
+
+namespace chassis
+{
+namespace internal
+{
+
+constexpr auto bootSettingsPath = "/xyz/openbmc_project/control/host0/boot";
+constexpr auto bootEnableIntf = "xyz.openbmc_project.Object.Enable";
+constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
+constexpr auto bootTypeIntf = "xyz.openbmc_project.Control.Boot.Type";
+constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source";
+constexpr auto bootSettingsOneTimePath =
+    "/xyz/openbmc_project/control/host0/boot/one_time";
+constexpr auto bootOneTimeIntf = "xyz.openbmc_project.Object.Enable";
+
+constexpr auto powerRestoreIntf =
+    "xyz.openbmc_project.Control.Power.RestorePolicy";
+sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection());
+
+namespace cache
+{
+
+std::unique_ptr<settings::Objects> objectsPtr = nullptr;
+
+settings::Objects& getObjects()
+{
+    if (objectsPtr == nullptr)
+    {
+        objectsPtr = std::make_unique<settings::Objects>(
+            dbus, std::vector<std::string>{bootModeIntf, bootTypeIntf,
+                                           bootSourceIntf, powerRestoreIntf});
+    }
+    return *objectsPtr;
+}
+
+} // namespace cache
+} // namespace internal
+} // namespace chassis
+
+namespace poh
+{
+
+constexpr auto minutesPerCount = 60;
+
+} // namespace poh
+
+int getHostNetworkData(ipmi::message::Payload& payload)
+{
+    ipmi::PropertyMap properties;
+    int rc = 0;
+    uint8_t addrSize = ipmi::network::IPV4_ADDRESS_SIZE_BYTE;
+
+    try
+    {
+        // TODO There may be cases where an interface is implemented by multiple
+        // objects,to handle such cases we are interested on that object
+        //  which are on interested busname.
+        //  Currenlty mapper doesn't give the readable busname(gives busid)
+        //  so we can't match with bus name so giving some object specific info
+        //  as SETTINGS_MATCH.
+        //  Later SETTINGS_MATCH will be replaced with busname.
+
+        sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
+
+        auto ipObjectInfo = ipmi::getDbusObject(bus, IP_INTERFACE,
+                                                SETTINGS_ROOT, SETTINGS_MATCH);
+
+        auto macObjectInfo = ipmi::getDbusObject(bus, MAC_INTERFACE,
+                                                 SETTINGS_ROOT, SETTINGS_MATCH);
+
+        properties = ipmi::getAllDbusProperties(
+            bus, ipObjectInfo.second, ipObjectInfo.first, IP_INTERFACE);
+        auto variant = ipmi::getDbusProperty(
+            bus, macObjectInfo.second, macObjectInfo.first, MAC_INTERFACE,
+            "MACAddress");
+
+        auto ipAddress = std::get<std::string>(properties["Address"]);
+
+        auto gateway = std::get<std::string>(properties["Gateway"]);
+
+        auto prefix = std::get<uint8_t>(properties["PrefixLength"]);
+
+        uint8_t isStatic =
+            (std::get<std::string>(properties["Origin"]) ==
+             "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
+                ? 1
+                : 0;
+
+        auto MACAddress = std::get<std::string>(variant);
+
+        // it is expected here that we should get the valid data
+        // but we may also get the default values.
+        // Validation of the data is done by settings.
+        //
+        // if mac address is default mac address then
+        // don't send blank override.
+        if ((MACAddress == ipmi::network::DEFAULT_MAC_ADDRESS))
+        {
+            rc = -1;
+            return rc;
+        }
+        // if addr is static then ipaddress,gateway,prefix
+        // should not be default one,don't send blank override.
+        if (isStatic)
+        {
+            if ((ipAddress == ipmi::network::DEFAULT_ADDRESS) ||
+                (gateway == ipmi::network::DEFAULT_ADDRESS) || (!prefix))
+            {
+                rc = -1;
+                return rc;
+            }
+        }
+
+        std::string token;
+        std::stringstream ss(MACAddress);
+
+        // First pack macOffset no of bytes in payload.
+        // Latter this PetiBoot-Specific data will be populated.
+        std::vector<uint8_t> payloadInitialBytes(macOffset);
+        payload.pack(payloadInitialBytes);
+
+        while (std::getline(ss, token, ':'))
+        {
+            payload.pack(stoi(token, nullptr, 16));
+        }
+
+        payload.pack(0x00);
+
+        payload.pack(isStatic);
+
+        uint8_t addressFamily = (std::get<std::string>(properties["Type"]) ==
+                                 "xyz.openbmc_project.Network.IP.Protocol.IPv4")
+                                    ? AF_INET
+                                    : AF_INET6;
+
+        addrSize = (addressFamily == AF_INET)
+                       ? ipmi::network::IPV4_ADDRESS_SIZE_BYTE
+                       : ipmi::network::IPV6_ADDRESS_SIZE_BYTE;
+
+        // ipaddress and gateway would be in IPv4 format
+        std::vector<uint8_t> addrInBinary(addrSize);
+        inet_pton(addressFamily, ipAddress.c_str(),
+                  reinterpret_cast<void*>(addrInBinary.data()));
+
+        payload.pack(addrInBinary);
+
+        payload.pack(prefix);
+
+        std::vector<uint8_t> gatewayDetails(addrSize);
+        inet_pton(addressFamily, gateway.c_str(),
+                  reinterpret_cast<void*>(gatewayDetails.data()));
+        payload.pack(gatewayDetails);
+    }
+    catch (const InternalFailure& e)
+    {
+        commit<InternalFailure>();
+        rc = -1;
+        return rc;
+    }
+
+    // PetiBoot-Specific
+    // If success then copy the first 9 bytes to the payload message
+    // payload first 2 bytes contain the parameter values. Skip that 2 bytes.
+    uint8_t skipFirstTwoBytes = 2;
+    size_t payloadSize = payload.size();
+    uint8_t* configDataStartingAddress = payload.data() + skipFirstTwoBytes;
+
+    if (payloadSize < skipFirstTwoBytes + sizeof(netConfInitialBytes))
+    {
+        lg2::error("Invalid net config");
+        rc = -1;
+        return rc;
+    }
+    std::copy(netConfInitialBytes,
+              netConfInitialBytes + sizeof(netConfInitialBytes),
+              configDataStartingAddress);
+
+    if (payloadSize < skipFirstTwoBytes + addrSizeOffset + sizeof(addrSize))
+    {
+        lg2::error("Invalid length of address size");
+        rc = -1;
+        return rc;
+    }
+    std::copy(&addrSize, &(addrSize) + sizeof(addrSize),
+              configDataStartingAddress + addrSizeOffset);
+
+#ifdef _IPMI_DEBUG_
+    std::printf("\n===Printing the IPMI Formatted Data========\n");
+
+    for (uint8_t pos = 0; pos < index; pos++)
+    {
+        std::printf("%02x ", payloadStartingAddress[pos]);
+    }
+#endif
+
+    return rc;
+}
+
+/** @brief convert IPv4 and IPv6 addresses from binary to text form.
+ *  @param[in] family - IPv4/Ipv6
+ *  @param[in] data - req data pointer.
+ *  @param[in] offset - offset in the data.
+ *  @param[in] addrSize - size of the data which needs to be read from offset.
+ *  @returns address in text form.
+ */
+
+std::string getAddrStr(uint8_t family, uint8_t* data, uint8_t offset,
+                       uint8_t addrSize)
+{
+    char ipAddr[INET6_ADDRSTRLEN] = {};
+
+    switch (family)
+    {
+        case AF_INET:
+        {
+            struct sockaddr_in addr4{};
+            std::memcpy(&addr4.sin_addr.s_addr, &data[offset], addrSize);
+
+            inet_ntop(AF_INET, &addr4.sin_addr, ipAddr, INET_ADDRSTRLEN);
+
+            break;
+        }
+        case AF_INET6:
+        {
+            struct sockaddr_in6 addr6{};
+            std::memcpy(&addr6.sin6_addr.s6_addr, &data[offset], addrSize);
+
+            inet_ntop(AF_INET6, &addr6.sin6_addr, ipAddr, INET6_ADDRSTRLEN);
+
+            break;
+        }
+        default:
+        {
+            return {};
+        }
+    }
+
+    return ipAddr;
+}
+
+ipmi::Cc setHostNetworkData(ipmi::message::Payload& data)
+{
+    using namespace std::string_literals;
+    std::string hostNetworkConfig;
+    std::string mac("00:00:00:00:00:00");
+    std::string ipAddress, gateway;
+    std::string addrOrigin{0};
+    uint8_t addrSize{0};
+    std::string addressOrigin =
+        "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
+    std::string addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
+    uint8_t prefix{0};
+    uint8_t family = AF_INET;
+
+    // cookie starts from second byte
+    // version starts from sixth byte
+
+    try
+    {
+        do
+        {
+            // cookie ==  0x21 0x70 0x62 0x21
+            data.trailingOk = true;
+            auto msgLen = data.size();
+            std::vector<uint8_t> msgPayloadBytes(msgLen);
+            if (data.unpack(msgPayloadBytes) != 0 || !data.fullyUnpacked())
+            {
+                lg2::error("Error in unpacking message of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+
+            uint8_t* msgPayloadStartingPos = msgPayloadBytes.data();
+            constexpr size_t cookieSize = 4;
+            if (msgLen < cookieOffset + cookieSize)
+            {
+                lg2::error("Error in cookie getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            if (std::equal(msgPayloadStartingPos + cookieOffset,
+                           msgPayloadStartingPos + cookieOffset + cookieSize,
+                           (netConfInitialBytes + cookieOffset)) != 0)
+            {
+                // all cookie == 0
+                if (std::all_of(msgPayloadStartingPos + cookieOffset,
+                                msgPayloadStartingPos + cookieOffset +
+                                    cookieSize,
+                                [](int i) { return i == 0; }) == true)
+                {
+                    // need to zero out the network settings.
+                    break;
+                }
+
+                lg2::error("Invalid Cookie");
+                elog<InternalFailure>();
+            }
+
+            // vesion == 0x00 0x01
+            if (msgLen < versionOffset + sizeVersion)
+            {
+                lg2::error("Error in version getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            if (std::equal(msgPayloadStartingPos + versionOffset,
+                           msgPayloadStartingPos + versionOffset + sizeVersion,
+                           (netConfInitialBytes + versionOffset)) != 0)
+            {
+                lg2::error("Invalid Version");
+                elog<InternalFailure>();
+            }
+
+            if (msgLen < macOffset + 6)
+            {
+                lg2::error(
+                    "Error in mac address getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            std::stringstream result;
+            std::copy((msgPayloadStartingPos + macOffset),
+                      (msgPayloadStartingPos + macOffset + 5),
+                      std::ostream_iterator<int>(result, ":"));
+            mac = result.str();
+
+            if (msgLen < addrTypeOffset + sizeof(decltype(addrOrigin)))
+            {
+                lg2::error(
+                    "Error in original address getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            std::copy(msgPayloadStartingPos + addrTypeOffset,
+                      msgPayloadStartingPos + addrTypeOffset +
+                          sizeof(decltype(addrOrigin)),
+                      std::ostream_iterator<int>(result, ""));
+            addrOrigin = result.str();
+
+            if (!addrOrigin.empty())
+            {
+                addressOrigin =
+                    "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
+            }
+
+            if (msgLen < addrSizeOffset + sizeof(decltype(addrSize)))
+            {
+                lg2::error(
+                    "Error in address size getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            // Get the address size
+            std::copy(msgPayloadStartingPos + addrSizeOffset,
+                      (msgPayloadStartingPos + addrSizeOffset +
+                       sizeof(decltype(addrSize))),
+                      &addrSize);
+
+            uint8_t prefixOffset = ipAddrOffset + addrSize;
+            if (msgLen < prefixOffset + sizeof(decltype(prefix)))
+            {
+                lg2::error("Error in prefix getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            // std::copy(msgPayloadStartingPos + prefixOffset,
+            //           msgPayloadStartingPos + prefixOffset +
+            //               sizeof(decltype(prefix)),
+            //           &prefix);
+            // Workaround compiler misdetecting out of bounds memcpy
+            prefix = msgPayloadStartingPos[prefixOffset];
+
+            uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
+            if (addrSize != ipmi::network::IPV4_ADDRESS_SIZE_BYTE)
+            {
+                addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
+                family = AF_INET6;
+            }
+
+            if (msgLen < ipAddrOffset + addrSize)
+            {
+                lg2::error("Error in IP address getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            ipAddress = getAddrStr(family, msgPayloadStartingPos, ipAddrOffset,
+                                   addrSize);
+
+            if (msgLen < gatewayOffset + addrSize)
+            {
+                lg2::error(
+                    "Error in gateway address getting of setHostNetworkData");
+                return ipmi::ccReqDataLenInvalid;
+            }
+            gateway = getAddrStr(family, msgPayloadStartingPos, gatewayOffset,
+                                 addrSize);
+
+        } while (0);
+
+        // Cookie == 0 or it is a valid cookie
+        hostNetworkConfig +=
+            "ipaddress="s + ipAddress + ",prefix="s + std::to_string(prefix) +
+            ",gateway="s + gateway + ",mac="s + mac + ",addressOrigin="s +
+            addressOrigin;
+
+        sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
+
+        auto ipObjectInfo = ipmi::getDbusObject(bus, IP_INTERFACE,
+                                                SETTINGS_ROOT, SETTINGS_MATCH);
+        auto macObjectInfo = ipmi::getDbusObject(bus, MAC_INTERFACE,
+                                                 SETTINGS_ROOT, SETTINGS_MATCH);
+        // set the dbus property
+        ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
+                              IP_INTERFACE, "Address", std::string(ipAddress));
+        ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
+                              IP_INTERFACE, "PrefixLength", prefix);
+        ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
+                              IP_INTERFACE, "Origin", addressOrigin);
+        ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
+                              IP_INTERFACE, "Gateway", std::string(gateway));
+        ipmi::setDbusProperty(
+            bus, ipObjectInfo.second, ipObjectInfo.first, IP_INTERFACE, "Type",
+            std::string("xyz.openbmc_project.Network.IP.Protocol.IPv4"));
+        ipmi::setDbusProperty(bus, macObjectInfo.second, macObjectInfo.first,
+                              MAC_INTERFACE, "MACAddress", std::string(mac));
+
+        lg2::debug("Network configuration changed: {NETWORKCONFIG}",
+                   "NETWORKCONFIG", hostNetworkConfig);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        commit<InternalFailure>();
+        lg2::error("Error in ipmiChassisSetSysBootOptions call");
+        return ipmi::ccUnspecifiedError;
+    }
+
+    return ipmi::ccSuccess;
+}
+
+uint32_t getPOHCounter()
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    auto chassisStateObj =
+        ipmi::getDbusObject(bus, chassisPOHStateIntf, chassisStateRoot, match);
+
+    auto service =
+        ipmi::getService(bus, chassisPOHStateIntf, chassisStateObj.first);
+
+    auto propValue =
+        ipmi::getDbusProperty(bus, service, chassisStateObj.first,
+                              chassisPOHStateIntf, pohCounterProperty);
+
+    return std::get<uint32_t>(propValue);
+}
+
+/** @brief Implements the get chassis capabilities command
+ *
+ *  @returns IPMI completion code plus response data
+ *  chassisCapFlags        - chassis capability flag
+ *  chassisFRUInfoDevAddr  - chassis FRU info Device Address
+ *  chassisSDRDevAddr      - chassis SDR device address
+ *  chassisSELDevAddr      - chassis SEL device address
+ *  chassisSMDevAddr       - chassis system management device address
+ *  chassisBridgeDevAddr   - chassis bridge device address
+ */
+ipmi::RspType<bool,    // chassis intrusion sensor
+              bool,    // chassis Front panel lockout
+              bool,    // chassis NMI
+              bool,    // chassis power interlock
+              uint4_t, // reserved
+              uint8_t, // chassis FRU info Device Address
+              uint8_t, // chassis SDR device address
+              uint8_t, // chassis SEL device address
+              uint8_t, // chassis system management device address
+              uint8_t  // chassis bridge device address
+              >
+    ipmiGetChassisCap()
+{
+    ipmi::PropertyMap properties;
+    try
+    {
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+        ipmi::DbusObjectInfo chassisCapObject =
+            ipmi::getDbusObject(bus, chassisCapIntf);
+
+        // capabilities flags
+        // [7..4] - reserved
+        // [3] – 1b = provides power interlock  (IPM 1.5)
+        // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
+        // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis
+        // has capabilities
+        //            to lock out external power control and reset button or
+        //            front panel interfaces and/or detect tampering with those
+        //            interfaces).
+        // [0] -1b = Chassis provides intrusion (physical security) sensor.
+        // set to default value 0x0.
+
+        properties =
+            ipmi::getAllDbusProperties(bus, chassisCapObject.second,
+                                       chassisCapObject.first, chassisCapIntf);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to fetch Chassis Capability properties: {ERROR}",
+                   "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    bool* chassisIntrusionFlag =
+        std::get_if<bool>(&properties[chassisIntrusionProp]);
+    if (chassisIntrusionFlag == nullptr)
+    {
+        lg2::error("Error to get chassis Intrusion flags");
+        return ipmi::responseUnspecifiedError();
+    }
+    bool* chassisFrontPanelFlag =
+        std::get_if<bool>(&properties[chassisFrontPanelLockoutProp]);
+    if (chassisFrontPanelFlag == nullptr)
+    {
+        lg2::error("Error to get chassis intrusion flags");
+        return ipmi::responseUnspecifiedError();
+    }
+    bool* chassisNMIFlag = std::get_if<bool>(&properties[chassisNMIProp]);
+    if (chassisNMIFlag == nullptr)
+    {
+        lg2::error("Error to get chassis NMI flags");
+        return ipmi::responseUnspecifiedError();
+    }
+    bool* chassisPowerInterlockFlag =
+        std::get_if<bool>(&properties[chassisPowerInterlockProp]);
+    if (chassisPowerInterlockFlag == nullptr)
+    {
+        lg2::error("Error to get chassis power interlock flags");
+        return ipmi::responseUnspecifiedError();
+    }
+    uint8_t* chassisFRUInfoDevAddr =
+        std::get_if<uint8_t>(&properties[chassisFRUDevAddrProp]);
+    if (chassisFRUInfoDevAddr == nullptr)
+    {
+        lg2::error("Error to get chassis FRU info device address");
+        return ipmi::responseUnspecifiedError();
+    }
+    uint8_t* chassisSDRDevAddr =
+        std::get_if<uint8_t>(&properties[chassisSDRDevAddrProp]);
+    if (chassisSDRDevAddr == nullptr)
+    {
+        lg2::error("Error to get chassis SDR device address");
+        return ipmi::responseUnspecifiedError();
+    }
+    uint8_t* chassisSELDevAddr =
+        std::get_if<uint8_t>(&properties[chassisSELDevAddrProp]);
+    if (chassisSELDevAddr == nullptr)
+    {
+        lg2::error("Error to get chassis SEL device address");
+        return ipmi::responseUnspecifiedError();
+    }
+    uint8_t* chassisSMDevAddr =
+        std::get_if<uint8_t>(&properties[chassisSMDevAddrProp]);
+    if (chassisSMDevAddr == nullptr)
+    {
+        lg2::error("Error to get chassis SM device address");
+        return ipmi::responseUnspecifiedError();
+    }
+    uint8_t* chassisBridgeDevAddr =
+        std::get_if<uint8_t>(&properties[chassisBridgeDevAddrProp]);
+    if (chassisBridgeDevAddr == nullptr)
+    {
+        lg2::error("Error to get chassis bridge device address");
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(
+        *chassisIntrusionFlag, *chassisFrontPanelFlag, *chassisNMIFlag,
+        *chassisPowerInterlockFlag, 0, *chassisFRUInfoDevAddr,
+        *chassisSDRDevAddr, *chassisSELDevAddr, *chassisSMDevAddr,
+        *chassisBridgeDevAddr);
+}
+
+/** @brief implements set chassis capalibities command
+ *  @param intrusion        - chassis intrusion
+ *  @param fpLockout        - frontpannel lockout
+ *  @param reserved1        - skip one bit
+ *  @param fruDeviceAddr    - chassis FRU info Device Address
+ *  @param sdrDeviceAddr    - chassis SDR device address
+ *  @param selDeviceAddr    - chassis SEL device address
+ *  @param smDeviceAddr     - chassis system management device address
+ *  @param bridgeDeviceAddr - chassis bridge device address
+ *
+ *  @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiSetChassisCap(
+    bool intrusion, bool fpLockout, uint6_t reserved1,
+
+    uint8_t fruDeviceAddr,
+
+    uint8_t sdrDeviceAddr,
+
+    uint8_t selDeviceAddr,
+
+    uint8_t smDeviceAddr,
+
+    uint8_t bridgeDeviceAddr)
+{
+    // check input data
+    if (reserved1 != 0)
+    {
+        lg2::error("Unsupported request parameter");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if ((fruDeviceAddr & ~chassisCapAddrMask) != 0)
+    {
+        lg2::error("Unsupported request parameter(FRU Addr) for REQ={REQ}",
+                   "REQ", lg2::hex, fruDeviceAddr);
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if ((sdrDeviceAddr & ~chassisCapAddrMask) != 0)
+    {
+        lg2::error("Unsupported request parameter(SDR Addr) for REQ={REQ}",
+                   "REQ", lg2::hex, sdrDeviceAddr);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if ((selDeviceAddr & ~chassisCapAddrMask) != 0)
+    {
+        lg2::error("Unsupported request parameter(SEL Addr) for REQ={REQ}",
+                   "REQ", lg2::hex, selDeviceAddr);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if ((smDeviceAddr & ~chassisCapAddrMask) != 0)
+    {
+        lg2::error("Unsupported request parameter(SM Addr) for REQ={REQ}",
+                   "REQ", lg2::hex, smDeviceAddr);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if ((bridgeDeviceAddr & ~chassisCapAddrMask) != 0)
+    {
+        lg2::error("Unsupported request parameter(Bridge Addr) for REQ={REQ}",
+                   "REQ", lg2::hex, bridgeDeviceAddr);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    try
+    {
+        sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
+        ipmi::DbusObjectInfo chassisCapObject =
+            ipmi::getDbusObject(bus, chassisCapIntf);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisIntrusionProp, intrusion);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisFrontPanelLockoutProp, fpLockout);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisFRUDevAddrProp, fruDeviceAddr);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisSDRDevAddrProp, sdrDeviceAddr);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisSELDevAddrProp, selDeviceAddr);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisSMDevAddrProp, smDeviceAddr);
+
+        ipmi::setDbusProperty(bus, chassisCapObject.second,
+                              chassisCapObject.first, chassisCapIntf,
+                              chassisBridgeDevAddrProp, bridgeDeviceAddr);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to set chassis capability properties: {ERR}", "ERR",
+                   e);
+        return ipmi::responseUnspecifiedError();
+    }
+    return ipmi::responseSuccess();
+}
+
+//------------------------------------------
+// Calls into Host State Manager Dbus object
+//------------------------------------------
+int initiateHostStateTransition(ipmi::Context::ptr& ctx,
+                                State::Host::Transition transition)
+{
+    // OpenBMC Host State Manager dbus framework
+    constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";
+    constexpr auto hostStateIntf = "xyz.openbmc_project.State.Host";
+
+    // Convert to string equivalent of the passed in transition enum.
+    auto request =
+        sdbusplus::common::xyz::openbmc_project::state::convertForMessage(
+            transition);
+
+    std::string service;
+    boost::system::error_code ec =
+        ipmi::getService(ctx, hostStateIntf, hostStatePath, service);
+
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, hostStatePath, hostStateIntf,
+                                   "RequestedHostTransition", request);
+    }
+    if (ec)
+    {
+        lg2::error(
+            "Failed to initiate transition for request {REQUEST}: {EXCEPTION}",
+            "REQUEST", request, "EXCEPTION", ec.message());
+        return -1;
+    }
+    lg2::info(
+        "Transition request {REQUEST} initiated successfully by user {USERID}",
+        "REQUEST", request, "USERID", ctx->userId);
+    return 0;
+}
+
+//------------------------------------------
+// Calls into Chassis State Manager Dbus object
+//------------------------------------------
+int initiateChassisStateTransition(ipmi::Context::ptr& ctx,
+                                   State::Chassis::Transition transition)
+{
+    // OpenBMC Chassis State Manager dbus framework
+    constexpr auto chassisStatePath = "/xyz/openbmc_project/state/chassis0";
+    constexpr auto chassisStateIntf = "xyz.openbmc_project.State.Chassis";
+
+    std::string service;
+    boost::system::error_code ec =
+        ipmi::getService(ctx, chassisStateIntf, chassisStatePath, service);
+
+    // Convert to string equivalent of the passed in transition enum.
+    auto request =
+        sdbusplus::common::xyz::openbmc_project::state::convertForMessage(
+            transition);
+
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, chassisStatePath,
+                                   chassisStateIntf, "RequestedPowerTransition",
+                                   request);
+    }
+    if (ec)
+    {
+        lg2::error("Failed to initiate transition {REQUEST}: {EXCEPTION}",
+                   "REQUEST", request, "EXCEPTION", ec.message());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+//------------------------------------------
+// Trigger an NMI on the host via dbus
+//------------------------------------------
+static int doNmi(ipmi::Context::ptr& ctx)
+{
+    constexpr const char* nmiIntfName = "xyz.openbmc_project.Control.Host.NMI";
+    ipmi::DbusObjectInfo nmiObj{};
+    boost::system::error_code ec;
+
+    ec = ipmi::getDbusObject(ctx, nmiIntfName, nmiObj);
+    if (ec)
+    {
+        lg2::error("Failed to find NMI service: {ERROR}", "ERROR",
+                   ec.message());
+        return -1;
+    }
+
+    ec = ipmi::callDbusMethod(ctx, nmiObj.second, nmiObj.first, nmiIntfName,
+                              "NMI");
+    if (ec)
+    {
+        lg2::error("NMI call failed: {ERROR}", "ERROR", ec.message());
+        elog<InternalFailure>();
+        return -1;
+    }
+
+    return 0;
+}
+
+namespace power_policy
+{
+
+using namespace sdbusplus::server::xyz::openbmc_project::control::power;
+using IpmiValue = uint8_t;
+using DbusValue = RestorePolicy::Policy;
+
+const std::map<DbusValue, IpmiValue> dbusToIpmi = {
+    {RestorePolicy::Policy::AlwaysOff, 0x00},
+    {RestorePolicy::Policy::Restore, 0x01},
+    {RestorePolicy::Policy::AlwaysOn, 0x02},
+    {RestorePolicy::Policy::None, 0x03}};
+
+static constexpr uint8_t noChange = 0x03;
+static constexpr uint8_t allSupport = 0x01 | 0x02 | 0x04;
+
+/* helper function for Get Chassis Status Command
+ */
+std::optional<uint2_t> getPowerRestorePolicy()
+{
+    uint2_t restorePolicy = 0;
+    using namespace chassis::internal;
+
+    settings::Objects& objects = cache::getObjects();
+
+    try
+    {
+        const auto& powerRestoreSetting =
+            objects.map.at(powerRestoreIntf).front();
+        ipmi::Value result = ipmi::getDbusProperty(
+            *getSdBus(),
+            objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
+            powerRestoreSetting.c_str(), powerRestoreIntf,
+            "PowerRestorePolicy");
+        auto powerRestore = RestorePolicy::convertPolicyFromString(
+            std::get<std::string>(result));
+        restorePolicy = dbusToIpmi.at(powerRestore);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "Failed to fetch pgood property ({PATH}/{INTERFACE}): {ERROR}",
+            "PATH", objects.map.at(powerRestoreIntf).front(), "INTERFACE",
+            powerRestoreIntf, "ERROR", e);
+        cache::objectsPtr.reset();
+        return std::nullopt;
+    }
+    return std::make_optional(restorePolicy);
+}
+
+/*
+ * getPowerStatus
+ * helper function for Get Chassis Status Command
+ * return - optional value for pgood (no value on error)
+ */
+std::optional<bool> getPowerStatus()
+{
+    bool powerGood = false;
+    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+    try
+    {
+        constexpr const char* chassisStatePath =
+            "/xyz/openbmc_project/state/chassis0";
+        constexpr const char* chassisStateIntf =
+            "xyz.openbmc_project.State.Chassis";
+        auto service =
+            ipmi::getService(*busp, chassisStateIntf, chassisStatePath);
+
+        ipmi::Value powerState =
+            ipmi::getDbusProperty(*busp, service, chassisStatePath,
+                                  chassisStateIntf, "CurrentPowerState");
+        std::string powerStateStr = std::get<std::string>(powerState);
+        if (powerStateStr.ends_with(".On") ||
+            powerStateStr.ends_with(".TransitioningToOff"))
+        {
+            powerGood = true;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        try
+        {
+            // FIXME: some legacy modules use the older path; try that next
+            constexpr const char* legacyPwrCtrlObj =
+                "/org/openbmc/control/power0";
+            constexpr const char* legacyPwrCtrlIntf =
+                "org.openbmc.control.Power";
+            auto service =
+                ipmi::getService(*busp, legacyPwrCtrlIntf, legacyPwrCtrlObj);
+
+            ipmi::Value variant = ipmi::getDbusProperty(
+                *busp, service, legacyPwrCtrlObj, legacyPwrCtrlIntf, "pgood");
+            powerGood = static_cast<bool>(std::get<int>(variant));
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Failed to fetch pgood property: {ERROR}", "ERROR", e);
+            return std::nullopt;
+        }
+    }
+    return std::make_optional(powerGood);
+}
+
+/*
+ * getACFailStatus
+ * helper function for Get Chassis Status Command
+ * return - bool value for ACFail (false on error)
+ */
+bool getACFailStatus()
+{
+    constexpr const char* powerControlObj =
+        "/xyz/openbmc_project/Chassis/Control/Power0";
+    constexpr const char* powerControlIntf =
+        "xyz.openbmc_project.Chassis.Control.Power";
+    bool acFail = false;
+    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
+    try
+    {
+        auto service =
+            ipmi::getService(*bus, powerControlIntf, powerControlObj);
+
+        ipmi::Value variant = ipmi::getDbusProperty(
+            *bus, service, powerControlObj, powerControlIntf, "PFail");
+        acFail = std::get<bool>(variant);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "Failed to fetch PFail property ({PATH}/{INTERFACE}): {ERROR}",
+            "PATH", powerControlObj, "INTERFACE", powerControlIntf, "ERROR", e);
+    }
+    return acFail;
+}
+} // namespace power_policy
+
+static std::optional<bool> getButtonDisabled(ipmi::Context::ptr& ctx,
+                                             const std::string& buttonPath,
+                                             const std::string& buttonIntf)
+{
+    bool buttonDisabled = false;
+    boost::system::error_code ec;
+    std::string service;
+    ec = ipmi::getService(ctx, buttonIntf, buttonPath, service);
+    if (!ec)
+    {
+        bool enabled;
+        ec = ipmi::getDbusProperty(ctx, service, buttonPath, buttonIntf,
+                                   "Enabled", enabled);
+        buttonDisabled = !enabled;
+    }
+
+    if (ec)
+    {
+        lg2::error("Fail to get button Enabled property ({PATH}): {ERROR}",
+                   "PATH", buttonPath, "ERROR", ec.message());
+        return std::nullopt;
+    }
+    return std::make_optional(buttonDisabled);
+}
+
+static bool setButtonDisabled(ipmi::Context::ptr& ctx,
+                              const std::string& buttonPath,
+                              const std::string& buttonIntf, bool disable)
+{
+    std::string service;
+    boost::system::error_code ec;
+    ec = ipmi::getService(ctx, buttonIntf, buttonPath, service);
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, buttonPath, buttonIntf,
+                                   "Enabled", !disable);
+    }
+    if (ec)
+    {
+        lg2::error(
+            "Fail to set button Enabled property ({SERVICE}:{PATH}): {ERROR}",
+            "SERVICE", service, "PATH", buttonPath, "ERROR", ec.message());
+        return false;
+    }
+    return true;
+}
+
+static std::optional<bool> getChassisIntrusionStatus(ipmi::Context::ptr& ctx)
+{
+    std::vector<std::string> interfaces = {std::string(Intrusion::interface)};
+    ipmi::ObjectTree objs;
+    std::string propVal;
+    std::optional<bool> ret = std::nullopt;
+
+    boost::system::error_code ec =
+        ipmi::getSubTree(ctx, interfaces, std::string("/"), 0, objs);
+
+    if (ec)
+    {
+        lg2::error("Fail to find Chassis Intrusion Interface on D-Bus "
+                   "({INTERFACE}): {ERROR}",
+                   "INTERFACE", Intrusion::interface, "ERROR", ec.message());
+        return ret;
+    }
+
+    for (const auto& [path, map] : objs)
+    {
+        for (const auto& [service, intfs] : map)
+        {
+            ec = ipmi::getDbusProperty<std::string>(
+                ctx, service, path, Intrusion::interface, "Status", propVal);
+            if (ec)
+            {
+                lg2::error("Fail to get Chassis Intrusion Status property "
+                           "({SERVICE}/{PATH}/{INTERFACE}): {ERROR}",
+                           "SERVICE", service, "PATH", path, "INTERFACE",
+                           Intrusion::interface, "ERROR", ec.message());
+            }
+            else
+            {
+                // return false if all values are Normal
+                // return true if one value is not Normal
+                // return nullopt when no value can be retrieved from D-Bus
+                auto status =
+                    sdbusplus::message::convert_from_string<Intrusion::Status>(
+                        propVal)
+                        .value();
+                if (status == Intrusion::Status::Normal)
+                {
+                    ret = std::make_optional(false);
+                }
+                else
+                {
+                    ret = std::make_optional(true);
+                    return ret;
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+//----------------------------------------------------------------------
+// Get Chassis Status commands
+//----------------------------------------------------------------------
+ipmi::RspType<bool,    // Power is on
+              bool,    // Power overload
+              bool,    // Interlock
+              bool,    // power fault
+              bool,    // power control fault
+              uint2_t, // power restore policy
+              bool,    // reserved
+
+              bool,    // AC failed
+              bool,    // last power down caused by a Power overload
+              bool,    // last power down caused by a power interlock
+              bool,    // last power down caused by power fault
+              bool,    // last ‘Power is on’ state was entered via IPMI command
+              uint3_t, // reserved
+
+              bool,    // Chassis intrusion active
+              bool,    // Front Panel Lockout active
+              bool,    // Drive Fault
+              bool,    // Cooling/fan fault detected
+              uint2_t, // Chassis Identify State
+              bool,    // Chassis Identify command and state info supported
+              bool,    // reserved
+
+              bool,    // Power off button disabled
+              bool,    // Reset button disabled
+              bool,    // Diagnostic Interrupt button disabled
+              bool,    // Standby (sleep) button disabled
+              bool,    // Power off button disable allowed
+              bool,    // Reset button disable allowed
+              bool,    // Diagnostic Interrupt button disable allowed
+              bool     // Standby (sleep) button disable allowed
+              >
+    ipmiGetChassisStatus(ipmi::Context::ptr& ctx)
+{
+    using namespace chassis::internal;
+    std::optional<uint2_t> restorePolicy =
+        power_policy::getPowerRestorePolicy();
+    std::optional<bool> powerGood = power_policy::getPowerStatus();
+    if (!restorePolicy || !powerGood)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    //  Front Panel Button Capabilities and disable/enable status(Optional)
+    std::optional<bool> powerButtonReading =
+        getButtonDisabled(ctx, powerButtonPath, powerButtonIntf);
+    // allow disable if the interface is present
+    bool powerButtonDisableAllow = static_cast<bool>(powerButtonReading);
+    // default return the button is enabled (not disabled)
+    bool powerButtonDisabled = false;
+    if (powerButtonDisableAllow)
+    {
+        // return the real value of the button status, if present
+        powerButtonDisabled = *powerButtonReading;
+    }
+
+    std::optional<bool> resetButtonReading =
+        getButtonDisabled(ctx, resetButtonPath, resetButtonIntf);
+    // allow disable if the interface is present
+    bool resetButtonDisableAllow = static_cast<bool>(resetButtonReading);
+    // default return the button is enabled (not disabled)
+    bool resetButtonDisabled = false;
+    if (resetButtonDisableAllow)
+    {
+        // return the real value of the button status, if present
+        resetButtonDisabled = *resetButtonReading;
+    }
+
+    bool powerDownAcFailed = power_policy::getACFailStatus();
+
+    bool chassisIntrusionActive = false;
+    std::optional<bool> chassisIntrusionStatus = getChassisIntrusionStatus(ctx);
+    if (chassisIntrusionStatus)
+    {
+        chassisIntrusionActive = chassisIntrusionStatus.value();
+    }
+
+    // This response has a lot of hard-coded, unsupported fields
+    // They are set to false or 0
+    constexpr bool powerOverload = false;
+    constexpr bool chassisInterlock = false;
+    constexpr bool powerFault = false;
+    constexpr bool powerControlFault = false;
+    constexpr bool powerDownOverload = false;
+    constexpr bool powerDownInterlock = false;
+    constexpr bool powerDownPowerFault = false;
+    constexpr bool powerStatusIPMI = false;
+    constexpr bool frontPanelLockoutActive = false;
+    constexpr bool driveFault = false;
+    constexpr bool coolingFanFault = false;
+    // chassisIdentifySupport set because this command is implemented
+    constexpr bool chassisIdentifySupport = true;
+    uint2_t chassisIdentifyState = types::enum_cast<uint2_t>(chassisIDState);
+    constexpr bool diagButtonDisabled = false;
+    constexpr bool sleepButtonDisabled = false;
+    constexpr bool diagButtonDisableAllow = false;
+    constexpr bool sleepButtonDisableAllow = false;
+
+    return ipmi::responseSuccess(
+        *powerGood, powerOverload, chassisInterlock, powerFault,
+        powerControlFault, *restorePolicy,
+        false, // reserved
+
+        powerDownAcFailed, powerDownOverload, powerDownInterlock,
+        powerDownPowerFault, powerStatusIPMI,
+        uint3_t(0), // reserved
+
+        chassisIntrusionActive, frontPanelLockoutActive, driveFault,
+        coolingFanFault, chassisIdentifyState, chassisIdentifySupport,
+        false, // reserved
+
+        powerButtonDisabled, resetButtonDisabled, diagButtonDisabled,
+        sleepButtonDisabled, powerButtonDisableAllow, resetButtonDisableAllow,
+        diagButtonDisableAllow, sleepButtonDisableAllow);
+}
+
+enum class IpmiRestartCause
+{
+    Unknown = 0x0,
+    RemoteCommand = 0x1,
+    ResetButton = 0x2,
+    PowerButton = 0x3,
+    WatchdogTimer = 0x4,
+    PowerPolicyAlwaysOn = 0x6,
+    PowerPolicyPreviousState = 0x7,
+    SoftReset = 0xa,
+};
+
+static IpmiRestartCause restartCauseToIpmiRestartCause(
+    State::Host::RestartCause cause)
+{
+    switch (cause)
+    {
+        case State::Host::RestartCause::Unknown:
+        {
+            return IpmiRestartCause::Unknown;
+        }
+        case State::Host::RestartCause::RemoteCommand:
+        {
+            return IpmiRestartCause::RemoteCommand;
+        }
+        case State::Host::RestartCause::ResetButton:
+        {
+            return IpmiRestartCause::ResetButton;
+        }
+        case State::Host::RestartCause::PowerButton:
+        {
+            return IpmiRestartCause::PowerButton;
+        }
+        case State::Host::RestartCause::WatchdogTimer:
+        {
+            return IpmiRestartCause::WatchdogTimer;
+        }
+        case State::Host::RestartCause::PowerPolicyAlwaysOn:
+        {
+            return IpmiRestartCause::PowerPolicyAlwaysOn;
+        }
+        case State::Host::RestartCause::PowerPolicyPreviousState:
+        {
+            return IpmiRestartCause::PowerPolicyPreviousState;
+        }
+        case State::Host::RestartCause::SoftReset:
+        {
+            return IpmiRestartCause::SoftReset;
+        }
+        default:
+        {
+            return IpmiRestartCause::Unknown;
+        }
+    }
+}
+
+/*
+ * getRestartCause
+ * helper function for Get Host restart cause Command
+ * return - optional value for RestartCause (no value on error)
+ */
+static std::optional<uint4_t> getRestartCause(ipmi::Context::ptr ctx)
+{
+    constexpr const char* restartCausePath = "/xyz/openbmc_project/state/host0";
+    constexpr const char* restartCauseIntf = "xyz.openbmc_project.State.Host";
+
+    std::string service;
+    boost::system::error_code ec =
+        ipmi::getService(ctx, restartCauseIntf, restartCausePath, service);
+    if (!ec)
+    {
+        std::string restartCauseStr;
+        ec = ipmi::getDbusProperty<std::string>(
+            ctx, service, restartCausePath, restartCauseIntf, "RestartCause",
+            restartCauseStr);
+        if (!ec)
+        {
+            auto cause =
+                State::Host::convertRestartCauseFromString(restartCauseStr);
+            return types::enum_cast<uint4_t>(
+                restartCauseToIpmiRestartCause(cause));
+        }
+    }
+
+    lg2::error(
+        "Failed to fetch RestartCause property ({PATH}/{INTERFACE}): {ERROR}",
+        "ERROR", ec.message(), "PATH", restartCausePath, "INTERFACE",
+        restartCauseIntf);
+    return std::nullopt;
+}
+
+ipmi::RspType<uint4_t, // Restart Cause
+              uint4_t, // reserved
+              uint8_t  // channel number (not supported)
+              >
+    ipmiGetSystemRestartCause(ipmi::Context::ptr ctx)
+{
+    std::optional<uint4_t> cause = getRestartCause(ctx);
+    if (!cause)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    constexpr uint4_t reserved = 0;
+    auto channel = static_cast<uint8_t>(ctx->channel);
+    return ipmi::responseSuccess(cause.value(), reserved, channel);
+}
+/** @brief Implementation of chassis control command
+ *
+ *  @param - chassisControl command byte
+ *
+ *  @return  Success or InvalidFieldRequest.
+ */
+ipmi::RspType<> ipmiChassisControl(ipmi::Context::ptr& ctx,
+                                   uint8_t chassisControl)
+{
+    int rc = 0;
+    switch (chassisControl)
+    {
+        case CMD_POWER_ON:
+            rc = initiateHostStateTransition(ctx, State::Host::Transition::On);
+            break;
+        case CMD_POWER_OFF:
+            rc = initiateChassisStateTransition(
+                ctx, State::Chassis::Transition::Off);
+            break;
+        case CMD_HARD_RESET:
+            rc = initiateHostStateTransition(
+                ctx, State::Host::Transition::ForceWarmReboot);
+            break;
+        case CMD_POWER_CYCLE:
+            rc = initiateHostStateTransition(ctx,
+                                             State::Host::Transition::Reboot);
+            break;
+        case CMD_SOFT_OFF_VIA_OVER_TEMP:
+            rc = initiateHostStateTransition(ctx, State::Host::Transition::Off);
+            break;
+        case CMD_PULSE_DIAGNOSTIC_INTR:
+            rc = doNmi(ctx);
+            break;
+
+        default:
+        {
+            lg2::error("Invalid Chassis Control command: {CMD}", "CMD",
+                       lg2::hex, chassisControl);
+            return ipmi::responseInvalidFieldRequest();
+        }
+    }
+
+    return ((rc < 0) ? ipmi::responseUnspecifiedError()
+                     : ipmi::responseSuccess());
+}
+
+/** @brief Return D-Bus connection string to enclosure identify LED object
+ *
+ *  @param[in, out] connection - connection to D-Bus object
+ *  @return a IPMI return code
+ */
+std::string getEnclosureIdentifyConnection()
+{
+    // lookup enclosure_identify group owner(s) in mapper
+    try
+    {
+        return ipmi::getService(*getSdBus(), "xyz.openbmc_project.Led.Group",
+                                identify_led_object_name);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Chassis Identify: Error communicating to mapper: {ERROR}",
+                   "ERROR", e);
+        elog<InternalFailure>();
+    }
+}
+
+/** @brief Turn On/Off enclosure identify LED
+ *
+ *  @param[in] flag - true to turn on LED, false to turn off
+ *  @return a IPMI return code
+ */
+void enclosureIdentifyLed(bool flag)
+{
+    using namespace chassis::internal;
+    try
+    {
+        std::string connection = getEnclosureIdentifyConnection();
+
+        auto msg = std::string("enclosureIdentifyLed(") +
+                   boost::lexical_cast<std::string>(flag) + ")";
+        lg2::debug(msg.c_str());
+
+        ipmi::setDbusProperty(*getSdBus(), connection, identify_led_object_name,
+                              "xyz.openbmc_project.Led.Group", "Asserted",
+                              flag);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Chassis Identify: Error Setting State {LED_STATE}: {ERROR}",
+                   "LED_STATE", flag, "ERROR", e);
+        elog<InternalFailure>();
+    }
+}
+
+/** @brief Callback method to turn off LED
+ */
+void enclosureIdentifyLedOff()
+{
+    try
+    {
+        chassisIDState = ChassisIDState::off;
+        enclosureIdentifyLed(false);
+    }
+    catch (const InternalFailure& e)
+    {
+        report<InternalFailure>();
+    }
+}
+
+/** @brief Create timer to turn on and off the enclosure LED
+ */
+void createIdentifyTimer()
+{
+    if (!identifyTimer)
+    {
+        identifyTimer =
+            std::make_unique<sdbusplus::Timer>(enclosureIdentifyLedOff);
+    }
+}
+
+ipmi::RspType<> ipmiChassisIdentify(std::optional<uint8_t> interval,
+                                    std::optional<uint8_t> force)
+{
+    uint8_t identifyInterval = interval.value_or(DEFAULT_IDENTIFY_TIME_OUT);
+    bool forceIdentify = force.value_or(0) & 0x01;
+
+    if (identifyInterval || forceIdentify)
+    {
+        // stop the timer if already started;
+        // for force identify we should not turn off LED
+        identifyTimer->stop();
+        try
+        {
+            chassisIDState = ChassisIDState::temporaryOn;
+            enclosureIdentifyLed(true);
+        }
+        catch (const InternalFailure& e)
+        {
+            report<InternalFailure>();
+            return ipmi::responseResponseError();
+        }
+
+        if (forceIdentify)
+        {
+            chassisIDState = ChassisIDState::indefiniteOn;
+            return ipmi::responseSuccess();
+        }
+        // start the timer
+        auto time = std::chrono::duration_cast<std::chrono::microseconds>(
+            std::chrono::seconds(identifyInterval));
+        identifyTimer->start(time);
+    }
+    else if (!identifyInterval)
+    {
+        identifyTimer->stop();
+        enclosureIdentifyLedOff();
+    }
+    return ipmi::responseSuccess();
+}
+
+namespace boot_options
+{
+
+using namespace sdbusplus::server::xyz::openbmc_project::control::boot;
+using IpmiValue = uint8_t;
+constexpr auto ipmiDefault = 0;
+
+std::map<IpmiValue, Type::Types> typeIpmiToDbus = {{0x00, Type::Types::Legacy},
+                                                   {0x01, Type::Types::EFI}};
+
+std::map<IpmiValue, Source::Sources> sourceIpmiToDbus = {
+    {0x01, Source::Sources::Network},
+    {0x02, Source::Sources::Disk},
+    {0x05, Source::Sources::ExternalMedia},
+    {0x0f, Source::Sources::RemovableMedia},
+    {ipmiDefault, Source::Sources::Default}};
+
+std::map<IpmiValue, Mode::Modes> modeIpmiToDbus = {
+#ifdef ENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT
+    {0x03, Mode::Modes::Safe},
+#endif // ENABLE_BOOT_SAFE_MODE_SUPPORT
+    {0x06, Mode::Modes::Setup},
+    {ipmiDefault, Mode::Modes::Regular}};
+
+std::map<Type::Types, IpmiValue> typeDbusToIpmi = {{Type::Types::Legacy, 0x00},
+                                                   {Type::Types::EFI, 0x01}};
+
+std::map<Source::Sources, IpmiValue> sourceDbusToIpmi = {
+    {Source::Sources::Network, 0x01},
+    {Source::Sources::Disk, 0x02},
+    {Source::Sources::ExternalMedia, 0x05},
+    {Source::Sources::RemovableMedia, 0x0f},
+    {Source::Sources::Default, ipmiDefault}};
+
+std::map<Mode::Modes, IpmiValue> modeDbusToIpmi = {
+#ifdef ENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT
+    {Mode::Modes::Safe, 0x03},
+#endif // ENABLE_BOOT_SAFE_MODE_SUPPORT
+    {Mode::Modes::Setup, 0x06},
+    {Mode::Modes::Regular, ipmiDefault}};
+
+} // namespace boot_options
+
+/** @brief Get the property value for boot source
+ *  @param[in] ctx - context pointer
+ *  @param[out] source - boot source value
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc getBootSource(ipmi::Context::ptr& ctx, Source::Sources& source)
+{
+    using namespace chassis::internal;
+    std::string result;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootSourceIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath,
+                                   bootSourceIntf, "BootSource", result);
+        if (!ec)
+        {
+            source = Source::convertSourcesFromString(result);
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in BootSource Get: {ERROR}", "ERROR", ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Set the property value for boot source
+ *  @param[in] ctx - context pointer
+ *  @param[in] source - boot source value
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc setBootSource(ipmi::Context::ptr& ctx,
+                              const Source::Sources& source)
+{
+    using namespace chassis::internal;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootSourceIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath,
+                                   bootSourceIntf, "BootSource",
+                                   convertForMessage(source));
+        if (!ec)
+        {
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in BootSource Set: {ERROR}", "ERROR", ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Get the property value for boot mode
+ *  @param[in] ctx - context pointer
+ *  @param[out] mode - boot mode value
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc getBootMode(ipmi::Context::ptr& ctx, Mode::Modes& mode)
+{
+    using namespace chassis::internal;
+    std::string result;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootModeIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath, bootModeIntf,
+                                   "BootMode", result);
+        if (!ec)
+        {
+            mode = Mode::convertModesFromString(result);
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in BootMode Get: {ERROR}", "ERROR", ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Set the property value for boot mode
+ *  @param[in] ctx - context pointer
+ *  @param[in] mode - boot mode value
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc setBootMode(ipmi::Context::ptr& ctx, const Mode::Modes& mode)
+{
+    using namespace chassis::internal;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootModeIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath, bootModeIntf,
+                                   "BootMode", convertForMessage(mode));
+        if (!ec)
+        {
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in BootMode Set: {ERROR}", "ERROR", ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Get the property value for boot type
+ *  @param[in] ctx - context pointer
+ *  @param[out] type - boot type value
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc getBootType(ipmi::Context::ptr& ctx, Type::Types& type)
+{
+    using namespace chassis::internal;
+    std::string result;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootTypeIntf, bootSettingsPath, service);
+
+    // Don't throw error if BootType interface is not present.
+    // This interface is not relevant for some Host architectures
+    // (for example POWER). In this case we don't won't IPMI to
+    // return an error, but simply return bootType as EFI.
+    type = Type::Types::EFI;
+    if (!ec)
+    {
+        ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath, bootTypeIntf,
+                                   "BootType", result);
+        if (ec)
+        {
+            lg2::error("Error in BootType Get: {ERROR}", "ERROR", ec.message());
+            return ipmi::ccUnspecifiedError;
+        }
+        type = Type::convertTypesFromString(result);
+    }
+
+    return ipmi::ccSuccess;
+}
+
+/** @brief Set the property value for boot type
+ *  @param[in] ctx - context pointer
+ *  @param[in] type - boot type value
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc setBootType(ipmi::Context::ptr& ctx, const Type::Types& type)
+{
+    using namespace chassis::internal;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootTypeIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath, bootTypeIntf,
+                                   "BootType", convertForMessage(type));
+        if (ec)
+        {
+            lg2::error("Error in BootType Set: {ERROR}", "ERROR", ec.message());
+            return ipmi::ccUnspecifiedError;
+        }
+    }
+    // Don't throw error if BootType interface is not present.
+    // This interface is not relevant for some Host architectures
+    // (for example POWER). In this case we don't won't IPMI to
+    // return an error, but want to just skip this function.
+    return ipmi::ccSuccess;
+}
+
+/** @brief Get the property value for boot override enable
+ *  @param[in] ctx - context pointer
+ *  @param[out] enable - boot override enable
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc getBootEnable(ipmi::Context::ptr& ctx, bool& enable)
+{
+    using namespace chassis::internal;
+    std::string result;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootEnableIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath,
+                                   bootEnableIntf, "Enabled", enable);
+        if (!ec)
+        {
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in Boot Override Enable Get: {ERROR}", "ERROR",
+               ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Set the property value for boot override enable
+ *  @param[in] ctx - context pointer
+ *  @param[in] enable - boot override enable
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc setBootEnable(ipmi::Context::ptr& ctx, const bool& enable)
+{
+    using namespace chassis::internal;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootEnableIntf, bootSettingsPath, service);
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath,
+                                   bootEnableIntf, "Enabled", enable);
+        if (!ec)
+        {
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in Boot Source Override Enable Set: {ERROR}", "ERROR",
+               ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Get the property value for boot override one-time
+ *  @param[in] ctx - context pointer
+ *  @param[out] onetime - boot override one-time
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc getBootOneTime(ipmi::Context::ptr& ctx, bool& onetime)
+{
+    using namespace chassis::internal;
+    std::string result;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootOneTimeIntf, bootSettingsOneTimePath, service);
+    if (!ec)
+    {
+        ec = ipmi::getDbusProperty(ctx, service, bootSettingsOneTimePath,
+                                   bootOneTimeIntf, "Enabled", onetime);
+        if (!ec)
+        {
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in Boot Override OneTime Get: {ERROR}", "ERROR",
+               ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+/** @brief Set the property value for boot override one-time
+ *  @param[in] ctx - context pointer
+ *  @param[in] onetime - boot override one-time
+ *  @return On failure return IPMI error.
+ */
+static ipmi::Cc setBootOneTime(ipmi::Context::ptr& ctx, const bool& onetime)
+{
+    using namespace chassis::internal;
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, bootOneTimeIntf, bootSettingsOneTimePath, service);
+    if (!ec)
+    {
+        ec = ipmi::setDbusProperty(ctx, service, bootSettingsOneTimePath,
+                                   bootOneTimeIntf, "Enabled", onetime);
+        if (!ec)
+        {
+            return ipmi::ccSuccess;
+        }
+    }
+    lg2::error("Error in Boot Source Override OneTime Set: {ERROR}", "ERROR",
+               ec.message());
+    return ipmi::ccUnspecifiedError;
+}
+
+static constexpr uint8_t setComplete = 0x0;
+static constexpr uint8_t setInProgress = 0x1;
+static uint8_t transferStatus = setComplete;
+static uint8_t bootFlagValidBitClr = 0;
+static uint5_t bootInitiatorAckData = 0x0;
+static bool cmosClear = false;
+static uint2_t biosVerbosity = 0x0;
+
+/** @brief implements the Get Chassis system boot option
+ *  @param ctx - context pointer
+ *  @param bootOptionParameter   - boot option parameter selector
+ *  @param reserved1    - reserved bit
+ *  @param setSelector  - selects a particular block or set of parameters
+ *                        under the given parameter selector
+ *                        write as 00h if parameter doesn't use a setSelector
+ *  @param blockSelector- selects a particular block within a set of
+ *                        parameters write as 00h if parameter doesn't use a
+ *                        blockSelector
+ *
+ *  @return IPMI completion code plus response data
+ *  @return Payload contains below parameters:
+ *   version             - parameter version
+ *   bootOptionParameter - boot option parameter selector
+ *   parmIndicator - parameter valid/invalid indicator
+ *   data          - configuration parameter data
+ */
+ipmi::RspType<ipmi::message::Payload> ipmiChassisGetSysBootOptions(
+    ipmi::Context::ptr ctx, uint7_t bootOptionParameter, bool reserved1,
+    [[maybe_unused]] uint8_t setSelector,
+    [[maybe_unused]] uint8_t blockSelector)
+{
+    ipmi::Cc rc;
+    if (reserved1)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    constexpr uint4_t version = 0x01;
+    ipmi::message::Payload response;
+    response.pack(version, uint4_t{});
+    using namespace boot_options;
+
+    IpmiValue bootOption = ipmiDefault;
+
+    if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
+        BootOptionParameter::setInProgress)
+    {
+        response.pack(bootOptionParameter, reserved1, transferStatus);
+        return ipmi::responseSuccess(std::move(response));
+    }
+
+    if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
+        BootOptionParameter::bootInfo)
+    {
+        constexpr uint8_t writeMask = 0;
+        response.pack(bootOptionParameter, reserved1, writeMask,
+                      bootInitiatorAckData);
+        return ipmi::responseSuccess(std::move(response));
+    }
+
+    if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
+        BootOptionParameter::bootFlagValidClr)
+    {
+        response.pack(bootOptionParameter, reserved1,
+                      uint5_t{bootFlagValidBitClr}, uint3_t{});
+        return ipmi::responseSuccess(std::move(response));
+    }
+
+    /*
+     * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+     * This is the only parameter used by petitboot.
+     */
+    if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
+        BootOptionParameter::bootFlags)
+    {
+        using namespace chassis::internal;
+        using namespace chassis::internal::cache;
+
+        try
+        {
+            Source::Sources bootSource;
+            rc = getBootSource(ctx, bootSource);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            Type::Types bootType;
+            rc = getBootType(ctx, bootType);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            Mode::Modes bootMode;
+            rc = getBootMode(ctx, bootMode);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            bootOption = sourceDbusToIpmi.at(bootSource);
+            if ((Mode::Modes::Regular == bootMode) &&
+                (Source::Sources::Default == bootSource))
+            {
+                bootOption = ipmiDefault;
+            }
+            else if (Source::Sources::Default == bootSource)
+            {
+                bootOption = modeDbusToIpmi.at(bootMode);
+            }
+
+            IpmiValue biosBootType = typeDbusToIpmi.at(bootType);
+
+            bool oneTimeEnabled;
+            rc = getBootOneTime(ctx, oneTimeEnabled);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            uint1_t permanent = oneTimeEnabled ? 0 : 1;
+
+            bool valid;
+            rc = getBootEnable(ctx, valid);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            uint1_t validFlag = valid ? 1 : 0;
+
+            response.pack(
+                bootOptionParameter, reserved1, uint5_t{},
+                uint1_t{biosBootType}, uint1_t{permanent}, uint1_t{validFlag},
+                uint2_t{}, uint4_t{bootOption}, uint1_t{}, cmosClear, uint5_t{},
+                uint2_t{biosVerbosity}, uint1_t{}, uint8_t{}, uint8_t{});
+            return ipmi::responseSuccess(std::move(response));
+        }
+        catch (const InternalFailure& e)
+        {
+            cache::objectsPtr.reset();
+            report<InternalFailure>();
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+    else
+    {
+        if ((bootOptionParameter >= oemParmStart) &&
+            (bootOptionParameter <= oemParmEnd))
+        {
+            if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
+                BootOptionParameter::opalNetworkSettings)
+            {
+                response.pack(bootOptionParameter, reserved1);
+                int ret = getHostNetworkData(response);
+                if (ret < 0)
+                {
+                    response.trailingOk = true;
+                    lg2::error(
+                        "getHostNetworkData failed for GetSysBootOptions.");
+                    return ipmi::responseUnspecifiedError();
+                }
+                else
+                {
+                    return ipmi::responseSuccess(std::move(response));
+                }
+            }
+            else
+            {
+                lg2::error(
+                    "ipmiChassisGetSysBootOptions: Unsupported parameter {PARAM}",
+                    "PARAM", lg2::hex,
+                    static_cast<uint8_t>(bootOptionParameter));
+                return ipmi::responseParmNotSupported();
+            }
+        }
+        else
+        {
+            lg2::error(
+                "ipmiChassisGetSysBootOptions: Unsupported parameter {PARAM}",
+                "PARAM", lg2::hex, static_cast<uint8_t>(bootOptionParameter));
+            return ipmi::responseParmNotSupported();
+        }
+    }
+    return ipmi::responseUnspecifiedError();
+}
+
+ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,
+                                             uint7_t parameterSelector, bool,
+                                             ipmi::message::Payload& data)
+{
+    using namespace boot_options;
+    ipmi::Cc rc;
+
+    if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
+        BootOptionParameter::setInProgress)
+    {
+        uint2_t setInProgressFlag;
+        uint6_t rsvd;
+        if (data.unpack(setInProgressFlag, rsvd) != 0 || !data.fullyUnpacked())
+        {
+            return ipmi::responseReqDataLenInvalid();
+        }
+        if (rsvd)
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        if ((transferStatus == setInProgress) &&
+            (static_cast<uint8_t>(setInProgressFlag) != setComplete))
+        {
+            return ipmi::response(IPMI_CC_FAIL_SET_IN_PROGRESS);
+        }
+        transferStatus = static_cast<uint8_t>(setInProgressFlag);
+        return ipmi::responseSuccess();
+    }
+
+    /*  000101
+     * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+     * This is the only parameter used by petitboot.
+     */
+
+    if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
+        BootOptionParameter::bootFlags)
+    {
+        uint5_t rsvd;
+        bool validFlag;
+        bool permanent;
+        bool biosBootType;
+        bool lockOutResetButton;
+        bool screenBlank;
+        uint4_t bootDeviceSelector;
+        bool lockKeyboard;
+        uint5_t biosCtrls;
+        bool lockOutPower;
+        uint4_t biosInfo;
+        uint4_t rsvd1;
+        uint5_t deviceInstance;
+        uint3_t rsvd2;
+
+        if (data.unpack(rsvd, biosBootType, permanent, validFlag,
+                        lockOutResetButton, screenBlank, bootDeviceSelector,
+                        lockKeyboard, cmosClear, biosCtrls, biosVerbosity,
+                        lockOutPower, biosInfo, rsvd1, deviceInstance, rsvd2) !=
+                0 ||
+            !data.fullyUnpacked())
+        {
+            return ipmi::responseReqDataLenInvalid();
+        }
+        if (rsvd || rsvd1 || rsvd2)
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+
+        using namespace chassis::internal;
+        using namespace chassis::internal::cache;
+
+        try
+        {
+            rc = setBootOneTime(ctx, !permanent);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            rc = setBootEnable(ctx, validFlag);
+            if (rc != ipmi::ccSuccess)
+            {
+                return ipmi::response(rc);
+            }
+
+            auto modeItr =
+                modeIpmiToDbus.find(static_cast<uint8_t>(bootDeviceSelector));
+            auto typeItr =
+                typeIpmiToDbus.find(static_cast<uint8_t>(biosBootType));
+            auto sourceItr =
+                sourceIpmiToDbus.find(static_cast<uint8_t>(bootDeviceSelector));
+            if (sourceIpmiToDbus.end() != sourceItr)
+            {
+                rc = setBootSource(ctx, sourceItr->second);
+                if (rc != ipmi::ccSuccess)
+                {
+                    return ipmi::response(rc);
+                }
+                // If a set boot device is mapping to a boot source, then reset
+                // the boot mode D-Bus property to default.
+                // This way the ipmid code can determine which property is not
+                // at the default value
+                if (sourceItr->second != Source::Sources::Default)
+                {
+                    rc = setBootMode(ctx, Mode::Modes::Regular);
+                    if (rc != ipmi::ccSuccess)
+                    {
+                        return ipmi::response(rc);
+                    }
+                }
+            }
+
+            if (typeIpmiToDbus.end() != typeItr)
+            {
+                rc = setBootType(ctx, typeItr->second);
+                if (rc != ipmi::ccSuccess)
+                {
+                    return ipmi::response(rc);
+                }
+            }
+
+            if (modeIpmiToDbus.end() != modeItr)
+            {
+                rc = setBootMode(ctx, modeItr->second);
+                if (rc != ipmi::ccSuccess)
+                {
+                    return ipmi::response(rc);
+                }
+                // If a set boot device is mapping to a boot mode, then reset
+                // the boot source D-Bus property to default.
+                // This way the ipmid code can determine which property is not
+                // at the default value
+                if (modeItr->second != Mode::Modes::Regular)
+                {
+                    rc = setBootSource(ctx, Source::Sources::Default);
+                    if (rc != ipmi::ccSuccess)
+                    {
+                        return ipmi::response(rc);
+                    }
+                }
+            }
+            if ((modeIpmiToDbus.end() == modeItr) &&
+                (typeIpmiToDbus.end() == typeItr) &&
+                (sourceIpmiToDbus.end() == sourceItr))
+            {
+                // return error if boot option is not supported
+                lg2::error(
+                    "ipmiChassisSetSysBootOptions: Boot option not supported");
+                return ipmi::responseInvalidFieldRequest();
+            }
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            objectsPtr.reset();
+            report<InternalFailure>();
+            lg2::error("ipmiChassisSetSysBootOptions: Error in setting Boot "
+                       "flag parameters");
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+    else if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
+             BootOptionParameter::bootInfo)
+    {
+        uint8_t writeMak;
+        uint5_t bootInfoAck;
+        uint3_t rsvd;
+
+        if (data.unpack(writeMak, bootInfoAck, rsvd) != 0 ||
+            !data.fullyUnpacked())
+        {
+            return ipmi::responseReqDataLenInvalid();
+        }
+        if (rsvd)
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        bootInitiatorAckData &= ~writeMak;
+        bootInitiatorAckData |= (writeMak & bootInfoAck);
+        lg2::info("ipmiChassisSetSysBootOptions: bootInfo parameter set "
+                  "successfully");
+        data.trailingOk = true;
+        return ipmi::responseSuccess();
+    }
+    else if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
+             BootOptionParameter::bootFlagValidClr)
+    {
+        uint5_t bootFlagValidClr;
+        uint3_t rsvd;
+
+        if (data.unpack(bootFlagValidClr, rsvd) != 0 || !data.fullyUnpacked())
+        {
+            return ipmi::responseReqDataLenInvalid();
+        }
+        if (rsvd)
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        // store boot flag valid bits clear value
+        bootFlagValidBitClr = static_cast<uint8_t>(bootFlagValidClr);
+        lg2::info(
+            "ipmiChassisSetSysBootOptions: bootFlagValidBits parameter set "
+            "successfully to {VALUE}",
+            "VALUE", lg2::hex, bootFlagValidBitClr);
+        return ipmi::responseSuccess();
+    }
+    else
+    {
+        if ((parameterSelector >= static_cast<uint7_t>(oemParmStart)) &&
+            (parameterSelector <= static_cast<uint7_t>(oemParmEnd)))
+        {
+            if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
+                BootOptionParameter::opalNetworkSettings)
+            {
+                ipmi::Cc ret = setHostNetworkData(data);
+                if (ret != ipmi::ccSuccess)
+                {
+                    lg2::error("ipmiChassisSetSysBootOptions: Error in "
+                               "setHostNetworkData");
+                    data.trailingOk = true;
+                    return ipmi::response(ret);
+                }
+                data.trailingOk = true;
+                return ipmi::responseSuccess();
+            }
+            else
+            {
+                lg2::error(
+                    "ipmiChassisSetSysBootOptions: Unsupported param: {PARAM}",
+                    "PARAM", lg2::hex, static_cast<uint8_t>(parameterSelector));
+                data.trailingOk = true;
+                return ipmi::responseParmNotSupported();
+            }
+        }
+        data.trailingOk = true;
+        return ipmi::responseParmNotSupported();
+    }
+    return ipmi::responseSuccess();
+}
+
+/** @brief implements Get POH counter command
+ *  @parameter
+ *   -  none
+ *  @returns IPMI completion code plus response data
+ *   - minPerCount - Minutes per count
+ *   - counterReading - counter reading
+ */
+ipmi::RspType<uint8_t, // Minutes per count
+              uint32_t // Counter reading
+              >
+    ipmiGetPOHCounter()
+{
+    // sd_bus error
+    try
+    {
+        return ipmi::responseSuccess(static_cast<uint8_t>(poh::minutesPerCount),
+                                     getPOHCounter());
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("getPOHCounter error: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+}
+
+ipmi::RspType<uint3_t, // policy support
+              uint5_t  // reserved
+              >
+    ipmiChassisSetPowerRestorePolicy(ipmi::Context::ptr ctx, uint3_t policy,
+                                     uint5_t reserved)
+{
+    power_policy::DbusValue value =
+        power_policy::RestorePolicy::Policy::AlwaysOff;
+
+    if (reserved || (policy > power_policy::noChange))
+    {
+        lg2::error("Reserved request parameter: {REQ}", "REQ", lg2::hex,
+                   static_cast<int>(policy));
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (policy == power_policy::noChange)
+    {
+        // just return the supported policy
+        return ipmi::responseSuccess(power_policy::allSupport, reserved);
+    }
+
+    for (const auto& it : power_policy::dbusToIpmi)
+    {
+        if (it.second == policy)
+        {
+            value = it.first;
+            break;
+        }
+    }
+
+    try
+    {
+        settings::Objects& objects = chassis::internal::cache::getObjects();
+        const settings::Path& powerRestoreSetting =
+            objects.map.at(chassis::internal::powerRestoreIntf).front();
+
+        boost::system::error_code ec = ipmi::setDbusProperty(
+            ctx,
+            objects.service(powerRestoreSetting,
+                            chassis::internal::powerRestoreIntf),
+            powerRestoreSetting, chassis::internal::powerRestoreIntf,
+            "PowerRestorePolicy", convertForMessage(value));
+        if (ec)
+        {
+            lg2::error("Unspecified Error");
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+    catch (const InternalFailure& e)
+    {
+        chassis::internal::cache::objectsPtr.reset();
+        report<InternalFailure>();
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(power_policy::allSupport, reserved);
+}
+
+ipmi::RspType<> ipmiSetFrontPanelButtonEnables(
+    ipmi::Context::ptr ctx, bool disablePowerButton, bool disableResetButton,
+    bool, bool, uint4_t)
+{
+    using namespace chassis::internal;
+
+    // set power button Enabled property
+    bool success = setButtonDisabled(ctx, powerButtonPath, powerButtonIntf,
+                                     disablePowerButton);
+
+    // set reset button Enabled property
+    success &= setButtonDisabled(ctx, resetButtonPath, resetButtonIntf,
+                                 disableResetButton);
+
+    if (!success)
+    {
+        // not all buttons were successfully set
+        return ipmi::responseUnspecifiedError();
+    }
+    return ipmi::responseSuccess();
+}
+
+void registerNetFnChassisFunctions()
+{
+    createIdentifyTimer();
+
+    // Get Chassis Capabilities
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdGetChassisCapabilities,
+                          ipmi::Privilege::User, ipmiGetChassisCap);
+
+    // Set Front Panel Button Enables
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdSetFrontPanelButtonEnables,
+                          ipmi::Privilege::Admin,
+                          ipmiSetFrontPanelButtonEnables);
+
+    // Set Chassis Capabilities
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdSetChassisCapabilities,
+                          ipmi::Privilege::User, ipmiSetChassisCap);
+
+    // <Get System Boot Options>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdGetSystemBootOptions,
+                          ipmi::Privilege::Operator,
+                          ipmiChassisGetSysBootOptions);
+
+    // <Get Chassis Status>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdGetChassisStatus,
+                          ipmi::Privilege::User, ipmiGetChassisStatus);
+
+    // <Chassis Get System Restart Cause>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdGetSystemRestartCause,
+                          ipmi::Privilege::User, ipmiGetSystemRestartCause);
+
+    // <Chassis Control>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdChassisControl,
+                          ipmi::Privilege::Operator, ipmiChassisControl);
+
+    // <Chassis Identify>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdChassisIdentify,
+                          ipmi::Privilege::Operator, ipmiChassisIdentify);
+
+    // <Set System Boot Options>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdSetSystemBootOptions,
+                          ipmi::Privilege::Operator,
+                          ipmiChassisSetSysBootOptions);
+
+    // <Get POH Counter>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdGetPohCounter,
+                          ipmi::Privilege::User, ipmiGetPOHCounter);
+
+    // <Set Power Restore Policy>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+                          ipmi::chassis::cmdSetPowerRestorePolicy,
+                          ipmi::Privilege::Operator,
+                          ipmiChassisSetPowerRestorePolicy);
+}
diff --git a/chassishandler.hpp b/chassishandler.hpp
new file mode 100644
index 0000000..8d8af3b
--- /dev/null
+++ b/chassishandler.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <cstddef>
+
+// Command specific completion codes
+enum ipmi_chassis_return_codes
+{
+    IPMI_OK = 0x0,
+    IPMI_CC_PARM_NOT_SUPPORTED = 0x80,
+    IPMI_CC_FAIL_SET_IN_PROGRESS = 0x81,
+};
+
+// Generic completion codes,
+// see IPMI doc section 5.2
+enum ipmi_generic_return_codes
+{
+    IPMI_OUT_OF_SPACE = 0xC4,
+};
+
+// Various Chassis operations under a single command.
+enum ipmi_chassis_control_cmds : uint8_t
+{
+    CMD_POWER_OFF = 0x00,
+    CMD_POWER_ON = 0x01,
+    CMD_POWER_CYCLE = 0x02,
+    CMD_HARD_RESET = 0x03,
+    CMD_PULSE_DIAGNOSTIC_INTR = 0x04,
+    CMD_SOFT_OFF_VIA_OVER_TEMP = 0x05,
+};
+enum class BootOptionParameter : size_t
+{
+    setInProgress = 0x0,
+    bootFlagValidClr = 0x3,
+    bootInfo = 0x4,
+    bootFlags = 0x5,
+    opalNetworkSettings = 0x61
+};
+
+enum class BootOptionResponseSize : size_t
+{
+    setInProgress = 3,
+    bootFlags = 5,
+    opalNetworkSettings = 50
+};
+
+enum class ChassisIDState : uint8_t
+{
+    off = 0x0,
+    temporaryOn = 0x1,
+    indefiniteOn = 0x2,
+    reserved = 0x3
+};
diff --git a/dbus-sdr/meson.build b/dbus-sdr/meson.build
new file mode 100644
index 0000000..a937485
--- /dev/null
+++ b/dbus-sdr/meson.build
@@ -0,0 +1,43 @@
+sensorutils_lib = static_library(
+    'sensorutils',
+    'sensorutils.cpp',
+    include_directories: root_inc,
+    implicit_include_directories: false,
+)
+
+sensorutils_dep = declare_dependency(link_with: sensorutils_lib)
+
+hybrid_src = []
+
+if get_option('hybrid-sensors').allowed()
+    hybrid_src = [
+        'sensorhandler.cpp',
+        'sensordatahandler.cpp',
+        'ipmisensor.cpp',
+        generated_src,
+    ]
+endif
+
+sensorsoem_src = []
+if get_option('sensors-oem').allowed()
+    sensorsoem_src = ['dbus-sdr/sensorcommands_oem.cpp']
+endif
+
+dbus_sdr_pre = declare_dependency(
+    include_directories: root_inc,
+    dependencies: [
+        crypto,
+        nlohmann_json_dep,
+        phosphor_logging_dep,
+        ipmid_dep,
+        sensorutils_dep,
+    ],
+)
+
+dbus_sdr_src = [
+    'dbus-sdr/sdrutils.cpp',
+    'dbus-sdr/sensorcommands.cpp',
+    'dbus-sdr/storagecommands.cpp',
+    hybrid_src,
+    sensorsoem_src,
+]
diff --git a/dbus-sdr/sdrutils.cpp b/dbus-sdr/sdrutils.cpp
new file mode 100644
index 0000000..9523593
--- /dev/null
+++ b/dbus-sdr/sdrutils.cpp
@@ -0,0 +1,652 @@
+/*
+// Copyright (c) 2018 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 "dbus-sdr/sdrutils.hpp"
+
+#include <ipmid/utils.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <fstream>
+#include <optional>
+#include <unordered_set>
+
+#ifdef FEATURE_HYBRID_SENSORS
+
+#include <ipmid/utils.hpp>
+namespace ipmi
+{
+namespace sensor
+{
+extern const IdInfoMap sensors;
+} // namespace sensor
+} // namespace ipmi
+
+#endif
+
+boost::container::flat_map<
+    const char*, std::pair<SensorTypeCodes, SensorEventTypeCodes>, CmpStr>
+    sensorTypes{
+        {{"temperature", std::make_pair(SensorTypeCodes::temperature,
+                                        SensorEventTypeCodes::threshold)},
+         {"voltage", std::make_pair(SensorTypeCodes::voltage,
+                                    SensorEventTypeCodes::threshold)},
+         {"current", std::make_pair(SensorTypeCodes::current,
+                                    SensorEventTypeCodes::threshold)},
+         {"fan_tach", std::make_pair(SensorTypeCodes::fan,
+                                     SensorEventTypeCodes::threshold)},
+         {"fan_pwm", std::make_pair(SensorTypeCodes::fan,
+                                    SensorEventTypeCodes::threshold)},
+         {"intrusion", std::make_pair(SensorTypeCodes::physical_security,
+                                      SensorEventTypeCodes::sensorSpecified)},
+         {"processor", std::make_pair(SensorTypeCodes::processor,
+                                      SensorEventTypeCodes::sensorSpecified)},
+         {"power", std::make_pair(SensorTypeCodes::other,
+                                  SensorEventTypeCodes::threshold)},
+         {"memory", std::make_pair(SensorTypeCodes::memory,
+                                   SensorEventTypeCodes::sensorSpecified)},
+         {"state", std::make_pair(SensorTypeCodes::power_unit,
+                                  SensorEventTypeCodes::sensorSpecified)},
+         {"buttons", std::make_pair(SensorTypeCodes::buttons,
+                                    SensorEventTypeCodes::sensorSpecified)},
+         {"watchdog", std::make_pair(SensorTypeCodes::watchdog2,
+                                     SensorEventTypeCodes::sensorSpecified)},
+         {"entity", std::make_pair(SensorTypeCodes::entity,
+                                   SensorEventTypeCodes::sensorSpecified)},
+         {"energy", std::make_pair(SensorTypeCodes::other,
+                                   SensorEventTypeCodes::threshold)}}};
+
+namespace details
+{
+
+// IPMI supports a smaller number of sensors than are available via Redfish.
+// Trim the list of sensors, via a configuration file.
+// Read the IPMI Sensor Filtering section in docs/configuration.md for
+// a more detailed description.
+static void filterSensors(SensorSubTree& subtree)
+{
+    constexpr const char* filterFilename =
+        "/usr/share/ipmi-providers/sensor_filter.json";
+    std::ifstream filterFile(filterFilename);
+    if (!filterFile.good())
+    {
+        return;
+    }
+    nlohmann::json sensorFilterJSON =
+        nlohmann::json::parse(filterFile, nullptr, false);
+    nlohmann::json::iterator svcFilterit =
+        sensorFilterJSON.find("ServiceFilter");
+    if (svcFilterit == sensorFilterJSON.end())
+    {
+        return;
+    }
+
+    subtree.erase(std::remove_if(subtree.begin(), subtree.end(),
+                                 [svcFilterit](SensorSubTree::value_type& kv) {
+                                     auto& [_, serviceToIfaces] = kv;
+
+                                     for (auto service = svcFilterit->begin();
+                                          service != svcFilterit->end();
+                                          ++service)
+                                     {
+                                         serviceToIfaces.erase(*service);
+                                     }
+                                     return serviceToIfaces.empty();
+                                 }),
+                  subtree.end());
+}
+
+uint16_t getSensorSubtree(std::shared_ptr<SensorSubTree>& subtree)
+{
+    static std::shared_ptr<SensorSubTree> sensorTreePtr;
+    static uint16_t sensorUpdatedIndex = 0;
+    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+    static sdbusplus::bus::match_t sensorAdded(
+        *dbus,
+        "type='signal',member='InterfacesAdded',arg0path='/xyz/openbmc_project/"
+        "sensors/'",
+        [](sdbusplus::message_t&) { sensorTreePtr.reset(); });
+
+    static sdbusplus::bus::match_t sensorRemoved(
+        *dbus,
+        "type='signal',member='InterfacesRemoved',arg0path='/xyz/"
+        "openbmc_project/sensors/'",
+        [](sdbusplus::message_t&) { sensorTreePtr.reset(); });
+
+    if (sensorTreePtr)
+    {
+        subtree = sensorTreePtr;
+        return sensorUpdatedIndex;
+    }
+
+    sensorTreePtr = std::make_shared<SensorSubTree>();
+
+    static constexpr const int32_t depth = 2;
+
+    auto lbdUpdateSensorTree = [&dbus](const char* path,
+                                       const auto& interfaces) {
+        auto mapperCall = dbus->new_method_call(
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree");
+        SensorSubTree sensorTreePartial;
+
+        mapperCall.append(path, depth, interfaces);
+
+        try
+        {
+            auto mapperReply = dbus->call(mapperCall);
+            mapperReply.read(sensorTreePartial);
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            lg2::error("Failed to update subtree, path: {PATH}, error: {ERROR}",
+                       "PATH", path, "ERROR", e);
+            return false;
+        }
+        if constexpr (debug)
+        {
+            std::fprintf(stderr, "IPMI updated: %zu sensors under %s\n",
+                         sensorTreePartial.size(), path);
+        }
+        sensorTreePtr->merge(std::move(sensorTreePartial));
+        return true;
+    };
+
+    // Add sensors to SensorTree
+    static constexpr const std::array sensorInterfaces = {
+        "xyz.openbmc_project.Sensor.Value",
+        "xyz.openbmc_project.Sensor.ValueMutability",
+        "xyz.openbmc_project.Sensor.Threshold.Warning",
+        "xyz.openbmc_project.Sensor.Threshold.Critical"};
+    static constexpr const std::array vrInterfaces = {
+        "xyz.openbmc_project.Control.VoltageRegulatorMode"};
+
+    bool sensorRez =
+        lbdUpdateSensorTree("/xyz/openbmc_project/sensors", sensorInterfaces);
+
+#ifdef FEATURE_HYBRID_SENSORS
+
+    if (!ipmi::sensor::sensors.empty())
+    {
+        for (const auto& sensor : ipmi::sensor::sensors)
+        {
+            // Threshold sensors should not be emplaced in here.
+            if (boost::starts_with(sensor.second.sensorPath,
+                                   "/xyz/openbmc_project/sensors/"))
+            {
+                continue;
+            }
+
+            // The bus service name is not listed in ipmi::sensor::Info. Give it
+            // an empty string. For those function using non-threshold sensors,
+            // the bus service name will be retrieved in an alternative way.
+            boost::container::flat_map<std::string, std::vector<std::string>>
+                connectionMap{
+                    {"", {sensor.second.propertyInterfaces.begin()->first}}};
+            sensorTreePtr->emplace(sensor.second.sensorPath, connectionMap);
+        }
+    }
+
+#endif
+
+    // Error if searching for sensors failed.
+    if (!sensorRez)
+    {
+        return sensorUpdatedIndex;
+    }
+
+    filterSensors(*sensorTreePtr);
+    // Add VR control as optional search path.
+    (void)lbdUpdateSensorTree("/xyz/openbmc_project/vr", vrInterfaces);
+
+    subtree = sensorTreePtr;
+    sensorUpdatedIndex++;
+    // The SDR is being regenerated, wipe the old stats
+    sdrStatsTable.wipeTable();
+    sdrWriteTable.wipeTable();
+    return sensorUpdatedIndex;
+}
+
+bool getSensorNumMap(std::shared_ptr<SensorNumMap>& sensorNumMap)
+{
+    static std::shared_ptr<SensorNumMap> sensorNumMapPtr;
+    bool sensorNumMapUpated = false;
+    static uint16_t prevSensorUpdatedIndex = 0;
+    std::shared_ptr<SensorSubTree> sensorTree;
+    uint16_t curSensorUpdatedIndex = details::getSensorSubtree(sensorTree);
+    if (!sensorTree)
+    {
+        return sensorNumMapUpated;
+    }
+
+    if ((curSensorUpdatedIndex == prevSensorUpdatedIndex) && sensorNumMapPtr)
+    {
+        sensorNumMap = sensorNumMapPtr;
+        return sensorNumMapUpated;
+    }
+    prevSensorUpdatedIndex = curSensorUpdatedIndex;
+
+    sensorNumMapPtr = std::make_shared<SensorNumMap>();
+
+    uint16_t sensorNum = 0;
+    uint16_t sensorIndex = 0;
+    for (const auto& sensor : *sensorTree)
+    {
+        sensorNumMapPtr->insert(
+            SensorNumMap::value_type(sensorNum, sensor.first));
+        sensorIndex++;
+        if (sensorIndex == maxSensorsPerLUN)
+        {
+            sensorIndex = lun1Sensor0;
+        }
+        else if (sensorIndex == (lun1Sensor0 | maxSensorsPerLUN))
+        {
+            // Skip assigning LUN 0x2 any sensors
+            sensorIndex = lun3Sensor0;
+        }
+        else if (sensorIndex == (lun3Sensor0 | maxSensorsPerLUN))
+        {
+            // this is an error, too many IPMI sensors
+            throw std::out_of_range("Maximum number of IPMI sensors exceeded.");
+        }
+        sensorNum = sensorIndex;
+    }
+    sensorNumMap = sensorNumMapPtr;
+    sensorNumMapUpated = true;
+    return sensorNumMapUpated;
+}
+} // namespace details
+
+bool getSensorSubtree(SensorSubTree& subtree)
+{
+    std::shared_ptr<SensorSubTree> sensorTree;
+    details::getSensorSubtree(sensorTree);
+    if (!sensorTree)
+    {
+        return false;
+    }
+
+    subtree = *sensorTree;
+    return true;
+}
+
+#ifdef FEATURE_HYBRID_SENSORS
+// Static sensors are listed in sensor-gen.cpp.
+ipmi::sensor::IdInfoMap::const_iterator findStaticSensor(
+    const std::string& path)
+{
+    return std::find_if(
+        ipmi::sensor::sensors.begin(), ipmi::sensor::sensors.end(),
+        [&path](const ipmi::sensor::IdInfoMap::value_type& findSensor) {
+            return findSensor.second.sensorPath == path;
+        });
+}
+#endif
+
+std::string getSensorTypeStringFromPath(const std::string& path)
+{
+    // get sensor type string from path, path is defined as
+    // /xyz/openbmc_project/sensors/<type>/label
+    size_t typeEnd = path.rfind("/");
+    if (typeEnd == std::string::npos)
+    {
+        return path;
+    }
+    size_t typeStart = path.rfind("/", typeEnd - 1);
+    if (typeStart == std::string::npos)
+    {
+        return path;
+    }
+    // Start at the character after the '/'
+    typeStart++;
+    return path.substr(typeStart, typeEnd - typeStart);
+}
+
+uint8_t getSensorTypeFromPath(const std::string& path)
+{
+    uint8_t sensorType = 0;
+    std::string type = getSensorTypeStringFromPath(path);
+    auto findSensor = sensorTypes.find(type.c_str());
+    if (findSensor != sensorTypes.end())
+    {
+        sensorType =
+            static_cast<uint8_t>(std::get<sensorTypeCodes>(findSensor->second));
+    } // else default 0x0 RESERVED
+
+    return sensorType;
+}
+
+uint16_t getSensorNumberFromPath(const std::string& path)
+{
+    std::shared_ptr<SensorNumMap> sensorNumMapPtr;
+    details::getSensorNumMap(sensorNumMapPtr);
+    if (!sensorNumMapPtr)
+    {
+        return invalidSensorNumber;
+    }
+
+    try
+    {
+        return sensorNumMapPtr->right.at(path);
+    }
+    catch (const std::out_of_range& e)
+    {
+        return invalidSensorNumber;
+    }
+}
+
+uint8_t getSensorEventTypeFromPath(const std::string& path)
+{
+    uint8_t sensorEventType = 0;
+    std::string type = getSensorTypeStringFromPath(path);
+    auto findSensor = sensorTypes.find(type.c_str());
+    if (findSensor != sensorTypes.end())
+    {
+        sensorEventType = static_cast<uint8_t>(
+            std::get<sensorEventTypeCodes>(findSensor->second));
+    }
+
+    return sensorEventType;
+}
+
+std::string getPathFromSensorNumber(uint16_t sensorNum)
+{
+    std::shared_ptr<SensorNumMap> sensorNumMapPtr;
+    details::getSensorNumMap(sensorNumMapPtr);
+    if (!sensorNumMapPtr)
+    {
+        return std::string();
+    }
+
+    try
+    {
+        return sensorNumMapPtr->left.at(sensorNum);
+    }
+    catch (const std::out_of_range& e)
+    {
+        return std::string();
+    }
+}
+
+namespace ipmi
+{
+
+std::optional<std::map<std::string, std::vector<std::string>>>
+    getObjectInterfaces(const char* path)
+{
+    std::map<std::string, std::vector<std::string>> interfacesResponse;
+    std::vector<std::string> interfaces;
+    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+
+    sdbusplus::message_t getObjectMessage =
+        dbus->new_method_call("xyz.openbmc_project.ObjectMapper",
+                              "/xyz/openbmc_project/object_mapper",
+                              "xyz.openbmc_project.ObjectMapper", "GetObject");
+    getObjectMessage.append(path, interfaces);
+
+    try
+    {
+        sdbusplus::message_t response = dbus->call(getObjectMessage);
+        response.read(interfacesResponse);
+    }
+    catch (const std::exception& e)
+    {
+        return std::nullopt;
+    }
+
+    return interfacesResponse;
+}
+
+std::map<std::string, Value> getEntityManagerProperties(const char* path,
+                                                        const char* interface)
+{
+    std::map<std::string, Value> properties;
+    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+
+    sdbusplus::message_t getProperties =
+        dbus->new_method_call("xyz.openbmc_project.EntityManager", path,
+                              "org.freedesktop.DBus.Properties", "GetAll");
+    getProperties.append(interface);
+
+    try
+    {
+        sdbusplus::message_t response = dbus->call(getProperties);
+        response.read(properties);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to GetAll, path: {PATH}, interface: {INTERFACE}, "
+                   "error: {ERROR}",
+                   "PATH", path, "INTERFACE", interface, "ERROR", e);
+    }
+
+    return properties;
+}
+
+// Fetch the ipmiDecoratorPaths to get the list of dbus objects that
+// have ipmi decorator to prevent unnessary dbus call to fetch the info
+std::optional<std::unordered_set<std::string>>& getIpmiDecoratorPaths(
+    const std::optional<ipmi::Context::ptr>& ctx)
+{
+    static std::optional<std::unordered_set<std::string>> ipmiDecoratorPaths;
+
+    if (!ctx.has_value() || ipmiDecoratorPaths != std::nullopt)
+    {
+        return ipmiDecoratorPaths;
+    }
+
+    using Paths = std::vector<std::string>;
+    boost::system::error_code ec;
+    Paths paths = ipmi::callDbusMethod<Paths>(
+        *ctx, ec, "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", int32_t(0),
+        std::array<const char*, 1>{
+            "xyz.openbmc_project.Inventory.Decorator.Ipmi"});
+
+    if (ec)
+    {
+        return ipmiDecoratorPaths;
+    }
+
+    ipmiDecoratorPaths =
+        std::unordered_set<std::string>(paths.begin(), paths.end());
+    return ipmiDecoratorPaths;
+}
+
+const std::string* getSensorConfigurationInterface(
+    const std::map<std::string, std::vector<std::string>>&
+        sensorInterfacesResponse)
+{
+    auto entityManagerService =
+        sensorInterfacesResponse.find("xyz.openbmc_project.EntityManager");
+    if (entityManagerService == sensorInterfacesResponse.end())
+    {
+        return nullptr;
+    }
+
+    // Find the fan configuration first (fans can have multiple configuration
+    // interfaces).
+    for (const auto& entry : entityManagerService->second)
+    {
+        if (entry == "xyz.openbmc_project.Configuration.AspeedFan" ||
+            entry == "xyz.openbmc_project.Configuration.I2CFan" ||
+            entry == "xyz.openbmc_project.Configuration.NuvotonFan")
+        {
+            return &entry;
+        }
+    }
+
+    for (const auto& entry : entityManagerService->second)
+    {
+        if (boost::algorithm::starts_with(entry,
+                                          "xyz.openbmc_project.Configuration."))
+        {
+            return &entry;
+        }
+    }
+
+    return nullptr;
+}
+
+// Follow Association properties for Sensor back to the Board dbus object to
+// check for an EntityId and EntityInstance property.
+void updateIpmiFromAssociation(
+    const std::string& path,
+    const std::unordered_set<std::string>& ipmiDecoratorPaths,
+    const DbusInterfaceMap& sensorMap, uint8_t& entityId,
+    uint8_t& entityInstance)
+{
+    namespace fs = std::filesystem;
+
+    auto sensorAssociationObject =
+        sensorMap.find("xyz.openbmc_project.Association.Definitions");
+    if (sensorAssociationObject == sensorMap.end())
+    {
+        if constexpr (debug)
+        {
+            std::fprintf(stderr, "path=%s, no association interface found\n",
+                         path.c_str());
+        }
+
+        return;
+    }
+
+    auto associationObject =
+        sensorAssociationObject->second.find("Associations");
+    if (associationObject == sensorAssociationObject->second.end())
+    {
+        if constexpr (debug)
+        {
+            std::fprintf(stderr, "path=%s, no association records found\n",
+                         path.c_str());
+        }
+
+        return;
+    }
+
+    std::vector<Association> associationValues =
+        std::get<std::vector<Association>>(associationObject->second);
+
+    // loop through the Associations looking for the right one:
+    for (const auto& entry : associationValues)
+    {
+        // forward, reverse, endpoint
+        const std::string& forward = std::get<0>(entry);
+        const std::string& reverse = std::get<1>(entry);
+        const std::string& endpoint = std::get<2>(entry);
+
+        // We only currently concern ourselves with chassis+all_sensors.
+        if (!(forward == "chassis" && reverse == "all_sensors"))
+        {
+            continue;
+        }
+
+        // the endpoint is the board entry provided by
+        // Entity-Manager. so let's grab its properties if it has
+        // the right interface.
+
+        // just try grabbing the properties first.
+        ipmi::PropertyMap::iterator entityIdProp;
+        ipmi::PropertyMap::iterator entityInstanceProp;
+        if (ipmiDecoratorPaths.contains(endpoint))
+        {
+            std::map<std::string, Value> ipmiProperties =
+                getEntityManagerProperties(
+                    endpoint.c_str(),
+                    "xyz.openbmc_project.Inventory.Decorator.Ipmi");
+
+            entityIdProp = ipmiProperties.find("EntityId");
+            entityInstanceProp = ipmiProperties.find("EntityInstance");
+            if (entityIdProp != ipmiProperties.end())
+            {
+                entityId = static_cast<uint8_t>(
+                    std::get<uint64_t>(entityIdProp->second));
+            }
+            if (entityInstanceProp != ipmiProperties.end())
+            {
+                entityInstance = static_cast<uint8_t>(
+                    std::get<uint64_t>(entityInstanceProp->second));
+            }
+        }
+
+        // Now check the entity-manager entry for this sensor to see
+        // if it has its own value and use that instead.
+        //
+        // In theory, checking this first saves us from checking
+        // both, except in most use-cases identified, there won't be
+        // a per sensor override, so we need to always check both.
+        std::string sensorNameFromPath = fs::path(path).filename();
+
+        std::string sensorConfigPath = endpoint + "/" + sensorNameFromPath;
+
+        // Download the interfaces for the sensor from
+        // Entity-Manager to find the name of the configuration
+        // interface.
+        std::optional<std::map<std::string, std::vector<std::string>>>
+            sensorInterfacesResponseOpt =
+                getObjectInterfaces(sensorConfigPath.c_str());
+
+        if (!sensorInterfacesResponseOpt.has_value())
+        {
+            lg2::debug("Failed to GetObject, path: {PATH}", "PATH",
+                       sensorConfigPath);
+            continue;
+        }
+
+        const std::string* configurationInterface =
+            getSensorConfigurationInterface(
+                sensorInterfacesResponseOpt.value());
+
+        // If there are multi association path settings and only one path exist,
+        // we need to continue if cannot find configuration interface for this
+        // sensor.
+        if (!configurationInterface)
+        {
+            continue;
+        }
+
+        // We found a configuration interface.
+        std::map<std::string, Value> configurationProperties =
+            getEntityManagerProperties(sensorConfigPath.c_str(),
+                                       configurationInterface->c_str());
+
+        entityIdProp = configurationProperties.find("EntityId");
+        entityInstanceProp = configurationProperties.find("EntityInstance");
+        if (entityIdProp != configurationProperties.end())
+        {
+            entityId =
+                static_cast<uint8_t>(std::get<uint64_t>(entityIdProp->second));
+        }
+        if (entityInstanceProp != configurationProperties.end())
+        {
+            entityInstance = static_cast<uint8_t>(
+                std::get<uint64_t>(entityInstanceProp->second));
+        }
+
+        // stop searching Association records.
+        break;
+    } // end for Association vectors.
+
+    if constexpr (debug)
+    {
+        std::fprintf(stderr, "path=%s, entityId=%d, entityInstance=%d\n",
+                     path.c_str(), entityId, entityInstance);
+    }
+}
+
+} // namespace ipmi
diff --git a/dbus-sdr/sensorcommands.cpp b/dbus-sdr/sensorcommands.cpp
new file mode 100644
index 0000000..2ef33b9
--- /dev/null
+++ b/dbus-sdr/sensorcommands.cpp
@@ -0,0 +1,2882 @@
+/*
+// Copyright (c) 2017 2018 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 "config.h"
+
+#include "dbus-sdr/sensorcommands.hpp"
+
+#include "dbus-sdr/sdrutils.hpp"
+#include "dbus-sdr/sensorutils.hpp"
+#include "dbus-sdr/storagecommands.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/container/flat_map.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/entity_map_json.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <user_channel/channel_layer.hpp>
+
+#include <algorithm>
+#include <array>
+#include <chrono>
+#include <cmath>
+#include <cstring>
+#include <format>
+#include <iostream>
+#include <map>
+#include <optional>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <variant>
+
+#ifdef FEATURE_HYBRID_SENSORS
+
+#include "sensordatahandler.hpp"
+namespace ipmi
+{
+namespace sensor
+{
+extern const IdInfoMap sensors;
+} // namespace sensor
+} // namespace ipmi
+#endif
+namespace ipmi
+{
+namespace dcmi
+{
+// Refer Table 6-14, DCMI Entity ID Extension, DCMI v1.5 spec
+static const std::map<uint8_t, uint8_t> validEntityId{
+    {0x40, 0x37}, {0x37, 0x40}, {0x41, 0x03},
+    {0x03, 0x41}, {0x42, 0x07}, {0x07, 0x42}};
+constexpr uint8_t temperatureSensorType = 0x01;
+constexpr uint8_t maxRecords = 8;
+} // namespace dcmi
+} // namespace ipmi
+constexpr std::array<const char*, 7> suffixes = {
+    "_Output_Voltage", "_Input_Voltage", "_Output_Current", "_Input_Current",
+    "_Output_Power",   "_Input_Power",   "_Temperature"};
+namespace ipmi
+{
+
+using phosphor::logging::entry;
+using phosphor::logging::level;
+using phosphor::logging::log;
+
+static constexpr int sensorMapUpdatePeriod = 10;
+static constexpr int sensorMapSdrUpdatePeriod = 60;
+
+// BMC I2C address is generally at 0x20
+static constexpr uint8_t bmcI2CAddr = 0x20;
+
+constexpr size_t maxSDRTotalSize =
+    76; // Largest SDR Record Size (type 01) + SDR Overheader Size
+constexpr static const uint32_t noTimestamp = 0xFFFFFFFF;
+
+static uint16_t sdrReservationID;
+static uint32_t sdrLastAdd = noTimestamp;
+static uint32_t sdrLastRemove = noTimestamp;
+static constexpr size_t lastRecordIndex = 0xFFFF;
+
+// The IPMI spec defines four Logical Units (LUN), each capable of supporting
+// 255 sensors. The 256 values assigned to LUN 2 are special and are not used
+// for general purpose sensors. Each LUN reserves location 0xFF. The maximum
+// number of IPMI sensors are LUN 0 + LUN 1 + LUN 3, less the reserved
+// location.
+static constexpr size_t maxIPMISensors = ((3 * 256) - (3 * 1));
+
+static constexpr uint8_t lun0 = 0x0;
+static constexpr uint8_t lun1 = 0x1;
+static constexpr uint8_t lun3 = 0x3;
+
+static constexpr size_t lun0MaxSensorNum = 0xfe;
+static constexpr size_t lun1MaxSensorNum = 0x1fe;
+static constexpr size_t lun3MaxSensorNum = 0x3fe;
+static constexpr int GENERAL_ERROR = -1;
+
+static boost::container::flat_map<std::string, ObjectValueTree> SensorCache;
+
+// Specify the comparison required to sort and find char* map objects
+struct CmpStr
+{
+    bool operator()(const char* a, const char* b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
+};
+const static boost::container::flat_map<const char*, SensorUnits, CmpStr>
+    sensorUnits{{{"temperature", SensorUnits::degreesC},
+                 {"voltage", SensorUnits::volts},
+                 {"current", SensorUnits::amps},
+                 {"fan_tach", SensorUnits::rpm},
+                 {"power", SensorUnits::watts},
+                 {"energy", SensorUnits::joules}}};
+
+void registerSensorFunctions() __attribute__((constructor));
+
+static sdbusplus::bus::match_t sensorAdded(
+    *getSdBus(),
+    "type='signal',member='InterfacesAdded',arg0path='/xyz/openbmc_project/"
+    "sensors/'",
+    [](sdbusplus::message_t&) {
+        getSensorTree().clear();
+        getIpmiDecoratorPaths(/*ctx=*/std::nullopt).reset();
+        sdrLastAdd = std::chrono::duration_cast<std::chrono::seconds>(
+                         std::chrono::system_clock::now().time_since_epoch())
+                         .count();
+    });
+
+static sdbusplus::bus::match_t sensorRemoved(
+    *getSdBus(),
+    "type='signal',member='InterfacesRemoved',arg0path='/xyz/openbmc_project/"
+    "sensors/'",
+    [](sdbusplus::message_t&) {
+        getSensorTree().clear();
+        getIpmiDecoratorPaths(/*ctx=*/std::nullopt).reset();
+        sdrLastRemove = std::chrono::duration_cast<std::chrono::seconds>(
+                            std::chrono::system_clock::now().time_since_epoch())
+                            .count();
+    });
+
+ipmi_ret_t getSensorConnection(ipmi::Context::ptr ctx, uint8_t sensnum,
+                               std::string& connection, std::string& path,
+                               std::vector<std::string>* interfaces)
+{
+    auto& sensorTree = getSensorTree();
+    if (!getSensorSubtree(sensorTree) && sensorTree.empty())
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    if (ctx == nullptr)
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    path = getPathFromSensorNumber((ctx->lun << 8) | sensnum);
+    if (path.empty())
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    for (const auto& sensor : sensorTree)
+    {
+        if (path == sensor.first)
+        {
+            connection = sensor.second.begin()->first;
+            if (interfaces)
+                *interfaces = sensor.second.begin()->second;
+            break;
+        }
+    }
+
+    return 0;
+}
+
+SensorSubTree& getSensorTree()
+{
+    static SensorSubTree sensorTree;
+    return sensorTree;
+}
+
+// this keeps track of deassertions for sensor event status command. A
+// deasertion can only happen if an assertion was seen first.
+static boost::container::flat_map<
+    std::string, boost::container::flat_map<std::string, std::optional<bool>>>
+    thresholdDeassertMap;
+
+static sdbusplus::bus::match_t thresholdChanged(
+    *getSdBus(),
+    "type='signal',member='PropertiesChanged',interface='org.freedesktop.DBus."
+    "Properties',arg0namespace='xyz.openbmc_project.Sensor.Threshold'",
+    [](sdbusplus::message_t& m) {
+        boost::container::flat_map<std::string, std::variant<bool, double>>
+            values;
+        m.read(std::string(), values);
+
+        auto findAssert =
+            std::find_if(values.begin(), values.end(), [](const auto& pair) {
+                return pair.first.find("Alarm") != std::string::npos;
+            });
+        if (findAssert != values.end())
+        {
+            auto ptr = std::get_if<bool>(&(findAssert->second));
+            if (ptr == nullptr)
+            {
+                lg2::error("thresholdChanged: Assert non bool");
+                return;
+            }
+            if (*ptr)
+            {
+                lg2::info(
+                    "thresholdChanged: Assert, sensor path: {SENSOR_PATH}",
+                    "SENSOR_PATH", m.get_path());
+                thresholdDeassertMap[m.get_path()][findAssert->first] = *ptr;
+            }
+            else
+            {
+                auto& value =
+                    thresholdDeassertMap[m.get_path()][findAssert->first];
+                if (value)
+                {
+                    lg2::info(
+                        "thresholdChanged: deassert, sensor path: {SENSOR_PATH}",
+                        "SENSOR_PATH", m.get_path());
+                    value = *ptr;
+                }
+            }
+        }
+    });
+
+namespace sensor
+{
+static constexpr const char* vrInterface =
+    "xyz.openbmc_project.Control.VoltageRegulatorMode";
+static constexpr const char* sensorInterface =
+    "xyz.openbmc_project.Sensor.Value";
+} // namespace sensor
+
+static void getSensorMaxMin(const DbusInterfaceMap& sensorMap, double& max,
+                            double& min)
+{
+    max = 127;
+    min = -128;
+
+    auto sensorObject = sensorMap.find(sensor::sensorInterface);
+    auto critical =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+    auto warning =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+
+    if (sensorObject != sensorMap.end())
+    {
+        auto maxMap = sensorObject->second.find("MaxValue");
+        auto minMap = sensorObject->second.find("MinValue");
+
+        if (maxMap != sensorObject->second.end())
+        {
+            max = std::visit(VariantToDoubleVisitor(), maxMap->second);
+        }
+        if (minMap != sensorObject->second.end())
+        {
+            min = std::visit(VariantToDoubleVisitor(), minMap->second);
+        }
+    }
+    if (critical != sensorMap.end())
+    {
+        auto lower = critical->second.find("CriticalLow");
+        auto upper = critical->second.find("CriticalHigh");
+        if (lower != critical->second.end())
+        {
+            double value = std::visit(VariantToDoubleVisitor(), lower->second);
+            if (std::isfinite(value))
+            {
+                min = std::fmin(value, min);
+            }
+        }
+        if (upper != critical->second.end())
+        {
+            double value = std::visit(VariantToDoubleVisitor(), upper->second);
+            if (std::isfinite(value))
+            {
+                max = std::fmax(value, max);
+            }
+        }
+    }
+    if (warning != sensorMap.end())
+    {
+        auto lower = warning->second.find("WarningLow");
+        auto upper = warning->second.find("WarningHigh");
+        if (lower != warning->second.end())
+        {
+            double value = std::visit(VariantToDoubleVisitor(), lower->second);
+            if (std::isfinite(value))
+            {
+                min = std::fmin(value, min);
+            }
+        }
+        if (upper != warning->second.end())
+        {
+            double value = std::visit(VariantToDoubleVisitor(), upper->second);
+            if (std::isfinite(value))
+            {
+                max = std::fmax(value, max);
+            }
+        }
+    }
+}
+
+static bool getSensorMap(ipmi::Context::ptr ctx, std::string sensorConnection,
+                         std::string sensorPath, DbusInterfaceMap& sensorMap,
+                         int updatePeriod = sensorMapUpdatePeriod)
+{
+#ifdef FEATURE_HYBRID_SENSORS
+    if (auto sensor = findStaticSensor(sensorPath);
+        sensor != ipmi::sensor::sensors.end() &&
+        getSensorEventTypeFromPath(sensorPath) !=
+            static_cast<uint8_t>(SensorEventTypeCodes::threshold))
+    {
+        // If the incoming sensor is a discrete sensor, it might fail in
+        // getManagedObjects(), return true, and use its own getFunc to get
+        // value.
+        return true;
+    }
+#endif
+
+    static boost::container::flat_map<
+        std::string, std::chrono::time_point<std::chrono::steady_clock>>
+        updateTimeMap;
+
+    auto updateFind = updateTimeMap.find(sensorConnection);
+    auto lastUpdate = std::chrono::time_point<std::chrono::steady_clock>();
+    if (updateFind != updateTimeMap.end())
+    {
+        lastUpdate = updateFind->second;
+    }
+
+    auto now = std::chrono::steady_clock::now();
+
+    if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate)
+            .count() > updatePeriod)
+    {
+        bool found = false;
+
+        // Object managers for different kinds of OpenBMC DBus interfaces.
+        // Documented in the phosphor-dbus-interfaces repository.
+        const char* paths[] = {
+            "/xyz/openbmc_project/sensors",
+            "/xyz/openbmc_project/vr",
+        };
+        constexpr size_t num_paths = sizeof(paths) / sizeof(paths[0]);
+        ObjectValueTree allManagedObjects;
+
+        for (size_t i = 0; i < num_paths; i++)
+        {
+            ObjectValueTree managedObjects;
+            boost::system::error_code ec = getManagedObjects(
+                ctx, sensorConnection.c_str(), paths[i], managedObjects);
+            if (ec)
+            {
+                continue;
+            }
+            allManagedObjects.merge(managedObjects);
+            found = true;
+        }
+
+        if (!found)
+        {
+            lg2::error("GetMangagedObjects for getSensorMap failed, "
+                       "service: {SERVICE}",
+                       "SERVICE", sensorConnection);
+
+            return false;
+        }
+
+        SensorCache[sensorConnection] = allManagedObjects;
+        // Update time after finish building the map which allow the
+        // data to be cached for updatePeriod plus the build time.
+        updateTimeMap[sensorConnection] = std::chrono::steady_clock::now();
+    }
+    auto connection = SensorCache.find(sensorConnection);
+    if (connection == SensorCache.end())
+    {
+        return false;
+    }
+    auto path = connection->second.find(sensorPath);
+    if (path == connection->second.end())
+    {
+        return false;
+    }
+    sensorMap = path->second;
+
+    return true;
+}
+
+namespace sensor
+{
+// Read VR profiles from sensor(daemon) interface
+static std::optional<std::vector<std::string>> getSupportedVrProfiles(
+    const ipmi::DbusInterfaceMap::mapped_type& object)
+{
+    // get VR mode profiles from Supported Interface
+    auto supportedProperty = object.find("Supported");
+    if (supportedProperty == object.end() ||
+        object.find("Selected") == object.end())
+    {
+        lg2::error("Missing the required Supported and Selected properties");
+        return std::nullopt;
+    }
+
+    const auto profilesPtr =
+        std::get_if<std::vector<std::string>>(&supportedProperty->second);
+
+    if (profilesPtr == nullptr)
+    {
+        lg2::error("property is not array of string");
+        return std::nullopt;
+    }
+    return *profilesPtr;
+}
+
+// Calculate VR Mode from input IPMI discrete event bytes
+static std::optional<std::string> calculateVRMode(
+    uint15_t assertOffset, const ipmi::DbusInterfaceMap::mapped_type& VRObject)
+{
+    // get VR mode profiles from Supported Interface
+    auto profiles = getSupportedVrProfiles(VRObject);
+    if (!profiles)
+    {
+        return std::nullopt;
+    }
+
+    // interpret IPMI cmd bits into profiles' index
+    long unsigned int index = 0;
+    // only one bit should be set and the highest bit should not be used.
+    if (assertOffset == 0 || assertOffset == (1u << 15) ||
+        (assertOffset & (assertOffset - 1)))
+    {
+        lg2::error("IPMI cmd format incorrect, bytes: {BYTES}", "BYTES",
+                   lg2::hex, static_cast<uint16_t>(assertOffset));
+        return std::nullopt;
+    }
+
+    while (assertOffset != 1)
+    {
+        assertOffset >>= 1;
+        index++;
+    }
+
+    if (index >= profiles->size())
+    {
+        lg2::error("profile index out of boundary");
+        return std::nullopt;
+    }
+
+    return profiles->at(index);
+}
+
+// Calculate sensor value from IPMI reading byte
+static std::optional<double> calculateValue(
+    uint8_t reading, const ipmi::DbusInterfaceMap& sensorMap,
+    const ipmi::DbusInterfaceMap::mapped_type& valueObject)
+{
+    if (valueObject.find("Value") == valueObject.end())
+    {
+        lg2::error("Missing the required Value property");
+        return std::nullopt;
+    }
+
+    double max = 0;
+    double min = 0;
+    getSensorMaxMin(sensorMap, max, min);
+
+    int16_t mValue = 0;
+    int16_t bValue = 0;
+    int8_t rExp = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        return std::nullopt;
+    }
+
+    double value = bSigned ? ((int8_t)reading) : reading;
+
+    value *= ((double)mValue);
+    value += ((double)bValue) * std::pow(10.0, bExp);
+    value *= std::pow(10.0, rExp);
+
+    return value;
+}
+
+// Extract file name from sensor path as the sensors SDR ID. Simplify the name
+// if it is too long.
+std::string parseSdrIdFromPath(const std::string& path)
+{
+    std::string name;
+    size_t nameStart = path.rfind("/");
+    if (nameStart != std::string::npos)
+    {
+        name = path.substr(nameStart + 1, std::string::npos - nameStart);
+    }
+
+    if (name.size() > FULL_RECORD_ID_STR_MAX_LENGTH)
+    {
+#ifdef SHORTNAME_REMOVE_SUFFIX
+        for (const auto& suffix : suffixes)
+        {
+            if (boost::ends_with(name, suffix))
+            {
+                boost::replace_all(name, suffix, "");
+                break;
+            }
+        }
+#endif
+#ifdef SHORTNAME_REPLACE_WORDS
+        constexpr std::array<std::pair<const char*, const char*>, 2>
+            replaceWords = {std::make_pair("Output", "Out"),
+                            std::make_pair("Input", "In")};
+        for (const auto& [find, replace] : replaceWords)
+        {
+            boost::replace_all(name, find, replace);
+        }
+#endif
+
+        // as a backup and if nothing else is configured
+        name.resize(FULL_RECORD_ID_STR_MAX_LENGTH);
+    }
+    return name;
+}
+
+bool getVrEventStatus(ipmi::Context::ptr ctx, const std::string& connection,
+                      const std::string& path,
+                      const ipmi::DbusInterfaceMap::mapped_type& object,
+                      std::bitset<16>& assertions)
+{
+    auto profiles = sensor::getSupportedVrProfiles(object);
+    if (!profiles)
+    {
+        return false;
+    }
+    std::string mode;
+
+    auto ec = getDbusProperty(ctx, connection, path, sensor::vrInterface,
+                              "Selected", mode);
+    if (ec)
+    {
+        lg2::error("Failed to get Selected, path: {PATH}, "
+                   "interface: {INTERFACE}, error: {ERROR}",
+                   "PATH", path, "INTERFACE", sensor::sensorInterface, "ERROR",
+                   ec.message());
+        return false;
+    }
+
+    auto itr = std::find(profiles->begin(), profiles->end(), mode);
+    if (itr == profiles->end())
+    {
+        lg2::error("VR mode doesn't match any of its profiles, path: {PATH}",
+                   "PATH", path);
+        return false;
+    }
+    std::size_t index =
+        static_cast<std::size_t>(std::distance(profiles->begin(), itr));
+
+    // map index to response event assertion bit.
+    if (index < 16)
+    {
+        assertions.set(index);
+    }
+    else
+    {
+        lg2::error("VR profile index reaches max assertion bit, "
+                   "path: {PATH}, index: {INDEX}",
+                   "PATH", path, "INDEX", index);
+        return false;
+    }
+    if constexpr (debug)
+    {
+        std::cerr << "VR sensor " << sensor::parseSdrIdFromPath(path)
+                  << " mode is: [" << index << "] " << mode << std::endl;
+    }
+    return true;
+}
+
+/*
+ * Handle every Sensor Data Record besides Type 01
+ *
+ * The D-Bus sensors work well for generating Type 01 SDRs.
+ * After the Type 01 sensors are processed the remaining sensor types require
+ * special handling. Each BMC vendor is going to have their own requirements for
+ * insertion of non-Type 01 records.
+ * Manage non-Type 01 records:
+ *
+ * Create a new file: dbus-sdr/sensorcommands_oem.cpp
+ * Populate it with the two weakly linked functions below, without adding the
+ * 'weak' attribute definition prior to the function definition.
+ *    getOtherSensorsCount(...)
+ *    getOtherSensorsDataRecord(...)
+ *    Example contents are provided in the weak definitions below
+ *    Enable 'sensors-oem' in your phosphor-ipmi-host bbappend file
+ *      'EXTRA_OEMESON:append = " -Dsensors-oem=enabled"'
+ * The contents of the sensorcommands_oem.cpp file will then override the code
+ * provided below.
+ */
+
+size_t getOtherSensorsCount(ipmi::Context::ptr ctx) __attribute__((weak));
+size_t getOtherSensorsCount(ipmi::Context::ptr ctx)
+{
+    size_t fruCount = 0;
+
+    ipmi::Cc ret = ipmi::storage::getFruSdrCount(ctx, fruCount);
+    if (ret != ipmi::ccSuccess)
+    {
+        lg2::error("getOtherSensorsCount: getFruSdrCount error");
+        return std::numeric_limits<size_t>::max();
+    }
+
+    const auto& entityRecords =
+        ipmi::sensor::EntityInfoMapContainer::getContainer()
+            ->getIpmiEntityRecords();
+    size_t entityCount = entityRecords.size();
+
+    return fruCount + ipmi::storage::type12Count + entityCount;
+}
+
+int getOtherSensorsDataRecord(ipmi::Context::ptr ctx, uint16_t recordID,
+                              std::vector<uint8_t>& recordData)
+    __attribute__((weak));
+int getOtherSensorsDataRecord(ipmi::Context::ptr ctx, uint16_t recordID,
+                              std::vector<uint8_t>& recordData)
+{
+    size_t otherCount{ipmi::sensor::getOtherSensorsCount(ctx)};
+    if (otherCount == std::numeric_limits<size_t>::max())
+    {
+        return GENERAL_ERROR;
+    }
+    const auto& entityRecords =
+        ipmi::sensor::EntityInfoMapContainer::getContainer()
+            ->getIpmiEntityRecords();
+
+    size_t sdrIndex(recordID - ipmi::getNumberOfSensors());
+    size_t entityCount{entityRecords.size()};
+    size_t fruCount{otherCount - ipmi::storage::type12Count - entityCount};
+
+    if (sdrIndex > otherCount)
+    {
+        return std::numeric_limits<int>::min();
+    }
+    else if (sdrIndex >= fruCount + ipmi::storage::type12Count)
+    {
+        // handle type 8 entity map records
+        ipmi::sensor::EntityInfoMap::const_iterator entity =
+            entityRecords.find(static_cast<uint8_t>(
+                sdrIndex - fruCount - ipmi::storage::type12Count));
+
+        if (entity == entityRecords.end())
+        {
+            return GENERAL_ERROR;
+        }
+        recordData = ipmi::storage::getType8SDRs(entity, recordID);
+    }
+    else if (sdrIndex >= fruCount)
+    {
+        // handle type 12 hardcoded records
+        size_t type12Index = sdrIndex - fruCount;
+        if (type12Index >= ipmi::storage::type12Count)
+        {
+            lg2::error("getSensorDataRecord: type12Index error");
+            return GENERAL_ERROR;
+        }
+        recordData = ipmi::storage::getType12SDRs(type12Index, recordID);
+    }
+    else
+    {
+        // handle fru records
+        get_sdr::SensorDataFruRecord data;
+        if (ipmi::Cc ret = ipmi::storage::getFruSdrs(ctx, sdrIndex, data);
+            ret != IPMI_CC_OK)
+        {
+            return GENERAL_ERROR;
+        }
+        data.header.record_id_msb = recordID >> 8;
+        data.header.record_id_lsb = recordID & 0xFF;
+        recordData.insert(recordData.end(), reinterpret_cast<uint8_t*>(&data),
+                          reinterpret_cast<uint8_t*>(&data) + sizeof(data));
+    }
+
+    return 0;
+}
+
+} // namespace sensor
+
+ipmi::RspType<> ipmiSenPlatformEvent(ipmi::Context::ptr ctx,
+                                     ipmi::message::Payload& p)
+{
+    constexpr const uint8_t validEnvmRev = 0x04;
+    constexpr const uint8_t lastSensorType = 0x2C;
+    constexpr const uint8_t oemReserved = 0xC0;
+
+    uint8_t sysgeneratorID = 0;
+    uint8_t evmRev = 0;
+    uint8_t sensorType = 0;
+    uint8_t sensorNum = 0;
+    uint8_t eventType = 0;
+    uint8_t eventData1 = 0;
+    std::optional<uint8_t> eventData2 = 0;
+    std::optional<uint8_t> eventData3 = 0;
+    [[maybe_unused]] uint16_t generatorID = 0;
+    ipmi::ChannelInfo chInfo;
+
+    if (ipmi::getChannelInfo(ctx->channel, chInfo) != ipmi::ccSuccess)
+    {
+        lg2::error("Failed to get Channel Info, channel: {CHANNEL}", "CHANNEL",
+                   ctx->channel);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    if (static_cast<ipmi::EChannelMediumType>(chInfo.mediumType) ==
+        ipmi::EChannelMediumType::systemInterface)
+    {
+        p.unpack(sysgeneratorID, evmRev, sensorType, sensorNum, eventType,
+                 eventData1, eventData2, eventData3);
+        constexpr const uint8_t isSoftwareID = 0x01;
+        if (!(sysgeneratorID & isSoftwareID))
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        // Refer to IPMI Spec Table 32: SEL Event Records
+        generatorID = (ctx->channel << 12) // Channel
+                      | (0x0 << 10)        // Reserved
+                      | (0x0 << 8)         // 0x0 for sys-soft ID
+                      | sysgeneratorID;
+    }
+    else
+    {
+        p.unpack(evmRev, sensorType, sensorNum, eventType, eventData1,
+                 eventData2, eventData3);
+        // Refer to IPMI Spec Table 32: SEL Event Records
+        generatorID = (ctx->channel << 12)      // Channel
+                      | (0x0 << 10)             // Reserved
+                      | ((ctx->lun & 0x3) << 8) // Lun
+                      | (ctx->rqSA << 1);
+    }
+
+    if (!p.fullyUnpacked())
+    {
+        return ipmi::responseReqDataLenInvalid();
+    }
+
+    // Check for valid evmRev and Sensor Type(per Table 42 of spec)
+    if (evmRev != validEnvmRev)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if ((sensorType > lastSensorType) && (sensorType < oemReserved))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    return ipmi::responseSuccess();
+}
+
+ipmi::RspType<> ipmiSetSensorReading(
+    ipmi::Context::ptr ctx, uint8_t sensorNumber, uint8_t, uint8_t reading,
+    uint15_t assertOffset, bool, uint15_t, bool, uint8_t, uint8_t, uint8_t)
+{
+    std::string connection;
+    std::string path;
+    std::vector<std::string> interfaces;
+
+    ipmi::Cc status =
+        getSensorConnection(ctx, sensorNumber, connection, path, &interfaces);
+    if (status)
+    {
+        return ipmi::response(status);
+    }
+
+    // we can tell the sensor type by its interface type
+    if (std::find(interfaces.begin(), interfaces.end(),
+                  sensor::sensorInterface) != interfaces.end())
+    {
+        DbusInterfaceMap sensorMap;
+        if (!getSensorMap(ctx, connection, path, sensorMap))
+        {
+            return ipmi::responseResponseError();
+        }
+        auto sensorObject = sensorMap.find(sensor::sensorInterface);
+        if (sensorObject == sensorMap.end())
+        {
+            return ipmi::responseResponseError();
+        }
+
+        // Only allow external SetSensor if write permission granted
+        if (!details::sdrWriteTable.getWritePermission(
+                (ctx->lun << 8) | sensorNumber))
+        {
+            return ipmi::responseResponseError();
+        }
+
+        auto value =
+            sensor::calculateValue(reading, sensorMap, sensorObject->second);
+        if (!value)
+        {
+            return ipmi::responseResponseError();
+        }
+
+        if constexpr (debug)
+        {
+            lg2::info("IPMI SET_SENSOR, sensor number: {SENSOR_NUM}, "
+                      "byte: {BYTE}, value: {VALUE}",
+                      "SENSOR_NUM", sensorNumber, "BYTE", (unsigned int)reading,
+                      "VALUE", *value);
+        }
+
+        boost::system::error_code ec =
+            setDbusProperty(ctx, connection, path, sensor::sensorInterface,
+                            "Value", ipmi::Value(*value));
+
+        // setDbusProperty intended to resolve dbus exception/rc within the
+        // function but failed to achieve that. Catch exception in the ipmi
+        // callback functions for now (e.g. ipmiSetSensorReading).
+        if (ec)
+        {
+            lg2::error("Failed to set Value, path: {PATH}, "
+                       "interface: {INTERFACE}, ERROR: {ERROR}",
+                       "PATH", path, "INTERFACE", sensor::sensorInterface,
+                       "ERROR", ec.message());
+            return ipmi::responseResponseError();
+        }
+        return ipmi::responseSuccess();
+    }
+
+    if (std::find(interfaces.begin(), interfaces.end(), sensor::vrInterface) !=
+        interfaces.end())
+    {
+        DbusInterfaceMap sensorMap;
+        if (!getSensorMap(ctx, connection, path, sensorMap))
+        {
+            return ipmi::responseResponseError();
+        }
+        auto sensorObject = sensorMap.find(sensor::vrInterface);
+        if (sensorObject == sensorMap.end())
+        {
+            return ipmi::responseResponseError();
+        }
+
+        // VR sensors are treated as a special case and we will not check the
+        // write permission for VR sensors, since they always deemed writable
+        // and permission table are not applied to VR sensors.
+        auto vrMode =
+            sensor::calculateVRMode(assertOffset, sensorObject->second);
+        if (!vrMode)
+        {
+            return ipmi::responseResponseError();
+        }
+        boost::system::error_code ec = setDbusProperty(
+            ctx, connection, path, sensor::vrInterface, "Selected", *vrMode);
+        // setDbusProperty intended to resolve dbus exception/rc within the
+        // function but failed to achieve that. Catch exception in the ipmi
+        // callback functions for now (e.g. ipmiSetSensorReading).
+        if (ec)
+        {
+            lg2::error("Failed to set Selected, path: {PATH}, "
+                       "interface: {INTERFACE}, ERROR: {ERROR}",
+                       "PATH", path, "INTERFACE", sensor::sensorInterface,
+                       "ERROR", ec.message());
+        }
+        return ipmi::responseSuccess();
+    }
+
+    lg2::error("unknown sensor type, path: {PATH}", "PATH", path);
+    return ipmi::responseResponseError();
+}
+
+ipmi::RspType<uint8_t, uint8_t, uint8_t, std::optional<uint8_t>>
+    ipmiSenGetSensorReading(ipmi::Context::ptr ctx, uint8_t sensnum)
+{
+    std::string connection;
+    std::string path;
+
+    if (sensnum == reservedSensorNumber)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    auto status = getSensorConnection(ctx, sensnum, connection, path);
+    if (status)
+    {
+        return ipmi::response(status);
+    }
+
+#ifdef FEATURE_HYBRID_SENSORS
+    if (auto sensor = findStaticSensor(path);
+        sensor != ipmi::sensor::sensors.end() &&
+        getSensorEventTypeFromPath(path) !=
+            static_cast<uint8_t>(SensorEventTypeCodes::threshold))
+    {
+        if (ipmi::sensor::Mutability::Read !=
+            (sensor->second.mutability & ipmi::sensor::Mutability::Read))
+        {
+            return ipmi::responseIllegalCommand();
+        }
+
+        uint8_t operation;
+        try
+        {
+            ipmi::sensor::GetSensorResponse getResponse =
+                sensor->second.getFunc(sensor->second);
+
+            if (getResponse.readingOrStateUnavailable)
+            {
+                operation |= static_cast<uint8_t>(
+                    IPMISensorReadingByte2::readingStateUnavailable);
+            }
+            if (getResponse.scanningEnabled)
+            {
+                operation |= static_cast<uint8_t>(
+                    IPMISensorReadingByte2::sensorScanningEnable);
+            }
+            if (getResponse.allEventMessagesEnabled)
+            {
+                operation |= static_cast<uint8_t>(
+                    IPMISensorReadingByte2::eventMessagesEnable);
+            }
+            return ipmi::responseSuccess(
+                getResponse.reading, operation,
+                getResponse.thresholdLevelsStates,
+                getResponse.discreteReadingSensorStates);
+        }
+        catch (const std::exception& e)
+        {
+            operation |= static_cast<uint8_t>(
+                IPMISensorReadingByte2::readingStateUnavailable);
+            return ipmi::responseSuccess(0, operation, 0, std::nullopt);
+        }
+    }
+#endif
+
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, connection, path, sensorMap))
+    {
+        return ipmi::responseResponseError();
+    }
+    auto sensorObject = sensorMap.find(sensor::sensorInterface);
+
+    if (sensorObject == sensorMap.end() ||
+        sensorObject->second.find("Value") == sensorObject->second.end())
+    {
+        return ipmi::responseResponseError();
+    }
+    auto& valueVariant = sensorObject->second["Value"];
+    double reading = std::visit(VariantToDoubleVisitor(), valueVariant);
+
+    double max = 0;
+    double min = 0;
+    getSensorMaxMin(sensorMap, max, min);
+
+    int16_t mValue = 0;
+    int16_t bValue = 0;
+    int8_t rExp = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        return ipmi::responseResponseError();
+    }
+
+    uint8_t value =
+        scaleIPMIValueFromDouble(reading, mValue, rExp, bValue, bExp, bSigned);
+    uint8_t operation =
+        static_cast<uint8_t>(IPMISensorReadingByte2::sensorScanningEnable);
+    operation |=
+        static_cast<uint8_t>(IPMISensorReadingByte2::eventMessagesEnable);
+    bool notReading = std::isnan(reading);
+
+    if (!notReading)
+    {
+        auto availableObject =
+            sensorMap.find("xyz.openbmc_project.State.Decorator.Availability");
+        if (availableObject != sensorMap.end())
+        {
+            auto findAvailable = availableObject->second.find("Available");
+            if (findAvailable != availableObject->second.end())
+            {
+                bool* available = std::get_if<bool>(&(findAvailable->second));
+                if (available && !(*available))
+                {
+                    notReading = true;
+                }
+            }
+        }
+    }
+
+    if (notReading)
+    {
+        operation |= static_cast<uint8_t>(
+            IPMISensorReadingByte2::readingStateUnavailable);
+    }
+
+    if constexpr (details::enableInstrumentation)
+    {
+        int byteValue;
+        if (bSigned)
+        {
+            byteValue = static_cast<int>(static_cast<int8_t>(value));
+        }
+        else
+        {
+            byteValue = static_cast<int>(static_cast<uint8_t>(value));
+        }
+
+        // Keep stats on the reading just obtained, even if it is "NaN"
+        if (details::sdrStatsTable.updateReading((ctx->lun << 8) | sensnum,
+                                                 reading, byteValue))
+        {
+            // This is the first reading, show the coefficients
+            double step = (max - min) / 255.0;
+            std::cerr
+                << "IPMI sensor "
+                << details::sdrStatsTable.getName((ctx->lun << 8) | sensnum)
+                << ": Range min=" << min << " max=" << max << ", step=" << step
+                << ", Coefficients mValue=" << static_cast<int>(mValue)
+                << " rExp=" << static_cast<int>(rExp)
+                << " bValue=" << static_cast<int>(bValue)
+                << " bExp=" << static_cast<int>(bExp)
+                << " bSigned=" << static_cast<int>(bSigned) << "\n";
+        }
+    }
+
+    uint8_t thresholds = 0;
+
+    auto warningObject =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    if (warningObject != sensorMap.end())
+    {
+        auto alarmHigh = warningObject->second.find("WarningAlarmHigh");
+        auto alarmLow = warningObject->second.find("WarningAlarmLow");
+        if (alarmHigh != warningObject->second.end())
+        {
+            if (std::get<bool>(alarmHigh->second))
+            {
+                thresholds |= static_cast<uint8_t>(
+                    IPMISensorReadingByte3::upperNonCritical);
+            }
+        }
+        if (alarmLow != warningObject->second.end())
+        {
+            if (std::get<bool>(alarmLow->second))
+            {
+                thresholds |= static_cast<uint8_t>(
+                    IPMISensorReadingByte3::lowerNonCritical);
+            }
+        }
+    }
+
+    auto criticalObject =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+    if (criticalObject != sensorMap.end())
+    {
+        auto alarmHigh = criticalObject->second.find("CriticalAlarmHigh");
+        auto alarmLow = criticalObject->second.find("CriticalAlarmLow");
+        if (alarmHigh != criticalObject->second.end())
+        {
+            if (std::get<bool>(alarmHigh->second))
+            {
+                thresholds |=
+                    static_cast<uint8_t>(IPMISensorReadingByte3::upperCritical);
+            }
+        }
+        if (alarmLow != criticalObject->second.end())
+        {
+            if (std::get<bool>(alarmLow->second))
+            {
+                thresholds |=
+                    static_cast<uint8_t>(IPMISensorReadingByte3::lowerCritical);
+            }
+        }
+    }
+
+    // no discrete as of today so optional byte is never returned
+    return ipmi::responseSuccess(value, operation, thresholds, std::nullopt);
+}
+
+/** @brief implements the Set Sensor threshold command
+ *  @param sensorNumber        - sensor number
+ *  @param lowerNonCriticalThreshMask
+ *  @param lowerCriticalThreshMask
+ *  @param lowerNonRecovThreshMask
+ *  @param upperNonCriticalThreshMask
+ *  @param upperCriticalThreshMask
+ *  @param upperNonRecovThreshMask
+ *  @param reserved
+ *  @param lowerNonCritical    - lower non-critical threshold
+ *  @param lowerCritical       - Lower critical threshold
+ *  @param lowerNonRecoverable - Lower non recovarable threshold
+ *  @param upperNonCritical    - Upper non-critical threshold
+ *  @param upperCritical       - Upper critical
+ *  @param upperNonRecoverable - Upper Non-recoverable
+ *
+ *  @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiSenSetSensorThresholds(
+    ipmi::Context::ptr ctx, uint8_t sensorNum, bool lowerNonCriticalThreshMask,
+    bool lowerCriticalThreshMask, bool lowerNonRecovThreshMask,
+    bool upperNonCriticalThreshMask, bool upperCriticalThreshMask,
+    bool upperNonRecovThreshMask, uint2_t reserved, uint8_t lowerNonCritical,
+    uint8_t lowerCritical, [[maybe_unused]] uint8_t lowerNonRecoverable,
+    uint8_t upperNonCritical, uint8_t upperCritical,
+    [[maybe_unused]] uint8_t upperNonRecoverable)
+{
+    if (sensorNum == reservedSensorNumber || reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // lower nc and upper nc not suppported on any sensor
+    if (lowerNonRecovThreshMask || upperNonRecovThreshMask)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // if none of the threshold mask are set, nothing to do
+    if (!(lowerNonCriticalThreshMask | lowerCriticalThreshMask |
+          lowerNonRecovThreshMask | upperNonCriticalThreshMask |
+          upperCriticalThreshMask | upperNonRecovThreshMask))
+    {
+        return ipmi::responseSuccess();
+    }
+
+    std::string connection;
+    std::string path;
+
+    ipmi::Cc status = getSensorConnection(ctx, sensorNum, connection, path);
+    if (status)
+    {
+        return ipmi::response(status);
+    }
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, connection, path, sensorMap))
+    {
+        return ipmi::responseResponseError();
+    }
+
+    double max = 0;
+    double min = 0;
+    getSensorMaxMin(sensorMap, max, min);
+
+    int16_t mValue = 0;
+    int16_t bValue = 0;
+    int8_t rExp = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        return ipmi::responseResponseError();
+    }
+
+    // store a vector of property name, value to set, and interface
+    std::vector<std::tuple<std::string, uint8_t, std::string>> thresholdsToSet;
+
+    // define the indexes of the tuple
+    constexpr uint8_t propertyName = 0;
+    constexpr uint8_t thresholdValue = 1;
+    constexpr uint8_t interface = 2;
+    // verifiy all needed fields are present
+    if (lowerCriticalThreshMask || upperCriticalThreshMask)
+    {
+        auto findThreshold =
+            sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+        if (findThreshold == sensorMap.end())
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        if (lowerCriticalThreshMask)
+        {
+            auto findLower = findThreshold->second.find("CriticalLow");
+            if (findLower == findThreshold->second.end())
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+            thresholdsToSet.emplace_back("CriticalLow", lowerCritical,
+                                         findThreshold->first);
+        }
+        if (upperCriticalThreshMask)
+        {
+            auto findUpper = findThreshold->second.find("CriticalHigh");
+            if (findUpper == findThreshold->second.end())
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+            thresholdsToSet.emplace_back("CriticalHigh", upperCritical,
+                                         findThreshold->first);
+        }
+    }
+    if (lowerNonCriticalThreshMask || upperNonCriticalThreshMask)
+    {
+        auto findThreshold =
+            sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+        if (findThreshold == sensorMap.end())
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        if (lowerNonCriticalThreshMask)
+        {
+            auto findLower = findThreshold->second.find("WarningLow");
+            if (findLower == findThreshold->second.end())
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+            thresholdsToSet.emplace_back("WarningLow", lowerNonCritical,
+                                         findThreshold->first);
+        }
+        if (upperNonCriticalThreshMask)
+        {
+            auto findUpper = findThreshold->second.find("WarningHigh");
+            if (findUpper == findThreshold->second.end())
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+            thresholdsToSet.emplace_back("WarningHigh", upperNonCritical,
+                                         findThreshold->first);
+        }
+    }
+    for (const auto& property : thresholdsToSet)
+    {
+        // from section 36.3 in the IPMI Spec, assume all linear
+        double valueToSet = ((mValue * std::get<thresholdValue>(property)) +
+                             (bValue * std::pow(10.0, bExp))) *
+                            std::pow(10.0, rExp);
+        setDbusProperty(
+            *getSdBus(), connection, path, std::get<interface>(property),
+            std::get<propertyName>(property), ipmi::Value(valueToSet));
+    }
+    return ipmi::responseSuccess();
+}
+
+IPMIThresholds getIPMIThresholds(const DbusInterfaceMap& sensorMap)
+{
+    IPMIThresholds resp;
+    auto warningInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    auto criticalInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+
+    if ((warningInterface != sensorMap.end()) ||
+        (criticalInterface != sensorMap.end()))
+    {
+        auto sensorPair = sensorMap.find(sensor::sensorInterface);
+
+        if (sensorPair == sensorMap.end())
+        {
+            // should not have been able to find a sensor not implementing
+            // the sensor object
+            throw std::runtime_error("Invalid sensor map");
+        }
+
+        double max = 0;
+        double min = 0;
+        getSensorMaxMin(sensorMap, max, min);
+
+        int16_t mValue = 0;
+        int16_t bValue = 0;
+        int8_t rExp = 0;
+        int8_t bExp = 0;
+        bool bSigned = false;
+
+        if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+        {
+            throw std::runtime_error("Invalid sensor atrributes");
+        }
+        if (warningInterface != sensorMap.end())
+        {
+            auto& warningMap = warningInterface->second;
+
+            auto warningHigh = warningMap.find("WarningHigh");
+            auto warningLow = warningMap.find("WarningLow");
+
+            if (warningHigh != warningMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), warningHigh->second);
+                if (std::isfinite(value))
+                {
+                    resp.warningHigh = scaleIPMIValueFromDouble(
+                        value, mValue, rExp, bValue, bExp, bSigned);
+                }
+            }
+            if (warningLow != warningMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), warningLow->second);
+                if (std::isfinite(value))
+                {
+                    resp.warningLow = scaleIPMIValueFromDouble(
+                        value, mValue, rExp, bValue, bExp, bSigned);
+                }
+            }
+        }
+        if (criticalInterface != sensorMap.end())
+        {
+            auto& criticalMap = criticalInterface->second;
+
+            auto criticalHigh = criticalMap.find("CriticalHigh");
+            auto criticalLow = criticalMap.find("CriticalLow");
+
+            if (criticalHigh != criticalMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), criticalHigh->second);
+                if (std::isfinite(value))
+                {
+                    resp.criticalHigh = scaleIPMIValueFromDouble(
+                        value, mValue, rExp, bValue, bExp, bSigned);
+                }
+            }
+            if (criticalLow != criticalMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), criticalLow->second);
+                if (std::isfinite(value))
+                {
+                    resp.criticalLow = scaleIPMIValueFromDouble(
+                        value, mValue, rExp, bValue, bExp, bSigned);
+                }
+            }
+        }
+    }
+    return resp;
+}
+
+ipmi::RspType<uint8_t, // readable
+              uint8_t, // lowerNCrit
+              uint8_t, // lowerCrit
+              uint8_t, // lowerNrecoverable
+              uint8_t, // upperNC
+              uint8_t, // upperCrit
+              uint8_t> // upperNRecoverable
+    ipmiSenGetSensorThresholds(ipmi::Context::ptr ctx, uint8_t sensorNumber)
+{
+    std::string connection;
+    std::string path;
+
+    if (sensorNumber == reservedSensorNumber)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    auto status = getSensorConnection(ctx, sensorNumber, connection, path);
+    if (status)
+    {
+        return ipmi::response(status);
+    }
+
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, connection, path, sensorMap))
+    {
+        return ipmi::responseResponseError();
+    }
+
+    IPMIThresholds thresholdData;
+    try
+    {
+        thresholdData = getIPMIThresholds(sensorMap);
+    }
+    catch (const std::exception&)
+    {
+        return ipmi::responseResponseError();
+    }
+
+    uint8_t readable = 0;
+    uint8_t lowerNC = 0;
+    uint8_t lowerCritical = 0;
+    uint8_t lowerNonRecoverable = 0;
+    uint8_t upperNC = 0;
+    uint8_t upperCritical = 0;
+    uint8_t upperNonRecoverable = 0;
+
+    if (thresholdData.warningHigh)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::upperNonCritical);
+        upperNC = *thresholdData.warningHigh;
+    }
+    if (thresholdData.warningLow)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::lowerNonCritical);
+        lowerNC = *thresholdData.warningLow;
+    }
+
+    if (thresholdData.criticalHigh)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::upperCritical);
+        upperCritical = *thresholdData.criticalHigh;
+    }
+    if (thresholdData.criticalLow)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::lowerCritical);
+        lowerCritical = *thresholdData.criticalLow;
+    }
+
+    return ipmi::responseSuccess(readable, lowerNC, lowerCritical,
+                                 lowerNonRecoverable, upperNC, upperCritical,
+                                 upperNonRecoverable);
+}
+
+/** @brief implements the get Sensor event enable command
+ *  @param sensorNumber - sensor number
+ *
+ *  @returns IPMI completion code plus response data
+ *   - enabled               - Sensor Event messages
+ *   - assertionEnabledLsb   - Assertion event messages
+ *   - assertionEnabledMsb   - Assertion event messages
+ *   - deassertionEnabledLsb - Deassertion event messages
+ *   - deassertionEnabledMsb - Deassertion event messages
+ */
+
+ipmi::RspType<uint8_t, // enabled
+              uint8_t, // assertionEnabledLsb
+              uint8_t, // assertionEnabledMsb
+              uint8_t, // deassertionEnabledLsb
+              uint8_t> // deassertionEnabledMsb
+    ipmiSenGetSensorEventEnable(ipmi::Context::ptr ctx, uint8_t sensorNum)
+{
+    std::string connection;
+    std::string path;
+
+    uint8_t enabled = 0;
+    uint8_t assertionEnabledLsb = 0;
+    uint8_t assertionEnabledMsb = 0;
+    uint8_t deassertionEnabledLsb = 0;
+    uint8_t deassertionEnabledMsb = 0;
+
+    if (sensorNum == reservedSensorNumber)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    auto status = getSensorConnection(ctx, sensorNum, connection, path);
+    if (status)
+    {
+        return ipmi::response(status);
+    }
+
+#ifdef FEATURE_HYBRID_SENSORS
+    if (auto sensor = findStaticSensor(path);
+        sensor != ipmi::sensor::sensors.end() &&
+        getSensorEventTypeFromPath(path) !=
+            static_cast<uint8_t>(SensorEventTypeCodes::threshold))
+    {
+        enabled = static_cast<uint8_t>(
+            IPMISensorEventEnableByte2::sensorScanningEnable);
+        uint16_t assertionEnabled = 0;
+        for (auto& offsetValMap : sensor->second.propertyInterfaces.begin()
+                                      ->second.begin()
+                                      ->second.second)
+        {
+            assertionEnabled |= (1 << offsetValMap.first);
+        }
+        assertionEnabledLsb = static_cast<uint8_t>((assertionEnabled & 0xFF));
+        assertionEnabledMsb =
+            static_cast<uint8_t>(((assertionEnabled >> 8) & 0xFF));
+
+        return ipmi::responseSuccess(enabled, assertionEnabledLsb,
+                                     assertionEnabledMsb, deassertionEnabledLsb,
+                                     deassertionEnabledMsb);
+    }
+#endif
+
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, connection, path, sensorMap))
+    {
+        return ipmi::responseResponseError();
+    }
+
+    auto warningInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    auto criticalInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+    if ((warningInterface != sensorMap.end()) ||
+        (criticalInterface != sensorMap.end()))
+    {
+        enabled = static_cast<uint8_t>(
+            IPMISensorEventEnableByte2::sensorScanningEnable);
+        if (warningInterface != sensorMap.end())
+        {
+            auto& warningMap = warningInterface->second;
+
+            auto warningHigh = warningMap.find("WarningHigh");
+            auto warningLow = warningMap.find("WarningLow");
+            if (warningHigh != warningMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), warningHigh->second);
+                if (std::isfinite(value))
+                {
+                    assertionEnabledLsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::
+                            upperNonCriticalGoingHigh);
+                    deassertionEnabledLsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::
+                            upperNonCriticalGoingLow);
+                }
+            }
+            if (warningLow != warningMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), warningLow->second);
+                if (std::isfinite(value))
+                {
+                    assertionEnabledLsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::
+                            lowerNonCriticalGoingLow);
+                    deassertionEnabledLsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::
+                            lowerNonCriticalGoingHigh);
+                }
+            }
+        }
+        if (criticalInterface != sensorMap.end())
+        {
+            auto& criticalMap = criticalInterface->second;
+
+            auto criticalHigh = criticalMap.find("CriticalHigh");
+            auto criticalLow = criticalMap.find("CriticalLow");
+
+            if (criticalHigh != criticalMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), criticalHigh->second);
+                if (std::isfinite(value))
+                {
+                    assertionEnabledMsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::
+                            upperCriticalGoingHigh);
+                    deassertionEnabledMsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::upperCriticalGoingLow);
+                }
+            }
+            if (criticalLow != criticalMap.end())
+            {
+                double value =
+                    std::visit(VariantToDoubleVisitor(), criticalLow->second);
+                if (std::isfinite(value))
+                {
+                    assertionEnabledLsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::lowerCriticalGoingLow);
+                    deassertionEnabledLsb |= static_cast<uint8_t>(
+                        IPMISensorEventEnableThresholds::
+                            lowerCriticalGoingHigh);
+                }
+            }
+        }
+    }
+
+    return ipmi::responseSuccess(enabled, assertionEnabledLsb,
+                                 assertionEnabledMsb, deassertionEnabledLsb,
+                                 deassertionEnabledMsb);
+}
+
+/** @brief implements the get Sensor event status command
+ *  @param sensorNumber - sensor number, FFh = reserved
+ *
+ *  @returns IPMI completion code plus response data
+ *   - sensorEventStatus - Sensor Event messages state
+ *   - assertions        - Assertion event messages
+ *   - deassertions      - Deassertion event messages
+ */
+ipmi::RspType<uint8_t,         // sensorEventStatus
+              std::bitset<16>, // assertions
+              std::bitset<16>  // deassertion
+              >
+    ipmiSenGetSensorEventStatus(ipmi::Context::ptr ctx, uint8_t sensorNum)
+{
+    if (sensorNum == reservedSensorNumber)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    std::string connection;
+    std::string path;
+    auto status = getSensorConnection(ctx, sensorNum, connection, path);
+    if (status)
+    {
+        lg2::error("ipmiSenGetSensorEventStatus: Sensor connection Error, "
+                   "sensor number: {SENSOR_NUM}",
+                   "SENSOR_NUM", sensorNum);
+        return ipmi::response(status);
+    }
+
+#ifdef FEATURE_HYBRID_SENSORS
+    if (auto sensor = findStaticSensor(path);
+        sensor != ipmi::sensor::sensors.end() &&
+        getSensorEventTypeFromPath(path) !=
+            static_cast<uint8_t>(SensorEventTypeCodes::threshold))
+    {
+        auto response = ipmi::sensor::get::mapDbusToAssertion(
+            sensor->second, path, sensor->second.sensorInterface);
+        std::bitset<16> assertions;
+        // deassertions are not used.
+        std::bitset<16> deassertions = 0;
+        uint8_t sensorEventStatus;
+        if (response.readingOrStateUnavailable)
+        {
+            sensorEventStatus |= static_cast<uint8_t>(
+                IPMISensorReadingByte2::readingStateUnavailable);
+        }
+        if (response.scanningEnabled)
+        {
+            sensorEventStatus |= static_cast<uint8_t>(
+                IPMISensorReadingByte2::sensorScanningEnable);
+        }
+        if (response.allEventMessagesEnabled)
+        {
+            sensorEventStatus |= static_cast<uint8_t>(
+                IPMISensorReadingByte2::eventMessagesEnable);
+        }
+        assertions |= response.discreteReadingSensorStates << 8;
+        assertions |= response.thresholdLevelsStates;
+        return ipmi::responseSuccess(sensorEventStatus, assertions,
+                                     deassertions);
+    }
+#endif
+
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, connection, path, sensorMap))
+    {
+        lg2::error("ipmiSenGetSensorEventStatus: Sensor Mapping Error, "
+                   "sensor path: {SENSOR_PATH}",
+                   "SENSOR_PATH", path);
+        return ipmi::responseResponseError();
+    }
+
+    uint8_t sensorEventStatus =
+        static_cast<uint8_t>(IPMISensorEventEnableByte2::sensorScanningEnable);
+    std::bitset<16> assertions = 0;
+    std::bitset<16> deassertions = 0;
+
+    // handle VR typed sensor
+    auto vrInterface = sensorMap.find(sensor::vrInterface);
+    if (vrInterface != sensorMap.end())
+    {
+        if (!sensor::getVrEventStatus(ctx, connection, path,
+                                      vrInterface->second, assertions))
+        {
+            return ipmi::responseResponseError();
+        }
+
+        // both Event Message and Sensor Scanning are disable for VR.
+        sensorEventStatus = 0;
+        return ipmi::responseSuccess(sensorEventStatus, assertions,
+                                     deassertions);
+    }
+
+    auto warningInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
+    auto criticalInterface =
+        sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical");
+
+    std::optional<bool> criticalDeassertHigh =
+        thresholdDeassertMap[path]["CriticalAlarmHigh"];
+    std::optional<bool> criticalDeassertLow =
+        thresholdDeassertMap[path]["CriticalAlarmLow"];
+    std::optional<bool> warningDeassertHigh =
+        thresholdDeassertMap[path]["WarningAlarmHigh"];
+    std::optional<bool> warningDeassertLow =
+        thresholdDeassertMap[path]["WarningAlarmLow"];
+
+    if (criticalDeassertHigh && !*criticalDeassertHigh)
+    {
+        deassertions.set(static_cast<size_t>(
+            IPMIGetSensorEventEnableThresholds::upperCriticalGoingHigh));
+    }
+    if (criticalDeassertLow && !*criticalDeassertLow)
+    {
+        deassertions.set(static_cast<size_t>(
+            IPMIGetSensorEventEnableThresholds::upperCriticalGoingLow));
+    }
+    if (warningDeassertHigh && !*warningDeassertHigh)
+    {
+        deassertions.set(static_cast<size_t>(
+            IPMIGetSensorEventEnableThresholds::upperNonCriticalGoingHigh));
+    }
+    if (warningDeassertLow && !*warningDeassertLow)
+    {
+        deassertions.set(static_cast<size_t>(
+            IPMIGetSensorEventEnableThresholds::lowerNonCriticalGoingHigh));
+    }
+    if ((warningInterface != sensorMap.end()) ||
+        (criticalInterface != sensorMap.end()))
+    {
+        sensorEventStatus = static_cast<size_t>(
+            IPMISensorEventEnableByte2::eventMessagesEnable);
+        if (warningInterface != sensorMap.end())
+        {
+            auto& warningMap = warningInterface->second;
+
+            auto warningHigh = warningMap.find("WarningAlarmHigh");
+            auto warningLow = warningMap.find("WarningAlarmLow");
+            auto warningHighAlarm = false;
+            auto warningLowAlarm = false;
+
+            if (warningHigh != warningMap.end())
+            {
+                warningHighAlarm = std::get<bool>(warningHigh->second);
+            }
+            if (warningLow != warningMap.end())
+            {
+                warningLowAlarm = std::get<bool>(warningLow->second);
+            }
+            if (warningHighAlarm)
+            {
+                assertions.set(static_cast<size_t>(
+                    IPMIGetSensorEventEnableThresholds::
+                        upperNonCriticalGoingHigh));
+            }
+            if (warningLowAlarm)
+            {
+                assertions.set(static_cast<size_t>(
+                    IPMIGetSensorEventEnableThresholds::
+                        lowerNonCriticalGoingLow));
+            }
+        }
+        if (criticalInterface != sensorMap.end())
+        {
+            auto& criticalMap = criticalInterface->second;
+
+            auto criticalHigh = criticalMap.find("CriticalAlarmHigh");
+            auto criticalLow = criticalMap.find("CriticalAlarmLow");
+            auto criticalHighAlarm = false;
+            auto criticalLowAlarm = false;
+
+            if (criticalHigh != criticalMap.end())
+            {
+                criticalHighAlarm = std::get<bool>(criticalHigh->second);
+            }
+            if (criticalLow != criticalMap.end())
+            {
+                criticalLowAlarm = std::get<bool>(criticalLow->second);
+            }
+            if (criticalHighAlarm)
+            {
+                assertions.set(static_cast<size_t>(
+                    IPMIGetSensorEventEnableThresholds::
+                        upperCriticalGoingHigh));
+            }
+            if (criticalLowAlarm)
+            {
+                assertions.set(static_cast<size_t>(
+                    IPMIGetSensorEventEnableThresholds::lowerCriticalGoingLow));
+            }
+        }
+    }
+
+    return ipmi::responseSuccess(sensorEventStatus, assertions, deassertions);
+}
+
+// Construct a type 1 SDR for threshold sensor.
+void constructSensorSdrHeaderKey(uint16_t sensorNum, uint16_t recordID,
+                                 get_sdr::SensorDataFullRecord& record)
+{
+    get_sdr::header::set_record_id(
+        recordID, reinterpret_cast<get_sdr::SensorDataRecordHeader*>(&record));
+
+    uint8_t sensornumber = static_cast<uint8_t>(sensorNum);
+    uint8_t lun = static_cast<uint8_t>(sensorNum >> 8);
+
+    record.header.sdr_version = ipmiSdrVersion;
+    record.header.record_type = get_sdr::SENSOR_DATA_FULL_RECORD;
+    record.header.record_length = sizeof(get_sdr::SensorDataFullRecord) -
+                                  sizeof(get_sdr::SensorDataRecordHeader);
+    record.key.owner_id = bmcI2CAddr;
+    record.key.owner_lun = lun;
+    record.key.sensor_number = sensornumber;
+}
+bool constructSensorSdr(
+    ipmi::Context::ptr ctx,
+    const std::unordered_set<std::string>& ipmiDecoratorPaths,
+    uint16_t sensorNum, uint16_t recordID, const std::string& service,
+    const std::string& path, get_sdr::SensorDataFullRecord& record)
+{
+    constructSensorSdrHeaderKey(sensorNum, recordID, record);
+
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, service, path, sensorMap, sensorMapSdrUpdatePeriod))
+    {
+        lg2::error("Failed to update sensor map for threshold sensor, "
+                   "service: {SERVICE}, path: {PATH}",
+                   "SERVICE", service, "PATH", path);
+        return false;
+    }
+
+    record.body.sensor_capabilities = 0x68; // auto rearm - todo hysteresis
+    record.body.sensor_type = getSensorTypeFromPath(path);
+    std::string type = getSensorTypeStringFromPath(path);
+    auto typeCstr = type.c_str();
+    auto findUnits = sensorUnits.find(typeCstr);
+    if (findUnits != sensorUnits.end())
+    {
+        record.body.sensor_units_2_base =
+            static_cast<uint8_t>(findUnits->second);
+    } // else default 0x0 unspecified
+
+    record.body.event_reading_type = getSensorEventTypeFromPath(path);
+
+    auto sensorObject = sensorMap.find(sensor::sensorInterface);
+    if (sensorObject == sensorMap.end())
+    {
+        lg2::error("constructSensorSdr: sensorObject error");
+        return false;
+    }
+
+    uint8_t entityId = 0;
+    uint8_t entityInstance = 0x01;
+
+    // follow the association chain to get the parent board's entityid and
+    // entityInstance
+    updateIpmiFromAssociation(path, ipmiDecoratorPaths, sensorMap, entityId,
+                              entityInstance);
+
+    record.body.entity_id = entityId;
+    record.body.entity_instance = entityInstance;
+
+    double max = 0;
+    double min = 0;
+    getSensorMaxMin(sensorMap, max, min);
+
+    int16_t mValue = 0;
+    int8_t rExp = 0;
+    int16_t bValue = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
+    {
+        lg2::error("constructSensorSdr: getSensorAttributes error");
+        return false;
+    }
+
+    // The record.body is a struct SensorDataFullRecordBody
+    // from sensorhandler.hpp in phosphor-ipmi-host.
+    // The meaning of these bits appears to come from
+    // table 43.1 of the IPMI spec.
+    // The above 5 sensor attributes are stuffed in as follows:
+    // Byte 21 = AA000000 = analog interpretation, 10 signed, 00 unsigned
+    // Byte 22-24 are for other purposes
+    // Byte 25 = MMMMMMMM = LSB of M
+    // Byte 26 = MMTTTTTT = MSB of M (signed), and Tolerance
+    // Byte 27 = BBBBBBBB = LSB of B
+    // Byte 28 = BBAAAAAA = MSB of B (signed), and LSB of Accuracy
+    // Byte 29 = AAAAEE00 = MSB of Accuracy, exponent of Accuracy
+    // Byte 30 = RRRRBBBB = rExp (signed), bExp (signed)
+
+    // apply M, B, and exponents, M and B are 10 bit values, exponents are 4
+    record.body.m_lsb = mValue & 0xFF;
+
+    uint8_t mBitSign = (mValue < 0) ? 1 : 0;
+    uint8_t mBitNine = (mValue & 0x0100) >> 8;
+
+    // move the smallest bit of the MSB into place (bit 9)
+    // the MSbs are bits 7:8 in m_msb_and_tolerance
+    record.body.m_msb_and_tolerance = (mBitSign << 7) | (mBitNine << 6);
+
+    record.body.b_lsb = bValue & 0xFF;
+
+    uint8_t bBitSign = (bValue < 0) ? 1 : 0;
+    uint8_t bBitNine = (bValue & 0x0100) >> 8;
+
+    // move the smallest bit of the MSB into place (bit 9)
+    // the MSbs are bits 7:8 in b_msb_and_accuracy_lsb
+    record.body.b_msb_and_accuracy_lsb = (bBitSign << 7) | (bBitNine << 6);
+
+    uint8_t rExpSign = (rExp < 0) ? 1 : 0;
+    uint8_t rExpBits = rExp & 0x07;
+
+    uint8_t bExpSign = (bExp < 0) ? 1 : 0;
+    uint8_t bExpBits = bExp & 0x07;
+
+    // move rExp and bExp into place
+    record.body.r_b_exponents =
+        (rExpSign << 7) | (rExpBits << 4) | (bExpSign << 3) | bExpBits;
+
+    // Set the analog reading byte interpretation accordingly
+    record.body.sensor_units_1 = (bSigned ? 1 : 0) << 7;
+
+    // TODO(): Perhaps care about Tolerance, Accuracy, and so on
+    // These seem redundant, but derivable from the above 5 attributes
+    // Original comment said "todo fill out rest of units"
+
+    // populate sensor name from path
+    auto name = sensor::parseSdrIdFromPath(path);
+    get_sdr::body::set_id_strlen(name.size(), &record.body);
+    get_sdr::body::set_id_type(3, &record.body); // "8-bit ASCII + Latin 1"
+    std::memcpy(record.body.id_string, name.c_str(),
+                std::min(name.length() + 1, sizeof(record.body.id_string)));
+
+    // Remember the sensor name, as determined for this sensor number
+    details::sdrStatsTable.updateName(sensorNum, name);
+
+    bool sensorSettable = false;
+    auto mutability =
+        sensorMap.find("xyz.openbmc_project.Sensor.ValueMutability");
+    if (mutability != sensorMap.end())
+    {
+        sensorSettable =
+            mappedVariant<bool>(mutability->second, "Mutable", false);
+    }
+    get_sdr::body::init_settable_state(sensorSettable, &record.body);
+
+    // Grant write permission to sensors deemed externally settable
+    details::sdrWriteTable.setWritePermission(sensorNum, sensorSettable);
+
+    IPMIThresholds thresholdData;
+    try
+    {
+        thresholdData = getIPMIThresholds(sensorMap);
+    }
+    catch (const std::exception&)
+    {
+        lg2::error("constructSensorSdr: getIPMIThresholds error");
+        return false;
+    }
+
+    if (thresholdData.criticalHigh)
+    {
+        record.body.upper_critical_threshold = *thresholdData.criticalHigh;
+        record.body.supported_deassertions[1] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::criticalThreshold);
+        record.body.supported_deassertions[1] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::upperCriticalGoingHigh);
+        record.body.supported_assertions[1] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::upperCriticalGoingHigh);
+        record.body.discrete_reading_setting_mask[0] |=
+            static_cast<uint8_t>(IPMISensorReadingByte3::upperCritical);
+    }
+    if (thresholdData.warningHigh)
+    {
+        record.body.upper_noncritical_threshold = *thresholdData.warningHigh;
+        record.body.supported_deassertions[1] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::nonCriticalThreshold);
+        record.body.supported_deassertions[0] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh);
+        record.body.supported_assertions[0] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh);
+        record.body.discrete_reading_setting_mask[0] |=
+            static_cast<uint8_t>(IPMISensorReadingByte3::upperNonCritical);
+    }
+    if (thresholdData.criticalLow)
+    {
+        record.body.lower_critical_threshold = *thresholdData.criticalLow;
+        record.body.supported_assertions[1] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::criticalThreshold);
+        record.body.supported_deassertions[0] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::lowerCriticalGoingLow);
+        record.body.supported_assertions[0] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::lowerCriticalGoingLow);
+        record.body.discrete_reading_setting_mask[0] |=
+            static_cast<uint8_t>(IPMISensorReadingByte3::lowerCritical);
+    }
+    if (thresholdData.warningLow)
+    {
+        record.body.lower_noncritical_threshold = *thresholdData.warningLow;
+        record.body.supported_assertions[1] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::nonCriticalThreshold);
+        record.body.supported_deassertions[0] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::lowerNonCriticalGoingLow);
+        record.body.supported_assertions[0] |= static_cast<uint8_t>(
+            IPMISensorEventEnableThresholds::lowerNonCriticalGoingLow);
+        record.body.discrete_reading_setting_mask[0] |=
+            static_cast<uint8_t>(IPMISensorReadingByte3::lowerNonCritical);
+    }
+
+    // everything that is readable is setable
+    record.body.discrete_reading_setting_mask[1] =
+        record.body.discrete_reading_setting_mask[0];
+    return true;
+}
+
+#ifdef FEATURE_HYBRID_SENSORS
+// Construct a type 1 SDR for discrete Sensor typed sensor.
+void constructStaticSensorSdr(ipmi::Context::ptr, uint16_t sensorNum,
+                              uint16_t recordID,
+                              ipmi::sensor::IdInfoMap::const_iterator sensor,
+                              get_sdr::SensorDataFullRecord& record)
+{
+    constructSensorSdrHeaderKey(sensorNum, recordID, record);
+
+    record.body.entity_id = sensor->second.entityType;
+    record.body.sensor_type = sensor->second.sensorType;
+    record.body.event_reading_type = sensor->second.sensorReadingType;
+    record.body.entity_instance = sensor->second.instance;
+    if (ipmi::sensor::Mutability::Write ==
+        (sensor->second.mutability & ipmi::sensor::Mutability::Write))
+    {
+        get_sdr::body::init_settable_state(true, &(record.body));
+    }
+
+    auto id_string = sensor->second.sensorName;
+
+    if (id_string.empty())
+    {
+        id_string = sensor->second.sensorNameFunc(sensor->second);
+    }
+
+    if (id_string.length() > FULL_RECORD_ID_STR_MAX_LENGTH)
+    {
+        get_sdr::body::set_id_strlen(FULL_RECORD_ID_STR_MAX_LENGTH,
+                                     &(record.body));
+    }
+    else
+    {
+        get_sdr::body::set_id_strlen(id_string.length(), &(record.body));
+    }
+    get_sdr::body::set_id_type(3, &record.body); // "8-bit ASCII + Latin 1"
+    std::strncpy(record.body.id_string, id_string.c_str(),
+                 get_sdr::body::get_id_strlen(&(record.body)));
+}
+#endif
+
+// Construct type 3 SDR header and key (for VR and other discrete sensors)
+void constructEventSdrHeaderKey(uint16_t sensorNum, uint16_t recordID,
+                                get_sdr::SensorDataEventRecord& record)
+{
+    uint8_t sensornumber = static_cast<uint8_t>(sensorNum);
+    uint8_t lun = static_cast<uint8_t>(sensorNum >> 8);
+
+    get_sdr::header::set_record_id(
+        recordID, reinterpret_cast<get_sdr::SensorDataRecordHeader*>(&record));
+
+    record.header.sdr_version = ipmiSdrVersion;
+    record.header.record_type = get_sdr::SENSOR_DATA_EVENT_RECORD;
+    record.header.record_length = sizeof(get_sdr::SensorDataEventRecord) -
+                                  sizeof(get_sdr::SensorDataRecordHeader);
+    record.key.owner_id = bmcI2CAddr;
+    record.key.owner_lun = lun;
+    record.key.sensor_number = sensornumber;
+
+    record.body.entity_id = 0x00;
+    record.body.entity_instance = 0x01;
+}
+
+// Construct a type 3 SDR for VR typed sensor(daemon).
+bool constructVrSdr(ipmi::Context::ptr ctx,
+                    const std::unordered_set<std::string>& ipmiDecoratorPaths,
+                    uint16_t sensorNum, uint16_t recordID,
+                    const std::string& service, const std::string& path,
+                    get_sdr::SensorDataEventRecord& record)
+{
+    constructEventSdrHeaderKey(sensorNum, recordID, record);
+
+    DbusInterfaceMap sensorMap;
+    if (!getSensorMap(ctx, service, path, sensorMap, sensorMapSdrUpdatePeriod))
+    {
+        lg2::error("Failed to update sensor map for VR sensor, "
+                   "service: {SERVICE}, path: {PATH}",
+                   "SERVICE", service, "PATH", path);
+        return false;
+    }
+    // follow the association chain to get the parent board's entityid and
+    // entityInstance
+    updateIpmiFromAssociation(path, ipmiDecoratorPaths, sensorMap,
+                              record.body.entity_id,
+                              record.body.entity_instance);
+
+    // Sensor type is hardcoded as a module/board type instead of parsing from
+    // sensor path. This is because VR control is allocated in an independent
+    // path(/xyz/openbmc_project/vr/profile/...) which is not categorized by
+    // types.
+    static constexpr const uint8_t module_board_type = 0x15;
+    record.body.sensor_type = module_board_type;
+    record.body.event_reading_type = 0x00;
+
+    record.body.sensor_record_sharing_1 = 0x00;
+    record.body.sensor_record_sharing_2 = 0x00;
+
+    // populate sensor name from path
+    auto name = sensor::parseSdrIdFromPath(path);
+    int nameSize = std::min(name.size(), sizeof(record.body.id_string));
+    get_sdr::body::set_id_strlen(nameSize, &record.body);
+    get_sdr::body::set_id_type(3, &record.body); // "8-bit ASCII + Latin 1"
+    std::memset(record.body.id_string, 0x00, sizeof(record.body.id_string));
+    std::memcpy(record.body.id_string, name.c_str(), nameSize);
+
+    // Remember the sensor name, as determined for this sensor number
+    details::sdrStatsTable.updateName(sensorNum, name);
+
+    return true;
+}
+
+uint16_t getNumberOfSensors()
+{
+    return std::min(getSensorTree().size(), maxIPMISensors);
+}
+
+static int getSensorDataRecord(
+    ipmi::Context::ptr ctx,
+    const std::unordered_set<std::string>& ipmiDecoratorPaths,
+    std::vector<uint8_t>& recordData, uint16_t recordID,
+    uint8_t readBytes = std::numeric_limits<uint8_t>::max())
+{
+    recordData.clear();
+    size_t lastRecord = ipmi::getNumberOfSensors() +
+                        ipmi::sensor::getOtherSensorsCount(ctx) - 1;
+    uint16_t nextRecord(recordID + 1);
+
+    if (recordID == lastRecordIndex)
+    {
+        recordID = lastRecord;
+    }
+    if (recordID == lastRecord)
+    {
+        nextRecord = lastRecordIndex;
+    }
+    if (recordID > lastRecord)
+    {
+        lg2::error("getSensorDataRecord: recordID > lastRecord error");
+        return GENERAL_ERROR;
+    }
+    if (recordID >= ipmi::getNumberOfSensors())
+    {
+        if (auto err = ipmi::sensor::getOtherSensorsDataRecord(ctx, recordID,
+                                                               recordData);
+            err < 0)
+        {
+            return lastRecordIndex;
+        }
+        return nextRecord;
+    }
+
+    // Perform a incremental scan of the SDR Record ID's and translate the
+    // first 765 SDR records (i.e. maxIPMISensors) into IPMI Sensor
+    // Numbers. The IPMI sensor numbers are not linear, and have a reserved
+    // gap at 0xff. This code creates 254 sensors per LUN, excepting LUN 2
+    // which has special meaning.
+    std::string connection;
+    std::string path;
+    std::vector<std::string> interfaces;
+    uint16_t sensNumFromRecID{recordID};
+    if ((recordID > lun0MaxSensorNum) && (recordID < lun1MaxSensorNum))
+    {
+        // LUN 0 has one reserved sensor number. Compensate here by adding one
+        // to the record ID
+        sensNumFromRecID = recordID + 1;
+        ctx->lun = lun1;
+    }
+    else if ((recordID >= lun1MaxSensorNum) && (recordID < maxIPMISensors))
+    {
+        // LUN 0, 1 have a reserved sensor number. Compensate here by adding 2
+        // to the record ID. Skip all 256 sensors in LUN 2, as it has special
+        // rules governing its use.
+        sensNumFromRecID = recordID + (maxSensorsPerLUN + 1) + 2;
+        ctx->lun = lun3;
+    }
+
+    auto status =
+        getSensorConnection(ctx, static_cast<uint8_t>(sensNumFromRecID),
+                            connection, path, &interfaces);
+    if (status)
+    {
+        lg2::error("getSensorDataRecord: getSensorConnection error");
+        return GENERAL_ERROR;
+    }
+    uint16_t sensorNum = getSensorNumberFromPath(path);
+    // Return an error on LUN 2 assingments, and any sensor number beyond the
+    // range of LUN 3
+    if (((sensorNum > lun1MaxSensorNum) && (sensorNum <= maxIPMISensors)) ||
+        (sensorNum > lun3MaxSensorNum))
+    {
+        lg2::error("getSensorDataRecord: invalidSensorNumber");
+        return GENERAL_ERROR;
+    }
+    uint8_t sensornumber = static_cast<uint8_t>(sensorNum);
+    uint8_t lun = static_cast<uint8_t>(sensorNum >> 8);
+
+    if ((sensornumber != static_cast<uint8_t>(sensNumFromRecID)) &&
+        (lun != ctx->lun))
+    {
+        lg2::error("getSensorDataRecord: sensor record mismatch");
+        return GENERAL_ERROR;
+    }
+
+    // Construct full record (SDR type 1) for the threshold sensors
+    if (std::find(interfaces.begin(), interfaces.end(),
+                  sensor::sensorInterface) != interfaces.end())
+    {
+        get_sdr::SensorDataFullRecord record = {};
+
+        // If the request doesn't read SDR body, construct only header and key
+        // part to avoid additional DBus transaction.
+        if (readBytes <= sizeof(record.header) + sizeof(record.key))
+        {
+            constructSensorSdrHeaderKey(sensorNum, recordID, record);
+        }
+        else if (!constructSensorSdr(ctx, ipmiDecoratorPaths, sensorNum,
+                                     recordID, connection, path, record))
+        {
+            return GENERAL_ERROR;
+        }
+
+        recordData.insert(recordData.end(), reinterpret_cast<uint8_t*>(&record),
+                          reinterpret_cast<uint8_t*>(&record) + sizeof(record));
+
+        return nextRecord;
+    }
+
+#ifdef FEATURE_HYBRID_SENSORS
+    if (auto sensor = findStaticSensor(path);
+        sensor != ipmi::sensor::sensors.end() &&
+        getSensorEventTypeFromPath(path) !=
+            static_cast<uint8_t>(SensorEventTypeCodes::threshold))
+    {
+        get_sdr::SensorDataFullRecord record = {};
+
+        // If the request doesn't read SDR body, construct only header and key
+        // part to avoid additional DBus transaction.
+        if (readBytes <= sizeof(record.header) + sizeof(record.key))
+        {
+            constructSensorSdrHeaderKey(sensorNum, recordID, record);
+        }
+        else
+        {
+            constructStaticSensorSdr(ctx, sensorNum, recordID, sensor, record);
+        }
+
+        recordData.insert(recordData.end(), reinterpret_cast<uint8_t*>(&record),
+                          reinterpret_cast<uint8_t*>(&record) + sizeof(record));
+
+        return nextRecord;
+    }
+#endif
+
+    // Contruct SDR type 3 record for VR sensor (daemon)
+    if (std::find(interfaces.begin(), interfaces.end(), sensor::vrInterface) !=
+        interfaces.end())
+    {
+        get_sdr::SensorDataEventRecord record = {};
+
+        // If the request doesn't read SDR body, construct only header and key
+        // part to avoid additional DBus transaction.
+        if (readBytes <= sizeof(record.header) + sizeof(record.key))
+        {
+            constructEventSdrHeaderKey(sensorNum, recordID, record);
+        }
+        else if (!constructVrSdr(ctx, ipmiDecoratorPaths, sensorNum, recordID,
+                                 connection, path, record))
+        {
+            return GENERAL_ERROR;
+        }
+        recordData.insert(recordData.end(), reinterpret_cast<uint8_t*>(&record),
+                          reinterpret_cast<uint8_t*>(&record) + sizeof(record));
+    }
+
+    return nextRecord;
+}
+
+/** @brief implements the get SDR Info command
+ *  @param operation : 0 or not supplied returns sensor count
+ *                     1 return SDR count
+ *
+ *  @returns IPMI completion code plus response data
+ *   - sdrCount - sensor/SDR count
+ *   - lunsAndDynamicPopulation - static/Dynamic sensor population flag
+ */
+static ipmi::RspType<uint8_t, // respcount
+                     uint8_t, // dynamic population flags
+                     uint32_t // last time a sensor was added
+                     >
+    ipmiSensorGetDeviceSdrInfo(ipmi::Context::ptr ctx,
+                               std::optional<uint8_t> operation)
+{
+    auto& sensorTree{getSensorTree()};
+    uint8_t sdrCount{};
+    // Sensors are dynamically allocated
+    uint8_t lunsAndDynamicPopulation{0x80};
+    constexpr uint8_t getSdrCount{1};
+    constexpr uint8_t getSensorCount{0};
+
+    if (!getSensorSubtree(sensorTree) || sensorTree.empty())
+    {
+        return ipmi::responseResponseError();
+    }
+    uint16_t numSensors{ipmi::getNumberOfSensors()};
+    if (operation.value_or(0) == getSdrCount)
+    {
+        sdrCount = numSensors + ipmi::sensor::getOtherSensorsCount(ctx) - 1;
+    }
+    else if (operation.value_or(0) == getSensorCount)
+    {
+        // Return the number of sensors attached to the LUN
+        if ((ctx->lun == lun0) && (numSensors > 0))
+        {
+            sdrCount =
+                (numSensors > maxSensorsPerLUN) ? maxSensorsPerLUN : numSensors;
+        }
+        else if ((ctx->lun == lun1) && (numSensors > maxSensorsPerLUN))
+        {
+            sdrCount = (numSensors > (2 * maxSensorsPerLUN))
+                           ? maxSensorsPerLUN
+                           : (numSensors - maxSensorsPerLUN) & maxSensorsPerLUN;
+        }
+        else if (ctx->lun == lun3)
+        {
+            if (numSensors <= maxIPMISensors)
+            {
+                sdrCount = (numSensors - (2 * maxSensorsPerLUN)) &
+                           maxSensorsPerLUN;
+            }
+            else
+            {
+                throw std::out_of_range(
+                    "Maximum number of IPMI sensors exceeded.");
+            }
+        }
+    }
+    else
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // Flag which LUNs have sensors associated
+    if (numSensors > 0)
+    {
+        lunsAndDynamicPopulation |= 1;
+    }
+    if (numSensors > maxSensorsPerLUN)
+    {
+        lunsAndDynamicPopulation |= 2;
+    }
+    if (numSensors >= (maxSensorsPerLUN * 2))
+    {
+        lunsAndDynamicPopulation |= 8;
+    }
+    if (numSensors > maxIPMISensors)
+    {
+        throw std::out_of_range("Maximum number of IPMI sensors exceeded.");
+    }
+
+    return ipmi::responseSuccess(sdrCount, lunsAndDynamicPopulation,
+                                 sdrLastAdd);
+}
+
+/* end sensor commands */
+
+/* storage commands */
+
+ipmi::RspType<uint8_t,  // sdr version
+              uint16_t, // record count
+              uint16_t, // free space
+              uint32_t, // most recent addition
+              uint32_t, // most recent erase
+              uint8_t   // operationSupport
+              >
+    ipmiStorageGetSDRRepositoryInfo(ipmi::Context::ptr ctx)
+{
+    constexpr const uint16_t unspecifiedFreeSpace = 0xFFFF;
+    uint16_t recordCount =
+        ipmi::getNumberOfSensors() + ipmi::sensor::getOtherSensorsCount(ctx);
+
+    uint8_t operationSupport = static_cast<uint8_t>(
+        SdrRepositoryInfoOps::overflow); // write not supported
+
+    operationSupport |=
+        static_cast<uint8_t>(SdrRepositoryInfoOps::allocCommandSupported);
+    operationSupport |= static_cast<uint8_t>(
+        SdrRepositoryInfoOps::reserveSDRRepositoryCommandSupported);
+    return ipmi::responseSuccess(ipmiSdrVersion, recordCount,
+                                 unspecifiedFreeSpace, sdrLastAdd,
+                                 sdrLastRemove, operationSupport);
+}
+
+/** @brief implements the get SDR allocation info command
+ *
+ *  @returns IPMI completion code plus response data
+ *   - allocUnits    - Number of possible allocation units
+ *   - allocUnitSize - Allocation unit size in bytes.
+ *   - allocUnitFree - Number of free allocation units
+ *   - allocUnitLargestFree - Largest free block in allocation units
+ *   - maxRecordSize    - Maximum record size in allocation units.
+ */
+ipmi::RspType<uint16_t, // allocUnits
+              uint16_t, // allocUnitSize
+              uint16_t, // allocUnitFree
+              uint16_t, // allocUnitLargestFree
+              uint8_t   // maxRecordSize
+              >
+    ipmiStorageGetSDRAllocationInfo()
+{
+    // 0000h unspecified number of alloc units
+    constexpr uint16_t allocUnits = 0;
+
+    constexpr uint16_t allocUnitFree = 0;
+    constexpr uint16_t allocUnitLargestFree = 0;
+    // only allow one block at a time
+    constexpr uint8_t maxRecordSize = 1;
+
+    return ipmi::responseSuccess(allocUnits, maxSDRTotalSize, allocUnitFree,
+                                 allocUnitLargestFree, maxRecordSize);
+}
+
+/** @brief implements the reserve SDR command
+ *  @returns IPMI completion code plus response data
+ *   - sdrReservationID
+ */
+ipmi::RspType<uint16_t> ipmiStorageReserveSDR()
+{
+    sdrReservationID++;
+    if (sdrReservationID == 0)
+    {
+        sdrReservationID++;
+    }
+
+    return ipmi::responseSuccess(sdrReservationID);
+}
+
+ipmi::RspType<uint16_t,            // next record ID
+              std::vector<uint8_t> // payload
+              >
+    ipmiStorageGetSDR(ipmi::Context::ptr ctx, uint16_t reservationID,
+                      uint16_t recordID, uint8_t offset, uint8_t bytesToRead)
+{
+    // reservation required for partial reads with non zero offset into
+    // record
+    if ((sdrReservationID == 0 || reservationID != sdrReservationID) && offset)
+    {
+        lg2::error("ipmiStorageGetSDR: responseInvalidReservationId");
+        return ipmi::responseInvalidReservationId();
+    }
+
+    auto& sensorTree = getSensorTree();
+    if (!getSensorSubtree(sensorTree) && sensorTree.empty())
+    {
+        lg2::error("ipmiStorageGetSDR: getSensorSubtree error");
+        return ipmi::responseResponseError();
+    }
+
+    auto& ipmiDecoratorPaths = getIpmiDecoratorPaths(ctx);
+
+    std::vector<uint8_t> record;
+    int nextRecordId = getSensorDataRecord(
+        ctx, ipmiDecoratorPaths.value_or(std::unordered_set<std::string>()),
+        record, recordID, offset + bytesToRead);
+
+    if (nextRecordId < 0)
+    {
+        lg2::error("ipmiStorageGetSDR: fail to get SDR");
+        return ipmi::responseInvalidFieldRequest();
+    }
+    get_sdr::SensorDataRecordHeader* hdr =
+        reinterpret_cast<get_sdr::SensorDataRecordHeader*>(record.data());
+    if (!hdr)
+    {
+        lg2::error("ipmiStorageGetSDR: record header is null");
+        return ipmi::responseSuccess(nextRecordId, record);
+    }
+
+    size_t sdrLength =
+        sizeof(get_sdr::SensorDataRecordHeader) + hdr->record_length;
+    if (offset >= sdrLength)
+    {
+        lg2::error("ipmiStorageGetSDR: offset is outside the record");
+        return ipmi::responseParmOutOfRange();
+    }
+    if (sdrLength < (offset + bytesToRead))
+    {
+        bytesToRead = sdrLength - offset;
+    }
+
+    uint8_t* respStart = reinterpret_cast<uint8_t*>(hdr) + offset;
+    if (!respStart)
+    {
+        lg2::error("ipmiStorageGetSDR: record is null");
+        return ipmi::responseSuccess(nextRecordId, record);
+    }
+
+    std::vector<uint8_t> recordData(respStart, respStart + bytesToRead);
+
+    return ipmi::responseSuccess(nextRecordId, recordData);
+}
+namespace dcmi
+{
+
+std::tuple<uint8_t,                // Total of instance sensors
+           std::vector<sensorInfo> // The list of sensors
+           >
+    getSensorsByEntityId(ipmi::Context::ptr ctx, uint8_t entityId,
+                         uint8_t entityInstance, uint8_t instanceStart)
+{
+    std::vector<sensorInfo> sensorList;
+    uint8_t totalInstSensor = 0;
+    auto match = ipmi::dcmi::validEntityId.find(entityId);
+
+    if (match == ipmi::dcmi::validEntityId.end())
+    {
+        return std::make_tuple(totalInstSensor, sensorList);
+    }
+
+    auto& sensorTree = getSensorTree();
+    if (!getSensorSubtree(sensorTree) && sensorTree.empty())
+    {
+        return std::make_tuple(totalInstSensor, sensorList);
+    }
+
+    auto& ipmiDecoratorPaths = getIpmiDecoratorPaths(ctx);
+
+    size_t invalidSensorNumberErrCount = 0;
+    for (const auto& sensor : sensorTree)
+    {
+        const std::string& sensorObjPath = sensor.first;
+        const auto& sensorTypeValue = getSensorTypeFromPath(sensorObjPath);
+
+        /*
+         * In the DCMI specification, it only supports the sensor type is 0x01
+         * (temperature type) for both Get Sensor Info and Get Temperature
+         * Readings commands.
+         */
+        if (sensorTypeValue != ipmi::dcmi::temperatureSensorType)
+        {
+            continue;
+        }
+
+        const auto& connection = sensor.second.begin()->first;
+        DbusInterfaceMap sensorMap;
+
+        if (!getSensorMap(ctx, connection, sensorObjPath, sensorMap,
+                          sensorMapSdrUpdatePeriod))
+        {
+            lg2::error("Failed to update sensor map for threshold sensor, "
+                       "service: {SERVICE}, path: {PATH}",
+                       "SERVICE", connection, "PATH", sensorObjPath);
+            continue;
+        }
+
+        uint8_t entityIdValue = 0;
+        uint8_t entityInstanceValue = 0;
+
+        /*
+         * Get the Entity ID, Entity Instance information which are configured
+         * in the Entity-Manger.
+         */
+        updateIpmiFromAssociation(
+            sensorObjPath,
+            ipmiDecoratorPaths.value_or(std::unordered_set<std::string>()),
+            sensorMap, entityIdValue, entityInstanceValue);
+
+        if (entityIdValue == match->first || entityIdValue == match->second)
+        {
+            totalInstSensor++;
+
+            /*
+             * When Entity Instance parameter is not 0, we only get the first
+             * sensor whose Entity Instance number is equal input Entity
+             * Instance parameter.
+             */
+            if (entityInstance)
+            {
+                if (!sensorList.empty())
+                {
+                    continue;
+                }
+
+                if (entityInstanceValue == entityInstance)
+                {
+                    auto recordId = getSensorNumberFromPath(sensorObjPath);
+                    if (recordId == invalidSensorNumber)
+                    {
+                        ++invalidSensorNumberErrCount;
+                        continue;
+                    }
+                    sensorList.emplace_back(sensorObjPath, sensorTypeValue,
+                                            recordId, entityIdValue,
+                                            entityInstanceValue);
+                }
+            }
+            else if (entityInstanceValue >= instanceStart)
+            {
+                auto recordId = getSensorNumberFromPath(sensorObjPath);
+                if (recordId == invalidSensorNumber)
+                {
+                    ++invalidSensorNumberErrCount;
+                    continue;
+                }
+                sensorList.emplace_back(sensorObjPath, sensorTypeValue,
+                                        recordId, entityIdValue,
+                                        entityInstanceValue);
+            }
+        }
+    }
+    if (invalidSensorNumberErrCount != 0)
+    {
+        lg2::error("getSensorNumberFromPath returned invalidSensorNumber "
+                   "{ERR_COUNT} times",
+                   "ERR_COUNT", invalidSensorNumberErrCount);
+    }
+
+    auto cmpFunc = [](sensorInfo first, sensorInfo second) {
+        return first.entityInstance <= second.entityInstance;
+    };
+
+    sort(sensorList.begin(), sensorList.end(), cmpFunc);
+
+    return std::make_tuple(totalInstSensor, sensorList);
+}
+
+std::tuple<bool,    // Reading result
+           uint7_t, // Temp value
+           bool>    // Sign bit
+    readTemp(ipmi::Context::ptr ctx, const std::string& objectPath)
+{
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, sensor::sensorInterface, objectPath, service);
+    if (ec.value())
+    {
+        return std::make_tuple(false, 0, false);
+    }
+
+    ipmi::PropertyMap properties{};
+    ec = ipmi::getAllDbusProperties(ctx, service, objectPath,
+                                    sensor::sensorInterface, properties);
+    if (ec.value())
+    {
+        return std::make_tuple(false, 0, false);
+    }
+
+    auto scaleIt = properties.find("Scale");
+    double scaleVal = 0.0;
+    if (scaleIt != properties.end())
+    {
+        scaleVal = std::visit(ipmi::VariantToDoubleVisitor(), scaleIt->second);
+    }
+
+    auto tempValIt = properties.find("Value");
+    double tempVal = 0.0;
+    if (tempValIt == properties.end())
+    {
+        return std::make_tuple(false, 0, false);
+    }
+
+    const double maxTemp = 127;
+    double absTempVal = 0.0;
+    bool signBit = false;
+
+    tempVal = std::visit(ipmi::VariantToDoubleVisitor(), tempValIt->second);
+    tempVal = std::pow(10, scaleVal) * tempVal;
+    absTempVal = std::abs(tempVal);
+    absTempVal = std::min(absTempVal, maxTemp);
+    signBit = (tempVal < 0) ? true : false;
+
+    return std::make_tuple(true, static_cast<uint7_t>(absTempVal), signBit);
+}
+
+ipmi::RspType<uint8_t,              // No of instances for requested id
+              uint8_t,              // No of record ids in the response
+              std::vector<uint16_t> // SDR Record ID corresponding to the Entity
+                                    // IDs
+              >
+    getSensorInfo(ipmi::Context::ptr ctx, uint8_t sensorType, uint8_t entityId,
+                  uint8_t entityInstance, uint8_t instanceStart)
+{
+    auto match = ipmi::dcmi::validEntityId.find(entityId);
+    if (match == ipmi::dcmi::validEntityId.end())
+    {
+        lg2::error("Unknown Entity ID: {ENTITY_ID}", "ENTITY_ID", entityId);
+
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (sensorType != ipmi::dcmi::temperatureSensorType)
+    {
+        lg2::error("Invalid sensor type: {SENSOR_TYPE}", "SENSOR_TYPE",
+                   sensorType);
+
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    std::vector<uint16_t> sensorRec{};
+    const auto& [totalSensorInst, sensorList] =
+        getSensorsByEntityId(ctx, entityId, entityInstance, instanceStart);
+
+    if (sensorList.empty())
+    {
+        return ipmi::responseSuccess(totalSensorInst, 0, sensorRec);
+    }
+
+    /*
+     * As DCMI specification, the maximum number of Record Ids of response data
+     * is 1 if Entity Instance paramter is not 0. Else the maximum number of
+     * Record Ids of response data is 8. Therefore, not all of sensors are shown
+     * in response data.
+     */
+    uint8_t numOfRec = (entityInstance != 0) ? 1 : ipmi::dcmi::maxRecords;
+
+    for (const auto& sensor : sensorList)
+    {
+        sensorRec.emplace_back(sensor.recordId);
+        if (sensorRec.size() >= numOfRec)
+        {
+            break;
+        }
+    }
+
+    return ipmi::responseSuccess(
+        totalSensorInst, static_cast<uint8_t>(sensorRec.size()), sensorRec);
+}
+
+ipmi::RspType<uint8_t,                // No of instances for requested id
+              uint8_t,                // No of record ids in the response
+              std::vector<            // Temperature Data
+                  std::tuple<uint7_t, // Temperature value
+                             bool,    // Sign bit
+                             uint8_t  // Entity Instance of sensor
+                             >>>
+    getTempReadings(ipmi::Context::ptr ctx, uint8_t sensorType,
+                    uint8_t entityId, uint8_t entityInstance,
+                    uint8_t instanceStart)
+{
+    auto match = ipmi::dcmi::validEntityId.find(entityId);
+    if (match == ipmi::dcmi::validEntityId.end())
+    {
+        lg2::error("Unknown Entity ID: {ENTITY_ID}", "ENTITY_ID", entityId);
+
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (sensorType != ipmi::dcmi::temperatureSensorType)
+    {
+        lg2::error("Invalid sensor type: {SENSOR_TYPE}", "SENSOR_TYPE",
+                   sensorType);
+
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    std::vector<std::tuple<uint7_t, bool, uint8_t>> tempReadingVal{};
+    const auto& [totalSensorInst, sensorList] =
+        getSensorsByEntityId(ctx, entityId, entityInstance, instanceStart);
+
+    if (sensorList.empty())
+    {
+        return ipmi::responseSuccess(totalSensorInst, 0, tempReadingVal);
+    }
+
+    /*
+     * As DCMI specification, the maximum number of Record Ids of response data
+     * is 1 if Entity Instance paramter is not 0. Else the maximum number of
+     * Record Ids of response data is 8. Therefore, not all of sensors are shown
+     * in response data.
+     */
+    uint8_t numOfRec = (entityInstance != 0) ? 1 : ipmi::dcmi::maxRecords;
+
+    for (const auto& sensor : sensorList)
+    {
+        const auto& [readResult, tempVal, signBit] =
+            readTemp(ctx, sensor.objectPath);
+
+        if (readResult)
+        {
+            tempReadingVal.emplace_back(
+                std::make_tuple(tempVal, signBit, sensor.entityInstance));
+
+            if (tempReadingVal.size() >= numOfRec)
+            {
+                break;
+            }
+        }
+    }
+
+    return ipmi::responseSuccess(totalSensorInst,
+                                 static_cast<uint8_t>(tempReadingVal.size()),
+                                 tempReadingVal);
+}
+
+} // namespace dcmi
+
+/* end storage commands */
+
+void registerSensorFunctions()
+{
+    // <Platform Event>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdPlatformEvent,
+                          ipmi::Privilege::Operator, ipmiSenPlatformEvent);
+
+    // <Set Sensor Reading and Event Status>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdSetSensorReadingAndEvtSts,
+                          ipmi::Privilege::Operator, ipmiSetSensorReading);
+
+    // <Get Sensor Reading>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorReading,
+                          ipmi::Privilege::User, ipmiSenGetSensorReading);
+
+    // <Get Sensor Threshold>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorThreshold,
+                          ipmi::Privilege::User, ipmiSenGetSensorThresholds);
+
+    // <Set Sensor Threshold>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdSetSensorThreshold,
+                          ipmi::Privilege::Operator,
+                          ipmiSenSetSensorThresholds);
+
+    // <Get Sensor Event Enable>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorEventEnable,
+                          ipmi::Privilege::User, ipmiSenGetSensorEventEnable);
+
+    // <Get Sensor Event Status>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorEventStatus,
+                          ipmi::Privilege::User, ipmiSenGetSensorEventStatus);
+
+    // register all storage commands for both Sensor and Storage command
+    // versions
+
+    // <Get SDR Repository Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSdrRepositoryInfo,
+                          ipmi::Privilege::User,
+                          ipmiStorageGetSDRRepositoryInfo);
+
+    // <Get Device SDR Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetDeviceSdrInfo,
+                          ipmi::Privilege::User, ipmiSensorGetDeviceSdrInfo);
+
+    // <Get SDR Allocation Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSdrRepositoryAllocInfo,
+                          ipmi::Privilege::User,
+                          ipmiStorageGetSDRAllocationInfo);
+
+    // <Reserve SDR Repo>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdReserveDeviceSdrRepository,
+                          ipmi::Privilege::User, ipmiStorageReserveSDR);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdReserveSdrRepository,
+                          ipmi::Privilege::User, ipmiStorageReserveSDR);
+
+    // <Get Sdr>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetDeviceSdr,
+                          ipmi::Privilege::User, ipmiStorageGetSDR);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSdr, ipmi::Privilege::User,
+                          ipmiStorageGetSDR);
+    // <Get DCMI Sensor Info>
+    ipmi::registerGroupHandler(
+        ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+        ipmi::dcmi::cmdGetDcmiSensorInfo, ipmi::Privilege::Operator,
+        ipmi::dcmi::getSensorInfo);
+    // <Get Temperature Readings>
+    ipmi::registerGroupHandler(
+        ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+        ipmi::dcmi::cmdGetTemperatureReadings, ipmi::Privilege::User,
+        ipmi::dcmi::getTempReadings);
+}
+} // namespace ipmi
diff --git a/dbus-sdr/sensorutils.cpp b/dbus-sdr/sensorutils.cpp
new file mode 100644
index 0000000..8c6952b
--- /dev/null
+++ b/dbus-sdr/sensorutils.cpp
@@ -0,0 +1,324 @@
+/*
+// Copyright (c) 2017 2018 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 "dbus-sdr/sensorutils.hpp"
+
+#include <algorithm>
+#include <cmath>
+#include <iostream>
+
+namespace ipmi
+{
+
+// Helper function to avoid repeated complicated expression
+static bool baseInRange(double base)
+{
+    auto min10 = static_cast<double>(minInt10);
+    auto max10 = static_cast<double>(maxInt10);
+
+    return ((base >= min10) && (base <= max10));
+}
+
+// Helper function for internal use by getSensorAttributes()
+// Ensures floating-point "base" is within bounds,
+// and adjusts integer exponent "expShift" accordingly.
+// To minimize data loss when later truncating to integer,
+// the floating-point "base" will be as large as possible,
+// but still within the bounds (minInt10,maxInt10).
+// The bounds of "expShift" are (minInt4,maxInt4).
+// Consider this equation: n = base * (10.0 ** expShift)
+// This function will try to maximize "base",
+// adjusting "expShift" to keep the value "n" unchanged,
+// while keeping base and expShift within bounds.
+// Returns true if successful, modifies values in-place
+static bool scaleFloatExp(double& base, int8_t& expShift)
+{
+    // Comparing with zero should be OK, zero is special in floating-point
+    // If base is exactly zero, no adjustment of the exponent is necessary
+    if (base == 0.0)
+    {
+        return true;
+    }
+
+    // As long as base value is within allowed range, expand precision
+    // This will help to avoid loss when later rounding to integer
+    while (baseInRange(base))
+    {
+        if (expShift <= minInt4)
+        {
+            // Already at the minimum expShift, can not decrement it more
+            break;
+        }
+
+        // Multiply by 10, but shift decimal point to the left, no net change
+        base *= 10.0;
+        --expShift;
+    }
+
+    // As long as base value is *not* within range, shrink precision
+    // This will pull base value closer to zero, thus within range
+    while (!(baseInRange(base)))
+    {
+        if (expShift >= maxInt4)
+        {
+            // Already at the maximum expShift, can not increment it more
+            break;
+        }
+
+        // Divide by 10, but shift decimal point to the right, no net change
+        base /= 10.0;
+        ++expShift;
+    }
+
+    // If the above loop was not able to pull it back within range,
+    // the base value is beyond what expShift can represent, return false.
+    return baseInRange(base);
+}
+
+// Helper function for internal use by getSensorAttributes()
+// Ensures integer "ibase" is no larger than necessary,
+// by normalizing it so that the decimal point shift is in the exponent,
+// whenever possible.
+// This provides more consistent results,
+// as many equivalent solutions are collapsed into one consistent solution.
+// If integer "ibase" is a clean multiple of 10,
+// divide it by 10 (this is lossless), so it is closer to zero.
+// Also modify floating-point "dbase" at the same time,
+// as both integer and floating-point base share the same expShift.
+// Example: (ibase=300, expShift=2) becomes (ibase=3, expShift=4)
+// because the underlying value is the same: 200*(10**2) == 2*(10**4)
+// Always successful, modifies values in-place
+static void normalizeIntExp(int16_t& ibase, int8_t& expShift, double& dbase)
+{
+    for (;;)
+    {
+        // If zero, already normalized, ensure exponent also zero
+        if (ibase == 0)
+        {
+            expShift = 0;
+            break;
+        }
+
+        // If not cleanly divisible by 10, already normalized
+        if ((ibase % 10) != 0)
+        {
+            break;
+        }
+
+        // If exponent already at max, already normalized
+        if (expShift >= maxInt4)
+        {
+            break;
+        }
+
+        // Bring values closer to zero, correspondingly shift exponent,
+        // without changing the underlying number that this all represents,
+        // similar to what is done by scaleFloatExp().
+        // The floating-point base must be kept in sync with the integer base,
+        // as both floating-point and integer share the same exponent.
+        ibase /= 10;
+        dbase /= 10.0;
+        ++expShift;
+    }
+}
+
+// The IPMI equation:
+// y = (Mx + (B * 10^(bExp))) * 10^(rExp)
+// Section 36.3 of this document:
+// https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf
+//
+// The goal is to exactly match the math done by the ipmitool command,
+// at the other side of the interface:
+// https://github.com/ipmitool/ipmitool/blob/42a023ff0726c80e8cc7d30315b987fe568a981d/lib/ipmi_sdr.c#L360
+//
+// To use with Wolfram Alpha, make all variables single letters
+// bExp becomes E, rExp becomes R
+// https://www.wolframalpha.com/input/?i=y%3D%28%28M*x%29%2B%28B*%2810%5EE%29%29%29*%2810%5ER%29
+bool getSensorAttributes(const double max, const double min, int16_t& mValue,
+                         int8_t& rExp, int16_t& bValue, int8_t& bExp,
+                         bool& bSigned)
+{
+    if (!(std::isfinite(min)))
+    {
+        std::cerr << "getSensorAttributes: Min value is unusable\n";
+        return false;
+    }
+    if (!(std::isfinite(max)))
+    {
+        std::cerr << "getSensorAttributes: Max value is unusable\n";
+        return false;
+    }
+
+    // Because NAN has already been tested for, this comparison works
+    if (max <= min)
+    {
+        std::cerr << "getSensorAttributes: Max must be greater than min\n";
+        return false;
+    }
+
+    // Given min and max, we must solve for M, B, bExp, rExp
+    // y comes in from D-Bus (the actual sensor reading)
+    // x is calculated from y by scaleIPMIValueFromDouble() below
+    // If y is min, x should equal = 0 (or -128 if signed)
+    // If y is max, x should equal 255 (or 127 if signed)
+    double fullRange = max - min;
+    double lowestX;
+
+    rExp = 0;
+    bExp = 0;
+
+    // TODO(): The IPMI document is ambiguous, as to whether
+    // the resulting byte should be signed or unsigned,
+    // essentially leaving it up to the caller.
+    // The document just refers to it as "raw reading",
+    // or "byte of reading", without giving further details.
+    // Previous code set it signed if min was less than zero,
+    // so I'm sticking with that, until I learn otherwise.
+    if (min < 0.0)
+    {
+        // TODO(): It would be worth experimenting with the range (-127,127),
+        // instead of the range (-128,127), because this
+        // would give good symmetry around zero, and make results look better.
+        // Divide by 254 instead of 255, and change -128 to -127 elsewhere.
+        bSigned = true;
+        lowestX = -128.0;
+    }
+    else
+    {
+        bSigned = false;
+        lowestX = 0.0;
+    }
+
+    // Step 1: Set y to (max - min), set x to 255, set B to 0, solve for M
+    // This works, regardless of signed or unsigned,
+    // because total range is the same.
+    double dM = fullRange / 255.0;
+
+    // Step 2: Constrain M, and set rExp accordingly
+    if (!(scaleFloatExp(dM, rExp)))
+    {
+        std::cerr << "getSensorAttributes: Multiplier range exceeds scale (M="
+                  << dM << ", rExp=" << (int)rExp << ")\n";
+        return false;
+    }
+
+    mValue = static_cast<int16_t>(std::round(dM));
+
+    normalizeIntExp(mValue, rExp, dM);
+
+    // The multiplier can not be zero, for obvious reasons
+    if (mValue == 0)
+    {
+        std::cerr << "getSensorAttributes: Multiplier range below scale\n";
+        return false;
+    }
+
+    // Step 3: set y to min, set x to min, keep M and rExp, solve for B
+    // If negative, x will be -128 (the most negative possible byte), not 0
+
+    // Solve the IPMI equation for B, instead of y
+    // https://www.wolframalpha.com/input/?i=solve+y%3D%28%28M*x%29%2B%28B*%2810%5EE%29%29%29*%2810%5ER%29+for+B
+    // B = 10^(-rExp - bExp) (y - M 10^rExp x)
+    // TODO(): Compare with this alternative solution from SageMathCell
+    // https://sagecell.sagemath.org/?z=eJyrtC1LLNJQr1TX5KqAMCuATF8I0xfIdIIwnYDMIteKAggPxAIKJMEFkiACxfk5Zaka0ZUKtrYKGhq-CloKFZoK2goaTkCWhqGBgpaWAkilpqYmQgBklmasjoKTJgDAECTH&lang=sage&interacts=eJyLjgUAARUAuQ==
+    double dB = std::pow(10.0, ((-rExp) - bExp)) *
+                (min - ((dM * std::pow(10.0, rExp) * lowestX)));
+
+    // Step 4: Constrain B, and set bExp accordingly
+    if (!(scaleFloatExp(dB, bExp)))
+    {
+        std::cerr << "getSensorAttributes: Offset (B=" << dB << ", bExp="
+                  << (int)bExp << ") exceeds multiplier scale (M=" << dM
+                  << ", rExp=" << (int)rExp << ")\n";
+        return false;
+    }
+
+    bValue = static_cast<int16_t>(std::round(dB));
+
+    normalizeIntExp(bValue, bExp, dB);
+
+    // Unlike the multiplier, it is perfectly OK for bValue to be zero
+    return true;
+}
+
+uint8_t scaleIPMIValueFromDouble(const double value, const int16_t mValue,
+                                 const int8_t rExp, const int16_t bValue,
+                                 const int8_t bExp, const bool bSigned)
+{
+    // Avoid division by zero below
+    if (mValue == 0)
+    {
+        throw std::out_of_range("Scaling multiplier is uninitialized");
+    }
+
+    auto dM = static_cast<double>(mValue);
+    auto dB = static_cast<double>(bValue);
+
+    // Solve the IPMI equation for x, instead of y
+    // https://www.wolframalpha.com/input/?i=solve+y%3D%28%28M*x%29%2B%28B*%2810%5EE%29%29%29*%2810%5ER%29+for+x
+    // x = (10^(-rExp) (y - B 10^(rExp + bExp)))/M and M 10^rExp!=0
+    // TODO(): Compare with this alternative solution from SageMathCell
+    // https://sagecell.sagemath.org/?z=eJyrtC1LLNJQr1TX5KqAMCuATF8I0xfIdIIwnYDMIteKAggPxAIKJMEFkiACxfk5Zaka0ZUKtrYKGhq-CloKFZoK2goaTkCWhqGBgpaWAkilpqYmQgBklmasDlAlAMB8JP0=&lang=sage&interacts=eJyLjgUAARUAuQ==
+    double dX =
+        (std::pow(10.0, -rExp) * (value - (dB * std::pow(10.0, rExp + bExp)))) /
+        dM;
+
+    auto scaledValue = static_cast<int32_t>(std::round(dX));
+
+    int32_t minClamp;
+    int32_t maxClamp;
+
+    // Because of rounding and integer truncation of scaling factors,
+    // sometimes the resulting byte is slightly out of range.
+    // Still allow this, but clamp the values to range.
+    if (bSigned)
+    {
+        minClamp = std::numeric_limits<int8_t>::lowest();
+        maxClamp = std::numeric_limits<int8_t>::max();
+    }
+    else
+    {
+        minClamp = std::numeric_limits<uint8_t>::lowest();
+        maxClamp = std::numeric_limits<uint8_t>::max();
+    }
+
+    auto clampedValue = std::clamp(scaledValue, minClamp, maxClamp);
+
+    // This works for both signed and unsigned,
+    // because it is the same underlying byte storage.
+    return static_cast<uint8_t>(clampedValue);
+}
+
+uint8_t getScaledIPMIValue(const double value, const double max,
+                           const double min)
+{
+    int16_t mValue = 0;
+    int8_t rExp = 0;
+    int16_t bValue = 0;
+    int8_t bExp = 0;
+    bool bSigned = false;
+
+    bool result =
+        getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned);
+    if (!result)
+    {
+        throw std::runtime_error("Illegal sensor attributes");
+    }
+
+    return scaleIPMIValueFromDouble(value, mValue, rExp, bValue, bExp, bSigned);
+}
+
+} // namespace ipmi
diff --git a/dbus-sdr/storagecommands.cpp b/dbus-sdr/storagecommands.cpp
new file mode 100644
index 0000000..e8c4223
--- /dev/null
+++ b/dbus-sdr/storagecommands.cpp
@@ -0,0 +1,1296 @@
+/*
+// Copyright (c) 2017-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 "dbus-sdr/storagecommands.hpp"
+
+#include "dbus-sdr/sdrutils.hpp"
+#include "selutility.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/asio/detached.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/process.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <sdbusplus/timer.hpp>
+
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <stdexcept>
+#include <string_view>
+
+static constexpr bool DEBUG = false;
+
+namespace dynamic_sensors::ipmi::sel
+{
+static const std::filesystem::path selLogDir = "/var/log";
+static const std::string selLogFilename = "ipmi_sel";
+
+static int getFileTimestamp(const std::filesystem::path& file)
+{
+    struct stat st;
+
+    if (stat(file.c_str(), &st) >= 0)
+    {
+        return st.st_mtime;
+    }
+    return ::ipmi::sel::invalidTimeStamp;
+}
+
+namespace erase_time
+{
+static constexpr const char* selEraseTimestamp = "/var/lib/ipmi/sel_erase_time";
+
+int get()
+{
+    return getFileTimestamp(selEraseTimestamp);
+}
+} // namespace erase_time
+} // namespace dynamic_sensors::ipmi::sel
+
+namespace ipmi
+{
+
+namespace storage
+{
+
+constexpr static const size_t maxFruSdrNameSize = 16;
+using ObjectType =
+    boost::container::flat_map<std::string,
+                               boost::container::flat_map<std::string, Value>>;
+using ManagedObjectType =
+    boost::container::flat_map<sdbusplus::message::object_path, ObjectType>;
+using ManagedEntry = std::pair<sdbusplus::message::object_path, ObjectType>;
+
+constexpr static const char* fruDeviceServiceName =
+    "xyz.openbmc_project.FruDevice";
+constexpr static const size_t writeTimeoutSeconds = 10;
+constexpr static const char* chassisTypeRackMount = "23";
+constexpr static const char* chassisTypeMainServer = "17";
+
+static std::vector<uint8_t> fruCache;
+static constexpr uint16_t invalidBus = 0xFFFF;
+static constexpr uint8_t invalidAddr = 0xFF;
+static constexpr uint8_t typeASCIILatin8 = 0xC0;
+static uint16_t cacheBus = invalidBus;
+static uint8_t cacheAddr = invalidAddr;
+static uint8_t lastDevId = 0xFF;
+
+static uint16_t writeBus = invalidBus;
+static uint8_t writeAddr = invalidAddr;
+
+std::unique_ptr<sdbusplus::Timer> writeTimer = nullptr;
+static std::vector<sdbusplus::bus::match_t> fruMatches;
+
+ManagedObjectType frus;
+
+// we unfortunately have to build a map of hashes in case there is a
+// collision to verify our dev-id
+boost::container::flat_map<uint8_t, std::pair<uint16_t, uint8_t>> deviceHashes;
+void registerStorageFunctions() __attribute__((constructor));
+
+bool writeFru(const std::vector<uint8_t>& fru)
+{
+    if (writeBus == invalidBus && writeAddr == invalidAddr)
+    {
+        return true;
+    }
+    lastDevId = 0xFF;
+    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+    sdbusplus::message_t writeFru = dbus->new_method_call(
+        fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
+        "xyz.openbmc_project.FruDeviceManager", "WriteFru");
+    writeFru.append(writeBus, writeAddr, fru);
+    try
+    {
+        sdbusplus::message_t writeFruResp = dbus->call(writeFru);
+    }
+    catch (const sdbusplus::exception_t&)
+    {
+        // todo: log sel?
+        lg2::error("error writing fru");
+        return false;
+    }
+    writeBus = invalidBus;
+    writeAddr = invalidAddr;
+    return true;
+}
+
+void writeFruCache()
+{
+    writeFru(fruCache);
+}
+
+void createTimers()
+{
+    writeTimer = std::make_unique<sdbusplus::Timer>(writeFruCache);
+}
+
+void recalculateHashes()
+{
+    deviceHashes.clear();
+    // hash the object paths to create unique device id's. increment on
+    // collision
+    std::hash<std::string> hasher;
+    for (const auto& fru : frus)
+    {
+        auto fruIface = fru.second.find("xyz.openbmc_project.FruDevice");
+        if (fruIface == fru.second.end())
+        {
+            continue;
+        }
+
+        auto busFind = fruIface->second.find("BUS");
+        auto addrFind = fruIface->second.find("ADDRESS");
+        if (busFind == fruIface->second.end() ||
+            addrFind == fruIface->second.end())
+        {
+            lg2::info("fru device missing Bus or Address, fru: {FRU}", "FRU",
+                      fru.first.str);
+            continue;
+        }
+
+        uint16_t fruBus = std::get<uint32_t>(busFind->second);
+        uint8_t fruAddr = std::get<uint32_t>(addrFind->second);
+        auto chassisFind = fruIface->second.find("CHASSIS_TYPE");
+        std::string chassisType;
+        if (chassisFind != fruIface->second.end())
+        {
+            chassisType = std::get<std::string>(chassisFind->second);
+        }
+
+        uint8_t fruHash = 0;
+        if (chassisType.compare(chassisTypeRackMount) != 0 &&
+            chassisType.compare(chassisTypeMainServer) != 0)
+        {
+            fruHash = hasher(fru.first.str);
+            // can't be 0xFF based on spec, and 0 is reserved for baseboard
+            if (fruHash == 0 || fruHash == 0xFF)
+            {
+                fruHash = 1;
+            }
+        }
+        std::pair<uint16_t, uint8_t> newDev(fruBus, fruAddr);
+
+        bool emplacePassed = false;
+        while (!emplacePassed)
+        {
+            auto resp = deviceHashes.emplace(fruHash, newDev);
+            emplacePassed = resp.second;
+            if (!emplacePassed)
+            {
+                fruHash++;
+                // can't be 0xFF based on spec, and 0 is reserved for
+                // baseboard
+                if (fruHash == 0XFF)
+                {
+                    fruHash = 0x1;
+                }
+            }
+        }
+    }
+}
+
+void replaceCacheFru(
+    const std::shared_ptr<sdbusplus::asio::connection>& bus,
+    boost::asio::yield_context& yield,
+    [[maybe_unused]] const std::optional<std::string>& path = std::nullopt)
+{
+    boost::system::error_code ec;
+
+    frus = bus->yield_method_call<ManagedObjectType>(
+        yield, ec, fruDeviceServiceName, "/",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    if (ec)
+    {
+        lg2::error("GetMangagedObjects for replaceCacheFru failed: {ERROR}",
+                   "ERROR", ec.message());
+
+        return;
+    }
+    recalculateHashes();
+}
+
+std::pair<ipmi::Cc, std::vector<uint8_t>> getFru(ipmi::Context::ptr ctx,
+                                                 uint8_t devId)
+{
+    if (lastDevId == devId && devId != 0xFF)
+    {
+        return {ipmi::ccSuccess, fruCache};
+    }
+
+    auto deviceFind = deviceHashes.find(devId);
+    if (deviceFind == deviceHashes.end())
+    {
+        return {IPMI_CC_SENSOR_INVALID, {}};
+    }
+
+    cacheBus = deviceFind->second.first;
+    cacheAddr = deviceFind->second.second;
+
+    boost::system::error_code ec;
+    std::vector<uint8_t> fru = ipmi::callDbusMethod<std::vector<uint8_t>>(
+        ctx, ec, fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
+        "xyz.openbmc_project.FruDeviceManager", "GetRawFru", cacheBus,
+        cacheAddr);
+
+    if (ec)
+    {
+        lg2::error("Couldn't get raw fru: {ERROR}", "ERROR", ec.message());
+
+        cacheBus = invalidBus;
+        cacheAddr = invalidAddr;
+        return {ipmi::ccResponseError, {}};
+    }
+
+    fruCache.clear();
+    lastDevId = devId;
+    fruCache = fru;
+
+    return {ipmi::ccSuccess, fru};
+}
+
+void writeFruIfRunning()
+{
+    if (!writeTimer->isRunning())
+    {
+        return;
+    }
+    writeTimer->stop();
+    writeFruCache();
+}
+
+void startMatch(void)
+{
+    if (fruMatches.size())
+    {
+        return;
+    }
+
+    fruMatches.reserve(2);
+
+    auto bus = getSdBus();
+    fruMatches.emplace_back(
+        *bus,
+        "type='signal',arg0path='/xyz/openbmc_project/"
+        "FruDevice/',member='InterfacesAdded'",
+        [](sdbusplus::message_t& message) {
+            sdbusplus::message::object_path path;
+            ObjectType object;
+            try
+            {
+                message.read(path, object);
+            }
+            catch (const sdbusplus::exception_t&)
+            {
+                return;
+            }
+            auto findType = object.find("xyz.openbmc_project.FruDevice");
+            if (findType == object.end())
+            {
+                return;
+            }
+            writeFruIfRunning();
+            frus[path] = object;
+            recalculateHashes();
+            lastDevId = 0xFF;
+        });
+
+    fruMatches.emplace_back(
+        *bus,
+        "type='signal',arg0path='/xyz/openbmc_project/"
+        "FruDevice/',member='InterfacesRemoved'",
+        [](sdbusplus::message_t& message) {
+            sdbusplus::message::object_path path;
+            std::set<std::string> interfaces;
+            try
+            {
+                message.read(path, interfaces);
+            }
+            catch (const sdbusplus::exception_t&)
+            {
+                return;
+            }
+            auto findType = interfaces.find("xyz.openbmc_project.FruDevice");
+            if (findType == interfaces.end())
+            {
+                return;
+            }
+            writeFruIfRunning();
+            frus.erase(path);
+            recalculateHashes();
+            lastDevId = 0xFF;
+        });
+
+    // call once to populate
+    boost::asio::spawn(
+        *getIoContext(),
+        [](boost::asio::yield_context yield) {
+            replaceCacheFru(getSdBus(), yield);
+        },
+        boost::asio::detached);
+}
+
+/** @brief implements the read FRU data command
+ *  @param fruDeviceId        - FRU Device ID
+ *  @param fruInventoryOffset - FRU Inventory Offset to write
+ *  @param countToRead        - Count to read
+ *
+ *  @returns ipmi completion code plus response data
+ *   - countWritten  - Count written
+ */
+ipmi::RspType<uint8_t,             // Count
+              std::vector<uint8_t> // Requested data
+              >
+    ipmiStorageReadFruData(ipmi::Context::ptr ctx, uint8_t fruDeviceId,
+                           uint16_t fruInventoryOffset, uint8_t countToRead)
+{
+    if (fruDeviceId == 0xFF)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    auto [status, fru] = getFru(ctx, fruDeviceId);
+    if (status != ipmi::ccSuccess)
+    {
+        return ipmi::response(status);
+    }
+
+    size_t fromFruByteLen = 0;
+    if (countToRead + fruInventoryOffset < fru.size())
+    {
+        fromFruByteLen = countToRead;
+    }
+    else if (fru.size() > fruInventoryOffset)
+    {
+        fromFruByteLen = fru.size() - fruInventoryOffset;
+    }
+    else
+    {
+        return ipmi::responseReqDataLenExceeded();
+    }
+
+    std::vector<uint8_t> requestedData;
+
+    requestedData.insert(requestedData.begin(),
+                         fru.begin() + fruInventoryOffset,
+                         fru.begin() + fruInventoryOffset + fromFruByteLen);
+
+    return ipmi::responseSuccess(static_cast<uint8_t>(requestedData.size()),
+                                 requestedData);
+}
+
+/** @brief implements the write FRU data command
+ *  @param fruDeviceId        - FRU Device ID
+ *  @param fruInventoryOffset - FRU Inventory Offset to write
+ *  @param dataToWrite        - Data to write
+ *
+ *  @returns ipmi completion code plus response data
+ *   - countWritten  - Count written
+ */
+ipmi::RspType<uint8_t> ipmiStorageWriteFruData(
+    ipmi::Context::ptr ctx, uint8_t fruDeviceId, uint16_t fruInventoryOffset,
+    std::vector<uint8_t>& dataToWrite)
+{
+    if (fruDeviceId == 0xFF)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    size_t writeLen = dataToWrite.size();
+
+    auto [status, fru] = getFru(ctx, fruDeviceId);
+    if (status != ipmi::ccSuccess)
+    {
+        return ipmi::response(status);
+    }
+    size_t lastWriteAddr = fruInventoryOffset + writeLen;
+    if (fru.size() < lastWriteAddr)
+    {
+        fru.resize(fruInventoryOffset + writeLen);
+    }
+
+    std::copy(dataToWrite.begin(), dataToWrite.begin() + writeLen,
+              fru.begin() + fruInventoryOffset);
+
+    bool atEnd = false;
+
+    if (fru.size() >= sizeof(FRUHeader))
+    {
+        FRUHeader* header = reinterpret_cast<FRUHeader*>(fru.data());
+
+        size_t areaLength = 0;
+        size_t lastRecordStart = std::max(
+            {header->internalOffset, header->chassisOffset, header->boardOffset,
+             header->productOffset, header->multiRecordOffset});
+        lastRecordStart *= 8; // header starts in are multiples of 8 bytes
+
+        if (header->multiRecordOffset)
+        {
+            // This FRU has a MultiRecord Area
+            uint8_t endOfList = 0;
+            // Walk the MultiRecord headers until the last record
+            while (!endOfList)
+            {
+                // The MSB in the second byte of the MultiRecord header signals
+                // "End of list"
+                endOfList = fru[lastRecordStart + 1] & 0x80;
+                // Third byte in the MultiRecord header is the length
+                areaLength = fru[lastRecordStart + 2];
+                // This length is in bytes (not 8 bytes like other headers)
+                areaLength += 5; // The length omits the 5 byte header
+                if (!endOfList)
+                {
+                    // Next MultiRecord header
+                    lastRecordStart += areaLength;
+                }
+            }
+        }
+        else
+        {
+            // This FRU does not have a MultiRecord Area
+            // Get the length of the area in multiples of 8 bytes
+            if (lastWriteAddr > (lastRecordStart + 1))
+            {
+                // second byte in record area is the length
+                areaLength = fru[lastRecordStart + 1];
+                areaLength *= 8; // it is in multiples of 8 bytes
+            }
+        }
+        if (lastWriteAddr >= (areaLength + lastRecordStart))
+        {
+            atEnd = true;
+        }
+    }
+    uint8_t countWritten = 0;
+
+    writeBus = cacheBus;
+    writeAddr = cacheAddr;
+    if (atEnd)
+    {
+        // cancel timer, we're at the end so might as well send it
+        writeTimer->stop();
+        if (!writeFru(fru))
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+        countWritten = std::min(fru.size(), static_cast<size_t>(0xFF));
+    }
+    else
+    {
+        fruCache = fru; // Write-back
+        // start a timer, if no further data is sent  to check to see if it is
+        // valid
+        writeTimer->start(std::chrono::duration_cast<std::chrono::microseconds>(
+            std::chrono::seconds(writeTimeoutSeconds)));
+        countWritten = 0;
+    }
+
+    return ipmi::responseSuccess(countWritten);
+}
+
+/** @brief implements the get FRU inventory area info command
+ *  @param fruDeviceId  - FRU Device ID
+ *
+ *  @returns IPMI completion code plus response data
+ *   - inventorySize - Number of possible allocation units
+ *   - accessType    - Allocation unit size in bytes.
+ */
+ipmi::RspType<uint16_t, // inventorySize
+              uint8_t>  // accessType
+    ipmiStorageGetFruInvAreaInfo(ipmi::Context::ptr ctx, uint8_t fruDeviceId)
+{
+    if (fruDeviceId == 0xFF)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    auto [ret, fru] = getFru(ctx, fruDeviceId);
+    if (ret != ipmi::ccSuccess)
+    {
+        return ipmi::response(ret);
+    }
+
+    constexpr uint8_t accessType =
+        static_cast<uint8_t>(GetFRUAreaAccessType::byte);
+
+    return ipmi::responseSuccess(fru.size(), accessType);
+}
+
+ipmi_ret_t getFruSdrCount(ipmi::Context::ptr, size_t& count)
+{
+    count = deviceHashes.size();
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t getFruSdrs([[maybe_unused]] ipmi::Context::ptr ctx, size_t index,
+                      get_sdr::SensorDataFruRecord& resp)
+{
+    if (deviceHashes.size() < index)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    auto device = deviceHashes.begin() + index;
+    uint16_t& bus = device->second.first;
+    uint8_t& address = device->second.second;
+
+    boost::container::flat_map<std::string, Value>* fruData = nullptr;
+    auto fru = std::find_if(
+        frus.begin(), frus.end(),
+        [bus, address, &fruData](ManagedEntry& entry) {
+            auto findFruDevice =
+                entry.second.find("xyz.openbmc_project.FruDevice");
+            if (findFruDevice == entry.second.end())
+            {
+                return false;
+            }
+            fruData = &(findFruDevice->second);
+            auto findBus = findFruDevice->second.find("BUS");
+            auto findAddress = findFruDevice->second.find("ADDRESS");
+            if (findBus == findFruDevice->second.end() ||
+                findAddress == findFruDevice->second.end())
+            {
+                return false;
+            }
+            if (std::get<uint32_t>(findBus->second) != bus)
+            {
+                return false;
+            }
+            if (std::get<uint32_t>(findAddress->second) != address)
+            {
+                return false;
+            }
+            return true;
+        });
+    if (fru == frus.end())
+    {
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+    std::string name;
+
+#ifdef USING_ENTITY_MANAGER_DECORATORS
+
+    boost::container::flat_map<std::string, Value>* entityData = nullptr;
+
+    // todo: this should really use caching, this is a very inefficient lookup
+    boost::system::error_code ec;
+    ManagedObjectType entities = ipmi::callDbusMethod<ManagedObjectType>(
+        ctx, ec, "xyz.openbmc_project.EntityManager",
+        "/xyz/openbmc_project/inventory", "org.freedesktop.DBus.ObjectManager",
+        "GetManagedObjects");
+
+    if (ec)
+    {
+        lg2::error("GetMangagedObjects for ipmiStorageGetFruInvAreaInfo "
+                   "failed: {ERROR}",
+                   "ERROR", ec.message());
+
+        return ipmi::ccResponseError;
+    }
+
+    auto entity = std::find_if(
+        entities.begin(), entities.end(),
+        [bus, address, &entityData, &name](ManagedEntry& entry) {
+            auto findFruDevice = entry.second.find(
+                "xyz.openbmc_project.Inventory.Decorator.I2CDevice");
+            if (findFruDevice == entry.second.end())
+            {
+                return false;
+            }
+
+            // Integer fields added via Entity-Manager json are uint64_ts by
+            // default.
+            auto findBus = findFruDevice->second.find("Bus");
+            auto findAddress = findFruDevice->second.find("Address");
+
+            if (findBus == findFruDevice->second.end() ||
+                findAddress == findFruDevice->second.end())
+            {
+                return false;
+            }
+            if ((std::get<uint64_t>(findBus->second) != bus) ||
+                (std::get<uint64_t>(findAddress->second) != address))
+            {
+                return false;
+            }
+
+            auto fruName = findFruDevice->second.find("Name");
+            if (fruName != findFruDevice->second.end())
+            {
+                name = std::get<std::string>(fruName->second);
+            }
+
+            // At this point we found the device entry and should return
+            // true.
+            auto findIpmiDevice = entry.second.find(
+                "xyz.openbmc_project.Inventory.Decorator.Ipmi");
+            if (findIpmiDevice != entry.second.end())
+            {
+                entityData = &(findIpmiDevice->second);
+            }
+
+            return true;
+        });
+
+    if (entity == entities.end())
+    {
+        if constexpr (DEBUG)
+        {
+            std::fprintf(stderr, "Ipmi or FruDevice Decorator interface "
+                                 "not found for Fru\n");
+        }
+    }
+
+#endif
+
+    std::vector<std::string> nameProperties = {
+        "PRODUCT_PRODUCT_NAME",  "BOARD_PRODUCT_NAME",   "PRODUCT_PART_NUMBER",
+        "BOARD_PART_NUMBER",     "PRODUCT_MANUFACTURER", "BOARD_MANUFACTURER",
+        "PRODUCT_SERIAL_NUMBER", "BOARD_SERIAL_NUMBER"};
+
+    for (const std::string& prop : nameProperties)
+    {
+        auto findProp = fruData->find(prop);
+        if (findProp != fruData->end())
+        {
+            name = std::get<std::string>(findProp->second);
+            break;
+        }
+    }
+
+    if (name.empty())
+    {
+        name = "UNKNOWN";
+    }
+    if (name.size() > maxFruSdrNameSize)
+    {
+        name = name.substr(0, maxFruSdrNameSize);
+    }
+    size_t sizeDiff = maxFruSdrNameSize - name.size();
+
+    resp.header.record_id_lsb = 0x0; // calling code is to implement these
+    resp.header.record_id_msb = 0x0;
+    resp.header.sdr_version = ipmiSdrVersion;
+    resp.header.record_type = get_sdr::SENSOR_DATA_FRU_RECORD;
+    resp.header.record_length = sizeof(resp.body) + sizeof(resp.key) - sizeDiff;
+    resp.key.deviceAddress = 0x20;
+    resp.key.fruID = device->first;
+    resp.key.accessLun = 0x80; // logical / physical fru device
+    resp.key.channelNumber = 0x0;
+    resp.body.reserved = 0x0;
+    resp.body.deviceType = 0x10;
+    resp.body.deviceTypeModifier = 0x0;
+
+    uint8_t entityID = 0;
+    uint8_t entityInstance = 0x1;
+
+#ifdef USING_ENTITY_MANAGER_DECORATORS
+    if (entityData)
+    {
+        auto entityIdProperty = entityData->find("EntityId");
+        auto entityInstanceProperty = entityData->find("EntityInstance");
+
+        if (entityIdProperty != entityData->end())
+        {
+            entityID = static_cast<uint8_t>(
+                std::get<uint64_t>(entityIdProperty->second));
+        }
+        if (entityInstanceProperty != entityData->end())
+        {
+            entityInstance = static_cast<uint8_t>(
+                std::get<uint64_t>(entityInstanceProperty->second));
+        }
+    }
+#endif
+
+    resp.body.entityID = entityID;
+    resp.body.entityInstance = entityInstance;
+
+    resp.body.oem = 0x0;
+    resp.body.deviceIDLen = ipmi::storage::typeASCIILatin8 | name.size();
+    name.copy(resp.body.deviceID, name.size());
+
+    return IPMI_CC_OK;
+}
+
+static bool getSELLogFiles(std::vector<std::filesystem::path>& selLogFiles)
+{
+    // Loop through the directory looking for ipmi_sel log files
+    for (const std::filesystem::directory_entry& dirEnt :
+         std::filesystem::directory_iterator(
+             dynamic_sensors::ipmi::sel::selLogDir))
+    {
+        std::string filename = dirEnt.path().filename();
+        if (boost::starts_with(filename,
+                               dynamic_sensors::ipmi::sel::selLogFilename))
+        {
+            // If we find an ipmi_sel log file, save the path
+            selLogFiles.emplace_back(
+                dynamic_sensors::ipmi::sel::selLogDir / filename);
+        }
+    }
+    // As the log files rotate, they are appended with a ".#" that is higher for
+    // the older logs. Since we don't expect more than 10 log files, we
+    // can just sort the list to get them in order from newest to oldest
+    std::sort(selLogFiles.begin(), selLogFiles.end());
+
+    return !selLogFiles.empty();
+}
+
+static int countSELEntries()
+{
+    // Get the list of ipmi_sel log files
+    std::vector<std::filesystem::path> selLogFiles;
+    if (!getSELLogFiles(selLogFiles))
+    {
+        return 0;
+    }
+    int numSELEntries = 0;
+    // Loop through each log file and count the number of logs
+    for (const std::filesystem::path& file : selLogFiles)
+    {
+        std::ifstream logStream(file);
+        if (!logStream.is_open())
+        {
+            continue;
+        }
+
+        std::string line;
+        while (std::getline(logStream, line))
+        {
+            numSELEntries++;
+        }
+    }
+    return numSELEntries;
+}
+
+static bool findSELEntry(const int recordID,
+                         const std::vector<std::filesystem::path>& selLogFiles,
+                         std::string& entry)
+{
+    // Record ID is the first entry field following the timestamp. It is
+    // preceded by a space and followed by a comma
+    std::string search = " " + std::to_string(recordID) + ",";
+
+    // Loop through the ipmi_sel log entries
+    for (const std::filesystem::path& file : selLogFiles)
+    {
+        std::ifstream logStream(file);
+        if (!logStream.is_open())
+        {
+            continue;
+        }
+
+        while (std::getline(logStream, entry))
+        {
+            // Check if the record ID matches
+            if (entry.find(search) != std::string::npos)
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+static uint16_t getNextRecordID(
+    const uint16_t recordID,
+    const std::vector<std::filesystem::path>& selLogFiles)
+{
+    uint16_t nextRecordID = recordID + 1;
+    std::string entry;
+    if (findSELEntry(nextRecordID, selLogFiles, entry))
+    {
+        return nextRecordID;
+    }
+    else
+    {
+        return ipmi::sel::lastEntry;
+    }
+}
+
+static int fromHexStr(const std::string& hexStr, std::vector<uint8_t>& data)
+{
+    for (unsigned int i = 0; i < hexStr.size(); i += 2)
+    {
+        try
+        {
+            data.push_back(static_cast<uint8_t>(
+                std::stoul(hexStr.substr(i, 2), nullptr, 16)));
+        }
+        catch (const std::invalid_argument& e)
+        {
+            lg2::error("Invalid argument: {ERROR}", "ERROR", e);
+            return -1;
+        }
+        catch (const std::out_of_range& e)
+        {
+            lg2::error("Out of range: {ERROR}", "ERROR", e);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+ipmi::RspType<uint8_t,  // SEL version
+              uint16_t, // SEL entry count
+              uint16_t, // free space
+              uint32_t, // last add timestamp
+              uint32_t, // last erase timestamp
+              uint8_t>  // operation support
+    ipmiStorageGetSELInfo()
+{
+    constexpr uint8_t selVersion = ipmi::sel::selVersion;
+    uint16_t entries = countSELEntries();
+    uint32_t addTimeStamp = dynamic_sensors::ipmi::sel::getFileTimestamp(
+        dynamic_sensors::ipmi::sel::selLogDir /
+        dynamic_sensors::ipmi::sel::selLogFilename);
+    uint32_t eraseTimeStamp = dynamic_sensors::ipmi::sel::erase_time::get();
+    constexpr uint8_t operationSupport =
+        dynamic_sensors::ipmi::sel::selOperationSupport;
+    constexpr uint16_t freeSpace =
+        0xffff; // Spec indicates that more than 64kB is free
+
+    return ipmi::responseSuccess(selVersion, entries, freeSpace, addTimeStamp,
+                                 eraseTimeStamp, operationSupport);
+}
+
+using systemEventType = std::tuple<
+    uint32_t, // Timestamp
+    uint16_t, // Generator ID
+    uint8_t,  // EvM Rev
+    uint8_t,  // Sensor Type
+    uint8_t,  // Sensor Number
+    uint7_t,  // Event Type
+    bool,     // Event Direction
+    std::array<uint8_t, dynamic_sensors::ipmi::sel::systemEventSize>>; // Event
+                                                                       // Data
+using oemTsEventType = std::tuple<
+    uint32_t, // Timestamp
+    std::array<uint8_t, dynamic_sensors::ipmi::sel::oemTsEventSize>>; // Event
+                                                                      // Data
+using oemEventType =
+    std::array<uint8_t, dynamic_sensors::ipmi::sel::oemEventSize>; // Event Data
+
+ipmi::RspType<uint16_t,                   // Next Record ID
+              uint16_t,                   // Record ID
+              uint8_t,                    // Record Type
+              std::variant<systemEventType, oemTsEventType,
+                           oemEventType>> // Record Content
+    ipmiStorageGetSELEntry(uint16_t reservationID, uint16_t targetID,
+                           uint8_t offset, uint8_t size)
+{
+    // Only support getting the entire SEL record. If a partial size or non-zero
+    // offset is requested, return an error
+    if (offset != 0 || size != ipmi::sel::entireRecord)
+    {
+        return ipmi::responseRetBytesUnavailable();
+    }
+
+    // Check the reservation ID if one is provided or required (only if the
+    // offset is non-zero)
+    if (reservationID != 0 || offset != 0)
+    {
+        if (!checkSELReservation(reservationID))
+        {
+            return ipmi::responseInvalidReservationId();
+        }
+    }
+
+    // Get the ipmi_sel log files
+    std::vector<std::filesystem::path> selLogFiles;
+    if (!getSELLogFiles(selLogFiles))
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    std::string targetEntry;
+
+    if (targetID == ipmi::sel::firstEntry)
+    {
+        // The first entry will be at the top of the oldest log file
+        std::ifstream logStream(selLogFiles.back());
+        if (!logStream.is_open())
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+
+        if (!std::getline(logStream, targetEntry))
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+    else if (targetID == ipmi::sel::lastEntry)
+    {
+        // The last entry will be at the bottom of the newest log file
+        std::ifstream logStream(selLogFiles.front());
+        if (!logStream.is_open())
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+
+        std::string line;
+        while (std::getline(logStream, line))
+        {
+            targetEntry = line;
+        }
+    }
+    else
+    {
+        if (!findSELEntry(targetID, selLogFiles, targetEntry))
+        {
+            return ipmi::responseSensorInvalid();
+        }
+    }
+
+    // The format of the ipmi_sel message is "<Timestamp>
+    // <ID>,<Type>,<EventData>,[<Generator ID>,<Path>,<Direction>]".
+    // First get the Timestamp
+    size_t space = targetEntry.find_first_of(" ");
+    if (space == std::string::npos)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    std::string entryTimestamp = targetEntry.substr(0, space);
+    // Then get the log contents
+    size_t entryStart = targetEntry.find_first_not_of(" ", space);
+    if (entryStart == std::string::npos)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    std::string_view entry(targetEntry);
+    entry.remove_prefix(entryStart);
+    // Use split to separate the entry into its fields
+    std::vector<std::string> targetEntryFields;
+    boost::split(targetEntryFields, entry, boost::is_any_of(","),
+                 boost::token_compress_on);
+    if (targetEntryFields.size() < 3)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    std::string& recordIDStr = targetEntryFields[0];
+    std::string& recordTypeStr = targetEntryFields[1];
+    std::string& eventDataStr = targetEntryFields[2];
+
+    uint16_t recordID;
+    uint8_t recordType;
+    try
+    {
+        recordID = std::stoul(recordIDStr);
+        recordType = std::stoul(recordTypeStr, nullptr, 16);
+    }
+    catch (const std::invalid_argument&)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    uint16_t nextRecordID = getNextRecordID(recordID, selLogFiles);
+    std::vector<uint8_t> eventDataBytes;
+    if (fromHexStr(eventDataStr, eventDataBytes) < 0)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    if (recordType == dynamic_sensors::ipmi::sel::systemEvent)
+    {
+        // Get the timestamp
+        std::tm timeStruct = {};
+        std::istringstream entryStream(entryTimestamp);
+
+        uint32_t timestamp = ipmi::sel::invalidTimeStamp;
+        if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S"))
+        {
+            timeStruct.tm_isdst = -1;
+            timestamp = std::mktime(&timeStruct);
+        }
+
+        // Set the event message revision
+        uint8_t evmRev = dynamic_sensors::ipmi::sel::eventMsgRev;
+
+        uint16_t generatorID = 0;
+        uint8_t sensorType = 0;
+        uint16_t sensorAndLun = 0;
+        uint8_t sensorNum = 0xFF;
+        uint7_t eventType = 0;
+        bool eventDir = 0;
+        // System type events should have six fields
+        if (targetEntryFields.size() >= 6)
+        {
+            std::string& generatorIDStr = targetEntryFields[3];
+            std::string& sensorPath = targetEntryFields[4];
+            std::string& eventDirStr = targetEntryFields[5];
+
+            // Get the generator ID
+            try
+            {
+                generatorID = std::stoul(generatorIDStr, nullptr, 16);
+            }
+            catch (const std::invalid_argument&)
+            {
+                std::cerr << "Invalid Generator ID\n";
+            }
+
+            // Get the sensor type, sensor number, and event type for the sensor
+            sensorType = getSensorTypeFromPath(sensorPath);
+            sensorAndLun = getSensorNumberFromPath(sensorPath);
+            sensorNum = static_cast<uint8_t>(sensorAndLun);
+            if ((generatorID & 0x0001) == 0)
+            {
+                // IPMB Address
+                generatorID |= sensorAndLun & 0x0300;
+            }
+            else
+            {
+                // system software
+                generatorID |= sensorAndLun >> 8;
+            }
+            eventType = getSensorEventTypeFromPath(sensorPath);
+
+            // Get the event direction
+            try
+            {
+                eventDir = std::stoul(eventDirStr) ? 0 : 1;
+            }
+            catch (const std::invalid_argument&)
+            {
+                std::cerr << "Invalid Event Direction\n";
+            }
+        }
+
+        // Only keep the eventData bytes that fit in the record
+        std::array<uint8_t, dynamic_sensors::ipmi::sel::systemEventSize>
+            eventData{};
+        std::copy_n(eventDataBytes.begin(),
+                    std::min(eventDataBytes.size(), eventData.size()),
+                    eventData.begin());
+
+        return ipmi::responseSuccess(
+            nextRecordID, recordID, recordType,
+            systemEventType{timestamp, generatorID, evmRev, sensorType,
+                            sensorNum, eventType, eventDir, eventData});
+    }
+
+    if (recordType >= dynamic_sensors::ipmi::sel::oemTsEventFirst &&
+        recordType <= dynamic_sensors::ipmi::sel::oemTsEventLast)
+    {
+        // Get the timestamp
+        std::tm timeStruct = {};
+        std::istringstream entryStream(entryTimestamp);
+
+        uint32_t timestamp = ipmi::sel::invalidTimeStamp;
+        if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S"))
+        {
+            timeStruct.tm_isdst = -1;
+            timestamp = std::mktime(&timeStruct);
+        }
+
+        // Only keep the bytes that fit in the record
+        std::array<uint8_t, dynamic_sensors::ipmi::sel::oemTsEventSize>
+            eventData{};
+        std::copy_n(eventDataBytes.begin(),
+                    std::min(eventDataBytes.size(), eventData.size()),
+                    eventData.begin());
+
+        return ipmi::responseSuccess(nextRecordID, recordID, recordType,
+                                     oemTsEventType{timestamp, eventData});
+    }
+
+    if (recordType >= dynamic_sensors::ipmi::sel::oemEventFirst)
+    {
+        // Only keep the bytes that fit in the record
+        std::array<uint8_t, dynamic_sensors::ipmi::sel::oemEventSize>
+            eventData{};
+        std::copy_n(eventDataBytes.begin(),
+                    std::min(eventDataBytes.size(), eventData.size()),
+                    eventData.begin());
+
+        return ipmi::responseSuccess(nextRecordID, recordID, recordType,
+                                     eventData);
+    }
+
+    return ipmi::responseUnspecifiedError();
+}
+
+/*
+Unused arguments
+  uint16_t recordID, uint8_t recordType, uint32_t timestamp,
+  uint16_t generatorID, uint8_t evmRev, uint8_t sensorType, uint8_t sensorNum,
+  uint8_t eventType, uint8_t eventData1, uint8_t eventData2,
+  uint8_t eventData3
+*/
+ipmi::RspType<uint16_t> ipmiStorageAddSELEntry(
+    uint16_t, uint8_t, uint32_t, uint16_t, uint8_t, uint8_t, uint8_t, uint8_t,
+    uint8_t, uint8_t, uint8_t)
+{
+    // Per the IPMI spec, need to cancel any reservation when a SEL entry is
+    // added
+    cancelSELReservation();
+
+    uint16_t responseID = 0xFFFF;
+    return ipmi::responseSuccess(responseID);
+}
+
+ipmi::RspType<uint8_t> ipmiStorageClearSEL(
+    ipmi::Context::ptr ctx, uint16_t reservationID,
+    const std::array<uint8_t, 3>& clr, uint8_t eraseOperation)
+{
+    if (!checkSELReservation(reservationID))
+    {
+        return ipmi::responseInvalidReservationId();
+    }
+
+    static constexpr std::array<uint8_t, 3> clrExpected = {'C', 'L', 'R'};
+    if (clr != clrExpected)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // Erasure status cannot be fetched, so always return erasure status as
+    // `erase completed`.
+    if (eraseOperation == ipmi::sel::getEraseStatus)
+    {
+        return ipmi::responseSuccess(ipmi::sel::eraseComplete);
+    }
+
+    // Check that initiate erase is correct
+    if (eraseOperation != ipmi::sel::initiateErase)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // Per the IPMI spec, need to cancel any reservation when the SEL is
+    // cleared
+    cancelSELReservation();
+
+    boost::system::error_code ec =
+        ipmi::callDbusMethod(ctx, "xyz.openbmc_project.Logging.IPMI",
+                             "/xyz/openbmc_project/Logging/IPMI",
+                             "xyz.openbmc_project.Logging.IPMI", "Clear");
+    if (ec)
+    {
+        std::cerr << "error in clear SEL: " << ec.message() << std::endl;
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(ipmi::sel::eraseComplete);
+}
+
+std::vector<uint8_t> getType8SDRs(
+    ipmi::sensor::EntityInfoMap::const_iterator& entity, uint16_t recordId)
+{
+    std::vector<uint8_t> resp;
+    get_sdr::SensorDataEntityRecord data{};
+
+    /* Header */
+    get_sdr::header::set_record_id(recordId, &(data.header));
+    // Based on IPMI Spec v2.0 rev 1.1
+    data.header.sdr_version = SDR_VERSION;
+    data.header.record_type = 0x08;
+    data.header.record_length = sizeof(data.key) + sizeof(data.body);
+
+    /* Key */
+    data.key.containerEntityId = entity->second.containerEntityId;
+    data.key.containerEntityInstance = entity->second.containerEntityInstance;
+    get_sdr::key::set_flags(entity->second.isList, entity->second.isLinked,
+                            &(data.key));
+    data.key.entityId1 = entity->second.containedEntities[0].first;
+    data.key.entityInstance1 = entity->second.containedEntities[0].second;
+
+    /* Body */
+    data.body.entityId2 = entity->second.containedEntities[1].first;
+    data.body.entityInstance2 = entity->second.containedEntities[1].second;
+    data.body.entityId3 = entity->second.containedEntities[2].first;
+    data.body.entityInstance3 = entity->second.containedEntities[2].second;
+    data.body.entityId4 = entity->second.containedEntities[3].first;
+    data.body.entityInstance4 = entity->second.containedEntities[3].second;
+
+    resp.insert(resp.end(), (uint8_t*)&data, ((uint8_t*)&data) + sizeof(data));
+
+    return resp;
+}
+
+std::vector<uint8_t> getType12SDRs(uint16_t index, uint16_t recordId)
+{
+    std::vector<uint8_t> resp;
+    if (index == 0)
+    {
+        std::string bmcName = "Basbrd Mgmt Ctlr";
+        Type12Record bmc(recordId, 0x20, 0, 0, 0xbf, 0x2e, 1, 0, bmcName);
+        uint8_t* bmcPtr = reinterpret_cast<uint8_t*>(&bmc);
+        resp.insert(resp.end(), bmcPtr, bmcPtr + sizeof(Type12Record));
+    }
+    else if (index == 1)
+    {
+        std::string meName = "Mgmt Engine";
+        Type12Record me(recordId, 0x2c, 6, 0x24, 0x21, 0x2e, 2, 0, meName);
+        uint8_t* mePtr = reinterpret_cast<uint8_t*>(&me);
+        resp.insert(resp.end(), mePtr, mePtr + sizeof(Type12Record));
+    }
+    else
+    {
+        throw std::runtime_error(
+            "getType12SDRs:: Illegal index " + std::to_string(index));
+    }
+
+    return resp;
+}
+
+void registerStorageFunctions()
+{
+    createTimers();
+    startMatch();
+
+    // <Get FRU Inventory Area Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetFruInventoryAreaInfo,
+                          ipmi::Privilege::User, ipmiStorageGetFruInvAreaInfo);
+    // <READ FRU Data>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdReadFruData, ipmi::Privilege::User,
+                          ipmiStorageReadFruData);
+
+    // <WRITE FRU Data>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdWriteFruData,
+                          ipmi::Privilege::Operator, ipmiStorageWriteFruData);
+
+    // <Get SEL Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelInfo, ipmi::Privilege::User,
+                          ipmiStorageGetSELInfo);
+
+    // <Get SEL Entry>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelEntry, ipmi::Privilege::User,
+                          ipmiStorageGetSELEntry);
+
+    // <Add SEL Entry>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdAddSelEntry,
+                          ipmi::Privilege::Operator, ipmiStorageAddSELEntry);
+
+    // <Clear SEL>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdClearSel, ipmi::Privilege::Operator,
+                          ipmiStorageClearSEL);
+}
+} // namespace storage
+} // namespace ipmi
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
new file mode 100644
index 0000000..769081a
--- /dev/null
+++ b/dcmihandler.cpp
@@ -0,0 +1,1245 @@
+#include "config.h"
+
+#include "dcmihandler.hpp"
+
+#include "user_channel/channel_layer.hpp"
+
+#include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
+
+#include <bitset>
+#include <cmath>
+#include <fstream>
+#include <variant>
+
+using namespace phosphor::logging;
+using sdbusplus::server::xyz::openbmc_project::network::EthernetInterface;
+
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+void registerNetFnDcmiFunctions() __attribute__((constructor));
+
+constexpr auto pcapPath = "/xyz/openbmc_project/control/host0/power_cap";
+constexpr auto pcapInterface = "xyz.openbmc_project.Control.Power.Cap";
+
+constexpr auto powerCapProp = "PowerCap";
+constexpr auto powerCapEnableProp = "PowerCapEnable";
+
+using namespace phosphor::logging;
+
+namespace dcmi
+{
+constexpr auto assetTagMaxOffset = 62;
+constexpr auto assetTagMaxSize = 63;
+constexpr auto maxBytes = 16;
+constexpr size_t maxCtrlIdStrLen = 63;
+
+constexpr uint8_t parameterRevision = 2;
+constexpr uint8_t specMajorVersion = 1;
+constexpr uint8_t specMinorVersion = 5;
+constexpr auto sensorValueIntf = "xyz.openbmc_project.Sensor.Value";
+constexpr auto sensorValueProp = "Value";
+constexpr uint8_t configParameterRevision = 1;
+constexpr auto option12Mask = 0x01;
+constexpr auto activateDhcpReply = 0x00;
+constexpr uint8_t dhcpTiming1 = 0x04;  // 4 sec
+constexpr uint16_t dhcpTiming2 = 0x78; // 120 sec
+constexpr uint16_t dhcpTiming3 = 0x40; // 60 sec
+// When DHCP Option 12 is enabled the string "SendHostName=true" will be
+// added into n/w configuration file and the parameter
+// SendHostNameEnabled will set to true.
+constexpr auto dhcpOpt12Enabled = "SendHostNameEnabled";
+
+enum class DCMIConfigParameters : uint8_t
+{
+    ActivateDHCP = 1,
+    DiscoveryConfig,
+    DHCPTiming1,
+    DHCPTiming2,
+    DHCPTiming3,
+};
+
+// Refer Table 6-14, DCMI Entity ID Extension, DCMI v1.5 spec
+static const std::map<uint8_t, std::string> entityIdToName{
+    {0x40, "inlet"}, {0x37, "inlet"},     {0x41, "cpu"},
+    {0x03, "cpu"},   {0x42, "baseboard"}, {0x07, "baseboard"}};
+
+nlohmann::json parseJSONConfig(const std::string& configFile)
+{
+    std::ifstream jsonFile(configFile);
+    if (!jsonFile.is_open())
+    {
+        lg2::error("Temperature readings JSON file not found");
+        elog<InternalFailure>();
+    }
+
+    auto data = nlohmann::json::parse(jsonFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        lg2::error("Temperature readings JSON parser failure");
+        elog<InternalFailure>();
+    }
+
+    return data;
+}
+
+bool isDCMIPowerMgmtSupported()
+{
+    static bool parsed = false;
+    static bool supported = false;
+    if (!parsed)
+    {
+        auto data = parseJSONConfig(gDCMICapabilitiesConfig);
+
+        supported = (gDCMIPowerMgmtSupported ==
+                     data.value(gDCMIPowerMgmtCapability, 0));
+    }
+    return supported;
+}
+
+std::optional<uint32_t> getPcap(ipmi::Context::ptr& ctx)
+{
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, pcapInterface, pcapPath, service);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+    uint32_t pcap{};
+    ec = ipmi::getDbusProperty(ctx, service, pcapPath, pcapInterface,
+                               powerCapProp, pcap);
+    if (ec.value())
+    {
+        lg2::error("Error in getPcap prop: {ERROR}", "ERROR", ec.message());
+        elog<InternalFailure>();
+        return std::nullopt;
+    }
+    return pcap;
+}
+
+std::optional<bool> getPcapEnabled(ipmi::Context::ptr& ctx)
+{
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, pcapInterface, pcapPath, service);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+    bool pcapEnabled{};
+    ec = ipmi::getDbusProperty(ctx, service, pcapPath, pcapInterface,
+                               powerCapEnableProp, pcapEnabled);
+    if (ec.value())
+    {
+        lg2::error("Error in getPcap prop");
+        elog<InternalFailure>();
+        return std::nullopt;
+    }
+    return pcapEnabled;
+}
+
+bool setPcap(ipmi::Context::ptr& ctx, const uint32_t powerCap)
+{
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, pcapInterface, pcapPath, service);
+    if (ec.value())
+    {
+        return false;
+    }
+
+    ec = ipmi::setDbusProperty(ctx, service, pcapPath, pcapInterface,
+                               powerCapProp, powerCap);
+    if (ec.value())
+    {
+        lg2::error("Error in setPcap property: {ERROR}", "ERROR", ec.message());
+        elog<InternalFailure>();
+        return false;
+    }
+    return true;
+}
+
+bool setPcapEnable(ipmi::Context::ptr& ctx, bool enabled)
+{
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, pcapInterface, pcapPath, service);
+    if (ec.value())
+    {
+        return false;
+    }
+
+    ec = ipmi::setDbusProperty(ctx, service, pcapPath, pcapInterface,
+                               powerCapEnableProp, enabled);
+    if (ec.value())
+    {
+        lg2::error("Error in setPcapEnabled property: {ERROR}", "ERROR",
+                   ec.message());
+        elog<InternalFailure>();
+        return false;
+    }
+    return true;
+}
+
+std::optional<std::string> readAssetTag(ipmi::Context::ptr& ctx)
+{
+    // Read the object tree with the inventory root to figure out the object
+    // that has implemented the Asset tag interface.
+    ipmi::DbusObjectInfo objectInfo;
+    boost::system::error_code ec = getDbusObject(
+        ctx, dcmi::assetTagIntf, ipmi::sensor::inventoryRoot, "", objectInfo);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+
+    std::string assetTag{};
+    ec =
+        ipmi::getDbusProperty(ctx, objectInfo.second, objectInfo.first,
+                              dcmi::assetTagIntf, dcmi::assetTagProp, assetTag);
+    if (ec.value())
+    {
+        lg2::error("Error in reading asset tag: {ERROR}", "ERROR",
+                   ec.message());
+        elog<InternalFailure>();
+        return std::nullopt;
+    }
+
+    return assetTag;
+}
+
+bool writeAssetTag(ipmi::Context::ptr& ctx, const std::string& assetTag)
+{
+    // Read the object tree with the inventory root to figure out the object
+    // that has implemented the Asset tag interface.
+    ipmi::DbusObjectInfo objectInfo;
+    boost::system::error_code ec = getDbusObject(
+        ctx, dcmi::assetTagIntf, ipmi::sensor::inventoryRoot, "", objectInfo);
+    if (ec.value())
+    {
+        return false;
+    }
+
+    ec =
+        ipmi::setDbusProperty(ctx, objectInfo.second, objectInfo.first,
+                              dcmi::assetTagIntf, dcmi::assetTagProp, assetTag);
+    if (ec.value())
+    {
+        lg2::error("Error in writing asset tag: {ERROR}", "ERROR",
+                   ec.message());
+        elog<InternalFailure>();
+        return false;
+    }
+    return true;
+}
+
+std::optional<std::string> getHostName(ipmi::Context::ptr& ctx)
+{
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, networkConfigIntf, networkConfigObj, service);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+    std::string hostname{};
+    ec = ipmi::getDbusProperty(ctx, service, networkConfigObj,
+                               networkConfigIntf, hostNameProp, hostname);
+    if (ec.value())
+    {
+        lg2::error("Error fetching hostname");
+        elog<InternalFailure>();
+        return std::nullopt;
+    }
+    return hostname;
+}
+
+std::optional<EthernetInterface::DHCPConf> getDHCPEnabled(
+    ipmi::Context::ptr& ctx)
+{
+    auto ethdevice = ipmi::getChannelName(ethernetDefaultChannelNum);
+    ipmi::DbusObjectInfo ethernetObj{};
+    boost::system::error_code ec = ipmi::getDbusObject(
+        ctx, ethernetIntf, networkRoot, ethdevice, ethernetObj);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+    std::string service{};
+    ec = ipmi::getService(ctx, ethernetIntf, ethernetObj.first, service);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+    std::string dhcpVal{};
+    ec = ipmi::getDbusProperty(ctx, service, ethernetObj.first, ethernetIntf,
+                               "DHCPEnabled", dhcpVal);
+    if (ec.value())
+    {
+        return std::nullopt;
+    }
+
+    return EthernetInterface::convertDHCPConfFromString(dhcpVal);
+}
+
+std::optional<bool> getDHCPOption(ipmi::Context::ptr& ctx,
+                                  const std::string& prop)
+{
+    ipmi::ObjectTree objectTree;
+    if (ipmi::getAllDbusObjects(ctx, networkRoot, dhcpIntf, objectTree))
+    {
+        return std::nullopt;
+    }
+
+    for (const auto& [path, serviceMap] : objectTree)
+    {
+        for (const auto& [service, object] : serviceMap)
+        {
+            bool value{};
+            if (ipmi::getDbusProperty(ctx, service, path, dhcpIntf, prop,
+                                      value))
+            {
+                return std::nullopt;
+            }
+
+            if (value)
+            {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+bool setDHCPOption(ipmi::Context::ptr& ctx, std::string prop, bool value)
+{
+    ipmi::ObjectTree objectTree;
+    if (ipmi::getAllDbusObjects(ctx, networkRoot, dhcpIntf, objectTree))
+    {
+        return false;
+    }
+
+    for (const auto& [path, serviceMap] : objectTree)
+    {
+        for (const auto& [service, object] : serviceMap)
+        {
+            if (ipmi::setDbusProperty(ctx, service, path, dhcpIntf, prop,
+                                      value))
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+} // namespace dcmi
+
+constexpr uint8_t exceptionPowerOff = 0x01;
+ipmi::RspType<uint16_t, // reserved
+              uint8_t,  // exception actions
+              uint16_t, // power limit requested in watts
+              uint32_t, // correction time in milliseconds
+              uint16_t, // reserved
+              uint16_t  // statistics sampling period in seconds
+              >
+    getPowerLimit(ipmi::Context::ptr ctx, uint16_t reserved)
+{
+    if (!dcmi::isDCMIPowerMgmtSupported())
+    {
+        return ipmi::responseInvalidCommand();
+    }
+    if (reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    std::optional<uint16_t> pcapValue = dcmi::getPcap(ctx);
+    std::optional<bool> pcapEnable = dcmi::getPcapEnabled(ctx);
+    if (!pcapValue || !pcapEnable)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    constexpr uint16_t reserved1{};
+    constexpr uint16_t reserved2{};
+    /*
+     * Exception action if power limit is exceeded and cannot be controlled
+     * with the correction time limit is hardcoded to Hard Power Off system
+     * and log event to SEL.
+     */
+    constexpr uint8_t exception = exceptionPowerOff;
+    /*
+     * Correction time limit and Statistics sampling period is currently not
+     * populated.
+     */
+    constexpr uint32_t correctionTime{};
+    constexpr uint16_t statsPeriod{};
+    if (*pcapEnable == false)
+    {
+        constexpr ipmi::Cc responseNoPowerLimitSet = 0x80;
+        return ipmi::response(responseNoPowerLimitSet, reserved1, exception,
+                              *pcapValue, correctionTime, reserved2,
+                              statsPeriod);
+    }
+    return ipmi::responseSuccess(reserved1, exception, *pcapValue,
+                                 correctionTime, reserved2, statsPeriod);
+}
+
+ipmi::RspType<> setPowerLimit(ipmi::Context::ptr& ctx, uint16_t reserved1,
+                              uint8_t reserved2, uint8_t exceptionAction,
+                              uint16_t powerLimit, uint32_t correctionTime,
+                              uint16_t reserved3, uint16_t statsPeriod)
+{
+    if (!dcmi::isDCMIPowerMgmtSupported())
+    {
+        lg2::error("DCMI Power management is unsupported!");
+        return ipmi::responseInvalidCommand();
+    }
+
+    // Only process the power limit requested in watts. Return errors
+    // for other fields that are set
+    if (reserved1 || reserved2 || reserved3 || correctionTime || statsPeriod ||
+        exceptionAction != exceptionPowerOff)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (!dcmi::setPcap(ctx, powerLimit))
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    lg2::info("Set Power Cap: {POWERCAP}", "POWERCAP", powerLimit);
+
+    return ipmi::responseSuccess();
+}
+
+ipmi::RspType<> applyPowerLimit(ipmi::Context::ptr& ctx, bool enabled,
+                                uint7_t reserved1, uint16_t reserved2)
+{
+    if (!dcmi::isDCMIPowerMgmtSupported())
+    {
+        lg2::error("DCMI Power management is unsupported!");
+        return ipmi::responseInvalidCommand();
+    }
+    if (reserved1 || reserved2)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (!dcmi::setPcapEnable(ctx, enabled))
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    lg2::info("Set Power Cap Enable: {POWERCAPENABLE}", "POWERCAPENABLE",
+              enabled);
+
+    return ipmi::responseSuccess();
+}
+
+ipmi::RspType<uint8_t,          // total tag length
+              std::vector<char> // tag data
+              >
+    getAssetTag(ipmi::Context::ptr& ctx, uint8_t offset, uint8_t count)
+{
+    // Verify offset to read and number of bytes to read are not exceeding
+    // the range.
+    if ((offset > dcmi::assetTagMaxOffset) || (count > dcmi::maxBytes) ||
+        ((offset + count) > dcmi::assetTagMaxSize))
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    std::optional<std::string> assetTagResp = dcmi::readAssetTag(ctx);
+    if (!assetTagResp)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    std::string& assetTag = assetTagResp.value();
+    // If the asset tag is longer than 63 bytes, restrict it to 63 bytes to
+    // suit Get Asset Tag command.
+    if (assetTag.size() > dcmi::assetTagMaxSize)
+    {
+        assetTag.resize(dcmi::assetTagMaxSize);
+    }
+
+    if (offset >= assetTag.size())
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    // silently truncate reads beyond the end of assetTag
+    if ((offset + count) >= assetTag.size())
+    {
+        count = assetTag.size() - offset;
+    }
+
+    auto totalTagSize = static_cast<uint8_t>(assetTag.size());
+    std::vector<char> data{assetTag.begin() + offset,
+                           assetTag.begin() + offset + count};
+
+    return ipmi::responseSuccess(totalTagSize, data);
+}
+
+ipmi::RspType<uint8_t // new asset tag length
+              >
+    setAssetTag(ipmi::Context::ptr& ctx, uint8_t offset, uint8_t count,
+                const std::vector<char>& data)
+{
+    // Verify offset to read and number of bytes to read are not exceeding
+    // the range.
+    if ((offset > dcmi::assetTagMaxOffset) || (count > dcmi::maxBytes) ||
+        ((offset + count) > dcmi::assetTagMaxSize))
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+    if (data.size() != count)
+    {
+        return ipmi::responseReqDataLenInvalid();
+    }
+
+    std::optional<std::string> assetTagResp = dcmi::readAssetTag(ctx);
+    if (!assetTagResp)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    std::string& assetTag = assetTagResp.value();
+
+    if (offset > assetTag.size())
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    // operation is to truncate at offset and append new data
+    assetTag.resize(offset);
+    assetTag.append(data.begin(), data.end());
+
+    if (!dcmi::writeAssetTag(ctx, assetTag))
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    auto totalTagSize = static_cast<uint8_t>(assetTag.size());
+    return ipmi::responseSuccess(totalTagSize);
+}
+
+ipmi::RspType<uint8_t,          // length
+              std::vector<char> // data
+              >
+    getMgmntCtrlIdStr(ipmi::Context::ptr& ctx, uint8_t offset, uint8_t count)
+{
+    if (count > dcmi::maxBytes || offset + count > dcmi::maxCtrlIdStrLen)
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    std::optional<std::string> hostnameResp = dcmi::getHostName(ctx);
+    if (!hostnameResp)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    std::string& hostname = hostnameResp.value();
+    // If the id string is longer than 63 bytes, restrict it to 63 bytes to
+    // suit set management ctrl str  command.
+    if (hostname.size() > dcmi::maxCtrlIdStrLen)
+    {
+        hostname.resize(dcmi::maxCtrlIdStrLen);
+    }
+
+    if (offset >= hostname.size())
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    // silently truncate reads beyond the end of hostname
+    if ((offset + count) >= hostname.size())
+    {
+        count = hostname.size() - offset;
+    }
+
+    auto nameSize = static_cast<uint8_t>(hostname.size());
+    std::vector<char> data{hostname.begin() + offset,
+                           hostname.begin() + offset + count};
+
+    return ipmi::responseSuccess(nameSize, data);
+}
+
+ipmi::RspType<uint8_t> setMgmntCtrlIdStr(ipmi::Context::ptr& ctx,
+                                         uint8_t offset, uint8_t count,
+                                         std::vector<char> data)
+{
+    if ((offset > dcmi::maxCtrlIdStrLen) || (count > dcmi::maxBytes) ||
+        ((offset + count) > dcmi::maxCtrlIdStrLen))
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+    if (data.size() != count)
+    {
+        return ipmi::responseReqDataLenInvalid();
+    }
+    bool terminalWrite{data.back() == '\0'};
+    if (terminalWrite)
+    {
+        // remove the null termination from the data (no need with std::string)
+        data.resize(count - 1);
+    }
+
+    static std::string hostname{};
+    // read in the current value if not starting at offset 0
+    if (hostname.size() == 0 && offset != 0)
+    {
+        /* read old ctrlIdStr */
+        std::optional<std::string> hostnameResp = dcmi::getHostName(ctx);
+        if (!hostnameResp)
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+        hostname = hostnameResp.value();
+        hostname.resize(offset);
+    }
+
+    // operation is to truncate at offset and append new data
+    hostname.append(data.begin(), data.end());
+
+    // do the update if this is the last write
+    if (terminalWrite)
+    {
+        boost::system::error_code ec = ipmi::setDbusProperty(
+            ctx, dcmi::networkServiceName, dcmi::networkConfigObj,
+            dcmi::networkConfigIntf, dcmi::hostNameProp, hostname);
+        hostname.clear();
+        if (ec.value())
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+    }
+
+    auto totalIdSize = static_cast<uint8_t>(offset + count);
+    return ipmi::responseSuccess(totalIdSize);
+}
+
+ipmi::RspType<ipmi::message::Payload> getDCMICapabilities(uint8_t parameter)
+{
+    std::ifstream dcmiCapFile(dcmi::gDCMICapabilitiesConfig);
+    if (!dcmiCapFile.is_open())
+    {
+        lg2::error("DCMI Capabilities file not found");
+        return ipmi::responseUnspecifiedError();
+    }
+
+    auto data = nlohmann::json::parse(dcmiCapFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        lg2::error("DCMI Capabilities JSON parser failure");
+        return ipmi::responseUnspecifiedError();
+    }
+
+    constexpr bool reserved1{};
+    constexpr uint5_t reserved5{};
+    constexpr uint7_t reserved7{};
+    constexpr uint8_t reserved8{};
+    constexpr uint16_t reserved16{};
+
+    ipmi::message::Payload payload;
+    payload.pack(dcmi::specMajorVersion, dcmi::specMinorVersion,
+                 dcmi::parameterRevision);
+
+    enum class DCMICapParameters : uint8_t
+    {
+        SupportedDcmiCaps = 0x01,             // Supported DCMI Capabilities
+        MandatoryPlatAttributes = 0x02,       // Mandatory Platform Attributes
+        OptionalPlatAttributes = 0x03,        // Optional Platform Attributes
+        ManageabilityAccessAttributes = 0x04, // Manageability Access Attributes
+    };
+
+    switch (static_cast<DCMICapParameters>(parameter))
+    {
+        case DCMICapParameters::SupportedDcmiCaps:
+        {
+            bool powerManagement = data.value("PowerManagement", 0);
+            bool oobSecondaryLan = data.value("OOBSecondaryLan", 0);
+            bool serialTMode = data.value("SerialTMODE", 0);
+            bool inBandSystemInterfaceChannel =
+                data.value("InBandSystemInterfaceChannel", 0);
+            payload.pack(reserved8, powerManagement, reserved7,
+                         inBandSystemInterfaceChannel, serialTMode,
+                         oobSecondaryLan, reserved5);
+            break;
+        }
+            // Mandatory Platform Attributes
+        case DCMICapParameters::MandatoryPlatAttributes:
+        {
+            bool selAutoRollOver = data.value("SELAutoRollOver", 0);
+            bool flushEntireSELUponRollOver =
+                data.value("FlushEntireSELUponRollOver", 0);
+            bool recordLevelSELFlushUponRollOver =
+                data.value("RecordLevelSELFlushUponRollOver", 0);
+            uint12_t numberOfSELEntries =
+                data.value("NumberOfSELEntries", 0xcac);
+            uint8_t tempMonitoringSamplingFreq =
+                data.value("TempMonitoringSamplingFreq", 0);
+            payload.pack(numberOfSELEntries, reserved1,
+                         recordLevelSELFlushUponRollOver,
+                         flushEntireSELUponRollOver, selAutoRollOver,
+                         reserved16, tempMonitoringSamplingFreq);
+            break;
+        }
+        // Optional Platform Attributes
+        case DCMICapParameters::OptionalPlatAttributes:
+        {
+            uint7_t powerMgmtDeviceTargetAddress =
+                data.value("PowerMgmtDeviceSlaveAddress", 0);
+            uint4_t bmcChannelNumber = data.value("BMCChannelNumber", 0);
+            uint4_t deviceRivision = data.value("DeviceRivision", 0);
+            payload.pack(powerMgmtDeviceTargetAddress, reserved1,
+                         deviceRivision, bmcChannelNumber);
+            break;
+        }
+        // Manageability Access Attributes
+        case DCMICapParameters::ManageabilityAccessAttributes:
+        {
+            uint8_t mandatoryPrimaryLanOOBSupport =
+                data.value("MandatoryPrimaryLanOOBSupport", 0xff);
+            uint8_t optionalSecondaryLanOOBSupport =
+                data.value("OptionalSecondaryLanOOBSupport", 0xff);
+            uint8_t optionalSerialOOBMTMODECapability =
+                data.value("OptionalSerialOOBMTMODECapability", 0xff);
+            payload.pack(mandatoryPrimaryLanOOBSupport,
+                         optionalSecondaryLanOOBSupport,
+                         optionalSerialOOBMTMODECapability);
+            break;
+        }
+        default:
+        {
+            lg2::error("Invalid input parameter");
+            return ipmi::responseInvalidFieldRequest();
+        }
+    }
+
+    return ipmi::responseSuccess(payload);
+}
+
+namespace dcmi
+{
+namespace temp_readings
+{
+
+std::tuple<bool, bool, uint8_t> readTemp(ipmi::Context::ptr& ctx,
+                                         const std::string& dbusService,
+                                         const std::string& dbusPath)
+{
+    // Read the temperature value from d-bus object. Need some conversion.
+    // As per the interface xyz.openbmc_project.Sensor.Value, the
+    // temperature is an double and in degrees C. It needs to be scaled by
+    // using the formula Value * 10^Scale. The ipmi spec has the temperature
+    // as a uint8_t, with a separate single bit for the sign.
+
+    ipmi::PropertyMap result{};
+    boost::system::error_code ec = ipmi::getAllDbusProperties(
+        ctx, dbusService, dbusPath, "xyz.openbmc_project.Sensor.Value", result);
+    if (ec.value())
+    {
+        return std::make_tuple(false, false, 0);
+    }
+    auto temperature =
+        std::visit(ipmi::VariantToDoubleVisitor(), result.at("Value"));
+    double absTemp = std::abs(temperature);
+
+    auto findFactor = result.find("Scale");
+    double factor = 0.0;
+    if (findFactor != result.end())
+    {
+        factor = std::visit(ipmi::VariantToDoubleVisitor(), findFactor->second);
+    }
+    double scale = std::pow(10, factor);
+
+    auto tempDegrees = absTemp * scale;
+    // Max absolute temp as per ipmi spec is 127.
+    constexpr auto maxTemp = 127;
+    if (tempDegrees > maxTemp)
+    {
+        tempDegrees = maxTemp;
+    }
+
+    return std::make_tuple(true, (temperature < 0),
+                           static_cast<uint8_t>(tempDegrees));
+}
+
+std::tuple<std::vector<std::tuple<uint7_t, bool, uint8_t>>, uint8_t> read(
+    ipmi::Context::ptr& ctx, const std::string& type, uint8_t instance,
+    size_t count)
+{
+    std::vector<std::tuple<uint7_t, bool, uint8_t>> response{};
+
+    auto data = parseJSONConfig(gDCMISensorsConfig);
+    static const std::vector<nlohmann::json> empty{};
+    std::vector<nlohmann::json> readings = data.value(type, empty);
+    for (const auto& j : readings)
+    {
+        // Max of 8 response data sets
+        if (response.size() == count)
+        {
+            break;
+        }
+
+        uint8_t instanceNum = j.value("instance", 0);
+        // Not in the instance range we're interested in
+        if (instanceNum < instance)
+        {
+            continue;
+        }
+
+        std::string path = j.value("dbus", "");
+        std::string service{};
+        boost::system::error_code ec = ipmi::getService(
+            ctx, "xyz.openbmc_project.Sensor.Value", path, service);
+        if (ec.value())
+        {
+            // not found on dbus
+            continue;
+        }
+
+        const auto& [ok, sign, temp] = readTemp(ctx, service, path);
+        if (ok)
+        {
+            response.emplace_back(uint7_t{temp}, sign, instanceNum);
+        }
+    }
+
+    auto totalInstances =
+        static_cast<uint8_t>(std::min(readings.size(), maxInstances));
+    return std::make_tuple(response, totalInstances);
+}
+
+} // namespace temp_readings
+} // namespace dcmi
+
+ipmi::RspType<uint8_t,                // total instances for entity id
+              uint8_t,                // number of instances in this reply
+              std::vector<            // zero or more of the following two bytes
+                  std::tuple<uint7_t, // temperature value
+                             bool,    // sign bit
+                             uint8_t  // entity instance
+                             >>>
+    getTempReadings(ipmi::Context::ptr& ctx, uint8_t sensorType,
+                    uint8_t entityId, uint8_t entityInstance,
+                    uint8_t instanceStart)
+{
+    auto it = dcmi::entityIdToName.find(entityId);
+    if (it == dcmi::entityIdToName.end())
+    {
+        lg2::error("Unknown Entity ID: {ENTITY_ID}", "ENTITY_ID", entityId);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (sensorType != dcmi::temperatureSensorType)
+    {
+        lg2::error("Invalid sensor type: {SENSOR_TYPE}", "SENSOR_TYPE",
+                   sensorType);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    uint8_t requestedRecords = (entityInstance == 0) ? dcmi::maxRecords : 1;
+
+    // Read requested instances
+    const auto& [temps, totalInstances] = dcmi::temp_readings::read(
+        ctx, it->second, instanceStart, requestedRecords);
+
+    auto numInstances = static_cast<uint8_t>(temps.size());
+
+    return ipmi::responseSuccess(totalInstances, numInstances, temps);
+}
+
+ipmi::RspType<> setDCMIConfParams(ipmi::Context::ptr& ctx, uint8_t parameter,
+                                  uint8_t setSelector,
+                                  ipmi::message::Payload& payload)
+{
+    if (setSelector)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    // Take action based on the Parameter Selector
+    switch (static_cast<dcmi::DCMIConfigParameters>(parameter))
+    {
+        case dcmi::DCMIConfigParameters::ActivateDHCP:
+        {
+            uint7_t reserved{};
+            bool activate{};
+            if (payload.unpack(activate, reserved) || !payload.fullyUnpacked())
+            {
+                return ipmi::responseReqDataLenInvalid();
+            }
+            if (reserved)
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+            std::optional<EthernetInterface::DHCPConf> dhcpEnabled =
+                dcmi::getDHCPEnabled(ctx);
+            if (!dhcpEnabled)
+            {
+                return ipmi::responseUnspecifiedError();
+            }
+            if (activate &&
+                (dhcpEnabled.value() != EthernetInterface::DHCPConf::none))
+            {
+                // When these conditions are met we have to trigger DHCP
+                // protocol restart using the latest parameter settings,
+                // but as per n/w manager design, each time when we
+                // update n/w parameters, n/w service is restarted. So
+                // we no need to take any action in this case.
+            }
+            break;
+        }
+        case dcmi::DCMIConfigParameters::DiscoveryConfig:
+        {
+            bool option12{};
+            uint6_t reserved1{};
+            bool randBackOff{};
+            if (payload.unpack(option12, reserved1, randBackOff) ||
+                !payload.fullyUnpacked())
+            {
+                return ipmi::responseReqDataLenInvalid();
+            }
+            // Systemd-networkd doesn't support Random Back off
+            if (reserved1 || randBackOff)
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+            dcmi::setDHCPOption(ctx, dcmi::dhcpOpt12Enabled, option12);
+            break;
+        }
+        // Systemd-networkd doesn't allow to configure DHCP timigs
+        case dcmi::DCMIConfigParameters::DHCPTiming1:
+        case dcmi::DCMIConfigParameters::DHCPTiming2:
+        case dcmi::DCMIConfigParameters::DHCPTiming3:
+        default:
+            return ipmi::responseInvalidFieldRequest();
+    }
+    return ipmi::responseSuccess();
+}
+
+ipmi::RspType<ipmi::message::Payload> getDCMIConfParams(
+    ipmi::Context::ptr& ctx, uint8_t parameter, uint8_t setSelector)
+{
+    if (setSelector)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    ipmi::message::Payload payload;
+    payload.pack(dcmi::specMajorVersion, dcmi::specMinorVersion,
+                 dcmi::configParameterRevision);
+
+    // Take action based on the Parameter Selector
+    switch (static_cast<dcmi::DCMIConfigParameters>(parameter))
+    {
+        case dcmi::DCMIConfigParameters::ActivateDHCP:
+            payload.pack(dcmi::activateDhcpReply);
+            break;
+        case dcmi::DCMIConfigParameters::DiscoveryConfig:
+        {
+            uint8_t discovery{};
+            std::optional<bool> enabled =
+                dcmi::getDHCPOption(ctx, dcmi::dhcpOpt12Enabled);
+            if (!enabled.has_value())
+            {
+                return ipmi::responseUnspecifiedError();
+            }
+            if (enabled.value())
+            {
+                discovery = dcmi::option12Mask;
+            }
+            payload.pack(discovery);
+            break;
+        }
+        // Get below values from Systemd-networkd source code
+        case dcmi::DCMIConfigParameters::DHCPTiming1:
+            payload.pack(dcmi::dhcpTiming1);
+            break;
+        case dcmi::DCMIConfigParameters::DHCPTiming2:
+            payload.pack(dcmi::dhcpTiming2);
+            break;
+        case dcmi::DCMIConfigParameters::DHCPTiming3:
+            payload.pack(dcmi::dhcpTiming3);
+            break;
+        default:
+            return ipmi::responseInvalidFieldRequest();
+    }
+
+    return ipmi::responseSuccess(payload);
+}
+
+static std::optional<uint16_t> readPower(ipmi::Context::ptr& ctx)
+{
+    std::ifstream sensorFile(POWER_READING_SENSOR);
+    std::string objectPath;
+    if (!sensorFile.is_open())
+    {
+        lg2::error(
+            "Power reading configuration file not found: {POWER_SENSOR_FILE}",
+            "POWER_SENSOR_FILE", std::string_view{POWER_READING_SENSOR});
+        return std::nullopt;
+    }
+
+    auto data = nlohmann::json::parse(sensorFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        lg2::error("Error in parsing configuration file: {POWER_SENSOR_FILE}",
+                   "POWER_SENSOR_FILE", std::string_view{POWER_READING_SENSOR});
+        return std::nullopt;
+    }
+
+    objectPath = data.value("path", "");
+    if (objectPath.empty())
+    {
+        lg2::error(
+            "Power sensor D-Bus object path is empty: {POWER_SENSOR_FILE}",
+            "POWER_SENSOR_FILE", std::string_view{POWER_READING_SENSOR});
+        return std::nullopt;
+    }
+
+    // Return default value if failed to read from D-Bus object
+    std::string service{};
+    boost::system::error_code ec =
+        ipmi::getService(ctx, dcmi::sensorValueIntf, objectPath, service);
+    if (ec.value())
+    {
+        lg2::error("Failed to fetch service for D-Bus object, "
+                   "object path: {OBJECT_PATH}, interface: {INTERFACE}",
+                   "OBJECT_PATH", objectPath, "INTERFACE",
+                   dcmi::sensorValueIntf);
+        return std::nullopt;
+    }
+
+    // Read the sensor value and scale properties
+    double value{};
+    ec = ipmi::getDbusProperty(ctx, service, objectPath, dcmi::sensorValueIntf,
+                               dcmi::sensorValueProp, value);
+    if (ec.value())
+    {
+        lg2::error("Failed to read power value from D-Bus object, "
+                   "object path: {OBJECT_PATH}, interface: {INTERFACE}",
+                   "OBJECT_PATH", objectPath, "INTERFACE",
+                   dcmi::sensorValueIntf);
+        return std::nullopt;
+    }
+    auto power = static_cast<uint16_t>(value);
+    return power;
+}
+
+ipmi::RspType<uint16_t, // current power
+              uint16_t, // minimum power
+              uint16_t, // maximum power
+              uint16_t, // average power
+              uint32_t, // timestamp
+              uint32_t, // sample period ms
+              uint6_t,  // reserved
+              bool,     // power measurement active
+              bool      // reserved
+              >
+    getPowerReading(ipmi::Context::ptr& ctx, uint8_t mode, uint8_t attributes,
+                    uint8_t reserved)
+{
+    if (!dcmi::isDCMIPowerMgmtSupported())
+    {
+        lg2::error("DCMI Power management is unsupported!");
+        return ipmi::responseInvalidCommand();
+    }
+    if (reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    enum class PowerMode : uint8_t
+    {
+        SystemPowerStatistics = 1,
+        EnhancedSystemPowerStatistics = 2,
+    };
+
+    if (static_cast<PowerMode>(mode) != PowerMode::SystemPowerStatistics)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if (attributes)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    std::optional<uint16_t> powerResp = readPower(ctx);
+    if (!powerResp)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    auto& power = powerResp.value();
+
+    // TODO: openbmc/openbmc#2819
+    // Minimum, Maximum, Average power, TimeFrame, TimeStamp,
+    // PowerReadingState readings need to be populated
+    // after Telemetry changes.
+    constexpr uint32_t samplePeriod = 1;
+    constexpr uint6_t reserved1 = 0;
+    constexpr bool measurementActive = true;
+    constexpr bool reserved2 = false;
+    auto timestamp = static_cast<uint32_t>(time(nullptr));
+    return ipmi::responseSuccess(power, power, power, power, timestamp,
+                                 samplePeriod, reserved1, measurementActive,
+                                 reserved2);
+}
+
+namespace dcmi
+{
+namespace sensor_info
+{
+
+std::tuple<std::vector<uint16_t>, uint8_t> read(
+    const std::string& type, uint8_t instance, const nlohmann::json& config,
+    uint8_t count)
+{
+    std::vector<uint16_t> responses{};
+
+    static const std::vector<nlohmann::json> empty{};
+    std::vector<nlohmann::json> readings = config.value(type, empty);
+    uint8_t totalInstances = std::min(readings.size(), maxInstances);
+    for (const auto& reading : readings)
+    {
+        // limit to requested count
+        if (responses.size() == count)
+        {
+            break;
+        }
+
+        uint8_t instanceNum = reading.value("instance", 0);
+        // Not in the instance range we're interested in
+        if (instanceNum < instance)
+        {
+            continue;
+        }
+
+        uint16_t recordId = reading.value("record_id", 0);
+        responses.emplace_back(recordId);
+    }
+
+    return std::make_tuple(responses, totalInstances);
+}
+
+} // namespace sensor_info
+} // namespace dcmi
+
+ipmi::RspType<uint8_t,              // total available instances
+              uint8_t,              // number of records in this response
+              std::vector<uint16_t> // records
+              >
+    getSensorInfo(uint8_t sensorType, uint8_t entityId, uint8_t entityInstance,
+                  uint8_t instanceStart)
+{
+    auto it = dcmi::entityIdToName.find(entityId);
+    if (it == dcmi::entityIdToName.end())
+    {
+        lg2::error("Unknown Entity ID: {ENTITY_ID}", "ENTITY_ID", entityId);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (sensorType != dcmi::temperatureSensorType)
+    {
+        lg2::error("Invalid sensor type: {SENSOR_TYPE}", "SENSOR_TYPE",
+                   sensorType);
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    nlohmann::json config = dcmi::parseJSONConfig(dcmi::gDCMISensorsConfig);
+
+    uint8_t requestedRecords = (entityInstance == 0) ? dcmi::maxRecords : 1;
+    // Read requested instances
+    const auto& [sensors, totalInstances] = dcmi::sensor_info::read(
+        it->second, instanceStart, config, requestedRecords);
+    uint8_t numRecords = sensors.size();
+
+    return ipmi::responseSuccess(totalInstances, numRecords, sensors);
+}
+
+void registerNetFnDcmiFunctions()
+{
+    // <Get Power Limit>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetPowerLimit, ipmi::Privilege::User,
+                         getPowerLimit);
+
+    // <Set Power Limit>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdSetPowerLimit,
+                         ipmi::Privilege::Operator, setPowerLimit);
+
+    // <Activate/Deactivate Power Limit>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdActDeactivatePwrLimit,
+                         ipmi::Privilege::Operator, applyPowerLimit);
+
+    // <Get Asset Tag>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetAssetTag, ipmi::Privilege::User,
+                         getAssetTag);
+
+    // <Set Asset Tag>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdSetAssetTag, ipmi::Privilege::Operator,
+                         setAssetTag);
+
+    // <Get Management Controller Identifier String>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetMgmtCntlrIdString,
+                         ipmi::Privilege::User, getMgmntCtrlIdStr);
+
+    // <Set Management Controller Identifier String>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdSetMgmtCntlrIdString,
+                         ipmi::Privilege::Admin, setMgmntCtrlIdStr);
+
+    // <Get DCMI capabilities>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetDcmiCapabilitiesInfo,
+                         ipmi::Privilege::User, getDCMICapabilities);
+
+    // <Get Power Reading>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetPowerReading, ipmi::Privilege::User,
+                         getPowerReading);
+
+// The Get sensor should get the senor details dynamically when
+// FEATURE_DYNAMIC_SENSORS is enabled.
+#ifndef FEATURE_DYNAMIC_SENSORS
+    // <Get Sensor Info>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetDcmiSensorInfo,
+                         ipmi::Privilege::Operator, getSensorInfo);
+
+    // <Get Temperature Readings>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetTemperatureReadings,
+                         ipmi::Privilege::User, getTempReadings);
+#endif
+    // <Get DCMI Configuration Parameters>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdGetDcmiConfigParameters,
+                         ipmi::Privilege::User, getDCMIConfParams);
+
+    // <Set DCMI Configuration Parameters>
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                         ipmi::dcmi::cmdSetDcmiConfigParameters,
+                         ipmi::Privilege::Admin, setDCMIConfParams);
+
+    return;
+}
diff --git a/dcmihandler.hpp b/dcmihandler.hpp
new file mode 100644
index 0000000..8fa5e82
--- /dev/null
+++ b/dcmihandler.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "nlohmann/json.hpp"
+
+#include <sdbusplus/bus.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace dcmi
+{
+
+static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
+static constexpr auto assetTagIntf =
+    "xyz.openbmc_project.Inventory.Decorator.AssetTag";
+static constexpr auto assetTagProp = "AssetTag";
+static constexpr auto networkServiceName = "xyz.openbmc_project.Network";
+static constexpr auto networkConfigObj = "/xyz/openbmc_project/network/config";
+static constexpr auto networkConfigIntf =
+    "xyz.openbmc_project.Network.SystemConfiguration";
+static constexpr auto hostNameProp = "HostName";
+static constexpr auto temperatureSensorType = 0x01;
+static constexpr size_t maxInstances = 255;
+static constexpr uint8_t maxRecords = 8;
+static constexpr auto gDCMISensorsConfig =
+    "/usr/share/ipmi-providers/dcmi_sensors.json";
+static constexpr auto ethernetIntf =
+    "xyz.openbmc_project.Network.EthernetInterface";
+static constexpr auto ethernetDefaultChannelNum = 0x1;
+static constexpr auto networkRoot = "/xyz/openbmc_project/network";
+static constexpr auto dhcpIntf =
+    "xyz.openbmc_project.Network.DHCPConfiguration";
+static constexpr auto systemBusName = "org.freedesktop.systemd1";
+static constexpr auto systemPath = "/org/freedesktop/systemd1";
+static constexpr auto systemIntf = "org.freedesktop.systemd1.Manager";
+static constexpr auto gDCMICapabilitiesConfig =
+    "/usr/share/ipmi-providers/dcmi_cap.json";
+static constexpr auto gDCMIPowerMgmtCapability = "PowerManagement";
+static constexpr auto gDCMIPowerMgmtSupported = 0x1;
+static constexpr auto gMaxSELEntriesMask = 0xFFF;
+static constexpr auto gByteBitSize = 8;
+
+/** @brief Check whether DCMI power management is supported
+ *         in the DCMI Capabilities config file.
+ *
+ *  @return True if DCMI power management is supported
+ */
+bool isDCMIPowerMgmtSupported();
+
+} // namespace dcmi
diff --git a/docs/configuration.md b/docs/configuration.md
new file mode 100644
index 0000000..139f025
--- /dev/null
+++ b/docs/configuration.md
@@ -0,0 +1,58 @@
+# Configuration
+
+## Device ID Configuration
+
+There is a default dev_id.json file provided by
+meta-phosphor/common/recipes-phosphor/ipmi/phosphor-ipmi-host.bb
+
+Any target can override the default json file by providing a
+phosphor-ipmi-host.bbappend with an ODM or platform customizable configuration.
+
+For a specific example, see:
+[Witherspoon](https://github.com/openbmc/openbmc/blob/master/meta-openbmc-machines/meta-openpower/meta-ibm/meta-witherspoon/recipes-phosphor/ipmi/phosphor-ipmi-host.bbappend)
+
+The JSON format for get_device_id:
+
+    {"id": 0, "revision": 0, "addn_dev_support": 0,
+        "manuf_id": 0, "prod_id": 0, "aux": 0}
+
+Each value in this JSON object should be an integer. The file is placed in
+/usr/share/ipmi-providers/ by Yocto, and will be parsed upon the first call to
+get_device_id. The data is then cached for future use. If you change the data at
+runtime, simply restart the service to see the new data fetched by a call to
+get_device_id.
+
+## IPMI D-Bus Sensor Filtering
+
+Phosphor-ipmi-host provides a compile time option to control how IPMI sensors
+are populated. The default model is for the sensors to be culled from a set of
+JSON files. There is another model that collects the sensors to display from
+D-Bus. The D-Bus method is the default mode used by Redfish. Redfish does not
+have a fixed limit on the number of sensors that can be reported.
+
+IPMI supports a smaller number of sensors than are available via Redfish. The
+limit being the number of Sensor Data Records (SDR) supported in the IPMI
+specification. Enabling IPMI to use D-Bus may cause the number of sensors
+retrieved to exceed the number SDRs IPMI can support. Even if the number of
+sensors retrieved is within the SDR limit IPMI can support, it may be desirable
+to filter entries that are uninteresting.
+
+Meson uses the _dyanmic-sensors_ configuration option to enable retrieving the
+sensors via D-Bus. When dynamic sensors are active all of the sensors placed on
+D-Bus by a service are added to the IPMI sensor list. In the event that too many
+sensors are exposed on D-Bus, the list can be filtered by adding a list of
+services to filter to _/usr/share/ipmi-providers/sensor_filter.json_.
+
+Example filtering:
+
+```json
+{
+  "ServiceFilter": [
+    "xyz.openbmc_project.RedfishSensors1",
+    "xyz.openbmc_project.RedfishSensors2"
+  ]
+}
+```
+
+Any sensors published by the example services are blocked from being added to
+the IPMI SDR table.
diff --git a/docs/contributing.md b/docs/contributing.md
new file mode 100644
index 0000000..8be4ecf
--- /dev/null
+++ b/docs/contributing.md
@@ -0,0 +1,122 @@
+# Contributing Guidelines
+
+This document attempts to outline some basic rules to follow when contributing
+to OpenBMC's IPMI stack. It does _not_ outline coding style; we follow the
+[OpenBMC C++ style guide](https://github.com/openbmc/docs/blob/master/cpp-style-and-conventions)
+for that.
+
+## Organizing Commits
+
+A good commit does exactly one thing. We prefer many small, atomic commits to
+one large commit which makes many functional changes.
+
+- Too large: "convert foo to new API; also fix CVE 1234 in bar"
+- Too small: "move abc.h to top of include list" and "move xyz.h to bottom of
+  include list"
+- Just right: "convert foo to new API" and "convert foo from tab to space"
+
+Often, creating small commits this way results in a number of commits which are
+dependent on prior commits; Gerrit handles this situation well, so feel free to
+push commits which are based on your change still in review. However, when
+possible, your commit should stand alone on top of master - "Fix whitespace in
+bar()" does not need to depend on "refactor foo()". Said differently, ensure
+that topics which are not related to each other semantically are also not
+related to each other in Git until they are merged into master.
+
+When pushing a stack of patches (current branch is >1 commits ahead of
+origin/master), these commits will show up with that same relationship in
+gerrit. This means that each patch must be merged in order of that relationship.
+So if one of the patches in the middle needs to be changed, all the patches from
+that point on would need to be pushed to maintain the relationship. This will
+effectively rebase the unchanged patches, which would in turn trigger a new CI
+build. Ideally, changes from the entire patchset could be done all in one go to
+reduce unnecessary rebasing.
+
+When someone makes a comment on your commit in Gerrit, modify that commit and
+send it again to Gerrit. This typically involves `git rebase --interactive` or
+`git commit --amend`, for which there are many guides online. As mentioned in
+the paragraph above, when possible you should make changes to multiple patches
+in the same stack before you push, in order to minimize CI and notification
+churn from the rebase operations.
+
+Commits which include changes that can be tested by a unit test should also
+include a unit test to exercise that change, within the same commit. Unit tests
+should be clearly written - even moreso than production code, unit tests are
+meant primarily to be read by humans - and should test both good and bad
+behaviors. Refer to the
+[testing documentation](https://github.com/openbmc/phosphor-host-ipmid/blob/master/docs/testing.md)
+for help writing tests, as well as best practices.
+
+## Formatting Commit Messages
+
+Your commit message should explain:
+
+- Concisely, _what_ change are you making? e.g. "docs: convert from US to UK
+  spelling" This first line of your commit message is the subject line.
+- Comprehensively, _why_ are you making that change? In some cases, like a small
+  refactor, the why is fairly obvious. But in cases like the inclusion of a new
+  feature, you should explain why the feature is needed.
+- Concisely, _how_ did you test? This comes in the form of a "Tested:" footer in
+  your commit message and is required for all code changes in the IPMI stack. It
+  typically consists of copy-pasted ipmitool requests and responses. When
+  possible, use the high-level ipmitool commands (e.g. "ipmitool sensor read
+  0x1"). In cases where that's not possible, or when testing edge or error
+  cases, it is acceptable to use "ipmitool raw" - but an explanation of your
+  output is appreciated. If the change can be validated entirely by running unit
+  tests, say so in the "Tested:" tag.
+
+Try to include the component you are changing at the front of your subject line;
+this typically comes in the form of the class, module, handler, or directory you
+are modifying. e.g. "apphandler: refactor foo to new API"
+
+Loosely, we try to follow the 50/72 rule for commit messages - that is, the
+subject line should not exceed 50 characters and the body should not exceed 72
+characters. This is common practice in many projects which use Git.
+
+All commit messages must include a Signed-off-by line, which indicates that you
+the contributor have agreed to the Developer Certificate of Origin. This line
+must include the name you commonly use, often a given name and a family name or
+surname. (ok: A. U. Thor, Sam Samuelsson, robert a. heinlein; not ok: xXthorXx,
+Sam, RAH)
+
+## Sending Patches
+
+Like most projects in OpenBMC, we use Gerrit to review patches. Please check the
+MAINTAINERS file to determine who needs to approve your review in order for your
+change to be merged. Submitters will need to manually add their reviewers in
+Gerrit; reviewers are not currently added automatically. Maintainers may not see
+the commit if they have not been added to the review!
+
+## Pace of Review
+
+Contributors who are used to code reviews by their team internal to their own
+company, or who are not used to code reviews at all, are sometimes surprised by
+the pace of code reviews in open source projects. Try to keep in mind that those
+reviewing your patch may be contributing to OpenBMC in a volunteer or
+partial-time capacity, may be in a timezone far removed from your own, and may
+have very deep review queues already of patches which have been waiting longer
+than yours.
+
+If you feel your patch has been missed entirely, of course it's alright to email
+the maintainers (addresses available in MAINTAINERS file) - but a reasonable
+timeframe to do so is on the order of a week, not on the order of hours.
+
+Additionally, the IPMI stack has a set of policies for when and how changes can
+be approved; please check the MAINTAINERS file for the full list ("Change
+approval rules").
+
+The maintainers' job is to ensure that incoming patches are as correct and easy
+to maintain as possible. Part of the nature of open source is attrition -
+contributors can come and go easily - so maintainers tend not to put stock in
+promises such as "I will add unit tests in a later patch" or "I will be
+implementing this proposal by the end of next month." This often manifests as
+reviews which may seem harsh or exacting; please keep in mind that the community
+is trying to collaborate with you to build a patch that will benefit the project
+on its own.
+
+## Code of Conduct
+
+We enthusiastically adhere to the same
+[Code of Conduct](https://github.com/openbmc/docs/blob/master/code-of-conduct.md)
+as the rest of OpenBMC. If you have any concerns, please check that document for
+guidelines on who can help you resolve them.
diff --git a/docs/ipmi-network-format.md b/docs/ipmi-network-format.md
new file mode 100644
index 0000000..140afd5
--- /dev/null
+++ b/docs/ipmi-network-format.md
@@ -0,0 +1,57 @@
+# IPMI network format
+
+On platforms running AMI BMC firmware (Habanero and Firestone at the moment),
+the 'Get/Set' System Boot Options' command has been extended to allow overrides
+to the network configuration to be specified. In Petitboot this will cause any
+existing network configuration to be overridden by the specified configuration.
+The format of each IPMI request is similar to that of the usual boot options
+request, with a slightly different payload.
+
+The start of the request is similar to a usual boot option override, but
+specifies the fields of interest differently, ie;
+
+Specify 'chassis bootdev', field 96, data1 0x00 0x08 0x61 0x80
+
+The rest of request format is defined by Petitboot as: - 4 byte cookie value
+(always 0x21 0x70 0x62 0x21) - 2 byte version value (always 0x00 0x01) - 1 byte
+hardware address size (eg. 0x06 for MAC address) - 1 byte IP address size (eg.
+0x04 for IPv4) - Hardware (MAC) address - 1 byte flags for 'ignore' and
+'method', where method = 0 is DHCP and method = 1 is Static. And for static
+configs: - IP Address - 1 byte subnet value - Gateway address
+
+Describing each field in more detail:
+
+Specify 'chassis bootdev', field 96, data1 0x00 0x08 0x61 0x80
+
+Set a special cookie that Petitboot will recognise: 0x21 0x70 0x62 0x21
+
+Specify the version (only 1 at the moment) 0x00 0x01
+
+Specify the size of the MAC address and IP address. This is used to
+differentiate between IPv4 and IPv6 addresses, or potential future support for
+Infiniband/etc. 0x06 0x04 (6-byte MAC address, IPv4 IP address)
+
+Set the hardware address of the interface you want to override, eg: 0xf4 0x52
+0x14 0xf3 0x01 0xdf
+
+Specify 'ignore' or 'static/dynamic' flags. The second byte specifies to use
+either DHCP or static IP configuration (0 for DHCP). 0x00 0x01
+
+The below fields are required if setting a static configuration:
+
+Set the IP address you want to use, eg: 0x0a 0x3d 0xa1 0x42
+
+Set the subnet mask (short notation), eg '16': 0x10
+
+Set the gateway address, eg: 0x0a 0x3d 0x2 0x1
+
+All together this should look like: 0x00 0x08 0x61 0x80 0x21 0x70 0x62 0x21 0x00
+0x01 0x06 0x04 0xf4 0x52 0x14 0xf3 0x01 0xdf 0x00 0x01 0x0a 0x3d 0xa1 0x42 0x10
+0x0a 0x3d 0x2 0x1
+
+To clear a network override, it is sufficient to clear out the request, or set a
+zero-cookie which Petitboot will reject. Eg: 0x00 0x08 0x61 0x80 0x00 0x00 0x00
+0x00
+
+You can 'Get' the override back with 0x00 0x09 0x61 0x80 0x00 which should
+return whatever is currently set.
diff --git a/docs/ipmitool-commands-cheatsheet.md b/docs/ipmitool-commands-cheatsheet.md
new file mode 100644
index 0000000..b35317f
--- /dev/null
+++ b/docs/ipmitool-commands-cheatsheet.md
@@ -0,0 +1,36 @@
+# IPMI command cheat sheet
+
+This document is intended to provide a set of IPMI commands for quick reference.
+
+Note: If the ipmitool is on the BMC then set the interface as "-I dbus" and if
+the ipmitool is outside the BMC (i.e on the network) then set the interface as
+"-I lanplus".
+
+## Network Configuration
+
+### Set the interface mode
+
+`ipmitool lan set <channel> ipsrc static`
+
+### Set the IP Address
+
+`ipmitool lan set <channel> ipaddr <x.x.x.x>`
+
+### Set the network mask
+
+`ipmitool lan set <channel> netmask <x.x.x.x>`
+
+### Set the default gateway
+
+`ipmitool lan set <channel> defgw ipaddr <x.x.x.x>`
+
+### Set the VLAN
+
+`ipmitool lan set <channel> vlan id <id>`
+
+### Delete the VLAN
+
+`ipmitool lan set <channel> vlan id off`
+
+NOTE: The user can group multiple set operations since the IPMI daemon waits for
+10 seconds after each set operation before applying the configuration.
diff --git a/docs/oem-extension-numbering.md b/docs/oem-extension-numbering.md
new file mode 100644
index 0000000..29daa3c
--- /dev/null
+++ b/docs/oem-extension-numbering.md
@@ -0,0 +1,170 @@
+# Sketch of OpenBMC OEM message formats
+
+This document describes OEM Requests to be supported using the OpenBMC OEM
+Number.
+
+## What's in the box?
+
+- Briefly recap OEM Extension layout as described in IPMI Specification.
+- Enumerate Command codes allocated for use with the OpenBMC OEM Number.
+- For each such code, describe the associated messages, including
+  representation, function, meaning, limits, and so on.
+
+## OEM Extensions, Block Transfer Transport Example
+
+This table and the next briefly recap OEM Extension messages as described in the
+[IPMI Specification](http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-second-gen-interface-spec-v2-rev1-1.html).
+To keep it both simple and concrete, only BT Tansport is described. Please
+consult that specification for the full story.
+
+### OEM Request
+
+Per section 11.1 of IPMI Spec
+
+|  Bytes  | Bits | Spec ID  | Value | Description                               |
+| :-----: | ---: | :------- | :---: | :---------------------------------------- |
+|    0    |      | Length\* |   -   | Number of bytes to follow in this request |
+|    1    |  2:7 | NetFn    | 0x2E  | OEM Request                               |
+|    1    |  0:1 | LUN      |   -   | Allow any LUN                             |
+|    2    |      | Seq\*    |   -   | Per section 11.3 of IPMI Spec             |
+|    3    |      | Cmd      |   -   | Table 3 - OpenBMC Cmd Codes               |
+|  4 ~ 6  |      | OEN      | 49871 | OEM Enterprise Number                     |
+| 2 ~ n+6 |      | Data     |   -   | n data bytes, encoding depends on Cmd     |
+
+Notes:
+
+- Length and Seq are specific to BT transport - other transports may not have
+  them.
+
+- Serialize numbers larger than 1 byte LSB first - e.g., represent OEM
+  Enterprise Number 49871 as `{0xcf, 0xc2, 0x00}`
+
+### OEM Response
+
+Per section 11.2 of IPMI Spec
+
+|  Bytes  | Bits | Spec ID  | Value | Description                                     |
+| :-----: | ---: | :------- | :---: | :---------------------------------------------- |
+|    0    |      | Length\* |   -   | Number of bytes to follow in this response      |
+|    1    |  2:7 | NetFn    | 0x2F  | OEM Response                                    |
+|    1    |  0:1 | LUN      |   -   | LUN of request to which this is a response      |
+|    2    |      | Seq\*    |   -   | Seq of request to which this is a response      |
+|    3    |      | Cmd      |   -   | Cmd code of request to which this is a response |
+|    4    |      | CC       |   -   | Completion code, Section 5.2 of IPMI Spec v2.0  |
+|  5 ~ 7  |      | OEN      | 49871 | OEM Enterprise Number                           |
+| 8 ~ n+7 |      | Data     |   -   | n data bytes, encoding depends on Cmd           |
+
+## OpenBMC OEM Cmd Codes
+
+```c
+/*
+ * This is the OpenBMC IANA OEM Number
+ */
+constexpr OemNumber obmcOemNumber = 49871;
+```
+
+These are the Command codes allocated for use with the OpenBMC OEM Number.
+
+|   Cmd   | Identifier   | Description         |
+| :-----: | :----------- | :------------------ |
+|    0    | -            | Reserved            |
+|    1    | gpioCmd      | GPIO Access         |
+|    2    | i2cCmd       | I2C Device Access   |
+|    3    | flashCmd     | Flash Device Access |
+|    4    | fanManualCmd | Manual Fan Controls |
+| 5 ~ 255 | -            | Unallocated         |
+
+## I2C Device Access (Command 2)
+
+The next subsections describe command and response messages supporting the I2C
+Device Access extension OpenBMC OEM extension (command code 2).
+
+### I2C Request Message - Overall
+
+|  Bytes  | Bits | Identifier    | Description               |
+| :-----: | :--- | :------------ | :------------------------ |
+|    0    |      | bus           | Logical I2C bus.          |
+|    1    |      | xferFlags     | Flags for all steps.      |
+|         | 7    | I2cFlagUsePec | 1 => use PEC - see note.  |
+|         | 6:0  |               | Reserved(0)               |
+| 2 ~ n-1 |      |               | Step sequence - see next. |
+
+Notes
+
+- Total length of step sequence must exactly fill request.
+
+- Intent is to handle
+  [Linux Kernel SMBus Protocol](https://www.kernel.org/doc/Documentation/i2c/smbus-protocol),
+  with com generalized to m byte sequence - e.g., at24c64 uses 2 address bytes,
+  and n bytes of received data, rather than specific operations for various
+  sizes.
+
+- Goal is to support SMBus v2 32-byte data block length limit; but easily
+  supports new 4 and 8 byte transfers added for
+  [SMBus v3](http://smbus.org/specs/SMBus_3_0_20141220.pdf).
+
+- PEC refers to SMBus Packet Error Check.
+
+- SMBus address resolution, alerts, and non-standard protocols not supported. So
+  for example, there is no way to insert a stop command within a transfer.
+
+- Depending on options, i2cdetect uses either quick write or 1 byte read;
+  default is 1-byte read for eeprom/spd memory ranges, else quick write.
+
+### I2C Request Message - Step Properties
+
+| Bytes | Bits | Identifier     | Description                                   |
+| :---: | :--: | :------------- | :-------------------------------------------- |
+|   0   |      | devAndDir      |                                               |
+|       | 7:1  | dev            | 7-bit I2C device address.                     |
+|       |  0   | isRead         | 1 = read, 0 = write.                          |
+|   1   |      | stepFlags      |                                               |
+|       |  7   | i2cFlagRecvLen | 1 if block read, else regular; see table.     |
+|       |  6   | i2cFlagNoStart | 1 to suppress I2C start.                      |
+|       | 5:0  |                | Reserved(0)                                   |
+|   2   |      | p              | Count parameter; see table                    |
+| 3:m+2 |      | wrPayload      | Nonempty iff p supplies nonzero m; see table. |
+
+#### Allowed step property combinations
+
+| is_read | RecvLen |  p  | Size | Description                             |
+| :-----: | :-----: | :-: | :--- | :-------------------------------------- |
+|    0    |    0    |  0  | 3    | Quick write 0; same as write m=0 bytes. |
+|    0    |    0    |  m  | m+3  | Consume and write next m bytes.         |
+|    0    |    1    |  -  | 3    | Reserved.                               |
+|    1    |    0    |  0  | 3    | Quick write 1; same as read n=0 bytes.  |
+|    1    |    0    |  n  | 3    | Read n bytes.                           |
+|    1    |    1    |  -  | 3    | Read count from device.                 |
+
+Notes
+
+- All other combinations are reserved.
+
+- RecvLen corresponds to Linux
+  [I2C_M_RECV_LEN message flags bit](http://elixir.free-electrons.com/linux/v4.10.17/source/include/uapi/linux/i2c.h#L78)
+
+- Transfers include byte count in SMBUS block modes, and PEC byte when selected.
+  Allows for use with SMBUS compatibility layer.
+
+- In case of write steps, wrPayload may include:
+  - register address byte or bytes;
+  - count byte if implementing SMBUS block or call operation;
+  - up to 32 bytes of logical payload; and
+  - PEC byte.
+
+### I2C Response Message
+
+| Bytes | Identifier |  Size  | Description        |
+| :---: | :--------- | :----: | :----------------- |
+| 0:n-1 | rd_data    | 0 ~ 34 | byte sequence read |
+
+Notes
+
+- Maximum logical payload is 32.
+
+- In the unlikely event a transfer specifies multiple read steps, all bytes read
+  are simply concatenated in the order read.
+
+- However, maximum reply limit is sized for the largest single read.
+
+- RecvLen case w/ PEC can return up to 34 bytes: count + payload + PEC
diff --git a/docs/testing.md b/docs/testing.md
new file mode 100644
index 0000000..9ee1dcb
--- /dev/null
+++ b/docs/testing.md
@@ -0,0 +1,473 @@
+# Running Tests
+
+## Setting Up Your Environment
+
+For the purposes of this tutorial, we'll be setting up an environment in Docker.
+Docker is handy because it's fairly portable, and won't interfere with the rest
+of your machine setup. It also offers a strong guarantee that you're testing the
+same way that others working on the project are. Finally, we can get away with
+using the same Docker image that's run by the OpenBMC continuous integration
+bot, so we have even more confidence that we're running relevant tests the way
+they'd be run upstream.
+
+### Install Docker
+
+Installation of Docker CE (Community Edition) varies by platform, and may differ
+in your organization. But the
+[Docker Docs](https://docs.docker.com/v17.12/install) are a good place to start
+looking.
+
+Check that the installation was successful by running
+`sudo docker run hello-world`.
+
+### Download OpenBMC Continuous Integration Image
+
+You'll want a couple of different repositories, so start by making a place for
+it all to go, and clone the CI scripts:
+
+```shell
+mkdir openbmc-ci-tests
+cd openbmc-ci-tests
+git clone https://github.com/openbmc/openbmc-build-scripts.git
+```
+
+## Add `phosphor-host-ipmid`
+
+We also need to put a copy of the project you want to test against here. But
+you've probably got a copy checked out already, so we're going to make a _git
+worktree_. You can read more about those by running `git help worktree`, but the
+basic idea is that it's like having a second copy of your repo - but the second
+copy is in sync with your main copy, knows about your local branches, and
+protects you from checking out the same branch in two places.
+
+Your new worktree doesn't know about any untracked files you have in your main
+worktree, so you should get in the habit of committing everything you want to
+run tests against. However, because of the implementation of
+`run-unit-test-docker.sh`, you can't run the CI with untracked changes anyways,
+so this isn't the worst thing in the world. (If you make untracked changes in
+your testing worktree, it's easy to update a commit with those.)
+
+Note the placeholders in the following steps; modify the commands to match your
+directory layout.
+
+```shell
+cd /my/dir/for/phosphor-host-ipmid
+git worktree add /path/to/openbmc-ci-tests/phosphor-host-ipmid
+```
+
+Now, if you `cd /path/to/openbmc-ci-tests`, you should see a directory
+`phosphor-host-ipmid/`, and if you enter it and run `git status` you will see
+that you're likely on a new branch named `phosphor-host-ipmid`. This is just for
+convenience, since you can't check out a branch in your worktree that's already
+checked out somewhere else; you can safely ignore or delete that branch later.
+
+However, Git won't be able to figure out how to get to your main worktree
+(`/my/dir/for/phosphor-host-ipmid`), so we'll need to mount it when we run. Open
+up `/path/to/openbmc-ci-tests/openbmc-build-scripts/run-unit-test-docker.sh` and
+find where we call `docker run`, way down at the bottom. Add an additional
+argument, remembering to escape the newline ('\'):
+
+```shell
+PHOSPHOR_IPMI_HOST_PATH="/my/dir/for/phosphor-host-ipmid"
+
+docker run --blah-blah-existing-flags \
+  -v ${PHOSPHOR_IPMI_HOST_PATH}:${PHOSPHOR_IPMI_HOST_PATH} \
+  -other \
+  -args
+```
+
+Then commit this, so you can make sure not to lose it if you update the scripts
+repo:
+
+```shell
+cd openbmc-build-scripts
+git add run-unit-test-docker.sh
+git commit -m "mount phosphor-host-ipmid"
+```
+
+NOTE: There are other ways to do this besides a worktree; other approaches trade
+the cruft of mounting extra paths to the Docker container for different cruft:
+
+You can create a local upstream:
+
+```shell
+cd openbmc-ci-tests
+mkdir phosphor-host-ipmid
+cd phosphor-host-ipmid
+git init
+cd /my/dir/for/phosphor-host-ipmid
+git remote add /path/to/openbmc-ci-tests/phosphor-host-ipmid ci
+git push ci
+```
+
+This method would require you to push your topic branch to `ci` and then
+`git checkout` the appropriate branch every time you switched topics:
+
+```shell
+cd /my/dir/for/phosphor-host-ipmid
+git commit -m "my changes to be tested"
+git push ci
+cd /path/to/openbmc-ci-tests/phosphor-host-ipmid
+git checkout topic-branch
+```
+
+You can also create a symlink from your Git workspace into `openbmc-ci-tests/`.
+This is especially not recommended, since you won't be able to work on your code
+in parallel while the tests run, and since the CI scripts are unhappy when you
+have untracked changes - which you're likely to have during active development.
+
+### Building and Running
+
+The OpenBMC CI scripts take care of the build for you, and run the test suite.
+Build and run like so:
+
+```shell
+sudo WORKSPACE=$(pwd) UNIT_TEST_PKG=phosphor-host-ipmid \
+  ./openbmc-build-scripts/run-unit-test-docker.sh
+```
+
+The first run will take a long time! But afterwards it shouldn't be so bad, as
+many parts of the Docker container are already downloaded and configured.
+
+### Reading Output
+
+Your results will appear in
+`openbmc-ci-tests/phosphor-host-ipmid/test/test-suite.log`, as well as being
+printed to `stdout`. You will also see other `.log` files generated for each
+test file, for example `sample_unittest.log`. All these `*.log` files are
+human-readable and can be examined to determine why something failed
+
+### Writing Tests
+
+Now that you've got an easy working environment for running tests, let's write
+some new ones.
+
+### Setting Up Your Environment
+
+In `/my/dir/for/phosphor-host-ipmid`, create a new branch based on `master` (or
+your current patchset). For this tutorial, let's call it `sensorhandler-tests`.
+
+```shell
+git checkout -b sensorhandler-tests master
+```
+
+This creates a new branch `sensorhandler-tests` which is based on `master`, then
+checks out that branch for you to start hacking.
+
+### Write Some Tests
+
+For this tutorial, we'll be adding some basic unit testing of the struct
+accessors for `get_sdr::GetSdrReq`, just because they're fairly simple. The text
+of the struct and accessors is recreated here:
+
+```c++
+/**
+ * Get SDR
+ */
+namespace get_sdr
+{
+
+struct GetSdrReq
+{
+    uint8_t reservation_id_lsb;
+    uint8_t reservation_id_msb;
+    uint8_t record_id_lsb;
+    uint8_t record_id_msb;
+    uint8_t offset;
+    uint8_t bytes_to_read;
+} __attribute__((packed));
+
+namespace request
+{
+
+inline uint8_t get_reservation_id(GetSdrReq* req)
+{
+    return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
+};
+
+inline uint16_t get_record_id(GetSdrReq* req)
+{
+    return (req->record_id_lsb + (req->record_id_msb << 8));
+};
+
+} // namespace request
+
+...
+} // namespace get_sdr
+```
+
+We'll create the tests in `test/sensorhandler_unittest.cpp`; go ahead and start
+that file with your editor.
+
+First, include the header you want to test, as well as the GTest header:
+
+```c++
+#include <sensorhandler.hpp>
+
+#include <gtest/gtest.h>
+```
+
+Let's plan the test cases we care about before we build any additional
+scaffolding. We've only got two functions - `get_reservation_id()` and
+`get_record_id()`. We want to test:
+
+- "Happy path" - in an ideal case, everything works correctly
+- Error handling - when given bad input, things break as expected
+- Edge cases - when given extremes (e.g. very large or very small numbers),
+  things work correctly or break as expected
+
+For `get_reservation_id()`:
+
+```c++
+TEST(SensorHandlerTest, GetSdrReq_get_reservation_id_HappyPath)
+{
+}
+
+TEST(SensorHandlerTest, GetSdrReq_get_reservation_id_NullInputDies)
+{
+}
+
+TEST(SensorHandlerTest, GetSdrReq_get_reservation_id_Uint16MaxWorksCorrectly)
+{
+}
+```
+
+For `get_record_id()`, we have pretty much the same set of tests:
+
+```c++
+TEST(SensorHandlerTest, GetSdrReq_get_record_id_HappyPath)
+{
+}
+
+TEST(SensorHandlerTest, GetSdrReq_get_record_id_NullInputDies)
+{
+}
+
+TEST(SensorHandlerTest, GetSdrReq_get_record_id_Uint16MaxWorksCorrectly)
+{
+}
+```
+
+In the case of these two methods, there's really not much else to test. Some
+types of edge cases - like overflow/underflow - are prevented by C++'s strong
+typing; other types - like passing the incorrect type - are impossible to
+insulate against because it's possible to cast anything to a `GetSdrReq*` if we
+want. Since these are particularly boring, they make a good example for a
+tutorial like this; in practice, tests you write will likely be for more
+complicated code! We'll talk more about this in the Best Practices section
+below.
+
+Let's implement the `get_reservation_id()` items first. The implementations for
+`get_record_id()` will be identical, so we won't cover them here.
+
+For the happy path, we want to make it very clear that the test value we're
+using is within range, so we express it in binary. We also want to be able to
+ensure that the MSB and LSB are being combined in the correct order, so we make
+sure that the MSB and LSB values are different (don't use `0x3333` as the
+expected ID here). Finally, we want it to be obvious to the reader if we have
+populated the `GetSdrReq` incorrectly, so we've labeled all the fields. Since we
+are only testing one operation, it's okay to use either `ASSERT_EQ` or
+`EXPECT_EQ`; more on that in the Best Practices section.
+
+```c++
+TEST(SensorHandlerTest, GetSdrReq_get_reservation_id_HappyPath)
+{
+    uint16_t expected_id = 0x1234; // Expected ID spans both bytes.
+    GetSdrReq input = {0x34,  // Reservation ID LSB
+                       0x12,  // Reservation ID MSB
+                       0x00,  // Record ID LSB
+                       0x00,  // Record ID MSB
+                       0x00,  // Offset
+                       0x00}; // Bytes to Read
+
+    uint16_t actual = get_sdr::request::get_reservation_id(&input);
+    ASSERT_EQ(actual, expected_id);
+}
+```
+
+We don't expect that our `GetSdrReq` pointer will ever be null; in this case,
+the null pointer validation is done much, much earlier. So it's okay for us to
+specify that in the unlikely case we're given a null pointer, we die. We don't
+really care what the output message is.
+
+```c++
+TEST(SensorHandlerTest, GetSdrReq_get_reservation_id_NullInputDies)
+{
+    ASSERT_DEATH(get_sdr::request::get_reservation_id(nullptr), ".*");
+}
+```
+
+Finally, while negative values are taken care of by C++'s type system, we can at
+least check that our code still works happily with `UINT16_MAX`. This test is
+similar to the happy path test, but uses an edge value instead.
+
+```c++
+TEST(SensorHandlerTest, GetSdrReq_get_reservation_id_Uint16MaxWorksCorrectly)
+{
+    uint16_t expected_id = 0xFFFF; // Expected ID spans both bytes.
+    GetSdrReq input = {0xFF,  // Reservation ID LSB
+                       0xFF,  // Reservation ID MSB
+                       0x00,  // Record ID LSB
+                       0x00,  // Record ID MSB
+                       0x00,  // Offset
+                       0x00}; // Bytes to Read
+
+    uint16_t actual = get_sdr::request::get_reservation_id(&input);
+    ASSERT_EQ(actual, expected_id);
+}
+```
+
+The `get_record_id()` tests are identical, except that they are testing the
+Record ID field. They will not be duplicated here.
+
+Finally, we'll need to add the new tests to `test/Makefile.am`. You can mimic
+other existing test setups:
+
+```make
+# Build/add sensorhandler_unittest to test suite
+sensorhandler_unittest_CPPFLAGS = \
+    -Igtest \
+    $(GTEST_CPPFLAGS) \
+    $(AM_CPPFLAGS)
+sensorhandler_unittest_CXXFLAGS = \
+    $(PTHREAD_CFLAGS) \
+    $(CODE_COVERAGE_CXXFLAGS) \
+    $(CODE_COVERAGE_CFLAGS) \
+    -DBOOST_COROUTINES_NO_DEPRECATION_WARNING
+sensorhandler_unittest_LDFLAGS = \
+    -lgtest_main \
+    -lgtest \
+    -pthread \
+    $(OESDK_TESTCASE_FLAGS) \
+    $(CODE_COVERAGE_LDFLAGS)
+sensorhandler_unittest_SOURCES = \
+    %reldir%/sensorhandler_unittest.cpp
+check_PROGRAMS += %reldir%/sensorhandler_unittest
+```
+
+### Run the New Tests
+
+Commit your test changes. Then, you'll want to checkout the
+`sensorhandler-tests` branch in your CI worktree, which will involve releasing
+it from your main worktree:
+
+```shell
+cd /my/dir/for/phosphor-host-ipmid
+git add test/sensorhandler_unittest.cpp
+git commit -s
+git checkout master   # Here you can use any branch except sensorhandler-tests
+cd /path/to/openbmc-ci-tests/phosphor-host-ipmid
+git checkout sensorhandler-tests
+```
+
+Now you can run the test suite as described earlier in the document. If you see
+a linter error when you run, you can actually apply the cleaned-up code easily:
+
+```shell
+cd ./phosphor-host-ipmid
+git diff    # Examine the proposed changes
+git add -u  # Apply the proposed changes
+git commit --amend
+```
+
+(If you will need to apply the proposed changes to multiple commits, you can do
+this with interactive rebase, which won't be described here.)
+
+### Best Practices
+
+While a good unit test can ensure your code's stability, a flaky or
+poorly-written unit test can make life harder for contributors down the road.
+Some things to remember:
+
+Include both positive (happy-path) and negative (error) testing in your
+testbench. It's not enough to know that the code works when it's supposed to; we
+also need to know that it fails gracefully when something goes wrong. Applying
+edge-case testing helps us find bugs that may take years to occur (and
+reproduce!) in the field.
+
+Keep your tests small. Avoid branching - if you feel a desire to, instead
+explore that codepath in another test. The best tests are easy to read and
+understand.
+
+When a test fails, it's useful if the test is named in such a way that you can
+tell _what it's supposed to do_ and _when_. That way you can be certain whether
+the change you made really broke it or not. A good pattern is
+`Object_NameCircumstanceResult` - for example,
+`FooFactory_OutOfBoundsNameThrowsException`. From the name, it's very clear that
+when some "name" is out of bounds, an exception should be thrown. (What "name"
+is should be clear from the context of the function in `FooFactory`.)
+
+Don't test other people's code. Make sure to limit the test assertions to the
+code under test. For example, don't test what happens if you give a bad input to
+`sdbusplus` when you're supposed to be testing `phosphor-host-ipmid`.
+
+However, don't trust other people's code, either! Try to test _how you respond_
+when a service fails unexpectedly. Rather than checking if `sdbusplus` fails on
+bad inputs, check whether you handle an `sdbusplus` failure gracefully. You can
+use GMock for this kind of testing.
+
+Think about testing when you write your business logic code. Concepts like
+dependency injection and small functions make your code more testable - you'll
+be thanking yourself later when you're writing tests.
+
+Finally, you're very likely to find bugs while writing tests, especially if it's
+for code that wasn't previously unit-tested. It's okay to check in a bugfix
+along with a test that verifies the fix worked, if you're only doing one test
+and one bugfix. If you're checking in a large suite of tests, do the bugfixes in
+independent commits which your test suite commit is based on:
+
+master -> fix Foo.Abc() -> fix Foo.Def() -> Fix Foo.Ghi() -> test Foo class
+
+### Sending for Review
+
+You can send your test update and any associated bugfixes for review to Gerrit
+as you would send any other change. For the `Tested:` field in the commit
+message, you can state that you ran the new unit tests written.
+
+### Reviewing Tests
+
+Tests are written primarily to be read. So when you review a test, you're the
+first customer of that test!
+
+## Best Practices
+
+First, all the best practices listed above for writing tests are things you
+should check for and encourage when you're reading tests.
+
+Next, you should ensure that you can tell what's going on when you read the
+test. If it's not clear to you, it's not going to be clear to someone else, and
+the test is more prone to error - ask!
+
+Finally, think about what's _not_ being tested. If there's a case you're curious
+about and it isn't covered, you should mention it to the committer.
+
+## Quickly Running At Home
+
+Now that you've got a handy setup as described earlier in this document, you can
+quickly download and run the tests yourself. Within the Gerrit change, you
+should be able to find a button that says "Download", which will give you
+commands for various types of downloads into an existing Git repo. Use
+"Checkout", for example:
+
+```shell
+cd openbmc-ci-tests/phosphor-host-ipmid
+git fetch "https://gerrit.openbmc-project.xyz/openbmc/phosphor-host-ipmid" \
+  refs/changes/43/23043/1 && git checkout FETCH_HEAD
+```
+
+This won't disturb the rest of your Git repo state, and will put your CI
+worktree into detached-HEAD mode pointing to the commit that's under review. You
+can then run your tests normally, and even make changes and push again if the
+commit was abandoned or otherwise left to rot by its author.
+
+Doing so can be handy in a number of scenarios:
+
+- Jenkins isn't responding
+- The Jenkins build is broken for a reason beyond the committer's control
+- The committer doesn't have "Ok-To-Test" permission, and you don't have
+  permission to grant it to them
+
+## Credits
+
+Thanks very much to Patrick Venture for his prior work putting together
+documentation on this topic internal to Google.
diff --git a/error-HostEvent.hpp b/error-HostEvent.hpp
new file mode 100644
index 0000000..9e6397a
--- /dev/null
+++ b/error-HostEvent.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <sdbusplus/exception.hpp>
+
+#include <cerrno>
+
+namespace sdbusplus::error::org::open_power::host
+{
+struct Event final : public sdbusplus::exception::generated_exception
+{
+    static constexpr auto errName = "org.open_power.Host.Error.Event";
+    static constexpr auto errDesc = "A host system event was received";
+    static constexpr auto errWhat =
+        "org.open_power.Host.Error.Event: A host system event was received";
+
+    const char* name() const noexcept override
+    {
+        return errName;
+    }
+    const char* description() const noexcept override
+    {
+        return errDesc;
+    }
+    const char* what() const noexcept override
+    {
+        return errWhat;
+    }
+};
+struct MaintenanceProcedure final :
+    public sdbusplus::exception::generated_exception
+{
+    static constexpr auto errName =
+        "org.open_power.Host.Error.MaintenanceProcedure";
+    static constexpr auto errDesc =
+        "A host system event with a procedure callout";
+    static constexpr auto errWhat =
+        "org.open_power.Host.Error.MaintenanceProcedure: A host system event with a procedure callout";
+
+    const char* name() const noexcept override
+    {
+        return errName;
+    }
+    const char* description() const noexcept override
+    {
+        return errDesc;
+    }
+    const char* what() const noexcept override
+    {
+        return errWhat;
+    }
+};
+} // namespace sdbusplus::error::org::open_power::host
+
+#ifndef SDBUSPP_REMOVE_DEPRECATED_NAMESPACE
+namespace sdbusplus::org::open_power::Host::Error
+{
+using Event = sdbusplus::error::org::open_power::host::Event;
+using MaintenanceProcedure =
+    sdbusplus::error::org::open_power::host::MaintenanceProcedure;
+} // namespace sdbusplus::org::open_power::Host::Error
+#endif
diff --git a/fruread.hpp b/fruread.hpp
new file mode 100644
index 0000000..a2fb650
--- /dev/null
+++ b/fruread.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <systemd/sd-bus.h>
+
+#include <array>
+#include <map>
+#include <string>
+#include <vector>
+
+struct IPMIFruData
+{
+    std::string section;
+    std::string property;
+    std::string delimiter;
+};
+
+using DbusProperty = std::string;
+using DbusPropertyVec = std::vector<std::pair<DbusProperty, IPMIFruData>>;
+
+using DbusInterface = std::string;
+using DbusInterfaceVec = std::vector<std::pair<DbusInterface, DbusPropertyVec>>;
+
+using FruInstancePath = std::string;
+
+struct FruInstance
+{
+    uint8_t entityID;
+    uint8_t entityInstance;
+    FruInstancePath path;
+    DbusInterfaceVec interfaces;
+};
+
+using FruInstanceVec = std::vector<FruInstance>;
+
+using FruId = uint32_t;
+using FruMap = std::map<FruId, FruInstanceVec>;
diff --git a/generate_whitelist.sh b/generate_whitelist.sh
new file mode 100755
index 0000000..d3d03e3
--- /dev/null
+++ b/generate_whitelist.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# Ensure some files have been passed.
+if [ -z "$*" ]; then
+    echo "Usage: $0 [allowlist_files+]" >&2
+    exit 1
+fi
+
+cat << EOF
+#include <ipmiallowlist.hpp>
+
+const std::vector<netfncmd_pair> allowlist = {
+
+EOF
+
+# Output each row of allowlist vector.
+# Concatenate all the passed files.
+# Remove comments and empty lines.
+# Sort the list [numerically].
+# Remove any duplicates.
+# Turn "a:b //<NetFn>:<Command>" -> "{ a, b }, //<NetFn>:<Command>"
+sed "s/#.*//" "$*" | sed '/^$/d' | sort -n | uniq | sed "s/^/    { /" | \
+    sed "s/\:\(....\)\(.*\)/ , \1 }, \2/"
+
+cat << EOF
+};
+EOF
diff --git a/generate_whitelist_create.sh b/generate_whitelist_create.sh
new file mode 100755
index 0000000..654a20a
--- /dev/null
+++ b/generate_whitelist_create.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Ensure some files have been passed.
+./generate_whitelist.sh "$*" > ipmiwhitelist.cpp
diff --git a/globalhandler.cpp b/globalhandler.cpp
new file mode 100644
index 0000000..7b64d42
--- /dev/null
+++ b/globalhandler.cpp
@@ -0,0 +1,54 @@
+#include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/State/BMC/server.hpp>
+
+#include <string>
+
+static constexpr auto bmcStateRoot = "/xyz/openbmc_project/state";
+static constexpr auto bmcStateIntf = "xyz.openbmc_project.State.BMC";
+static constexpr auto reqTransition = "RequestedBMCTransition";
+static constexpr auto match = "bmc0";
+
+using BMC = sdbusplus::server::xyz::openbmc_project::state::BMC;
+
+void registerNetFnGlobalFunctions() __attribute__((constructor));
+
+/** @brief implements cold and warm reset commands
+ *  @param - None
+ *  @returns IPMI completion code.
+ */
+ipmi::RspType<> ipmiGlobalReset(ipmi::Context::ptr ctx)
+{
+    ipmi::DbusObjectInfo bmcStateObj;
+    boost::system::error_code ec = ipmi::getDbusObject(
+        ctx, bmcStateIntf, bmcStateRoot, match, bmcStateObj);
+    if (!ec)
+    {
+        std::string service;
+        ec = ipmi::getService(ctx, bmcStateIntf, bmcStateObj.first, service);
+        if (!ec)
+        {
+            ec = ipmi::setDbusProperty(
+                ctx, service, bmcStateObj.first, bmcStateIntf, reqTransition,
+                convertForMessage(BMC::Transition::Reboot));
+        }
+    }
+    if (ec)
+    {
+        lg2::error("Exception in Global Reset: {ERROR}", "ERROR", ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+
+    // Status code.
+    return ipmi::responseSuccess();
+}
+
+void registerNetFnGlobalFunctions()
+{
+    // Cold Reset
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdColdReset, ipmi::Privilege::Admin,
+                          ipmiGlobalReset);
+    return;
+}
diff --git a/groupext.cpp b/groupext.cpp
new file mode 100644
index 0000000..f61bf1f
--- /dev/null
+++ b/groupext.cpp
@@ -0,0 +1,31 @@
+#include <ipmid/api.hpp>
+
+#include <cstdio>
+
+#define GRPEXT_GET_GROUP_CMD 0
+void registerNetFnGroupExtFunctions() __attribute__((constructor));
+
+ipmi_ret_t ipmi_groupext(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
+                         ipmi_response_t response, ipmi_data_len_t data_len,
+                         ipmi_context_t)
+{
+    // Generic return from IPMI commands.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    uint8_t* p = (uint8_t*)response;
+
+    std::printf("IPMI GROUP EXTENSIONS\n");
+
+    *data_len = 1;
+    *p = 0;
+
+    return rc;
+}
+
+void registerNetFnGroupExtFunctions()
+{
+    // <Group Extension Command>
+    ipmi_register_callback(NETFUN_GRPEXT, GRPEXT_GET_GROUP_CMD, nullptr,
+                           ipmi_groupext, PRIVILEGE_USER);
+
+    return;
+}
diff --git a/host-cmd-manager.cpp b/host-cmd-manager.cpp
new file mode 100644
index 0000000..3b3304f
--- /dev/null
+++ b/host-cmd-manager.cpp
@@ -0,0 +1,195 @@
+#include "config.h"
+
+#include "host-cmd-manager.hpp"
+
+#include "systemintfcmds.hpp"
+
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <sdbusplus/timer.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
+
+#include <chrono>
+
+namespace phosphor
+{
+namespace host
+{
+namespace command
+{
+
+constexpr auto HOST_STATE_PATH = "/xyz/openbmc_project/state/host0";
+constexpr auto HOST_STATE_INTERFACE = "xyz.openbmc_project.State.Host";
+constexpr auto HOST_TRANS_PROP = "RequestedHostTransition";
+
+// For throwing exceptions
+using namespace phosphor::logging;
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+namespace sdbusRule = sdbusplus::bus::match::rules;
+
+Manager::Manager(sdbusplus::bus_t& bus) :
+    bus(bus), timer(std::bind(&Manager::hostTimeout, this)),
+    hostTransitionMatch(
+        bus,
+        sdbusRule::propertiesChanged(HOST_STATE_PATH, HOST_STATE_INTERFACE),
+        std::bind(&Manager::clearQueueOnPowerOn, this, std::placeholders::_1))
+{
+    // Nothing to do here.
+}
+
+// Called as part of READ_MSG_DATA command
+IpmiCmdData Manager::getNextCommand()
+{
+    // Stop the timer. Don't have to Err failure doing so.
+    auto r = timer.stop();
+    if (r < 0)
+    {
+        lg2::error("Failure to STOP the timer: {ERROR}", "ERROR", strerror(-r));
+    }
+
+    if (this->workQueue.empty())
+    {
+        // Just return a heartbeat in this case.  A spurious SMS_ATN was
+        // asserted for the host (probably from a previous boot).
+        lg2::debug("Control Host work queue is empty!");
+
+        return std::make_pair(CMD_HEARTBEAT, 0x00);
+    }
+
+    // Pop the processed entry off the queue
+    auto command = this->workQueue.front();
+    this->workQueue.pop();
+
+    // IPMI command is the first element in pair
+    auto ipmiCmdData = std::get<0>(command);
+
+    // Now, call the user registered functions so that
+    // implementation specific CommandComplete signals
+    // can be sent. `true` indicating Success.
+    std::get<CallBack>(command)(ipmiCmdData, true);
+
+    // Check for another entry in the queue and kick it off
+    this->checkQueueAndAlertHost();
+
+    // Tuple of command and data
+    return ipmiCmdData;
+}
+
+// Called when initial timer goes off post sending SMS_ATN
+void Manager::hostTimeout()
+{
+    lg2::error("Host control timeout hit!");
+
+    clearQueue();
+}
+
+void Manager::clearQueue()
+{
+    // Dequeue all entries and send fail signal
+    while (!this->workQueue.empty())
+    {
+        auto command = this->workQueue.front();
+        this->workQueue.pop();
+
+        // IPMI command is the first element in pair
+        auto ipmiCmdData = std::get<0>(command);
+
+        // Call the implementation specific Command Failure.
+        // `false` indicating Failure
+        std::get<CallBack>(command)(ipmiCmdData, false);
+    }
+}
+
+// Called for alerting the host
+void Manager::checkQueueAndAlertHost()
+{
+    if (this->workQueue.size() >= 1)
+    {
+        lg2::debug("Asserting SMS Attention");
+
+        std::string HOST_IPMI_SVC("org.openbmc.HostIpmi");
+        std::string IPMI_PATH("/org/openbmc/HostIpmi/1");
+        std::string IPMI_INTERFACE("org.openbmc.HostIpmi");
+
+        // Start the timer for this transaction
+        auto time = std::chrono::duration_cast<std::chrono::microseconds>(
+            std::chrono::seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS));
+
+        auto r = timer.start(time);
+        if (r < 0)
+        {
+            lg2::error("Error starting timer for control host");
+            return;
+        }
+
+        auto method =
+            this->bus.new_method_call(HOST_IPMI_SVC.c_str(), IPMI_PATH.c_str(),
+                                      IPMI_INTERFACE.c_str(), "setAttention");
+
+        try
+        {
+            auto reply = this->bus.call(method);
+
+            lg2::debug("SMS Attention asserted");
+        }
+        catch (sdbusplus::exception_t& e)
+        {
+            lg2::error("Error when call setAttention method");
+        }
+    }
+}
+
+// Called by specific implementations that provide commands
+void Manager::execute(CommandHandler command)
+{
+    lg2::debug("Pushing cmd on to queue, command: {COMMAND}", "COMMAND",
+               std::get<0>(command).first);
+
+    this->workQueue.emplace(command);
+
+    // Alert host if this is only command in queue otherwise host will
+    // be notified of next message after processing the current one
+    if (this->workQueue.size() == 1)
+    {
+        this->checkQueueAndAlertHost();
+    }
+    else
+    {
+        lg2::info("Command in process, no attention");
+    }
+
+    return;
+}
+
+void Manager::clearQueueOnPowerOn(sdbusplus::message_t& msg)
+{
+    namespace server = sdbusplus::server::xyz::openbmc_project::state;
+
+    ::ipmi::DbusInterface interface;
+    ::ipmi::PropertyMap properties;
+
+    msg.read(interface, properties);
+
+    if (properties.find(HOST_TRANS_PROP) == properties.end())
+    {
+        return;
+    }
+
+    auto& requestedState =
+        std::get<std::string>(properties.at(HOST_TRANS_PROP));
+
+    if (server::Host::convertTransitionFromString(requestedState) ==
+        server::Host::Transition::On)
+    {
+        clearQueue();
+    }
+}
+
+} // namespace command
+} // namespace host
+} // namespace phosphor
diff --git a/host-cmd-manager.hpp b/host-cmd-manager.hpp
new file mode 100644
index 0000000..8937e43
--- /dev/null
+++ b/host-cmd-manager.hpp
@@ -0,0 +1,113 @@
+#pragma once
+
+#include <ipmid-host/cmd-utils.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/timer.hpp>
+
+#include <queue>
+#include <tuple>
+
+namespace phosphor
+{
+namespace host
+{
+namespace command
+{
+
+/** @class
+ *  @brief Manages commands that are to be sent to Host
+ */
+class Manager
+{
+  public:
+    Manager() = delete;
+    ~Manager() = default;
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = delete;
+    Manager& operator=(Manager&&) = delete;
+
+    /** @brief Constructs Manager object
+     *
+     *  @param[in] bus   - dbus handler
+     *  @param[in] event - pointer to sd_event
+     */
+    explicit Manager(sdbusplus::bus_t& bus);
+
+    /** @brief  Extracts the next entry in the queue and returns
+     *          Command and data part of it.
+     *
+     *  @detail Also calls into the registered handlers so that they can now
+     *          send the CommandComplete signal since the interface contract
+     *          is that we emit this signal once the message has been
+     *          passed to the host (which is required when calling this)
+     *
+     *          Also, if the queue has more commands, then it will alert the
+     *          host
+     */
+    IpmiCmdData getNextCommand();
+
+    /** @brief  Pushes the command onto the queue.
+     *
+     *  @detail If the queue is empty, then it alerts the Host. If not,
+     *          then it returns and the API documented above will handle
+     *          the commands in Queue.
+     *
+     *  @param[in] command - tuple of <IPMI command, data, callback>
+     */
+    void execute(CommandHandler command);
+
+  private:
+    /** @brief Check if anything in queue and alert host if so */
+    void checkQueueAndAlertHost();
+
+    /** @brief  Call back interface on message timeouts to host.
+     *
+     *  @detail When this happens, a failure message would be sent
+     *          to all the commands that are in the Queue and queue
+     *          will be purged
+     */
+    void hostTimeout();
+
+    /** @brief Clears the command queue
+     *
+     *  @detail Clears the command queue and calls all callbacks
+     *          specifying the command wasn't successful.
+     */
+    void clearQueue();
+
+    /** @brief Clears the command queue on a power on
+     *
+     *  @detail The properties changed handler for the
+     *          RequestedHostTransition property.  When this property
+     *          changes to 'On', this function will purge the command
+     *          queue.
+     *
+     *          This is done to avoid having commands that were issued
+     *          before the host powers on from getting sent to the host,
+     *          either due to race conditions around state transitions
+     *          or from a user doing something like requesting an already
+     *          powered off system to power off again and then immediately
+     *          requesting a power on.
+     *
+     *  @param[in] msg - the sdbusplus message containing the property
+     */
+    void clearQueueOnPowerOn(sdbusplus::message_t& msg);
+
+    /** @brief Reference to the dbus handler */
+    sdbusplus::bus_t& bus;
+
+    /** @brief Queue to store the requested commands */
+    std::queue<CommandHandler> workQueue{};
+
+    /** @brief Timer for commands to host */
+    sdbusplus::Timer timer;
+
+    /** @brief Match handler for the requested host state */
+    sdbusplus::bus::match_t hostTransitionMatch;
+};
+
+} // namespace command
+} // namespace host
+} // namespace phosphor
diff --git a/host-interface.cpp b/host-interface.cpp
new file mode 100644
index 0000000..bc01d65
--- /dev/null
+++ b/host-interface.cpp
@@ -0,0 +1,122 @@
+
+#include "config.h"
+
+#include "host-interface.hpp"
+
+#include "systemintfcmds.hpp"
+
+#include <ipmid-host/cmd-utils.hpp>
+#include <ipmid-host/cmd.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <functional>
+#include <memory>
+#include <optional>
+
+namespace phosphor
+{
+namespace host
+{
+namespace command
+{
+
+// When you see Base:: you know we're referencing our base class
+namespace Base = sdbusplus::server::xyz::openbmc_project::control;
+
+// IPMI OEM command.
+// https://github.com/openbmc/openbmc/issues/2082 for handling
+// Non-OEM commands that need to send SMS_ATN
+using OEMCmd = uint8_t;
+
+// Map of IPMI OEM command to its equivalent interface command.
+// This is needed when invoking the callback handler to indicate
+// the status of the executed command.
+static const std::map<OEMCmd, Host::Command> intfCommand = {
+    {CMD_HEARTBEAT, Base::Host::Command::Heartbeat},
+    {CMD_POWER, Base::Host::Command::SoftOff}};
+
+// Map of Interface command to its corresponding IPMI OEM command.
+// This is needed when pushing IPMI commands to command manager's
+// queue. The same pair will be returned when IPMI asks us
+// why a SMS_ATN was sent
+static const std::map<Host::Command, IpmiCmdData> ipmiCommand = {
+    {Base::Host::Command::Heartbeat, std::make_pair(CMD_HEARTBEAT, 0x00)},
+    {Base::Host::Command::SoftOff, std::make_pair(CMD_POWER, SOFT_OFF)}};
+
+// Called at user request
+void Host::execute(Base::Host::Command command)
+{
+    lg2::debug("Pushing cmd on to queue, control host cmd: {CONTROL_HOST_CMD}",
+               "CONTROL_HOST_CMD", convertForMessage(command));
+
+    auto cmd = std::make_tuple(
+        ipmiCommand.at(command),
+        std::bind(&Host::commandStatusHandler, this, std::placeholders::_1,
+                  std::placeholders::_2));
+
+    ipmid_send_cmd_to_host(std::move(cmd));
+}
+
+// Called into by Command Manager
+void Host::commandStatusHandler(IpmiCmdData cmd, bool status)
+{
+    // Need to convert <cmd> to the equivalent one mentioned in spec
+    auto value = status ? Result::Success : Result::Failure;
+
+    // Fire a signal
+    this->commandComplete(intfCommand.at(std::get<0>(cmd)), value);
+}
+
+Host::FirmwareCondition Host::currentFirmwareCondition() const
+{
+    // shared object used to wait for host response
+    auto hostCondition =
+        std::make_shared<std::optional<Host::FirmwareCondition>>();
+
+    // callback for command to host
+    auto hostAckCallback = [hostCondition](IpmiCmdData, bool status) {
+        auto value = status ? Host::FirmwareCondition::Running
+                            : Host::FirmwareCondition::Off;
+
+        lg2::debug("currentFirmwareCondition:hostAckCallback fired, "
+                   "control host cmd: {CONTROL_HOST_CMD}",
+                   "CONTROL_HOST_CMD", value);
+
+        *(hostCondition.get()) = value;
+        return;
+    };
+
+    auto cmd = phosphor::host::command::CommandHandler(
+        ipmiCommand.at(Base::Host::Command::Heartbeat),
+        std::move(hostAckCallback));
+
+    ipmid_send_cmd_to_host(std::move(cmd));
+
+    // Timer to ensure this function returns something within a reasonable time
+    sdbusplus::Timer hostAckTimer([hostCondition]() {
+        lg2::debug("currentFirmwareCondition: timer expired!");
+        *(hostCondition.get()) = Host::FirmwareCondition::Off;
+    });
+
+    // Wait 1 second past the ATN_ACK timeout to ensure we wait for as
+    // long as the timeout
+    hostAckTimer.start(std::chrono::seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS + 1));
+
+    auto io = getIoContext();
+
+    while (!hostCondition.get()->has_value())
+    {
+        lg2::debug("currentFirmwareCondition: waiting for host response");
+        io->run_for(std::chrono::milliseconds(100));
+    }
+    hostAckTimer.stop();
+
+    lg2::debug("currentFirmwareCondition: hostCondition is ready!");
+    return hostCondition.get()->value();
+}
+
+} // namespace command
+} // namespace host
+} // namespace phosphor
diff --git a/host-interface.hpp b/host-interface.hpp
new file mode 100644
index 0000000..52dbab1
--- /dev/null
+++ b/host-interface.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <host-cmd-manager.hpp>
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Condition/HostFirmware/server.hpp>
+#include <xyz/openbmc_project/Control/Host/server.hpp>
+namespace phosphor
+{
+namespace host
+{
+namespace command
+{
+
+/** @class Host
+ *  @brief OpenBMC control and condition host interface implementation.
+ *  @details A concrete implementation for xyz.openbmc_project.Control.Host
+ *  and xyz.openbmc_project.Condition.HostFirmware DBus API's.
+ */
+class Host :
+    public sdbusplus::server::object_t<
+        sdbusplus::server::xyz::openbmc_project::control::Host,
+        sdbusplus::server::xyz::openbmc_project::condition::HostFirmware>
+{
+  public:
+    /** @brief Constructs Host Control and Condition Interfaces
+     *
+     *  @param[in] bus     - The Dbus bus object
+     *  @param[in] objPath - The Dbus object path
+     */
+    Host(sdbusplus::bus_t& bus, const char* objPath) :
+        sdbusplus::server::object_t<
+            sdbusplus::server::xyz::openbmc_project::control::Host,
+            sdbusplus::server::xyz::openbmc_project::condition::HostFirmware>(
+            bus, objPath),
+        bus(bus)
+    {
+        // Nothing to do
+    }
+
+    /** @brief Send input command to host
+     *         Note that the command will be queued in a FIFO if
+     *         other commands to the host have yet to be run
+     *
+     *  @param[in] command - Input command to execute
+     */
+    void execute(Command command) override;
+
+    /** @brief Override reads to CurrentFirmwareCondition */
+    FirmwareCondition currentFirmwareCondition() const override;
+
+  private:
+    /** @brief sdbusplus DBus bus connection. */
+    sdbusplus::bus_t& bus;
+
+    /** @brief  Callback function to be invoked by command manager
+     *
+     *  @detail Conveys the status of the last Host bound command.
+     *          Depending on the status,  a CommandComplete or
+     *          CommandFailure signal would be sent
+     *
+     *  @param[in] cmd    - IPMI command and data sent to Host
+     *  @param[in] status - Success or Failure
+     */
+    void commandStatusHandler(IpmiCmdData cmd, bool status);
+};
+
+} // namespace command
+} // namespace host
+} // namespace phosphor
diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
new file mode 100644
index 0000000..9dd1eb1
--- /dev/null
+++ b/host-ipmid-whitelist.conf
@@ -0,0 +1,51 @@
+#<NetFn>:<Command
+0x00:0x00    //<Chassis>:<Chassis Capabiliti>
+0x00:0x01    //<Chassis>:<Get Chassis Status>
+0x00:0x02    //<Chassis>:<Chassis Control>
+0x00:0x05    //<Chassis>:<Set Chassis Capabilities>
+0x00:0x06    //<Chassis>:<Set Power Restore Policy>
+0x00:0x08    //<Chassis>:<Set System Boot Options>
+0x00:0x09    //<Chassis>:<Get System Boot Options>
+0x00:0x0F    //<Chassis>:<Get POH Counter Command>
+0x04:0x02    //<Sensor/Event>:<Platform event>
+0x04:0x2D    //<Sensor/Event>:<Get Sensor Reading>
+0x04:0x2F    //<Sensor/Event>:<Get Sensor Type>
+0x04:0x30    //<Sensor/Event>:<Set Sensor Reading and Event Status>
+0x06:0x01    //<App>:<Get Device ID>
+0x06:0x04    //<App>:<Get Self Test Results>
+0x06:0x06    //<App>:<Set ACPI Power State>
+0x06:0x07    //<App>:<Get ACPI Power State>
+0x06:0x08    //<App>:<Get Device GUID>
+0x06:0x22    //<App>:<Reset Watchdog Timer>
+0x06:0x24    //<App>:<Set Watchdog Timer>
+0x06:0x25    //<App>:<Get Watchdog Timer>
+0x06:0x2E    //<App>:<Set BMC Global Enables>
+0x06:0x2F    //<App>:<Get BMC Global Enables>
+0x06:0x31    //<App>:<Get Message Flags>
+0x06:0x35    //<App>:<Read Event Message Buffer>
+0x06:0x36    //<App>:<Get BT Interface Capabilities>
+0x06:0x37    //<App>:<Get System GUID>
+0x06:0x42    //<App>:<Get Channel Info Command>
+0x06:0x4D    //<App>:<Get User Payload Access>
+0x06:0x4E    //<App>:<Get Channel Payload Support>
+0x06:0x4F    //<App>:<Get Channel Payload Version>
+0x06:0x54    //<App>:<Get Channel Cipher Suites>
+0x0A:0x10    //<Storage>:<Get FRU Inventory Area Info>
+0x0A:0x11    //<Storage>:<Read FRU Data>
+0x0A:0x20    //<Storage>:<Get SDR Repository Info>
+0x0A:0x22    //<Storage>:<Reserve SDR Repository>
+0x0A:0x23    //<Storage>:<Get SDR>
+0x0A:0x40    //<Storage>:<Get SEL Info>
+0x0A:0x42    //<Storage>:<Reserve SEL>
+0x0A:0x44    //<Storage>:<Add SEL Entry>
+0x0A:0x48    //<Storage>:<Get SEL Time>
+0x0A:0x49    //<Storage>:<Set SEL Time>
+0x0A:0x5C    //<Storage>:<Get SEL Time UTC Offset>
+0x0C:0x02    //<Transport>:<Get LAN Configuration Parameters>
+0x2C:0x00    //<Group Extension>:<Group Extension Command>
+0x2C:0x01    //<Group Extension>:<Get DCMI Capabilities>
+0x2C:0x02    //<Group Extension>:<Get Power Reading>
+0x2C:0x03    //<Group Extension>:<Get Power Limit>
+0x2C:0x06    //<Group Extension>:<Get Asset Tag>
+0x2C:0x07    //<Group Extension>:<Get Sensor Info>
+0x2C:0x10    //<Group Extension>:<Get Temperature Readings>
diff --git a/include/dbus-sdr/sdrutils.hpp b/include/dbus-sdr/sdrutils.hpp
new file mode 100644
index 0000000..b52351d
--- /dev/null
+++ b/include/dbus-sdr/sdrutils.hpp
@@ -0,0 +1,363 @@
+/*
+// Copyright (c) 2018 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 <boost/algorithm/string.hpp>
+#include <boost/bimap.hpp>
+#include <boost/container/flat_map.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <cstdio>
+#include <cstring>
+#include <exception>
+#include <filesystem>
+#include <map>
+#include <optional>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#pragma once
+
+static constexpr bool debug = false;
+
+struct CmpStrVersion
+{
+    bool operator()(std::string a, std::string b) const
+    {
+        return strverscmp(a.c_str(), b.c_str()) < 0;
+    }
+};
+
+using SensorSubTree = boost::container::flat_map<
+    std::string,
+    boost::container::flat_map<std::string, std::vector<std::string>>,
+    CmpStrVersion>;
+
+using SensorNumMap = boost::bimap<int, std::string>;
+
+static constexpr uint16_t maxSensorsPerLUN = 255;
+static constexpr uint16_t maxIPMISensors = (maxSensorsPerLUN * 3);
+static constexpr uint16_t lun1Sensor0 = 0x100;
+static constexpr uint16_t lun3Sensor0 = 0x300;
+static constexpr uint16_t invalidSensorNumber = 0xFFFF;
+static constexpr uint8_t reservedSensorNumber = 0xFF;
+
+namespace details
+{
+// Enable/disable the logging of stats instrumentation
+static constexpr bool enableInstrumentation = false;
+
+class IPMIStatsEntry
+{
+  private:
+    int numReadings = 0;
+    int numMissings = 0;
+    int numStreakRead = 0;
+    int numStreakMiss = 0;
+    double minValue = 0.0;
+    double maxValue = 0.0;
+    std::string sensorName;
+
+  public:
+    const std::string& getName(void) const
+    {
+        return sensorName;
+    }
+
+    void updateName(std::string_view name)
+    {
+        sensorName = name;
+    }
+
+    // Returns true if this is the first successful reading
+    // This is so the caller can log the coefficients used
+    bool updateReading(double reading, int raw)
+    {
+        if constexpr (!enableInstrumentation)
+        {
+            return false;
+        }
+
+        bool first = ((numReadings == 0) && (numMissings == 0));
+
+        // Sensors can use "nan" to indicate unavailable reading
+        if (!(std::isfinite(reading)))
+        {
+            // Only show this if beginning a new streak
+            if (numStreakMiss == 0)
+            {
+                std::cerr << "IPMI sensor " << sensorName
+                          << ": Missing reading, byte=" << raw
+                          << ", Reading counts good=" << numReadings
+                          << " miss=" << numMissings
+                          << ", Prior good streak=" << numStreakRead << "\n";
+            }
+
+            numStreakRead = 0;
+            ++numMissings;
+            ++numStreakMiss;
+
+            return first;
+        }
+
+        // Only show this if beginning a new streak and not the first time
+        if ((numStreakRead == 0) && (numReadings != 0))
+        {
+            std::cerr << "IPMI sensor " << sensorName
+                      << ": Recovered reading, value=" << reading << " byte="
+                      << raw << ", Reading counts good=" << numReadings
+                      << " miss=" << numMissings
+                      << ", Prior miss streak=" << numStreakMiss << "\n";
+        }
+
+        // Initialize min/max if the first successful reading
+        if (numReadings == 0)
+        {
+            std::cerr << "IPMI sensor " << sensorName
+                      << ": First reading, value=" << reading << " byte=" << raw
+                      << "\n";
+
+            minValue = reading;
+            maxValue = reading;
+        }
+
+        numStreakMiss = 0;
+        ++numReadings;
+        ++numStreakRead;
+
+        // Only provide subsequent output if new min/max established
+        if (reading < minValue)
+        {
+            std::cerr << "IPMI sensor " << sensorName
+                      << ": Lowest reading, value=" << reading
+                      << " byte=" << raw << "\n";
+
+            minValue = reading;
+        }
+
+        if (reading > maxValue)
+        {
+            std::cerr << "IPMI sensor " << sensorName
+                      << ": Highest reading, value=" << reading
+                      << " byte=" << raw << "\n";
+
+            maxValue = reading;
+        }
+
+        return first;
+    }
+};
+
+class IPMIStatsTable
+{
+  private:
+    std::vector<IPMIStatsEntry> entries;
+
+  private:
+    void padEntries(size_t index)
+    {
+        char hexbuf[16];
+
+        // Pad vector until entries[index] becomes a valid index
+        while (entries.size() <= index)
+        {
+            // As name not known yet, use human-readable hex as name
+            IPMIStatsEntry newEntry;
+            sprintf(hexbuf, "0x%02zX", entries.size());
+            newEntry.updateName(hexbuf);
+
+            entries.push_back(std::move(newEntry));
+        }
+    }
+
+  public:
+    void wipeTable(void)
+    {
+        entries.clear();
+    }
+
+    const std::string& getName(size_t index)
+    {
+        padEntries(index);
+        return entries[index].getName();
+    }
+
+    void updateName(size_t index, std::string_view name)
+    {
+        padEntries(index);
+        entries[index].updateName(name);
+    }
+
+    bool updateReading(size_t index, double reading, int raw)
+    {
+        padEntries(index);
+        return entries[index].updateReading(reading, raw);
+    }
+};
+
+class IPMIWriteEntry
+{
+  private:
+    bool writePermission = false;
+
+  public:
+    bool getWritePermission(void) const
+    {
+        return writePermission;
+    }
+
+    void setWritePermission(bool permission)
+    {
+        writePermission = permission;
+    }
+};
+
+class IPMIWriteTable
+{
+  private:
+    std::vector<IPMIWriteEntry> entries;
+
+  private:
+    void padEntries(size_t index)
+    {
+        // Pad vector until entries[index] becomes a valid index
+        if (entries.size() <= index)
+        {
+            entries.resize(index + 1);
+        }
+    }
+
+  public:
+    void wipeTable(void)
+    {
+        entries.clear();
+    }
+
+    bool getWritePermission(size_t index)
+    {
+        padEntries(index);
+        return entries[index].getWritePermission();
+    }
+
+    void setWritePermission(size_t index, bool permission)
+    {
+        padEntries(index);
+        entries[index].setWritePermission(permission);
+    }
+};
+
+// Store information for threshold sensors and they are not used by VR
+// sensors. These objects are global singletons, used from a variety of places.
+inline IPMIStatsTable sdrStatsTable;
+inline IPMIWriteTable sdrWriteTable;
+
+/**
+ * Search ObjectMapper for sensors and update them to subtree.
+ *
+ * The function will search for sensors under either
+ * /xyz/openbmc_project/sensors or /xyz/openbmc_project/extsensors. It will
+ * optionally search VR typed sensors under /xyz/openbmc_project/vr
+ *
+ * @return the updated amount of times any of "sensors" or "extsensors" sensor
+ * paths updated successfully, previous amount if all failed. The "vr"
+ * sensor path is optional, and does not participate in the return value.
+ */
+uint16_t getSensorSubtree(std::shared_ptr<SensorSubTree>& subtree);
+
+bool getSensorNumMap(std::shared_ptr<SensorNumMap>& sensorNumMap);
+} // namespace details
+
+bool getSensorSubtree(SensorSubTree& subtree);
+
+#ifdef FEATURE_HYBRID_SENSORS
+ipmi::sensor::IdInfoMap::const_iterator findStaticSensor(
+    const std::string& path);
+#endif
+
+struct CmpStr
+{
+    bool operator()(const char* a, const char* b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
+};
+
+static constexpr size_t sensorTypeCodes = 0;
+static constexpr size_t sensorEventTypeCodes = 1;
+
+enum class SensorTypeCodes : uint8_t
+{
+    reserved = 0x00,
+    temperature = 0x01,
+    voltage = 0x02,
+    current = 0x03,
+    fan = 0x04,
+    physical_security = 0x5,
+    processor = 0x07,
+    power_unit = 0x09,
+    other = 0x0b,
+    memory = 0x0c,
+    buttons = 0x14,
+    watchdog2 = 0x23,
+    entity = 0x25,
+    oemC0 = 0xc0,
+};
+
+enum class SensorEventTypeCodes : uint8_t
+{
+    unspecified = 0x00,
+    threshold = 0x01,
+    sensorSpecified = 0x6f
+};
+
+extern boost::container::flat_map<
+    const char*, std::pair<SensorTypeCodes, SensorEventTypeCodes>, CmpStr>
+    sensorTypes;
+
+std::string getSensorTypeStringFromPath(const std::string& path);
+
+uint8_t getSensorTypeFromPath(const std::string& path);
+
+uint16_t getSensorNumberFromPath(const std::string& path);
+
+uint8_t getSensorEventTypeFromPath(const std::string& path);
+
+std::string getPathFromSensorNumber(uint16_t sensorNum);
+
+namespace ipmi
+{
+std::optional<std::map<std::string, std::vector<std::string>>>
+    getObjectInterfaces(const char* path);
+
+std::map<std::string, Value> getEntityManagerProperties(const char* path,
+                                                        const char* interface);
+
+std::optional<std::unordered_set<std::string>>& getIpmiDecoratorPaths(
+    const std::optional<ipmi::Context::ptr>& ctx);
+
+const std::string* getSensorConfigurationInterface(
+    const std::map<std::string, std::vector<std::string>>&
+        sensorInterfacesResponse);
+
+void updateIpmiFromAssociation(
+    const std::string& path,
+    const std::unordered_set<std::string>& ipmiDecoratorPaths,
+    const DbusInterfaceMap& sensorMap, uint8_t& entityId,
+    uint8_t& entityInstance);
+} // namespace ipmi
diff --git a/include/dbus-sdr/sensorcommands.hpp b/include/dbus-sdr/sensorcommands.hpp
new file mode 100644
index 0000000..9184633
--- /dev/null
+++ b/include/dbus-sdr/sensorcommands.hpp
@@ -0,0 +1,163 @@
+/*
+// Copyright (c) 2017 2018 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.
+*/
+
+#pragma once
+#include <dbus-sdr/sdrutils.hpp>
+
+#include <cstdint>
+
+#pragma pack(push, 1)
+
+struct SensorThresholdResp
+{
+    uint8_t readable;
+    uint8_t lowernc;
+    uint8_t lowercritical;
+    uint8_t lowernonrecoverable;
+    uint8_t uppernc;
+    uint8_t uppercritical;
+    uint8_t uppernonrecoverable;
+};
+
+#pragma pack(pop)
+
+enum class IPMIThresholdRespBits
+{
+    lowerNonCritical,
+    lowerCritical,
+    lowerNonRecoverable,
+    upperNonCritical,
+    upperCritical,
+    upperNonRecoverable
+};
+
+enum class IPMISensorReadingByte2 : uint8_t
+{
+    eventMessagesEnable = (1 << 7),
+    sensorScanningEnable = (1 << 6),
+    readingStateUnavailable = (1 << 5),
+};
+
+enum class IPMISensorReadingByte3 : uint8_t
+{
+    upperNonRecoverable = (1 << 5),
+    upperCritical = (1 << 4),
+    upperNonCritical = (1 << 3),
+    lowerNonRecoverable = (1 << 2),
+    lowerCritical = (1 << 1),
+    lowerNonCritical = (1 << 0),
+};
+
+enum class IPMISensorEventEnableByte2 : uint8_t
+{
+    eventMessagesEnable = (1 << 7),
+    sensorScanningEnable = (1 << 6),
+};
+
+enum class IPMISensorEventEnableThresholds : uint8_t
+{
+    nonRecoverableThreshold = (1 << 6),
+    criticalThreshold = (1 << 5),
+    nonCriticalThreshold = (1 << 4),
+    upperNonRecoverableGoingHigh = (1 << 3),
+    upperNonRecoverableGoingLow = (1 << 2),
+    upperCriticalGoingHigh = (1 << 1),
+    upperCriticalGoingLow = (1 << 0),
+    upperNonCriticalGoingHigh = (1 << 7),
+    upperNonCriticalGoingLow = (1 << 6),
+    lowerNonRecoverableGoingHigh = (1 << 5),
+    lowerNonRecoverableGoingLow = (1 << 4),
+    lowerCriticalGoingHigh = (1 << 3),
+    lowerCriticalGoingLow = (1 << 2),
+    lowerNonCriticalGoingHigh = (1 << 1),
+    lowerNonCriticalGoingLow = (1 << 0),
+};
+
+enum class IPMIGetSensorEventEnableThresholds : uint8_t
+{
+    lowerNonCriticalGoingLow = 0,
+    lowerNonCriticalGoingHigh = 1,
+    lowerCriticalGoingLow = 2,
+    lowerCriticalGoingHigh = 3,
+    lowerNonRecoverableGoingLow = 4,
+    lowerNonRecoverableGoingHigh = 5,
+    upperNonCriticalGoingLow = 6,
+    upperNonCriticalGoingHigh = 7,
+    upperCriticalGoingLow = 8,
+    upperCriticalGoingHigh = 9,
+    upperNonRecoverableGoingLow = 10,
+    upperNonRecoverableGoingHigh = 11,
+};
+
+namespace ipmi
+{
+
+uint16_t getNumberOfSensors();
+
+SensorSubTree& getSensorTree();
+
+ipmi_ret_t getSensorConnection(ipmi::Context::ptr ctx, uint8_t sensnum,
+                               std::string& connection, std::string& path,
+                               std::vector<std::string>* interfaces = nullptr);
+
+struct IPMIThresholds
+{
+    std::optional<uint8_t> warningLow;
+    std::optional<uint8_t> warningHigh;
+    std::optional<uint8_t> criticalLow;
+    std::optional<uint8_t> criticalHigh;
+};
+
+namespace sensor
+{
+/**
+ * @brief Retrieve the number of sensors that are not included in the list of
+ * sensors published via D-Bus
+ *
+ * @param[in]: ctx: the pointer to the D-Bus context
+ * @return: The number of additional sensors separate from those published
+ * dynamically on D-Bus
+ */
+size_t getOtherSensorsCount(ipmi::Context::ptr ctx);
+
+/**
+ * @brief Retrieve the record data for the sensors not published via D-Bus
+ *
+ * @param[in]: ctx: the pointer to the D-Bus context
+ * @param[in]: recordID: the integer index for the sensor to retrieve
+ * @param[out]: SDR data for the indexed sensor
+ * @return: 0: success
+ *          negative number: error condition
+ */
+int getOtherSensorsDataRecord(ipmi::Context::ptr ctx, uint16_t recordID,
+                              std::vector<uint8_t>& recordData);
+} // namespace sensor
+
+namespace dcmi
+{
+
+struct sensorInfo
+{
+    std::string objectPath;
+    uint8_t type;
+    uint16_t recordId;
+    uint8_t entityId;
+    uint8_t entityInstance;
+};
+
+} // namespace dcmi
+
+} // namespace ipmi
diff --git a/include/dbus-sdr/sensorutils.hpp b/include/dbus-sdr/sensorutils.hpp
new file mode 100644
index 0000000..51fbeaf
--- /dev/null
+++ b/include/dbus-sdr/sensorutils.hpp
@@ -0,0 +1,40 @@
+/*
+// Copyright (c) 2017 2018 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.
+*/
+#pragma once
+
+#include <algorithm>
+#include <cmath>
+#include <cstdint>
+#include <iostream>
+
+namespace ipmi
+{
+static constexpr int16_t maxInt10 = 0x1FF;
+static constexpr int16_t minInt10 = -0x200;
+static constexpr int8_t maxInt4 = 7;
+static constexpr int8_t minInt4 = -8;
+
+bool getSensorAttributes(const double max, const double min, int16_t& mValue,
+                         int8_t& rExp, int16_t& bValue, int8_t& bExp,
+                         bool& bSigned);
+
+uint8_t scaleIPMIValueFromDouble(const double value, const int16_t mValue,
+                                 const int8_t rExp, const int16_t bValue,
+                                 const int8_t bExp, const bool bSigned);
+
+uint8_t getScaledIPMIValue(const double value, const double max,
+                           const double min);
+} // namespace ipmi
diff --git a/include/dbus-sdr/storagecommands.hpp b/include/dbus-sdr/storagecommands.hpp
new file mode 100644
index 0000000..21c7613
--- /dev/null
+++ b/include/dbus-sdr/storagecommands.hpp
@@ -0,0 +1,136 @@
+/*
+// Copyright (c) 2017 2018 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.
+*/
+
+#pragma once
+#include "sensorhandler.hpp"
+
+#include <cstdint>
+
+static constexpr uint8_t ipmiSdrVersion = 0x51;
+
+namespace dynamic_sensors::ipmi::sel
+{
+static constexpr uint8_t selOperationSupport = 0x02;
+static constexpr uint8_t systemEvent = 0x02;
+static constexpr size_t systemEventSize = 3;
+static constexpr uint8_t oemTsEventFirst = 0xC0;
+static constexpr uint8_t oemTsEventLast = 0xDF;
+static constexpr size_t oemTsEventSize = 9;
+static constexpr uint8_t oemEventFirst = 0xE0;
+static constexpr uint8_t oemEventLast = 0xFF;
+static constexpr size_t oemEventSize = 13;
+static constexpr uint8_t eventMsgRev = 0x04;
+} // namespace dynamic_sensors::ipmi::sel
+
+enum class SdrRepositoryInfoOps : uint8_t
+{
+    allocCommandSupported = 0x1,
+    reserveSDRRepositoryCommandSupported = 0x2,
+    partialAddSDRSupported = 0x4,
+    deleteSDRSupported = 0x8,
+    reserved = 0x10,
+    modalLSB = 0x20,
+    modalMSB = 0x40,
+    overflow = 0x80
+};
+
+enum class GetFRUAreaAccessType : uint8_t
+{
+    byte = 0x0,
+    words = 0x1
+};
+
+enum class SensorUnits : uint8_t
+{
+    unspecified = 0x0,
+    degreesC = 0x1,
+    volts = 0x4,
+    amps = 0x5,
+    watts = 0x6,
+    joules = 0x7,
+    rpm = 0x12,
+};
+
+#pragma pack(push, 1)
+struct FRUHeader
+{
+    uint8_t commonHeaderFormat;
+    uint8_t internalOffset;
+    uint8_t chassisOffset;
+    uint8_t boardOffset;
+    uint8_t productOffset;
+    uint8_t multiRecordOffset;
+    uint8_t pad;
+    uint8_t checksum;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct Type12Record
+{
+    get_sdr::SensorDataRecordHeader header;
+    uint8_t targetAddress;
+    uint8_t channelNumber;
+    uint8_t powerStateNotification;
+    uint8_t deviceCapabilities;
+    // define reserved bytes explicitly. The uint24_t is silently expanded to
+    // uint32_t, which ruins the byte alignment required by this structure.
+    uint8_t reserved[3];
+    uint8_t entityID;
+    uint8_t entityInstance;
+    uint8_t oem;
+    uint8_t typeLengthCode;
+    char name[16];
+
+    Type12Record(uint16_t recordID, uint8_t address, uint8_t chNumber,
+                 uint8_t pwrStateNotification, uint8_t capabilities,
+                 uint8_t eid, uint8_t entityInst, uint8_t mfrDefined,
+                 const std::string& sensorname) :
+        targetAddress(address), channelNumber(chNumber),
+        powerStateNotification(pwrStateNotification),
+        deviceCapabilities(capabilities), reserved{}, entityID(eid),
+        entityInstance(entityInst), oem(mfrDefined)
+    {
+        get_sdr::header::set_record_id(recordID, &header);
+        header.sdr_version = ipmiSdrVersion;
+        header.record_type = 0x12;
+        size_t nameLen = std::min(sensorname.size(), sizeof(name));
+        header.record_length =
+            sizeof(Type12Record) - sizeof(get_sdr::SensorDataRecordHeader) -
+            sizeof(name) + nameLen;
+        typeLengthCode = 0xc0 | nameLen;
+        std::copy(sensorname.begin(), sensorname.begin() + nameLen, name);
+    }
+};
+#pragma pack(pop)
+
+namespace ipmi
+{
+namespace storage
+{
+
+constexpr const size_t type12Count = 2;
+ipmi_ret_t getFruSdrs(ipmi::Context::ptr ctx, size_t index,
+                      get_sdr::SensorDataFruRecord& resp);
+
+ipmi_ret_t getFruSdrCount(ipmi::Context::ptr ctx, size_t& count);
+
+std::vector<uint8_t> getType8SDRs(
+    ipmi::sensor::EntityInfoMap::const_iterator& entity, uint16_t recordId);
+std::vector<uint8_t> getType12SDRs(uint16_t index, uint16_t recordId);
+std::vector<uint8_t> getNMDiscoverySDR(uint16_t index, uint16_t recordId);
+} // namespace storage
+} // namespace ipmi
diff --git a/include/ipmid-host/cmd-utils.hpp b/include/ipmid-host/cmd-utils.hpp
new file mode 100644
index 0000000..6646f03
--- /dev/null
+++ b/include/ipmid-host/cmd-utils.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <unistd.h>
+
+#include <cstdint>
+#include <functional>
+#include <tuple>
+
+namespace phosphor
+{
+namespace host
+{
+namespace command
+{
+/** @detail After sending SMS_ATN to the Host, Host comes down and
+ *          asks why an 'SMS_ATN` was sent.
+ *          BMC then sends 'There is a Message to be Read` as response.
+ *          Host then comes down asks for Message and the specified
+ *          commands and data would go as data conforming to IPMI spec.
+ *
+ *          Refer: 6.13.2 Send Message Command From System Interface
+ *          in IPMI V2.0 spec.
+ */
+
+/** @brief IPMI command */
+using IPMIcmd = uint8_t;
+
+/** @brief Data associated with command */
+using Data = uint8_t;
+
+/** @brief <IPMI command, Data> to be sent as payload when Host asks for
+ *          the message that can be associated with the previous SMS_ATN
+ */
+using IpmiCmdData = std::pair<IPMIcmd, Data>;
+
+/** @detail Implementation specific callback function to be invoked
+ *          conveying the status of the executed command. Specific
+ *          implementations may then broadcast an agreed signal
+ */
+using CallBack = std::function<void(IpmiCmdData, bool)>;
+
+/** @detail Tuple encapsulating above 2 to enable using Manager by
+ *          different implementations. Users of Manager will supply
+ *          <Ipmi command, Data> along with the callback handler.
+ *          Manager will invoke the handler onveying the status of
+ *          the command.
+ */
+using CommandHandler = std::tuple<IpmiCmdData, CallBack>;
+
+} // namespace command
+} // namespace host
+} // namespace phosphor
diff --git a/include/ipmid-host/cmd.hpp b/include/ipmid-host/cmd.hpp
new file mode 100644
index 0000000..e844e8f
--- /dev/null
+++ b/include/ipmid-host/cmd.hpp
@@ -0,0 +1,9 @@
+#include <ipmid-host/cmd-utils.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <memory>
+
+// Global Host Bound Command manager
+extern void ipmid_send_cmd_to_host(phosphor::host::command::CommandHandler&&);
+extern std::unique_ptr<sdbusplus::asio::connection>&
+    ipmid_get_sdbus_plus_handler();
diff --git a/include/ipmid/api-types.hpp b/include/ipmid/api-types.hpp
new file mode 100644
index 0000000..52c68ee
--- /dev/null
+++ b/include/ipmid/api-types.hpp
@@ -0,0 +1,565 @@
+/*
+ * Copyright © 2018 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.
+ *
+ */
+#pragma once
+#include <ipmid/iana.hpp>
+
+#include <cstdint>
+#include <optional>
+#include <tuple>
+
+namespace ipmi
+{
+
+using Iana = oem::Number;
+
+using Group = uint8_t;
+constexpr Group groupPICMG = 0x00;
+constexpr Group groupDMTG = 0x01;
+constexpr Group groupSSI = 0x02;
+constexpr Group groupVSO = 0x03;
+#ifdef ARM_SBMR_SUPPORT
+constexpr Group groupSBMR = 0xAE;
+#endif
+constexpr Group groupDCMI = 0xDC;
+
+/*
+ * Set the priority as the lowest number that is necessary so
+ * it is possible that others can override it if desired.
+ * This may be linked to what level of integration the handler
+ * is being created at.
+ */
+constexpr int prioOpenBmcBase = 10;
+constexpr int prioOemBase = 20;
+constexpr int prioOdmBase = 30;
+constexpr int prioCustomBase = 40;
+constexpr int prioMax = 50;
+
+/*
+ * Channel IDs pulled from the IPMI 2.0 specification
+ */
+constexpr int channelPrimaryIpmb = 0x00;
+// 0x01-0x0B Implementation specific
+// Implementation specific channel numbers are specified
+// by a configuration file external to ipmid
+// 0x0C-0x0D reserved
+constexpr int channelCurrentIface = 0x0E; // 'Present I/F'
+constexpr int channelSystemIface = 0x0F;
+
+/*
+ * Specifies the minimum privilege level required to execute the command
+ * This means the command can be executed at a given privilege level or higher
+ * privilege level. Those commands which can be executed via system interface
+ * only should use SYSTEM_INTERFACE
+ */
+enum class Privilege : uint8_t
+{
+    None = 0x00,
+    Callback,
+    User,
+    Operator,
+    Admin,
+    Oem,
+};
+
+// IPMI Net Function number as specified by IPMI V2.0 spec.
+using NetFn = uint8_t;
+
+// IPMI Command for a Net Function number as specified by IPMI V2.0 spec.
+using Cmd = uint8_t;
+
+// ipmi function return the status code
+using Cc = uint8_t;
+
+// IPMI 2.0 and DCMI 1.5 standard commands, namespaced by NetFn
+// OEM and non-standard commands should be defined where they are used
+namespace app
+{
+// 0x00 reserved
+constexpr Cmd cmdGetDeviceId = 0x01;
+constexpr Cmd cmdColdReset = 0x02;
+constexpr Cmd cmdWarmReset = 0x03;
+constexpr Cmd cmdGetSelfTestResults = 0x04;
+constexpr Cmd cmdManufacturingTestOn = 0x05;
+constexpr Cmd cmdSetAcpiPowerState = 0x06;
+constexpr Cmd cmdGetAcpiPowerState = 0x07;
+constexpr Cmd cmdGetDeviceGuid = 0x08;
+constexpr Cmd cmdGetNetFnSupport = 0x09;
+constexpr Cmd cmdGetCmdSupport = 0x0A;
+constexpr Cmd cmdGetCmdSubFnSupport = 0x0B;
+constexpr Cmd cmdGetConfigurableCmds = 0x0C;
+constexpr Cmd cmdGetConfigurableCmdSubFns = 0x0D;
+// 0x0E-0x21 unassigned
+constexpr Cmd cmdResetWatchdogTimer = 0x22;
+// 0x23 unassigned
+constexpr Cmd cmdSetWatchdogTimer = 0x24;
+constexpr Cmd cmdGetWatchdogTimer = 0x25;
+// 0x26-0x2D unassigned
+constexpr Cmd cmdSetBmcGlobalEnables = 0x2E;
+constexpr Cmd cmdGetBmcGlobalEnables = 0x2F;
+constexpr Cmd cmdClearMessageFlags = 0x30;
+constexpr Cmd cmdGetMessageFlags = 0x31;
+constexpr Cmd cmdEnableMessageChannelRcv = 0x32;
+constexpr Cmd cmdGetMessage = 0x33;
+constexpr Cmd cmdSendMessage = 0x34;
+constexpr Cmd cmdReadEventMessageBuffer = 0x35;
+constexpr Cmd cmdGetBtIfaceCapabilities = 0x36;
+constexpr Cmd cmdGetSystemGuid = 0x37;
+constexpr Cmd cmdGetChannelAuthCapabilities = 0x38;
+constexpr Cmd cmdGetSessionChallenge = 0x39;
+constexpr Cmd cmdActivateSession = 0x3A;
+constexpr Cmd cmdSetSessionPrivilegeLevel = 0x3B;
+constexpr Cmd cmdCloseSession = 0x3C;
+constexpr Cmd cmdGetSessionInfo = 0x3D;
+// 0x3E unassigned
+constexpr Cmd cmdGetAuthCode = 0x3F;
+constexpr Cmd cmdSetChannelAccess = 0x40;
+constexpr Cmd cmdGetChannelAccess = 0x41;
+constexpr Cmd cmdGetChannelInfoCommand = 0x42;
+constexpr Cmd cmdSetUserAccessCommand = 0x43;
+constexpr Cmd cmdGetUserAccessCommand = 0x44;
+constexpr Cmd cmdSetUserName = 0x45;
+constexpr Cmd cmdGetUserNameCommand = 0x46;
+constexpr Cmd cmdSetUserPasswordCommand = 0x47;
+constexpr Cmd cmdActivatePayload = 0x48;
+constexpr Cmd cmdDeactivatePayload = 0x49;
+constexpr Cmd cmdGetPayloadActivationStatus = 0x4A;
+constexpr Cmd cmdGetPayloadInstanceInfo = 0x4B;
+constexpr Cmd cmdSetUserPayloadAccess = 0x4C;
+constexpr Cmd cmdGetUserPayloadAccess = 0x4D;
+constexpr Cmd cmdGetChannelPayloadSupport = 0x4E;
+constexpr Cmd cmdGetChannelPayloadVersion = 0x4F;
+constexpr Cmd cmdGetChannelOemPayloadInfo = 0x50;
+// 0x51 unassigned
+constexpr Cmd cmdMasterWriteRead = 0x52;
+// 0x53 unassigned
+constexpr Cmd cmdGetChannelCipherSuites = 0x54;
+constexpr Cmd cmdSuspendResumePayloadEnc = 0x55;
+constexpr Cmd cmdSetChannelSecurityKeys = 0x56;
+constexpr Cmd cmdGetSystemIfCapabilities = 0x57;
+constexpr Cmd cmdSetSystemInfoParameters = 0x58;
+constexpr Cmd cmdGetSystemInfoParameters = 0x59;
+// 0x5A-0x5F unassigned
+constexpr Cmd cmdSetCommandEnables = 0x60;
+constexpr Cmd cmdGetCommandEnables = 0x61;
+constexpr Cmd cmdSetCommandSubFnEnables = 0x62;
+constexpr Cmd cmdGetCommandSubFnEnables = 0x63;
+constexpr Cmd cmdGetOemNetFnIanaSupport = 0x64;
+// 0x65-0xff unassigned
+} // namespace app
+
+namespace chassis
+{
+constexpr Cmd cmdGetChassisCapabilities = 0x00;
+constexpr Cmd cmdGetChassisStatus = 0x01;
+constexpr Cmd cmdChassisControl = 0x02;
+constexpr Cmd cmdChassisReset = 0x03;
+constexpr Cmd cmdChassisIdentify = 0x04;
+constexpr Cmd cmdSetChassisCapabilities = 0x05;
+constexpr Cmd cmdSetPowerRestorePolicy = 0x06;
+constexpr Cmd cmdGetSystemRestartCause = 0x07;
+constexpr Cmd cmdSetSystemBootOptions = 0x08;
+constexpr Cmd cmdGetSystemBootOptions = 0x09;
+constexpr Cmd cmdSetFrontPanelButtonEnables = 0x0A;
+constexpr Cmd cmdSetPowerCycleInterval = 0x0B;
+// 0x0C-0x0E unassigned
+constexpr Cmd cmdGetPohCounter = 0x0F;
+// 0x10-0xFF unassigned
+} // namespace chassis
+
+namespace sensor_event
+{
+constexpr Cmd cmdSetEventReceiver = 0x00;
+constexpr Cmd cmdGetEventReceiver = 0x01;
+constexpr Cmd cmdPlatformEvent = 0x02;
+// 0x03-0x0F unassigned
+constexpr Cmd cmdGetPefCapabilities = 0x10;
+constexpr Cmd cmdArmPefPostponeTimer = 0x11;
+constexpr Cmd cmdSetPefConfigurationParams = 0x12;
+constexpr Cmd cmdGetPefConfigurationParams = 0x13;
+constexpr Cmd cmdSetLastProcessedEventId = 0x14;
+constexpr Cmd cmdGetLastProcessedEventId = 0x15;
+constexpr Cmd cmdAlertImmediate = 0x16;
+constexpr Cmd cmdPetAcknowledge = 0x17;
+constexpr Cmd cmdGetDeviceSdrInfo = 0x20;
+constexpr Cmd cmdGetDeviceSdr = 0x21;
+constexpr Cmd cmdReserveDeviceSdrRepository = 0x22;
+constexpr Cmd cmdGetSensorReadingFactors = 0x23;
+constexpr Cmd cmdSetSensorHysteresis = 0x24;
+constexpr Cmd cmdGetSensorHysteresis = 0x25;
+constexpr Cmd cmdSetSensorThreshold = 0x26;
+constexpr Cmd cmdGetSensorThreshold = 0x27;
+constexpr Cmd cmdSetSensorEventEnable = 0x28;
+constexpr Cmd cmdGetSensorEventEnable = 0x29;
+constexpr Cmd cmdRearmSensorEvents = 0x2A;
+constexpr Cmd cmdGetSensorEventStatus = 0x2B;
+constexpr Cmd cmdGetSensorReading = 0x2D;
+constexpr Cmd cmdSetSensorType = 0x2E;
+constexpr Cmd cmdGetSensorType = 0x2F;
+constexpr Cmd cmdSetSensorReadingAndEvtSts = 0x30;
+// 0x31-0xFF unassigned
+} // namespace sensor_event
+
+namespace storage
+{
+// 0x00-0x0F unassigned
+constexpr Cmd cmdGetFruInventoryAreaInfo = 0x10;
+constexpr Cmd cmdReadFruData = 0x11;
+constexpr Cmd cmdWriteFruData = 0x12;
+// 0x13-0x1F unassigned
+constexpr Cmd cmdGetSdrRepositoryInfo = 0x20;
+constexpr Cmd cmdGetSdrRepositoryAllocInfo = 0x21;
+constexpr Cmd cmdReserveSdrRepository = 0x22;
+constexpr Cmd cmdGetSdr = 0x23;
+constexpr Cmd cmdAddSdr = 0x24;
+constexpr Cmd cmdPartialAddSdr = 0x25;
+constexpr Cmd cmdDeleteSdr = 0x26;
+constexpr Cmd cmdClearSdrRepository = 0x27;
+constexpr Cmd cmdGetSdrRepositoryTime = 0x28;
+constexpr Cmd cmdSetSdrRepositoryTime = 0x29;
+constexpr Cmd cmdEnterSdrRepoUpdateMode = 0x2A;
+constexpr Cmd cmdExitSdrReposUpdateMode = 0x2B;
+constexpr Cmd cmdRunInitializationAgent = 0x2C;
+// 0x2D-0x3F unassigned
+constexpr Cmd cmdGetSelInfo = 0x40;
+constexpr Cmd cmdGetSelAllocationInfo = 0x41;
+constexpr Cmd cmdReserveSel = 0x42;
+constexpr Cmd cmdGetSelEntry = 0x43;
+constexpr Cmd cmdAddSelEntry = 0x44;
+constexpr Cmd cmdPartialAddSelEntry = 0x45;
+constexpr Cmd cmdDeleteSelEntry = 0x46;
+constexpr Cmd cmdClearSel = 0x47;
+constexpr Cmd cmdGetSelTime = 0x48;
+constexpr Cmd cmdSetSelTime = 0x49;
+constexpr Cmd cmdGetAuxiliaryLogStatus = 0x5A;
+constexpr Cmd cmdSetAuxiliaryLogStatus = 0x5B;
+constexpr Cmd cmdGetSelTimeUtcOffset = 0x5C;
+constexpr Cmd cmdSetSelTimeUtcOffset = 0x5D;
+// 0x5E-0xFF unassigned
+} // namespace storage
+
+namespace transport
+{
+constexpr Cmd cmdSetLanConfigParameters = 0x01;
+constexpr Cmd cmdGetLanConfigParameters = 0x02;
+constexpr Cmd cmdSuspendBmcArps = 0x03;
+constexpr Cmd cmdGetIpUdpRmcpStatistics = 0x04;
+constexpr Cmd cmdSetSerialModemConfig = 0x10;
+constexpr Cmd cmdGetSerialModemConfig = 0x11;
+constexpr Cmd cmdSetSerialModemMux = 0x12;
+constexpr Cmd cmdGetTapResponseCodes = 0x13;
+constexpr Cmd cmdSetPppUdpProxyTransmitData = 0x14;
+constexpr Cmd cmdGetPppUdpProxyTransmitData = 0x15;
+constexpr Cmd cmdSendPppUdpProxyPacket = 0x16;
+constexpr Cmd cmdGetPppUdpProxyReceiveData = 0x17;
+constexpr Cmd cmdSerialModemConnActive = 0x18;
+constexpr Cmd cmdCallback = 0x19;
+constexpr Cmd cmdSetUserCallbackOptions = 0x1A;
+constexpr Cmd cmdGetUserCallbackOptions = 0x1B;
+constexpr Cmd cmdSetSerialRoutingMux = 0x1C;
+constexpr Cmd cmdSolActivating = 0x20;
+constexpr Cmd cmdSetSolConfigParameters = 0x21;
+constexpr Cmd cmdGetSolConfigParameters = 0x22;
+constexpr Cmd cmdForwardedCommand = 0x30;
+constexpr Cmd cmdSetForwardedCommands = 0x31;
+constexpr Cmd cmdGetForwardedCommands = 0x32;
+constexpr Cmd cmdEnableForwardedCommands = 0x33;
+} // namespace transport
+
+namespace bridge
+{
+constexpr Cmd cmdGetBridgeState = 0x00;
+constexpr Cmd cmdSetBridgeState = 0x01;
+constexpr Cmd cmdGetIcmbAddress = 0x02;
+constexpr Cmd cmdSetIcmbAddress = 0x03;
+constexpr Cmd cmdSetBridgeProxyAddress = 0x04;
+constexpr Cmd cmdGetBridgeStatistics = 0x05;
+constexpr Cmd cmdGetIcmbCapabilities = 0x06;
+constexpr Cmd cmdClearBridgeStatistics = 0x08;
+constexpr Cmd cmdGetBridgeProxyAddress = 0x09;
+constexpr Cmd cmdGetIcmbConnectorInfo = 0x0A;
+constexpr Cmd cmdGetIcmbConnectionId = 0x0B;
+constexpr Cmd cmdSendIcmbConnectionId = 0x0C;
+constexpr Cmd cmdPrepareForDiscovery = 0x10;
+constexpr Cmd cmdGetAddresses = 0x11;
+constexpr Cmd cmdSetDiscovered = 0x12;
+constexpr Cmd cmdGetChassisDeviceId = 0x13;
+constexpr Cmd cmdSetChassisDeviceId = 0x14;
+constexpr Cmd cmdBridgeRequest = 0x20;
+constexpr Cmd cmdBridgeMessage = 0x21;
+// 0x22-0x2F unassigned
+constexpr Cmd cmdGetEventCount = 0x30;
+constexpr Cmd cmdSetEventDestination = 0x31;
+constexpr Cmd cmdSetEventReceptionState = 0x32;
+constexpr Cmd cmdSendIcmbEventMessage = 0x33;
+constexpr Cmd cmdGetEventDestination = 0x34;
+constexpr Cmd cmdGetEventReceptionState = 0x35;
+// 0xC0-0xFE OEM Commands
+constexpr Cmd cmdErrorReport = 0xFF;
+} // namespace bridge
+
+namespace dcmi
+{
+constexpr Cmd cmdGetDcmiCapabilitiesInfo = 0x01;
+constexpr Cmd cmdGetPowerReading = 0x02;
+constexpr Cmd cmdGetPowerLimit = 0x03;
+constexpr Cmd cmdSetPowerLimit = 0x04;
+constexpr Cmd cmdActDeactivatePwrLimit = 0x05;
+constexpr Cmd cmdGetAssetTag = 0x06;
+constexpr Cmd cmdGetDcmiSensorInfo = 0x07;
+constexpr Cmd cmdSetAssetTag = 0x08;
+constexpr Cmd cmdGetMgmtCntlrIdString = 0x09;
+constexpr Cmd cmdSetMgmtCntlrIdString = 0x0A;
+constexpr Cmd cmdSetThermalLimit = 0x0B;
+constexpr Cmd cmdGetThermalLimit = 0x0C;
+constexpr Cmd cmdGetTemperatureReadings = 0x10;
+constexpr Cmd cmdSetDcmiConfigParameters = 0x12;
+constexpr Cmd cmdGetDcmiConfigParameters = 0x13;
+} // namespace dcmi
+
+#ifdef ARM_SBMR_SUPPORT
+namespace sbmr
+{
+constexpr Cmd cmdSendBootProgressCode = 0x02;
+constexpr Cmd cmdGetBootProgressCode = 0x03;
+} // namespace sbmr
+#endif
+
+// These are the command network functions, the response
+// network functions are the function + 1. So to determine
+// the proper network function which issued the command
+// associated with a response, subtract 1.
+// Note: these will be left shifted when combined with the LUN
+constexpr NetFn netFnChassis = 0x00;
+constexpr NetFn netFnBridge = 0x02;
+constexpr NetFn netFnSensor = 0x04;
+constexpr NetFn netFnApp = 0x06;
+constexpr NetFn netFnFirmware = 0x08;
+constexpr NetFn netFnStorage = 0x0A;
+constexpr NetFn netFnTransport = 0x0C;
+// reserved 0Eh..28h
+constexpr NetFn netFnGroup = 0x2C;
+constexpr NetFn netFnOem = 0x2E;
+constexpr NetFn netFnOemOne = 0x30;
+constexpr NetFn netFnOemTwo = 0x32;
+constexpr NetFn netFnOemThree = 0x34;
+constexpr NetFn netFnOemFour = 0x36;
+constexpr NetFn netFnOemFive = 0x38;
+constexpr NetFn netFnOemSix = 0x3A;
+constexpr NetFn netFnOemSeven = 0x3C;
+constexpr NetFn netFnOemEight = 0x3E;
+
+// IPMI commands for net functions. Callbacks using this should be careful to
+// parse arguments to the sub-functions and can take advantage of the built-in
+// message handling mechanism to create custom routing
+constexpr Cmd cmdWildcard = 0xFF;
+
+// IPMI standard completion codes specified by the IPMI V2.0 spec.
+//
+// This might have been an enum class, but that would make it hard for
+// OEM- and command-specific completion codes to be added elsewhere.
+//
+// Custom completion codes can be defined in individual modules for
+// command specific errors in the 0x80-0xBE range
+//
+// Alternately, OEM completion codes are in the 0x01-0x7E range
+constexpr Cc ccSuccess = 0x00;
+constexpr Cc ccBusy = 0xC0;
+constexpr Cc ccInvalidCommand = 0xC1;
+constexpr Cc ccInvalidCommandOnLun = 0xC2;
+constexpr Cc ccTimeout = 0xC3;
+constexpr Cc ccOutOfSpace = 0xC4;
+constexpr Cc ccInvalidReservationId = 0xC5;
+constexpr Cc ccReqDataTruncated = 0xC6;
+constexpr Cc ccReqDataLenInvalid = 0xC7;
+constexpr Cc ccReqDataLenExceeded = 0xC8;
+constexpr Cc ccParmOutOfRange = 0xC9;
+constexpr Cc ccRetBytesUnavailable = 0xCA;
+constexpr Cc ccSensorInvalid = 0xCB;
+constexpr Cc ccInvalidFieldRequest = 0xCC;
+constexpr Cc ccIllegalCommand = 0xCD;
+constexpr Cc ccResponseError = 0xCE;
+constexpr Cc ccDuplicateRequest = 0xCF;
+constexpr Cc ccCmdFailSdrMode = 0xD0;
+constexpr Cc ccCmdFailFwUpdMode = 0xD1;
+constexpr Cc ccCmdFailInitAgent = 0xD2;
+constexpr Cc ccDestinationUnavailable = 0xD3;
+constexpr Cc ccInsufficientPrivilege = 0xD4;
+constexpr Cc ccCommandNotAvailable = 0xD5;
+constexpr Cc ccCommandDisabled = 0xD6;
+constexpr Cc ccUnspecifiedError = 0xFF;
+
+/* ipmi often has two return types:
+ * 1. Failure: CC is non-zero; no trailing data
+ * 2. Success: CC is zero; trailing data (usually a fixed type)
+ *
+ * using ipmi::response(cc, ...), it will automatically always pack
+ * the correct type for the response without having to explicitly type out all
+ * the parameters that the function would return.
+ *
+ * To enable this feature, you just define the ipmi function as returning an
+ * ipmi::RspType which has the optional trailing data built in, with your types
+ * defined as parameters.
+ */
+
+template <typename... RetTypes>
+using RspType = std::tuple<ipmi::Cc, std::optional<std::tuple<RetTypes...>>>;
+
+/**
+ * @brief helper function to create an IPMI response tuple
+ *
+ * IPMI handlers all return a tuple with two parts: a completion code and an
+ * optional tuple containing the rest of the data to return. This helper
+ * function makes it easier by constructing that out of an arbitrary number of
+ * arguments.
+ *
+ * @param cc - the completion code for the response
+ * @param args... - the optional list of values to return
+ *
+ * @return a standard IPMI return type (as described above)
+ */
+template <typename... Args>
+static inline auto response(ipmi::Cc cc, Args&&... args)
+{
+    return std::make_tuple(cc, std::make_optional(std::make_tuple(args...)));
+}
+static inline auto response(ipmi::Cc cc)
+{
+    return std::make_tuple(cc, std::nullopt);
+}
+
+/**
+ * @brief helper function to create an IPMI success response tuple
+ *
+ * IPMI handlers all return a tuple with two parts: a completion code and an
+ * optional tuple containing the rest of the data to return. This helper
+ * function makes it easier by constructing that out of an arbitrary number of
+ * arguments. Because it is a success response, this automatically packs
+ * the completion code, without needing to explicitly pass it in.
+ *
+ * @param args... - the optional list of values to return
+ *
+ * @return a standard IPMI return type (as described above)
+ */
+template <typename... Args>
+static inline auto responseSuccess(Args&&... args)
+{
+    return response(ipmi::ccSuccess, args...);
+}
+static inline auto responseSuccess()
+{
+    return response(ipmi::ccSuccess);
+}
+
+/* helper functions for the various standard error response types */
+static inline auto responseBusy()
+{
+    return response(ccBusy);
+}
+static inline auto responseInvalidCommand()
+{
+    return response(ccInvalidCommand);
+}
+static inline auto responseInvalidCommandOnLun()
+{
+    return response(ccInvalidCommandOnLun);
+}
+static inline auto responseTimeout()
+{
+    return response(ccTimeout);
+}
+static inline auto responseOutOfSpace()
+{
+    return response(ccOutOfSpace);
+}
+static inline auto responseInvalidReservationId()
+{
+    return response(ccInvalidReservationId);
+}
+static inline auto responseReqDataTruncated()
+{
+    return response(ccReqDataTruncated);
+}
+static inline auto responseReqDataLenInvalid()
+{
+    return response(ccReqDataLenInvalid);
+}
+static inline auto responseReqDataLenExceeded()
+{
+    return response(ccReqDataLenExceeded);
+}
+static inline auto responseParmOutOfRange()
+{
+    return response(ccParmOutOfRange);
+}
+static inline auto responseRetBytesUnavailable()
+{
+    return response(ccRetBytesUnavailable);
+}
+static inline auto responseSensorInvalid()
+{
+    return response(ccSensorInvalid);
+}
+static inline auto responseInvalidFieldRequest()
+{
+    return response(ccInvalidFieldRequest);
+}
+static inline auto responseIllegalCommand()
+{
+    return response(ccIllegalCommand);
+}
+static inline auto responseResponseError()
+{
+    return response(ccResponseError);
+}
+static inline auto responseDuplicateRequest()
+{
+    return response(ccDuplicateRequest);
+}
+static inline auto responseCmdFailSdrMode()
+{
+    return response(ccCmdFailSdrMode);
+}
+static inline auto responseCmdFailFwUpdMode()
+{
+    return response(ccCmdFailFwUpdMode);
+}
+static inline auto responseCmdFailInitAgent()
+{
+    return response(ccCmdFailInitAgent);
+}
+static inline auto responseDestinationUnavailable()
+{
+    return response(ccDestinationUnavailable);
+}
+static inline auto responseInsufficientPrivilege()
+{
+    return response(ccInsufficientPrivilege);
+}
+static inline auto responseCommandNotAvailable()
+{
+    return response(ccCommandNotAvailable);
+}
+static inline auto responseCommandDisabled()
+{
+    return response(ccCommandDisabled);
+}
+static inline auto responseUnspecifiedError()
+{
+    return response(ccUnspecifiedError);
+}
+
+} // namespace ipmi
diff --git a/include/ipmid/api.h b/include/ipmid/api.h
new file mode 100644
index 0000000..fd6fee6
--- /dev/null
+++ b/include/ipmid/api.h
@@ -0,0 +1,153 @@
+#ifndef __HOST_IPMID_IPMI_COMMON_H__
+#define __HOST_IPMID_IPMI_COMMON_H__
+
+#include <systemd/sd-bus.h>
+
+#include <cstddef>
+
+/*
+ * Specifies the minimum privilege level required to execute the command
+ * This means the command can be executed at a given privilege level or higher
+ * privilege level. Those commands which can be executed via system interface
+ * only should use SYSTEM_INTERFACE
+ */
+enum CommandPrivilege
+{
+    PRIVILEGE_CALLBACK = 0x01,
+    PRIVILEGE_USER,
+    PRIVILEGE_OPERATOR,
+    PRIVILEGE_ADMIN,
+    PRIVILEGE_OEM,
+    SYSTEM_INTERFACE = 0xFF,
+};
+
+// length of Completion Code and its ALWAYS _1_
+#define IPMI_CC_LEN 1
+
+// IPMI Net Function number as specified by IPMI V2.0 spec.
+// Example :
+// NETFUN_APP      =   (0x06 << 2),
+typedef unsigned char ipmi_netfn_t;
+
+// IPMI Command for a Net Function number as specified by IPMI V2.0 spec.
+typedef unsigned char ipmi_cmd_t;
+
+// Buffer containing data from sender of netfn and command as part of request
+typedef void* ipmi_request_t;
+
+// This is the response buffer that the provider of [netfn,cmd] will send back
+// to the caller. Provider will allocate the memory inside the handler and then
+// will do a memcpy to this response buffer and also will set the data size
+// parameter to the size of the buffer.
+// EXAMPLE :
+// unsigned char str[] = {0x00, 0x01, 0xFE, 0xFF, 0x0A, 0x01};
+// *data_len = 6;
+// memcpy(response, &str, *data_len);
+typedef void* ipmi_response_t;
+
+// This buffer contains any *user specific* data that is of interest only to the
+// plugin. For a ipmi function router, this data is opaque. At the time of
+// registering the plugin handlers, plugin may optionally allocate a memory and
+// fill in whatever needed that will be of help during the actual handling of
+// command. IPMID will just pass the netfn, cmd and also this data to plugins
+// during the command handler invocation.
+typedef void* ipmi_context_t;
+
+// Length of request / response buffer depending on whether the data is a
+// request or a response from a plugin handler.
+typedef std::size_t* ipmi_data_len_t;
+
+// Plugin function return the status code
+typedef unsigned char ipmi_ret_t;
+
+typedef enum CommandPrivilege ipmi_cmd_privilege_t;
+
+// This is the callback handler that the plugin registers with IPMID. IPMI
+// function router will then make a call to this callback handler with the
+// necessary arguments of netfn, cmd, request, response, size and context.
+typedef ipmi_ret_t (*ipmid_callback_t)(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
+                                       ipmi_response_t, ipmi_data_len_t,
+                                       ipmi_context_t);
+
+// This is the constructor function that is called into by each plugin handlers.
+// When ipmi sets up the callback handlers, a call is made to this with
+// information of netfn, cmd, callback handler pointer and context data.
+void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t, ipmi_context_t,
+                            ipmid_callback_t, ipmi_cmd_privilege_t);
+
+unsigned short reserveSel(void);
+bool checkSELReservation(unsigned short id);
+void cancelSELReservation(void);
+
+// These are the command network functions, the response
+// network functions are the function + 1. So to determine
+// the proper network function which issued the command
+// associated with a response, subtract 1.
+// Note: these are also shifted left to make room for the LUN.
+enum ipmi_net_fns
+{
+    NETFUN_CHASSIS = 0x00,
+    NETFUN_BRIDGE = 0x02,
+    NETFUN_SENSOR = 0x04,
+    NETFUN_APP = 0x06,
+    NETFUN_FIRMWARE = 0x08,
+    NETFUN_STORAGE = 0x0a,
+    NETFUN_TRANSPORT = 0x0c,
+    NETFUN_GRPEXT = 0x2c,
+    NETFUN_OEM_GROUP = 0x2e,
+    NETFUN_NONE = 0x30,
+    NETFUN_OEM = 0x32,
+    NETFUN_IBM_OEM = 0x3A
+};
+
+// Return (completion) codes from a IPMI operation as needed by IPMI V2.0 spec.
+enum ipmi_return_codes
+{
+    IPMI_CC_OK = 0x00,
+    IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT = 0x80,
+    IPMI_WDOG_CC_NOT_INIT = 0x80,
+    IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED = 0x80,
+    IPMI_CC_SYSTEM_INFO_PARAMETER_SET_READ_ONLY = 0x82,
+    IPMI_CC_BUSY = 0xC0,
+    IPMI_CC_INVALID = 0xC1,
+    IPMI_CC_TIMEOUT = 0xC3,
+    IPMI_CC_OUT_OF_SPACE = 0xC4,
+    IPMI_CC_INVALID_RESERVATION_ID = 0xC5,
+    IPMI_CC_REQ_DATA_TRUNCATED = 0xC6,
+    IPMI_CC_REQ_DATA_LEN_INVALID = 0xC7,
+    IPMI_CC_PARM_OUT_OF_RANGE = 0xC9,
+    IPMI_CC_REQUESTED_TOO_MANY_BYTES = 0xCA,
+    IPMI_CC_SENSOR_INVALID = 0xCB,
+    IPMI_CC_INVALID_FIELD_REQUEST = 0xCC,
+    IPMI_CC_ILLEGAL_COMMAND = 0xCD,
+    IPMI_CC_RESPONSE_ERROR = 0xCE,
+    IPMI_CC_INSUFFICIENT_PRIVILEGE = 0xD4,
+    IPMI_CC_UNSPECIFIED_ERROR = 0xFF,
+};
+
+// Temp solution: To detect the request source channel.
+// There is no stright forward way to get the exact
+// channel so we are hardcoding it to KCS in case host-ipmid
+// and LAN1 for netipmid.
+// we can't differentiate between LAN1 & LAN2 for netipmid in this logic.
+// As our current design will not be able to support the same. This is done
+// so that in all the places where ever we need to use the self channel can be
+// be implemented properly and based on new architecture.this can be updated.
+typedef enum
+{
+    interfaceKCS = 0,
+    interfaceLAN1 = 1,
+    interfaceUnknown = 0xFF
+} EInterfaceIndex;
+
+EInterfaceIndex getInterfaceIndex(void);
+
+sd_bus* ipmid_get_sd_bus_connection(void);
+sd_event* ipmid_get_sd_event_connection(void);
+sd_bus_slot* ipmid_get_sd_bus_slot(void);
+
+// move this from ipmid.hpp, which is now gone
+// this should not be used. Use the channel API to get the channel size
+#define MAX_IPMI_BUFFER 64
+
+#endif
diff --git a/include/ipmid/api.hpp b/include/ipmid/api.hpp
new file mode 100644
index 0000000..68e24ea
--- /dev/null
+++ b/include/ipmid/api.hpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2018 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.
+ *
+ */
+#pragma once
+
+#define ALLOW_DEPRECATED_API 1
+// make it possible to ONLY include api.hpp during the transition
+#ifdef ALLOW_DEPRECATED_API
+#include <ipmid/api.h>
+#endif
+
+#include <boost/asio/io_context.hpp>
+#include <ipmid/api-types.hpp>
+#include <ipmid/filter.hpp>
+#include <ipmid/handler.hpp>
+#include <ipmid/message/types.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+// any client can interact with the main asio context
+std::shared_ptr<boost::asio::io_context> getIoContext();
+
+// any client can interact with the main sdbus
+std::shared_ptr<sdbusplus::asio::connection> getSdBus();
+
+/**
+ * @brief post some work to the async exection queue
+ *
+ * The IPMI daemon runs an async exection queue; this allows any function to
+ * pass in work to be executed in that context
+ *
+ * @tparam WorkFn - a function of type void(void)
+ * @param work - the callback function to be executed
+ */
+template <typename WorkFn>
+static inline void post_work(WorkFn work)
+{
+    boost::asio::post(*getIoContext(), std::forward<WorkFn>(work));
+}
+
+enum class SignalResponse : int
+{
+    breakExecution,
+    continueExecution,
+};
+
+/**
+ * @brief add a signal handler
+ *
+ * This registers a handler to be called asynchronously via the execution
+ * queue when the specified signal is received.
+ *
+ * Priority allows a signal handler to specify what order in the handler
+ * chain it gets called. Lower priority numbers will cause the handler to
+ * be executed later in the chain, while the highest priority numbers will cause
+ * the handler to be executed first.
+ *
+ * In order to facilitate a chain of handlers, each handler in the chain will be
+ * able to return breakExecution or continueExecution. Returning breakExecution
+ * will break the chain and no further handlers will execute for that signal.
+ * Returning continueExecution will allow lower-priority handlers to execute.
+ *
+ * By default, the main asio execution loop will register a low priority
+ * (prioOpenBmcBase) handler for SIGINT and SIGTERM to cause the process to stop
+ * on either of those signals. To prevent one of those signals from causing the
+ * process to stop, simply register a higher priority handler that returns
+ * breakExecution.
+ *
+ * @param int - priority of handler
+ * @param int - signal number to wait for
+ * @param handler - the callback function to be executed
+ */
+void registerSignalHandler(int priority, int signalNumber,
+                           const std::function<SignalResponse(int)>& handler);
diff --git a/include/ipmid/entity_map_json.hpp b/include/ipmid/entity_map_json.hpp
new file mode 100644
index 0000000..bfc8e72
--- /dev/null
+++ b/include/ipmid/entity_map_json.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <ipmid/types.hpp>
+#include <nlohmann/json.hpp>
+
+#include <memory>
+
+namespace ipmi
+{
+namespace sensor
+{
+
+/**
+ * @brief Grab a handle to the entity map.
+ */
+const EntityInfoMap& getIpmiEntityRecords();
+
+/**
+ * @brief Open the default entity map json file, and if present and valid json,
+ * return a built entity map.
+ *
+ * @return the map
+ */
+EntityInfoMap buildEntityMapFromFile();
+
+/**
+ * @brief Given json data validate the data matches the expected format for the
+ * entity map configuration and parse the data into a map of the entities.
+ *
+ * If any entry is invalid, the entire contents passed in is disregarded as
+ * possibly corrupt.
+ *
+ * @param[in] data - the json data
+ * @return the map
+ */
+EntityInfoMap buildJsonEntityMap(const nlohmann::json& data);
+
+/**
+ * @brief Owner of the EntityInfoMap.
+ */
+class EntityInfoMapContainer
+{
+  public:
+    /** Get ahold of the owner. */
+    static EntityInfoMapContainer* getContainer();
+    /** Get ahold of the records. */
+    const EntityInfoMap& getIpmiEntityRecords();
+
+  private:
+    EntityInfoMapContainer(const EntityInfoMap& entityRecords) :
+        entityRecords(entityRecords)
+    {}
+    EntityInfoMap entityRecords;
+};
+
+} // namespace sensor
+} // namespace ipmi
diff --git a/include/ipmid/filter.hpp b/include/ipmid/filter.hpp
new file mode 100644
index 0000000..d57b838
--- /dev/null
+++ b/include/ipmid/filter.hpp
@@ -0,0 +1,136 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+#include <boost/callable_traits.hpp>
+#include <ipmid/api-types.hpp>
+#include <ipmid/message.hpp>
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <tuple>
+#include <utility>
+
+namespace ipmi
+{
+
+using FilterFunction = ipmi::Cc(ipmi::message::Request::ptr);
+
+/**
+ * @brief Filter base class for dealing with IPMI request/response
+ *
+ * The subclasses are all templated so they can provide access to any type of
+ * command callback functions.
+ */
+class FilterBase
+{
+  public:
+    using ptr = std::shared_ptr<FilterBase>;
+
+    virtual ~FilterBase() = default;
+
+    virtual ipmi::Cc call(message::Request::ptr request) = 0;
+};
+
+/**
+ * @brief filter concrete class
+ *
+ * This is the base template that ipmi filters will resolve into. This is
+ * essentially just a wrapper to hold the filter callback so it can be stored in
+ * the filter list.
+ *
+ * Filters are called with a ipmi::message::Request shared_ptr on all IPMI
+ * commands in priority order and each filter has the opportunity to reject the
+ * command (by returning an IPMI error competion code.) If all the filters
+ * return success, the actual IPMI command will be executed. Filters can reject
+ * the command for any reason, based on system state, the context, the command
+ * payload, etc.
+ */
+template <typename Filter>
+class IpmiFilter : public FilterBase
+{
+  public:
+    IpmiFilter(Filter&& filter) : filter_(std::move(filter)) {}
+
+    ipmi::Cc call(message::Request::ptr request) override
+    {
+        return filter_(request);
+    }
+
+  private:
+    Filter filter_;
+};
+
+/**
+ * @brief helper function to construct a filter object
+ *
+ * This is called internally by the ipmi::registerFilter function.
+ */
+template <typename Filter>
+static inline auto makeFilter(Filter&& filter)
+{
+    FilterBase::ptr ptr(new IpmiFilter<Filter>(std::forward<Filter>(filter)));
+    return ptr;
+}
+template <typename Filter>
+static inline auto makeFilter(const Filter& filter)
+{
+    Filter lFilter = filter;
+    return makeFilter(std::forward<Filter>(lFilter));
+}
+
+namespace impl
+{
+
+// IPMI command filter registration implementation
+void registerFilter(int prio, ::ipmi::FilterBase::ptr filter);
+
+} // namespace impl
+
+/**
+ * @brief IPMI command filter registration function
+ *
+ * This function should be used to register IPMI command filter functions.
+ * This function just passes the callback to makeFilter, which creates a
+ * wrapper functor object that ultimately calls the callback.
+ *
+ * Filters are called with a ipmi::message::Request shared_ptr on all IPMI
+ * commands in priority order and each filter has the opportunity to reject the
+ * command (by returning an IPMI error competion code.) If all the filters
+ * return success, the actual IPMI command will be executed. Filters can reject
+ * the command for any reason, based on system state, the context, the command
+ * payload, etc.
+ *
+ * @param prio - priority at which to register; see api.hpp
+ * @param filter - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ */
+template <typename Filter>
+void registerFilter(int prio, Filter&& filter)
+{
+    auto f = ipmi::makeFilter(std::forward<Filter>(filter));
+    impl::registerFilter(prio, f);
+}
+
+template <typename Filter>
+void registerFilter(int prio, const Filter& filter)
+{
+    auto f = ipmi::makeFilter(filter);
+    impl::registerFilter(prio, f);
+}
+
+} // namespace ipmi
diff --git a/include/ipmid/handler.hpp b/include/ipmid/handler.hpp
new file mode 100644
index 0000000..c3d5f91
--- /dev/null
+++ b/include/ipmid/handler.hpp
@@ -0,0 +1,677 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+#include <cxxabi.h>
+
+#include <boost/asio/spawn.hpp>
+#include <boost/callable_traits.hpp>
+#include <ipmid/api-types.hpp>
+#include <ipmid/message.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <phosphor-logging/log.hpp>
+#include <user_channel/channel_layer.hpp>
+
+#include <algorithm>
+#include <cstdint>
+#include <exception>
+#include <memory>
+#include <optional>
+#include <stdexcept>
+#include <tuple>
+#include <utility>
+
+#ifdef ALLOW_DEPRECATED_API
+#include <ipmid/api.h>
+
+#include <ipmid/oemrouter.hpp>
+#endif /* ALLOW_DEPRECATED_API */
+
+namespace ipmi
+{
+
+template <typename... Args>
+static inline message::Response::ptr errorResponse(
+    message::Request::ptr request, ipmi::Cc cc, Args&&... args)
+{
+    message::Response::ptr response = request->makeResponse();
+    response->cc = cc;
+    response->pack(args...);
+    return response;
+}
+static inline message::Response::ptr errorResponse(
+    message::Request::ptr request, ipmi::Cc cc)
+{
+    message::Response::ptr response = request->makeResponse();
+    response->cc = cc;
+    return response;
+}
+
+/** @brief Exception extension that allows setting an IPMI return code */
+class HandlerCompletion
+{
+  public:
+    HandlerCompletion(Cc cc) noexcept : cc(cc) {}
+
+    Cc code() const noexcept
+    {
+        return cc;
+    }
+
+  private:
+    Cc cc;
+};
+
+/** @brief Exception extension that allows setting an IPMI return code and
+ * printing out a logged error */
+class HandlerException : public HandlerCompletion, public std::runtime_error
+{
+  public:
+    HandlerException(Cc cc, const char* what) :
+        HandlerCompletion(cc), std::runtime_error(what)
+    {}
+    HandlerException(Cc cc, const std::string& what) :
+        HandlerException(cc, what.c_str())
+    {}
+};
+
+static inline const char* currentExceptionType()
+{
+    int status;
+    return abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(),
+                               nullptr, nullptr, &status);
+}
+
+/**
+ * @brief Handler base class for dealing with IPMI request/response
+ *
+ * The subclasses are all templated so they can provide access to any type
+ * of command callback functions.
+ */
+class HandlerBase
+{
+  public:
+    using ptr = std::shared_ptr<HandlerBase>;
+
+    virtual ~HandlerBase() = default;
+
+    /** @brief wrap the call to the registered handler with the request
+     *
+     * This is called from the running queue context after it has already
+     * created a request object that contains all the information required to
+     * execute the ipmi command. This function will return the response object
+     * pointer that owns the response object that will ultimately get sent back
+     * to the requester.
+     *
+     * This is a non-virtual function wrapper to the virtualized executeCallback
+     * function that actually does the work. This is required because of how
+     * templates and virtualization work together.
+     *
+     * @param request a shared_ptr to a Request object
+     *
+     * @return a shared_ptr to a Response object
+     */
+    message::Response::ptr call(message::Request::ptr request)
+    {
+        return executeCallback(request);
+    }
+
+  private:
+    /** @brief call the registered handler with the request
+     *
+     * This is called from the running queue context after it has already
+     * created a request object that contains all the information required to
+     * execute the ipmi command. This function will return the response object
+     * pointer that owns the response object that will ultimately get sent back
+     * to the requester.
+     *
+     * @param request a shared_ptr to a Request object
+     *
+     * @return a shared_ptr to a Response object
+     */
+    virtual message::Response::ptr executeCallback(
+        message::Request::ptr request) = 0;
+};
+
+/**
+ * @brief Main IPMI handler class
+ *
+ * New IPMI handlers will resolve into this class, which will read the signature
+ * of the registering function, attempt to extract the appropriate arguments
+ * from a request, pass the arguments to the function, and then pack the
+ * response of the function back into an IPMI response.
+ */
+template <typename Handler>
+class IpmiHandler final : public HandlerBase
+{
+  public:
+    explicit IpmiHandler(Handler&& handler) :
+        handler_(std::forward<Handler>(handler))
+    {}
+
+  private:
+    Handler handler_;
+
+    /** @brief call the registered handler with the request
+     *
+     * This is called from the running queue context after it has already
+     * created a request object that contains all the information required to
+     * execute the ipmi command. This function will return the response object
+     * pointer that owns the response object that will ultimately get sent back
+     * to the requester.
+     *
+     * Because this is the new variety of IPMI handler, this is the function
+     * that attempts to extract the requested parameters in order to pass them
+     * onto the callback function and then packages up the response into a plain
+     * old vector to pass back to the caller.
+     *
+     * @param request a shared_ptr to a Request object
+     *
+     * @return a shared_ptr to a Response object
+     */
+    message::Response::ptr executeCallback(
+        message::Request::ptr request) override
+    {
+        message::Response::ptr response = request->makeResponse();
+
+        using CallbackSig = boost::callable_traits::args_t<Handler>;
+        using InputArgsType = typename utility::DecayTuple<CallbackSig>::type;
+        using UnpackArgsType = typename utility::StripFirstArgs<
+            utility::NonIpmiArgsCount<InputArgsType>::size(),
+            InputArgsType>::type;
+        using ResultType = boost::callable_traits::return_type_t<Handler>;
+
+        UnpackArgsType unpackArgs{};
+        request->payload.trailingOk = false;
+        ipmi::Cc unpackError = request->unpack(unpackArgs);
+        if (unpackError != ipmi::ccSuccess)
+        {
+            response->cc = unpackError;
+            return response;
+        }
+        /* callbacks can contain an optional first argument of one of:
+         * 1) boost::asio::yield_context
+         * 2) ipmi::Context::ptr
+         * 3) ipmi::message::Request::ptr
+         *
+         * If any of those is part of the callback signature as the first
+         * argument, it will automatically get packed into the parameter pack
+         * here.
+         *
+         * One more special optional argument is an ipmi::message::Payload.
+         * This argument can be in any position, though logically it makes the
+         * most sense if it is the last. If this class is included in the
+         * handler signature, it will allow for the handler to unpack optional
+         * parameters. For example, the Set LAN Configuration Parameters
+         * command takes variable length (and type) values for each of the LAN
+         * parameters. This means that the  only fixed data is the channel and
+         * parameter selector. All the remaining data can be extracted using
+         * the Payload class and the unpack API available to the Payload class.
+         */
+        ResultType result;
+        try
+        {
+            std::optional<InputArgsType> inputArgs;
+            if constexpr (std::tuple_size<InputArgsType>::value > 0)
+            {
+                if constexpr (std::is_same<
+                                  std::tuple_element_t<0, InputArgsType>,
+                                  boost::asio::yield_context>::value)
+                {
+                    inputArgs.emplace(std::tuple_cat(
+                        std::forward_as_tuple(request->ctx->yield),
+                        std::move(unpackArgs)));
+                }
+                else if constexpr (std::is_same<
+                                       std::tuple_element_t<0, InputArgsType>,
+                                       ipmi::Context::ptr>::value)
+                {
+                    inputArgs.emplace(
+                        std::tuple_cat(std::forward_as_tuple(request->ctx),
+                                       std::move(unpackArgs)));
+                }
+                else if constexpr (std::is_same<
+                                       std::tuple_element_t<0, InputArgsType>,
+                                       ipmi::message::Request::ptr>::value)
+                {
+                    inputArgs.emplace(std::tuple_cat(
+                        std::forward_as_tuple(request), std::move(unpackArgs)));
+                }
+                else
+                {
+                    // no special parameters were requested (but others were)
+                    inputArgs.emplace(std::move(unpackArgs));
+                }
+            }
+            else
+            {
+                // no parameters were requested
+                inputArgs = std::move(unpackArgs);
+            }
+
+            // execute the registered callback function and get the
+            // ipmi::RspType<>
+            result = std::apply(handler_, *inputArgs);
+        }
+        catch (const HandlerException& e)
+        {
+            lg2::info("Handler produced exception, NetFn: {NETFN}, "
+                      "Cmd: {CMD}: {ERROR}",
+                      "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                      request->ctx->cmd, "ERROR", e);
+            return errorResponse(request, e.code());
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Handler failed to catch exception, NetFn: {NETFN}, "
+                       "Cmd: {CMD}: {ERROR}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd, "ERROR", e);
+            return errorResponse(request, ccUnspecifiedError);
+        }
+        catch (const HandlerCompletion& c)
+        {
+            return errorResponse(request, c.code());
+        }
+        catch (...)
+        {
+            const char* what = currentExceptionType();
+            lg2::error("Handler failed to catch exception, NetFn: {NETFN}, "
+                       "Cmd: {CMD}: {ERROR}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd, "ERROR", what);
+            return errorResponse(request, ccUnspecifiedError);
+        }
+
+        response->cc = std::get<0>(result);
+        auto payload = std::get<1>(result);
+        // check for optional payload
+        if (payload)
+        {
+            response->pack(*payload);
+        }
+        return response;
+    }
+};
+
+#ifdef ALLOW_DEPRECATED_API
+static constexpr size_t maxLegacyBufferSize = 64 * 1024;
+/**
+ * @brief Legacy IPMI handler class
+ *
+ * Legacy IPMI handlers will resolve into this class, which will behave the same
+ * way as the legacy IPMI queue, passing in a big buffer for the request and a
+ * big buffer for the response.
+ *
+ * As soon as all the handlers have been rewritten, this class will be marked as
+ * deprecated and eventually removed.
+ */
+template <>
+class IpmiHandler<ipmid_callback_t> final : public HandlerBase
+{
+  public:
+    explicit IpmiHandler(const ipmid_callback_t& handler, void* ctx = nullptr) :
+        handler_(handler), handlerCtx(ctx)
+    {}
+
+  private:
+    ipmid_callback_t handler_;
+    void* handlerCtx;
+
+    /** @brief call the registered handler with the request
+     *
+     * This is called from the running queue context after it has already
+     * created a request object that contains all the information required to
+     * execute the ipmi command. This function will return the response object
+     * pointer that owns the response object that will ultimately get sent back
+     * to the requester.
+     *
+     * Because this is the legacy variety of IPMI handler, this function does
+     * not really have to do much other than pass the payload to the callback
+     * and return response to the caller.
+     *
+     * @param request a shared_ptr to a Request object
+     *
+     * @return a shared_ptr to a Response object
+     */
+    message::Response::ptr executeCallback(
+        message::Request::ptr request) override
+    {
+        message::Response::ptr response = request->makeResponse();
+        // allocate a big response buffer here
+        response->payload.resize(maxLegacyBufferSize);
+
+        size_t len = request->payload.size() - request->payload.rawIndex;
+        Cc ccRet{ccSuccess};
+        try
+        {
+            ccRet =
+                handler_(request->ctx->netFn, request->ctx->cmd,
+                         request->payload.data() + request->payload.rawIndex,
+                         response->payload.data(), &len, handlerCtx);
+        }
+        catch (const HandlerException& e)
+        {
+            lg2::info("Legacy Handler produced exception, NetFn: {NETFN}, "
+                      "Cmd: {CMD}: {ERROR}",
+                      "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                      request->ctx->cmd, "ERROR", e);
+            return errorResponse(request, e.code());
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Legacy Handler failed to catch exception, "
+                       "NetFn: {NETFN}, Cmd: {CMD}: {ERROR}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd, "ERROR", e);
+            return errorResponse(request, ccUnspecifiedError);
+        }
+        catch (const HandlerCompletion& c)
+        {
+            return errorResponse(request, c.code());
+        }
+        catch (...)
+        {
+            const char* what = currentExceptionType();
+            lg2::error("Handler failed to catch exception, NetFn: {NETFN}, "
+                       "Cmd: {CMD}: {ERROR}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd, "ERROR", what);
+            return errorResponse(request, ccUnspecifiedError);
+        }
+        response->cc = ccRet;
+        response->payload.resize(len);
+        return response;
+    }
+};
+
+/**
+ * @brief Legacy IPMI OEM handler class
+ *
+ * Legacy IPMI OEM handlers will resolve into this class, which will behave the
+ * same way as the legacy IPMI queue, passing in a big buffer for the request
+ * and a big buffer for the response.
+ *
+ * As soon as all the handlers have been rewritten, this class will be marked as
+ * deprecated and eventually removed.
+ */
+template <>
+class IpmiHandler<oem::Handler> final : public HandlerBase
+{
+  public:
+    explicit IpmiHandler(const oem::Handler& handler) : handler_(handler) {}
+
+  private:
+    oem::Handler handler_;
+
+    /** @brief call the registered handler with the request
+     *
+     * This is called from the running queue context after it has already
+     * created a request object that contains all the information required to
+     * execute the ipmi command. This function will return the response object
+     * pointer that owns the response object that will ultimately get sent back
+     * to the requester.
+     *
+     * Because this is the legacy variety of IPMI handler, this function does
+     * not really have to do much other than pass the payload to the callback
+     * and return response to the caller.
+     *
+     * @param request a shared_ptr to a Request object
+     *
+     * @return a shared_ptr to a Response object
+     */
+    message::Response::ptr executeCallback(
+        message::Request::ptr request) override
+    {
+        message::Response::ptr response = request->makeResponse();
+        // allocate a big response buffer here
+        response->payload.resize(maxLegacyBufferSize);
+
+        size_t len = request->payload.size() - request->payload.rawIndex;
+        Cc ccRet{ccSuccess};
+        try
+        {
+            ccRet =
+                handler_(request->ctx->cmd,
+                         request->payload.data() + request->payload.rawIndex,
+                         response->payload.data(), &len);
+        }
+        catch (const HandlerException& e)
+        {
+            lg2::info("Legacy OEM Handler produced exception, NetFn: {NETFN}, "
+                      "Cmd: {CMD}: {ERROR}",
+                      "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                      request->ctx->cmd, "ERROR", e);
+            return errorResponse(request, e.code());
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Legacy OEM Handler failed to catch exception, "
+                       "NetFn: {NETFN}, Cmd: {CMD}: {ERROR}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd, "ERROR", e);
+            return errorResponse(request, ccUnspecifiedError);
+        }
+        catch (const HandlerCompletion& c)
+        {
+            return errorResponse(request, c.code());
+        }
+        catch (...)
+        {
+            const char* what = currentExceptionType();
+            lg2::error("Legacy failed to catch exception, NetFn: {NETFN}, "
+                       "Cmd: {CMD}: {ERROR}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd, "ERROR", what);
+            return errorResponse(request, ccUnspecifiedError);
+        }
+        response->cc = ccRet;
+        response->payload.resize(len);
+        return response;
+    }
+};
+
+/**
+ * @brief create a legacy IPMI handler class and return a shared_ptr
+ *
+ * The queue uses a map of pointers to do the lookup. This function returns the
+ * shared_ptr that owns the Handler object.
+ *
+ * This is called internally via the ipmi_register_callback function.
+ *
+ * @param handler the function pointer to the callback
+ *
+ * @return A shared_ptr to the created handler object
+ */
+inline auto makeLegacyHandler(const ipmid_callback_t& handler,
+                              void* ctx = nullptr)
+{
+    HandlerBase::ptr ptr(new IpmiHandler<ipmid_callback_t>(handler, ctx));
+    return ptr;
+}
+
+/**
+ * @brief create a legacy IPMI OEM handler class and return a shared_ptr
+ *
+ * The queue uses a map of pointers to do the lookup. This function returns the
+ * shared_ptr that owns the Handler object.
+ *
+ * This is called internally via the Router::registerHandler method.
+ *
+ * @param handler the function pointer to the callback
+ *
+ * @return A shared_ptr to the created handler object
+ */
+inline auto makeLegacyHandler(oem::Handler&& handler)
+{
+    HandlerBase::ptr ptr(
+        new IpmiHandler<oem::Handler>(std::forward<oem::Handler>(handler)));
+    return ptr;
+}
+#endif // ALLOW_DEPRECATED_API
+
+/**
+ * @brief create an IPMI handler class and return a shared_ptr
+ *
+ * The queue uses a map of pointers to do the lookup. This function returns the
+ * shared_ptr that owns the Handler object.
+ *
+ * This is called internally via the ipmi::registerHandler function.
+ *
+ * @param handler the function pointer to the callback
+ *
+ * @return A shared_ptr to the created handler object
+ */
+template <typename Handler>
+inline auto makeHandler(Handler&& handler)
+{
+    HandlerBase::ptr ptr(
+        new IpmiHandler<Handler>(std::forward<Handler>(handler)));
+    return ptr;
+}
+
+namespace impl
+{
+
+// IPMI command handler registration implementation
+bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
+                     ::ipmi::HandlerBase::ptr handler);
+bool registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
+                          ::ipmi::HandlerBase::ptr handler);
+bool registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
+                        ::ipmi::HandlerBase::ptr handler);
+
+} // namespace impl
+
+/**
+ * @brief main IPMI handler registration function
+ *
+ * This function should be used to register all new-style IPMI handler
+ * functions. This function just passes the callback to makeHandler, which
+ * creates a new wrapper object that will automatically extract the appropriate
+ * parameters for the callback function as well as pack up the response.
+ *
+ * @param prio - priority at which to register; see api.hpp
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param priv - the IPMI user privilige required for this command
+ * @param handler - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ */
+template <typename Handler>
+bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
+                     Handler&& handler)
+{
+    auto h = ipmi::makeHandler(std::forward<Handler>(handler));
+    return impl::registerHandler(prio, netFn, cmd, priv, h);
+}
+
+/**
+ * @brief register a IPMI OEM group handler
+ *
+ * From IPMI 2.0 spec Network Function Codes Table (Row 2Ch):
+ * The first data byte position in requests and responses under this network
+ * function identifies the defining body that specifies command functionality.
+ * Software assumes that the command and completion code field positions will
+ * hold command and completion code values.
+ *
+ * The following values are used to identify the defining body:
+ * 00h PICMG - PCI Industrial Computer Manufacturer’s Group.  (www.picmg.com)
+ * 01h DMTF Pre-OS Working Group ASF Specification (www.dmtf.org)
+ * 02h Server System Infrastructure (SSI) Forum (www.ssiforum.org)
+ * 03h VITA Standards Organization (VSO) (www.vita.com)
+ * DCh DCMI Specifications (www.intel.com/go/dcmi)
+ * all other Reserved
+ *
+ * When this network function is used, the ID for the defining body occupies
+ * the first data byte in a request, and the second data byte (following the
+ * completion code) in a response.
+ *
+ * @tparam Handler - implicitly specified callback function type
+ * @param prio - priority at which to register; see api.hpp
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param priv - the IPMI user privilige required for this command
+ * @param handler - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ *
+ */
+template <typename Handler>
+void registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
+                          Handler&& handler)
+{
+    auto h = ipmi::makeHandler(handler);
+    impl::registerGroupHandler(prio, group, cmd, priv, h);
+}
+
+/**
+ * @brief register a IPMI OEM IANA handler
+ *
+ * From IPMI spec Network Function Codes Table (Row 2Eh):
+ * The first three data bytes of requests and responses under this network
+ * function explicitly identify the OEM or non-IPMI group that specifies the
+ * command functionality. While the OEM or non-IPMI group defines the
+ * functional semantics for the cmd and remaining data fields, the cmd field
+ * is required to hold the same value in requests and responses for a given
+ * operation in order to be supported under the IPMI message handling and
+ * transport mechanisms.
+ *
+ * When this network function is used, the IANA Enterprise Number for the
+ * defining body occupies the first three data bytes in a request, and the
+ * first three data bytes following the completion code position in a
+ * response.
+ *
+ * @tparam Handler - implicitly specified callback function type
+ * @param prio - priority at which to register; see api.hpp
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param priv - the IPMI user privilige required for this command
+ * @param handler - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ *
+ */
+template <typename Handler>
+void registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
+                        Handler&& handler)
+{
+    auto h = ipmi::makeHandler(handler);
+    impl::registerOemHandler(prio, iana, cmd, priv, h);
+}
+
+} // namespace ipmi
+
+#ifdef ALLOW_DEPRECATED_API
+/**
+ * @brief legacy IPMI handler registration function
+ *
+ * This function should be used to register all legacy IPMI handler
+ * functions. This function just behaves just as the legacy registration
+ * mechanism did, silently replacing any existing handler with a new one.
+ *
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param context - ignored
+ * @param handler - the callback function that will handle this request
+ * @param priv - the IPMI user privilige required for this command
+ */
+// [[deprecated("Use ipmi::registerHandler() instead")]]
+void ipmi_register_callback(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                            ipmi_context_t context, ipmid_callback_t handler,
+                            ipmi_cmd_privilege_t priv);
+
+#endif /* ALLOW_DEPRECATED_API */
diff --git a/include/ipmid/iana.hpp b/include/ipmid/iana.hpp
new file mode 100644
index 0000000..aa9e173
--- /dev/null
+++ b/include/ipmid/iana.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <cstdint>
+
+namespace oem
+{
+using Number = std::uint32_t; // smallest standard size >= 24.
+
+/*
+ * This is the OpenBMC IANA OEM Number
+ */
+constexpr Number obmcOemNumber = 49871;
+
+/*
+ * This is the Google IANA OEM Number
+ */
+constexpr Number googOemNumber = 11129;
+
+} // namespace oem
diff --git a/include/ipmid/message.hpp b/include/ipmid/message.hpp
new file mode 100644
index 0000000..6698581
--- /dev/null
+++ b/include/ipmid/message.hpp
@@ -0,0 +1,668 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+
+#include <boost/asio/spawn.hpp>
+#include <ipmid/api-types.hpp>
+#include <ipmid/message/types.hpp>
+#include <ipmid/types.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <algorithm>
+#include <cstdint>
+#include <exception>
+#include <memory>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace ipmi
+{
+
+struct Context
+{
+    using ptr = std::shared_ptr<Context>;
+
+    Context() = delete;
+    Context(const Context&) = default;
+    Context& operator=(const Context&) = default;
+    Context(Context&&) = delete;
+    Context& operator=(Context&&) = delete;
+
+    Context(std::shared_ptr<sdbusplus::asio::connection> bus, NetFn netFn,
+            uint8_t lun, Cmd cmd, int channel, int userId, uint32_t sessionId,
+            Privilege priv, int rqSA, int hostIdx,
+            boost::asio::yield_context& yield) :
+        bus(bus), netFn(netFn), lun(lun), cmd(cmd), channel(channel),
+        userId(userId), sessionId(sessionId), priv(priv), group(0), rqSA(rqSA),
+        hostIdx(hostIdx), yield(yield)
+    {}
+
+    std::shared_ptr<sdbusplus::asio::connection> bus;
+    // normal IPMI context (what call is this, from whence it came...)
+    NetFn netFn;
+    uint8_t lun;
+    Cmd cmd;
+    int channel;
+    int userId;
+    uint32_t sessionId;
+    Privilege priv;
+    // defining body code for netFnGroup
+    Group group;
+    // srcAddr is only set on IPMB requests because
+    // Platform Event Message needs it to determine the incoming format
+    int rqSA;
+    int hostIdx;
+    boost::asio::yield_context yield;
+};
+
+namespace message
+{
+
+namespace details
+{
+
+template <typename A>
+struct UnpackSingle;
+
+template <typename T>
+using UnpackSingle_t = UnpackSingle<utility::TypeIdDowncast_t<T>>;
+
+template <typename A>
+struct PackSingle;
+
+template <typename T>
+using PackSingle_t = PackSingle<utility::TypeIdDowncast_t<T>>;
+
+// size to hold 64 bits plus one (possibly-)partial byte
+static constexpr size_t bitStreamSize = ((sizeof(uint64_t) + 1) * CHAR_BIT);
+
+} // namespace details
+
+/**
+ * @brief a payload class that provides a mechanism to pack and unpack data
+ *
+ * When a new request is being executed, the Payload class is responsible for
+ * attempting to unpack all the required arguments from the incoming blob. For
+ * variable-length functions, it is possible to have function signature have a
+ * Payload object, which will then allow the remaining data to be extracted as
+ * needed.
+ *
+ * When creating a response, the parameters returned from the callback use a
+ * newly created payload object to pack all the parameters into a buffer that is
+ * then returned to the requester.
+ *
+ * These interfaces make calls into the message/pack.hpp and message/unpack.hpp
+ * functions.
+ */
+struct Payload
+{
+    Payload() = default;
+    Payload(const Payload&) = default;
+    Payload& operator=(const Payload&) = default;
+    Payload(Payload&&) = default;
+    Payload& operator=(Payload&&) = default;
+
+    explicit Payload(SecureBuffer&& data) : raw(std::move(data)) {}
+
+    ~Payload()
+    {
+        if (raw.size() != 0 && std::uncaught_exceptions() == 0 && !trailingOk &&
+            !unpackCheck && !unpackError)
+        {
+            lg2::error(
+                "Failed to check request for full unpack: raw size: {RAW_SIZE}",
+                "RAW_SIZE", raw.size());
+        }
+    }
+
+    /******************************************************************
+     * raw vector access
+     *****************************************************************/
+    /**
+     * @brief return the size of the underlying raw buffer
+     */
+    size_t size() const
+    {
+        return raw.size();
+    }
+    /**
+     * @brief resize the underlying raw buffer to a new size
+     *
+     * @param sz - new size for the buffer
+     */
+    void resize(size_t sz)
+    {
+        raw.resize(sz);
+    }
+    /**
+     * @brief return a pointer to the underlying raw buffer
+     */
+    uint8_t* data()
+    {
+        return raw.data();
+    }
+    /**
+     * @brief return a const pointer to the underlying raw buffer
+     */
+    const uint8_t* data() const
+    {
+        return raw.data();
+    }
+
+    /******************************************************************
+     * Response operations
+     *****************************************************************/
+    /**
+     * @brief append a series of bytes to the buffer
+     *
+     * @tparam T - the type pointer to return; must be compatible to a byte
+     *
+     * @param begin - a pointer to the beginning of the series
+     * @param end - a pointer to the end of the series
+     */
+    template <typename T>
+    void append(T* begin, T* end)
+    {
+        static_assert(
+            std::is_same_v<utility::TypeIdDowncast_t<T>, int8_t> ||
+                std::is_same_v<utility::TypeIdDowncast_t<T>, uint8_t> ||
+                std::is_same_v<utility::TypeIdDowncast_t<T>, char>,
+            "begin and end must be signed or unsigned byte pointers");
+        // this interface only allows full-byte access; pack in partial bytes
+        drain();
+        raw.insert(raw.end(), reinterpret_cast<const uint8_t*>(begin),
+                   reinterpret_cast<const uint8_t*>(end));
+    }
+
+    /**
+     * @brief append a series of bits to the buffer
+     *
+     * Only the lowest @count order of bits will be appended, with the most
+     * significant of those bits getting appended first.
+     *
+     * @param count - number of bits to append
+     * @param bits - a byte with count significant bits to append
+     */
+    void appendBits(size_t count, uint8_t bits)
+    {
+        // drain whole bytes out
+        drain(true);
+
+        // add in the new bits as the higher-order bits, filling LSBit first
+        fixed_uint_t<details::bitStreamSize> tmp = bits;
+        tmp <<= bitCount;
+        bitStream |= tmp;
+        bitCount += count;
+
+        // drain any whole bytes we have appended
+        drain(true);
+    }
+
+    /**
+     * @brief empty out the bucket and pack it as bytes LSB-first
+     *
+     * @param wholeBytesOnly - if true, only the whole bytes will be drained
+     */
+    void drain(bool wholeBytesOnly = false)
+    {
+        while (bitCount > 0)
+        {
+            uint8_t retVal;
+            if (bitCount < CHAR_BIT)
+            {
+                if (wholeBytesOnly)
+                {
+                    break;
+                }
+            }
+            size_t bitsOut = std::min(static_cast<size_t>(CHAR_BIT), bitCount);
+            retVal = static_cast<uint8_t>(bitStream);
+            raw.push_back(retVal);
+            bitStream >>= bitsOut;
+            bitCount -= bitsOut;
+        }
+    }
+
+    // base empty pack
+    int pack()
+    {
+        return 0;
+    }
+
+    /**
+     * @brief pack arbitrary values (of any supported type) into the buffer
+     *
+     * @tparam Arg - the type of the first argument
+     * @tparam Args - the type of the optional remaining arguments
+     *
+     * @param arg - the first argument to pack
+     * @param args... - the optional remaining arguments to pack
+     *
+     * @return int - non-zero on pack errors
+     */
+    template <typename Arg, typename... Args>
+    int pack(Arg&& arg, Args&&... args)
+    {
+        int packRet =
+            details::PackSingle_t<Arg>::op(*this, std::forward<Arg>(arg));
+        if (packRet)
+        {
+            return packRet;
+        }
+        packRet = pack(std::forward<Args>(args)...);
+        drain();
+        return packRet;
+    }
+
+    /**
+     * @brief Prepends another payload to this one
+     *
+     * Avoid using this unless absolutely required since it inserts into the
+     * front of the response payload.
+     *
+     * @param p - The payload to prepend
+     *
+     * @retunr int - non-zero on prepend errors
+     */
+    int prepend(const ipmi::message::Payload& p)
+    {
+        if (bitCount != 0 || p.bitCount != 0)
+        {
+            return 1;
+        }
+        raw.reserve(raw.size() + p.raw.size());
+        raw.insert(raw.begin(), p.raw.begin(), p.raw.end());
+        return 0;
+    }
+
+    /******************************************************************
+     * Request operations
+     *****************************************************************/
+    /**
+     * @brief pop a series of bytes from the raw buffer
+     *
+     * @tparam T - the type pointer to return; must be compatible to a byte
+     *
+     * @param count - the number of bytes to return
+     *
+     * @return - a tuple of pointers (begin,begin+count)
+     */
+    template <typename T>
+    auto pop(size_t count)
+    {
+        static_assert(
+            std::is_same_v<utility::TypeIdDowncast_t<T>, int8_t> ||
+                std::is_same_v<utility::TypeIdDowncast_t<T>, uint8_t> ||
+                std::is_same_v<utility::TypeIdDowncast_t<T>, char>,
+            "T* must be signed or unsigned byte pointers");
+        // this interface only allows full-byte access; skip partial bits
+        if (bitCount)
+        {
+            // WARN on unused bits?
+            discardBits();
+        }
+        if (count <= (raw.size() - rawIndex))
+        {
+            auto range = std::make_tuple(
+                reinterpret_cast<T*>(raw.data() + rawIndex),
+                reinterpret_cast<T*>(raw.data() + rawIndex + count));
+            rawIndex += count;
+            return range;
+        }
+        unpackError = true;
+        return std::make_tuple(reinterpret_cast<T*>(NULL),
+                               reinterpret_cast<T*>(NULL));
+    }
+
+    /**
+     * @brief fill bit stream with at least count bits for consumption
+     *
+     * @param count - number of bit needed
+     *
+     * @return - unpackError
+     */
+    bool fillBits(size_t count)
+    {
+        // add more bits to the top end of the bitstream
+        // so we consume bits least-significant first
+        if (count > (details::bitStreamSize - CHAR_BIT))
+        {
+            unpackError = true;
+            return unpackError;
+        }
+        while (bitCount < count)
+        {
+            if (rawIndex < raw.size())
+            {
+                fixed_uint_t<details::bitStreamSize> tmp = raw[rawIndex++];
+                tmp <<= bitCount;
+                bitStream |= tmp;
+                bitCount += CHAR_BIT;
+            }
+            else
+            {
+                // raw has run out of bytes to pop
+                unpackError = true;
+                return unpackError;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @brief consume count bits from bitstream (must call fillBits first)
+     *
+     * @param count - number of bit needed
+     *
+     * @return - count bits from stream
+     */
+    uint8_t popBits(size_t count)
+    {
+        if (bitCount < count)
+        {
+            unpackError = true;
+            return 0;
+        }
+        // consume bits low-order bits first
+        auto bits = bitStream.convert_to<uint8_t>();
+        bits &= ((1 << count) - 1);
+        bitStream >>= count;
+        bitCount -= count;
+        return bits;
+    }
+
+    /**
+     * @brief discard all partial bits
+     */
+    void discardBits()
+    {
+        bitStream = 0;
+        bitCount = 0;
+    }
+
+    /**
+     * @brief fully reset the unpack stream
+     */
+    void reset()
+    {
+        discardBits();
+        rawIndex = 0;
+        unpackError = false;
+    }
+
+    /**
+     * @brief check to see if the stream has been fully unpacked
+     *
+     * @return bool - true if the stream has been unpacked and has no errors
+     */
+    bool fullyUnpacked()
+    {
+        unpackCheck = true;
+        return raw.size() == rawIndex && bitCount == 0 && !unpackError;
+    }
+
+    // base empty unpack
+    int unpack()
+    {
+        return 0;
+    }
+
+    /**
+     * @brief unpack arbitrary values (of any supported type) from the buffer
+     *
+     * @tparam Arg - the type of the first argument
+     * @tparam Args - the type of the optional remaining arguments
+     *
+     * @param arg - the first argument to unpack
+     * @param args... - the optional remaining arguments to unpack
+     *
+     * @return int - non-zero for unpack error
+     */
+    template <typename Arg, typename... Args>
+    int unpack(Arg&& arg, Args&&... args)
+    {
+        int unpackRet =
+            details::UnpackSingle_t<Arg>::op(*this, std::forward<Arg>(arg));
+        if (unpackRet)
+        {
+            unpackError = true;
+            return unpackRet;
+        }
+        return unpack(std::forward<Args>(args)...);
+    }
+
+    /**
+     * @brief unpack a tuple of values (of any supported type) from the buffer
+     *
+     * This will unpack the elements of the tuple as if each one was passed in
+     * individually, as if passed into the above variadic function.
+     *
+     * @tparam Types - the implicitly declared list of the tuple element types
+     *
+     * @param t - the tuple of values to unpack
+     *
+     * @return int - non-zero on unpack error
+     */
+    template <typename... Types>
+    int unpack(std::tuple<Types...>& t)
+    {
+        // roll back checkpoint so that unpacking a tuple is atomic
+        size_t priorBitCount = bitCount;
+        size_t priorIndex = rawIndex;
+        fixed_uint_t<details::bitStreamSize> priorBits = bitStream;
+
+        int ret =
+            std::apply([this](Types&... args) { return unpack(args...); }, t);
+        if (ret)
+        {
+            bitCount = priorBitCount;
+            bitStream = priorBits;
+            rawIndex = priorIndex;
+        }
+
+        return ret;
+    }
+
+    // partial bytes in the form of bits
+    fixed_uint_t<details::bitStreamSize> bitStream;
+    size_t bitCount = 0;
+    SecureBuffer raw;
+    size_t rawIndex = 0;
+    bool trailingOk = true;
+    bool unpackCheck = false;
+    bool unpackError = false;
+};
+
+/**
+ * @brief high-level interface to an IPMI response
+ *
+ * Make it easy to just pack in the response args from the callback into a
+ * buffer that goes back to the requester.
+ */
+struct Response
+{
+    /* Define all of the basic class operations:
+     *     Not allowed:
+     *         - Default constructor to avoid nullptrs.
+     *     Allowed:
+     *         - Copy operations.
+     *         - Move operations.
+     *         - Destructor.
+     */
+    Response() = delete;
+    Response(const Response&) = default;
+    Response& operator=(const Response&) = default;
+    Response(Response&&) = default;
+    Response& operator=(Response&&) = default;
+    ~Response() = default;
+
+    using ptr = std::shared_ptr<Response>;
+
+    explicit Response(Context::ptr& context) :
+        payload(), ctx(context), cc(ccSuccess)
+    {}
+
+    /**
+     * @brief pack arbitrary values (of any supported type) into the payload
+     *
+     * @tparam Args - the type of the optional arguments
+     *
+     * @param args... - the optional arguments to pack
+     *
+     * @return int - non-zero on pack errors
+     */
+    template <typename... Args>
+    int pack(Args&&... args)
+    {
+        return payload.pack(std::forward<Args>(args)...);
+    }
+
+    /**
+     * @brief pack a tuple of values (of any supported type) into the payload
+     *
+     * This will pack the elements of the tuple as if each one was passed in
+     * individually, as if passed into the above variadic function.
+     *
+     * @tparam Types - the implicitly declared list of the tuple element types
+     *
+     * @param t - the tuple of values to pack
+     *
+     * @return int - non-zero on pack errors
+     */
+    template <typename... Types>
+    int pack(std::tuple<Types...>& t)
+    {
+        return payload.pack(t);
+    }
+
+    /**
+     * @brief Prepends another payload to this one
+     *
+     * Avoid using this unless absolutely required since it inserts into the
+     * front of the response payload.
+     *
+     * @param p - The payload to prepend
+     *
+     * @retunr int - non-zero on prepend errors
+     */
+    int prepend(const ipmi::message::Payload& p)
+    {
+        return payload.prepend(p);
+    }
+
+    Payload payload;
+    Context::ptr ctx;
+    Cc cc;
+};
+
+/**
+ * @brief high-level interface to an IPMI request
+ *
+ * Make it easy to unpack the buffer into the request args for the callback.
+ */
+struct Request
+{
+    /* Define all of the basic class operations:
+     *     Not allowed:
+     *         - Default constructor to avoid nullptrs.
+     *     Allowed:
+     *         - Copy operations.
+     *         - Move operations.
+     *         - Destructor.
+     */
+    Request() = delete;
+    Request(const Request&) = default;
+    Request& operator=(const Request&) = default;
+    Request(Request&&) = default;
+    Request& operator=(Request&&) = default;
+    ~Request() = default;
+
+    using ptr = std::shared_ptr<Request>;
+
+    explicit Request(Context::ptr context, SecureBuffer&& d) :
+        payload(std::forward<SecureBuffer>(d)), ctx(context)
+    {}
+
+    /**
+     * @brief unpack arbitrary values (of any supported type) from the payload
+     *
+     * @tparam Args - the type of the optional arguments
+     *
+     * @param args... - the optional arguments to unpack
+     *
+     * @return int - non-zero for unpack error
+     */
+    template <typename... Args>
+    int unpack(Args&&... args)
+    {
+        int unpackRet = payload.unpack(std::forward<Args>(args)...);
+        if (unpackRet != ipmi::ccSuccess)
+        {
+            // not all bits were consumed by requested parameters
+            return ipmi::ccReqDataLenInvalid;
+        }
+        if (!payload.trailingOk)
+        {
+            if (!payload.fullyUnpacked())
+            {
+                // not all bits were consumed by requested parameters
+                return ipmi::ccReqDataLenInvalid;
+            }
+        }
+        return ipmi::ccSuccess;
+    }
+
+    /**
+     * @brief unpack a tuple of values (of any supported type) from the payload
+     *
+     * This will unpack the elements of the tuple as if each one was passed in
+     * individually, as if passed into the above variadic function.
+     *
+     * @tparam Types - the implicitly declared list of the tuple element types
+     *
+     * @param t - the tuple of values to unpack
+     *
+     * @return int - non-zero on unpack error
+     */
+    template <typename... Types>
+    int unpack(std::tuple<Types...>& t)
+    {
+        return std::apply([this](Types&... args) { return unpack(args...); },
+                          t);
+    }
+
+    /** @brief Create a response message that corresponds to this request
+     *
+     * @return A shared_ptr to the response message created
+     */
+    Response::ptr makeResponse()
+    {
+        return std::make_shared<Response>(ctx);
+    }
+
+    Payload payload;
+    Context::ptr ctx;
+};
+
+} // namespace message
+
+} // namespace ipmi
+
+// include packing and unpacking of types
+#include <ipmid/message/pack.hpp>
+#include <ipmid/message/unpack.hpp>
diff --git a/include/ipmid/message/pack.hpp b/include/ipmid/message/pack.hpp
new file mode 100644
index 0000000..724bffc
--- /dev/null
+++ b/include/ipmid/message/pack.hpp
@@ -0,0 +1,340 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+
+#include <ipmid/message.hpp>
+#include <ipmid/message/types.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <phosphor-logging/log.hpp>
+
+#include <array>
+#include <memory>
+#include <optional>
+#include <span>
+#include <string_view>
+#include <tuple>
+#include <utility>
+#include <variant>
+#include <vector>
+
+namespace ipmi
+{
+
+namespace message
+{
+
+namespace details
+{
+
+/**************************************
+ * ipmi return type helpers
+ **************************************/
+
+template <typename NumericType, size_t byteIndex = 0>
+void PackBytes(uint8_t* pointer, const NumericType& i)
+{
+    if constexpr (byteIndex < sizeof(NumericType))
+    {
+        *pointer = static_cast<uint8_t>(i >> (8 * byteIndex));
+        PackBytes<NumericType, byteIndex + 1>(pointer + 1, i);
+    }
+}
+
+template <typename NumericType, size_t byteIndex = 0>
+void PackBytesUnaligned(Payload& p, const NumericType& i)
+{
+    if constexpr (byteIndex < sizeof(NumericType))
+    {
+        p.appendBits(CHAR_BIT, static_cast<uint8_t>(i >> (8 * byteIndex)));
+        PackBytesUnaligned<NumericType, byteIndex + 1>(p, i);
+    }
+}
+
+/** @struct PackSingle
+ *  @brief Utility to pack a single C++ element into a Payload
+ *
+ *  User-defined types are expected to specialize this template in order to
+ *  get their functionality.
+ *
+ *  @tparam S - Type of element to pack.
+ */
+template <typename T>
+struct PackSingle
+{
+    /** @brief Do the operation to pack element.
+     *
+     *  @param[in] p - Payload to pack into.
+     *  @param[out] t - The reference to pack item into.
+     */
+    static int op(Payload& p, const T& t)
+    {
+        static_assert(std::is_integral_v<T>,
+                      "Attempt to pack a type that has no IPMI pack operation");
+        // if not on a byte boundary, must pack values LSbit/LSByte first
+        if (p.bitCount)
+        {
+            PackBytesUnaligned<T>(p, t);
+        }
+        else
+        {
+            // copy in bits to vector....
+            p.raw.resize(p.raw.size() + sizeof(T));
+            uint8_t* out = p.raw.data() + p.raw.size() - sizeof(T);
+            PackBytes<T>(out, t);
+        }
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::tuple<T> */
+template <typename... T>
+struct PackSingle<std::tuple<T...>>
+{
+    static int op(Payload& p, const std::tuple<T...>& v)
+    {
+        return std::apply([&p](const T&... args) { return p.pack(args...); },
+                          v);
+    }
+};
+
+/** @brief Specialization of PackSingle for std::string
+ *  represented as a UCSD-Pascal style string
+ */
+template <>
+struct PackSingle<std::string>
+{
+    static int op(Payload& p, const std::string& t)
+    {
+        // check length first
+        uint8_t len;
+        if (t.length() > std::numeric_limits<decltype(len)>::max())
+        {
+            lg2::error("long string truncated on IPMI message pack");
+            return 1;
+        }
+        len = static_cast<uint8_t>(t.length());
+        PackSingle<uint8_t>::op(p, len);
+        p.append(t.c_str(), t.c_str() + t.length());
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for fixed_uint_t types
+ */
+template <bitcount_t N>
+struct PackSingle<fixed_uint_t<N>>
+{
+    static int op(Payload& p, const fixed_uint_t<N>& t)
+    {
+        size_t count = N;
+        static_assert(N <= (details::bitStreamSize - CHAR_BIT));
+        static_assert(N <= std::numeric_limits<uint64_t>::digits,
+                      "Type exceeds uint64_t limit");
+        uint64_t bits = static_cast<uint64_t>(t);
+        while (count > 0)
+        {
+            size_t appendCount = std::min(count, static_cast<size_t>(CHAR_BIT));
+            p.appendBits(appendCount, static_cast<uint8_t>(bits));
+            bits >>= CHAR_BIT;
+            count -= appendCount;
+        }
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for bool. */
+template <>
+struct PackSingle<bool>
+{
+    static int op(Payload& p, const bool& b)
+    {
+        p.appendBits(1, b);
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::bitset<N> */
+template <size_t N>
+struct PackSingle<std::bitset<N>>
+{
+    static int op(Payload& p, const std::bitset<N>& t)
+    {
+        size_t count = N;
+        static_assert(N <= (details::bitStreamSize - CHAR_BIT));
+        unsigned long long bits = t.to_ullong();
+        while (count > 0)
+        {
+            size_t appendCount = std::min(count, size_t(CHAR_BIT));
+            p.appendBits(appendCount, static_cast<uint8_t>(bits));
+            bits >>= CHAR_BIT;
+            count -= appendCount;
+        }
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::optional<T> */
+template <typename T>
+struct PackSingle<std::optional<T>>
+{
+    static int op(Payload& p, const std::optional<T>& t)
+    {
+        int ret = 0;
+        if (t)
+        {
+            ret = PackSingle<T>::op(p, *t);
+        }
+        return ret;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::array<T, N> */
+template <typename T, size_t N>
+struct PackSingle<std::array<T, N>>
+{
+    static int op(Payload& p, const std::array<T, N>& t)
+    {
+        int ret = 0;
+        for (const auto& v : t)
+        {
+            int ret = PackSingle<T>::op(p, v);
+            if (ret)
+            {
+                break;
+            }
+        }
+        return ret;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::vector<T> */
+template <typename T>
+struct PackSingle<std::vector<T>>
+{
+    static int op(Payload& p, const std::vector<T>& t)
+    {
+        int ret = 0;
+        for (const auto& v : t)
+        {
+            int ret = PackSingle<T>::op(p, v);
+            if (ret)
+            {
+                break;
+            }
+        }
+        return ret;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::vector<uint8_t> */
+template <>
+struct PackSingle<std::vector<uint8_t>>
+{
+    static int op(Payload& p, const std::vector<uint8_t>& t)
+    {
+        if (p.bitCount != 0)
+        {
+            return 1;
+        }
+        p.raw.reserve(p.raw.size() + t.size());
+        p.raw.insert(p.raw.end(), t.begin(), t.end());
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for SecureBuffer */
+template <>
+struct PackSingle<SecureBuffer>
+{
+    static int op(Payload& p, const SecureBuffer& t)
+    {
+        if (p.bitCount != 0)
+        {
+            return 1;
+        }
+        p.raw.reserve(p.raw.size() + t.size());
+        p.raw.insert(p.raw.end(), t.begin(), t.end());
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::span<const uint8_t> */
+template <>
+struct PackSingle<std::span<const uint8_t>>
+{
+    static int op(Payload& p, const std::span<const uint8_t>& t)
+    {
+        if (p.bitCount != 0)
+        {
+            return 1;
+        }
+        p.raw.reserve(p.raw.size() + t.size());
+        p.raw.insert(p.raw.end(), t.begin(), t.end());
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::string_view */
+template <>
+struct PackSingle<std::string_view>
+{
+    static int op(Payload& p, const std::string_view& t)
+    {
+        if (p.bitCount != 0)
+        {
+            return 1;
+        }
+        p.raw.reserve(p.raw.size() + t.size());
+        p.raw.insert(p.raw.end(), t.begin(), t.end());
+        return 0;
+    }
+};
+
+/** @brief Specialization of PackSingle for std::variant<T, N> */
+template <typename... T>
+struct PackSingle<std::variant<T...>>
+{
+    static int op(Payload& p, const std::variant<T...>& v)
+    {
+        return std::visit(
+            [&p](const auto& arg) {
+                return PackSingle<std::decay_t<decltype(arg)>>::op(p, arg);
+            },
+            v);
+    }
+};
+
+/** @brief Specialization of PackSingle for Payload */
+template <>
+struct PackSingle<Payload>
+{
+    static int op(Payload& p, const Payload& t)
+    {
+        if (p.bitCount != 0 || t.bitCount != 0)
+        {
+            return 1;
+        }
+        p.raw.reserve(p.raw.size() + t.raw.size());
+        p.raw.insert(p.raw.end(), t.raw.begin(), t.raw.end());
+        return 0;
+    }
+};
+
+} // namespace details
+
+} // namespace message
+
+} // namespace ipmi
diff --git a/include/ipmid/message/types.hpp b/include/ipmid/message/types.hpp
new file mode 100644
index 0000000..c53529b
--- /dev/null
+++ b/include/ipmid/message/types.hpp
@@ -0,0 +1,138 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+
+#include <boost/multiprecision/cpp_int.hpp>
+#include <boost/version.hpp>
+#include <ipmid/utility.hpp>
+
+#include <bitset>
+#include <tuple>
+
+#if BOOST_VERSION < 107900
+using bitcount_t = unsigned;
+#else
+using bitcount_t = std::size_t;
+#endif
+
+// unsigned fixed-bit sizes
+template <bitcount_t N>
+using fixed_uint_t =
+    boost::multiprecision::number<boost::multiprecision::cpp_int_backend<
+        N, N, boost::multiprecision::unsigned_magnitude,
+        boost::multiprecision::unchecked, void>>;
+// signed fixed-bit sizes
+template <bitcount_t N>
+using fixed_int_t =
+    boost::multiprecision::number<boost::multiprecision::cpp_int_backend<
+        N, N, boost::multiprecision::signed_magnitude,
+        boost::multiprecision::unchecked, void>>;
+
+using uint1_t = fixed_uint_t<1>;
+using uint2_t = fixed_uint_t<2>;
+using uint3_t = fixed_uint_t<3>;
+using uint4_t = fixed_uint_t<4>;
+using uint5_t = fixed_uint_t<5>;
+using uint6_t = fixed_uint_t<6>;
+using uint7_t = fixed_uint_t<7>;
+// native uint8_t
+using uint9_t = fixed_uint_t<9>;
+using uint10_t = fixed_uint_t<10>;
+using uint11_t = fixed_uint_t<11>;
+using uint12_t = fixed_uint_t<12>;
+using uint13_t = fixed_uint_t<13>;
+using uint14_t = fixed_uint_t<14>;
+using uint15_t = fixed_uint_t<15>;
+// native uint16_t
+using uint24_t = fixed_uint_t<24>;
+
+// signed fixed-bit sizes
+using int2_t = fixed_int_t<2>;
+using int3_t = fixed_int_t<3>;
+using int4_t = fixed_int_t<4>;
+using int5_t = fixed_int_t<5>;
+using int6_t = fixed_int_t<6>;
+using int7_t = fixed_int_t<7>;
+// native int8_t
+using int9_t = fixed_int_t<9>;
+using int10_t = fixed_int_t<10>;
+using int11_t = fixed_int_t<11>;
+using int12_t = fixed_int_t<12>;
+using int13_t = fixed_int_t<13>;
+using int14_t = fixed_int_t<14>;
+using int15_t = fixed_int_t<15>;
+// native int16_t
+using int24_t = fixed_int_t<24>;
+
+// bool is more efficient than a uint1_t
+using bit = bool;
+
+// Mechanism for going from uint7_t, int7_t, or std::bitset<7> to 7 bits
+// use nrFixedBits<uint7_t> or nrFixedBits<decltype(u7)>
+namespace types
+{
+namespace details
+{
+
+template <bitcount_t N>
+struct Size
+{
+    static constexpr bitcount_t value = N;
+};
+
+template <bitcount_t Bits>
+constexpr auto getNrBits(const fixed_int_t<Bits>&) -> Size<Bits>;
+template <bitcount_t Bits>
+constexpr auto getNrBits(const fixed_uint_t<Bits>&) -> Size<Bits>;
+template <bitcount_t Bits>
+constexpr auto getNrBits(const std::bitset<Bits>&) -> Size<Bits>;
+
+template <typename U>
+using underlying_t =
+    typename std::conditional_t<std::is_enum_v<U>, std::underlying_type<U>,
+                                std::enable_if<true, U>>::type;
+
+} // namespace details
+
+/**
+ * @brief mechanism to get N from a type like fixed_int_t<N>
+ *
+ * helper template to extract N from a fixed_(u)int_t variable
+ *
+ * @tparam T - a type of fixed_int_t<N> or fixed_unint_t<N>
+ *
+ * @return size_t - evaluates to a constexpr size_t of N
+ */
+template <typename T>
+constexpr auto nrFixedBits =
+    decltype(details::getNrBits(std::declval<T>()))::value;
+
+/**
+ * @brief Converts a number or enum class to another
+ * @tparam R - The output type
+ * @tparam T - The input type
+ * @param t - An enum or integer value to cast
+ * @return The value in R form
+ */
+template <typename R, typename T>
+inline R enum_cast(T t)
+{
+    auto tu = static_cast<details::underlying_t<T>>(t);
+    auto ru = static_cast<details::underlying_t<R>>(tu);
+    return static_cast<R>(ru);
+}
+
+} // namespace types
diff --git a/include/ipmid/message/unpack.hpp b/include/ipmid/message/unpack.hpp
new file mode 100644
index 0000000..2e545b0
--- /dev/null
+++ b/include/ipmid/message/unpack.hpp
@@ -0,0 +1,378 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+
+#include <ipmid/message.hpp>
+#include <ipmid/message/types.hpp>
+
+#include <array>
+#include <optional>
+#include <span>
+#include <string>
+#include <tuple>
+#include <vector>
+
+namespace ipmi
+{
+
+namespace message
+{
+
+namespace details
+{
+
+/**************************************
+ * ipmi return type helpers
+ **************************************/
+
+template <typename NumericType, size_t byteIndex = 0>
+void UnpackBytes(uint8_t* pointer, NumericType& i)
+{
+    if constexpr (byteIndex < sizeof(NumericType))
+    {
+        i |= static_cast<NumericType>(*pointer) << (CHAR_BIT * byteIndex);
+        UnpackBytes<NumericType, byteIndex + 1>(pointer + 1, i);
+    }
+}
+
+template <typename NumericType, size_t byteIndex = 0>
+void UnpackBytesUnaligned(Payload& p, NumericType& i)
+{
+    if constexpr (byteIndex < sizeof(NumericType))
+    {
+        i |= static_cast<NumericType>(p.popBits(CHAR_BIT))
+             << (CHAR_BIT * byteIndex);
+        UnpackBytesUnaligned<NumericType, byteIndex + 1>(p, i);
+    }
+}
+
+/** @struct UnpackSingle
+ *  @brief Utility to unpack a single C++ element from a Payload
+ *
+ *  User-defined types are expected to specialize this template in order to
+ *  get their functionality.
+ *
+ *  @tparam T - Type of element to unpack.
+ */
+template <typename T>
+struct UnpackSingle
+{
+    /** @brief Do the operation to unpack element.
+     *
+     *  @param[in] p - Payload to unpack from.
+     *  @param[out] t - The reference to unpack item into.
+     */
+    static int op(Payload& p, T& t)
+    {
+        if constexpr (std::is_fundamental<T>::value)
+        {
+            t = 0;
+            if (p.bitCount)
+            {
+                if (p.fillBits(CHAR_BIT * sizeof(t)))
+                {
+                    return 1;
+                }
+                UnpackBytesUnaligned<T>(p, t);
+            }
+            else
+            {
+                // copy out bits from vector....
+                if (p.raw.size() < (p.rawIndex + sizeof(t)))
+                {
+                    return 1;
+                }
+                auto iter = p.raw.data() + p.rawIndex;
+                t = 0;
+                UnpackBytes<T>(iter, t);
+                p.rawIndex += sizeof(t);
+            }
+            return 0;
+        }
+        else if constexpr (utility::is_tuple<T>::value)
+        {
+            bool priorError = p.unpackError;
+            size_t priorIndex = p.rawIndex;
+            // more stuff to unroll if partial bytes are out
+            size_t priorBitCount = p.bitCount;
+            fixed_uint_t<details::bitStreamSize> priorBits = p.bitStream;
+            int ret = p.unpack(t);
+            if (ret != 0)
+            {
+                t = T();
+                p.rawIndex = priorIndex;
+                p.bitStream = priorBits;
+                p.bitCount = priorBitCount;
+                p.unpackError = priorError;
+            }
+            return ret;
+        }
+        else
+        {
+            static_assert(
+                utility::dependent_false<T>::value,
+                "Attempt to unpack a type that has no IPMI unpack operation");
+        }
+    }
+};
+
+/** @struct UnpackSingle
+ *  @brief Utility to unpack a single C++ element from a Payload
+ *
+ *  Specialization to unpack std::string represented as a
+ *  UCSD-Pascal style string
+ */
+template <>
+struct UnpackSingle<std::string>
+{
+    static int op(Payload& p, std::string& t)
+    {
+        // pop len first
+        if (p.rawIndex > (p.raw.size() - sizeof(uint8_t)))
+        {
+            return 1;
+        }
+        uint8_t len = p.raw[p.rawIndex++];
+        // check to see that there are n bytes left
+        auto [first, last] = p.pop<char>(len);
+        if (first == last)
+        {
+            return 1;
+        }
+        t.reserve(last - first);
+        t.insert(0, first, (last - first));
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for fixed_uint_t types
+ */
+template <bitcount_t N>
+struct UnpackSingle<fixed_uint_t<N>>
+{
+    static int op(Payload& p, fixed_uint_t<N>& t)
+    {
+        static_assert(N <= (details::bitStreamSize - CHAR_BIT));
+        constexpr size_t count = N;
+        // acquire enough bits in the stream to fulfill the Payload
+        if (p.fillBits(count))
+        {
+            return -1;
+        }
+        fixed_uint_t<details::bitStreamSize> bitmask = ((1 << count) - 1);
+        t = (p.bitStream & bitmask).convert_to<fixed_uint_t<N>>();
+        p.bitStream >>= count;
+        p.bitCount -= count;
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for bool. */
+template <>
+struct UnpackSingle<bool>
+{
+    static int op(Payload& p, bool& b)
+    {
+        // acquire enough bits in the stream to fulfill the Payload
+        if (p.fillBits(1))
+        {
+            return -1;
+        }
+        b = static_cast<bool>(p.bitStream & 0x01);
+        // clear bits from stream
+        p.bitStream >>= 1;
+        p.bitCount -= 1;
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::bitset<N>
+ */
+template <size_t N>
+struct UnpackSingle<std::bitset<N>>
+{
+    static int op(Payload& p, std::bitset<N>& t)
+    {
+        static_assert(N <= (details::bitStreamSize - CHAR_BIT));
+        size_t count = N;
+        // acquire enough bits in the stream to fulfill the Payload
+        if (p.fillBits(count))
+        {
+            return -1;
+        }
+        fixed_uint_t<details::bitStreamSize> bitmask =
+            ~fixed_uint_t<details::bitStreamSize>(0) >>
+            (details::bitStreamSize - count);
+        t |= (p.bitStream & bitmask).convert_to<unsigned long long>();
+        p.bitStream >>= count;
+        p.bitCount -= count;
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::optional<T> */
+template <typename T>
+struct UnpackSingle<std::optional<T>>
+{
+    static int op(Payload& p, std::optional<T>& t)
+    {
+        bool priorError = p.unpackError;
+        size_t priorIndex = p.rawIndex;
+        // more stuff to unroll if partial bytes are out
+        size_t priorBitCount = p.bitCount;
+        fixed_uint_t<details::bitStreamSize> priorBits = p.bitStream;
+        T value;
+        int ret = UnpackSingle<T>::op(p, value);
+        if (ret != 0)
+        {
+            t.reset();
+            p.rawIndex = priorIndex;
+            p.bitStream = priorBits;
+            p.bitCount = priorBitCount;
+            p.unpackError = priorError;
+        }
+        else
+        {
+            t.emplace(std::move(value));
+        }
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::array<T, N> */
+template <typename T, size_t N>
+struct UnpackSingle<std::array<T, N>>
+{
+    static int op(Payload& p, std::array<T, N>& t)
+    {
+        int ret = 0;
+        size_t priorIndex = p.rawIndex;
+        for (auto& v : t)
+        {
+            ret = UnpackSingle<T>::op(p, v);
+            if (ret)
+            {
+                p.rawIndex = priorIndex;
+                t = std::array<T, N>();
+                break;
+            }
+        }
+        return ret;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::array<uint8_t> */
+template <size_t N>
+struct UnpackSingle<std::array<uint8_t, N>>
+{
+    static int op(Payload& p, std::array<uint8_t, N>& t)
+    {
+        if (p.raw.size() - p.rawIndex < N)
+        {
+            t.fill(0);
+            return -1;
+        }
+        // copy out the bytes
+        std::copy(p.raw.begin() + p.rawIndex, p.raw.begin() + p.rawIndex + N,
+                  t.begin());
+        p.rawIndex += N;
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::vector<T> */
+template <typename T>
+struct UnpackSingle<std::vector<T>>
+{
+    static int op(Payload& p, std::vector<T>& t)
+    {
+        while (p.rawIndex < p.raw.size())
+        {
+            t.emplace_back();
+            if (UnpackSingle<T>::op(p, t.back()))
+            {
+                t.pop_back();
+                break;
+            }
+        }
+        // unpacking a vector is always successful:
+        // either stuff was unpacked successfully (return 0)
+        // or stuff was not unpacked, but should still return
+        // success because an empty vector or a not-fully-unpacked
+        // payload is not a failure.
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::vector<uint8_t> */
+template <>
+struct UnpackSingle<std::vector<uint8_t>>
+{
+    static int op(Payload& p, std::vector<uint8_t>& t)
+    {
+        // copy out the remainder of the message
+        t.reserve(p.raw.size() - p.rawIndex);
+        t.insert(t.begin(), p.raw.begin() + p.rawIndex, p.raw.end());
+        p.rawIndex = p.raw.size();
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for SecureBuffer */
+template <>
+struct UnpackSingle<SecureBuffer>
+{
+    static int op(Payload& p, SecureBuffer& t)
+    {
+        // copy out the remainder of the message
+        t.reserve(p.raw.size() - p.rawIndex);
+        t.insert(t.begin(), p.raw.begin() + p.rawIndex, p.raw.end());
+        p.rawIndex = p.raw.size();
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for std::span<const uint8_t> */
+template <>
+struct UnpackSingle<std::span<const uint8_t>>
+{
+    static int op(Payload& p, std::span<const uint8_t>& t)
+    {
+        // copy out the remainder of the message
+        t = std::span<const uint8_t>(p.raw.begin() + p.rawIndex, p.raw.end());
+        p.rawIndex = p.raw.size();
+        return 0;
+    }
+};
+
+/** @brief Specialization of UnpackSingle for Payload */
+template <>
+struct UnpackSingle<Payload>
+{
+    static int op(Payload& p, Payload& t)
+    {
+        t = p;
+        // mark that this payload is being included in the args
+        p.trailingOk = true;
+        return 0;
+    }
+};
+
+} // namespace details
+
+} // namespace message
+
+} // namespace ipmi
diff --git a/include/ipmid/oemopenbmc.hpp b/include/ipmid/oemopenbmc.hpp
new file mode 100644
index 0000000..b7b3a30
--- /dev/null
+++ b/include/ipmid/oemopenbmc.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <ipmid/api.h>
+
+#include <ipmid/oemrouter.hpp>
+
+namespace oem
+{
+/*
+ * OpenBMC OEM Extension IPMI Command codes.
+ */
+enum Cmd
+{
+    gpioCmd = 1,
+    i2cCmd = 2,
+    flashCmd = 3,
+    fanManualCmd = 4,
+    ethStatsCmd = 48,
+    blobTransferCmd = 128,
+};
+
+} // namespace oem
diff --git a/include/ipmid/oemrouter.hpp b/include/ipmid/oemrouter.hpp
new file mode 100644
index 0000000..4759950
--- /dev/null
+++ b/include/ipmid/oemrouter.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <ipmid/api.h>
+
+#include <ipmid/iana.hpp>
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <vector>
+
+namespace oem
+{
+constexpr std::size_t groupMagicSize = 3;
+
+using Group = std::array<std::uint8_t, groupMagicSize>;
+
+// Handler signature includes ipmi cmd to support wildcard cmd match.
+// Buffers and lengths exclude the OemGroup bytes in the IPMI message.
+// dataLen supplies length of reqBuf upon call, and should be set to the
+// length of replyBuf upon return - conventional in this code base.
+using Handler = std::function<ipmi_ret_t(ipmi_cmd_t,          // cmd byte
+                                         const std::uint8_t*, // reqBuf
+                                         std::uint8_t*,       // replyBuf
+                                         std::size_t*)>;      // dataLen
+
+/// Router Interface class.
+/// @brief Abstract Router Interface
+class Router
+{
+  public:
+    virtual ~Router() {}
+
+    /// Enable message routing to begin.
+    virtual void activate() = 0;
+
+    /// Register a handler for given OEMNumber & cmd.
+    /// Use cmdWildcard to catch any unregistered cmd
+    /// for the given OEMNumber.
+    ///
+    /// @param[in] oen - the OEM Number.
+    /// @param[in] cmd - the Command.
+    /// @param[in] handler - the handler to call given that OEN and
+    ///                      command.
+    virtual void registerHandler(Number oen, ipmi_cmd_t cmd,
+                                 Handler handler) = 0;
+};
+
+/// Expose mutable Router for configuration & activation.
+///
+/// @returns pointer to OEM Router to use.
+Router* mutableRouter();
+
+/// Convert a group to an OEN.
+///
+/// @param[in] oeg - request buffer for IPMI command.
+/// @return the OEN.
+constexpr Number toOemNumber(const std::uint8_t oeg[groupMagicSize])
+{
+    return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0];
+}
+
+/// Given a Group convert to an OEN.
+///
+/// @param[in] oeg - OEM Group reference.
+/// @return the OEN.
+constexpr Number toOemNumber(const Group& oeg)
+{
+    return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0];
+}
+
+/// Given an OEN, conver to the OEM Group.
+///
+/// @param[in] oen - the OEM Number.
+/// @return the OEM Group.
+constexpr Group toOemGroup(Number oen)
+{
+    return Group{static_cast<std::uint8_t>(oen),
+                 static_cast<std::uint8_t>(oen >> 8),
+                 static_cast<std::uint8_t>(oen >> 16)};
+}
+
+} // namespace oem
diff --git a/include/ipmid/sessiondef.hpp b/include/ipmid/sessiondef.hpp
new file mode 100644
index 0000000..0311c91
--- /dev/null
+++ b/include/ipmid/sessiondef.hpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 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.
+ *
+ */
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace session
+{
+
+static constexpr auto sessionManagerRootPath =
+    "/xyz/openbmc_project/ipmi/session";
+static constexpr auto sessionIntf = "xyz.openbmc_project.Ipmi.SessionInfo";
+static constexpr uint8_t ipmi20VerSession = 0x01;
+static constexpr size_t maxSessionCountPerChannel = 15;
+static constexpr size_t sessionZero = 0;
+static constexpr size_t maxSessionlessCount = 1;
+static constexpr uint8_t invalidSessionID = 0;
+static constexpr uint8_t invalidSessionHandle = 0;
+static constexpr uint8_t defaultSessionHandle = 0xFF;
+static constexpr uint8_t maxNetworkInstanceSupported = 4;
+static constexpr uint8_t ccInvalidSessionId = 0x87;
+static constexpr uint8_t ccInvalidSessionHandle = 0x88;
+static constexpr uint8_t searchCurrentSession = 0;
+static constexpr uint8_t searchSessionByHandle = 0xFE;
+static constexpr uint8_t searchSessionById = 0xFF;
+// MSB BIT 7 BIT 6 assigned for netipmid instance in session handle.
+static constexpr uint8_t multiIntfaceSessionHandleMask = 0x3F;
+
+// MSB BIT 31-BIT30 assigned for netipmid instance in session ID
+static constexpr uint32_t multiIntfaceSessionIDMask = 0x3FFFFFFF;
+
+enum class State : uint8_t
+{
+    inactive,           // Session is not in use
+    setupInProgress,    // Session Setup Sequence is progressing
+    active,             // Session is active
+    tearDownInProgress, // When Closing Session
+};
+
+} // namespace session
diff --git a/include/ipmid/sessionhelper.hpp b/include/ipmid/sessionhelper.hpp
new file mode 100644
index 0000000..5c09bfc
--- /dev/null
+++ b/include/ipmid/sessionhelper.hpp
@@ -0,0 +1,91 @@
+#pragma once
+
+#include <cstdint>
+#include <sstream>
+#include <string>
+
+/**
+ * @brief parse session input payload.
+ *
+ * This function retrives the session id and session handle from the session
+ * object path.
+ * A valid object path will be in the form
+ * "/xyz/openbmc_project/ipmi/session/channel/sessionId_sessionHandle"
+ *
+ * Ex: "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a"
+ * SessionId    : 0X12a4567d
+ * SessionHandle: 0X8a
+
+ * @param[in] objectPath - session object path
+ * @param[in] sessionId - retrived session id will be asigned.
+ * @param[in] sessionHandle - retrived session handle will be asigned.
+ *
+ * @return true if session id and session handle are retrived else returns
+ * false.
+ */
+bool parseCloseSessionInputPayload(const std::string& objectPath,
+                                   uint32_t& sessionId, uint8_t& sessionHandle)
+{
+    if (objectPath.empty())
+    {
+        return false;
+    }
+    // getting the position of session id and session handle string from
+    // object path.
+    std::size_t ptrPosition = objectPath.rfind("/");
+    uint16_t tempSessionHandle = 0;
+
+    if (ptrPosition != std::string::npos)
+    {
+        // get the sessionid & session handle string from the session object
+        // path Ex: sessionIdString: "12a4567d_8a"
+        std::string sessionIdString = objectPath.substr(ptrPosition + 1);
+        std::size_t pos = sessionIdString.rfind("_");
+
+        if (pos != std::string::npos)
+        {
+            // extracting the session handle
+            std::string sessionHandleString = sessionIdString.substr(pos + 1);
+            // extracting the session id
+            sessionIdString = sessionIdString.substr(0, pos);
+            // converting session id string  and session handle string to
+            // hexadecimal.
+            std::stringstream handle(sessionHandleString);
+            handle >> std::hex >> tempSessionHandle;
+            sessionHandle = tempSessionHandle & 0xFF;
+            std::stringstream idString(sessionIdString);
+            idString >> std::hex >> sessionId;
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * @brief is session object matched.
+ *
+ * This function checks whether the objectPath contains reqSessionId and
+ * reqSessionHandle, e.g., "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a"
+ * matches sessionId 0x12a4567d and sessionHandle 0x8a.
+ *
+ * @param[in] objectPath - session object path
+ * @param[in] reqSessionId - request session id
+ * @param[in] reqSessionHandle - request session handle
+ *
+ * @return true if the object is matched else return false
+ **/
+bool isSessionObjectMatched(const std::string objectPath,
+                            const uint32_t reqSessionId,
+                            const uint8_t reqSessionHandle)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+
+    if (parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle))
+    {
+        return (reqSessionId == sessionId) ||
+               (reqSessionHandle == sessionHandle);
+    }
+
+    return false;
+}
diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
new file mode 100644
index 0000000..91ff346
--- /dev/null
+++ b/include/ipmid/types.hpp
@@ -0,0 +1,326 @@
+#pragma once
+
+#include <openssl/crypto.h>
+#include <stdint.h>
+
+#include <sdbusplus/server.hpp>
+
+#include <map>
+#include <string>
+#include <variant>
+
+namespace ipmi
+{
+
+using DbusObjectPath = std::string;
+using DbusService = std::string;
+using DbusInterface = std::string;
+using DbusObjectInfo = std::pair<DbusObjectPath, DbusService>;
+using DbusProperty = std::string;
+
+using Association = std::tuple<std::string, std::string, std::string>;
+using BootProgressCode = std::tuple<std::vector<uint8_t>, std::vector<uint8_t>>;
+
+using Value = std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
+                           int64_t, uint64_t, double, std::string,
+                           std::vector<uint8_t>, std::vector<uint16_t>,
+                           std::vector<uint32_t>, std::vector<std::string>,
+                           std::vector<Association>, BootProgressCode>;
+
+using PropertyMap = std::map<DbusProperty, Value>;
+
+using ObjectTree =
+    std::map<DbusObjectPath, std::map<DbusService, std::vector<DbusInterface>>>;
+
+using InterfaceList = std::vector<std::string>;
+
+using DbusInterfaceMap = std::map<DbusInterface, PropertyMap>;
+
+using ObjectValueTree =
+    std::map<sdbusplus::message::object_path, DbusInterfaceMap>;
+
+namespace sensor
+{
+
+using Offset = uint8_t;
+
+/**
+ * @enum SkipAssertion
+ * Matching value for skipping the update
+ */
+enum class SkipAssertion
+{
+    NONE,     // No skip defined
+    ASSERT,   // Skip on Assert
+    DEASSERT, // Skip on Deassert
+};
+
+struct Values
+{
+    SkipAssertion skip;
+    Value assert;
+    Value deassert;
+};
+
+/**
+ * @enum PreReqValues
+ * Pre-req conditions for a property.
+ */
+struct PreReqValues
+{
+    Value assert;   // Value in case of assert.
+    Value deassert; // Value in case of deassert.
+};
+
+using PreReqOffsetValueMap = std::map<Offset, PreReqValues>;
+
+/**
+ * @struct SetSensorReadingReq
+ *
+ * IPMI Request data for Set Sensor Reading and Event Status Command
+ */
+struct SetSensorReadingReq
+{
+    uint8_t number;
+    uint8_t operation;
+    uint8_t reading;
+    uint8_t assertOffset0_7;
+    uint8_t assertOffset8_14;
+    uint8_t deassertOffset0_7;
+    uint8_t deassertOffset8_14;
+    uint8_t eventData1;
+    uint8_t eventData2;
+    uint8_t eventData3;
+} __attribute__((packed));
+
+/**
+ * @struct GetReadingResponse
+ *
+ * IPMI response data for Get Sensor Reading command.
+ */
+struct GetReadingResponse
+{
+    uint8_t reading;          //!< Sensor reading.
+    uint8_t operation;        //!< Sensor scanning status / reading state.
+    uint8_t assertOffset0_7;  //!< Discrete assertion states(0-7).
+    uint8_t assertOffset8_14; //!< Discrete assertion states(8-14).
+} __attribute__((packed));
+
+constexpr auto inventoryRoot = "/xyz/openbmc_project/inventory";
+
+struct GetSensorResponse
+{
+    uint8_t reading;                     // sensor reading
+    bool readingOrStateUnavailable;      // 1 = reading/state unavailable
+    bool scanningEnabled;                // 0 = sensor scanning disabled
+    bool allEventMessagesEnabled;        // 0 = All Event Messages disabled
+    uint8_t thresholdLevelsStates;       // threshold/discrete sensor states
+    uint8_t discreteReadingSensorStates; // discrete-only, optional states
+};
+
+using OffsetValueMap = std::map<Offset, Values>;
+
+using DbusPropertyValues = std::pair<PreReqOffsetValueMap, OffsetValueMap>;
+
+using DbusPropertyMap = std::map<DbusProperty, DbusPropertyValues>;
+
+using DbusInterfaceMap = std::map<DbusInterface, DbusPropertyMap>;
+
+using InstancePath = std::string;
+using Type = uint8_t;
+using ReadingType = uint8_t;
+using Multiplier = uint16_t;
+using OffsetB = int16_t;
+using Exponent = int8_t;
+using ScaledOffset = double;
+using Scale = int16_t;
+using Unit = std::string;
+using EntityType = uint8_t;
+using EntityInst = uint8_t;
+using SensorName = std::string;
+using SensorUnits1 = uint8_t;
+
+enum class Mutability
+{
+    Read = 1 << 0,
+    Write = 1 << 1,
+};
+
+inline Mutability operator|(Mutability lhs, Mutability rhs)
+{
+    return static_cast<Mutability>(
+        static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
+}
+
+inline Mutability operator&(Mutability lhs, Mutability rhs)
+{
+    return static_cast<Mutability>(
+        static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
+}
+
+struct Info
+{
+    EntityType entityType;
+    EntityInst instance;
+    Type sensorType;
+    InstancePath sensorPath;
+    DbusInterface sensorInterface;
+    ReadingType sensorReadingType;
+    Multiplier coefficientM;
+    OffsetB coefficientB;
+    Exponent exponentB;
+    ScaledOffset scaledOffset;
+    Exponent exponentR;
+    bool hasScale;
+    Scale scale;
+    SensorUnits1 sensorUnits1;
+    Unit unit;
+    std::function<uint8_t(SetSensorReadingReq&, const Info&)> updateFunc;
+#ifndef FEATURE_SENSORS_CACHE
+    std::function<GetSensorResponse(const Info&)> getFunc;
+#else
+    std::function<std::optional<GetSensorResponse>(uint8_t, const Info&,
+                                                   const ipmi::PropertyMap&)>
+        getFunc;
+#endif
+    Mutability mutability;
+    SensorName sensorName;
+    std::function<SensorName(const Info&)> sensorNameFunc;
+    DbusInterfaceMap propertyInterfaces;
+};
+
+using Id = uint8_t;
+using IdInfoMap = std::map<Id, Info>;
+
+using PropertyMap = ipmi::PropertyMap;
+
+using InterfaceMap = std::map<DbusInterface, PropertyMap>;
+
+using Object = sdbusplus::message::object_path;
+using ObjectMap = std::map<Object, InterfaceMap>;
+
+using IpmiUpdateData = sdbusplus::message_t;
+
+struct SelData
+{
+    Id sensorID;
+    Type sensorType;
+    ReadingType eventReadingType;
+    Offset eventOffset;
+};
+
+using InventoryPath = std::string;
+
+using InvObjectIDMap = std::map<InventoryPath, SelData>;
+
+enum class ThresholdMask
+{
+    NON_CRITICAL_LOW_MASK = 0x01,
+    CRITICAL_LOW_MASK = 0x02,
+    NON_RECOVERABLE_LOW_MASK = 0x4,
+    NON_CRITICAL_HIGH_MASK = 0x08,
+    CRITICAL_HIGH_MASK = 0x10,
+    NON_RECOVERABLE_HIGH_MASK = 0x20,
+};
+
+static constexpr uint8_t maxContainedEntities = 4;
+using ContainedEntitiesArray =
+    std::array<std::pair<uint8_t, uint8_t>, maxContainedEntities>;
+
+struct EntityInfo
+{
+    uint8_t containerEntityId;
+    uint8_t containerEntityInstance;
+    bool isList;
+    bool isLinked;
+    ContainedEntitiesArray containedEntities;
+};
+
+using EntityInfoMap = std::map<Id, EntityInfo>;
+
+#ifdef FEATURE_SENSORS_CACHE
+/**
+ * @struct SensorData
+ *
+ * The data to cache for sensors
+ */
+struct SensorData
+{
+    double value;
+    bool available;
+    bool functional;
+    GetSensorResponse response;
+};
+
+using SensorCacheMap = std::map<uint8_t, std::optional<SensorData>>;
+#endif
+
+} // namespace sensor
+
+namespace network
+{
+constexpr auto MAC_ADDRESS_FORMAT = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
+
+constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
+constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
+
+constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
+constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
+
+} // namespace network
+
+template <typename T>
+class SecureAllocator : public std::allocator<T>
+{
+  public:
+    template <typename U>
+    struct rebind
+    {
+        typedef SecureAllocator<U> other;
+    };
+
+    void deallocate(T* p, size_t n)
+    {
+        OPENSSL_cleanse(p, n);
+        return std::allocator<T>::deallocate(p, n);
+    }
+};
+
+using SecureStringBase =
+    std::basic_string<char, std::char_traits<char>, SecureAllocator<char>>;
+class SecureString : public SecureStringBase
+{
+  public:
+    using SecureStringBase::basic_string;
+    SecureString(const SecureStringBase& other) : SecureStringBase(other) {};
+    SecureString(SecureString&) = default;
+    SecureString(const SecureString&) = default;
+    SecureString(SecureString&&) = default;
+    SecureString& operator=(SecureString&&) = default;
+    SecureString& operator=(const SecureString&) = default;
+
+    ~SecureString()
+    {
+        OPENSSL_cleanse(this->data(), this->size());
+    }
+};
+
+using SecureBufferBase = std::vector<uint8_t, SecureAllocator<uint8_t>>;
+
+class SecureBuffer : public SecureBufferBase
+{
+  public:
+    using SecureBufferBase::vector;
+    SecureBuffer(const SecureBufferBase& other) : SecureBufferBase(other) {};
+    SecureBuffer(SecureBuffer&) = default;
+    SecureBuffer(const SecureBuffer&) = default;
+    SecureBuffer(SecureBuffer&&) = default;
+    SecureBuffer& operator=(SecureBuffer&&) = default;
+    SecureBuffer& operator=(const SecureBuffer&) = default;
+
+    ~SecureBuffer()
+    {
+        OPENSSL_cleanse(this->data(), this->size());
+    }
+};
+} // namespace ipmi
diff --git a/include/ipmid/utility.hpp b/include/ipmid/utility.hpp
new file mode 100644
index 0000000..a3f306f
--- /dev/null
+++ b/include/ipmid/utility.hpp
@@ -0,0 +1,223 @@
+/**
+ * Copyright © 2018 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.
+ */
+#pragma once
+#include <boost/asio/spawn.hpp>
+#include <boost/callable_traits.hpp>
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <vector>
+
+namespace ipmi
+{
+
+// forward declare Context and Request for NonIpmiArgsCount
+struct Context;
+namespace message
+{
+struct Request;
+}
+
+namespace utility
+{
+
+/**
+ * @brief a utility template to extract the args after N from a tuple
+ *
+ * Given a tuple of type <T1, ...TN, TN+1, ...>, provide type = tuple<TN+1,...>
+ */
+template <std::size_t N, typename FirstArg, typename... Rest>
+struct StripFirstArgs;
+
+template <std::size_t N, typename FirstArg, typename... Rest>
+struct StripFirstArgs<N, std::tuple<FirstArg, Rest...>> :
+    StripFirstArgs<N - 1, std::tuple<Rest...>>
+{};
+
+template <typename FirstArg, typename... Rest>
+struct StripFirstArgs<0, std::tuple<FirstArg, Rest...>>
+{
+    using type = std::tuple<FirstArg, Rest...>;
+};
+template <std::size_t N>
+struct StripFirstArgs<N, std::tuple<>>
+{
+    using type = std::tuple<>;
+};
+
+/**
+ * @brief a utility template to extract the remaining args from a tuple
+ *
+ * Given a tuple of type <T1, T2,...>, provide type = tuple<T2,...>
+ */
+template <typename T>
+using StripFirstArg = StripFirstArgs<1, T>;
+
+/**
+ * @brief a utility template to find the number of non-special arguments
+ *
+ * Given a tuple, count the args after the first special args
+ */
+template <typename FirstArg, typename... Rest>
+struct NonIpmiArgsCount;
+
+template <>
+struct NonIpmiArgsCount<std::tuple<>>
+{
+    constexpr static std::size_t size()
+    {
+        return 0;
+    }
+};
+template <typename FirstArg, typename... OtherArgs>
+struct NonIpmiArgsCount<std::tuple<FirstArg, OtherArgs...>>
+{
+    constexpr static std::size_t size()
+    {
+        if constexpr (std::is_same<
+                          FirstArg,
+                          std::shared_ptr<ipmi::message::Request>>::value ||
+                      std::is_same<FirstArg,
+                                   std::shared_ptr<ipmi::Context>>::value ||
+                      std::is_same<FirstArg, boost::asio::yield_context>::value)
+        {
+            return 1 + NonIpmiArgsCount<std::tuple<OtherArgs...>>::size();
+        }
+        else
+        {
+            return NonIpmiArgsCount<std::tuple<OtherArgs...>>::size();
+        }
+    }
+};
+
+/**
+ * @brief a utility template to find the type of the first arg
+ *
+ * Given a tuple, provide the type of the first element
+ */
+template <typename T>
+struct GetFirstArg
+{
+    using type = void;
+};
+
+template <typename FirstArg, typename... Rest>
+struct GetFirstArg<std::tuple<FirstArg, Rest...>>
+{
+    using type = FirstArg;
+};
+
+/**
+ * @brief a utility template to remove const and reference from types
+ *
+ * Given a tuple, provide the type of the first element
+ */
+template <typename... Args>
+struct DecayTuple;
+
+template <typename... Args>
+struct DecayTuple<std::tuple<Args...>>
+{
+    using type = std::tuple<typename std::decay<Args>::type...>;
+};
+
+/** @brief Convert T[N] to T* if is_same<Tbase,T>
+ *
+ *  @tparam Tbase - The base type expected.
+ *  @tparam T - The type to convert.
+ */
+template <typename Tbase, typename T>
+using ArrayToPtr_t = typename std::conditional_t<
+    std::is_array<T>::value,
+    std::conditional_t<std::is_same<Tbase, std::remove_extent_t<T>>::value,
+                       std::add_pointer_t<std::remove_extent_t<T>>, T>,
+    T>;
+
+/** @brief Downcast type submembers.
+ *
+ * This allows std::tuple and std::pair members to be downcast to their
+ * non-const, nonref versions of themselves to limit duplication in template
+ * specializations
+ *
+ *  1. Remove references.
+ *  2. Remove 'const' and 'volatile'.
+ *  3. Convert 'char[N]' to 'char*'.
+ */
+template <typename T>
+struct DowncastMembers
+{
+    using type = T;
+};
+template <typename... Args>
+struct DowncastMembers<std::pair<Args...>>
+{
+    using type = std::pair<utility::ArrayToPtr_t<
+        char, std::remove_cv_t<std::remove_reference_t<Args>>>...>;
+};
+
+template <typename... Args>
+struct DowncastMembers<std::tuple<Args...>>
+{
+    using type = std::tuple<utility::ArrayToPtr_t<
+        char, std::remove_cv_t<std::remove_reference_t<Args>>>...>;
+};
+
+template <typename T>
+using DowncastMembers_t = typename DowncastMembers<T>::type;
+
+/** @brief Convert some C++ types to others for 'TypeId' conversion purposes.
+ *
+ *  Similar C++ types have the same dbus type-id, so 'downcast' those to limit
+ *  duplication in TypeId template specializations.
+ *
+ *  1. Remove references.
+ *  2. Remove 'const' and 'volatile'.
+ *  3. Convert 'char[N]' to 'char*'.
+ */
+template <typename T>
+struct TypeIdDowncast
+{
+    using type = utility::ArrayToPtr_t<
+        char, DowncastMembers_t<std::remove_cv_t<std::remove_reference_t<T>>>>;
+};
+
+template <typename T>
+using TypeIdDowncast_t = typename TypeIdDowncast<T>::type;
+
+/** @brief Detect if a type is a tuple
+ *
+ */
+template <typename>
+struct is_tuple : std::false_type
+{};
+
+template <typename... T>
+struct is_tuple<std::tuple<T...>> : std::true_type
+{};
+
+/** @brief used for static_assert in a constexpr-if else statement
+ */
+template <typename T>
+struct dependent_false : std::false_type
+{};
+
+} // namespace utility
+
+} // namespace ipmi
diff --git a/include/ipmid/utils.hpp b/include/ipmid/utils.hpp
new file mode 100644
index 0000000..4547dc0
--- /dev/null
+++ b/include/ipmid/utils.hpp
@@ -0,0 +1,506 @@
+#pragma once
+
+#include <boost/system/error_code.hpp>
+#include <ipmid/api-types.hpp>
+#include <ipmid/message.hpp>
+#include <ipmid/types.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/server.hpp>
+
+#include <chrono>
+#include <optional>
+
+namespace ipmi
+{
+
+using namespace std::literals::chrono_literals;
+
+constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper";
+constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper";
+constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";
+
+constexpr auto ROOT = "/";
+constexpr auto HOST_MATCH = "host0";
+
+constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
+constexpr auto DELETE_INTERFACE = "xyz.openbmc_project.Object.Delete";
+
+constexpr auto METHOD_GET = "Get";
+constexpr auto METHOD_GET_ALL = "GetAll";
+constexpr auto METHOD_SET = "Set";
+
+/* Use a value of 5s which aligns with BT/KCS bridged timeouts, rather
+ * than the default 25s D-Bus timeout. */
+constexpr std::chrono::microseconds IPMI_DBUS_TIMEOUT = 5s;
+
+/** @class ServiceCache
+ *  @brief Caches lookups of service names from the object mapper.
+ *  @details Most ipmi commands need to talk to other dbus daemons to perform
+ *           their intended actions on the BMC. This usually means they will
+ *           first look up the service name providing the interface they
+ *           require. This class reduces the number of such calls by caching
+ *           the lookup for a specific service.
+ */
+class ServiceCache
+{
+  public:
+    /** @brief Creates a new service cache for the given interface
+     *         and path.
+     *
+     *  @param[in] intf - The interface used for each lookup
+     *  @param[in] path - The path used for each lookup
+     */
+    ServiceCache(const std::string& intf, const std::string& path);
+    ServiceCache(std::string&& intf, std::string&& path);
+
+    /** @brief Gets the service name from the cache or does in a
+     *         lookup when invalid.
+     *
+     *  @param[in] bus - The bus associated with and used for looking
+     *                   up the service.
+     */
+    const std::string& getService(sdbusplus::bus_t& bus);
+
+    /** @brief Invalidates the current service name */
+    void invalidate();
+
+    /** @brief A wrapper around sdbusplus bus.new_method_call
+     *
+     *  @param[in] bus - The bus used for calling the method
+     *  @param[in] intf - The interface containing the method
+     *  @param[in] method - The method name
+     *  @return The message containing the method call.
+     */
+    sdbusplus::message_t newMethodCall(sdbusplus::bus_t& bus, const char* intf,
+                                       const char* method);
+
+    /** @brief Check to see if the current cache is valid
+     *
+     * @param[in] bus - The bus used for the service lookup
+     * @return True if the cache is valid false otherwise.
+     */
+    bool isValid(sdbusplus::bus_t& bus) const;
+
+  private:
+    /** @brief DBUS interface provided by the service */
+    const std::string intf;
+    /** @brief DBUS path provided by the service */
+    const std::string path;
+    /** @brief The name of the service if valid */
+    std::optional<std::string> cachedService;
+    /** @brief The name of the bus used in the service lookup */
+    std::optional<std::string> cachedBusName;
+};
+
+/**
+ * @brief Get the DBUS Service name for the input dbus path
+ *
+ * @param[in] bus - DBUS Bus Object
+ * @param[in] intf - DBUS Interface
+ * @param[in] path - DBUS Object Path
+ *
+ */
+std::string getService(sdbusplus::bus_t& bus, const std::string& intf,
+                       const std::string& path);
+
+/** @brief Gets the dbus sub tree implementing the given interface.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] interfaces - Dbus interface.
+ *  @param[in] subtreePath - subtree from where the search should start.
+ *  @param[in] depth - Search depth
+ *  @return map of object path and service info.
+ */
+ObjectTree getSubTree(sdbusplus::bus_t& bus, const InterfaceList& interface,
+                      const std::string& subtreePath = ROOT, int32_t depth = 0);
+
+/** @brief Gets the dbus object info implementing the given interface
+ *         from the given subtree.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] subtreePath - subtree from where the search should start.
+ *  @param[in] match - identifier for object.
+ *  @return On success returns the object having objectpath and servicename.
+ */
+DbusObjectInfo getDbusObject(
+    sdbusplus::bus_t& bus, const std::string& interface,
+    const std::string& subtreePath = ROOT, const std::string& match = {});
+
+/** @brief Gets the value associated with the given object
+ *         and the interface.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] service - Dbus service name.
+ *  @param[in] objPath - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] property - name of the property.
+ *  @return On success returns the value of the property.
+ */
+Value getDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                      const std::string& objPath, const std::string& interface,
+                      const std::string& property,
+                      std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);
+
+/** @brief Gets all the properties associated with the given object
+ *         and the interface.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] service - Dbus service name.
+ *  @param[in] objPath - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *  @return On success returns the map of name value pair.
+ */
+PropertyMap getAllDbusProperties(
+    sdbusplus::bus_t& bus, const std::string& service,
+    const std::string& objPath, const std::string& interface,
+    std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);
+
+/** @brief Gets all managed objects associated with the given object
+ *         path and service.
+ *  @param[in] bus - D-Bus Bus Object.
+ *  @param[in] service - D-Bus service name.
+ *  @param[in] objPath - D-Bus object path.
+ *  @return On success returns the map of name value pair.
+ */
+ObjectValueTree getManagedObjects(sdbusplus::bus_t& bus,
+                                  const std::string& service,
+                                  const std::string& objPath);
+
+/** @brief Sets the property value of the given object.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] service - Dbus service name.
+ *  @param[in] objPath - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] property - name of the property.
+ *  @param[in] value - value which needs to be set.
+ */
+void setDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                     const std::string& objPath, const std::string& interface,
+                     const std::string& property, const Value& value,
+                     std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);
+
+/** @brief  Gets all the dbus objects from the given service root
+ *          which matches the object identifier.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] serviceRoot - Service root path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] match - Identifier for a path.
+ *  @returns map of object path and service info.
+ */
+ObjectTree getAllDbusObjects(
+    sdbusplus::bus_t& bus, const std::string& serviceRoot,
+    const std::string& interface, const std::string& match = {});
+
+/** @brief Deletes all the dbus objects from the given service root
+           which matches the object identifier.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] serviceRoot - Service root path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] match - Identifier for object.
+ */
+void deleteAllDbusObjects(sdbusplus::bus_t& bus, const std::string& serviceRoot,
+                          const std::string& interface,
+                          const std::string& match = {})
+    __attribute__((deprecated));
+
+/** @brief Gets the ancestor objects of the given object
+           which implements the given interface.
+ *  @param[in] bus - Dbus bus object.
+ *  @param[in] path - Child Dbus object path.
+ *  @param[in] interfaces - Dbus interface list.
+ *  @return map of object path and service info.
+ */
+ObjectTree getAllAncestors(sdbusplus::bus_t& bus, const std::string& path,
+                           InterfaceList&& interfaces)
+    __attribute__((deprecated));
+
+/********* Begin co-routine yielding alternatives ***************/
+
+/** @brief Get the D-Bus Service name for the input D-Bus path
+ *
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] intf - D-Bus Interface
+ *  @param[in] path - D-Bus Object Path
+ *  @param[out] service - requested service name
+ *  @return boost error code
+ *
+ */
+boost::system::error_code getService(Context::ptr ctx, const std::string& intf,
+                                     const std::string& path,
+                                     std::string& service);
+
+/** @brief Gets the dbus sub tree implementing the given interface.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] interfaces - Dbus interface.
+ *  @param[in] subtreePath - subtree from where the search should start.
+ *  @param[in] depth - Search depth
+ *  @param[out] objectTree - map of object path and service info.
+ *  @return map of object path and service info.
+ */
+boost::system::error_code getSubTree(
+    Context::ptr ctx, const InterfaceList& interface,
+    const std::string& subtreePath, int32_t depth, ObjectTree& objectTree);
+
+/** @brief Gets the D-Bus object info implementing the given interface
+ *         from the given subtree.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] interface - D-Bus interface.
+ *  @param[in][optional] subtreePath - subtree from where the search starts.
+ *  @param[in][optional] match - identifier for object.
+ *  @param[out] D-Bus object with path and service name
+ *  @return - boost error code object
+ */
+boost::system::error_code getDbusObject(
+    Context::ptr ctx, const std::string& interface,
+    const std::string& subtreePath, const std::string& match,
+    DbusObjectInfo& dbusObject);
+
+// default for ROOT for subtreePath and std::string{} for match
+static inline boost::system::error_code getDbusObject(
+    Context::ptr ctx, const std::string& interface, DbusObjectInfo& dbusObject)
+{
+    return getDbusObject(ctx, interface, ROOT, {}, dbusObject);
+}
+
+// default std::string{} for match
+static inline boost::system::error_code getDbusObject(
+    Context::ptr ctx, const std::string& interface,
+    const std::string& subtreePath, DbusObjectInfo& dbusObject)
+{
+    return getDbusObject(ctx, interface, subtreePath, {}, dbusObject);
+}
+
+/** @brief Gets the value associated with the given object
+ *         and the interface.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] service - D-Bus service name.
+ *  @param[in] objPath - D-Bus object path.
+ *  @param[in] interface - D-Bus interface.
+ *  @param[in] property - name of the property.
+ *  @param[out] propertyValue - value of the D-Bus property.
+ *  @return - boost error code object
+ */
+template <typename Type>
+boost::system::error_code getDbusProperty(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, const std::string& property,
+    Type& propertyValue)
+{
+    boost::system::error_code ec;
+    auto variant = ctx->bus->yield_method_call<std::variant<Type>>(
+        ctx->yield, ec, service.c_str(), objPath.c_str(), PROP_INTF, METHOD_GET,
+        interface, property);
+    if (!ec)
+    {
+        Type* tmp = std::get_if<Type>(&variant);
+        if (tmp)
+        {
+            propertyValue = *tmp;
+            return ec;
+        }
+        // user requested incorrect type; make an error code for them
+        ec = boost::system::errc::make_error_code(
+            boost::system::errc::invalid_argument);
+    }
+    return ec;
+}
+
+/** @brief Gets all the properties associated with the given object
+ *         and the interface.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] service - D-Bus service name.
+ *  @param[in] objPath - D-Bus object path.
+ *  @param[in] interface - D-Bus interface.
+ *  @param[out] properties - map of name value pair.
+ *  @return - boost error code object
+ */
+boost::system::error_code getAllDbusProperties(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, PropertyMap& properties);
+
+/** @brief Sets the property value of the given object.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] service - D-Bus service name.
+ *  @param[in] objPath - D-Bus object path.
+ *  @param[in] interface - D-Bus interface.
+ *  @param[in] property - name of the property.
+ *  @param[in] value - value which needs to be set.
+ *  @return - boost error code object
+ */
+boost::system::error_code setDbusProperty(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, const std::string& property,
+    const Value& value);
+
+/** @brief  Gets all the D-Bus objects from the given service root
+ *          which matches the object identifier.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] serviceRoot - Service root path.
+ *  @param[in] interface - D-Bus interface.
+ *  @param[in][optional] match - Identifier for a path.
+ *  @param[out] objectree - map of object path and service info.
+ *  @return - boost error code object
+ */
+boost::system::error_code getAllDbusObjects(
+    Context::ptr ctx, const std::string& serviceRoot,
+    const std::string& interface, const std::string& match,
+    ObjectTree& objectTree);
+
+// default std::string{} for match
+static inline boost::system::error_code getAllDbusObjects(
+    Context::ptr ctx, const std::string& serviceRoot,
+    const std::string& interface, ObjectTree& objectTree)
+{
+    return getAllDbusObjects(ctx, serviceRoot, interface, {}, objectTree);
+}
+
+/** @brief Deletes all the D-Bus objects from the given service root
+           which matches the object identifier.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[out] ec - boost error code object
+ *  @param[in] serviceRoot - Service root path.
+ *  @param[in] interface - D-Bus interface.
+ *  @param[in] match - Identifier for object.
+ */
+boost::system::error_code deleteAllDbusObjects(
+    Context::ptr ctx, const std::string& serviceRoot,
+    const std::string& interface, const std::string& match = {})
+    __attribute__((deprecated));
+
+/** @brief Gets all managed objects associated with the given object
+ *         path and service.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] service - D-Bus service name.
+ *  @param[in] objPath - D-Bus object path.
+ *  @param[out] objects - map of name value pair.
+ *  @return - boost error code object
+ */
+boost::system::error_code getManagedObjects(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    ObjectValueTree& objects);
+
+/** @brief Gets the ancestor objects of the given object
+           which implements the given interface.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] path - Child D-Bus object path.
+ *  @param[in] interfaces - D-Bus interface list.
+ *  @param[out] ObjectTree - map of object path and service info.
+ *  @return - boost error code object
+ */
+boost::system::error_code getAllAncestors(
+    Context::ptr ctx, const std::string& path, const InterfaceList& interfaces,
+    ObjectTree& objectTree) __attribute__((deprecated));
+
+/** @brief Gets the value associated with the given object
+ *         and the interface.
+ *  @param[in] ctx - ipmi::Context::ptr
+ *  @param[in] service - D-Bus service name.
+ *  @param[in] objPath - D-Bus object path.
+ *  @param[in] interface - D-Bus interface.
+ *  @param[in] method - name of the method.
+ *  @return - boost error code object
+ */
+
+boost::system::error_code callDbusMethod(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, const std::string& method);
+
+/********* End co-routine yielding alternatives ***************/
+
+/** @brief Retrieve the value from map of variants,
+ *         returning a default if the key does not exist or the
+ *         type of the value does not match the expected type
+ *
+ *  @tparam T - type of expected value to return
+ *  @param[in] props - D-Bus propery map (Map of variants)
+ *  @param[in] name - key name of property to fetch
+ *  @param[in] defaultValue - default value to return on error
+ *  @return - value from propery map at name, or defaultValue
+ */
+template <typename T>
+T mappedVariant(const ipmi::PropertyMap& props, const std::string& name,
+                const T& defaultValue)
+{
+    auto item = props.find(name);
+    if (item == props.end())
+    {
+        return defaultValue;
+    }
+    const T* prop = std::get_if<T>(&item->second);
+    if (!prop)
+    {
+        return defaultValue;
+    }
+    return *prop;
+}
+
+/** @struct VariantToDoubleVisitor
+ *  @brief Visitor to convert variants to doubles
+ *  @details Performs a static cast on the underlying type
+ */
+struct VariantToDoubleVisitor
+{
+    template <typename T>
+    std::enable_if_t<std::is_arithmetic<T>::value, double> operator()(
+        const T& t) const
+    {
+        return static_cast<double>(t);
+    }
+
+    template <typename T>
+    std::enable_if_t<!std::is_arithmetic<T>::value, double> operator()(
+        const T&) const
+    {
+        throw std::invalid_argument("Cannot translate type to double");
+    }
+};
+
+namespace method_no_args
+{
+
+/** @brief Calls the Dbus method which waits for response.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] service - Dbus service name.
+ *  @param[in] objPath - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] method - Dbus method.
+ */
+void callDbusMethod(sdbusplus::bus_t& bus, const std::string& service,
+                    const std::string& objPath, const std::string& interface,
+                    const std::string& method);
+
+} // namespace method_no_args
+
+template <typename... InputArgs>
+boost::system::error_code callDbusMethod(
+    ipmi::Context::ptr ctx, const std::string& service,
+    const std::string& objPath, const std::string& interface,
+    const std::string& method, const InputArgs&... args)
+{
+    boost::system::error_code ec;
+    ctx->bus->yield_method_call(ctx->yield, ec, service, objPath, interface,
+                                method, args...);
+
+    return ec;
+}
+
+template <typename RetType, typename... InputArgs>
+RetType callDbusMethod(ipmi::Context::ptr ctx, boost::system::error_code& ec,
+                       const std::string& service, const std::string& objPath,
+                       const std::string& interface, const std::string& method,
+                       const InputArgs&... args)
+{
+    auto rc = ctx->bus->yield_method_call<RetType>(
+        ctx->yield, ec, service, objPath, interface, method, args...);
+
+    return rc;
+}
+
+/** @brief Perform the low-level i2c bus write-read.
+ *  @param[in] i2cBus - i2c bus device node name, such as /dev/i2c-2.
+ *  @param[in] targetAddr - i2c device target address.
+ *  @param[in] writeData - The data written to i2c device.
+ *  @param[out] readBuf - Data read from the i2c device.
+ */
+ipmi::Cc i2cWriteRead(std::string i2cBus, const uint8_t targetAddr,
+                      std::vector<uint8_t> writeData,
+                      std::vector<uint8_t>& readBuf);
+} // namespace ipmi
diff --git a/include/meson.build b/include/meson.build
new file mode 100644
index 0000000..65b8385
--- /dev/null
+++ b/include/meson.build
@@ -0,0 +1,24 @@
+install_subdir(
+    'dbus-sdr',
+    install_dir: get_option('includedir'),
+    strip_directory: false,
+    exclude_files: '*.cpp',
+)
+
+install_subdir(
+    'ipmid',
+    install_dir: get_option('includedir'),
+    strip_directory: false,
+    exclude_files: '*.cpp',
+)
+
+install_subdir(
+    'ipmid-host',
+    install_dir: get_option('includedir'),
+    strip_directory: false,
+    exclude_files: '*.cpp',
+)
+
+# install the ipmid-host and ipmid includes
+install_subdir('ipmid-host', install_dir: get_option('includedir'))
+install_subdir('ipmid', install_dir: get_option('includedir'))
diff --git a/ipmi_fru_info_area.cpp b/ipmi_fru_info_area.cpp
new file mode 100644
index 0000000..d259731
--- /dev/null
+++ b/ipmi_fru_info_area.cpp
@@ -0,0 +1,485 @@
+#include "ipmi_fru_info_area.hpp"
+
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <algorithm>
+#include <ctime>
+#include <iomanip>
+#include <map>
+#include <numeric>
+#include <sstream>
+
+namespace ipmi
+{
+namespace fru
+{
+using namespace phosphor::logging;
+
+// Property variables
+static constexpr auto partNumber = "Part Number";
+static constexpr auto serialNumber = "Serial Number";
+static constexpr auto manufacturer = "Manufacturer";
+static constexpr auto buildDate = "Mfg Date";
+static constexpr auto modelNumber = "Model Number";
+static constexpr auto prettyName = "Name";
+static constexpr auto version = "Version";
+static constexpr auto type = "Type";
+
+// Board info areas
+static constexpr auto board = "Board";
+static constexpr auto chassis = "Chassis";
+static constexpr auto product = "Product";
+
+static constexpr auto specVersion = 0x1;
+static constexpr auto recordUnitOfMeasurement = 0x8; // size in bytes
+static constexpr auto checksumSize = 0x1;            // size in bytes
+static constexpr auto recordNotPresent = 0x0;
+static constexpr auto englishLanguageCode = 0x0;
+static constexpr auto typeLengthByteNull = 0x0;
+static constexpr auto endOfCustomFields = 0xC1;
+static constexpr auto commonHeaderFormatSize = 0x8; // size in bytes
+static constexpr auto areaSizeOffset = 0x1;
+static constexpr uint8_t typeASCII = 0xC0;
+static constexpr auto maxRecordAttributeValue = 0x3F;
+
+static constexpr auto secs_from_1970_1996 = 820454400;
+static constexpr auto maxMfgDateValue = 0xFFFFFF; // 3 Byte length
+static constexpr auto secs_per_min = 60;
+static constexpr auto secsToMaxMfgdate =
+    secs_from_1970_1996 + secs_per_min * maxMfgDateValue;
+
+// Minimum size of resulting FRU blob.
+// This is also the theoretical maximum size according to the spec:
+// 8 bytes header + 5 areas at 0xff*8 bytes max each
+// 8 + 5*0xff*8 = 0x27e0
+static constexpr auto fruMinSize = 0x27E0;
+
+// Value to use for padding.
+// Using 0xff to match the default (blank) value in a physical EEPROM.
+static constexpr auto fruPadValue = 0xff;
+
+/**
+ * @brief Format Beginning of Individual IPMI FRU Data Section
+ *
+ * @param[in] langCode Language code
+ * @param[in/out] data FRU area data
+ */
+void preFormatProcessing(bool langCode, FruAreaData& data)
+{
+    // Add id for version of FRU Info Storage Spec used
+    data.emplace_back(specVersion);
+
+    // Add Data Size - 0 as a placeholder, can edit after the data is finalized
+    data.emplace_back(typeLengthByteNull);
+
+    if (langCode)
+    {
+        data.emplace_back(englishLanguageCode);
+    }
+}
+
+/**
+ * @brief Append checksum of the FRU area data
+ *
+ * @param[in/out] data FRU area data
+ */
+void appendDataChecksum(FruAreaData& data)
+{
+    uint8_t checksumVal = std::accumulate(data.begin(), data.end(), 0);
+    // Push the Zero checksum as the last byte of this data
+    // This appears to be a simple summation of all the bytes
+    data.emplace_back(-checksumVal);
+}
+
+/**
+ * @brief Append padding bytes for the FRU area data
+ *
+ * @param[in/out] data FRU area data
+ */
+void padData(FruAreaData& data)
+{
+    uint8_t pad = (data.size() + checksumSize) % recordUnitOfMeasurement;
+    if (pad)
+    {
+        data.resize((data.size() + recordUnitOfMeasurement - pad));
+    }
+}
+
+/**
+ * @brief Format End of Individual IPMI FRU Data Section
+ *
+ * @param[in/out] fruAreaData FRU area info data
+ */
+void postFormatProcessing(FruAreaData& data)
+{
+    // This area needs to be padded to a multiple of 8 bytes (after checksum)
+    padData(data);
+
+    // Set size of data info area
+    data.at(areaSizeOffset) =
+        (data.size() + checksumSize) / (recordUnitOfMeasurement);
+
+    // Finally add area checksum
+    appendDataChecksum(data);
+}
+
+/**
+ * @brief Read chassis type property value from inventory and append to the FRU
+ * area data.
+ *
+ * @param[in] propMap map of property values
+ * @param[in,out] data FRU area data to be appended
+ */
+void appendChassisType(const PropertyMap& propMap, FruAreaData& data)
+{
+    uint8_t chassisType = 0; // Not specified
+    auto iter = propMap.find(type);
+    if (iter != propMap.end())
+    {
+        auto value = iter->second;
+        try
+        {
+            chassisType = std::stoi(value);
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Could not parse chassis type, value: {VALUE}, "
+                       "error: {ERROR}",
+                       "VALUE", value, "ERROR", e);
+            chassisType = 0;
+        }
+    }
+    data.emplace_back(chassisType);
+}
+
+/**
+ * @brief Read property value from inventory and append to the FRU area data
+ *
+ * @param[in] key key to search for in the property inventory data
+ * @param[in] propMap map of property values
+ * @param[in,out] data FRU area data to be appended
+ */
+void appendData(const Property& key, const PropertyMap& propMap,
+                FruAreaData& data)
+{
+    auto iter = propMap.find(key);
+    if (iter != propMap.end())
+    {
+        auto value = iter->second;
+        // If starts with 0x or 0X remove them
+        // ex: 0x123a just take 123a
+        if ((value.compare(0, 2, "0x")) == 0 ||
+            (value.compare(0, 2, "0X") == 0))
+        {
+            value.erase(0, 2);
+        }
+
+        // 6 bits for length as per FRU spec v1.0
+        // if length is greater then 63(2^6) bytes then trim the data to 63
+        // bytess.
+        auto valueLength = (value.length() > maxRecordAttributeValue)
+                               ? maxRecordAttributeValue
+                               : value.length();
+        // 2 bits for type
+        // Set the type to ascii
+        uint8_t typeLength = valueLength | ipmi::fru::typeASCII;
+
+        data.emplace_back(typeLength);
+        std::copy(value.begin(), value.begin() + valueLength,
+                  std::back_inserter(data));
+    }
+    else
+    {
+        // set 0 size
+        data.emplace_back(typeLengthByteNull);
+    }
+}
+
+std::time_t timeStringToRaw(const std::string& input)
+{
+    // TODO: For non-US region timestamps, pass in region information for the
+    // FRU to avoid the month/day swap.
+    // 2017-02-24 - 13:59:00, Tue Nov 20 23:08:00 2018
+    static const std::vector<std::string> patterns = {"%Y-%m-%d - %H:%M:%S",
+                                                      "%a %b %d %H:%M:%S %Y"};
+
+    std::tm time = {};
+
+    for (const auto& pattern : patterns)
+    {
+        std::istringstream timeStream(input);
+        timeStream >> std::get_time(&time, pattern.c_str());
+        if (!timeStream.fail())
+        {
+            break;
+        }
+    }
+
+    return timegm(&time);
+}
+
+/**
+ * @brief Appends Build Date
+ *
+ * @param[in] propMap map of property values
+ * @param[in/out] data FRU area to add the manfufacture date
+ */
+void appendMfgDate(const PropertyMap& propMap, FruAreaData& data)
+{
+    // MFG Date/Time
+    auto iter = propMap.find(buildDate);
+    if ((iter != propMap.end()) && (iter->second.size() > 0))
+    {
+        std::time_t raw = timeStringToRaw(iter->second);
+
+        // From FRU Spec:
+        // "Mfg. Date / Time
+        // Number of minutes from 0:00 hrs 1/1/96.
+        // LSbyte first (little endian)
+        // 00_00_00h = unspecified."
+        if ((raw >= secs_from_1970_1996) && (raw <= secsToMaxMfgdate))
+        {
+            raw -= secs_from_1970_1996;
+            raw /= secs_per_min;
+            uint8_t fru_raw[3];
+            fru_raw[0] = raw & 0xFF;
+            fru_raw[1] = (raw >> 8) & 0xFF;
+            fru_raw[2] = (raw >> 16) & 0xFF;
+            std::copy(fru_raw, fru_raw + 3, std::back_inserter(data));
+            return;
+        }
+        std::fprintf(stderr, "MgfDate invalid date: %u secs since UNIX epoch\n",
+                     static_cast<unsigned int>(raw));
+    }
+    // Blank date
+    data.emplace_back(0);
+    data.emplace_back(0);
+    data.emplace_back(0);
+}
+
+/**
+ * @brief Builds a section of the common header
+ *
+ * @param[in] infoAreaSize size of the FRU area to write
+ * @param[in] offset Current offset for data in overall record
+ * @param[in/out] data Common Header section data container
+ */
+void buildCommonHeaderSection(const uint32_t& infoAreaSize, uint16_t& offset,
+                              FruAreaData& data)
+{
+    // Check if data for internal use section populated
+    if (infoAreaSize == 0)
+    {
+        // Indicate record not present
+        data.emplace_back(recordNotPresent);
+    }
+    else
+    {
+        // offset should be multiple of 8.
+        auto remainder = offset % recordUnitOfMeasurement;
+        // add the padding bytes in the offset so that offset
+        // will be multiple of 8 byte.
+        offset += (remainder > 0) ? recordUnitOfMeasurement - remainder : 0;
+        // Place data to define offset to area data section
+        data.emplace_back(offset / recordUnitOfMeasurement);
+
+        offset += infoAreaSize;
+    }
+}
+
+/**
+ * @brief Builds the Chassis info area data section
+ *
+ * @param[in] propMap map of properties for chassis info area
+ * @return FruAreaData container with chassis info area
+ */
+FruAreaData buildChassisInfoArea(const PropertyMap& propMap)
+{
+    FruAreaData fruAreaData;
+    if (!propMap.empty())
+    {
+        // Set formatting data that goes at the beginning of the record
+        preFormatProcessing(false, fruAreaData);
+
+        // chassis type
+        appendChassisType(propMap, fruAreaData);
+
+        // Chasiss part number, in config.yaml it is configured as model
+        appendData(modelNumber, propMap, fruAreaData);
+
+        // Board serial number
+        appendData(serialNumber, propMap, fruAreaData);
+
+        // Indicate End of Custom Fields
+        fruAreaData.emplace_back(endOfCustomFields);
+
+        // Complete record data formatting
+        postFormatProcessing(fruAreaData);
+    }
+    return fruAreaData;
+}
+
+/**
+ * @brief Builds the Board info area data section
+ *
+ * @param[in] propMap map of properties for board info area
+ * @return FruAreaData container with board info area
+ */
+FruAreaData buildBoardInfoArea(const PropertyMap& propMap)
+{
+    FruAreaData fruAreaData;
+    if (!propMap.empty())
+    {
+        preFormatProcessing(true, fruAreaData);
+
+        // Manufacturing date
+        appendMfgDate(propMap, fruAreaData);
+
+        // manufacturer
+        appendData(manufacturer, propMap, fruAreaData);
+
+        // Product name/Pretty name
+        appendData(prettyName, propMap, fruAreaData);
+
+        // Board serial number
+        appendData(serialNumber, propMap, fruAreaData);
+
+        // Board part number
+        appendData(partNumber, propMap, fruAreaData);
+
+        // FRU File ID - Empty
+        fruAreaData.emplace_back(typeLengthByteNull);
+
+        // Empty FRU File ID bytes
+        fruAreaData.emplace_back(recordNotPresent);
+
+        // End of custom fields
+        fruAreaData.emplace_back(endOfCustomFields);
+
+        postFormatProcessing(fruAreaData);
+    }
+    return fruAreaData;
+}
+
+/**
+ * @brief Builds the Product info area data section
+ *
+ * @param[in] propMap map of FRU properties for Board info area
+ * @return FruAreaData container with product info area data
+ */
+FruAreaData buildProductInfoArea(const PropertyMap& propMap)
+{
+    FruAreaData fruAreaData;
+    if (!propMap.empty())
+    {
+        // Set formatting data that goes at the beginning of the record
+        preFormatProcessing(true, fruAreaData);
+
+        // manufacturer
+        appendData(manufacturer, propMap, fruAreaData);
+
+        // Product name/Pretty name
+        appendData(prettyName, propMap, fruAreaData);
+
+        // Product part/model number
+        appendData(modelNumber, propMap, fruAreaData);
+
+        // Product version
+        appendData(version, propMap, fruAreaData);
+
+        // Serial Number
+        appendData(serialNumber, propMap, fruAreaData);
+
+        // Add Asset Tag
+        fruAreaData.emplace_back(recordNotPresent);
+
+        // FRU File ID - Empty
+        fruAreaData.emplace_back(typeLengthByteNull);
+
+        // Empty FRU File ID bytes
+        fruAreaData.emplace_back(recordNotPresent);
+
+        // End of custom fields
+        fruAreaData.emplace_back(endOfCustomFields);
+
+        postFormatProcessing(fruAreaData);
+    }
+    return fruAreaData;
+}
+
+FruAreaData buildFruAreaData(const FruInventoryData& inventory)
+{
+    FruAreaData combFruArea{};
+    // Now build common header with data for this FRU Inv Record
+    // Use this variable to increment size of header as we go along to determine
+    // offset for the subsequent area offsets
+    uint16_t curDataOffset = commonHeaderFormatSize;
+    // First byte is id for version of FRU Info Storage Spec used
+    combFruArea.emplace_back(specVersion);
+
+    // 2nd byte is offset to internal use data
+    combFruArea.emplace_back(recordNotPresent);
+
+    // 3rd byte is offset to chassis data
+    FruAreaData chassisArea;
+    auto chassisIt = inventory.find(chassis);
+    if (chassisIt != inventory.end())
+    {
+        chassisArea = buildChassisInfoArea(chassisIt->second);
+    }
+    // update the offset to chassis data.
+    buildCommonHeaderSection(chassisArea.size(), curDataOffset, combFruArea);
+
+    // 4th byte is offset to board data
+    FruAreaData boardArea;
+    auto boardIt = inventory.find(board);
+    if (boardIt != inventory.end())
+    {
+        boardArea = buildBoardInfoArea(boardIt->second);
+    }
+    // update the offset to the board data.
+    buildCommonHeaderSection(boardArea.size(), curDataOffset, combFruArea);
+
+    // 5th byte is offset to product data
+    FruAreaData prodArea;
+    auto prodIt = inventory.find(product);
+    if (prodIt != inventory.end())
+    {
+        prodArea = buildProductInfoArea(prodIt->second);
+    }
+    // update the offset to the product data.
+    buildCommonHeaderSection(prodArea.size(), curDataOffset, combFruArea);
+
+    // 6th byte is offset to multirecord data
+    combFruArea.emplace_back(recordNotPresent);
+
+    // 7th byte is PAD
+    combFruArea.emplace_back(recordNotPresent);
+
+    // 8th (Final byte of Header Format) is the checksum
+    appendDataChecksum(combFruArea);
+
+    // Combine everything into one full IPMI FRU specification Record
+    // add chassis use area data
+    combFruArea.insert(combFruArea.end(), chassisArea.begin(),
+                       chassisArea.end());
+
+    // add board area data
+    combFruArea.insert(combFruArea.end(), boardArea.begin(), boardArea.end());
+
+    // add product use area data
+    combFruArea.insert(combFruArea.end(), prodArea.begin(), prodArea.end());
+
+    // If area is smaller than the minimum size, pad it. This enables ipmitool
+    // to update the FRU blob with values longer than the original payload.
+    if (combFruArea.size() < fruMinSize)
+    {
+        combFruArea.resize(fruMinSize, fruPadValue);
+    }
+
+    return combFruArea;
+}
+
+} // namespace fru
+} // namespace ipmi
diff --git a/ipmi_fru_info_area.hpp b/ipmi_fru_info_area.hpp
new file mode 100644
index 0000000..ea70401
--- /dev/null
+++ b/ipmi_fru_info_area.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace ipmi
+{
+namespace fru
+{
+using FruAreaData = std::vector<uint8_t>;
+using Section = std::string;
+using Value = std::string;
+using Property = std::string;
+using PropertyMap = std::map<Property, Value>;
+using FruInventoryData = std::map<Section, PropertyMap>;
+
+/**
+ * @brief Builds Fru area data from inventory data
+ *
+ * @param[in] invData FRU properties values read from inventory
+ *
+ * @return FruAreaData FRU area data as per IPMI specification
+ */
+FruAreaData buildFruAreaData(const FruInventoryData& inventory);
+
+} // namespace fru
+} // namespace ipmi
diff --git a/ipmiallowlist.hpp b/ipmiallowlist.hpp
new file mode 100644
index 0000000..7519de8
--- /dev/null
+++ b/ipmiallowlist.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <utility>
+#include <vector>
+
+using netfncmd_pair = std::pair<unsigned char, unsigned char>;
+
+extern const std::vector<netfncmd_pair> allowlist;
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
new file mode 100644
index 0000000..7d3dd2d
--- /dev/null
+++ b/ipmid-new.cpp
@@ -0,0 +1,910 @@
+/**
+ * Copyright © 2018 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 "config.h"
+
+#include "settings.hpp"
+
+#include <dlfcn.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/asio/detached.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/spawn.hpp>
+#include <host-cmd-manager.hpp>
+#include <ipmid-host/cmd.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/handler.hpp>
+#include <ipmid/message.hpp>
+#include <ipmid/oemrouter.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/asio/sd_event.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/timer.hpp>
+
+#include <algorithm>
+#include <any>
+#include <exception>
+#include <filesystem>
+#include <forward_list>
+#include <map>
+#include <memory>
+#include <optional>
+#include <tuple>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+namespace fs = std::filesystem;
+
+using namespace phosphor::logging;
+
+// IPMI Spec, shared Reservation ID.
+static unsigned short selReservationID = 0xFFFF;
+static bool selReservationValid = false;
+
+unsigned short reserveSel(void)
+{
+    // IPMI spec, Reservation ID, the value simply increases against each
+    // execution of the Reserve SEL command.
+    if (++selReservationID == 0)
+    {
+        selReservationID = 1;
+    }
+    selReservationValid = true;
+    return selReservationID;
+}
+
+bool checkSELReservation(unsigned short id)
+{
+    return (selReservationValid && selReservationID == id);
+}
+
+void cancelSELReservation(void)
+{
+    selReservationValid = false;
+}
+
+EInterfaceIndex getInterfaceIndex(void)
+{
+    return interfaceKCS;
+}
+
+sd_bus* bus;
+sd_event* events = nullptr;
+sd_event* ipmid_get_sd_event_connection(void)
+{
+    return events;
+}
+sd_bus* ipmid_get_sd_bus_connection(void)
+{
+    return bus;
+}
+
+namespace ipmi
+{
+
+static inline unsigned int makeCmdKey(unsigned int cluster, unsigned int cmd)
+{
+    return (cluster << 8) | cmd;
+}
+
+using HandlerTuple = std::tuple<int,                        /* prio */
+                                Privilege, HandlerBase::ptr /* handler */
+                                >;
+
+/* map to handle standard registered commands */
+static std::unordered_map<unsigned int, /* key is NetFn/Cmd */
+                          HandlerTuple>
+    handlerMap;
+
+/* special map for decoding Group registered commands (NetFn 2Ch) */
+static std::unordered_map<unsigned int, /* key is Group/Cmd (NetFn is 2Ch) */
+                          HandlerTuple>
+    groupHandlerMap;
+
+/* special map for decoding OEM registered commands (NetFn 2Eh) */
+static std::unordered_map<unsigned int, /* key is Iana/Cmd (NetFn is 2Eh) */
+                          HandlerTuple>
+    oemHandlerMap;
+
+using FilterTuple = std::tuple<int,            /* prio */
+                               FilterBase::ptr /* filter */
+                               >;
+
+/* list to hold all registered ipmi command filters */
+static std::forward_list<FilterTuple> filterList;
+
+namespace impl
+{
+/* common function to register all standard IPMI handlers */
+bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
+                     HandlerBase::ptr handler)
+{
+    // check for valid NetFn: even; 00-0Ch, 30-3Eh
+    if (netFn & 1 || (netFn > netFnTransport && netFn < netFnGroup) ||
+        netFn > netFnOemEight)
+    {
+        return false;
+    }
+
+    // create key and value for this handler
+    unsigned int netFnCmd = makeCmdKey(netFn, cmd);
+    HandlerTuple item(prio, priv, handler);
+
+    // consult the handler map and look for a match
+    auto& mapCmd = handlerMap[netFnCmd];
+    if (!std::get<HandlerBase::ptr>(mapCmd) || std::get<int>(mapCmd) <= prio)
+    {
+        mapCmd = item;
+        return true;
+    }
+    return false;
+}
+
+/* common function to register all Group IPMI handlers */
+bool registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
+                          HandlerBase::ptr handler)
+{
+    // create key and value for this handler
+    unsigned int netFnCmd = makeCmdKey(group, cmd);
+    HandlerTuple item(prio, priv, handler);
+
+    // consult the handler map and look for a match
+    auto& mapCmd = groupHandlerMap[netFnCmd];
+    if (!std::get<HandlerBase::ptr>(mapCmd) || std::get<int>(mapCmd) <= prio)
+    {
+        mapCmd = item;
+        return true;
+    }
+    return false;
+}
+
+/* common function to register all OEM IPMI handlers */
+bool registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
+                        HandlerBase::ptr handler)
+{
+    // create key and value for this handler
+    unsigned int netFnCmd = makeCmdKey(iana, cmd);
+    HandlerTuple item(prio, priv, handler);
+
+    // consult the handler map and look for a match
+    auto& mapCmd = oemHandlerMap[netFnCmd];
+    if (!std::get<HandlerBase::ptr>(mapCmd) || std::get<int>(mapCmd) <= prio)
+    {
+        mapCmd = item;
+        lg2::debug("registered OEM Handler: NetFn/Cmd={NETFNCMD}", "IANA",
+                   lg2::hex, iana, "CMD", lg2::hex, cmd, "NETFNCMD", lg2::hex,
+                   netFnCmd);
+        return true;
+    }
+
+    lg2::warning("could not register OEM Handler: NetFn/Cmd={NETFNCMD}", "IANA",
+                 lg2::hex, iana, "CMD", lg2::hex, cmd, "NETFNCMD", lg2::hex,
+                 netFnCmd);
+    return false;
+}
+
+/* common function to register all IPMI filter handlers */
+void registerFilter(int prio, FilterBase::ptr filter)
+{
+    // check for initial placement
+    if (filterList.empty() || std::get<int>(filterList.front()) < prio)
+    {
+        filterList.emplace_front(std::make_tuple(prio, filter));
+        return;
+    }
+    // walk the list and put it in the right place
+    auto j = filterList.begin();
+    for (auto i = j; i != filterList.end() && std::get<int>(*i) > prio; i++)
+    {
+        j = i;
+    }
+    filterList.emplace_after(j, std::make_tuple(prio, filter));
+}
+
+} // namespace impl
+
+message::Response::ptr filterIpmiCommand(message::Request::ptr request)
+{
+    // pass the command through the filter mechanism
+    // This can be the firmware firewall or any OEM mechanism like
+    // whitelist filtering based on operational mode
+    for (auto& item : filterList)
+    {
+        FilterBase::ptr filter = std::get<FilterBase::ptr>(item);
+        ipmi::Cc cc = filter->call(request);
+        if (ipmi::ccSuccess != cc)
+        {
+            return errorResponse(request, cc);
+        }
+    }
+    return message::Response::ptr();
+}
+
+message::Response::ptr executeIpmiCommandCommon(
+    std::unordered_map<unsigned int, HandlerTuple>& handlers,
+    unsigned int keyCommon, message::Request::ptr request)
+{
+    // filter the command first; a non-null message::Response::ptr
+    // means that the message has been rejected for some reason
+    message::Response::ptr filterResponse = filterIpmiCommand(request);
+
+    Cmd cmd = request->ctx->cmd;
+    unsigned int key = makeCmdKey(keyCommon, cmd);
+    auto cmdIter = handlers.find(key);
+    if (cmdIter != handlers.end())
+    {
+        // only return the filter response if the command is found
+        if (filterResponse)
+        {
+            lg2::debug("request for NetFn/Cmd {NETFN}/{CMD} has been filtered",
+                       "NETFN", lg2::hex, keyCommon, "CMD", lg2::hex, cmd);
+            return filterResponse;
+        }
+        HandlerTuple& chosen = cmdIter->second;
+        if (request->ctx->priv < std::get<Privilege>(chosen))
+        {
+            return errorResponse(request, ccInsufficientPrivilege);
+        }
+        return std::get<HandlerBase::ptr>(chosen)->call(request);
+    }
+    else
+    {
+        unsigned int wildcard = makeCmdKey(keyCommon, cmdWildcard);
+        cmdIter = handlers.find(wildcard);
+        if (cmdIter != handlers.end())
+        {
+            // only return the filter response if the command is found
+            if (filterResponse)
+            {
+                lg2::debug(
+                    "request for NetFn/Cmd {NETFN}/{CMD} has been filtered",
+                    "NETFN", lg2::hex, keyCommon, "CMD", lg2::hex, cmd);
+                return filterResponse;
+            }
+            HandlerTuple& chosen = cmdIter->second;
+            if (request->ctx->priv < std::get<Privilege>(chosen))
+            {
+                return errorResponse(request, ccInsufficientPrivilege);
+            }
+            return std::get<HandlerBase::ptr>(chosen)->call(request);
+        }
+    }
+    return errorResponse(request, ccInvalidCommand);
+}
+
+message::Response::ptr executeIpmiGroupCommand(message::Request::ptr request)
+{
+    // look up the group for this request
+    uint8_t bytes;
+    if (0 != request->payload.unpack(bytes))
+    {
+        return errorResponse(request, ccReqDataLenInvalid);
+    }
+    auto group = static_cast<Group>(bytes);
+    // Set defining body code
+    request->ctx->group = group;
+    message::Response::ptr response =
+        executeIpmiCommandCommon(groupHandlerMap, group, request);
+    ipmi::message::Payload prefix;
+    prefix.pack(bytes);
+    response->prepend(prefix);
+    return response;
+}
+
+message::Response::ptr executeIpmiOemCommand(message::Request::ptr request)
+{
+    // look up the iana for this request
+    uint24_t bytes;
+    if (0 != request->payload.unpack(bytes))
+    {
+        return errorResponse(request, ccReqDataLenInvalid);
+    }
+    auto iana = static_cast<Iana>(bytes);
+
+    lg2::debug("unpack IANA {IANA}", "IANA", lg2::hex, iana);
+
+    message::Response::ptr response =
+        executeIpmiCommandCommon(oemHandlerMap, iana, request);
+    ipmi::message::Payload prefix;
+    prefix.pack(bytes);
+    response->prepend(prefix);
+    return response;
+}
+
+message::Response::ptr executeIpmiCommand(message::Request::ptr request)
+{
+    NetFn netFn = request->ctx->netFn;
+    if (netFnGroup == netFn)
+    {
+        return executeIpmiGroupCommand(request);
+    }
+    else if (netFnOem == netFn)
+    {
+        return executeIpmiOemCommand(request);
+    }
+    return executeIpmiCommandCommon(handlerMap, netFn, request);
+}
+
+namespace utils
+{
+template <typename AssocContainer, typename UnaryPredicate>
+void assoc_erase_if(AssocContainer& c, UnaryPredicate p)
+{
+    typename AssocContainer::iterator next = c.begin();
+    typename AssocContainer::iterator last = c.end();
+    while ((next = std::find_if(next, last, p)) != last)
+    {
+        c.erase(next++);
+    }
+}
+} // namespace utils
+
+namespace
+{
+std::unordered_map<std::string, uint8_t> uniqueNameToChannelNumber;
+
+// sdbusplus::bus::match::rules::arg0namespace() wants the prefix
+// to match without any trailing '.'
+constexpr const char ipmiDbusChannelMatch[] =
+    "xyz.openbmc_project.Ipmi.Channel";
+void updateOwners(sdbusplus::asio::connection& conn, const std::string& name)
+{
+    conn.async_method_call(
+        [name](const boost::system::error_code ec,
+               const std::string& nameOwner) {
+            if (ec)
+            {
+                lg2::error("Error getting dbus owner for {INTERFACE}",
+                           "INTERFACE", name);
+                return;
+            }
+            // start after ipmiDbusChannelPrefix (after the '.')
+            std::string chName =
+                name.substr(std::strlen(ipmiDbusChannelMatch) + 1);
+            try
+            {
+                uint8_t channel = getChannelByName(chName);
+                uniqueNameToChannelNumber[nameOwner] = channel;
+                lg2::info(
+                    "New interface mapping: {INTERFACE} -> channel {CHANNEL}",
+                    "INTERFACE", name, "CHANNEL", channel);
+            }
+            catch (const std::exception& e)
+            {
+                lg2::info("Failed interface mapping, no such name: {INTERFACE}",
+                          "INTERFACE", name);
+            }
+        },
+        "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetNameOwner",
+        name);
+}
+
+void doListNames(sdbusplus::asio::connection& conn)
+{
+    conn.async_method_call(
+        [&conn](const boost::system::error_code ec,
+                std::vector<std::string> busNames) {
+            if (ec)
+            {
+                lg2::error("Error getting dbus names: {ERROR}", "ERROR",
+                           ec.message());
+                std::exit(EXIT_FAILURE);
+                return;
+            }
+            // Try to make startup consistent
+            std::sort(busNames.begin(), busNames.end());
+
+            const std::string channelPrefix =
+                std::string(ipmiDbusChannelMatch) + ".";
+            for (const std::string& busName : busNames)
+            {
+                if (busName.find(channelPrefix) == 0)
+                {
+                    updateOwners(conn, busName);
+                }
+            }
+        },
+        "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
+        "ListNames");
+}
+
+void nameChangeHandler(sdbusplus::message_t& message)
+{
+    std::string name;
+    std::string oldOwner;
+    std::string newOwner;
+
+    message.read(name, oldOwner, newOwner);
+
+    if (!oldOwner.empty())
+    {
+        if (boost::starts_with(oldOwner, ":"))
+        {
+            // Connection removed
+            auto it = uniqueNameToChannelNumber.find(oldOwner);
+            if (it != uniqueNameToChannelNumber.end())
+            {
+                uniqueNameToChannelNumber.erase(it);
+            }
+        }
+    }
+    if (!newOwner.empty())
+    {
+        // start after ipmiDbusChannelMatch (and after the '.')
+        std::string chName = name.substr(std::strlen(ipmiDbusChannelMatch) + 1);
+        try
+        {
+            uint8_t channel = getChannelByName(chName);
+            uniqueNameToChannelNumber[newOwner] = channel;
+            lg2::info("New interface mapping: {INTERFACE} -> channel {CHANNEL}",
+                      "INTERFACE", name, "CHANNEL", channel);
+        }
+        catch (const std::exception& e)
+        {
+            lg2::info("Failed interface mapping, no such name: {INTERFACE}",
+                      "INTERFACE", name);
+        }
+    }
+};
+
+} // anonymous namespace
+
+static constexpr const char intraBmcName[] = "INTRABMC";
+uint8_t channelFromMessage(sdbusplus::message_t& msg)
+{
+    // channel name for ipmitool to resolve to
+    std::string sender = msg.get_sender();
+    auto chIter = uniqueNameToChannelNumber.find(sender);
+    if (chIter != uniqueNameToChannelNumber.end())
+    {
+        return chIter->second;
+    }
+    // FIXME: currently internal connections are ephemeral and hard to pin down
+    try
+    {
+        return getChannelByName(intraBmcName);
+    }
+    catch (const std::exception& e)
+    {
+        return invalidChannel;
+    }
+} // namespace ipmi
+
+/* called from sdbus async server context */
+auto executionEntry(boost::asio::yield_context yield, sdbusplus::message_t& m,
+                    NetFn netFn, uint8_t lun, Cmd cmd, ipmi::SecureBuffer& data,
+                    std::map<std::string, ipmi::Value>& options)
+{
+    const auto dbusResponse =
+        [netFn, lun, cmd](Cc cc, const ipmi::SecureBuffer& data = {}) {
+            constexpr uint8_t netFnResponse = 0x01;
+            uint8_t retNetFn = netFn | netFnResponse;
+            return std::make_tuple(retNetFn, lun, cmd, cc, data);
+        };
+    std::string sender = m.get_sender();
+    Privilege privilege = Privilege::None;
+    int rqSA = 0;
+    int hostIdx = 0;
+    uint8_t userId = 0; // undefined user
+    uint32_t sessionId = 0;
+
+    // figure out what channel the request came in on
+    uint8_t channel = channelFromMessage(m);
+    if (channel == invalidChannel)
+    {
+        // unknown sender channel; refuse to service the request
+        lg2::error("ERROR determining source IPMI channel from "
+                   "{SENDER} NetFn/Cmd {NETFN}/{CMD}",
+                   "SENDER", sender, "NETFN", lg2::hex, netFn, "CMD", lg2::hex,
+                   cmd);
+        return dbusResponse(ipmi::ccDestinationUnavailable);
+    }
+
+    // session-based channels are required to provide userId, privilege and
+    // sessionId
+    if (getChannelSessionSupport(channel) != EChannelSessSupported::none)
+    {
+        try
+        {
+            Value requestPriv = options.at("privilege");
+            Value requestUserId = options.at("userId");
+            Value requestSessionId = options.at("currentSessionId");
+            privilege = static_cast<Privilege>(std::get<int>(requestPriv));
+            userId = static_cast<uint8_t>(std::get<int>(requestUserId));
+            sessionId =
+                static_cast<uint32_t>(std::get<uint32_t>(requestSessionId));
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("ERROR determining IPMI session credentials on "
+                       "channel {CHANNEL} for userid {USERID}",
+                       "CHANNEL", channel, "USERID", userId, "NETFN", lg2::hex,
+                       netFn, "CMD", lg2::hex, cmd);
+            return dbusResponse(ipmi::ccUnspecifiedError);
+        }
+    }
+    else
+    {
+        // get max privilege for session-less channels
+        // For now, there is not a way to configure this, default to Admin
+        privilege = Privilege::Admin;
+
+        // ipmb should supply rqSA
+        ChannelInfo chInfo;
+        getChannelInfo(channel, chInfo);
+        if (static_cast<EChannelMediumType>(chInfo.mediumType) ==
+            EChannelMediumType::ipmb)
+        {
+            const auto iter = options.find("rqSA");
+            if (iter != options.end())
+            {
+                if (std::holds_alternative<int>(iter->second))
+                {
+                    rqSA = std::get<int>(iter->second);
+                }
+            }
+            const auto iteration = options.find("hostId");
+            if (iteration != options.end())
+            {
+                if (std::holds_alternative<int>(iteration->second))
+                {
+                    hostIdx = std::get<int>(iteration->second);
+                }
+            }
+        }
+    }
+    // check to see if the requested priv/username is valid
+    lg2::debug("Set up ipmi context: Ch:NetFn/Cmd={CHANNEL}:{NETFN}/{CMD}",
+               "SENDER", sender, "NETFN", lg2::hex, netFn, "LUN", lg2::hex, lun,
+               "CMD", lg2::hex, cmd, "CHANNEL", channel, "USERID", userId,
+               "SESSIONID", lg2::hex, sessionId, "PRIVILEGE",
+               static_cast<uint8_t>(privilege), "RQSA", lg2::hex, rqSA);
+
+    auto ctx = std::make_shared<ipmi::Context>(
+        getSdBus(), netFn, lun, cmd, channel, userId, sessionId, privilege,
+        rqSA, hostIdx, yield);
+    auto request = std::make_shared<ipmi::message::Request>(
+        ctx, std::forward<ipmi::SecureBuffer>(data));
+    message::Response::ptr response = executeIpmiCommand(request);
+
+    return dbusResponse(response->cc, response->payload.raw);
+}
+
+/** @struct IpmiProvider
+ *
+ *  RAII wrapper for dlopen so that dlclose gets called on exit
+ */
+struct IpmiProvider
+{
+  public:
+    /** @brief address of the opened library */
+    void* addr;
+    std::string name;
+
+    IpmiProvider() = delete;
+    IpmiProvider(const IpmiProvider&) = delete;
+    IpmiProvider& operator=(const IpmiProvider&) = delete;
+    IpmiProvider(IpmiProvider&&) = delete;
+    IpmiProvider& operator=(IpmiProvider&&) = delete;
+
+    /** @brief dlopen a shared object file by path
+     *  @param[in]  filename - path of shared object to open
+     */
+    explicit IpmiProvider(const char* fname) : addr(nullptr), name(fname)
+    {
+        lg2::debug("Open IPMI provider library: {PROVIDER}", "PROVIDER", name);
+        try
+        {
+            addr = dlopen(name.c_str(), RTLD_NOW);
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("ERROR opening IPMI provider {PROVIDER}: {ERROR}",
+                       "PROVIDER", name, "ERROR", e);
+        }
+        catch (...)
+        {
+            const char* what = currentExceptionType();
+            lg2::error("ERROR opening IPMI provider {PROVIDER}: {ERROR}",
+                       "PROVIDER", name, "ERROR", what);
+        }
+        if (!isOpen())
+        {
+            lg2::error("ERROR opening IPMI provider {PROVIDER}: {ERROR}",
+                       "PROVIDER", name, "ERROR", dlerror());
+        }
+    }
+
+    ~IpmiProvider()
+    {
+        if (isOpen())
+        {
+            dlclose(addr);
+        }
+    }
+    bool isOpen() const
+    {
+        return (nullptr != addr);
+    }
+};
+
+// Plugin libraries need to contain .so either at the end or in the middle
+constexpr const char ipmiPluginExtn[] = ".so";
+
+/* return a list of self-closing library handles */
+std::forward_list<IpmiProvider> loadProviders(const fs::path& ipmiLibsPath)
+{
+    std::vector<fs::path> libs;
+    for (const auto& libPath : fs::directory_iterator(ipmiLibsPath))
+    {
+        std::error_code ec;
+        fs::path fname = libPath.path();
+        if (fs::is_symlink(fname, ec) || ec)
+        {
+            // it's a symlink or some other error; skip it
+            continue;
+        }
+        while (fname.has_extension())
+        {
+            fs::path extn = fname.extension();
+            if (extn == ipmiPluginExtn)
+            {
+                libs.push_back(libPath.path());
+                break;
+            }
+            fname.replace_extension();
+        }
+    }
+    std::sort(libs.begin(), libs.end());
+
+    std::forward_list<IpmiProvider> handles;
+    for (auto& lib : libs)
+    {
+#ifdef __IPMI_DEBUG__
+        lg2::debug("Registering handler {HANDLER}", "HANDLER", lib);
+#endif
+        handles.emplace_front(lib.c_str());
+    }
+    return handles;
+}
+
+} // namespace ipmi
+
+#ifdef ALLOW_DEPRECATED_API
+/* legacy registration */
+void ipmi_register_callback(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                            ipmi_context_t context, ipmid_callback_t handler,
+                            ipmi_cmd_privilege_t priv)
+{
+    auto h = ipmi::makeLegacyHandler(handler, context);
+    // translate priv from deprecated enum to current
+    ipmi::Privilege realPriv;
+    switch (priv)
+    {
+        case PRIVILEGE_CALLBACK:
+            realPriv = ipmi::Privilege::Callback;
+            break;
+        case PRIVILEGE_USER:
+            realPriv = ipmi::Privilege::User;
+            break;
+        case PRIVILEGE_OPERATOR:
+            realPriv = ipmi::Privilege::Operator;
+            break;
+        case PRIVILEGE_ADMIN:
+            realPriv = ipmi::Privilege::Admin;
+            break;
+        case PRIVILEGE_OEM:
+            realPriv = ipmi::Privilege::Oem;
+            break;
+        case SYSTEM_INTERFACE:
+            realPriv = ipmi::Privilege::Admin;
+            break;
+        default:
+            realPriv = ipmi::Privilege::Admin;
+            break;
+    }
+    // The original ipmi_register_callback allowed for group OEM handlers
+    // to be registered via this same interface. It just so happened that
+    // all the handlers were part of the DCMI group, so default to that.
+    if (netFn == NETFUN_GRPEXT)
+    {
+        ipmi::impl::registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupDCMI,
+                                         cmd, realPriv, h);
+    }
+    else
+    {
+        ipmi::impl::registerHandler(ipmi::prioOpenBmcBase, netFn, cmd, realPriv,
+                                    h);
+    }
+}
+
+namespace oem
+{
+
+class LegacyRouter : public oem::Router
+{
+  public:
+    virtual ~LegacyRouter() {}
+
+    /// Enable message routing to begin.
+    void activate() override {}
+
+    void registerHandler(Number oen, ipmi_cmd_t cmd, Handler handler) override
+    {
+        auto h = ipmi::makeLegacyHandler(std::forward<Handler>(handler));
+        ipmi::impl::registerOemHandler(ipmi::prioOpenBmcBase, oen, cmd,
+                                       ipmi::Privilege::Admin, h);
+    }
+};
+static LegacyRouter legacyRouter;
+
+Router* mutableRouter()
+{
+    return &legacyRouter;
+}
+
+} // namespace oem
+
+/* legacy alternative to executionEntry */
+void handleLegacyIpmiCommand(sdbusplus::message_t& m)
+{
+    // make a copy so the next two moves don't wreak havoc on the stack
+    sdbusplus::message_t b{m};
+    boost::asio::spawn(
+        *getIoContext(),
+        [b = std::move(b)](boost::asio::yield_context yield) {
+            sdbusplus::message_t m{std::move(b)};
+            unsigned char seq = 0, netFn = 0, lun = 0, cmd = 0;
+            ipmi::SecureBuffer data;
+
+            m.read(seq, netFn, lun, cmd, data);
+            std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
+            auto ctx = std::make_shared<ipmi::Context>(
+                bus, netFn, lun, cmd, 0, 0, 0, ipmi::Privilege::Admin, 0, 0,
+                yield);
+            auto request = std::make_shared<ipmi::message::Request>(
+                ctx, std::forward<ipmi::SecureBuffer>(data));
+            ipmi::message::Response::ptr response =
+                ipmi::executeIpmiCommand(request);
+
+            // Responses in IPMI require a bit set.  So there ya go...
+            netFn |= 0x01;
+
+            constexpr const char* DBUS_INTF = "org.openbmc.HostIpmi";
+
+            std::string dest = m.get_sender();
+            std::string path = m.get_path();
+            boost::system::error_code ec = ipmi::callDbusMethod(
+                ctx, dest, path, DBUS_INTF, "sendMessage", seq, netFn, lun, cmd,
+                response->cc, response->payload.raw);
+
+            if (ec)
+            {
+                lg2::error(
+                    "Failed to send response to requestor ({NETFN}/{CMD}): {ERROR}",
+                    "ERROR", ec.message(), "SENDER", dest, "NETFN", lg2::hex,
+                    netFn, "CMD", lg2::hex, cmd);
+            }
+        },
+        boost::asio::detached);
+}
+
+#endif /* ALLOW_DEPRECATED_API */
+
+// Calls host command manager to do the right thing for the command
+using CommandHandler = phosphor::host::command::CommandHandler;
+std::unique_ptr<phosphor::host::command::Manager> cmdManager;
+void ipmid_send_cmd_to_host(CommandHandler&& cmd)
+{
+    cmdManager->execute(std::forward<CommandHandler>(cmd));
+}
+
+std::unique_ptr<phosphor::host::command::Manager>& ipmid_get_host_cmd_manager()
+{
+    return cmdManager;
+}
+
+// These are symbols that are present in libipmid, but not expected
+// to be used except here (or maybe a unit test), so declare them here
+extern void setIoContext(std::shared_ptr<boost::asio::io_context>& newIo);
+extern void setSdBus(std::shared_ptr<sdbusplus::asio::connection>& newBus);
+
+int main(int argc, char* argv[])
+{
+    // Connect to system bus
+    auto io = std::make_shared<boost::asio::io_context>();
+    setIoContext(io);
+    if (argc > 1 && std::string(argv[1]) == "-session")
+    {
+        sd_bus_default_user(&bus);
+    }
+    else
+    {
+        sd_bus_default_system(&bus);
+    }
+    auto sdbusp = std::make_shared<sdbusplus::asio::connection>(*io, bus);
+    setSdBus(sdbusp);
+
+    // TODO: Hack to keep the sdEvents running.... Not sure why the sd_event
+    //       queue stops running if we don't have a timer that keeps re-arming
+    sdbusplus::Timer t2([]() { ; });
+    t2.start(std::chrono::microseconds(500000), true);
+
+    // TODO: Remove all vestiges of sd_event from phosphor-host-ipmid
+    //       until that is done, add the sd_event wrapper to the io object
+    sdbusplus::asio::sd_event_wrapper sdEvents(*io);
+
+    cmdManager = std::make_unique<phosphor::host::command::Manager>(*sdbusp);
+
+    // Register all command providers and filters
+    std::forward_list<ipmi::IpmiProvider> providers =
+        ipmi::loadProviders(HOST_IPMI_LIB_PATH);
+
+#ifdef ALLOW_DEPRECATED_API
+    // listen on deprecated signal interface for kcs/bt commands
+    constexpr const char* FILTER = "type='signal',interface='org.openbmc."
+                                   "HostIpmi',member='ReceivedMessage'";
+    sdbusplus::bus::match_t oldIpmiInterface(*sdbusp, FILTER,
+                                             handleLegacyIpmiCommand);
+#endif /* ALLOW_DEPRECATED_API */
+
+    // set up bus name watching to match channels with bus names
+    sdbusplus::bus::match_t nameOwnerChanged(
+        *sdbusp,
+        sdbusplus::bus::match::rules::nameOwnerChanged() +
+            sdbusplus::bus::match::rules::arg0namespace(
+                ipmi::ipmiDbusChannelMatch),
+        ipmi::nameChangeHandler);
+    ipmi::doListNames(*sdbusp);
+
+    int exitCode = 0;
+    // set up boost::asio signal handling
+    std::function<SignalResponse(int)> stopAsioRunLoop = [&io, &exitCode](
+                                                             int signalNumber) {
+        lg2::info("Received signal {SIGNAL}; quitting", "SIGNAL", signalNumber);
+        io->stop();
+        exitCode = signalNumber;
+        return SignalResponse::breakExecution;
+    };
+    registerSignalHandler(ipmi::prioOpenBmcBase, SIGINT, stopAsioRunLoop);
+    registerSignalHandler(ipmi::prioOpenBmcBase, SIGTERM, stopAsioRunLoop);
+
+    sdbusp->request_name("xyz.openbmc_project.Ipmi.Host");
+    // Add bindings for inbound IPMI requests
+    auto server = sdbusplus::asio::object_server(sdbusp);
+    auto iface = server.add_interface("/xyz/openbmc_project/Ipmi",
+                                      "xyz.openbmc_project.Ipmi.Server");
+    iface->register_method("execute", ipmi::executionEntry);
+    iface->initialize();
+
+    io->run();
+
+    // destroy all the IPMI handlers so the providers can unload safely
+    ipmi::handlerMap.clear();
+    ipmi::groupHandlerMap.clear();
+    ipmi::oemHandlerMap.clear();
+    ipmi::filterList.clear();
+    // unload the provider libraries
+    providers.clear();
+
+    std::exit(exitCode);
+}
diff --git a/ipmisensor.cpp b/ipmisensor.cpp
new file mode 100644
index 0000000..b66c585
--- /dev/null
+++ b/ipmisensor.cpp
@@ -0,0 +1,347 @@
+#include "sensorhandler.hpp"
+
+#include <malloc.h>
+
+#include <phosphor-logging/lg2.hpp>
+
+extern uint8_t find_type_for_sensor_number(uint8_t);
+
+struct sensorRES_t
+{
+    uint8_t sensor_number;
+    uint8_t operation;
+    uint8_t sensor_reading;
+    uint8_t assert_state7_0;
+    uint8_t assert_state14_8;
+    uint8_t deassert_state7_0;
+    uint8_t deassert_state14_8;
+    uint8_t event_data1;
+    uint8_t event_data2;
+    uint8_t event_data3;
+} __attribute__((packed));
+
+#define ISBITSET(x, y) (((x) >> (y)) & 0x01)
+#define ASSERTINDEX 0
+#define DEASSERTINDEX 1
+
+// Sensor Type,  Offset, function handler, Dbus Method, Assert value, Deassert
+// value
+struct lookup_t
+{
+    uint8_t sensor_type;
+    uint8_t offset;
+    int (*func)(const sensorRES_t*, const lookup_t*, const char*);
+    char member[16];
+    char assertion[64];
+    char deassertion[64];
+};
+
+extern int updateDbusInterface(uint8_t, const char*, const char*);
+
+int set_sensor_dbus_state_simple(const sensorRES_t* pRec,
+                                 const lookup_t* pTable, const char* value)
+{
+    return set_sensor_dbus_state_s(pRec->sensor_number, pTable->member, value);
+}
+
+struct event_data_t
+{
+    uint8_t data;
+    char text[64];
+};
+
+event_data_t g_fwprogress02h[] = {
+    {0x00, "Unspecified"},
+    {0x01, "Memory Init"},
+    {0x02, "HD Init"},
+    {0x03, "Secondary Proc Init"},
+    {0x04, "User Authentication"},
+    {0x05, "User init system setup"},
+    {0x06, "USB configuration"},
+    {0x07, "PCI configuration"},
+    {0x08, "Option ROM Init"},
+    {0x09, "Video Init"},
+    {0x0A, "Cache Init"},
+    {0x0B, "SM Bus init"},
+    {0x0C, "Keyboard Init"},
+    {0x0D, "Embedded ctrl init"},
+    {0x0E, "Docking station attachment"},
+    {0x0F, "Enable docking station"},
+    {0x10, "Docking station ejection"},
+    {0x11, "Disabling docking station"},
+    {0x12, "Calling OS Wakeup"},
+    {0x13, "Starting OS"},
+    {0x14, "Baseboard Init"},
+    {0x15, ""},
+    {0x16, "Floppy Init"},
+    {0x17, "Keyboard Test"},
+    {0x18, "Pointing Device Test"},
+    {0x19, "Primary Proc Init"},
+    {0xFF, "Unknown"}};
+
+event_data_t g_fwprogress00h[] = {
+    {0x00, "Unspecified."},
+    {0x01, "No system memory detected"},
+    {0x02, "No usable system memory"},
+    {0x03, "Unrecoverable hard-disk/ATAPI/IDE"},
+    {0x04, "Unrecoverable system-board"},
+    {0x05, "Unrecoverable diskette"},
+    {0x06, "Unrecoverable hard-disk controller"},
+    {0x07, "Unrecoverable PS/2 or USB keyboard"},
+    {0x08, "Removable boot media not found"},
+    {0x09, "Unrecoverable video controller"},
+    {0x0A, "No video device detected"},
+    {0x0B, "Firmware ROM corruption detected"},
+    {0x0C, "CPU voltage mismatch"},
+    {0x0D, "CPU speed matching"},
+    {0xFF, "unknown"},
+};
+
+char* event_data_lookup(event_data_t* p, uint8_t b)
+{
+    while (p->data != 0xFF)
+    {
+        if (p->data == b)
+        {
+            break;
+        }
+        p++;
+    }
+
+    return p->text;
+}
+
+//  The fw progress sensor contains some additional information that needs to be
+//  processed prior to calling the dbus code.
+int set_sensor_dbus_state_fwprogress(const sensorRES_t* pRec,
+                                     const lookup_t* pTable, const char*)
+{
+    char valuestring[128];
+    char* p = valuestring;
+
+    switch (pTable->offset)
+    {
+        case 0x00:
+            std::snprintf(
+                p, sizeof(valuestring), "POST Error, %s",
+                event_data_lookup(g_fwprogress00h, pRec->event_data2));
+            break;
+        case 0x01: /* Using g_fwprogress02h for 0x01 because that's what the
+                      ipmi spec says to do */
+            std::snprintf(
+                p, sizeof(valuestring), "FW Hang, %s",
+                event_data_lookup(g_fwprogress02h, pRec->event_data2));
+            break;
+        case 0x02:
+            std::snprintf(
+                p, sizeof(valuestring), "FW Progress, %s",
+                event_data_lookup(g_fwprogress02h, pRec->event_data2));
+            break;
+        default:
+            std::snprintf(
+                p, sizeof(valuestring),
+                "Internal warning, fw_progres offset unknown (0x%02x)",
+                pTable->offset);
+            break;
+    }
+
+    return set_sensor_dbus_state_s(pRec->sensor_number, pTable->member, p);
+}
+
+// Handling this special OEM sensor by coping what is in byte 4.  I also think
+// that is odd considering byte 3 is for sensor reading.  This seems like a
+// misuse of the IPMI spec
+int set_sensor_dbus_state_osbootcount(const sensorRES_t* pRec, const lookup_t*,
+                                      const char*)
+{
+    return set_sensor_dbus_state_y(pRec->sensor_number, "setValue",
+                                   pRec->assert_state7_0);
+}
+
+int set_sensor_dbus_state_system_event(const sensorRES_t* pRec,
+                                       const lookup_t* pTable, const char*)
+{
+    char valuestring[128];
+    char* p = valuestring;
+
+    switch (pTable->offset)
+    {
+        case 0x00:
+            std::snprintf(p, sizeof(valuestring), "System Reconfigured");
+            break;
+        case 0x01:
+            std::snprintf(p, sizeof(valuestring), "OEM Boot Event");
+            break;
+        case 0x02:
+            std::snprintf(p, sizeof(valuestring),
+                          "Undetermined System Hardware Failure");
+            break;
+        case 0x03:
+            std::snprintf(
+                p, sizeof(valuestring),
+                "System Failure see error log for more details (0x%02x)",
+                pRec->event_data2);
+            break;
+        case 0x04:
+            std::snprintf(
+                p, sizeof(valuestring),
+                "System Failure see PEF error log for more details (0x%02x)",
+                pRec->event_data2);
+            break;
+        default:
+            std::snprintf(
+                p, sizeof(valuestring),
+                "Internal warning, system_event offset unknown (0x%02x)",
+                pTable->offset);
+            break;
+    }
+
+    return set_sensor_dbus_state_s(pRec->sensor_number, pTable->member, p);
+}
+
+//  This table lists only senors we care about telling dbus about.
+//  Offset definition cab be found in section 42.2 of the IPMI 2.0
+//  spec.  Add more if/when there are more items of interest.
+lookup_t g_ipmidbuslookup[] = {
+
+    {0xe9, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled",
+     ""}, // OCC Inactive 0
+    {0xe9, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled",
+     ""}, // OCC Active 1
+    // Turbo Allowed
+    {0xda, 0x00, set_sensor_dbus_state_simple, "setValue", "True", "False"},
+    // Power Supply Derating
+    {0xb4, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""},
+    // Power Cap
+    {0xC2, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""},
+    {0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
+    {0x07, 0x08, set_sensor_dbus_state_simple, "setFault", "True", "False"},
+    {0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
+    {0x0C, 0x04, set_sensor_dbus_state_simple, "setFault", "True", "False"},
+    {0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
+    {0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
+    {0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
+    {0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"},
+    {0xc3, 0x00, set_sensor_dbus_state_osbootcount, "setValue", "", ""},
+    {0x1F, 0x00, set_sensor_dbus_state_simple, "setValue",
+     "Boot completed (00)", ""},
+    {0x1F, 0x01, set_sensor_dbus_state_simple, "setValue",
+     "Boot completed (01)", ""},
+    {0x1F, 0x02, set_sensor_dbus_state_simple, "setValue", "PXE boot completed",
+     ""},
+    {0x1F, 0x03, set_sensor_dbus_state_simple, "setValue",
+     "Diagnostic boot completed", ""},
+    {0x1F, 0x04, set_sensor_dbus_state_simple, "setValue",
+     "CD-ROM boot completed", ""},
+    {0x1F, 0x05, set_sensor_dbus_state_simple, "setValue", "ROM boot completed",
+     ""},
+    {0x1F, 0x06, set_sensor_dbus_state_simple, "setValue",
+     "Boot completed (06)", ""},
+    {0x12, 0x00, set_sensor_dbus_state_system_event, "setValue", "", ""},
+    {0x12, 0x01, set_sensor_dbus_state_system_event, "setValue", "", ""},
+    {0x12, 0x02, set_sensor_dbus_state_system_event, "setValue", "", ""},
+    {0x12, 0x03, set_sensor_dbus_state_system_event, "setValue", "", ""},
+    {0x12, 0x04, set_sensor_dbus_state_system_event, "setValue", "", ""},
+    {0xCA, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""},
+    {0xCA, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled", ""},
+    {0xFF, 0xFF, nullptr, "", "", ""}};
+
+void reportSensorEventAssert(const sensorRES_t* pRec, int index)
+{
+    lookup_t* pTable = &g_ipmidbuslookup[index];
+    (*pTable->func)(pRec, pTable, pTable->assertion);
+}
+void reportSensorEventDeassert(const sensorRES_t* pRec, int index)
+{
+    lookup_t* pTable = &g_ipmidbuslookup[index];
+    (*pTable->func)(pRec, pTable, pTable->deassertion);
+}
+
+int findindex(const uint8_t sensor_type, int offset, int* index)
+{
+    int i = 0, rc = 0;
+    lookup_t* pTable = g_ipmidbuslookup;
+
+    do
+    {
+        if (((pTable + i)->sensor_type == sensor_type) &&
+            ((pTable + i)->offset == offset))
+        {
+            rc = 1;
+            *index = i;
+            break;
+        }
+        i++;
+    } while ((pTable + i)->sensor_type != 0xFF);
+
+    return rc;
+}
+
+bool shouldReport(uint8_t sensorType, int offset, int* index)
+{
+    bool rc = false;
+
+    if (findindex(sensorType, offset, index))
+    {
+        rc = true;
+    }
+    if (rc == false)
+    {
+#ifdef __IPMI_DEBUG__
+        lg2::debug("LOOKATME: Sensor should not be reported, "
+                   "sensor type: {SENSORTYPE}, offset: {OFFSET}",
+                   SENSORTYPE, lg2::hex, sensorType, "OFFSET", lg2::hex,
+                   offset);
+#endif
+    }
+
+    return rc;
+}
+
+int updateSensorRecordFromSSRAESC(const void* record)
+{
+    auto pRec = static_cast<const sensorRES_t*>(record);
+    uint8_t stype;
+    int index;
+
+    stype = find_type_for_sensor_number(pRec->sensor_number);
+
+    // 0xC3 types use the assertion7_0 for the value to be set
+    // so skip the reseach and call the correct event reporting
+    // function
+    if (stype == 0xC3)
+    {
+        shouldReport(stype, 0x00, &index);
+        reportSensorEventAssert(pRec, index);
+    }
+    else
+    {
+        // Scroll through each bit position .  Determine
+        // if any bit is either asserted or Deasserted.
+        for (int i = 0; i < 8; i++)
+        {
+            if ((ISBITSET(pRec->assert_state7_0, i)) &&
+                (shouldReport(stype, i, &index)))
+            {
+                reportSensorEventAssert(pRec, index);
+            }
+            if ((ISBITSET(pRec->assert_state14_8, i)) &&
+                (shouldReport(stype, i + 8, &index)))
+            {
+                reportSensorEventAssert(pRec, index);
+            }
+            if ((ISBITSET(pRec->deassert_state7_0, i)) &&
+                (shouldReport(stype, i, &index)))
+            {
+                reportSensorEventDeassert(pRec, index);
+            }
+            if ((ISBITSET(pRec->deassert_state14_8, i)) &&
+                (shouldReport(stype, i + 8, &index)))
+            {
+                reportSensorEventDeassert(pRec, index);
+            }
+        }
+    }
+
+    return 0;
+}
diff --git a/libipmid/entity_map_json.cpp b/libipmid/entity_map_json.cpp
new file mode 100644
index 0000000..76fbb25
--- /dev/null
+++ b/libipmid/entity_map_json.cpp
@@ -0,0 +1,119 @@
+#include <ipmid/entity_map_json.hpp>
+#include <ipmid/types.hpp>
+#include <nlohmann/json.hpp>
+
+#include <exception>
+#include <fstream>
+#include <memory>
+#include <string>
+#include <utility>
+
+namespace ipmi
+{
+namespace sensor
+{
+
+EntityInfoMapContainer* EntityInfoMapContainer::getContainer()
+{
+    static std::unique_ptr<EntityInfoMapContainer> instance;
+
+    if (!instance)
+    {
+        /* TODO: With multi-threading this would all need to be locked so
+         * the first thread to hit it would set it up.
+         */
+        EntityInfoMap builtEntityMap = buildEntityMapFromFile();
+        instance = std::unique_ptr<EntityInfoMapContainer>(
+            new EntityInfoMapContainer(builtEntityMap));
+    }
+
+    return instance.get();
+}
+
+const EntityInfoMap& EntityInfoMapContainer::getIpmiEntityRecords()
+{
+    return entityRecords;
+}
+
+EntityInfoMap buildEntityMapFromFile()
+{
+    const char* entityMapJsonFilename =
+        "/usr/share/ipmi-providers/entity-map.json";
+    EntityInfoMap builtMap;
+
+    std::ifstream mapFile(entityMapJsonFilename);
+    if (!mapFile.is_open())
+    {
+        return builtMap;
+    }
+
+    auto data = nlohmann::json::parse(mapFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        return builtMap;
+    }
+
+    return buildJsonEntityMap(data);
+}
+
+EntityInfoMap buildJsonEntityMap(const nlohmann::json& data)
+{
+    EntityInfoMap builtMap;
+
+    if (data.type() != nlohmann::json::value_t::array)
+    {
+        return builtMap;
+    }
+
+    try
+    {
+        for (const auto& entry : data)
+        {
+            /* It's an array entry with the following fields: id,
+             * containerEntityId, containerEntityInstance, isList, isLinked,
+             * entities[4]
+             */
+            EntityInfo obj;
+            Id recordId = entry.at("id").get<Id>();
+            obj.containerEntityId =
+                entry.at("containerEntityId").get<uint8_t>();
+            obj.containerEntityInstance =
+                entry.at("containerEntityInstance").get<uint8_t>();
+            obj.isList = entry.at("isList").get<bool>();
+            obj.isLinked = entry.at("isLinked").get<bool>();
+
+            auto jsonEntities = entry.at("entities");
+
+            if (jsonEntities.type() != nlohmann::json::value_t::array)
+            {
+                throw std::runtime_error(
+                    "Invalid type for entities entry, must be array");
+            }
+            if (jsonEntities.size() != obj.containedEntities.size())
+            {
+                throw std::runtime_error(
+                    "Entities must be in pairs of " +
+                    std::to_string(obj.containedEntities.size()));
+            }
+
+            for (std::size_t i = 0; i < obj.containedEntities.size(); i++)
+            {
+                obj.containedEntities[i] = std::make_pair(
+                    jsonEntities[i].at("id").get<uint8_t>(),
+                    jsonEntities[i].at("instance").get<uint8_t>());
+            }
+
+            builtMap.insert({recordId, obj});
+        }
+    }
+    catch (const std::exception& e)
+    {
+        /* If any entry is invalid, the entire file cannot be trusted. */
+        builtMap.clear();
+    }
+
+    return builtMap;
+}
+
+} // namespace sensor
+} // namespace ipmi
diff --git a/libipmid/meson.build b/libipmid/meson.build
new file mode 100644
index 0000000..f9953b0
--- /dev/null
+++ b/libipmid/meson.build
@@ -0,0 +1,44 @@
+ipmid_pre = [
+    boost,
+    libsystemd_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+]
+
+entity_map_json_lib = static_library(
+    'entity_map_json',
+    'entity_map_json.cpp',
+    include_directories: root_inc,
+    dependencies: [nlohmann_json_dep, sdbusplus_dep],
+    implicit_include_directories: false,
+)
+
+entity_map_json_dep = declare_dependency(link_whole: entity_map_json_lib)
+
+libipmid = library(
+    'ipmid',
+    'sdbus-asio.cpp',
+    'signals.cpp',
+    'systemintf-sdbus.cpp',
+    'utils.cpp',
+    dependencies: [ipmid_pre, entity_map_json_dep],
+    version: meson.project_version(),
+    include_directories: root_inc,
+    install: true,
+    install_dir: get_option('libdir'),
+    override_options: ['b_lundef=false'],
+)
+
+ipmid_dep = declare_dependency(
+    dependencies: ipmid_pre,
+    include_directories: root_inc,
+    link_with: libipmid,
+)
+
+import('pkgconfig').generate(
+    libipmid,
+    name: 'libipmid',
+    version: meson.project_version(),
+    description: 'ipmid',
+)
diff --git a/libipmid/sdbus-asio.cpp b/libipmid/sdbus-asio.cpp
new file mode 100644
index 0000000..0f4cdaa
--- /dev/null
+++ b/libipmid/sdbus-asio.cpp
@@ -0,0 +1,32 @@
+#include <boost/asio/io_context.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <memory>
+
+namespace
+{
+
+std::shared_ptr<boost::asio::io_context> ioCtx;
+std::shared_ptr<sdbusplus::asio::connection> sdbusp;
+
+} // namespace
+
+void setIoContext(std::shared_ptr<boost::asio::io_context>& newIo)
+{
+    ioCtx = newIo;
+}
+
+std::shared_ptr<boost::asio::io_context> getIoContext()
+{
+    return ioCtx;
+}
+
+void setSdBus(std::shared_ptr<sdbusplus::asio::connection>& newBus)
+{
+    sdbusp = newBus;
+}
+
+std::shared_ptr<sdbusplus::asio::connection> getSdBus()
+{
+    return sdbusp;
+}
diff --git a/libipmid/signals.cpp b/libipmid/signals.cpp
new file mode 100644
index 0000000..5eca6ad
--- /dev/null
+++ b/libipmid/signals.cpp
@@ -0,0 +1,106 @@
+#include <boost/asio/signal_set.hpp>
+#include <ipmid/api.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <forward_list>
+#include <memory>
+#include <vector>
+
+namespace
+{
+
+class SignalHandler
+{
+  public:
+    SignalHandler(std::shared_ptr<boost::asio::io_context>& io, int sigNum) :
+        signal(std::make_unique<boost::asio::signal_set>(*io, sigNum))
+    {
+        asyncWait();
+    }
+
+    ~SignalHandler()
+    {
+        // unregister with asio to unmask the signal
+        signal->cancel();
+        signal->clear();
+    }
+
+    void registerHandler(int prio,
+                         const std::function<SignalResponse(int)>& handler)
+    {
+        // check for initial placement
+        if (handlers.empty() || std::get<0>(handlers.front()) < prio)
+        {
+            handlers.emplace_front(std::make_tuple(prio, handler));
+            return;
+        }
+        // walk the list and put it in the right place
+        auto j = handlers.begin();
+        for (auto i = j; i != handlers.end() && std::get<0>(*i) > prio; i++)
+        {
+            j = i;
+        }
+        handlers.emplace_after(j, std::make_tuple(prio, handler));
+    }
+
+    void handleSignal(const boost::system::error_code& ec, int sigNum)
+    {
+        if (ec)
+        {
+            lg2::error("Error in common signal handler, "
+                       "signal: {SIGNAL}, error: {ERROR}",
+                       "SIGNAL", sigNum, "ERROR", ec.message());
+            return;
+        }
+        for (auto h = handlers.begin(); h != handlers.end(); h++)
+        {
+            std::function<SignalResponse(int)>& handler = std::get<1>(*h);
+            if (handler(sigNum) == SignalResponse::breakExecution)
+            {
+                break;
+            }
+        }
+        // start the wait for the next signal
+        asyncWait();
+    }
+
+  protected:
+    void asyncWait()
+    {
+        signal->async_wait([this](const boost::system::error_code& ec,
+                                  int sigNum) { handleSignal(ec, sigNum); });
+    }
+
+    std::forward_list<std::tuple<int, std::function<SignalResponse(int)>>>
+        handlers;
+    std::unique_ptr<boost::asio::signal_set> signal;
+};
+
+// SIGRTMAX is defined as a non-constexpr function call and thus cannot be used
+// as an array size. Get around this by making a vector and resizing it the
+// first time it is needed
+std::vector<std::unique_ptr<SignalHandler>> signals;
+
+} // namespace
+
+void registerSignalHandler(int priority, int signalNumber,
+                           const std::function<SignalResponse(int)>& handler)
+{
+    if (signalNumber >= SIGRTMAX)
+    {
+        return;
+    }
+
+    if (signals.empty())
+    {
+        signals.resize(SIGRTMAX);
+    }
+
+    if (!signals[signalNumber])
+    {
+        std::shared_ptr<boost::asio::io_context> io = getIoContext();
+        signals[signalNumber] =
+            std::make_unique<SignalHandler>(io, signalNumber);
+    }
+    signals[signalNumber]->registerHandler(priority, handler);
+}
diff --git a/libipmid/systemintf-sdbus.cpp b/libipmid/systemintf-sdbus.cpp
new file mode 100644
index 0000000..a9a4e18
--- /dev/null
+++ b/libipmid/systemintf-sdbus.cpp
@@ -0,0 +1,33 @@
+#include <ipmid/api.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <memory>
+
+namespace
+{
+
+std::unique_ptr<sdbusplus::asio::connection> sdbusp;
+
+} // namespace
+
+/**
+ * @brief ipmid_get_sdbus_plus_handler is used by some ipmi providers
+ *
+ * @return: a reference to a unique pointer of the systemd connection
+ *          managed by the systemintfcmds code
+ */
+std::unique_ptr<sdbusplus::asio::connection>& ipmid_get_sdbus_plus_handler()
+{
+    if (!sdbusp)
+    {
+        // Create a new sdbus connection so it can have a well-known name
+        sd_bus* bus = nullptr;
+        sd_bus_open_system(&bus);
+        if (bus)
+        {
+            sdbusp = std::make_unique<sdbusplus::asio::connection>(
+                *getIoContext(), bus);
+        }
+    }
+    return sdbusp;
+}
diff --git a/libipmid/utils.cpp b/libipmid/utils.cpp
new file mode 100644
index 0000000..f8e8083
--- /dev/null
+++ b/libipmid/utils.cpp
@@ -0,0 +1,609 @@
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <ipmid/utils.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 <algorithm>
+#include <chrono>
+
+namespace ipmi
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+
+namespace network
+{
+
+/** @brief checks if the given ip is Link Local Ip or not.
+ *  @param[in] ipaddress - IPAddress.
+ */
+bool isLinkLocalIP(const std::string& ipaddress);
+
+} // namespace network
+
+// TODO There may be cases where an interface is implemented by multiple
+//  objects,to handle such cases we are interested on that object
+//  which are on interested busname.
+//  Currently mapper doesn't give the readable busname(gives busid) so we can't
+//  use busname to find the object,will do later once the support is there.
+
+DbusObjectInfo getDbusObject(
+    sdbusplus::bus_t& bus, const std::string& interface,
+    const std::string& serviceRoot, const std::string& match)
+{
+    std::vector<DbusInterface> interfaces;
+    interfaces.emplace_back(interface);
+
+    ObjectTree objectTree = getSubTree(bus, interfaces, serviceRoot);
+    if (objectTree.empty())
+    {
+        lg2::error("No Object has implemented the interface: {INTERFACE}",
+                   "INTERFACE", interface);
+        elog<InternalFailure>();
+    }
+
+    DbusObjectInfo objectInfo;
+
+    // if match is empty then return the first object
+    if (match == "")
+    {
+        objectInfo = std::make_pair(
+            objectTree.begin()->first,
+            std::move(objectTree.begin()->second.begin()->first));
+        return objectInfo;
+    }
+
+    // else search the match string in the object path
+    auto found = std::find_if(
+        objectTree.begin(), objectTree.end(), [&match](const auto& object) {
+            return (object.first.find(match) != std::string::npos);
+        });
+
+    if (found == objectTree.end())
+    {
+        lg2::error("Failed to find object which matches: {MATCH}", "MATCH",
+                   match);
+        elog<InternalFailure>();
+        // elog<> throws an exception.
+    }
+
+    return make_pair(found->first, std::move(found->second.begin()->first));
+}
+
+Value getDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                      const std::string& objPath, const std::string& interface,
+                      const std::string& property,
+                      std::chrono::microseconds timeout)
+{
+    Value value;
+
+    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                      PROP_INTF, METHOD_GET);
+
+    method.append(interface, property);
+
+    auto reply = bus.call(method, timeout.count());
+    reply.read(value);
+
+    return value;
+}
+
+PropertyMap getAllDbusProperties(
+    sdbusplus::bus_t& bus, const std::string& service,
+    const std::string& objPath, const std::string& interface,
+    std::chrono::microseconds timeout)
+{
+    PropertyMap properties;
+
+    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                      PROP_INTF, METHOD_GET_ALL);
+
+    method.append(interface);
+
+    auto reply = bus.call(method, timeout.count());
+    reply.read(properties);
+
+    return properties;
+}
+
+ObjectValueTree getManagedObjects(sdbusplus::bus_t& bus,
+                                  const std::string& service,
+                                  const std::string& objPath)
+{
+    ipmi::ObjectValueTree interfaces;
+
+    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                      "org.freedesktop.DBus.ObjectManager",
+                                      "GetManagedObjects");
+    auto reply = bus.call(method);
+    reply.read(interfaces);
+
+    return interfaces;
+}
+
+void setDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                     const std::string& objPath, const std::string& interface,
+                     const std::string& property, const Value& value,
+                     std::chrono::microseconds timeout)
+{
+    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                      PROP_INTF, METHOD_SET);
+
+    method.append(interface, property, value);
+
+    if (!bus.call(method, timeout.count()))
+    {
+        lg2::error("Failed to set {PROPERTY}, path: {PATH}, "
+                   "interface: {INTERFACE}",
+                   "PROPERTY", property, "PATH", objPath, "INTERFACE",
+                   interface);
+        elog<InternalFailure>();
+    }
+}
+
+ServiceCache::ServiceCache(const std::string& intf, const std::string& path) :
+    intf(intf), path(path), cachedService(std::nullopt),
+    cachedBusName(std::nullopt)
+{}
+
+ServiceCache::ServiceCache(std::string&& intf, std::string&& path) :
+    intf(std::move(intf)), path(std::move(path)), cachedService(std::nullopt),
+    cachedBusName(std::nullopt)
+{}
+
+const std::string& ServiceCache::getService(sdbusplus::bus_t& bus)
+{
+    if (!isValid(bus))
+    {
+        cachedBusName = bus.get_unique_name();
+        cachedService = ::ipmi::getService(bus, intf, path);
+    }
+    return cachedService.value();
+}
+
+void ServiceCache::invalidate()
+{
+    cachedBusName = std::nullopt;
+    cachedService = std::nullopt;
+}
+
+sdbusplus::message_t ServiceCache::newMethodCall(
+    sdbusplus::bus_t& bus, const char* intf, const char* method)
+{
+    return bus.new_method_call(getService(bus).c_str(), path.c_str(), intf,
+                               method);
+}
+
+bool ServiceCache::isValid(sdbusplus::bus_t& bus) const
+{
+    return cachedService && cachedBusName == bus.get_unique_name();
+}
+
+std::string getService(sdbusplus::bus_t& bus, const std::string& intf,
+                       const std::string& path)
+{
+    auto mapperCall =
+        bus.new_method_call("xyz.openbmc_project.ObjectMapper",
+                            "/xyz/openbmc_project/object_mapper",
+                            "xyz.openbmc_project.ObjectMapper", "GetObject");
+
+    mapperCall.append(path);
+    mapperCall.append(std::vector<std::string>({intf}));
+
+    auto mapperResponseMsg = bus.call(mapperCall);
+
+    std::map<std::string, std::vector<std::string>> mapperResponse;
+    mapperResponseMsg.read(mapperResponse);
+
+    if (mapperResponse.begin() == mapperResponse.end())
+    {
+        throw std::runtime_error("ERROR in reading the mapper response");
+    }
+
+    return mapperResponse.begin()->first;
+}
+
+ObjectTree getSubTree(sdbusplus::bus_t& bus, const InterfaceList& interfaces,
+                      const std::string& subtreePath, int32_t depth)
+{
+    auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
+                                          MAPPER_INTF, "GetSubTree");
+
+    mapperCall.append(subtreePath, depth, interfaces);
+
+    auto mapperReply = bus.call(mapperCall);
+    ObjectTree objectTree;
+    mapperReply.read(objectTree);
+
+    return objectTree;
+}
+
+ipmi::ObjectTree getAllDbusObjects(
+    sdbusplus::bus_t& bus, const std::string& serviceRoot,
+    const std::string& interface, const std::string& match)
+{
+    std::vector<std::string> interfaces;
+    interfaces.emplace_back(interface);
+
+    ObjectTree objectTree = getSubTree(bus, interfaces, serviceRoot);
+    for (auto it = objectTree.begin(); it != objectTree.end();)
+    {
+        if (it->first.find(match) == std::string::npos)
+        {
+            it = objectTree.erase(it);
+        }
+        else
+        {
+            ++it;
+        }
+    }
+
+    return objectTree;
+}
+
+void deleteAllDbusObjects(sdbusplus::bus_t& bus, const std::string& serviceRoot,
+                          const std::string& interface,
+                          const std::string& match)
+{
+    try
+    {
+        auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
+
+        for (auto& object : objectTree)
+        {
+            method_no_args::callDbusMethod(bus, object.second.begin()->first,
+                                           object.first, DELETE_INTERFACE,
+                                           "Delete");
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::info("sdbusplus exception - Unable to delete the objects, "
+                  "service: {SERVICE}, interface: {INTERFACE}, error: {ERROR}",
+                  "SERVICE", serviceRoot, "INTERFACE", interface, "ERROR", e);
+    }
+}
+
+static inline std::string convertToString(const InterfaceList& interfaces)
+{
+    std::string intfStr;
+    for (const auto& intf : interfaces)
+    {
+        intfStr += "," + intf;
+    }
+    return intfStr;
+}
+
+ObjectTree getAllAncestors(sdbusplus::bus_t& bus, const std::string& path,
+                           InterfaceList&& interfaces)
+{
+    auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
+                                          MAPPER_INTF, "GetAncestors");
+    mapperCall.append(path, interfaces);
+
+    auto mapperReply = bus.call(mapperCall);
+    ObjectTree objectTree;
+    mapperReply.read(objectTree);
+
+    if (objectTree.empty())
+    {
+        lg2::error("No Object has implemented the interface: {INTERFACE}, "
+                   "path: {PATH}",
+                   "INTERFACE", convertToString(interfaces), "PATH", path);
+        elog<InternalFailure>();
+    }
+
+    return objectTree;
+}
+
+namespace method_no_args
+{
+
+void callDbusMethod(sdbusplus::bus_t& bus, const std::string& service,
+                    const std::string& objPath, const std::string& interface,
+                    const std::string& method)
+
+{
+    auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                         interface.c_str(), method.c_str());
+    auto reply = bus.call(busMethod);
+}
+
+} // namespace method_no_args
+
+/********* Begin co-routine yielding alternatives ***************/
+
+boost::system::error_code getService(Context::ptr ctx, const std::string& intf,
+                                     const std::string& path,
+                                     std::string& service)
+{
+    boost::system::error_code ec;
+    std::map<std::string, std::vector<std::string>> mapperResponse =
+        ctx->bus->yield_method_call<decltype(mapperResponse)>(
+            ctx->yield, ec, "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetObject", path,
+            std::vector<std::string>({intf}));
+
+    if (!ec)
+    {
+        service = std::move(mapperResponse.begin()->first);
+    }
+    return ec;
+}
+
+boost::system::error_code getSubTree(
+    Context::ptr ctx, const InterfaceList& interfaces,
+    const std::string& subtreePath, int32_t depth, ObjectTree& objectTree)
+{
+    boost::system::error_code ec;
+    objectTree = ctx->bus->yield_method_call<ObjectTree>(
+        ctx->yield, ec, MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF, "GetSubTree",
+        subtreePath, depth, interfaces);
+
+    return ec;
+}
+
+boost::system::error_code getDbusObject(
+    Context::ptr ctx, const std::string& interface,
+    const std::string& subtreePath, const std::string& match,
+    DbusObjectInfo& dbusObject)
+{
+    std::vector<DbusInterface> interfaces;
+    interfaces.emplace_back(interface);
+
+    auto depth = 0;
+    ObjectTree objectTree;
+    boost::system::error_code ec =
+        getSubTree(ctx, interfaces, subtreePath, depth, objectTree);
+
+    if (ec)
+    {
+        return ec;
+    }
+
+    if (objectTree.empty())
+    {
+        lg2::error("No Object has implemented the interface: {INTERFACE}, "
+                   "NetFn: {NETFN}, Cmd: {CMD}",
+                   "INTERFACE", interface, "NETFN", lg2::hex, ctx->netFn, "CMD",
+                   lg2::hex, ctx->cmd);
+        return boost::system::errc::make_error_code(
+            boost::system::errc::no_such_process);
+    }
+
+    // if match is empty then return the first object
+    if (match == "")
+    {
+        dbusObject = std::make_pair(
+            std::move(objectTree.begin()->first),
+            std::move(objectTree.begin()->second.begin()->first));
+        return ec;
+    }
+
+    // else search the match string in the object path
+    auto found = std::find_if(
+        objectTree.begin(), objectTree.end(), [&match](const auto& object) {
+            return (object.first.find(match) != std::string::npos);
+        });
+
+    if (found == objectTree.end())
+    {
+        lg2::error("Failed to find object which matches: {MATCH}, "
+                   "NetFn: {NETFN}, Cmd: {CMD}",
+                   "MATCH", match, "NETFN", lg2::hex, ctx->netFn, "CMD",
+                   lg2::hex, ctx->cmd);
+        // set ec
+        return boost::system::errc::make_error_code(
+            boost::system::errc::no_such_file_or_directory);
+    }
+
+    dbusObject = std::make_pair(std::move(found->first),
+                                std::move(found->second.begin()->first));
+    return ec;
+}
+
+boost::system::error_code getAllDbusProperties(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, PropertyMap& properties)
+{
+    boost::system::error_code ec;
+    properties = ctx->bus->yield_method_call<PropertyMap>(
+        ctx->yield, ec, service.c_str(), objPath.c_str(), PROP_INTF,
+        METHOD_GET_ALL, interface);
+    return ec;
+}
+
+boost::system::error_code setDbusProperty(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, const std::string& property,
+    const Value& value)
+{
+    boost::system::error_code ec;
+    ctx->bus->yield_method_call(ctx->yield, ec, service.c_str(),
+                                objPath.c_str(), PROP_INTF, METHOD_SET,
+                                interface, property, value);
+    return ec;
+}
+
+boost::system::error_code getAllDbusObjects(
+    Context::ptr ctx, const std::string& serviceRoot,
+    const std::string& interface, const std::string& match,
+    ObjectTree& objectTree)
+{
+    std::vector<std::string> interfaces;
+    interfaces.emplace_back(interface);
+
+    auto depth = 0;
+    boost::system::error_code ec =
+        getSubTree(ctx, interfaces, serviceRoot, depth, objectTree);
+    if (ec)
+    {
+        return ec;
+    }
+
+    for (auto it = objectTree.begin(); it != objectTree.end();)
+    {
+        if (it->first.find(match) == std::string::npos)
+        {
+            it = objectTree.erase(it);
+        }
+        else
+        {
+            ++it;
+        }
+    }
+
+    return ec;
+}
+
+boost::system::error_code deleteAllDbusObjects(
+    Context::ptr ctx, const std::string& serviceRoot,
+    const std::string& interface, const std::string& match)
+{
+    ObjectTree objectTree;
+    boost::system::error_code ec =
+        getAllDbusObjects(ctx, serviceRoot, interface, match, objectTree);
+    if (ec)
+    {
+        return ec;
+    }
+
+    for (auto& object : objectTree)
+    {
+        ctx->bus->yield_method_call(ctx->yield, ec,
+                                    object.second.begin()->first, object.first,
+                                    DELETE_INTERFACE, "Delete");
+        if (ec)
+        {
+            lg2::error("Failed to delete all objects, service: {SERVICE}, "
+                       "interface: {INTERFACE}, NetFn: {NETFN}, "
+                       "Cmd: {CMD}, Error: {ERROR}",
+                       "SERVICE", serviceRoot, "INTERFACE", interface, "NETFN",
+                       lg2::hex, ctx->netFn, "CMD", lg2::hex, ctx->cmd, "ERROR",
+                       ec.message());
+            break;
+        }
+    }
+    return ec;
+}
+
+boost::system::error_code getManagedObjects(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    ObjectValueTree& objects)
+{
+    boost::system::error_code ec;
+    objects = ctx->bus->yield_method_call<ipmi::ObjectValueTree>(
+        ctx->yield, ec, service.c_str(), objPath.c_str(),
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    return ec;
+}
+
+boost::system::error_code getAllAncestors(
+    Context::ptr ctx, const std::string& path, const InterfaceList& interfaces,
+    ObjectTree& objectTree)
+{
+    std::string interfaceList = convertToString(interfaces);
+
+    boost::system::error_code ec;
+    objectTree = ctx->bus->yield_method_call<ObjectTree>(
+        ctx->yield, ec, MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
+        "GetAncestors", path, interfaceList);
+
+    if (ec)
+    {
+        return ec;
+    }
+
+    if (objectTree.empty())
+    {
+        lg2::error("No Object has implemented the interface: {INTERFACE}, "
+                   "path: {PATH}",
+                   "INTERFACE", interfaceList, "PATH", path);
+        elog<InternalFailure>();
+    }
+
+    return ec;
+}
+
+boost::system::error_code callDbusMethod(
+    Context::ptr ctx, const std::string& service, const std::string& objPath,
+    const std::string& interface, const std::string& method)
+{
+    boost::system::error_code ec;
+    ctx->bus->yield_method_call(ctx->yield, ec, service, objPath, interface,
+                                method);
+    return ec;
+}
+
+/********* End co-routine yielding alternatives ***************/
+
+ipmi::Cc i2cWriteRead(std::string i2cBus, const uint8_t targetAddr,
+                      std::vector<uint8_t> writeData,
+                      std::vector<uint8_t>& readBuf)
+{
+    // Open the i2c device, for low-level combined data write/read
+    int i2cDev = ::open(i2cBus.c_str(), O_RDWR | O_CLOEXEC);
+    if (i2cDev < 0)
+    {
+        lg2::error("Failed to open i2c bus: {BUS}", "BUS", i2cBus);
+        return ipmi::ccInvalidFieldRequest;
+    }
+
+    const size_t writeCount = writeData.size();
+    const size_t readCount = readBuf.size();
+    int msgCount = 0;
+    i2c_msg i2cmsg[2] = {};
+    if (writeCount)
+    {
+        // Data will be writtern to the target address
+        i2cmsg[msgCount].addr = targetAddr;
+        i2cmsg[msgCount].flags = 0x00;
+        i2cmsg[msgCount].len = writeCount;
+        i2cmsg[msgCount].buf = writeData.data();
+        msgCount++;
+    }
+    if (readCount)
+    {
+        // Data will be read into the buffer from the target address
+        i2cmsg[msgCount].addr = targetAddr;
+        i2cmsg[msgCount].flags = I2C_M_RD;
+        i2cmsg[msgCount].len = readCount;
+        i2cmsg[msgCount].buf = readBuf.data();
+        msgCount++;
+    }
+
+    i2c_rdwr_ioctl_data msgReadWrite = {};
+    msgReadWrite.msgs = i2cmsg;
+    msgReadWrite.nmsgs = msgCount;
+
+    // Perform the combined write/read
+    int ret = ::ioctl(i2cDev, I2C_RDWR, &msgReadWrite);
+    ::close(i2cDev);
+
+    if (ret < 0)
+    {
+        lg2::error("I2C WR Failed! {RET}", "RET", ret);
+        return ipmi::ccUnspecifiedError;
+    }
+    if (readCount)
+    {
+        readBuf.resize(msgReadWrite.msgs[msgCount - 1].len);
+    }
+
+    return ipmi::ccSuccess;
+}
+
+} // namespace ipmi
diff --git a/meson.build b/meson.build
index 0e449d4..a492697 100644
--- a/meson.build
+++ b/meson.build
@@ -1,40 +1,78 @@
 project(
-    'phosphor-net-ipmid',
+    'phosphor-host-ipmid',
     'cpp',
-    version: '1.0.0',
+    version: '0.1',
     meson_version: '>=1.1.1',
     default_options: [
-        'warning_level=3',
         'werror=true',
+        'warning_level=3',
         'cpp_std=c++23',
-        'buildtype=debugoptimized',
         'b_lto=true',
     ],
 )
 
+# Setting up config data
 conf_data = configuration_data()
-conf_data.set('RMCP_PING', get_option('rmcp_ping').allowed())
-conf_data.set('PAM_AUTHENTICATE', get_option('pam_authenticate').allowed())
 
-configure_file(output: 'config.h', configuration: conf_data)
+# The name of the callout's forward association
+conf_data.set_quoted('CALLOUT_FWD_ASSOCIATION', 'callout')
+conf_data.set_quoted('BOARD_SENSOR', get_option('board-sensor'))
+conf_data.set_quoted('SYSTEM_SENSOR', get_option('system-sensor'))
+conf_data.set(
+    'IPMI_SMS_ATN_ACK_TIMEOUT_SECS',
+    get_option('ipmi-sms-atn-ack-timeout-secs'),
+)
 
-sdbusplus_dep = dependency('sdbusplus')
-phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
-phosphor_logging_dep = dependency('phosphor-logging')
-libsystemd_dep = dependency('libsystemd')
-libcrypto_dep = dependency('libcrypto')
-ipmid_dep = dependency('libipmid')
-userlayer_dep = dependency('libuserlayer')
-channellayer_dep = dependency('libchannellayer')
+# Soft Power off related.
+if get_option('softoff').allowed()
+    conf_data.set_quoted('SOFTOFF_BUSNAME', get_option('softoff-busname'))
+    conf_data.set_quoted('SOFTOFF_OBJPATH', get_option('softoff-objpath'))
+    conf_data.set(
+        'IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS',
+        get_option('ipmi-host-shutdown-complete-timeout-secs'),
+    )
+    conf_data.set_quoted(
+        'HOST_INBAND_REQUEST_DIR',
+        get_option('host-inband-request-dir'),
+    )
+    conf_data.set_quoted(
+        'HOST_INBAND_REQUEST_FILE',
+        get_option('host-inband-request-file'),
+    )
+endif
+
+conf_data.set_quoted('CONTROL_HOST_BUSNAME', get_option('control-host-busname'))
+conf_data.set_quoted('CONTROL_HOST_OBJ_MGR', get_option('control-host-obj-mgr'))
+conf_data.set_quoted('HOST_NAME', get_option('host-name'))
+conf_data.set_quoted('POWER_READING_SENSOR', get_option('power-reading-sensor'))
+conf_data.set_quoted('HOST_IPMI_LIB_PATH', get_option('host-ipmi-lib-path'))
+conf_data.set_quoted('FW_VER_REGEX', get_option('fw-ver-regex'))
+
+if get_option('shortname-remove-suffix').allowed()
+    conf_data.set_quoted('SHORTNAME_REMOVE_SUFFIX', '1')
+endif
+if get_option('shortname-replace-words').allowed()
+    conf_data.set_quoted('SHORTNAME_REPLACE_WORDS', '1')
+endif
+if get_option('open-power').allowed()
+    conf_data.set_quoted('OPEN_POWER_SUPPORT', '1')
+endif
+
+matches_map = get_option('matches-map')
+conf_data.set('MAJOR_MATCH_INDEX', matches_map[0])
+conf_data.set('MINOR_MATCH_INDEX', matches_map[1])
+conf_data.set('AUX_0_MATCH_INDEX', matches_map[2])
+conf_data.set('AUX_1_MATCH_INDEX', matches_map[3])
+conf_data.set('AUX_2_MATCH_INDEX', matches_map[4])
+conf_data.set('AUX_3_MATCH_INDEX', matches_map[5])
+
+conf_h = configure_file(output: 'config.h', configuration: conf_data)
+
+root = meson.current_source_dir()
+root_inc = include_directories('.', 'include')
 
 # Project Arguments
 cpp = meson.get_compiler('cpp')
-if cpp.has_header('CLI/CLI.hpp')
-    cli11_dep = declare_dependency()
-else
-    cli11_dep = dependency('CLI11')
-endif
-
 add_project_arguments(
     cpp.get_supported_arguments(
         [
@@ -48,73 +86,283 @@
     language: 'cpp',
 )
 
-deps = [
-    cli11_dep,
-    ipmid_dep,
-    userlayer_dep,
-    channellayer_dep,
-    libcrypto_dep,
-    libsystemd_dep,
-    phosphor_dbus_interfaces_dep,
-    phosphor_logging_dep,
+if get_option('get-dbus-active-software').allowed()
+    add_project_arguments(
+        cpp.get_supported_arguments(['-DGET_DBUS_ACTIVE_SOFTWARE']),
+        language: 'cpp',
+    )
+endif
+
+feature_map = {
+    'boot-flag-safe-mode-support': '-DENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT',
+    'i2c-whitelist-check'        : '-DENABLE_I2C_WHITELIST_CHECK',
+    'update-functional-on-fail'  : '-DUPDATE_FUNCTIONAL_ON_FAIL',
+    'dynamic-sensors'            : '-DFEATURE_DYNAMIC_SENSORS',
+    'dynamic-sensors-write'      : '-DFEATURE_DYNAMIC_SENSORS_WRITE',
+    'entity-manager-decorators'  : '-DUSING_ENTITY_MANAGER_DECORATORS',
+    'hybrid-sensors'             : '-DFEATURE_HYBRID_SENSORS',
+    'sensors-cache'              : '-DFEATURE_SENSORS_CACHE',
+    'dynamic-storages-only'      : '-DFEATURE_DYNAMIC_STORAGES_ONLY',
+    'arm-sbmr'                   : '-DARM_SBMR_SUPPORT',
+}
+
+foreach option_key, option_value : feature_map
+    if (get_option(option_key).allowed())
+        summary(option_key, option_value, section: 'Enabled Features')
+        add_project_arguments(option_value, language: 'cpp')
+    endif
+endforeach
+
+add_project_arguments(
+    cpp.get_supported_arguments(
+        [
+            '-Wno-psabi',
+            '-Wno-missing-field-initializers',
+            '-Wno-pedantic',
+            '-Wno-non-virtual-dtor',
+        ],
+    ),
+    language: 'cpp',
+)
+
+# Dependencies
+
+boost = dependency('boost', modules: ['context', 'coroutine'], required: false)
+
+if not boost.found()
+    cmake = import('cmake')
+    opt = cmake.subproject_options()
+    opt.add_cmake_defines(
+        {
+            'BOOST_INCLUDE_LIBRARIES': 'asio;bimap;callable_traits;context;coroutine;interprocess;multiprecision;process',
+            'CMAKE_POSITION_INDEPENDENT_CODE': true,
+        },
+    )
+    boost_cmake = cmake.subproject('boost', required: true, options: opt)
+    boost_asio = boost_cmake.dependency('boost_asio').as_system()
+    boost_bimap = boost_cmake.dependency('boost_bimap').as_system()
+    boost_callable_traits = boost_cmake.dependency('boost_callable_traits').as_system()
+    boost_context = boost_cmake.dependency('boost_context').as_system()
+    boost_coroutine = boost_cmake.dependency('boost_coroutine').as_system()
+    boost_interprocess = boost_cmake.dependency('boost_interprocess').as_system()
+    boost_multiprecision = boost_cmake.dependency('boost_multiprecision').as_system()
+    boost_process = boost_cmake.dependency('boost_process').as_system()
+    boost = [
+        boost_asio,
+        boost_bimap,
+        boost_callable_traits,
+        boost_context,
+        boost_coroutine,
+        boost_interprocess,
+        boost_multiprecision,
+        boost_process,
+    ]
+endif
+
+phosphor_logging_dep = dependency('phosphor-logging')
+phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
+sdeventplus_dep = dependency('sdeventplus')
+libsystemd_dep = dependency('libsystemd')
+crypto = dependency('libcrypto', version: '>=1.0.2g')
+pam = cpp.find_library('pam', required: true)
+sdbusplus_dep = dependency('sdbusplus')
+stdplus_dep = dependency('stdplus')
+
+nlohmann_json_dep = dependency('nlohmann_json', include_type: 'system')
+
+generated_src = []
+
+# Subfolders
+subdir('libipmid')
+subdir('include')
+subdir('user_channel')
+subdir('scripts')
+
+if get_option('softoff').allowed()
+    subdir('xyz/openbmc_project/Ipmi/Internal/SoftPowerOff')
+    subdir('softoff')
+endif
+
+# whitelist
+if get_option('ipmi-whitelist').allowed()
+    generate_whitelist_script = files('generate_whitelist_create.sh')
+
+    whitelist_conf = get_option('whitelist-conf')
+    ipmiwhitelist = run_command( \
+            'bash', \
+            generate_whitelist_script, \
+            whitelist_conf,
+    )
+
+    whitelist_pre = declare_dependency(
+        include_directories: root_inc,
+        dependencies: [
+            crypto,
+            ipmid_dep,
+            phosphor_dbus_interfaces_dep,
+            phosphor_logging_dep,
+            sdbusplus_dep,
+        ],
+    )
+
+    whitelist_lib = library(
+        'whitelist',
+        'whitelist-filter.cpp',
+        'ipmiwhitelist.cpp',
+        implicit_include_directories: false,
+        dependencies: whitelist_pre,
+        version: meson.project_version(),
+        override_options: ['b_lundef=false'],
+        install: true,
+        install_dir: get_option('libdir') / 'ipmid-providers',
+    )
+endif
+
+# libsysintfcmds
+sysintfcmds_pre = declare_dependency(
+    include_directories: root_inc,
+    dependencies: [
+        channellayer_dep,
+        crypto,
+        nlohmann_json_dep,
+        phosphor_dbus_interfaces_dep,
+        phosphor_logging_dep,
+        sdbusplus_dep,
+        ipmid_dep,
+    ],
+)
+
+sysintfcmds_lib = library(
+    'sysintfcmds',
+    'systemintfcmds.cpp',
+    'host-interface.cpp',
+    implicit_include_directories: false,
+    dependencies: sysintfcmds_pre,
+    version: meson.project_version(),
+    override_options: ['b_lundef=false'],
+    install: true,
+    install_dir: get_option('libdir') / 'ipmid-providers',
+)
+
+# ipmid
+ipmid_pre = [
     sdbusplus_dep,
+    stdplus_dep,
+    phosphor_logging_dep,
+    phosphor_dbus_interfaces_dep,
+    boost,
+    crypto,
+    ipmid_dep,
+    channellayer_dep,
 ]
 
-sources = [
-    'auth_algo.cpp',
-    'sessions_manager.cpp',
-    'message_parsers.cpp',
-    'message_handler.cpp',
-    'command_table.cpp',
-    'command/channel_auth.cpp',
-    'command/guid.cpp',
-    'command/open_session.cpp',
-    'command/rakp12.cpp',
-    'command/rakp34.cpp',
-    'command/session_cmds.cpp',
-    'comm_module.cpp',
-    'main.cpp',
-    'integrity_algo.cpp',
-    'crypt_algo.cpp',
-    'sd_event_loop.cpp',
-    'sol/sol_manager.cpp',
-    'sol/sol_context.cpp',
-    'command/sol_cmds.cpp',
-    'command/payload_cmds.cpp',
-    'sol_module.cpp',
+transportoem_src = []
+if get_option('transport-oem').allowed()
+    transportoem_src = ['transporthandler_oem.cpp']
+endif
+
+storage_cmds_src = []
+if get_option('dynamic-sensors').disabled() and not get_option(
+    'dynamic-storages-only',
+).disabled()
+    storage_cmds_src = ['dbus-sdr/storagecommands.cpp', 'dbus-sdr/sdrutils.cpp']
+endif
+
+openpower_cmds_src = []
+if get_option('open-power').allowed()
+    openpower_cmds_src = ['storageaddsel.cpp']
+endif
+
+arm_sbmr_cmds_src = []
+if get_option('arm-sbmr').allowed()
+    arm_sbmr_cmds_src = ['sbmrhandler.cpp']
+endif
+
+libipmi20_src = [
+    'app/channel.cpp',
+    'app/watchdog.cpp',
+    'app/watchdog_service.cpp',
+    'apphandler.cpp',
+    'sys_info_param.cpp',
+    'sensorhandler.cpp',
+    'storagehandler.cpp',
+    'chassishandler.cpp',
+    'dcmihandler.cpp',
+    'ipmisensor.cpp',
+    'transporthandler.cpp',
+    'globalhandler.cpp',
+    'groupext.cpp',
+    'selutility.cpp',
+    'ipmi_fru_info_area.cpp',
+    'read_fru_data.cpp',
+    'sensordatahandler.cpp',
+    'user_channel/channelcommands.cpp',
+    generated_src,
+    transportoem_src,
+    storage_cmds_src,
+    openpower_cmds_src,
+    arm_sbmr_cmds_src,
+    conf_h,
 ]
 
+ipmi20_lib = library(
+    'ipmi20',
+    libipmi20_src,
+    dependencies: [ipmid_pre, nlohmann_json_dep],
+    include_directories: root_inc,
+    install: true,
+    install_dir: get_option('libdir') / 'ipmid-providers',
+    version: meson.project_version(),
+    override_options: ['b_lundef=false'],
+)
+
+libipmi20_dep = declare_dependency(
+    dependencies: ipmid_pre,
+    include_directories: root_inc,
+    link_with: ipmi20_lib,
+)
+
+# ipmid binary
 executable(
-    'netipmid',
-    sources,
-    implicit_include_directories: true,
-    include_directories: ['command', 'sol'],
-    dependencies: deps,
+    'ipmid',
+    'ipmid-new.cpp',
+    'host-cmd-manager.cpp',
+    'settings.cpp',
+    implicit_include_directories: false,
+    dependencies: [libipmi20_dep],
+    include_directories: root_inc,
+    export_dynamic: true,
     install: true,
     install_dir: get_option('bindir'),
 )
 
-systemd = dependency('systemd')
-systemd_system_unit_dir = systemd.get_variable(
-    'systemdsystemunitdir',
-    pkgconfig_define: ['prefix', get_option('prefix')],
-)
+# Dynamic Sensor Stack
+subdir('dbus-sdr')
 
-configure_file(
-    input: 'phosphor-ipmi-net@.service',
-    output: 'phosphor-ipmi-net@.service',
-    copy: true,
-    install_dir: systemd_system_unit_dir,
-)
-
-configure_file(
-    input: 'phosphor-ipmi-net@.socket',
-    output: 'phosphor-ipmi-net@.socket',
-    copy: true,
-    install_dir: systemd_system_unit_dir,
-)
-
-build_tests = get_option('tests')
-if build_tests.allowed()
-    subdir('test')
+if get_option('dynamic-sensors').disabled() or not get_option('tests').allowed()
+    library(
+        'dynamiccmds',
+        dbus_sdr_src,
+        implicit_include_directories: false,
+        dependencies: dbus_sdr_pre,
+        version: meson.project_version(),
+        override_options: ['b_lundef=false'],
+        install: true,
+        install_dir: get_option('libdir') / 'ipmid-providers',
+    )
 endif
+
+if get_option('tests').allowed()
+    subdir('test')
+    subdir('transport/serialbridge')
+endif
+
+install_subdir(
+    'user_channel',
+    install_dir: get_option('includedir'),
+    strip_directory: false,
+    exclude_files: '*.cpp',
+)
+
+# HW Transport
+subdir('transport')
diff --git a/meson.options b/meson.options
index 6f9cbaa..fcc8851 100644
--- a/meson.options
+++ b/meson.options
@@ -1,15 +1,260 @@
-option('tests', type: 'feature', value: 'enabled', description: 'Build tests')
 
+option('tests', type: 'feature', description: 'Build tests')
 option(
-    'rmcp_ping',
+    'boot-flag-safe-mode-support',
     type: 'feature',
-    value: 'enabled',
-    description: 'Enable RMCP Ping support',
+    description: 'Add option to enable/disable safe mode in boot flags',
+)
+option(
+    'i2c-whitelist-check',
+    type: 'feature',
+    description: 'Add option to enable/disable i2c master write read command white list checking',
 )
 
+# SoftPowerOff
+option('softoff', type: 'feature', description: 'Builds soft power off')
 option(
-    'pam_authenticate',
+    'softoff-busname',
+    type: 'string',
+    value: 'xyz.openbmc_project.Ipmi.Internal.SoftPowerOff',
+    description: 'The Dbus busname to own for SoftPowerOff',
+)
+option(
+    'softoff-objpath',
+    type: 'string',
+    value: '/xyz/openbmc_project/ipmi/internal/soft_power_off',
+    description: 'The SoftPowerOff Dbus root',
+)
+option(
+    'ipmi-sms-atn-ack-timeout-secs',
+    type: 'integer',
+    value: 3,
+    description: 'Timeout for host to ack and query SMS_ATN from BMC',
+)
+option(
+    'ipmi-host-shutdown-complete-timeout-secs',
+    type: 'integer',
+    value: 2700,
+    description: 'Wait time for host to shutdown',
+)
+# Indicates an in-band power off or reboot request from the host
+# This file is used to ensure the soft off service does not run for host
+# initiated shutdown or reboot requests
+option(
+    'host-inband-request-dir',
+    type: 'string',
+    value: '/run/openbmc/',
+    description: 'Directory to store host initiated shutdown file',
+)
+option(
+    'host-inband-request-file',
+    type: 'string',
+    value: 'host@%u-request',
+    description: 'File to create if host has initiated shutdown or reboot',
+)
+
+
+# Config Variables
+option(
+    'board-sensor',
+    type: 'string',
+    value: '/xyz/openbmc_project/inventory/system/chassis/motherboard',
+    description: 'The inventory path to the motherboard fault sensor',
+)
+option(
+    'system-sensor',
+    type: 'string',
+    value: '/xyz/openbmc_project/inventory/system',
+    description: 'The inventory path to the system event sensor',
+)
+
+# Control Host Interfaces
+option(
+    'control-host-busname',
+    type: 'string',
+    value: 'xyz.openbmc_project.Control.Host',
+    description: 'The Control Host Dbus busname to own',
+)
+option(
+    'control-host-obj-mgr',
+    type: 'string',
+    value: '/xyz/openbmc_project/control',
+    description: 'The Control Host D-Bus Object Manager',
+)
+option(
+    'host-name',
+    type: 'string',
+    value: 'host',
+    description: 'The Control Host D-Bus Object Manager',
+)
+
+# Power reading sensor configuration file
+option(
+    'power-reading-sensor',
+    type: 'string',
+    value: '/usr/share/ipmi-providers/power_reading.json',
+    description: 'Power reading sensor configuration file',
+)
+option(
+    'host-ipmi-lib-path',
+    type: 'string',
+    value: '/usr/lib/ipmid-providers/',
+    description: 'The file path to search for libraries',
+)
+
+# When a sensor read fails, hwmon will update the OperationalState interface's Functional property.
+# This will mark the sensor as not functional and we will skip reading from that sensor.
+option(
+    'update-functional-on-fail',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Check functional property to skip reading from faulty sensors',
+)
+
+# Features
+
+# When libuserlayer is disabled, libuserlayer won't be included in the build.
+option(
+    'libuserlayer',
+    type: 'feature',
+    description: 'Option to exclue exclude libuserlayer',
+)
+
+# When transport-oem is enabled, the transporthandler_oem.cpp contents
+# are compiled and added to the project. The transporthandler_oem.cpp file is
+# copied from your own customization layer in the
+# phosphor-ipmi-host_%.bbappend file. It is not necessary to create this file
+# unless OEM Parameter extensions are required.
+option(
+    'transport-oem',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Enable transporthandler_oem contents',
+)
+
+# IPMI whitelist mechanism is not needed by everyone; offer a way to disable it
+option(
+    'ipmi-whitelist',
+    type: 'feature',
+    description: 'Enable/disable IPMI whitelist filtering',
+)
+option(
+    'whitelist-conf',
+    type: 'string',
+    value: 'host-ipmid-whitelist.conf',
+    description: 'Paths to IPMI whitelisted commands conf files',
+)
+
+# Entity Manager Decorators
+option(
+    'entity-manager-decorators',
     type: 'feature',
     value: 'enabled',
-    description: 'Enable Pam Authenticate',
+    description: 'The Entity Manager Decorators flag is enabled by default; offer a way to disable it',
+)
+
+# Dynamic Sensor Stack
+option(
+    'dynamic-sensors',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Dynamic sensors stack is enabled by default; offer a way to disable it',
+)
+option(
+    'dynamic-sensors-write',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Dynamic sensors stack is enabled by default; offer a way to disable it',
+)
+option(
+    'hybrid-sensors',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Hybrid sensors stack is disabled by default; offer a way to enable it',
+)
+option(
+    'sensors-oem',
+    type: 'feature',
+    value: 'disabled',
+    description: 'OEM sensor SDR parsing is disabled by default; offer a way to enable it',
+)
+
+# Sensor Cache
+option(
+    'sensors-cache',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Sensor cache stack is disabled by default; offer a way to enable it',
+)
+
+# Short Sensor Names for IPMI
+option(
+    'shortname-remove-suffix',
+    type: 'feature',
+    value: 'enabled',
+    description: 'shortname-remove-suffix is enabled by default',
+)
+option(
+    'shortname-replace-words',
+    type: 'feature',
+    value: 'disabled',
+    description: 'shortname-replace-words is disabled by default',
+)
+
+# Generate configuration from Yaml
+option('sensor-yaml-gen', type: 'string', value: 'sensor-example.yaml')
+option(
+    'invsensor-yaml-gen',
+    type: 'string',
+    value: 'inventory-sensor-example.yaml',
+)
+option('fru-yaml-gen', type: 'string', value: 'fru-read-example.yaml')
+
+# Software Version
+option(
+    'get-dbus-active-software',
+    type: 'feature',
+    description: 'Use the  getActiveSoftwareVersionInfo for the BMC version and dev_id.json as backup',
+)
+option(
+    'fw-ver-regex',
+    type: 'string',
+    value: '(\\\\d+)\\\\.(\\\\d+)',
+    description: 'Regular expressions for parsing firmware revision',
+)
+option(
+    'matches-map',
+    type: 'array',
+    value: ['1', '2', '0', '0', '0', '0'],
+    description: 'An array of integers',
+)
+
+# libipmi20.so library
+option(
+    'dynamic-storages-only',
+    type: 'feature',
+    value: 'disabled',
+    description: 'Request to compile storage commands in the libipmi20 library',
+)
+
+# open-power specific functionality.
+option(
+    'open-power',
+    type: 'feature',
+    description: 'Support open-power specific functions',
+)
+
+# HW transport
+option(
+    'transport-implementation',
+    type: 'combo',
+    choices: ['null', 'serial'],
+    description: 'transport',
+)
+
+# arm-sbmr specific functionality.
+option(
+    'arm-sbmr',
+    type: 'feature',
+    description: 'Support Arm SBMR specific functions',
 )
diff --git a/read_fru_data.cpp b/read_fru_data.cpp
new file mode 100644
index 0000000..9e5fd59
--- /dev/null
+++ b/read_fru_data.cpp
@@ -0,0 +1,180 @@
+#include "read_fru_data.hpp"
+
+#include "fruread.hpp"
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.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 <algorithm>
+#include <map>
+
+extern const FruMap frus;
+namespace ipmi
+{
+namespace fru
+{
+
+using namespace phosphor::logging;
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+std::unique_ptr<sdbusplus::bus::match_t> matchPtr
+    __attribute__((init_priority(101)));
+
+namespace cache
+{
+// User initiate read FRU info area command followed by
+// FRU read command. Also data is read in small chunks of
+// the specified offset and count.
+// Caching the data which will be invalidated when ever there
+// is a change in FRU properties.
+FRUAreaMap fruMap;
+} // namespace cache
+/**
+ * @brief Read all the property value's for the specified interface
+ *  from Inventory.
+ *
+ * @param[in] intf Interface
+ * @param[in] path Object path
+ * @return map of properties
+ */
+ipmi::PropertyMap readAllProperties(const std::string& intf,
+                                    const std::string& path)
+{
+    ipmi::PropertyMap properties;
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    std::string service;
+    std::string objPath;
+
+    // Is the path the full dbus path?
+    if (path.find(xyzPrefix) != std::string::npos)
+    {
+        service = ipmi::getService(bus, intf, path);
+        objPath = path;
+    }
+    else
+    {
+        service = ipmi::getService(bus, invMgrInterface, invObjPath);
+        objPath = invObjPath + path;
+    }
+
+    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                      propInterface, "GetAll");
+    method.append(intf);
+    try
+    {
+        auto reply = bus.call(method);
+        reply.read(properties);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        // If property is not found simply return empty value
+        lg2::error("Error in reading property values: {ERROR}, path: {PATH}, "
+                   "interface: {INTERFACE}",
+                   "ERROR", e, "PATH", objPath, "INTERFACE", intf);
+    }
+
+    return properties;
+}
+
+void processFruPropChange(sdbusplus::message_t& msg)
+{
+    if (cache::fruMap.empty())
+    {
+        return;
+    }
+    std::string path = msg.get_path();
+    // trim the object base path, if found at the beginning
+    if (path.compare(0, strlen(invObjPath), invObjPath) == 0)
+    {
+        path.erase(0, strlen(invObjPath));
+    }
+    for (const auto& [fruId, instanceList] : frus)
+    {
+        auto found = std::find_if(
+            instanceList.begin(), instanceList.end(),
+            [&path](const auto& iter) { return (iter.path == path); });
+
+        if (found != instanceList.end())
+        {
+            cache::fruMap.erase(fruId);
+            break;
+        }
+    }
+}
+
+// register for fru property change
+int registerCallbackHandler()
+{
+    if (matchPtr == nullptr)
+    {
+        using namespace sdbusplus::bus::match::rules;
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+        matchPtr = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            path_namespace(invObjPath) + type::signal() +
+                member("PropertiesChanged") + interface(propInterface),
+            std::bind(processFruPropChange, std::placeholders::_1));
+    }
+    return 0;
+}
+
+/**
+ * @brief Read FRU property values from Inventory
+ *
+ * @param[in] fruNum  FRU id
+ * @return populate FRU Inventory data
+ */
+FruInventoryData readDataFromInventory(const FRUId& fruNum)
+{
+    auto iter = frus.find(fruNum);
+    if (iter == frus.end())
+    {
+        lg2::error("Unsupported FRU ID: {FRUID}", "FRUID", fruNum);
+        elog<InternalFailure>();
+    }
+
+    FruInventoryData data;
+    auto& instanceList = iter->second;
+    for (auto& instance : instanceList)
+    {
+        for (auto& intf : instance.interfaces)
+        {
+            ipmi::PropertyMap allProp =
+                readAllProperties(intf.first, instance.path);
+            for (auto& properties : intf.second)
+            {
+                auto iter = allProp.find(properties.first);
+                if (iter != allProp.end())
+                {
+                    data[properties.second.section].emplace(
+                        properties.second.property,
+                        std::move(
+                            std::get<std::string>(allProp[properties.first])));
+                }
+            }
+        }
+    }
+    return data;
+}
+
+const FruAreaData& getFruAreaData(const FRUId& fruNum)
+{
+    auto iter = cache::fruMap.find(fruNum);
+    if (iter != cache::fruMap.end())
+    {
+        return iter->second;
+    }
+    auto invData = readDataFromInventory(fruNum);
+
+    // Build area info based on inventory data
+    FruAreaData newdata = buildFruAreaData(std::move(invData));
+    cache::fruMap.emplace(fruNum, std::move(newdata));
+    return cache::fruMap.at(fruNum);
+}
+} // namespace fru
+} // namespace ipmi
diff --git a/read_fru_data.hpp b/read_fru_data.hpp
new file mode 100644
index 0000000..e0997fd
--- /dev/null
+++ b/read_fru_data.hpp
@@ -0,0 +1,38 @@
+#pragma once
+#include "ipmi_fru_info_area.hpp"
+
+#include <sdbusplus/bus.hpp>
+
+#include <string>
+
+namespace ipmi
+{
+namespace fru
+{
+using FRUId = uint8_t;
+using FRUAreaMap = std::map<FRUId, FruAreaData>;
+
+static constexpr auto xyzPrefix = "/xyz/openbmc_project/";
+static constexpr auto invMgrInterface = "xyz.openbmc_project.Inventory.Manager";
+static constexpr auto invObjPath = "/xyz/openbmc_project/inventory";
+static constexpr auto propInterface = "org.freedesktop.DBus.Properties";
+static constexpr auto invItemInterface = "xyz.openbmc_project.Inventory.Item";
+static constexpr auto itemPresentProp = "Present";
+
+/**
+ * @brief Get fru area data as per IPMI specification
+ *
+ * @param[in] fruNum FRU ID
+ *
+ * @return FRU area data as per IPMI specification
+ */
+const FruAreaData& getFruAreaData(const FRUId& fruNum);
+
+/**
+ * @brief Register callback handler into DBUS for PropertyChange events
+ *
+ * @return negative value on failure
+ */
+int registerCallbackHandler();
+} // namespace fru
+} // namespace ipmi
diff --git a/sbmrhandler.cpp b/sbmrhandler.cpp
new file mode 100644
index 0000000..328d503
--- /dev/null
+++ b/sbmrhandler.cpp
@@ -0,0 +1,317 @@
+#include <ipmid/api.hpp>
+#include <ipmid/filter.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+constexpr auto sbmrBootStateIntf = "xyz.openbmc_project.State.Boot.Raw";
+constexpr auto sbmrHostStateIntf = "xyz.openbmc_project.State.Boot.Progress";
+constexpr auto sbmrBootProgressCodeSize = 9;
+
+constexpr auto bootProgressOem = "OEM";
+constexpr auto bootProgressOsRuning = "OSRunning";
+constexpr auto bootProgressOsStart = "OSStart";
+constexpr auto bootProgressPciInit = "PCIInit";
+constexpr auto bootProgressSystemInitComplete = "SystemInitComplete";
+constexpr auto bootProgressSystemSetup = "SystemSetup";
+
+// EFI_STATUS_CODE_TYPE
+constexpr auto efiProgressCode = 0x01;
+constexpr auto efiCodeSeverityNone = 0;
+
+// EFI_STATUS_CODE_CLASS
+constexpr auto efiIoBus = 0x02;
+constexpr auto efiSoftware = 0x03;
+
+// EFI_STATUS_CODE_SUBCLASS
+constexpr auto efiIoBusPci = 0x01;
+constexpr auto efiSoftwareDxeCore = 0x04;
+constexpr auto efiSoftwareDxeBsDriver = 0x05;
+constexpr auto efiSoftwareEfiBootService = 0x10;
+
+// EFI_STATUS_CODE_OPERATION
+constexpr auto efiIoBusPciResAlloc = 0x0110;
+constexpr auto efiSwDxeCorePcHandoffToNext = 0x0110;
+constexpr auto efiSwPcUserSetup = 0x0700;
+constexpr auto efiSwOsLoaderStart = 0x0180;
+constexpr auto efiSwBsPcExitBootServices = 0x1910;
+
+void registerNetfnSBMRFunctions() __attribute__((constructor));
+
+namespace ipmi
+{
+
+std::string getSbmrBootProgressStage(uint8_t codeType, uint8_t codeSeverity,
+                                     uint8_t codeClass, uint8_t codeSubClass,
+                                     uint16_t codeOperation)
+{
+    // Return OEM if code type or severity are unexpected
+    if (codeType != efiProgressCode || codeSeverity != efiCodeSeverityNone)
+    {
+        return bootProgressOem;
+    }
+
+    // Code Class Software
+    if (codeClass == efiSoftware)
+    {
+        if (codeSubClass == efiSoftwareDxeCore &&
+            codeOperation == efiSwDxeCorePcHandoffToNext)
+        {
+            return bootProgressSystemInitComplete;
+        }
+        else if (codeSubClass == efiSoftwareDxeBsDriver &&
+                 codeOperation == efiSwPcUserSetup)
+        {
+            return bootProgressSystemSetup;
+        }
+        else if (codeSubClass == efiSoftwareDxeBsDriver &&
+                 codeOperation == efiSwOsLoaderStart)
+        {
+            return bootProgressOsStart;
+        }
+        else if (codeSubClass == efiSoftwareEfiBootService &&
+                 codeOperation == efiSwBsPcExitBootServices)
+        {
+            return bootProgressOsRuning;
+        }
+    }
+    // Code Class IO Bus
+    else if (codeClass == efiIoBus)
+    {
+        if (codeSubClass == efiIoBusPci && codeOperation == efiIoBusPciResAlloc)
+        {
+            return bootProgressPciInit;
+        }
+    }
+
+    // Fallback to OEM if no conditions met
+    return bootProgressOem;
+}
+
+bool updateBootProgressProperty(ipmi::Context::ptr& ctx,
+                                const std::string& value)
+{
+    std::string bootProgress =
+        "xyz.openbmc_project.State.Boot.Progress.ProgressStages." + value;
+    ipmi::DbusObjectInfo sbmrHostStateObject{};
+
+    /* Get Host State Object */
+    boost::system::error_code ec =
+        ipmi::getDbusObject(ctx, sbmrHostStateIntf, sbmrHostStateObject);
+    if (ec.value())
+    {
+        lg2::error("Failed to get Host State object, Error={ERROR}", "ERROR",
+                   ec.message());
+        return false;
+    }
+
+    /* Set Host State property */
+    ec = ipmi::setDbusProperty(ctx, sbmrHostStateObject.second,
+                               sbmrHostStateObject.first, sbmrHostStateIntf,
+                               "BootProgress", bootProgress);
+    if (ec.value())
+    {
+        lg2::error(
+            "updateBootProgressProperty, can't set progerty - Error={ERROR}",
+            "ERROR", ec.message());
+        return false;
+    }
+
+    return true;
+}
+
+bool updateBootProgressLastUpdateProperty(ipmi::Context::ptr& ctx,
+                                          uint64_t timeStamp)
+{
+    ipmi::DbusObjectInfo sbmrHostStateObject{};
+
+    /* Get Host State Object */
+    boost::system::error_code ec =
+        ipmi::getDbusObject(ctx, sbmrHostStateIntf, sbmrHostStateObject);
+    if (ec.value())
+    {
+        lg2::error("Failed to get Host State object, Error={ERROR}", "ERROR",
+                   ec.message());
+        return false;
+    }
+
+    /* Set Host State property */
+    ec = ipmi::setDbusProperty(ctx, sbmrHostStateObject.second,
+                               sbmrHostStateObject.first, sbmrHostStateIntf,
+                               "BootProgressLastUpdate", timeStamp);
+    if (ec.value())
+    {
+        lg2::error(
+            "updateBootProgressLastUpdateProperty, can't set property - Error={ERROR}",
+            "ERROR", ec.message());
+        return false;
+    }
+
+    return true;
+}
+
+ipmi::RspType<> sendBootProgressCode(
+    ipmi::Context::ptr ctx, uint8_t codeType, uint8_t codeReserved1,
+    uint8_t codeReserved2, uint8_t codeSeverity, uint8_t codeOperation1,
+    uint8_t codeOperation2, uint8_t codeSubClass, uint8_t codeClass,
+    uint8_t instance)
+{
+    /* Update boot progress code to Dbus property */
+    ipmi::DbusObjectInfo sbmrBootStateObject{};
+
+    /* Get Boot State Object */
+    boost::system::error_code ec =
+        ipmi::getDbusObject(ctx, sbmrBootStateIntf, sbmrBootStateObject);
+    if (ec.value())
+    {
+        lg2::error("Failed to get Boot State object, Error={ERROR}", "ERROR",
+                   ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+
+    /* Set Boot State property */
+    BootProgressCode bpCode(
+        {codeType, codeReserved1, codeReserved2, codeSeverity, codeOperation1,
+         codeOperation2, codeSubClass, codeClass, instance},
+        {});
+    ec = ipmi::setDbusProperty(ctx, sbmrBootStateObject.second,
+                               sbmrBootStateObject.first, sbmrBootStateIntf,
+                               "Value", bpCode);
+    if (ec.value())
+    {
+        lg2::error("Failed to set boot progress code, Error={ERROR}", "ERROR",
+                   ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+
+    /* Update Redfish BootProgress object */
+    auto timeStamp = std::chrono::duration_cast<std::chrono::microseconds>(
+                         std::chrono::system_clock::now().time_since_epoch())
+                         .count();
+    if (!updateBootProgressLastUpdateProperty(ctx, timeStamp))
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    /* Chek for BootProgressTypes */
+    uint16_t codeOperation =
+        static_cast<uint16_t>(codeOperation1) << 8 | codeOperation2;
+
+    std::string stage = getSbmrBootProgressStage(
+        codeType, codeSeverity, codeClass, codeSubClass, codeOperation);
+
+    if (!updateBootProgressProperty(ctx, stage))
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess();
+}
+
+ipmi::RspType<uint8_t, // STATUS_CODE_TYPE
+              uint8_t, // STATUS_CODE_RESERVED1
+              uint8_t, // STATUS_CODE_RESERVED2
+              uint8_t, // STATUS_CODE_SEVERITY
+              uint8_t, // STATUS_CODE_OPERATION1
+              uint8_t, // STATUS_CODE_OPERATION2
+              uint8_t, // STATUS_CODE_SUBCLASS
+              uint8_t, // STATUS_CODE_CLASS
+              uint8_t> // Instance
+    getBootProgressCode(ipmi::Context::ptr ctx)
+{
+    ipmi::DbusObjectInfo sbmrBootStateObject{};
+
+    /* Get Boot State Object */
+    boost::system::error_code ec =
+        ipmi::getDbusObject(ctx, sbmrBootStateIntf, sbmrBootStateObject);
+    if (ec.value())
+    {
+        lg2::error("Failed to get Boot State object, Error={ERROR}", "ERROR",
+                   ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+
+    /* Get Boot State property */
+    BootProgressCode value;
+    ec = ipmi::getDbusProperty(ctx, sbmrBootStateObject.second,
+                               sbmrBootStateObject.first, sbmrBootStateIntf,
+                               "Value", value);
+    if (ec.value())
+    {
+        lg2::error("Can't get property Value, Error={ERROR}", "ERROR",
+                   ec.message());
+        return ipmi::responseUnspecifiedError();
+    }
+
+    auto respBootProgressCode = std::get<0>(std::move(value));
+    if (respBootProgressCode.size() != sbmrBootProgressCodeSize)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(
+        respBootProgressCode[0], respBootProgressCode[1],
+        respBootProgressCode[2], respBootProgressCode[3],
+        respBootProgressCode[4], respBootProgressCode[5],
+        respBootProgressCode[6], respBootProgressCode[7],
+        respBootProgressCode[8]);
+}
+
+bool checkAllowedMediumType(uint8_t mediumType)
+{
+    if (mediumType ==
+            static_cast<uint8_t>(ipmi::EChannelMediumType::smbusV20) ||
+        mediumType ==
+            static_cast<uint8_t>(ipmi::EChannelMediumType::systemInterface) ||
+        mediumType == static_cast<uint8_t>(ipmi::EChannelMediumType::oem))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+ipmi::Cc sbmrFilterCommands(ipmi::message::Request::ptr request)
+{
+    if (request->ctx->netFn != ipmi::netFnGroup ||
+        request->ctx->group != ipmi::groupSBMR)
+    {
+        // Skip if not group SBMR
+        return ipmi::ccSuccess;
+    }
+
+    ipmi::ChannelInfo chInfo;
+    if (ipmi::getChannelInfo(request->ctx->channel, chInfo) != ipmi::ccSuccess)
+    {
+        lg2::error("Failed to get Channel Info, channel={CHANNEL}", "CHANNEL",
+                   request->ctx->channel);
+        return ipmi::ccUnspecifiedError;
+    }
+
+    if (request->ctx->cmd == ipmi::sbmr::cmdSendBootProgressCode &&
+        !checkAllowedMediumType(chInfo.mediumType))
+    {
+        lg2::error("Error - Medium interface not supported, medium={TYPE}",
+                   "TYPE", chInfo.mediumType);
+        return ipmi::ccCommandNotAvailable;
+    }
+
+    return ipmi::ccSuccess;
+}
+
+} // namespace ipmi
+
+void registerNetfnSBMRFunctions()
+{
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupSBMR,
+                         ipmi::sbmr::cmdSendBootProgressCode,
+                         ipmi::Privilege::Admin, ipmi::sendBootProgressCode);
+
+    registerGroupHandler(ipmi::prioOpenBmcBase, ipmi::groupSBMR,
+                         ipmi::sbmr::cmdGetBootProgressCode,
+                         ipmi::Privilege::User, ipmi::getBootProgressCode);
+
+    ipmi::registerFilter(ipmi::prioOemBase,
+                         [](ipmi::message::Request::ptr request) {
+                             return ipmi::sbmrFilterCommands(request);
+                         });
+}
diff --git a/scripts/entity-example.md b/scripts/entity-example.md
new file mode 100644
index 0000000..abeb581
--- /dev/null
+++ b/scripts/entity-example.md
@@ -0,0 +1,156 @@
+# Entity-example
+
+If your platform requires the entity container map, you can provide a json file
+of the format:
+
+```json
+[
+  {
+    "id": 1,
+    "containerEntityId": 2,
+    "containerEntityInstance": 3,
+    "isList": false,
+    "isLinked": false,
+    "entities": [
+      { "id": 1, "instance": 2 },
+      { "id": 1, "instance": 3 },
+      { "id": 1, "instance": 4 },
+      { "id": 1, "instance": 5 }
+    ]
+  }
+]
+```
+
+as part of your `phosphor-ipmi-config`
+
+The above json is identical to the original YAML documented below:
+
+```text
+# This record has:
+# Container Entity Id and Container Entity Instance = (0x13, 0x81)
+# Contained Entity Id and Contained Entity Instance = (0x0A, 0x1),
+# (0x0A, 0x3), (0x0A, 0x5), (0x0A, 0x7)
+# Entity Record id is the key
+0x01:
+  # Container entity contains other entities
+  # Entity Id and entity Instance for the container entity
+  containerEntityId: 0x13
+  containerEntityInstance: 0x81
+  # A record can have contained entities as a four entry list or as upto
+  # two ranges of entity instances; this record has contained entities
+  # as a four entry list
+  isList: "true"
+  # Records can be linked if necessary to extend the number of contained
+  # entities within a container entity; this record is not linked
+  isLinked: "false"
+  entityId1: 0x0A
+  entityInstance1: 0x1
+  entityId2: 0x0A
+  entityInstance2: 0x3
+  entityId3: 0x0A
+  entityInstance3: 0x5
+  entityId4: 0x0A
+  entityInstance4: 0x7
+
+# The below two records have:
+# Container Entity Id and Container Entity Instance = (0x18, 0x2)
+# Contained Entity Id and Contained Entity Instance = (0x1D, 0x1),
+# (0x1D, 0x4), (0x1D, 0x6), (0x2B, 0x1), (0x2B, 0x3), (0x0F, 0x1),
+# (0x0F, 0x3), (0x10, 0x5)
+0x02:
+  containerEntityId: 0x18
+  containerEntityInstance: 0x2
+  # This record  has contained entities as a four entry list
+  isList: "true"
+  # This record is linked with the below record; this record and the
+  # below record have the same container entity Id and container entity
+  # instance;
+  isLinked: "true"
+  entityId1: 0x1D
+  entityInstance1: 0x1
+  entityId2: 0x1D
+  entityInstance2: 0x4
+  entityId3: 0x1D
+  entityInstance3: 0x6
+  entityId4: 0x2B
+  entityInstance4: 0x1
+
+0x03:
+  containerEntityId: 0x18
+  containerEntityInstance: 0x2
+  # This record  has contained entities as a four entry list
+  isList: "true"
+  # This record is linked with the above record; this record and the
+  # above record have the same container entity Id and container entity
+  # instance
+  isLinked: "true"
+  entityId1: 0x2B
+  entityInstance1: 0x3
+  entityId2: 0x0F
+  entityInstance2: 0x1
+  entityId3: 0x0F
+  entityInstance3: 0x3
+  entityId4: 0x10
+  entityInstance4: 0x5
+
+# This record has:
+# Container Entity Id and Container Entity Instance = (0x1E, 0x1)
+# Contained Entity Id and Contained Entity Instance = (0x20, 0x1),
+# (0x20, 0x2), (0x20, 0x3), (0x20, 0x7), (0x20, 0x8), (0x20, 0x9)
+0x04:
+  containerEntityId: 0x1E
+  containerEntityInstance: 0x1
+  # This record has contained entities as two ranges of entity instances
+  isList: "false"
+  # This record is not linked
+  isLinked: "false"
+  entityId1: 0x20
+  entityInstance1: 0x1
+  entityId2: 0x20
+  entityInstance2: 0x3
+  entityId3: 0x20
+  entityInstance3: 0x7
+  entityId4: 0x20
+  entityInstance4: 0x9
+
+# The below two records have:
+# Container Entity Id and Container Entity Instance = (0x1E, 0x3)
+# Contained Entity Id and Contained Entity Instance = (0x20, 0x1),
+# (0x20, 0x2), (0x20, 0x3), (0x20, 0x6), (0x20, 0x7), (0x20, 0x8),
+# (0x20, 0xA), (0x20, 0xB), (0x20, 0xD), (0x20, 0xE), (0x20, 0xF)
+0x05:
+  containerEntityId: 0x1E
+  containerEntityInstance: 0x03
+  # This record has contained entities as two ranges of entity instances
+  isList: "false"
+  # This record is linked with the below record; this record and the
+  # below record have the same container entity Id and container entity
+  # instance;
+  isLinked: "true"
+  entityId1: 0x20
+  entityInstance1: 0x1
+  entityId2: 0x20
+  entityInstance2: 0x3
+  entityId3: 0x20
+  entityInstance3: 0x6
+  entityId4: 0x20
+  entityInstance4: 0x8
+
+0x06:
+  containerEntityId: 0x1E
+  containerEntityInstance: 0x03
+  # This record has contained entities as two ranges of entity instances
+  isList: "false"
+  # This record is linked with the above record; this record and the
+  # above record have the same container entity Id and container entity
+  # instance;
+  isLinked: "true"
+  entityId1: 0x20
+  entityInstance1: 0xA
+  entityId2: 0x20
+  entityInstance2: 0xB
+  entityId3: 0x20
+  entityInstance3: 0xD
+  entityId4: 0x20
+  entityInstance4: 0xF
+```
diff --git a/scripts/fru-read-example.yaml b/scripts/fru-read-example.yaml
new file mode 100644
index 0000000..a186794
--- /dev/null
+++ b/scripts/fru-read-example.yaml
@@ -0,0 +1,139 @@
+# A YAML similar to this example would have to be generated, for eg with MRW
+# inputs and system configuration, to depict IPMI Fru information.
+#
+# This file maps IPMI properties to phosphor dbus inventory properties
+#
+# This YAML could help generate C++ code.
+# Format of the YAML:
+# Fruid:
+#   Associated Fru paths
+#     d-bus Interfaces
+#       d-bus Properties
+#         IPMI Fru mapping
+0:
+    /system:
+        entityID: 23
+        entityInstance: 1
+        interfaces:
+            xyz.openbmc_project.Inventory.Item:
+                PrettyName:
+                    IPMIFruProperty: Product Name
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Decorator.Asset:
+                Manufacturer:
+                    IPMIFruProperty: Manufacturer
+                    IPMIFruSection: Product
+                PartNumber:
+                    IPMIFruProperty: Part Number
+                    IPMIFruSection: Product
+                SerialNumber:
+                    IPMIFruProperty: Serial Number
+                    IPMIFruSection: Product
+                BuildDate:
+                    IPMIFruProperty: Mfg Date
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Decorator.Revision:
+                Version:
+                    IPMIFruProperty: Version
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Item.System:
+1:
+    /system/chassis/motherboard/dimm0:
+        entityID: 32
+        entityInstance: 1
+        interfaces:
+            xyz.openbmc_project.Inventory.Item:
+                PrettyName:
+                    IPMIFruProperty: Product Name
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Decorator.Asset:
+                Manufacturer:
+                    IPMIFruProperty: Manufacturer
+                    IPMIFruSection: Product
+                BuildDate:
+                    IPMIFruProperty: Mfg Date
+                    IPMIFruSection: Product
+                SerialNumber:
+                    IPMIFruProperty: Serial Number
+                    IPMIFruSection: Product
+                PartNumber:
+                    IPMIFruProperty: Part Number
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Decorator.Revision:
+                Version:
+                    IPMIFruProperty: Version
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Item.Dimm:
+2:
+    /system/chassis/motherboard/dimm1:
+        entityID: 32
+        entityInstance: 2
+        interfaces:
+            xyz.openbmc_project.Inventory.Item:
+                PrettyName:
+                    IPMIFruProperty: Product Name
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Decorator.Asset:
+                Manufacturer:
+                    IPMIFruProperty: Manufacturer
+                    IPMIFruSection: Product
+                BuildDate:
+                    IPMIFruProperty: Mfg Date
+                    IPMIFruSection: Product
+                SerialNumber:
+                    IPMIFruProperty: Serial Number
+                    IPMIFruSection: Product
+                PartNumber:
+                    IPMIFruProperty: Part Number
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Decorator.Revision:
+                Version:
+                    IPMIFruProperty: Version
+                    IPMIFruSection: Product
+            xyz.openbmc_project.Inventory.Item.Dimm:
+3:
+    /system/chassis/motherboard/cpu0:
+        entityID: 3
+        entityInstance: 1
+        interfaces:
+            xyz.openbmc_project.Inventory.Item:
+                PrettyName:
+                    IPMIFruProperty: Product Name
+                    IPMIFruSection: Board
+            xyz.openbmc_project.Inventory.Decorator.Asset:
+                BuildDate:
+                    IPMIFruProperty: Mfg Date
+                    IPMIFruSection: Board
+                SerialNumber:
+                    IPMIFruProperty: Serial Number
+                    IPMIFruSection: Board
+                PartNumber:
+                    IPMIFruProperty: Part Number
+                    IPMIFruSection: Board
+                Manufacturer:
+                    IPMIFruProperty: Manufacturer
+                    IPMIFruSection: Board
+            xyz.openbmc_project.Inventory.Item.Cpu:
+4:
+    /system/chassis/motherboard/cpu1:
+        entityID: 3
+        entityInstance: 2
+        interfaces:
+            xyz.openbmc_project.Inventory.Item:
+                PrettyName:
+                    IPMIFruProperty: Product Name
+                    IPMIFruSection: Board
+            xyz.openbmc_project.Inventory.Decorator.Asset:
+                BuildDate:
+                    IPMIFruProperty: Mfg Date
+                    IPMIFruSection: Board
+                SerialNumber:
+                    IPMIFruProperty: Serial Number
+                    IPMIFruSection: Board
+                PartNumber:
+                    IPMIFruProperty: Part Number
+                    IPMIFruSection: Board
+                Manufacturer:
+                    IPMIFruProperty: Manufacturer
+                    IPMIFruSection: Board
+            xyz.openbmc_project.Inventory.Item.Cpu:
diff --git a/scripts/fru_gen.py b/scripts/fru_gen.py
new file mode 100755
index 0000000..fd0941c
--- /dev/null
+++ b/scripts/fru_gen.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+
+import yaml
+from mako.template import Template
+
+
+def generate_cpp(inventory_yaml, output_dir):
+    with open(inventory_yaml, "r") as f:
+        ifile = yaml.safe_load(f)
+        if not isinstance(ifile, dict):
+            ifile = {}
+
+        # Render the mako template
+
+        t = Template(filename=os.path.join(script_dir, "readfru.cpp.mako"))
+
+        output_hpp = os.path.join(output_dir, "fru-read-gen.cpp")
+        with open(output_hpp, "w") as fd:
+            fd.write(t.render(fruDict=ifile))
+
+
+def main():
+    valid_commands = {"generate-cpp": generate_cpp}
+    parser = argparse.ArgumentParser(description="IPMI FRU map code generator")
+
+    parser.add_argument(
+        "-i",
+        "--inventory_yaml",
+        dest="inventory_yaml",
+        default="example.yaml",
+        help="input inventory yaml file to parse",
+    )
+
+    parser.add_argument(
+        "-o",
+        "--output-dir",
+        dest="outputdir",
+        default=".",
+        help="output directory",
+    )
+
+    parser.add_argument(
+        "command",
+        metavar="COMMAND",
+        type=str,
+        choices=valid_commands.keys(),
+        help="Command to run.",
+    )
+
+    args = parser.parse_args()
+
+    if not (os.path.isfile(args.inventory_yaml)):
+        sys.exit("Can not find input yaml file " + args.inventory_yaml)
+
+    function = valid_commands[args.command]
+    function(args.inventory_yaml, args.outputdir)
+
+
+if __name__ == "__main__":
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    main()
diff --git a/scripts/inventory-sensor-example.yaml b/scripts/inventory-sensor-example.yaml
new file mode 100644
index 0000000..5dde38f
--- /dev/null
+++ b/scripts/inventory-sensor-example.yaml
@@ -0,0 +1,340 @@
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm0:
+    sensorID: 0xa6
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm1:
+    sensorID: 0xa8
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm10:
+    sensorID: 0xba
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm11:
+    sensorID: 0xbc
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm12:
+    sensorID: 0xbe
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm13:
+    sensorID: 0xc0
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm14:
+    sensorID: 0xc2
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm15:
+    sensorID: 0xc4
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm2:
+    sensorID: 0xaa
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm3:
+    sensorID: 0xac
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm4:
+    sensorID: 0xae
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm5:
+    sensorID: 0xb0
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm6:
+    sensorID: 0xb2
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm7:
+    sensorID: 0xb4
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm8:
+    sensorID: 0xb6
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm9:
+    sensorID: 0xb8
+    sensorType: 0x0C
+    eventReadingType: 0x6F
+    offset: 0x04
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0:
+    sensorID: 0x5a
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core0:
+    sensorID: 0x12
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core1:
+    sensorID: 0x15
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core2:
+    sensorID: 0x18
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core3:
+    sensorID: 0x1b
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core4:
+    sensorID: 0x1e
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core5:
+    sensorID: 0x21
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core6:
+    sensorID: 0x24
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core7:
+    sensorID: 0x27
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core8:
+    sensorID: 0x2a
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core9:
+    sensorID: 0x2d
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core10:
+    sensorID: 0x30
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core11:
+    sensorID: 0x33
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core12:
+    sensorID: 0x36
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core13:
+    sensorID: 0x39
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core14:
+    sensorID: 0x3c
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core15:
+    sensorID: 0x3f
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core16:
+    sensorID: 0x42
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core17:
+    sensorID: 0x45
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core18:
+    sensorID: 0x48
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core19:
+    sensorID: 0x4b
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core20:
+    sensorID: 0x4e
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core21:
+    sensorID: 0x51
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core22:
+    sensorID: 0x54
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0/core23:
+    sensorID: 0x57
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1:
+    sensorID: 0xa4
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core0:
+    sensorID: 0x5c
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core1:
+    sensorID: 0x5f
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core2:
+    sensorID: 0x62
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core3:
+    sensorID: 0x65
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core4:
+    sensorID: 0x68
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core5:
+    sensorID: 0x6b
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core6:
+    sensorID: 0x6e
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core7:
+    sensorID: 0x71
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core8:
+    sensorID: 0x74
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core9:
+    sensorID: 0x77
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core10:
+    sensorID: 0x7a
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core11:
+    sensorID: 0x7d
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core12:
+    sensorID: 0x80
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core13:
+    sensorID: 0x83
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core14:
+    sensorID: 0x86
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core15:
+    sensorID: 0x89
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core16:
+    sensorID: 0x8c
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core17:
+    sensorID: 0x8f
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core18:
+    sensorID: 0x92
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core19:
+    sensorID: 0x95
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core20:
+    sensorID: 0x98
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core21:
+    sensorID: 0x9b
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core22:
+    sensorID: 0x9e
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1/core23:
+    sensorID: 0xa1
+    sensorType: 0x07
+    eventReadingType: 0x6F
+    offset: 0x08
+/xyz/openbmc_project/inventory/system/chassis/motherboard:
+    sensorID: 0x0c
+    sensorType: 0xC7
+    eventReadingType: 0x03
+    offset: 0x00
+/xyz/openbmc_project/inventory/system:
+    sensorID: 0x01
+    sensorType: 0x12
+    eventReadingType: 0x6F
+    offset: 0x02
diff --git a/scripts/inventory-sensor.py b/scripts/inventory-sensor.py
new file mode 100755
index 0000000..8c7bc19
--- /dev/null
+++ b/scripts/inventory-sensor.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+
+import yaml
+from mako.template import Template
+
+
+def generate_cpp(sensor_yaml, output_dir):
+    with open(sensor_yaml, "r") as f:
+        ifile = yaml.safe_load(f)
+        if not isinstance(ifile, dict):
+            ifile = {}
+
+        # Render the mako template
+
+        t = Template(
+            filename=os.path.join(script_dir, "inventorysensor.cpp.mako")
+        )
+
+        output_cpp = os.path.join(output_dir, "inventory-sensor-gen.cpp")
+        with open(output_cpp, "w") as fd:
+            fd.write(t.render(sensorDict=ifile))
+
+
+def main():
+    valid_commands = {"generate-cpp": generate_cpp}
+    parser = argparse.ArgumentParser(
+        description="Inventory Object to IPMI SensorID code generator"
+    )
+
+    parser.add_argument(
+        "-i",
+        "--sensor_yaml",
+        dest="sensor_yaml",
+        default="example.yaml",
+        help="input sensor yaml file to parse",
+    )
+
+    parser.add_argument(
+        "-o",
+        "--output-dir",
+        dest="outputdir",
+        default=".",
+        help="output directory",
+    )
+
+    parser.add_argument(
+        "command",
+        metavar="COMMAND",
+        type=str,
+        choices=valid_commands.keys(),
+        help="Command to run.",
+    )
+
+    args = parser.parse_args()
+
+    if not (os.path.isfile(args.sensor_yaml)):
+        sys.exit("Can not find input yaml file " + args.sensor_yaml)
+
+    function = valid_commands[args.command]
+    function(args.sensor_yaml, args.outputdir)
+
+
+if __name__ == "__main__":
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    main()
diff --git a/scripts/inventorysensor.cpp.mako b/scripts/inventorysensor.cpp.mako
new file mode 100644
index 0000000..be3bb1e
--- /dev/null
+++ b/scripts/inventorysensor.cpp.mako
@@ -0,0 +1,26 @@
+## This file is a template.  The comment below is emitted
+## into the rendered file; feel free to edit this file.
+
+// !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!!
+
+#include <ipmid/types.hpp>
+using namespace ipmi::sensor;
+
+extern const InvObjectIDMap __attribute__((init_priority(101))) invSensors = {
+% for key in sensorDict.keys():
+   % if key:
+{"${key}",
+    {
+<%
+       objectPath = sensorDict[key]
+       sensorID = objectPath["sensorID"]
+       sensorType = objectPath["sensorType"]
+       eventReadingType = objectPath["eventReadingType"]
+       offset = objectPath["offset"]
+%>
+        ${sensorID},${sensorType},${eventReadingType},${offset}
+    }
+},
+   % endif
+% endfor
+};
diff --git a/scripts/meson.build b/scripts/meson.build
new file mode 100644
index 0000000..c5fcae5
--- /dev/null
+++ b/scripts/meson.build
@@ -0,0 +1,50 @@
+# Generate Configuration Files from Yaml
+python_exe = find_program('python3', 'python')
+
+sensor_gen = custom_target(
+    'sensor-gen',
+    output: 'sensor-gen.cpp',
+    input: ['sensor_gen.py', get_option('sensor-yaml-gen')],
+    command: [
+        python_exe,
+        '@INPUT0@',
+        '-i',
+        '@INPUT1@',
+        '-o',
+        meson.current_build_dir(),
+        'generate-cpp',
+    ],
+)
+generated_src += sensor_gen
+
+invsensor_gen = custom_target(
+    'invsensor-gen',
+    output: 'inventory-sensor-gen.cpp',
+    input: ['inventory-sensor.py', get_option('invsensor-yaml-gen')],
+    command: [
+        python_exe,
+        '@INPUT0@',
+        '-i',
+        '@INPUT1@',
+        '-o',
+        meson.current_build_dir(),
+        'generate-cpp',
+    ],
+)
+generated_src += invsensor_gen
+
+fru_gen = custom_target(
+    'fru-gen',
+    output: 'fru-read-gen.cpp',
+    input: ['fru_gen.py', get_option('fru-yaml-gen')],
+    command: [
+        python_exe,
+        '@INPUT0@',
+        '-i',
+        '@INPUT1@',
+        '-o',
+        meson.current_build_dir(),
+        'generate-cpp',
+    ],
+)
+generated_src += fru_gen
diff --git a/scripts/readfru.cpp.mako b/scripts/readfru.cpp.mako
new file mode 100644
index 0000000..e7fbab8
--- /dev/null
+++ b/scripts/readfru.cpp.mako
@@ -0,0 +1,42 @@
+// !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!!
+#include <iostream>
+#include "fruread.hpp"
+
+extern const FruMap __attribute__((init_priority(101))) frus = {
+% for key in fruDict.keys():
+   {${key},{
+<%
+    instanceList = fruDict[key]
+%>
+    % for instancePath,instanceInfo in instanceList.items():
+<%
+        entityID = instanceInfo["entityID"]
+        entityInstance = instanceInfo["entityInstance"]
+        interfaces = instanceInfo["interfaces"]
+%>
+         {${entityID}, ${entityInstance}, "${instancePath}",{
+         % for interface,properties in interfaces.items():
+             {"${interface}",{
+            % if properties:
+                % for dbus_property,property_value in properties.items():
+                    {"${dbus_property}",{
+                        "${property_value.get("IPMIFruSection", "")}",
+                        "${property_value.get("IPMIFruProperty", "")}",\
+<%
+    delimiter = property_value.get("IPMIFruValueDelimiter")
+    if not delimiter:
+        delimiter = ""
+    else:
+        delimiter = '\\' + hex(delimiter)[1:]
+%>
+                     "${delimiter}"
+                 }},
+                % endfor
+            %endif
+             }},
+         % endfor
+        }},
+    % endfor
+   }},
+% endfor
+};
diff --git a/scripts/sensor-example.yaml b/scripts/sensor-example.yaml
new file mode 100644
index 0000000..89430e4
--- /dev/null
+++ b/scripts/sensor-example.yaml
@@ -0,0 +1,194 @@
+# Sensor id is the key
+0x60:
+    sensorType: 0x07
+    sensorReadingType: 0x6F
+    # A "set" operation on this sensor should update this d-bus path.
+    # If the path is not specified, an MRW parser will try to determine the path
+    # based on the sensor id, on MRW based systems.  This typically happens for
+    # inventory items.
+    path: /org/open_power/control/occ0
+    # The interface that exposes method(s) to update the path above.
+    serviceInterface: org.freedesktop.DBus.Properties
+    # Where the sensor value is represented - assertion bits/reading/event data
+    readingType: assertion
+    # indicate if a sensor is READ/WRITE/RW.
+    # This particular sensor read and write operation is allowed
+    mutability: Mutability::Write|Mutability::Read
+    # Sensor name would be occ0
+    sensorNamePattern: nameLeaf
+    eventType: 0x6F
+    # All the d-bus interfaces : properties that must be updated for this path
+    interfaces:
+        # One or more interface dict entries
+        org.open_power.OCC.Status:
+            OccActive:
+                Offsets:
+                    # Sensor type specific offset
+                    0x06:
+                        # OccActive is a boolean
+                        type: "bool"
+                        # If offset 0x06 is asserted, set OccActive as false.
+                        assert: "false"
+                        deassert: "true"
+
+0x61:
+    sensorType: 0x04
+    sensorReadingType: 0x6F
+    # Inventory paths intentionally leave out the inventory root,
+    # /xyz/openbmc_project/inventory, because phosphor-inventory-manager
+    # adds that.
+    path: /system/chassis/motherboard/dimm1
+    serviceInterface: xyz.openbmc_project.Inventory.Manager
+    readingType: assertion
+    mutability: Mutability::Write|Mutability::Read
+    sensorNamePattern: nameLeaf
+    interfaces:
+        xyz.openbmc_project.State.Decorator.OperationalStatus:
+            Functional:
+                #Offsets contain the offsets in the sensor data.
+                Offsets:
+                    0x06:
+                        assert: true
+                        deassert: false
+                        type: bool
+                #Prereqs are pre-requisites for this property value to be true.
+                Prereqs:
+                    0x04:
+                        assert: false
+                        deassert: true
+                        type: bool
+        xyz.openbmc_project.Inventory.Item:
+            Present:
+                Offsets:
+                    0x04:
+                        assert: false
+                        deassert: true
+                        type: bool
+
+0x63:
+    interfaces:
+        xyz.openbmc_project.Control.Boot.RebootAttempts:
+            AttemptsLeft:
+                Offsets:
+                    0xFF:
+                        type: uint32_t
+    path: /xyz/openbmc_project/state/host0
+    # A special case of assertion, where the entire assert bitfield
+    # serves as the value, or reading. Hence, the offset above is intentionally
+    # 0xFF, to indicate not to check any specific bits in the assertion.
+    readingType: readingAssertion
+    # Sensor name would be AttemptsLeft
+    sensorNamePattern: nameProperty
+    sensorReadingType: 0x6F
+    mutability: Mutability::Write|Mutability::Read
+    sensorType: 0xC3
+    serviceInterface: org.freedesktop.DBus.Properties
+
+0x62:
+    interfaces:
+        xyz.openbmc_project.Control.Boot.RebootAttempts:
+            AttemptsLeft:
+                Offsets:
+                    0xFF:
+                        type: uint32_t
+    path: /xyz/openbmc_project/state/host1
+    readingType: readingAssertion
+    # set an explicit name for the sensor
+    sensorName: RebootAttempts
+    sensorReadingType: 0x6F
+    mutability: Mutability::Write|Mutability::Read
+    sensorType: 0xC3
+    serviceInterface: org.freedesktop.DBus.Properties
+
+0xD0:
+    sensorType: 0x01
+    path: /xyz/openbmc_project/sensors/temperature/fleeting0
+    sensorReadingType: 0x01
+    multiplierM: 511
+    offsetB: 0
+    bExp: 0
+    # Result exponent field in Type 1 SDR(2's complement, signed)
+    rExp: 0
+    # Applies for analog sensors, the actual reading value for the sensor is
+    # Value * 10^N
+    scale: -3
+    # Indicate Analog Data Format, Rate unit, Modifier unit and Percentage
+    sensorUnits1: 0x80
+    mutability: Mutability::Write|Mutability::Read
+    serviceInterface: org.freedesktop.DBus.Properties
+    readingType: readingData
+    sensorNamePattern: nameLeaf
+    interfaces:
+        xyz.openbmc_project.Sensor.Value:
+            Value:
+                Offsets:
+                    0xFF:
+                        type: int64_t
+
+0x54:
+    sensorType: 0x07
+    path: /system/chassis/motherboard/cpu0/core22
+    sensorReadingType: 0x6F
+    serviceInterface: xyz.openbmc_project.Inventory.Manager
+    readingType: assertion
+    mutability: Mutability::Write|Mutability::Read
+    # Sensor name would be cpu0_core22
+    sensorNamePattern: nameParentLeaf
+    interfaces:
+        xyz.openbmc_project.State.Decorator.OperationalStatus:
+            Functional:
+                Offsets:
+                    0x08:
+                        assert: false
+                        deassert: true
+                        type: bool
+                Prereqs:
+                    0x07:
+                        assert: true
+                        deassert: false
+        xyz.openbmc_project.Inventory.Item:
+            Present:
+                Offsets:
+                    0x07:
+                        assert: true
+                        deassert: false
+                        #The update will be skipped based on the value of skipOn
+                        #in this case if offset 0x07 is deasserted
+                        #the update will be skipped.
+                        skipOn: deassert
+                        type: bool
+
+0xC5:
+    sensorType: 0x17
+    path: /system/chassis/motherboard/gv100card0
+    sensorReadingType: 1
+    serviceInterface: xyz.openbmc_project.Inventory.Manager
+    readingType: assertion
+    mutability: Mutability::Write|Mutability::Read
+    sensorNamePattern: nameLeaf
+    interfaces:
+        xyz.openbmc_project.Inventory.Decorator.Replaceable:
+            FieldReplaceable:
+                Offsets:
+                    7:
+                        assert: true
+                        type: bool
+        xyz.openbmc_project.Inventory.Item:
+            Present:
+                Offsets:
+                    7:
+                        assert: true
+                        deassert: false
+                        type: bool
+        # Example of an interface with no attached properties
+        xyz.openbmc_project.Inventory.Item.Accelerator:
+        xyz.openbmc_project.State.Decorator.OperationalStatus:
+            Functional:
+                Offsets:
+                    8:
+                        assert: false
+                        type: bool
+                Prereqs:
+                    7:
+                        assert: true
+                        type: bool
diff --git a/scripts/sensor_gen.py b/scripts/sensor_gen.py
new file mode 100755
index 0000000..5da5909
--- /dev/null
+++ b/scripts/sensor_gen.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+
+import yaml
+from mako.template import Template
+
+
+def generate_cpp(sensor_yaml, output_dir):
+    with open(sensor_yaml, "r") as f:
+        ifile = yaml.safe_load(f)
+        if not isinstance(ifile, dict):
+            ifile = {}
+
+        # Render the mako template
+
+        t = Template(filename=os.path.join(script_dir, "writesensor.cpp.mako"))
+
+        output_cpp = os.path.join(output_dir, "sensor-gen.cpp")
+        with open(output_cpp, "w") as fd:
+            fd.write(t.render(sensorDict=ifile))
+
+
+def main():
+    valid_commands = {"generate-cpp": generate_cpp}
+    parser = argparse.ArgumentParser(
+        description="IPMI Sensor parser and code generator"
+    )
+
+    parser.add_argument(
+        "-i",
+        "--sensor_yaml",
+        dest="sensor_yaml",
+        default="example.yaml",
+        help="input sensor yaml file to parse",
+    )
+
+    parser.add_argument(
+        "-o",
+        "--output-dir",
+        dest="outputdir",
+        default=".",
+        help="output directory",
+    )
+
+    parser.add_argument(
+        "command",
+        metavar="COMMAND",
+        type=str,
+        choices=valid_commands.keys(),
+        help="Command to run.",
+    )
+
+    args = parser.parse_args()
+
+    if not (os.path.isfile(args.sensor_yaml)):
+        sys.exit("Can not find input yaml file " + args.sensor_yaml)
+
+    function = valid_commands[args.command]
+    function(args.sensor_yaml, args.outputdir)
+
+
+if __name__ == "__main__":
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    main()
diff --git a/scripts/writesensor.cpp.mako b/scripts/writesensor.cpp.mako
new file mode 100644
index 0000000..7123c37
--- /dev/null
+++ b/scripts/writesensor.cpp.mako
@@ -0,0 +1,182 @@
+## This file is a template.  The comment below is emitted
+## into the rendered file; feel free to edit this file.
+// !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!!
+<%
+interfaceDict = {}
+sensorNameMaxLength = 16
+%>\
+%for key in sensorDict.keys():
+<%
+    sensor = sensorDict[key]
+    serviceInterface = sensor["serviceInterface"]
+    if serviceInterface == "org.freedesktop.DBus.Properties":
+        updateFunc = "set::"
+        getFunc = "get::"
+    elif serviceInterface == "xyz.openbmc_project.Inventory.Manager":
+        updateFunc = "notify::"
+        getFunc = "inventory::get::"
+    else:
+        assert "Un-supported interface: " + serviceInterface
+    endif
+    if serviceInterface not in interfaceDict:
+        interfaceDict[serviceInterface] = {}
+        interfaceDict[serviceInterface]["updateFunc"] = updateFunc
+        interfaceDict[serviceInterface]["getFunc"] = getFunc
+%>\
+% endfor
+
+#include "sensordatahandler.hpp"
+
+#include <ipmid/types.hpp>
+
+namespace ipmi {
+namespace sensor {
+
+extern const IdInfoMap __attribute__((init_priority(101))) sensors = {
+% for key in sensorDict.keys():
+   % if key:
+{${key},{
+<%
+       sensor = sensorDict[key]
+       interfaces = sensor["interfaces"]
+       path = sensor["path"]
+       serviceInterface = sensor["serviceInterface"]
+       sensorType = sensor["sensorType"]
+       entityID = sensor.get("entityID", 0)
+       instance = sensor.get("entityInstance", 0)
+       readingType = sensor["sensorReadingType"]
+       multiplier = sensor.get("multiplierM", 1)
+       offsetB = sensor.get("offsetB", 0)
+       bExp = sensor.get("bExp", 0)
+       rExp = sensor.get("rExp", 0)
+       sensorUnits1 = sensor.get("sensorUnits1", 0)
+       unit = sensor.get("unit", "")
+       scale = sensor.get("scale", 0)
+       hasScale = "true" if "scale" in sensor.keys() else "false"
+       valueReadingType = sensor["readingType"]
+       updateFunc = interfaceDict[serviceInterface]["updateFunc"]
+       updateFunc += sensor["readingType"]
+       getFunc = interfaceDict[serviceInterface]["getFunc"]
+       getFunc += sensor["readingType"]
+       sensorName = sensor.get("sensorName", None)
+       if sensorName:
+           assert len(sensorName) <= sensorNameMaxLength, \
+                   "sensor name '%s' is too long (%d bytes max)" % \
+                   (sensorName, sensorNameMaxLength)
+       else:
+           sensorNameFunc = "get::" + sensor.get("sensorNamePattern",
+                   "nameLeaf")
+
+       if "readingAssertion" == valueReadingType or "readingData" == valueReadingType:
+           for interface,properties in interfaces.items():
+               for dbus_property,property_value in properties.items():
+                   for offset,values in property_value["Offsets"].items():
+                       valueType = values["type"]
+           updateFunc = "set::" + valueReadingType + "<" + valueType + ">"
+           getFunc = "get::" + valueReadingType + "<" + valueType + ">"
+       sensorInterface = serviceInterface
+       if serviceInterface == "org.freedesktop.DBus.Properties":
+           sensorInterface = next(iter(interfaces))
+       mutability = sensor.get("mutability", "Mutability::Read")
+%>
+        .entityType = ${entityID},
+        .instance = ${instance},
+        .sensorType = ${sensorType},
+        .sensorPath = "${path}",
+        .sensorInterface = "${sensorInterface}",
+        .sensorReadingType = ${readingType},
+        .coefficientM = ${multiplier},
+        .coefficientB = ${offsetB},
+        .exponentB = ${bExp},
+        .scaledOffset = ${offsetB * pow(10,bExp)},
+        .exponentR = ${rExp},
+        .hasScale = ${hasScale},
+        .scale = ${scale},
+        .sensorUnits1 = ${sensorUnits1},
+        .unit = "${unit}",
+        .updateFunc = ${updateFunc},
+        .getFunc = ${getFunc},
+        .mutability = Mutability(${mutability}),
+    % if sensorName:
+        .sensorName = "${sensorName}",
+        .sensorNameFunc = nullptr,
+    % else:
+        .sensorName = "",
+        .sensorNameFunc = ${sensorNameFunc},
+    % endif
+        .propertyInterfaces = {
+    % for interface,properties in interfaces.items():
+            {"${interface}",{
+            % if properties:
+                % for dbus_property,property_value in properties.items():
+                    {"${dbus_property}",{
+<%
+try:
+    preReq = property_value["Prereqs"]
+except KeyError:
+    preReq = dict()
+%>\
+                    {
+                        % for preOffset,preValues in preReq.items():
+                        { ${preOffset},{
+                            % for name,value in preValues.items():
+                                % if name == "type":
+<%                              continue %>\
+                                % endif
+<%                          value = str(value).lower() %>\
+                                ${value},
+                            % endfor
+                            }
+                        },
+                        % endfor
+                    },
+                    {
+                    % for offset,values in property_value["Offsets"].items():
+                        { ${offset},{
+                            % if offset == 0xFF:
+                                }},
+<%                          continue %>\
+                            % endif
+<%                          valueType = values["type"] %>\
+<%
+try:
+    skip = values["skipOn"]
+    if skip == "assert":
+        skipVal = "SkipAssertion::ASSERT"
+    elif skip == "deassert":
+        skipVal = "SkipAssertion::DEASSERT"
+    else:
+        assert "Unknown skip value " + str(skip)
+except KeyError:
+    skipVal = "SkipAssertion::NONE"
+%>\
+                                ${skipVal},
+                        % for name,value in values.items():
+                            % if name == "type" or name == "skipOn":
+<%                          continue %>\
+                            % endif
+                            % if valueType == "string":
+                            std::string("${value}"),
+                            % elif valueType == "bool":
+<%                         value = str(value).lower() %>\
+                            ${value},
+                            % else:
+                            ${value},
+                            % endif
+                        % endfor
+                            }
+                        },
+                    % endfor
+                    }}},
+                % endfor
+            % endif
+            }},
+    % endfor
+     },
+}},
+   % endif
+% endfor
+};
+
+} // namespace sensor
+} // namespace ipmi
diff --git a/selutility.cpp b/selutility.cpp
new file mode 100644
index 0000000..944b21c
--- /dev/null
+++ b/selutility.cpp
@@ -0,0 +1,411 @@
+#include "config.h"
+
+#include "selutility.hpp"
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <charconv>
+#include <chrono>
+#include <filesystem>
+#include <vector>
+
+extern const ipmi::sensor::InvObjectIDMap invSensors;
+using namespace phosphor::logging;
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+namespace
+{
+
+constexpr auto systemEventRecord = 0x02;
+constexpr auto generatorID = 0x2000;
+constexpr auto eventMsgRevision = 0x04;
+constexpr auto assertEvent = 0x00;
+constexpr auto deassertEvent = 0x80;
+constexpr auto selDataSize = 3;
+constexpr auto oemCDDataSize = 9;
+constexpr auto oemEFDataSize = 13;
+
+constexpr auto propAdditionalData = "AdditionalData";
+constexpr auto propResolved = "Resolved";
+
+constexpr auto strEventDir = "EVENT_DIR";
+constexpr auto strGenerateId = "GENERATOR_ID";
+constexpr auto strRecordType = "RECORD_TYPE";
+constexpr auto strSensorData = "SENSOR_DATA";
+constexpr auto strSensorPath = "SENSOR_PATH";
+
+} // namespace
+
+namespace ipmi
+{
+
+namespace sel
+{
+
+namespace internal
+{
+
+inline bool isRecordOEM(uint8_t recordType)
+{
+    return recordType != systemEventRecord;
+}
+
+using entryDataMap = std::map<PropertyName, PropertyType>;
+
+int convert(const std::string_view& str, int base = 10)
+{
+    int ret = 0;
+    std::from_chars(str.data(), str.data() + str.size(), ret, base);
+    return ret;
+}
+
+// Convert the string to a vector of uint8_t, where the str is formatted as hex
+std::vector<uint8_t> convertVec(const std::string_view& str)
+{
+    std::vector<uint8_t> ret;
+    auto len = str.size() / 2;
+    ret.reserve(len);
+    for (size_t i = 0; i < len; ++i)
+    {
+        ret.emplace_back(
+            static_cast<uint8_t>(convert(str.substr(i * 2, 2), 16)));
+    }
+    return ret;
+}
+
+/** Construct OEM SEL record according to IPMI spec 32.2, 32.3. */
+void constructOEMSEL(uint8_t recordType, std::chrono::milliseconds timestamp,
+                     const AdditionalData& data, GetSELEntryResponse& record)
+{
+    auto dataIter = data.find(strSensorData);
+    assert(dataIter != data.end());
+    auto sensorData = convertVec(dataIter->second);
+    if (recordType >= 0xC0 && recordType < 0xE0)
+    {
+        record.event.oemCD.timeStamp = static_cast<uint32_t>(
+            std::chrono::duration_cast<std::chrono::seconds>(timestamp)
+                .count());
+        record.event.oemCD.recordType = recordType;
+        // The ManufactureID and OEM Defined are packed in the sensor data
+        // Fill the 9 bytes of Manufacture ID and oemDefined
+        memcpy(&record.event.oemCD.manufacturerID, sensorData.data(),
+               std::min(sensorData.size(), static_cast<size_t>(oemCDDataSize)));
+    }
+    else if (recordType >= 0xE0)
+    {
+        record.event.oemEF.recordType = recordType;
+        // The remaining 13 bytes are the OEM Defined data
+        memcpy(&record.event.oemEF.oemDefined, sensorData.data(),
+               std::min(sensorData.size(), static_cast<size_t>(oemEFDataSize)));
+    }
+}
+
+void constructSEL(uint8_t recordType, std::chrono::milliseconds timestamp,
+                  const AdditionalData& data, const entryDataMap&,
+                  GetSELEntryResponse& record)
+{
+    if (recordType != systemEventRecord)
+    {
+        lg2::error("Invalid recordType");
+        elog<InternalFailure>();
+    }
+
+    // Default values when there is no matched sensor
+    record.event.eventRecord.sensorType = 0;
+    record.event.eventRecord.sensorNum = 0xFF;
+    record.event.eventRecord.eventType = 0;
+
+    auto iter = data.find(strSensorPath);
+    assert(iter != data.end());
+    const auto& sensorPath = iter->second;
+    auto sensorIter = invSensors.find(sensorPath);
+
+    if (sensorIter != invSensors.end())
+    {
+        // There is a matched sensor
+        record.event.eventRecord.sensorType = sensorIter->second.sensorType;
+        record.event.eventRecord.sensorNum = sensorIter->second.sensorID;
+
+        iter = data.find(strEventDir);
+        assert(iter != data.end());
+        auto eventDir = static_cast<uint8_t>(convert(iter->second));
+        uint8_t assert = eventDir ? assertEvent : deassertEvent;
+        record.event.eventRecord.eventType =
+            assert | sensorIter->second.eventReadingType;
+    }
+    record.event.eventRecord.recordType = recordType;
+    record.event.eventRecord.timeStamp = static_cast<uint32_t>(
+        std::chrono::duration_cast<std::chrono::seconds>(timestamp).count());
+    iter = data.find(strGenerateId);
+    assert(iter != data.end());
+    record.event.eventRecord.generatorID =
+        static_cast<uint16_t>(convert(iter->second));
+    record.event.eventRecord.eventMsgRevision = eventMsgRevision;
+    iter = data.find(strSensorData);
+    assert(iter != data.end());
+    auto sensorData = convertVec(iter->second);
+    // The remaining 3 bytes are the sensor data
+    memcpy(&record.event.eventRecord.eventData1, sensorData.data(),
+           std::min(sensorData.size(), static_cast<size_t>(selDataSize)));
+}
+
+GetSELEntryResponse prepareSELEntry(
+    const std::string& objPath,
+    ipmi::sensor::InvObjectIDMap::const_iterator iter)
+{
+    GetSELEntryResponse record{};
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    auto service = ipmi::getService(bus, logEntryIntf, objPath);
+
+    // Read all the log entry properties.
+    auto methodCall = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                          propIntf, "GetAll");
+    methodCall.append(logEntryIntf);
+
+    entryDataMap entryData;
+    try
+    {
+        auto reply = bus.call(methodCall);
+        reply.read(entryData);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in reading logging property entries: {ERROR}",
+                   "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    // Read Id from the log entry.
+    static constexpr auto propId = "Id";
+    auto iterId = entryData.find(propId);
+    if (iterId == entryData.end())
+    {
+        lg2::error("Error in reading Id of logging entry");
+        elog<InternalFailure>();
+    }
+
+    // Read Timestamp from the log entry.
+    static constexpr auto propTimeStamp = "Timestamp";
+    auto iterTimeStamp = entryData.find(propTimeStamp);
+    if (iterTimeStamp == entryData.end())
+    {
+        lg2::error("Error in reading Timestamp of logging entry");
+        elog<InternalFailure>();
+    }
+    std::chrono::milliseconds chronoTimeStamp(
+        std::get<uint64_t>(iterTimeStamp->second));
+
+    bool isFromSELLogger = false;
+
+    // The recordID are with the same offset between different types,
+    // so we are safe to set the recordID here
+    record.event.eventRecord.recordID =
+        static_cast<uint16_t>(std::get<uint32_t>(iterId->second));
+
+    iterId = entryData.find(propAdditionalData);
+    if (iterId != entryData.end())
+    {
+        // Check if it's a SEL from phosphor-sel-logger which shall contain
+        // the record ID, etc
+        const auto& addData = std::get<AdditionalData>(iterId->second);
+        auto recordTypeIter = addData.find(strRecordType);
+        if (recordTypeIter != addData.end())
+        {
+            // It is a SEL from phosphor-sel-logger
+            isFromSELLogger = true;
+        }
+        else
+        {
+            // Not a SEL from phosphor-sel-logger, it shall have a valid
+            // invSensor
+            if (iter == invSensors.end())
+            {
+                lg2::error("System event sensor not found");
+                elog<InternalFailure>();
+            }
+        }
+    }
+
+    if (isFromSELLogger)
+    {
+        // It is expected to be a custom SEL entry
+        const auto& addData = std::get<AdditionalData>(iterId->second);
+        auto recordType =
+            static_cast<uint8_t>(convert(addData.find(strRecordType)->second));
+        auto isOEM = isRecordOEM(recordType);
+        if (isOEM)
+        {
+            constructOEMSEL(recordType, chronoTimeStamp, addData, record);
+        }
+        else
+        {
+            constructSEL(recordType, chronoTimeStamp, addData, entryData,
+                         record);
+        }
+    }
+    else
+    {
+        record.event.eventRecord.timeStamp = static_cast<uint32_t>(
+            std::chrono::duration_cast<std::chrono::seconds>(chronoTimeStamp)
+                .count());
+
+        record.event.eventRecord.recordType = systemEventRecord;
+        record.event.eventRecord.generatorID = generatorID;
+        record.event.eventRecord.eventMsgRevision = eventMsgRevision;
+
+        record.event.eventRecord.sensorType = iter->second.sensorType;
+        record.event.eventRecord.sensorNum = iter->second.sensorID;
+        record.event.eventRecord.eventData1 = iter->second.eventOffset;
+
+        // Read Resolved from the log entry.
+        auto iterResolved = entryData.find(propResolved);
+        if (iterResolved == entryData.end())
+        {
+            lg2::error("Error in reading Resolved field of logging entry");
+            elog<InternalFailure>();
+        }
+
+        // Evaluate if the event is assertion or deassertion event
+        if (std::get<bool>(iterResolved->second))
+        {
+            record.event.eventRecord.eventType =
+                deassertEvent | iter->second.eventReadingType;
+        }
+        else
+        {
+            record.event.eventRecord.eventType = iter->second.eventReadingType;
+        }
+    }
+
+    return record;
+}
+
+} // namespace internal
+
+GetSELEntryResponse convertLogEntrytoSEL(const std::string& objPath)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    static constexpr auto assocIntf =
+        "xyz.openbmc_project.Association.Definitions";
+    static constexpr auto assocProp = "Associations";
+
+    std::vector<ipmi::Association> assocs;
+    try
+    {
+        auto service = ipmi::getService(bus, assocIntf, objPath);
+        auto propValue =
+            ipmi::getDbusProperty(bus, service, objPath, assocIntf, assocProp);
+        assocs = std::get<std::vector<ipmi::Association>>(propValue);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in reading Associations interface: {ERROR}", "ERROR",
+                   e);
+        elog<InternalFailure>();
+    }
+
+    /*
+     * Check if the log entry has any callout associations, if there is a
+     * callout association try to match the inventory path to the corresponding
+     * IPMI sensor.
+     */
+    for (const auto& item : assocs)
+    {
+        if (std::get<0>(item).compare(CALLOUT_FWD_ASSOCIATION) == 0)
+        {
+            auto iter = invSensors.find(std::get<2>(item));
+            if (iter == invSensors.end())
+            {
+                iter = invSensors.find(BOARD_SENSOR);
+                if (iter == invSensors.end())
+                {
+                    lg2::error("Motherboard sensor not found");
+                    elog<InternalFailure>();
+                }
+            }
+
+            return internal::prepareSELEntry(objPath, iter);
+        }
+    }
+
+    // If there are no callout associations link the log entry to system event
+    // sensor
+    auto iter = invSensors.find(SYSTEM_SENSOR);
+    return internal::prepareSELEntry(objPath, iter);
+}
+
+std::chrono::seconds getEntryTimeStamp(const std::string& objPath)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    static constexpr auto propTimeStamp = "Timestamp";
+
+    uint64_t timeStamp;
+    try
+    {
+        auto service = ipmi::getService(bus, logEntryIntf, objPath);
+        auto propValue = ipmi::getDbusProperty(bus, service, objPath,
+                                               logEntryIntf, propTimeStamp);
+        timeStamp = std::get<uint64_t>(propValue);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in reading Timestamp from Entry interface: {ERROR}",
+                   "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    std::chrono::milliseconds chronoTimeStamp(timeStamp);
+
+    return std::chrono::duration_cast<std::chrono::seconds>(chronoTimeStamp);
+}
+
+void readLoggingObjectPaths(ObjectPaths& paths)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    auto depth = 0;
+    paths.clear();
+
+    auto mapperCall = bus.new_method_call(mapperBusName, mapperObjPath,
+                                          mapperIntf, "GetSubTreePaths");
+    mapperCall.append(logBasePath);
+    mapperCall.append(depth);
+    mapperCall.append(ObjectPaths({logEntryIntf}));
+
+    try
+    {
+        auto reply = bus.call(mapperCall);
+        reply.read(paths);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        if (strcmp(e.name(),
+                   "xyz.openbmc_project.Common.Error.ResourceNotFound"))
+        {
+            throw;
+        }
+    }
+
+    std::sort(paths.begin(), paths.end(),
+              [](const std::string& a, const std::string& b) {
+                  namespace fs = std::filesystem;
+                  fs::path pathA(a);
+                  fs::path pathB(b);
+                  auto idA = std::stoul(pathA.filename().string());
+                  auto idB = std::stoul(pathB.filename().string());
+
+                  return idA < idB;
+              });
+}
+
+} // namespace sel
+
+} // namespace ipmi
diff --git a/selutility.hpp b/selutility.hpp
new file mode 100644
index 0000000..c6ba6b0
--- /dev/null
+++ b/selutility.hpp
@@ -0,0 +1,210 @@
+#pragma once
+
+#include <ipmid/types.hpp>
+#include <sdbusplus/server.hpp>
+
+#include <chrono>
+#include <cstdint>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+namespace ipmi
+{
+
+namespace sel
+{
+
+static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
+static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
+static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
+
+static constexpr auto logWatchPath = "/xyz/openbmc_project/logging";
+static constexpr auto logBasePath = "/xyz/openbmc_project/logging/entry";
+static constexpr auto logEntryIntf = "xyz.openbmc_project.Logging.Entry";
+static constexpr auto logDeleteIntf = "xyz.openbmc_project.Object.Delete";
+
+static constexpr auto logObj = "/xyz/openbmc_project/logging";
+static constexpr auto logIntf = "xyz.openbmc_project.Collection.DeleteAll";
+static constexpr auto logDeleteAllMethod = "DeleteAll";
+
+static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
+
+using ObjectPaths = std::vector<std::string>;
+using PropertyName = std::string;
+using Resolved = bool;
+using Id = uint32_t;
+using Timestamp = uint64_t;
+using Message = std::string;
+using AdditionalData = std::map<std::string, std::string>;
+using PropertyType =
+    std::variant<Resolved, Id, Timestamp, Message, AdditionalData>;
+
+static constexpr auto selVersion = 0x51;
+static constexpr auto invalidTimeStamp = 0xFFFFFFFF;
+
+static constexpr auto firstEntry = 0x0000;
+static constexpr auto lastEntry = 0xFFFF;
+static constexpr auto entireRecord = 0xFF;
+static constexpr auto selRecordSize = 16;
+
+namespace operationSupport
+{
+static constexpr bool overflow = false;
+static constexpr bool deleteSel = true;
+static constexpr bool partialAddSelEntry = false;
+static constexpr bool reserveSel = true;
+static constexpr bool getSelAllocationInfo = false;
+} // namespace operationSupport
+
+/** @struct GetSELEntryRequest
+ *
+ *  IPMI payload for Get SEL Entry command request.
+ */
+struct GetSELEntryRequest
+{
+    uint16_t reservationID; //!< Reservation ID.
+    uint16_t selRecordID;   //!< SEL Record ID.
+    uint8_t offset;         //!< Offset into record.
+    uint8_t readLength;     //!< Bytes to read.
+} __attribute__((packed));
+
+constexpr size_t SELRecordLength = 16;
+
+/** @struct SELEventRecord
+ *
+ * IPMI SEL Event Record
+ */
+struct SELEventRecord
+{
+    uint16_t recordID;        //!< Record ID.
+    uint8_t recordType;       //!< Record Type.
+    uint32_t timeStamp;       //!< Timestamp.
+    uint16_t generatorID;     //!< Generator ID.
+    uint8_t eventMsgRevision; //!< Event Message Revision.
+    uint8_t sensorType;       //!< Sensor Type.
+    uint8_t sensorNum;        //!< Sensor Number.
+    uint8_t eventType;        //!< Event Dir | Event Type.
+    uint8_t eventData1;       //!< Event Data 1.
+    uint8_t eventData2;       //!< Event Data 2.
+    uint8_t eventData3;       //!< Event Data 3.
+} __attribute__((packed));
+
+static_assert(sizeof(SELEventRecord) == SELRecordLength);
+
+/** @struct SELOEMRecordTypeCD
+ *
+ * IPMI SEL OEM Record - Type C0h-DFh
+ */
+struct SELOEMRecordTypeCD
+{
+    uint16_t recordID;         //!< Record ID.
+    uint8_t recordType;        //!< Record Type.
+    uint32_t timeStamp;        //!< Timestamp.
+    uint8_t manufacturerID[3]; //!< Manufacturer ID.
+    uint8_t oemDefined[6];     //!< OEM Defined data.
+} __attribute__((packed));
+
+static_assert(sizeof(SELOEMRecordTypeCD) == SELRecordLength);
+
+/** @struct SELOEMRecordTypeEF
+ *
+ * IPMI SEL OEM Record - Type E0h-FFh
+ */
+struct SELOEMRecordTypeEF
+{
+    uint16_t recordID;      //!< Record ID.
+    uint8_t recordType;     //!< Record Type.
+    uint8_t oemDefined[13]; //!< OEM Defined data.
+} __attribute__((packed));
+
+static_assert(sizeof(SELOEMRecordTypeEF) == SELRecordLength);
+
+union SELEventRecordFormat
+{
+    SELEventRecord eventRecord;
+    SELOEMRecordTypeCD oemCD;
+    SELOEMRecordTypeEF oemEF;
+};
+
+/** @struct GetSELEntryResponse
+ *
+ *  IPMI payload for Get SEL Entry command response.
+ */
+struct GetSELEntryResponse
+{
+    uint16_t nextRecordID;      //!< Next RecordID.
+    SELEventRecordFormat event; // !< The Event Record.
+} __attribute__((packed));
+
+static_assert(sizeof(GetSELEntryResponse) ==
+              SELRecordLength + sizeof(uint16_t));
+
+static constexpr auto initiateErase = 0xAA;
+static constexpr auto getEraseStatus = 0x00;
+static constexpr auto eraseComplete = 0x01;
+
+/** @brief Convert logging entry to SEL
+ *
+ *  @param[in] objPath - DBUS object path of the logging entry.
+ *
+ *  @return On success return the response of Get SEL entry command.
+ */
+GetSELEntryResponse convertLogEntrytoSEL(const std::string& objPath);
+
+/** @brief Get the timestamp of the log entry
+ *
+ *  @param[in] objPath - DBUS object path of the logging entry.
+ *
+ *  @return On success return the timestamp of the log entry as number of
+ *          seconds from epoch.
+ */
+std::chrono::seconds getEntryTimeStamp(const std::string& objPath);
+
+/** @brief Read the logging entry object paths
+ *
+ *  This API would read the logging dbus logging entry object paths and sorting
+ *  the filename in the numeric order. The paths is cleared before populating
+ *  the object paths.
+ *
+ *  @param[in,out] paths - sorted list of logging entry object paths.
+ *
+ *  @note This function is invoked when the Get SEL Info command or the Delete
+ *        SEL entry command is invoked. The Get SEL Entry command is preceded
+ *        typically by Get SEL Info command, so readLoggingObjectPaths is not
+ *        invoked before each Get SEL entry command.
+ */
+void readLoggingObjectPaths(ObjectPaths& paths);
+
+template <typename T>
+std::string toHexStr(const T& data)
+{
+    std::stringstream stream;
+    stream << std::hex << std::uppercase << std::setfill('0');
+    for (const auto& v : data)
+    {
+        stream << std::setw(2) << static_cast<int>(v);
+    }
+    return stream.str();
+}
+namespace internal
+{
+
+/** @brief Convert logging entry to SEL event record
+ *
+ *  @param[in] objPath - DBUS object path of the logging entry.
+ *  @param[in] iter - Iterator to the sensor data corresponding to the logging
+ *                    entry
+ *
+ *  @return On success return the SEL event record, throw an exception in case
+ *          of failure.
+ */
+GetSELEntryResponse prepareSELEntry(
+    const std::string& objPath,
+    ipmi::sensor::InvObjectIDMap::const_iterator iter);
+
+} // namespace internal
+
+} // namespace sel
+
+} // namespace ipmi
diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp
new file mode 100644
index 0000000..3505dfb
--- /dev/null
+++ b/sensordatahandler.cpp
@@ -0,0 +1,419 @@
+#include "sensordatahandler.hpp"
+
+#include "sensorhandler.hpp"
+
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <bitset>
+#include <filesystem>
+#include <optional>
+
+namespace ipmi
+{
+namespace sensor
+{
+
+using namespace phosphor::logging;
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData)
+{
+    Assertion assertionStates =
+        (static_cast<Assertion>(cmdData.assertOffset8_14)) << 8 |
+        cmdData.assertOffset0_7;
+    Deassertion deassertionStates =
+        (static_cast<Deassertion>(cmdData.deassertOffset8_14)) << 8 |
+        cmdData.deassertOffset0_7;
+    return std::make_pair(assertionStates, deassertionStates);
+}
+
+ipmi_ret_t updateToDbus(IpmiUpdateData& msg)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    try
+    {
+        auto serviceResponseMsg = bus.call(msg);
+    }
+    catch (const InternalFailure& e)
+    {
+        lg2::error("Error in D-Bus call: {ERROR}", "ERROR", e);
+        commit<InternalFailure>();
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+namespace get
+{
+
+SensorName nameParentLeaf(const Info& sensorInfo)
+{
+    const auto pos = sensorInfo.sensorPath.find_last_of('/');
+    const auto leaf = sensorInfo.sensorPath.substr(pos + 1);
+
+    const auto remaining = sensorInfo.sensorPath.substr(0, pos);
+
+    const auto parentPos = remaining.find_last_of('/');
+    auto parent = remaining.substr(parentPos + 1);
+
+    parent += "_" + leaf;
+    return parent;
+}
+
+GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
+                                     const InstancePath& path,
+                                     const DbusInterface& interface)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    GetSensorResponse response{};
+
+    enableScanning(&response);
+
+    auto service = ipmi::getService(bus, interface, path);
+
+    const auto& interfaceList = sensorInfo.propertyInterfaces;
+
+    for (const auto& interface : interfaceList)
+    {
+        for (const auto& property : interface.second)
+        {
+            auto propValue = ipmi::getDbusProperty(
+                bus, service, path, interface.first, property.first);
+
+            for (const auto& value : std::get<OffsetValueMap>(property.second))
+            {
+                if (propValue == value.second.assert)
+                {
+                    setOffset(value.first, &response);
+                    break;
+                }
+            }
+        }
+    }
+
+    return response;
+}
+
+GetSensorResponse mapDbusToEventdata2(const Info& sensorInfo)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    GetSensorResponse response{};
+
+    enableScanning(&response);
+
+    auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
+                                    sensorInfo.sensorPath);
+
+    const auto& interfaceList = sensorInfo.propertyInterfaces;
+
+    for (const auto& interface : interfaceList)
+    {
+        for (const auto& property : interface.second)
+        {
+            auto propValue =
+                ipmi::getDbusProperty(bus, service, sensorInfo.sensorPath,
+                                      interface.first, property.first);
+
+            for (const auto& value : std::get<OffsetValueMap>(property.second))
+            {
+                if (propValue == value.second.assert)
+                {
+                    setReading(value.first, &response);
+                    break;
+                }
+            }
+        }
+    }
+
+    return response;
+}
+
+#ifndef FEATURE_SENSORS_CACHE
+GetSensorResponse assertion(const Info& sensorInfo)
+{
+    return mapDbusToAssertion(sensorInfo, sensorInfo.sensorPath,
+                              sensorInfo.sensorInterface);
+}
+
+GetSensorResponse eventdata2(const Info& sensorInfo)
+{
+    return mapDbusToEventdata2(sensorInfo);
+}
+#else
+std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
+                                           const PropertyMap& /*properties*/)
+{
+    // The assertion may contain multiple properties
+    // So we have to get the properties from DBus anyway
+    auto response = mapDbusToAssertion(sensorInfo, sensorInfo.sensorPath,
+                                       sensorInfo.sensorInterface);
+
+    if (!sensorCacheMap[id].has_value())
+    {
+        sensorCacheMap[id] = SensorData{};
+    }
+    sensorCacheMap[id]->response = response;
+    return response;
+}
+
+std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
+                                            const PropertyMap& /*properties*/)
+{
+    // The eventdata2 may contain multiple properties
+    // So we have to get the properties from DBus anyway
+    auto response = mapDbusToEventdata2(sensorInfo);
+
+    if (!sensorCacheMap[id].has_value())
+    {
+        sensorCacheMap[id] = SensorData{};
+    }
+    sensorCacheMap[id]->response = response;
+    return response;
+}
+
+#endif // FEATURE_SENSORS_CACHE
+
+} // namespace get
+
+namespace set
+{
+
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+                           const std::string& sensorPath,
+                           const std::string& command,
+                           const std::string& sensorInterface)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    using namespace std::string_literals;
+
+    auto dbusService = getService(bus, sensorInterface, sensorPath);
+
+    return bus.new_method_call(dbusService.c_str(), sensorPath.c_str(),
+                               updateInterface.c_str(), command.c_str());
+}
+
+ipmi_ret_t eventdata(const SetSensorReadingReq&, const Info& sensorInfo,
+                     uint8_t data)
+{
+    auto msg =
+        makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
+                    "Set", sensorInfo.sensorInterface);
+
+    const auto& interface = sensorInfo.propertyInterfaces.begin();
+    msg.append(interface->first);
+    for (const auto& property : interface->second)
+    {
+        msg.append(property.first);
+        const auto& iter = std::get<OffsetValueMap>(property.second).find(data);
+        if (iter == std::get<OffsetValueMap>(property.second).end())
+        {
+            lg2::error("Invalid event data");
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+        }
+        msg.append(iter->second.assert);
+    }
+    return updateToDbus(msg);
+}
+
+ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo)
+{
+    std::bitset<16> assertionSet(getAssertionSet(cmdData).first);
+    std::bitset<16> deassertionSet(getAssertionSet(cmdData).second);
+    auto bothSet = assertionSet ^ deassertionSet;
+
+    const auto& interface = sensorInfo.propertyInterfaces.begin();
+
+    for (const auto& property : interface->second)
+    {
+        std::optional<Value> tmp;
+        for (const auto& value : std::get<OffsetValueMap>(property.second))
+        {
+            if (bothSet.size() <= value.first || !bothSet.test(value.first))
+            {
+                // A BIOS shouldn't do this but ignore if they do.
+                continue;
+            }
+
+            if (assertionSet.test(value.first))
+            {
+                tmp = value.second.assert;
+                break;
+            }
+            if (deassertionSet.test(value.first))
+            {
+                tmp = value.second.deassert;
+                break;
+            }
+        }
+
+        if (tmp)
+        {
+            auto msg = makeDbusMsg("org.freedesktop.DBus.Properties",
+                                   sensorInfo.sensorPath, "Set",
+                                   sensorInfo.sensorInterface);
+            msg.append(interface->first);
+            msg.append(property.first);
+            msg.append(*tmp);
+
+            auto rc = updateToDbus(msg);
+            if (rc)
+            {
+                return rc;
+            }
+        }
+    }
+
+    return IPMI_CC_OK;
+}
+
+} // namespace set
+
+namespace notify
+{
+
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+                           const std::string&, const std::string& command,
+                           const std::string&)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    using namespace std::string_literals;
+
+    static const auto dbusPath = "/xyz/openbmc_project/inventory"s;
+    std::string dbusService = ipmi::getService(bus, updateInterface, dbusPath);
+
+    return bus.new_method_call(dbusService.c_str(), dbusPath.c_str(),
+                               updateInterface.c_str(), command.c_str());
+}
+
+ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo)
+{
+    auto msg = makeDbusMsg(sensorInfo.sensorInterface, sensorInfo.sensorPath,
+                           "Notify", sensorInfo.sensorInterface);
+
+    std::bitset<16> assertionSet(getAssertionSet(cmdData).first);
+    std::bitset<16> deassertionSet(getAssertionSet(cmdData).second);
+    ipmi::sensor::ObjectMap objects;
+    ipmi::sensor::InterfaceMap interfaces;
+    for (const auto& interface : sensorInfo.propertyInterfaces)
+    {
+        // An interface with no properties - It is possible that the sensor
+        // object on DBUS implements a DBUS interface with no properties.
+        // Make sure we add the interface to the list if interfaces on the
+        // object with an empty property map.
+        if (interface.second.empty())
+        {
+            interfaces.emplace(interface.first, ipmi::sensor::PropertyMap{});
+            continue;
+        }
+        // For a property like functional state the result will be
+        // calculated based on the true value of all conditions.
+        for (const auto& property : interface.second)
+        {
+            ipmi::sensor::PropertyMap props;
+            bool valid = false;
+            auto result = true;
+            for (const auto& value : std::get<OffsetValueMap>(property.second))
+            {
+                if (assertionSet.test(value.first))
+                {
+                    // Skip update if skipOn is ASSERT
+                    if (SkipAssertion::ASSERT == value.second.skip)
+                    {
+                        return IPMI_CC_OK;
+                    }
+                    result = result && std::get<bool>(value.second.assert);
+                    valid = true;
+                }
+                else if (deassertionSet.test(value.first))
+                {
+                    // Skip update if skipOn is DEASSERT
+                    if (SkipAssertion::DEASSERT == value.second.skip)
+                    {
+                        return IPMI_CC_OK;
+                    }
+                    result = result && std::get<bool>(value.second.deassert);
+                    valid = true;
+                }
+            }
+            for (const auto& value :
+                 std::get<PreReqOffsetValueMap>(property.second))
+            {
+                if (assertionSet.test(value.first))
+                {
+                    result = result && std::get<bool>(value.second.assert);
+                }
+                else if (deassertionSet.test(value.first))
+                {
+                    result = result && std::get<bool>(value.second.deassert);
+                }
+            }
+            if (valid)
+            {
+                props.emplace(property.first, result);
+                interfaces.emplace(interface.first, std::move(props));
+            }
+        }
+    }
+
+    objects.emplace(sensorInfo.sensorPath, std::move(interfaces));
+    msg.append(std::move(objects));
+    return updateToDbus(msg);
+}
+
+} // namespace notify
+
+namespace inventory
+{
+
+namespace get
+{
+
+#ifndef FEATURE_SENSORS_CACHE
+
+GetSensorResponse assertion(const Info& sensorInfo)
+{
+    namespace fs = std::filesystem;
+
+    fs::path path{ipmi::sensor::inventoryRoot};
+    path += sensorInfo.sensorPath;
+
+    return ipmi::sensor::get::mapDbusToAssertion(
+        sensorInfo, path.string(),
+        sensorInfo.propertyInterfaces.begin()->first);
+}
+
+#else
+
+std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
+                                           const PropertyMap& /*properties*/)
+{
+    // The assertion may contain multiple properties
+    // So we have to get the properties from DBus anyway
+    namespace fs = std::filesystem;
+
+    fs::path path{ipmi::sensor::inventoryRoot};
+    path += sensorInfo.sensorPath;
+
+    auto response = ipmi::sensor::get::mapDbusToAssertion(
+        sensorInfo, path.string(),
+        sensorInfo.propertyInterfaces.begin()->first);
+
+    if (!sensorCacheMap[id].has_value())
+    {
+        sensorCacheMap[id] = SensorData{};
+    }
+    sensorCacheMap[id]->response = response;
+    return response;
+}
+
+#endif
+
+} // namespace get
+
+} // namespace inventory
+} // namespace sensor
+} // namespace ipmi
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
new file mode 100644
index 0000000..1cedda5
--- /dev/null
+++ b/sensordatahandler.hpp
@@ -0,0 +1,670 @@
+#pragma once
+
+#include "config.h"
+
+#include "sensorhandler.hpp"
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/message/types.hpp>
+
+#include <cmath>
+
+#ifdef FEATURE_SENSORS_CACHE
+
+extern ipmi::sensor::SensorCacheMap sensorCacheMap;
+
+// The signal's message type is 0x04 from DBus spec:
+// https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+static constexpr auto msgTypeSignal = 0x04;
+
+#endif
+
+namespace ipmi
+{
+namespace sensor
+{
+
+using Assertion = uint16_t;
+using Deassertion = uint16_t;
+using AssertionSet = std::pair<Assertion, Deassertion>;
+using Service = std::string;
+using Path = std::string;
+using Interface = std::string;
+using ServicePath = std::pair<Path, Service>;
+using Interfaces = std::vector<Interface>;
+using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
+using PropertyMap = ipmi::PropertyMap;
+
+using namespace phosphor::logging;
+
+/** @brief Make assertion set from input data
+ *  @param[in] cmdData - Input sensor data
+ *  @return pair of assertion and deassertion set
+ */
+AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
+
+/** @brief send the message to DBus
+ *  @param[in] msg - message to send
+ *  @return failure status in IPMI error code
+ */
+ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
+
+namespace get
+{
+
+/** @brief Populate sensor name from the D-Bus property associated with the
+ *         sensor. In the example entry from the yaml, the name of the D-bus
+ *         property "AttemptsLeft" is the sensor name.
+ *
+ *         0x07:
+ *            sensorType: 195
+ *            path: /xyz/openbmc_project/state/host0
+ *            sensorReadingType: 0x6F
+ *            serviceInterface: org.freedesktop.DBus.Properties
+ *            readingType: readingAssertion
+ *            sensorNamePattern: nameProperty
+ *            interfaces:
+ *              xyz.openbmc_project.Control.Boot.RebootAttempts:
+ *                AttemptsLeft:
+ *                    Offsets:
+ *                        0xFF:
+ *                          type: uint32_t
+ *
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return On success return the sensor name for the sensor.
+ */
+inline SensorName nameProperty(const Info& sensorInfo)
+{
+    return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
+}
+
+/** @brief Populate sensor name from the D-Bus object associated with the
+ *         sensor. If the object path is /system/chassis/motherboard/dimm0 then
+ *         the leaf dimm0 is considered as the sensor name.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return On success return the sensor name for the sensor.
+ */
+inline SensorName nameLeaf(const Info& sensorInfo)
+{
+    return sensorInfo.sensorPath.substr(
+        sensorInfo.sensorPath.find_last_of('/') + 1,
+        sensorInfo.sensorPath.length());
+}
+
+/** @brief Populate sensor name from the D-Bus object associated with the
+ *         sensor and the property.
+ *         If the object path is /xyz/openbmc_project/inventory/Fan0 and
+ *         the property is Present, the leaf Fan0 and the Property is
+ *         joined to Fan0_Present as the sensor name.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return On success return the sensor name for the sensor.
+ */
+inline SensorName nameLeafProperty(const Info& sensorInfo)
+{
+    return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
+}
+
+/** @brief Populate sensor name from the D-Bus object associated with the
+ *         sensor. If the object path is /system/chassis/motherboard/cpu0/core0
+ *         then the sensor name is cpu0_core0. The leaf and the parent is put
+ *         together to get the sensor name.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return On success return the sensor name for the sensor.
+ */
+SensorName nameParentLeaf(const Info& sensorInfo);
+
+/**
+ *  @brief Helper function to map the dbus info to sensor's assertion status
+ *         for the get sensor reading command.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] path - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
+                                     const InstancePath& path,
+                                     const DbusInterface& interface);
+
+#ifndef FEATURE_SENSORS_CACHE
+/**
+ *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
+ *         reading command response.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse assertion(const Info& sensorInfo);
+
+/**
+ *  @brief Maps the Dbus info to the reading field in the Get sensor reading
+ *         command response.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse eventdata2(const Info& sensorInfo);
+
+/**
+ *  @brief readingAssertion is a case where the entire assertion state field
+ *         serves as the sensor value.
+ *
+ *  @tparam T - type of the dbus property related to sensor.
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+template <typename T>
+GetSensorResponse readingAssertion(const Info& sensorInfo)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    GetSensorResponse response{};
+
+    enableScanning(&response);
+
+    auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
+                                    sensorInfo.sensorPath);
+
+    auto propValue = ipmi::getDbusProperty(
+        bus, service, sensorInfo.sensorPath,
+        sensorInfo.propertyInterfaces.begin()->first,
+        sensorInfo.propertyInterfaces.begin()->second.begin()->first);
+
+    setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)), &response);
+
+    return response;
+}
+
+/** @brief Map the Dbus info to the reading field in the Get sensor reading
+ *         command response
+ *
+ *  @tparam T - type of the dbus property related to sensor.
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+template <typename T>
+GetSensorResponse readingData(const Info& sensorInfo)
+{
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+
+    GetSensorResponse response{};
+
+    enableScanning(&response);
+
+    auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
+                                    sensorInfo.sensorPath);
+
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+    // Check the OperationalStatus interface for functional property
+    if (sensorInfo.propertyInterfaces.begin()->first ==
+        "xyz.openbmc_project.Sensor.Value")
+    {
+        bool functional = true;
+        try
+        {
+            auto funcValue = ipmi::getDbusProperty(
+                bus, service, sensorInfo.sensorPath,
+                "xyz.openbmc_project.State.Decorator.OperationalStatus",
+                "Functional");
+            functional = std::get<bool>(funcValue);
+        }
+        catch (...)
+        {
+            // No-op if Functional property could not be found since this
+            // check is only valid for Sensor.Value read for hwmonio
+        }
+        if (!functional)
+        {
+            throw SensorFunctionalError();
+        }
+    }
+#endif
+
+    auto propValue = ipmi::getDbusProperty(
+        bus, service, sensorInfo.sensorPath,
+        sensorInfo.propertyInterfaces.begin()->first,
+        sensorInfo.propertyInterfaces.begin()->second.begin()->first);
+
+    double value = std::get<T>(propValue) *
+                   std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
+    int32_t rawData =
+        (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
+
+    constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
+    constexpr uint8_t signedDataFormat = 0x80;
+    // if sensorUnits1 [7:6] = 10b, sensor is signed
+    int32_t minClamp;
+    int32_t maxClamp;
+    if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
+    {
+        minClamp = std::numeric_limits<int8_t>::lowest();
+        maxClamp = std::numeric_limits<int8_t>::max();
+    }
+    else
+    {
+        minClamp = std::numeric_limits<uint8_t>::lowest();
+        maxClamp = std::numeric_limits<uint8_t>::max();
+    }
+    setReading(static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp)),
+               &response);
+
+    if (!std::isfinite(value))
+    {
+        response.readingOrStateUnavailable = 1;
+    }
+
+    bool critAlarmHigh;
+    try
+    {
+        critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
+            bus, service, sensorInfo.sensorPath,
+            "xyz.openbmc_project.Sensor.Threshold.Critical",
+            "CriticalAlarmHigh"));
+    }
+    catch (const std::exception& e)
+    {
+        critAlarmHigh = false;
+    }
+    bool critAlarmLow;
+    try
+    {
+        critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
+            bus, service, sensorInfo.sensorPath,
+            "xyz.openbmc_project.Sensor.Threshold.Critical",
+            "CriticalAlarmLow"));
+    }
+    catch (const std::exception& e)
+    {
+        critAlarmLow = false;
+    }
+    bool warningAlarmHigh;
+    try
+    {
+        warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
+            bus, service, sensorInfo.sensorPath,
+            "xyz.openbmc_project.Sensor.Threshold.Warning",
+            "WarningAlarmHigh"));
+    }
+    catch (const std::exception& e)
+    {
+        warningAlarmHigh = false;
+    }
+    bool warningAlarmLow;
+    try
+    {
+        warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
+            bus, service, sensorInfo.sensorPath,
+            "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmLow"));
+    }
+    catch (const std::exception& e)
+    {
+        warningAlarmLow = false;
+    }
+    response.thresholdLevelsStates =
+        (static_cast<uint8_t>(critAlarmHigh) << 3) |
+        (static_cast<uint8_t>(critAlarmLow) << 2) |
+        (static_cast<uint8_t>(warningAlarmHigh) << 1) |
+        (static_cast<uint8_t>(warningAlarmLow));
+
+    return response;
+}
+
+#else
+
+/**
+ *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
+ *         reading command response.
+ *
+ *  @param[in] id - The sensor id
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] msg - Dbus message from match callback.
+ *
+ *  @return Response for get sensor reading command.
+ */
+std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
+                                           const PropertyMap& properties);
+
+/**
+ *  @brief Maps the Dbus info to the reading field in the Get sensor reading
+ *         command response.
+ *
+ *  @param[in] id - The sensor id
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] msg - Dbus message from match callback.
+ *
+ *  @return Response for get sensor reading command.
+ */
+std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
+                                            const PropertyMap& properties);
+
+/**
+ *  @brief readingAssertion is a case where the entire assertion state field
+ *         serves as the sensor value.
+ *
+ *  @tparam T - type of the dbus property related to sensor.
+ *  @param[in] id - The sensor id
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] msg - Dbus message from match callback.
+ *
+ *  @return Response for get sensor reading command.
+ */
+template <typename T>
+std::optional<GetSensorResponse> readingAssertion(
+    uint8_t id, const Info& sensorInfo, const PropertyMap& properties)
+{
+    GetSensorResponse response{};
+    enableScanning(&response);
+
+    auto iter = properties.find(
+        sensorInfo.propertyInterfaces.begin()->second.begin()->first);
+    if (iter == properties.end())
+    {
+        return {};
+    }
+
+    setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
+                      &response);
+
+    if (!sensorCacheMap[id].has_value())
+    {
+        sensorCacheMap[id] = SensorData{};
+    }
+    sensorCacheMap[id]->response = response;
+    return response;
+}
+
+/** @brief Get sensor reading from the dbus message from match
+ *
+ *  @tparam T - type of the dbus property related to sensor.
+ *  @param[in] id - The sensor id
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] msg - Dbus message from match callback.
+ *
+ *  @return Response for get sensor reading command.
+ */
+template <typename T>
+std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
+                                             const PropertyMap& properties)
+{
+    auto iter = properties.find("Functional");
+    if (iter != properties.end())
+    {
+        sensorCacheMap[id]->functional = std::get<bool>(iter->second);
+    }
+    iter = properties.find("Available");
+    if (iter != properties.end())
+    {
+        sensorCacheMap[id]->available = std::get<bool>(iter->second);
+    }
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+    if (sensorCacheMap[id])
+    {
+        if (!sensorCacheMap[id]->functional)
+        {
+            throw SensorFunctionalError();
+        }
+    }
+#endif
+
+    GetSensorResponse response{};
+
+    enableScanning(&response);
+
+    iter = properties.find(
+        sensorInfo.propertyInterfaces.begin()->second.begin()->first);
+    if (iter == properties.end())
+    {
+        return {};
+    }
+
+    double value = std::get<T>(iter->second) *
+                   std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
+    int32_t rawData =
+        (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
+
+    constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
+    constexpr uint8_t signedDataFormat = 0x80;
+    // if sensorUnits1 [7:6] = 10b, sensor is signed
+    if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
+    {
+        if (rawData > std::numeric_limits<int8_t>::max() ||
+            rawData < std::numeric_limits<int8_t>::lowest())
+        {
+            lg2::error("Value out of range");
+            throw std::out_of_range("Value out of range");
+        }
+        setReading(static_cast<int8_t>(rawData), &response);
+    }
+    else
+    {
+        if (rawData > std::numeric_limits<uint8_t>::max() ||
+            rawData < std::numeric_limits<uint8_t>::lowest())
+        {
+            lg2::error("Value out of range");
+            throw std::out_of_range("Value out of range");
+        }
+        setReading(static_cast<uint8_t>(rawData), &response);
+    }
+
+    if (!std::isfinite(value))
+    {
+        response.readingOrStateUnavailable = 1;
+    }
+
+    if (!sensorCacheMap[id].has_value())
+    {
+        sensorCacheMap[id] = SensorData{};
+    }
+    sensorCacheMap[id]->response = response;
+
+    return response;
+}
+
+#endif // FEATURE_SENSORS_CACHE
+
+} // namespace get
+
+namespace set
+{
+
+/** @brief Make a DBus message for a Dbus call
+ *  @param[in] updateInterface - Interface name
+ *  @param[in] sensorPath - Path of the sensor
+ *  @param[in] command - command to be executed
+ *  @param[in] sensorInterface - DBus interface of sensor
+ *  @return a dbus message
+ */
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+                           const std::string& sensorPath,
+                           const std::string& command,
+                           const std::string& sensorInterface);
+
+/** @brief Update d-bus based on assertion type sensor data
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
+                     const Info& sensorInfo);
+
+/** @brief Update d-bus based on a reading assertion
+ *  @tparam T - type of d-bus property mapping this sensor
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+template <typename T>
+ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
+                            const Info& sensorInfo)
+{
+    auto msg =
+        makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
+                    "Set", sensorInfo.sensorInterface);
+
+    const auto& interface = sensorInfo.propertyInterfaces.begin();
+    msg.append(interface->first);
+    for (const auto& property : interface->second)
+    {
+        msg.append(property.first);
+        std::variant<T> value = static_cast<T>(
+            (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7);
+        msg.append(value);
+    }
+    return updateToDbus(msg);
+}
+
+/** @brief Update d-bus based on a discrete reading
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return an IPMI error code
+ */
+template <typename T>
+ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
+                       const Info& sensorInfo)
+{
+    T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
+                  sensorInfo.scaledOffset;
+
+    raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
+
+    auto msg =
+        makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
+                    "Set", sensorInfo.sensorInterface);
+
+    const auto& interface = sensorInfo.propertyInterfaces.begin();
+    msg.append(interface->first);
+
+    for (const auto& property : interface->second)
+    {
+        msg.append(property.first);
+        std::variant<T> value = raw_value;
+        msg.append(value);
+    }
+    return updateToDbus(msg);
+}
+
+/** @brief Update d-bus based on eventdata type sensor data
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
+                     uint8_t data);
+
+/** @brief Update d-bus based on eventdata1 type sensor data
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
+                             const Info& sensorInfo)
+{
+    return eventdata(cmdData, sensorInfo, cmdData.eventData1);
+}
+
+/** @brief Update d-bus based on eventdata2 type sensor data
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
+                             const Info& sensorInfo)
+{
+    return eventdata(cmdData, sensorInfo, cmdData.eventData2);
+}
+
+/** @brief Update d-bus based on eventdata3 type sensor data
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
+                             const Info& sensorInfo)
+{
+    return eventdata(cmdData, sensorInfo, cmdData.eventData3);
+}
+
+} // namespace set
+
+namespace notify
+{
+
+/** @brief Make a DBus message for a Dbus call
+ *  @param[in] updateInterface - Interface name
+ *  @param[in] sensorPath - Path of the sensor
+ *  @param[in] command - command to be executed
+ *  @param[in] sensorInterface - DBus interface of sensor
+ *  @return a dbus message
+ */
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+                           const std::string& sensorPath,
+                           const std::string& command,
+                           const std::string& sensorInterface);
+
+/** @brief Update d-bus based on assertion type sensor data
+ *  @param[in] interfaceMap - sensor interface
+ *  @param[in] cmdData - input sensor data
+ *  @param[in] sensorInfo - sensor d-bus info
+ *  @return a IPMI error code
+ */
+ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
+                     const Info& sensorInfo);
+
+} // namespace notify
+
+namespace inventory
+{
+
+namespace get
+{
+
+#ifndef FEATURE_SENSORS_CACHE
+
+/**
+ *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
+ *         reading command response.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse assertion(const Info& sensorInfo);
+
+#else
+
+/**
+ *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
+ *         reading command response.
+ *
+ *  @param[in] id - The sensor id
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] msg - Dbus message from match callback.
+ *
+ *  @return Response for get sensor reading command.
+ */
+std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
+                                           const PropertyMap& properties);
+
+#endif
+
+} // namespace get
+
+} // namespace inventory
+} // namespace sensor
+} // namespace ipmi
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
new file mode 100644
index 0000000..134eaa6
--- /dev/null
+++ b/sensorhandler.cpp
@@ -0,0 +1,1588 @@
+#include "config.h"
+
+#include "sensorhandler.hpp"
+
+#include "fruread.hpp"
+
+#include <systemd/sd-bus.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/entity_map_json.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.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/Sensor/Value/server.hpp>
+
+#include <bitset>
+#include <cmath>
+#include <cstring>
+#include <set>
+
+static constexpr uint8_t fruInventoryDevice = 0x10;
+static constexpr uint8_t IPMIFruInventory = 0x02;
+static constexpr uint8_t BMCTargetAddress = 0x20;
+
+extern int updateSensorRecordFromSSRAESC(const void*);
+extern sd_bus* bus;
+
+namespace ipmi
+{
+namespace sensor
+{
+extern const IdInfoMap sensors;
+} // namespace sensor
+} // namespace ipmi
+
+extern const FruMap frus;
+
+using namespace phosphor::logging;
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+void registerNetFnSenFunctions() __attribute__((constructor));
+
+struct sensorTypemap_t
+{
+    uint8_t number;
+    uint8_t typecode;
+    char dbusname[32];
+};
+
+sensorTypemap_t g_SensorTypeMap[] = {
+
+    {0x01, 0x6F, "Temp"},
+    {0x0C, 0x6F, "DIMM"},
+    {0x0C, 0x6F, "MEMORY_BUFFER"},
+    {0x07, 0x6F, "PROC"},
+    {0x07, 0x6F, "CORE"},
+    {0x07, 0x6F, "CPU"},
+    {0x0F, 0x6F, "BootProgress"},
+    {0xe9, 0x09, "OccStatus"}, // E9 is an internal mapping to handle sensor
+                               // type code os 0x09
+    {0xC3, 0x6F, "BootCount"},
+    {0x1F, 0x6F, "OperatingSystemStatus"},
+    {0x12, 0x6F, "SYSTEM_EVENT"},
+    {0xC7, 0x03, "SYSTEM"},
+    {0xC7, 0x03, "MAIN_PLANAR"},
+    {0xC2, 0x6F, "PowerCap"},
+    {0x0b, 0xCA, "PowerSupplyRedundancy"},
+    {0xDA, 0x03, "TurboAllowed"},
+    {0xD8, 0xC8, "PowerSupplyDerating"},
+    {0xFF, 0x00, ""},
+};
+
+struct sensor_data_t
+{
+    uint8_t sennum;
+} __attribute__((packed));
+
+using SDRCacheMap = std::unordered_map<uint8_t, get_sdr::SensorDataFullRecord>;
+SDRCacheMap sdrCacheMap __attribute__((init_priority(101)));
+
+using SensorThresholdMap =
+    std::unordered_map<uint8_t, get_sdr::GetSensorThresholdsResponse>;
+SensorThresholdMap sensorThresholdMap __attribute__((init_priority(101)));
+
+#ifdef FEATURE_SENSORS_CACHE
+std::map<uint8_t, std::unique_ptr<sdbusplus::bus::match_t>> sensorAddedMatches
+    __attribute__((init_priority(101)));
+std::map<uint8_t, std::unique_ptr<sdbusplus::bus::match_t>> sensorUpdatedMatches
+    __attribute__((init_priority(101)));
+std::map<uint8_t, std::unique_ptr<sdbusplus::bus::match_t>> sensorRemovedMatches
+    __attribute__((init_priority(101)));
+std::unique_ptr<sdbusplus::bus::match_t> sensorsOwnerMatch
+    __attribute__((init_priority(101)));
+
+ipmi::sensor::SensorCacheMap sensorCacheMap __attribute__((init_priority(101)));
+
+// It is needed to know which objects belong to which service, so that when a
+// service exits without interfacesRemoved signal, we could invaildate the cache
+// that is related to the service. It uses below two variables:
+// - idToServiceMap records which sensors are known to have a related service;
+// - serviceToIdMap maps a service to the sensors.
+using sensorIdToServiceMap = std::unordered_map<uint8_t, std::string>;
+sensorIdToServiceMap idToServiceMap __attribute__((init_priority(101)));
+
+using sensorServiceToIdMap = std::unordered_map<std::string, std::set<uint8_t>>;
+sensorServiceToIdMap serviceToIdMap __attribute__((init_priority(101)));
+
+static void fillSensorIdServiceMap(const std::string&,
+                                   const std::string& /*intf*/, uint8_t id,
+                                   const std::string& service)
+{
+    if (idToServiceMap.find(id) != idToServiceMap.end())
+    {
+        return;
+    }
+    idToServiceMap[id] = service;
+    serviceToIdMap[service].insert(id);
+}
+
+static void fillSensorIdServiceMap(const std::string& obj,
+                                   const std::string& intf, uint8_t id)
+{
+    if (idToServiceMap.find(id) != idToServiceMap.end())
+    {
+        return;
+    }
+    try
+    {
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+        auto service = ipmi::getService(bus, intf, obj);
+        idToServiceMap[id] = service;
+        serviceToIdMap[service].insert(id);
+    }
+    catch (...)
+    {
+        // Ignore
+    }
+}
+
+void initSensorMatches()
+{
+    using namespace sdbusplus::bus::match::rules;
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    for (const auto& s : ipmi::sensor::sensors)
+    {
+        sensorAddedMatches.emplace(
+            s.first,
+            std::make_unique<sdbusplus::bus::match_t>(
+                bus, interfacesAdded() + argNpath(0, s.second.sensorPath),
+                [id = s.first, obj = s.second.sensorPath,
+                 intf = s.second.propertyInterfaces.begin()->first](
+                    auto& /*msg*/) { fillSensorIdServiceMap(obj, intf, id); }));
+        sensorRemovedMatches.emplace(
+            s.first,
+            std::make_unique<sdbusplus::bus::match_t>(
+                bus, interfacesRemoved() + argNpath(0, s.second.sensorPath),
+                [id = s.first](auto& /*msg*/) {
+                    // Ideally this should work.
+                    // But when a service is terminated or crashed, it does not
+                    // emit interfacesRemoved signal. In that case it's handled
+                    // by sensorsOwnerMatch
+                    sensorCacheMap[id].reset();
+                }));
+        sensorUpdatedMatches.emplace(
+            s.first,
+            std::make_unique<sdbusplus::bus::match_t>(
+                bus,
+                type::signal() + path(s.second.sensorPath) +
+                    member("PropertiesChanged"s) +
+                    interface("org.freedesktop.DBus.Properties"s),
+                [&s](auto& msg) {
+                    fillSensorIdServiceMap(
+                        s.second.sensorPath,
+                        s.second.propertyInterfaces.begin()->first, s.first);
+                    try
+                    {
+                        // This is signal callback
+                        std::string interfaceName;
+                        msg.read(interfaceName);
+                        ipmi::PropertyMap props;
+                        msg.read(props);
+                        s.second.getFunc(s.first, s.second, props);
+                    }
+                    catch (const std::exception& e)
+                    {
+                        sensorCacheMap[s.first].reset();
+                    }
+                }));
+    }
+    sensorsOwnerMatch = std::make_unique<sdbusplus::bus::match_t>(
+        bus, nameOwnerChanged(), [](auto& msg) {
+            std::string name;
+            std::string oldOwner;
+            std::string newOwner;
+            msg.read(name, oldOwner, newOwner);
+
+            if (!name.empty() && newOwner.empty())
+            {
+                // The service exits
+                const auto it = serviceToIdMap.find(name);
+                if (it == serviceToIdMap.end())
+                {
+                    return;
+                }
+                for (const auto& id : it->second)
+                {
+                    // Invalidate cache
+                    sensorCacheMap[id].reset();
+                }
+            }
+        });
+}
+#endif
+
+// Use a lookup table to find the interface name of a specific sensor
+// This will be used until an alternative is found.  this is the first
+// step for mapping IPMI
+int find_openbmc_path(uint8_t num, dbus_interface_t* interface)
+{
+    const auto& sensor_it = ipmi::sensor::sensors.find(num);
+    if (sensor_it == ipmi::sensor::sensors.end())
+    {
+        // The sensor map does not contain the sensor requested
+        return -EINVAL;
+    }
+
+    const auto& info = sensor_it->second;
+
+    std::string serviceName{};
+    try
+    {
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+        serviceName =
+            ipmi::getService(bus, info.sensorInterface, info.sensorPath);
+    }
+    catch (const sdbusplus::exception_t&)
+    {
+        std::fprintf(stderr, "Failed to get %s busname: %s\n",
+                     info.sensorPath.c_str(), serviceName.c_str());
+        return -EINVAL;
+    }
+
+    interface->sensortype = info.sensorType;
+    strcpy(interface->bus, serviceName.c_str());
+    strcpy(interface->path, info.sensorPath.c_str());
+    // Take the interface name from the beginning of the DbusInterfaceMap. This
+    // works for the Value interface but may not suffice for more complex
+    // sensors.
+    // tracked https://github.com/openbmc/phosphor-host-ipmid/issues/103
+    strcpy(interface->interface,
+           info.propertyInterfaces.begin()->first.c_str());
+    interface->sensornumber = num;
+
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+// Routines used by ipmi commands wanting to interact on the dbus
+//
+/////////////////////////////////////////////////////////////////////
+int set_sensor_dbus_state_s(uint8_t number, const char* method,
+                            const char* value)
+{
+    dbus_interface_t a;
+    int r;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message* m = nullptr;
+
+    r = find_openbmc_path(number, &a);
+
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to find Sensor 0x%02x\n", number);
+        return 0;
+    }
+
+    r = sd_bus_message_new_method_call(bus, &m, a.bus, a.path, a.interface,
+                                       method);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to create a method call: %s",
+                     strerror(-r));
+        goto final;
+    }
+
+    r = sd_bus_message_append(m, "v", "s", value);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to create a input parameter: %s",
+                     strerror(-r));
+        goto final;
+    }
+
+    r = sd_bus_call(bus, m, 0, &error, nullptr);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to call the method: %s", strerror(-r));
+    }
+
+final:
+    sd_bus_error_free(&error);
+    m = sd_bus_message_unref(m);
+
+    return 0;
+}
+int set_sensor_dbus_state_y(uint8_t number, const char* method,
+                            const uint8_t value)
+{
+    dbus_interface_t a;
+    int r;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message* m = nullptr;
+
+    r = find_openbmc_path(number, &a);
+
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to find Sensor 0x%02x\n", number);
+        return 0;
+    }
+
+    r = sd_bus_message_new_method_call(bus, &m, a.bus, a.path, a.interface,
+                                       method);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to create a method call: %s",
+                     strerror(-r));
+        goto final;
+    }
+
+    r = sd_bus_message_append(m, "v", "i", value);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Failed to create a input parameter: %s",
+                     strerror(-r));
+        goto final;
+    }
+
+    r = sd_bus_call(bus, m, 0, &error, nullptr);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "12 Failed to call the method: %s", strerror(-r));
+    }
+
+final:
+    sd_bus_error_free(&error);
+    m = sd_bus_message_unref(m);
+
+    return 0;
+}
+
+uint8_t dbus_to_sensor_type(char* p)
+{
+    sensorTypemap_t* s = g_SensorTypeMap;
+    char r = 0;
+    while (s->number != 0xFF)
+    {
+        if (!strcmp(s->dbusname, p))
+        {
+            r = s->typecode;
+            break;
+        }
+        s++;
+    }
+
+    if (s->number == 0xFF)
+        printf("Failed to find Sensor Type %s\n", p);
+
+    return r;
+}
+
+uint8_t get_type_from_interface(dbus_interface_t dbus_if)
+{
+    uint8_t type;
+
+    // This is where sensors that do not exist in dbus but do
+    // exist in the host code stop.  This should indicate it
+    // is not a supported sensor
+    if (dbus_if.interface[0] == 0)
+    {
+        return 0;
+    }
+
+    // Fetch type from interface itself.
+    if (dbus_if.sensortype != 0)
+    {
+        type = dbus_if.sensortype;
+    }
+    else
+    {
+        // Non InventoryItems
+        char* p = strrchr(dbus_if.path, '/');
+        type = dbus_to_sensor_type(p + 1);
+    }
+
+    return type;
+}
+
+// Replaces find_sensor
+uint8_t find_type_for_sensor_number(uint8_t num)
+{
+    int r;
+    dbus_interface_t dbus_if;
+    r = find_openbmc_path(num, &dbus_if);
+    if (r < 0)
+    {
+        std::fprintf(stderr, "Could not find sensor %d\n", num);
+        return 0;
+    }
+    return get_type_from_interface(dbus_if);
+}
+
+/**
+ *  @brief implements the get sensor type command.
+ *  @param - sensorNumber
+ *
+ *  @return IPMI completion code plus response data on success.
+ *   - sensorType
+ *   - eventType
+ **/
+
+ipmi::RspType<uint8_t, // sensorType
+              uint8_t  // eventType
+              >
+    ipmiGetSensorType(uint8_t sensorNumber)
+{
+    const auto it = ipmi::sensor::sensors.find(sensorNumber);
+    if (it == ipmi::sensor::sensors.end())
+    {
+        // The sensor map does not contain the sensor requested
+        return ipmi::responseSensorInvalid();
+    }
+
+    const auto& info = it->second;
+    uint8_t sensorType = info.sensorType;
+    uint8_t eventType = info.sensorReadingType;
+
+    return ipmi::responseSuccess(sensorType, eventType);
+}
+
+const std::set<std::string> analogSensorInterfaces = {
+    "xyz.openbmc_project.Sensor.Value",
+    "xyz.openbmc_project.Control.FanPwm",
+};
+
+bool isAnalogSensor(const std::string& interface)
+{
+    return (analogSensorInterfaces.count(interface));
+}
+
+/**
+@brief This command is used to set sensorReading.
+
+@param
+    -  sensorNumber
+    -  operation
+    -  reading
+    -  assertOffset0_7
+    -  assertOffset8_14
+    -  deassertOffset0_7
+    -  deassertOffset8_14
+    -  eventData1
+    -  eventData2
+    -  eventData3
+
+@return completion code on success.
+**/
+
+ipmi::RspType<> ipmiSetSensorReading(
+    uint8_t sensorNumber, uint8_t operation, uint8_t reading,
+    uint8_t assertOffset0_7, uint8_t assertOffset8_14,
+    uint8_t deassertOffset0_7, uint8_t deassertOffset8_14, uint8_t eventData1,
+    uint8_t eventData2, uint8_t eventData3)
+{
+    lg2::debug("IPMI SET_SENSOR, sensorNumber: {SENSOR_NUM}", "SENSOR_NUM",
+               lg2::hex, sensorNumber);
+
+    if (sensorNumber == 0xFF)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    ipmi::sensor::SetSensorReadingReq cmdData;
+
+    cmdData.number = sensorNumber;
+    cmdData.operation = operation;
+    cmdData.reading = reading;
+    cmdData.assertOffset0_7 = assertOffset0_7;
+    cmdData.assertOffset8_14 = assertOffset8_14;
+    cmdData.deassertOffset0_7 = deassertOffset0_7;
+    cmdData.deassertOffset8_14 = deassertOffset8_14;
+    cmdData.eventData1 = eventData1;
+    cmdData.eventData2 = eventData2;
+    cmdData.eventData3 = eventData3;
+
+    // Check if the Sensor Number is present
+    const auto iter = ipmi::sensor::sensors.find(sensorNumber);
+    if (iter == ipmi::sensor::sensors.end())
+    {
+        updateSensorRecordFromSSRAESC(&sensorNumber);
+        return ipmi::responseSuccess();
+    }
+
+    try
+    {
+        if (ipmi::sensor::Mutability::Write !=
+            (iter->second.mutability & ipmi::sensor::Mutability::Write))
+        {
+            lg2::error("Sensor Set operation is not allowed, "
+                       "sensorNumber: {SENSOR_NUM}",
+                       "SENSOR_NUM", lg2::hex, sensorNumber);
+            return ipmi::responseIllegalCommand();
+        }
+        auto ipmiRC = iter->second.updateFunc(cmdData, iter->second);
+        return ipmi::response(ipmiRC);
+    }
+    catch (const InternalFailure& e)
+    {
+        lg2::error("Set sensor failed, sensorNumber: {SENSOR_NUM}",
+                   "SENSOR_NUM", lg2::hex, sensorNumber);
+        commit<InternalFailure>();
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (const std::runtime_error& e)
+    {
+        lg2::error("runtime error: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+}
+
+/** @brief implements the get sensor reading command
+ *  @param sensorNum - sensor number
+ *
+ *  @returns IPMI completion code plus response data
+ *   - senReading           - sensor reading
+ *   - reserved
+ *   - readState            - sensor reading state enabled
+ *   - senScanState         - sensor scan state disabled
+ *   - allEventMessageState - all Event message state disabled
+ *   - assertionStatesLsb   - threshold levels states
+ *   - assertionStatesMsb   - discrete reading sensor states
+ */
+ipmi::RspType<uint8_t, // sensor reading
+
+              uint5_t, // reserved
+              bool,    // reading state
+              bool,    // 0 = sensor scanning state disabled
+              bool,    // 0 = all event messages disabled
+
+              uint8_t, // threshold levels states
+              uint8_t  // discrete reading sensor states
+              >
+    ipmiSensorGetSensorReading([[maybe_unused]] ipmi::Context::ptr& ctx,
+                               uint8_t sensorNum)
+{
+    if (sensorNum == 0xFF)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    const auto iter = ipmi::sensor::sensors.find(sensorNum);
+    if (iter == ipmi::sensor::sensors.end())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+    if (ipmi::sensor::Mutability::Read !=
+        (iter->second.mutability & ipmi::sensor::Mutability::Read))
+    {
+        return ipmi::responseIllegalCommand();
+    }
+
+    try
+    {
+#ifdef FEATURE_SENSORS_CACHE
+        auto& sensorData = sensorCacheMap[sensorNum];
+        if (!sensorData.has_value())
+        {
+            // No cached value, try read it
+            std::string service;
+            boost::system::error_code ec;
+            const auto& sensorInfo = iter->second;
+            ec = ipmi::getService(ctx, sensorInfo.sensorInterface,
+                                  sensorInfo.sensorPath, service);
+            if (ec)
+            {
+                return ipmi::responseUnspecifiedError();
+            }
+            fillSensorIdServiceMap(sensorInfo.sensorPath,
+                                   sensorInfo.propertyInterfaces.begin()->first,
+                                   iter->first, service);
+
+            ipmi::PropertyMap props;
+            ec = ipmi::getAllDbusProperties(
+                ctx, service, sensorInfo.sensorPath,
+                sensorInfo.propertyInterfaces.begin()->first, props);
+            if (ec)
+            {
+                fprintf(stderr, "Failed to get sensor %s, %d: %s\n",
+                        sensorInfo.sensorPath.c_str(), ec.value(),
+                        ec.message().c_str());
+                // Intitilizing with default values
+                constexpr uint8_t senReading = 0;
+                constexpr uint5_t reserved{0};
+                constexpr bool readState = true;
+                constexpr bool senScanState = false;
+                constexpr bool allEventMessageState = false;
+                constexpr uint8_t assertionStatesLsb = 0;
+                constexpr uint8_t assertionStatesMsb = 0;
+
+                return ipmi::responseSuccess(
+                    senReading, reserved, readState, senScanState,
+                    allEventMessageState, assertionStatesLsb,
+                    assertionStatesMsb);
+            }
+            sensorInfo.getFunc(sensorNum, sensorInfo, props);
+        }
+        return ipmi::responseSuccess(
+            sensorData->response.reading, uint5_t(0),
+            sensorData->response.readingOrStateUnavailable,
+            sensorData->response.scanningEnabled,
+            sensorData->response.allEventMessagesEnabled,
+            sensorData->response.thresholdLevelsStates,
+            sensorData->response.discreteReadingSensorStates);
+
+#else
+        ipmi::sensor::GetSensorResponse getResponse =
+            iter->second.getFunc(iter->second);
+
+        return ipmi::responseSuccess(
+            getResponse.reading, uint5_t(0),
+            getResponse.readingOrStateUnavailable, getResponse.scanningEnabled,
+            getResponse.allEventMessagesEnabled,
+            getResponse.thresholdLevelsStates,
+            getResponse.discreteReadingSensorStates);
+#endif
+    }
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+    catch (const SensorFunctionalError& e)
+    {
+        return ipmi::responseResponseError();
+    }
+#endif
+    catch (const std::exception& e)
+    {
+        // Intitilizing with default values
+        constexpr uint8_t senReading = 0;
+        constexpr uint5_t reserved{0};
+        constexpr bool readState = true;
+        constexpr bool senScanState = false;
+        constexpr bool allEventMessageState = false;
+        constexpr uint8_t assertionStatesLsb = 0;
+        constexpr uint8_t assertionStatesMsb = 0;
+
+        return ipmi::responseSuccess(senReading, reserved, readState,
+                                     senScanState, allEventMessageState,
+                                     assertionStatesLsb, assertionStatesMsb);
+    }
+}
+
+void updateWarningThreshold(uint8_t lowerValue, uint8_t upperValue,
+                            get_sdr::GetSensorThresholdsResponse& resp)
+{
+    resp.lowerNonCritical = lowerValue;
+    resp.upperNonCritical = upperValue;
+    if (lowerValue)
+    {
+        resp.validMask |= static_cast<uint8_t>(
+            ipmi::sensor::ThresholdMask::NON_CRITICAL_LOW_MASK);
+    }
+
+    if (upperValue)
+    {
+        resp.validMask |= static_cast<uint8_t>(
+            ipmi::sensor::ThresholdMask::NON_CRITICAL_HIGH_MASK);
+    }
+}
+
+void updateCriticalThreshold(uint8_t lowerValue, uint8_t upperValue,
+                             get_sdr::GetSensorThresholdsResponse& resp)
+{
+    resp.lowerCritical = lowerValue;
+    resp.upperCritical = upperValue;
+    if (lowerValue)
+    {
+        resp.validMask |= static_cast<uint8_t>(
+            ipmi::sensor::ThresholdMask::CRITICAL_LOW_MASK);
+    }
+
+    if (upperValue)
+    {
+        resp.validMask |= static_cast<uint8_t>(
+            ipmi::sensor::ThresholdMask::CRITICAL_HIGH_MASK);
+    }
+}
+
+void updateNonRecoverableThreshold(uint8_t lowerValue, uint8_t upperValue,
+                                   get_sdr::GetSensorThresholdsResponse& resp)
+{
+    resp.lowerNonRecoverable = lowerValue;
+    resp.upperNonRecoverable = upperValue;
+    if (lowerValue)
+    {
+        resp.validMask |= static_cast<uint8_t>(
+            ipmi::sensor::ThresholdMask::NON_RECOVERABLE_LOW_MASK);
+    }
+
+    if (upperValue)
+    {
+        resp.validMask |= static_cast<uint8_t>(
+            ipmi::sensor::ThresholdMask::NON_RECOVERABLE_HIGH_MASK);
+    }
+}
+
+get_sdr::GetSensorThresholdsResponse getSensorThresholds(
+    ipmi::Context::ptr& ctx, uint8_t sensorNum)
+{
+    get_sdr::GetSensorThresholdsResponse resp{};
+    const auto iter = ipmi::sensor::sensors.find(sensorNum);
+    const auto info = iter->second;
+
+    std::string service;
+    boost::system::error_code ec;
+    ec = ipmi::getService(ctx, info.sensorInterface, info.sensorPath, service);
+    if (ec)
+    {
+        return resp;
+    }
+
+    int32_t minClamp;
+    int32_t maxClamp;
+    int32_t rawData;
+    constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
+    constexpr uint8_t signedDataFormat = 0x80;
+    if ((info.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
+    {
+        minClamp = std::numeric_limits<int8_t>::lowest();
+        maxClamp = std::numeric_limits<int8_t>::max();
+    }
+    else
+    {
+        minClamp = std::numeric_limits<uint8_t>::lowest();
+        maxClamp = std::numeric_limits<uint8_t>::max();
+    }
+
+    static std::vector<std::string> thresholdNames{"Warning", "Critical",
+                                                   "NonRecoverable"};
+
+    for (const auto& thresholdName : thresholdNames)
+    {
+        std::string thresholdInterface =
+            "xyz.openbmc_project.Sensor.Threshold." + thresholdName;
+        std::string thresholdLow = thresholdName + "Low";
+        std::string thresholdHigh = thresholdName + "High";
+
+        ipmi::PropertyMap thresholds;
+        ec = ipmi::getAllDbusProperties(ctx, service, info.sensorPath,
+                                        thresholdInterface, thresholds);
+        if (ec)
+        {
+            continue;
+        }
+
+        double lowValue = ipmi::mappedVariant<double>(
+            thresholds, thresholdLow, std::numeric_limits<double>::quiet_NaN());
+        double highValue = ipmi::mappedVariant<double>(
+            thresholds, thresholdHigh,
+            std::numeric_limits<double>::quiet_NaN());
+
+        uint8_t lowerValue = 0;
+        uint8_t upperValue = 0;
+        if (std::isfinite(lowValue))
+        {
+            lowValue *= std::pow(10, info.scale - info.exponentR);
+            rawData = round((lowValue - info.scaledOffset) / info.coefficientM);
+            lowerValue =
+                static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp));
+        }
+
+        if (std::isfinite(highValue))
+        {
+            highValue *= std::pow(10, info.scale - info.exponentR);
+            rawData =
+                round((highValue - info.scaledOffset) / info.coefficientM);
+            upperValue =
+                static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp));
+        }
+
+        if (thresholdName == "Warning")
+        {
+            updateWarningThreshold(lowerValue, upperValue, resp);
+        }
+        else if (thresholdName == "Critical")
+        {
+            updateCriticalThreshold(lowerValue, upperValue, resp);
+        }
+        else if (thresholdName == "NonRecoverable")
+        {
+            updateNonRecoverableThreshold(lowerValue, upperValue, resp);
+        }
+    }
+
+    return resp;
+}
+
+/** @brief implements the get sensor thresholds command
+ *  @param ctx - IPMI context pointer
+ *  @param sensorNum - sensor number
+ *
+ *  @returns IPMI completion code plus response data
+ *   - validMask - threshold mask
+ *   - lower non-critical threshold - IPMI messaging state
+ *   - lower critical threshold - link authentication state
+ *   - lower non-recoverable threshold - callback state
+ *   - upper non-critical threshold
+ *   - upper critical
+ *   - upper non-recoverable
+ */
+ipmi::RspType<uint8_t, // validMask
+              uint8_t, // lowerNonCritical
+              uint8_t, // lowerCritical
+              uint8_t, // lowerNonRecoverable
+              uint8_t, // upperNonCritical
+              uint8_t, // upperCritical
+              uint8_t  // upperNonRecoverable
+              >
+    ipmiSensorGetSensorThresholds(ipmi::Context::ptr& ctx, uint8_t sensorNum)
+{
+    constexpr auto valueInterface = "xyz.openbmc_project.Sensor.Value";
+
+    const auto iter = ipmi::sensor::sensors.find(sensorNum);
+    if (iter == ipmi::sensor::sensors.end())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    const auto info = iter->second;
+
+    // Proceed only if the sensor value interface is implemented.
+    if (info.propertyInterfaces.find(valueInterface) ==
+        info.propertyInterfaces.end())
+    {
+        // return with valid mask as 0
+        return ipmi::responseSuccess();
+    }
+
+    auto it = sensorThresholdMap.find(sensorNum);
+    if (it == sensorThresholdMap.end())
+    {
+        auto resp = getSensorThresholds(ctx, sensorNum);
+        if (resp.validMask == 0)
+        {
+            return ipmi::responseSensorInvalid();
+        }
+        sensorThresholdMap[sensorNum] = std::move(resp);
+    }
+
+    const auto& resp = sensorThresholdMap[sensorNum];
+
+    return ipmi::responseSuccess(
+        resp.validMask, resp.lowerNonCritical, resp.lowerCritical,
+        resp.lowerNonRecoverable, resp.upperNonCritical, resp.upperCritical,
+        resp.upperNonRecoverable);
+}
+
+/** @brief implements the Set Sensor threshold command
+ *  @param sensorNumber        - sensor number
+ *  @param lowerNonCriticalThreshMask
+ *  @param lowerCriticalThreshMask
+ *  @param lowerNonRecovThreshMask
+ *  @param upperNonCriticalThreshMask
+ *  @param upperCriticalThreshMask
+ *  @param upperNonRecovThreshMask
+ *  @param reserved
+ *  @param lowerNonCritical    - lower non-critical threshold
+ *  @param lowerCritical       - Lower critical threshold
+ *  @param lowerNonRecoverable - Lower non recovarable threshold
+ *  @param upperNonCritical    - Upper non-critical threshold
+ *  @param upperCritical       - Upper critical
+ *  @param upperNonRecoverable - Upper Non-recoverable
+ *
+ *  @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiSenSetSensorThresholds(
+    ipmi::Context::ptr& ctx, uint8_t sensorNum, bool lowerNonCriticalThreshMask,
+    bool lowerCriticalThreshMask, bool lowerNonRecovThreshMask,
+    bool upperNonCriticalThreshMask, bool upperCriticalThreshMask,
+    bool upperNonRecovThreshMask, uint2_t reserved, uint8_t lowerNonCritical,
+    uint8_t lowerCritical, uint8_t, uint8_t upperNonCritical,
+    uint8_t upperCritical, uint8_t)
+{
+    if (reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // lower nc and upper nc not suppported on any sensor
+    if (lowerNonRecovThreshMask || upperNonRecovThreshMask)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // if none of the threshold mask are set, nothing to do
+    if (!(lowerNonCriticalThreshMask | lowerCriticalThreshMask |
+          lowerNonRecovThreshMask | upperNonCriticalThreshMask |
+          upperCriticalThreshMask | upperNonRecovThreshMask))
+    {
+        return ipmi::responseSuccess();
+    }
+
+    constexpr auto valueInterface = "xyz.openbmc_project.Sensor.Value";
+
+    const auto iter = ipmi::sensor::sensors.find(sensorNum);
+    if (iter == ipmi::sensor::sensors.end())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    const auto& info = iter->second;
+
+    // Proceed only if the sensor value interface is implemented.
+    if (info.propertyInterfaces.find(valueInterface) ==
+        info.propertyInterfaces.end())
+    {
+        // return with valid mask as 0
+        return ipmi::responseSuccess();
+    }
+
+    constexpr auto warningThreshIntf =
+        "xyz.openbmc_project.Sensor.Threshold.Warning";
+    constexpr auto criticalThreshIntf =
+        "xyz.openbmc_project.Sensor.Threshold.Critical";
+
+    std::string service;
+    boost::system::error_code ec;
+    ec = ipmi::getService(ctx, info.sensorInterface, info.sensorPath, service);
+    if (ec)
+    {
+        return ipmi::responseResponseError();
+    }
+    // store a vector of property name, value to set, and interface
+    std::vector<std::tuple<std::string, uint8_t, std::string>> thresholdsToSet;
+
+    // define the indexes of the tuple
+    constexpr uint8_t propertyName = 0;
+    constexpr uint8_t thresholdValue = 1;
+    constexpr uint8_t interface = 2;
+    // verifiy all needed fields are present
+    if (lowerCriticalThreshMask || upperCriticalThreshMask)
+    {
+        ipmi::PropertyMap findThreshold;
+        ec = ipmi::getAllDbusProperties(ctx, service, info.sensorPath,
+                                        criticalThreshIntf, findThreshold);
+
+        if (!ec)
+        {
+            if (lowerCriticalThreshMask)
+            {
+                auto findLower = findThreshold.find("CriticalLow");
+                if (findLower == findThreshold.end())
+                {
+                    return ipmi::responseInvalidFieldRequest();
+                }
+                thresholdsToSet.emplace_back("CriticalLow", lowerCritical,
+                                             criticalThreshIntf);
+            }
+            if (upperCriticalThreshMask)
+            {
+                auto findUpper = findThreshold.find("CriticalHigh");
+                if (findUpper == findThreshold.end())
+                {
+                    return ipmi::responseInvalidFieldRequest();
+                }
+                thresholdsToSet.emplace_back("CriticalHigh", upperCritical,
+                                             criticalThreshIntf);
+            }
+        }
+    }
+    if (lowerNonCriticalThreshMask || upperNonCriticalThreshMask)
+    {
+        ipmi::PropertyMap findThreshold;
+        ec = ipmi::getAllDbusProperties(ctx, service, info.sensorPath,
+                                        warningThreshIntf, findThreshold);
+
+        if (!ec)
+        {
+            if (lowerNonCriticalThreshMask)
+            {
+                auto findLower = findThreshold.find("WarningLow");
+                if (findLower == findThreshold.end())
+                {
+                    return ipmi::responseInvalidFieldRequest();
+                }
+                thresholdsToSet.emplace_back("WarningLow", lowerNonCritical,
+                                             warningThreshIntf);
+            }
+            if (upperNonCriticalThreshMask)
+            {
+                auto findUpper = findThreshold.find("WarningHigh");
+                if (findUpper == findThreshold.end())
+                {
+                    return ipmi::responseInvalidFieldRequest();
+                }
+                thresholdsToSet.emplace_back("WarningHigh", upperNonCritical,
+                                             warningThreshIntf);
+            }
+        }
+    }
+    for (const auto& property : thresholdsToSet)
+    {
+        // from section 36.3 in the IPMI Spec, assume all linear
+        double valueToSet =
+            ((info.coefficientM * std::get<thresholdValue>(property)) +
+             (info.scaledOffset * std::pow(10.0, info.scale))) *
+            std::pow(10.0, info.exponentR);
+        ipmi::setDbusProperty(
+            ctx, service, info.sensorPath, std::get<interface>(property),
+            std::get<propertyName>(property), ipmi::Value(valueToSet));
+    }
+
+    // Invalidate the cache
+    sensorThresholdMap.erase(sensorNum);
+    return ipmi::responseSuccess();
+}
+
+/** @brief implements the get SDR Info command
+ *  @param count - Operation
+ *
+ *  @returns IPMI completion code plus response data
+ *   - sdrCount - sensor/SDR count
+ *   - lunsAndDynamicPopulation - static/Dynamic sensor population flag
+ */
+ipmi::RspType<uint8_t, // respcount
+              uint8_t  // dynamic population flags
+              >
+    ipmiSensorGetDeviceSdrInfo(std::optional<uint8_t> count)
+{
+    uint8_t sdrCount;
+    // multiple LUNs not supported.
+    constexpr uint8_t lunsAndDynamicPopulation = 1;
+    constexpr uint8_t getSdrCount = 0x01;
+    constexpr uint8_t getSensorCount = 0x00;
+
+    if (count.value_or(0) == getSdrCount)
+    {
+        // Get SDR count. This returns the total number of SDRs in the device.
+        const auto& entityRecords =
+            ipmi::sensor::EntityInfoMapContainer::getContainer()
+                ->getIpmiEntityRecords();
+        sdrCount = ipmi::sensor::sensors.size() + frus.size() +
+                   entityRecords.size();
+    }
+    else if (count.value_or(0) == getSensorCount)
+    {
+        // Get Sensor count. This returns the number of sensors
+        sdrCount = ipmi::sensor::sensors.size();
+    }
+    else
+    {
+        return ipmi::responseInvalidCommandOnLun();
+    }
+
+    return ipmi::responseSuccess(sdrCount, lunsAndDynamicPopulation);
+}
+
+/** @brief implements the reserve SDR command
+ *  @returns IPMI completion code plus response data
+ *   - reservationID - reservation ID
+ */
+ipmi::RspType<uint16_t> ipmiSensorReserveSdr()
+{
+    // A constant reservation ID is okay until we implement add/remove SDR.
+    constexpr uint16_t reservationID = 1;
+
+    return ipmi::responseSuccess(reservationID);
+}
+
+void setUnitFieldsForObject(const ipmi::sensor::Info* info,
+                            get_sdr::SensorDataFullRecordBody* body)
+{
+    namespace server = sdbusplus::server::xyz::openbmc_project::sensor;
+    try
+    {
+        auto unit = server::Value::convertUnitFromString(info->unit);
+        // Unit strings defined in
+        // phosphor-dbus-interfaces/xyz/openbmc_project/Sensor/Value.interface.yaml
+        switch (unit)
+        {
+            case server::Value::Unit::DegreesC:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_DEGREES_C;
+                break;
+            case server::Value::Unit::RPMS:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_RPM;
+                break;
+            case server::Value::Unit::Volts:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_VOLTS;
+                break;
+            case server::Value::Unit::Meters:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_METERS;
+                break;
+            case server::Value::Unit::Amperes:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_AMPERES;
+                break;
+            case server::Value::Unit::Joules:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_JOULES;
+                break;
+            case server::Value::Unit::Watts:
+                body->sensor_units_2_base = get_sdr::SENSOR_UNIT_WATTS;
+                break;
+            default:
+                // Cannot be hit.
+                std::fprintf(stderr, "Unknown value unit type: = %s\n",
+                             info->unit.c_str());
+        }
+    }
+    catch (const sdbusplus::exception::InvalidEnumString& e)
+    {
+        lg2::warning("Warning: no unit provided for sensor!");
+    }
+}
+
+ipmi_ret_t populate_record_from_dbus(get_sdr::SensorDataFullRecordBody* body,
+                                     const ipmi::sensor::Info* info,
+                                     ipmi_data_len_t)
+{
+    /* Functional sensor case */
+    if (isAnalogSensor(info->propertyInterfaces.begin()->first))
+    {
+        body->sensor_units_1 = info->sensorUnits1; // default is 0. unsigned, no
+                                                   // rate, no modifier, not a %
+        /* Unit info */
+        setUnitFieldsForObject(info, body);
+
+        get_sdr::body::set_b(info->coefficientB, body);
+        get_sdr::body::set_m(info->coefficientM, body);
+        get_sdr::body::set_b_exp(info->exponentB, body);
+        get_sdr::body::set_r_exp(info->exponentR, body);
+    }
+
+    /* ID string */
+    auto id_string = info->sensorName;
+
+    if (id_string.empty())
+    {
+        id_string = info->sensorNameFunc(*info);
+    }
+
+    if (id_string.length() > FULL_RECORD_ID_STR_MAX_LENGTH)
+    {
+        get_sdr::body::set_id_strlen(FULL_RECORD_ID_STR_MAX_LENGTH, body);
+    }
+    else
+    {
+        get_sdr::body::set_id_strlen(id_string.length(), body);
+    }
+    get_sdr::body::set_id_type(3, body); // "8-bit ASCII + Latin 1"
+    strncpy(body->id_string, id_string.c_str(),
+            get_sdr::body::get_id_strlen(body));
+
+    return IPMI_CC_OK;
+};
+
+ipmi_ret_t ipmi_fru_get_sdr(ipmi_request_t request, ipmi_response_t response,
+                            ipmi_data_len_t data_len)
+{
+    auto req = reinterpret_cast<get_sdr::GetSdrReq*>(request);
+    auto resp = reinterpret_cast<get_sdr::GetSdrResp*>(response);
+    get_sdr::SensorDataFruRecord record{};
+    auto dataLength = 0;
+
+    auto fru = frus.begin();
+    uint8_t fruID{};
+    auto recordID = get_sdr::request::get_record_id(req);
+
+    fruID = recordID - FRU_RECORD_ID_START;
+    fru = frus.find(fruID);
+    if (fru == frus.end())
+    {
+        return IPMI_CC_SENSOR_INVALID;
+    }
+
+    /* Header */
+    get_sdr::header::set_record_id(recordID, &(record.header));
+    record.header.sdr_version = SDR_VERSION; // Based on IPMI Spec v2.0 rev 1.1
+    record.header.record_type = get_sdr::SENSOR_DATA_FRU_RECORD;
+    record.header.record_length = sizeof(record.key) + sizeof(record.body);
+
+    /* Key */
+    record.key.fruID = fruID;
+    record.key.accessLun |= IPMI_LOGICAL_FRU;
+    record.key.deviceAddress = BMCTargetAddress;
+
+    /* Body */
+    record.body.entityID = fru->second[0].entityID;
+    record.body.entityInstance = fru->second[0].entityInstance;
+    record.body.deviceType = fruInventoryDevice;
+    record.body.deviceTypeModifier = IPMIFruInventory;
+
+    /* Device ID string */
+    auto deviceID =
+        fru->second[0].path.substr(fru->second[0].path.find_last_of('/') + 1,
+                                   fru->second[0].path.length());
+
+    if (deviceID.length() > get_sdr::FRU_RECORD_DEVICE_ID_MAX_LENGTH)
+    {
+        get_sdr::body::set_device_id_strlen(
+            get_sdr::FRU_RECORD_DEVICE_ID_MAX_LENGTH, &(record.body));
+    }
+    else
+    {
+        get_sdr::body::set_device_id_strlen(deviceID.length(), &(record.body));
+    }
+
+    strncpy(record.body.deviceID, deviceID.c_str(),
+            get_sdr::body::get_device_id_strlen(&(record.body)));
+
+    if (++fru == frus.end())
+    {
+        // we have reached till end of fru, so assign the next record id to
+        // 512(Max fru ID = 511) + Entity Record ID(may start with 0).
+        const auto& entityRecords =
+            ipmi::sensor::EntityInfoMapContainer::getContainer()
+                ->getIpmiEntityRecords();
+        auto next_record_id =
+            (entityRecords.size())
+                ? entityRecords.begin()->first + ENTITY_RECORD_ID_START
+                : END_OF_RECORD;
+        get_sdr::response::set_next_record_id(next_record_id, resp);
+    }
+    else
+    {
+        get_sdr::response::set_next_record_id(
+            (FRU_RECORD_ID_START + fru->first), resp);
+    }
+
+    // Check for invalid offset size
+    if (req->offset > sizeof(record))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    dataLength = std::min(static_cast<size_t>(req->bytes_to_read),
+                          sizeof(record) - req->offset);
+
+    std::memcpy(resp->record_data,
+                reinterpret_cast<uint8_t*>(&record) + req->offset, dataLength);
+
+    *data_len = dataLength;
+    *data_len += 2; // additional 2 bytes for next record ID
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmi_entity_get_sdr(ipmi_request_t request, ipmi_response_t response,
+                               ipmi_data_len_t data_len)
+{
+    auto req = reinterpret_cast<get_sdr::GetSdrReq*>(request);
+    auto resp = reinterpret_cast<get_sdr::GetSdrResp*>(response);
+    get_sdr::SensorDataEntityRecord record{};
+    auto dataLength = 0;
+
+    const auto& entityRecords =
+        ipmi::sensor::EntityInfoMapContainer::getContainer()
+            ->getIpmiEntityRecords();
+    auto entity = entityRecords.begin();
+    uint8_t entityRecordID;
+    auto recordID = get_sdr::request::get_record_id(req);
+
+    entityRecordID = recordID - ENTITY_RECORD_ID_START;
+    entity = entityRecords.find(entityRecordID);
+    if (entity == entityRecords.end())
+    {
+        return IPMI_CC_SENSOR_INVALID;
+    }
+
+    /* Header */
+    get_sdr::header::set_record_id(recordID, &(record.header));
+    record.header.sdr_version = SDR_VERSION; // Based on IPMI Spec v2.0 rev 1.1
+    record.header.record_type = get_sdr::SENSOR_DATA_ENTITY_RECORD;
+    record.header.record_length = sizeof(record.key) + sizeof(record.body);
+
+    /* Key */
+    record.key.containerEntityId = entity->second.containerEntityId;
+    record.key.containerEntityInstance = entity->second.containerEntityInstance;
+    get_sdr::key::set_flags(entity->second.isList, entity->second.isLinked,
+                            &(record.key));
+    record.key.entityId1 = entity->second.containedEntities[0].first;
+    record.key.entityInstance1 = entity->second.containedEntities[0].second;
+
+    /* Body */
+    record.body.entityId2 = entity->second.containedEntities[1].first;
+    record.body.entityInstance2 = entity->second.containedEntities[1].second;
+    record.body.entityId3 = entity->second.containedEntities[2].first;
+    record.body.entityInstance3 = entity->second.containedEntities[2].second;
+    record.body.entityId4 = entity->second.containedEntities[3].first;
+    record.body.entityInstance4 = entity->second.containedEntities[3].second;
+
+    if (++entity == entityRecords.end())
+    {
+        get_sdr::response::set_next_record_id(END_OF_RECORD,
+                                              resp); // last record
+    }
+    else
+    {
+        get_sdr::response::set_next_record_id(
+            (ENTITY_RECORD_ID_START + entity->first), resp);
+    }
+
+    // Check for invalid offset size
+    if (req->offset > sizeof(record))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    dataLength = std::min(static_cast<size_t>(req->bytes_to_read),
+                          sizeof(record) - req->offset);
+
+    std::memcpy(resp->record_data,
+                reinterpret_cast<uint8_t*>(&record) + req->offset, dataLength);
+
+    *data_len = dataLength;
+    *data_len += 2; // additional 2 bytes for next record ID
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
+                            ipmi_response_t response, ipmi_data_len_t data_len,
+                            ipmi_context_t)
+{
+    ipmi_ret_t ret = IPMI_CC_OK;
+    get_sdr::GetSdrReq* req = (get_sdr::GetSdrReq*)request;
+    get_sdr::GetSdrResp* resp = (get_sdr::GetSdrResp*)response;
+
+    // Note: we use an iterator so we can provide the next ID at the end of
+    // the call.
+    auto sensor = ipmi::sensor::sensors.begin();
+    auto recordID = get_sdr::request::get_record_id(req);
+
+    // At the beginning of a scan, the host side will send us id=0.
+    if (recordID != 0)
+    {
+        // recordID 0 to 255 means it is a FULL record.
+        // recordID 256 to 511 means it is a FRU record.
+        // recordID greater then 511 means it is a Entity Association
+        // record. Currently we are supporting three record types: FULL
+        // record, FRU record and Enttiy Association record.
+        if (recordID >= ENTITY_RECORD_ID_START)
+        {
+            return ipmi_entity_get_sdr(request, response, data_len);
+        }
+        else if (recordID >= FRU_RECORD_ID_START &&
+                 recordID < ENTITY_RECORD_ID_START)
+        {
+            return ipmi_fru_get_sdr(request, response, data_len);
+        }
+        else
+        {
+            sensor = ipmi::sensor::sensors.find(recordID);
+            if (sensor == ipmi::sensor::sensors.end())
+            {
+                return IPMI_CC_SENSOR_INVALID;
+            }
+        }
+    }
+
+    uint8_t sensor_id = sensor->first;
+
+    auto it = sdrCacheMap.find(sensor_id);
+    if (it == sdrCacheMap.end())
+    {
+        /* Header */
+        get_sdr::SensorDataFullRecord record = {};
+        get_sdr::header::set_record_id(sensor_id, &(record.header));
+        record.header.sdr_version = 0x51; // Based on IPMI Spec v2.0 rev 1.1
+        record.header.record_type = get_sdr::SENSOR_DATA_FULL_RECORD;
+        record.header.record_length = sizeof(record.key) + sizeof(record.body);
+
+        /* Key */
+        get_sdr::key::set_owner_id_bmc(&(record.key));
+        record.key.sensor_number = sensor_id;
+
+        /* Body */
+        record.body.entity_id = sensor->second.entityType;
+        record.body.sensor_type = sensor->second.sensorType;
+        record.body.event_reading_type = sensor->second.sensorReadingType;
+        record.body.entity_instance = sensor->second.instance;
+        if (ipmi::sensor::Mutability::Write ==
+            (sensor->second.mutability & ipmi::sensor::Mutability::Write))
+        {
+            get_sdr::body::init_settable_state(true, &(record.body));
+        }
+
+        // Set the type-specific details given the DBus interface
+        populate_record_from_dbus(&(record.body), &(sensor->second), data_len);
+        sdrCacheMap[sensor_id] = std::move(record);
+    }
+
+    const auto& record = sdrCacheMap[sensor_id];
+
+    if (++sensor == ipmi::sensor::sensors.end())
+    {
+        // we have reached till end of sensor, so assign the next record id
+        // to 256(Max Sensor ID = 255) + FRU ID(may start with 0).
+        auto next_record_id = (frus.size())
+                                  ? frus.begin()->first + FRU_RECORD_ID_START
+                                  : END_OF_RECORD;
+
+        get_sdr::response::set_next_record_id(next_record_id, resp);
+    }
+    else
+    {
+        get_sdr::response::set_next_record_id(sensor->first, resp);
+    }
+
+    if (req->offset > sizeof(record))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // data_len will ultimately be the size of the record, plus
+    // the size of the next record ID:
+    *data_len = std::min(static_cast<size_t>(req->bytes_to_read),
+                         sizeof(record) - req->offset);
+
+    std::memcpy(resp->record_data,
+                reinterpret_cast<const uint8_t*>(&record) + req->offset,
+                *data_len);
+
+    // data_len should include the LSB and MSB:
+    *data_len += sizeof(resp->next_record_id_lsb) +
+                 sizeof(resp->next_record_id_msb);
+
+    return ret;
+}
+
+static bool isFromSystemChannel()
+{
+    // TODO we could not figure out where the request is from based on IPMI
+    // command handler parameters. because of it, we can not differentiate
+    // request from SMS/SMM or IPMB channel
+    return true;
+}
+
+ipmi_ret_t ipmicmdPlatformEvent(ipmi_netfn_t, ipmi_cmd_t,
+                                ipmi_request_t request, ipmi_response_t,
+                                ipmi_data_len_t dataLen, ipmi_context_t)
+{
+    uint16_t generatorID;
+    size_t count;
+    bool assert = true;
+    std::string sensorPath;
+    size_t paraLen = *dataLen;
+    PlatformEventRequest* req;
+    *dataLen = 0;
+
+    if ((paraLen < selSystemEventSizeWith1Bytes) ||
+        (paraLen > selSystemEventSizeWith3Bytes))
+    {
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    if (isFromSystemChannel())
+    { // first byte for SYSTEM Interface is Generator ID
+        // +1 to get common struct
+        req = reinterpret_cast<PlatformEventRequest*>((uint8_t*)request + 1);
+        // Capture the generator ID
+        generatorID = *reinterpret_cast<uint8_t*>(request);
+        // Platform Event usually comes from other firmware, like BIOS.
+        // Unlike BMC sensor, it does not have BMC DBUS sensor path.
+        sensorPath = "System";
+    }
+    else
+    {
+        req = reinterpret_cast<PlatformEventRequest*>(request);
+        // TODO GenratorID for IPMB is combination of RqSA and RqLUN
+        generatorID = 0xff;
+        sensorPath = "IPMB";
+    }
+    // Content of event data field depends on sensor class.
+    // When data0 bit[5:4] is non-zero, valid data counts is 3.
+    // When data0 bit[7:6] is non-zero, valid data counts is 2.
+    if (((req->data[0] & byte3EnableMask) != 0 &&
+         paraLen < selSystemEventSizeWith3Bytes) ||
+        ((req->data[0] & byte2EnableMask) != 0 &&
+         paraLen < selSystemEventSizeWith2Bytes))
+    {
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    // Count bytes of Event Data
+    if ((req->data[0] & byte3EnableMask) != 0)
+    {
+        count = 3;
+    }
+    else if ((req->data[0] & byte2EnableMask) != 0)
+    {
+        count = 2;
+    }
+    else
+    {
+        count = 1;
+    }
+    assert = req->eventDirectionType & directionMask ? false : true;
+    std::vector<uint8_t> eventData(req->data, req->data + count);
+
+    sdbusplus::bus_t dbus(bus);
+    std::string service =
+        ipmi::getService(dbus, ipmiSELAddInterface, ipmiSELPath);
+    sdbusplus::message_t writeSEL = dbus.new_method_call(
+        service.c_str(), ipmiSELPath, ipmiSELAddInterface, "IpmiSelAdd");
+    writeSEL.append(ipmiSELAddMessage, sensorPath, eventData, assert,
+                    generatorID);
+    try
+    {
+        dbus.call(writeSEL);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("exception message: {ERROR}", "ERROR", e);
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+void registerNetFnSenFunctions()
+{
+    // Handlers with dbus-sdr handler implementation.
+    // Do not register the hander if it dynamic sensors stack is used.
+
+#ifndef FEATURE_DYNAMIC_SENSORS
+
+#ifdef FEATURE_SENSORS_CACHE
+    // Initialize the sensor matches
+    initSensorMatches();
+#endif
+
+    // <Set Sensor Reading and Event Status>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdSetSensorReadingAndEvtSts,
+                          ipmi::Privilege::Operator, ipmiSetSensorReading);
+    // <Get Sensor Reading>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorReading,
+                          ipmi::Privilege::User, ipmiSensorGetSensorReading);
+
+    // <Reserve Device SDR Repository>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdReserveDeviceSdrRepository,
+                          ipmi::Privilege::User, ipmiSensorReserveSdr);
+
+    // <Get Device SDR Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetDeviceSdrInfo,
+                          ipmi::Privilege::User, ipmiSensorGetDeviceSdrInfo);
+
+    // <Get Sensor Thresholds>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorThreshold,
+                          ipmi::Privilege::User, ipmiSensorGetSensorThresholds);
+
+    // <Set Sensor Thresholds>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdSetSensorThreshold,
+                          ipmi::Privilege::User, ipmiSenSetSensorThresholds);
+
+    // <Get Device SDR>
+    ipmi_register_callback(NETFUN_SENSOR, ipmi::sensor_event::cmdGetDeviceSdr,
+                           nullptr, ipmi_sen_get_sdr, PRIVILEGE_USER);
+
+#endif
+
+    // Common Handers used by both implementation.
+
+    // <Platform Event Message>
+    ipmi_register_callback(NETFUN_SENSOR, ipmi::sensor_event::cmdPlatformEvent,
+                           nullptr, ipmicmdPlatformEvent, PRIVILEGE_OPERATOR);
+
+    // <Get Sensor Type>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
+                          ipmi::sensor_event::cmdGetSensorType,
+                          ipmi::Privilege::User, ipmiGetSensorType);
+
+    return;
+}
diff --git a/sensorhandler.hpp b/sensorhandler.hpp
new file mode 100644
index 0000000..74b1862
--- /dev/null
+++ b/sensorhandler.hpp
@@ -0,0 +1,766 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+
+#include <exception>
+
+/**
+ * @enum device_type
+ * IPMI FRU device types
+ */
+enum device_type
+{
+    IPMI_PHYSICAL_FRU = 0x00,
+    IPMI_LOGICAL_FRU = 0x80,
+};
+
+// Discrete sensor types.
+enum ipmi_sensor_types
+{
+    IPMI_SENSOR_TEMP = 0x01,
+    IPMI_SENSOR_VOLTAGE = 0x02,
+    IPMI_SENSOR_CURRENT = 0x03,
+    IPMI_SENSOR_FAN = 0x04,
+    IPMI_SENSOR_TPM = 0xCC,
+};
+
+/** @brief Custom exception for reading sensors that are not funcitonal.
+ */
+struct SensorFunctionalError : public std::exception
+{
+    const char* what() const noexcept
+    {
+        return "Sensor not functional";
+    }
+};
+
+#define MAX_DBUS_PATH 128
+struct dbus_interface_t
+{
+    uint8_t sensornumber;
+    uint8_t sensortype;
+
+    char bus[MAX_DBUS_PATH];
+    char path[MAX_DBUS_PATH];
+    char interface[MAX_DBUS_PATH];
+};
+
+struct PlatformEventRequest
+{
+    uint8_t eventMessageRevision;
+    uint8_t sensorType;
+    uint8_t sensorNumber;
+    uint8_t eventDirectionType;
+    uint8_t data[3];
+};
+
+static constexpr const char* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
+static constexpr const char* ipmiSELAddInterface =
+    "xyz.openbmc_project.Logging.IPMI";
+static const std::string ipmiSELAddMessage = "IPMI generated SEL Entry";
+
+static constexpr int selSystemEventSizeWith3Bytes = 8;
+static constexpr int selSystemEventSizeWith2Bytes = 7;
+static constexpr int selSystemEventSizeWith1Bytes = 6;
+static constexpr int selIPMBEventSize = 7;
+static constexpr uint8_t directionMask = 0x80;
+static constexpr uint8_t byte3EnableMask = 0x30;
+static constexpr uint8_t byte2EnableMask = 0xC0;
+
+int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
+int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
+int find_openbmc_path(uint8_t, dbus_interface_t*);
+
+ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                            ipmi_request_t request, ipmi_response_t response,
+                            ipmi_data_len_t data_len, ipmi_context_t context);
+
+ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
+
+static const uint16_t FRU_RECORD_ID_START = 256;
+static const uint16_t ENTITY_RECORD_ID_START = 512;
+static const uint8_t SDR_VERSION = 0x51;
+static const uint16_t END_OF_RECORD = 0xFFFF;
+static const uint8_t LENGTH_MASK = 0x1F;
+
+/**
+ * Get SDR Info
+ */
+
+namespace get_sdr_info
+{
+namespace request
+{
+// Note: for some reason the ipmi_request_t appears to be the
+// raw value for this call.
+inline bool get_count(void* req)
+{
+    return (bool)((uint64_t)(req) & 1);
+}
+} // namespace request
+} // namespace get_sdr_info
+
+/**
+ * Get SDR
+ */
+namespace get_sdr
+{
+
+struct GetSdrReq
+{
+    uint8_t reservation_id_lsb;
+    uint8_t reservation_id_msb;
+    uint8_t record_id_lsb;
+    uint8_t record_id_msb;
+    uint8_t offset;
+    uint8_t bytes_to_read;
+} __attribute__((packed));
+
+namespace request
+{
+
+inline uint16_t get_reservation_id(GetSdrReq* req)
+{
+    return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
+};
+
+inline uint16_t get_record_id(GetSdrReq* req)
+{
+    return (req->record_id_lsb + (req->record_id_msb << 8));
+};
+
+} // namespace request
+
+// Response
+struct GetSdrResp
+{
+    uint8_t next_record_id_lsb;
+    uint8_t next_record_id_msb;
+    uint8_t record_data[64];
+} __attribute__((packed));
+
+namespace response
+{
+
+inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
+{
+    resp->next_record_id_lsb = next & 0xff;
+    resp->next_record_id_msb = (next >> 8) & 0xff;
+};
+
+} // namespace response
+
+// Record header
+struct SensorDataRecordHeader
+{
+    uint8_t record_id_lsb;
+    uint8_t record_id_msb;
+    uint8_t sdr_version;
+    uint8_t record_type;
+    uint8_t record_length; // Length not counting the header
+} __attribute__((packed));
+
+namespace header
+{
+
+inline void set_record_id(int id, SensorDataRecordHeader* hdr)
+{
+    hdr->record_id_lsb = (id & 0xFF);
+    hdr->record_id_msb = (id >> 8) & 0xFF;
+};
+
+} // namespace header
+
+enum SensorDataRecordType
+{
+    SENSOR_DATA_FULL_RECORD = 0x1,
+    SENSOR_DATA_COMPACT_RECORD = 0x2,
+    SENSOR_DATA_EVENT_RECORD = 0x3,
+    SENSOR_DATA_ENTITY_RECORD = 0x8,
+    SENSOR_DATA_FRU_RECORD = 0x11,
+    SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
+};
+
+// Record key
+struct SensorDataRecordKey
+{
+    uint8_t owner_id;
+    uint8_t owner_lun;
+    uint8_t sensor_number;
+} __attribute__((packed));
+
+/** @struct SensorDataFruRecordKey
+ *
+ *  FRU Device Locator Record(key) - SDR Type 11
+ */
+struct SensorDataFruRecordKey
+{
+    uint8_t deviceAddress;
+    uint8_t fruID;
+    uint8_t accessLun;
+    uint8_t channelNumber;
+} __attribute__((packed));
+
+/** @struct SensorDataEntityRecordKey
+ *
+ *  Entity Association Record(key) - SDR Type 8
+ */
+struct SensorDataEntityRecordKey
+{
+    uint8_t containerEntityId;
+    uint8_t containerEntityInstance;
+    uint8_t flags;
+    uint8_t entityId1;
+    uint8_t entityInstance1;
+} __attribute__((packed));
+
+namespace key
+{
+
+static constexpr uint8_t listOrRangeBit = 7;
+static constexpr uint8_t linkedBit = 6;
+
+inline void set_owner_id_ipmb(SensorDataRecordKey* key)
+{
+    key->owner_id &= ~0x01;
+};
+
+inline void set_owner_id_system_sw(SensorDataRecordKey* key)
+{
+    key->owner_id |= 0x01;
+};
+
+inline void set_owner_id_bmc(SensorDataRecordKey* key)
+{
+    key->owner_id |= 0x20;
+};
+
+inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
+{
+    key->owner_id &= 0x01;
+    key->owner_id |= addr << 1;
+};
+
+inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
+{
+    key->owner_lun &= ~0x03;
+    key->owner_lun |= (lun & 0x03);
+};
+
+inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
+{
+    key->owner_lun &= 0x0f;
+    key->owner_lun |= ((channel & 0xf) << 4);
+};
+
+inline void set_flags(bool isList, bool isLinked,
+                      SensorDataEntityRecordKey* key)
+{
+    key->flags = 0x00;
+    if (!isList)
+        key->flags |= 1 << listOrRangeBit;
+
+    if (isLinked)
+        key->flags |= 1 << linkedBit;
+};
+
+} // namespace key
+
+/** @struct GetSensorThresholdsResponse
+ *
+ *  Response structure for Get Sensor Thresholds command
+ */
+struct GetSensorThresholdsResponse
+{
+    uint8_t validMask;           //!< valid mask
+    uint8_t lowerNonCritical;    //!< lower non-critical threshold
+    uint8_t lowerCritical;       //!< lower critical threshold
+    uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
+    uint8_t upperNonCritical;    //!< upper non-critical threshold
+    uint8_t upperCritical;       //!< upper critical threshold
+    uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
+} __attribute__((packed));
+
+// Body - full record
+#define FULL_RECORD_ID_STR_MAX_LENGTH 16
+
+static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
+
+struct SensorDataFullRecordBody
+{
+    uint8_t entity_id;
+    uint8_t entity_instance;
+    uint8_t sensor_initialization;
+    uint8_t sensor_capabilities; // no macro support
+    uint8_t sensor_type;
+    uint8_t event_reading_type;
+    uint8_t supported_assertions[2];          // no macro support
+    uint8_t supported_deassertions[2];        // no macro support
+    uint8_t discrete_reading_setting_mask[2]; // no macro support
+    uint8_t sensor_units_1;
+    uint8_t sensor_units_2_base;
+    uint8_t sensor_units_3_modifier;
+    uint8_t linearization;
+    uint8_t m_lsb;
+    uint8_t m_msb_and_tolerance;
+    uint8_t b_lsb;
+    uint8_t b_msb_and_accuracy_lsb;
+    uint8_t accuracy_and_sensor_direction;
+    uint8_t r_b_exponents;
+    uint8_t analog_characteristic_flags; // no macro support
+    uint8_t nominal_reading;
+    uint8_t normal_max;
+    uint8_t normal_min;
+    uint8_t sensor_max;
+    uint8_t sensor_min;
+    uint8_t upper_nonrecoverable_threshold;
+    uint8_t upper_critical_threshold;
+    uint8_t upper_noncritical_threshold;
+    uint8_t lower_nonrecoverable_threshold;
+    uint8_t lower_critical_threshold;
+    uint8_t lower_noncritical_threshold;
+    uint8_t positive_threshold_hysteresis;
+    uint8_t negative_threshold_hysteresis;
+    uint16_t reserved;
+    uint8_t oem_reserved;
+    uint8_t id_string_info;
+    char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
+} __attribute__((packed));
+
+/** @struct SensorDataCompactRecord
+ *
+ *  Compact Sensor Record(body) - SDR Type 2
+ */
+struct SensorDataCompactRecordBody
+{
+    uint8_t entity_id;
+    uint8_t entity_instance;
+    uint8_t sensor_initialization;
+    uint8_t sensor_capabilities; // no macro support
+    uint8_t sensor_type;
+    uint8_t event_reading_type;
+    uint8_t supported_assertions[2];          // no macro support
+    uint8_t supported_deassertions[2];        // no macro support
+    uint8_t discrete_reading_setting_mask[2]; // no macro support
+    uint8_t sensor_units_1;
+    uint8_t sensor_units_2_base;
+    uint8_t sensor_units_3_modifier;
+    uint8_t record_sharing[2];
+    uint8_t positive_threshold_hysteresis;
+    uint8_t negative_threshold_hysteresis;
+    uint8_t reserved[3];
+    uint8_t oem_reserved;
+    uint8_t id_string_info;
+    char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
+} __attribute__((packed));
+
+/** @struct SensorDataEventRecord
+ *
+ *  Event Only Sensor Record(body) - SDR Type 3
+ */
+struct SensorDataEventRecordBody
+{
+    uint8_t entity_id;
+    uint8_t entity_instance;
+    uint8_t sensor_type;
+    uint8_t event_reading_type;
+    uint8_t sensor_record_sharing_1;
+    uint8_t sensor_record_sharing_2;
+    uint8_t reserved;
+    uint8_t oem_reserved;
+    uint8_t id_string_info;
+    char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
+} __attribute__((packed));
+
+/** @struct SensorDataFruRecordBody
+ *
+ *  FRU Device Locator Record(body) - SDR Type 11
+ */
+struct SensorDataFruRecordBody
+{
+    uint8_t reserved;
+    uint8_t deviceType;
+    uint8_t deviceTypeModifier;
+    uint8_t entityID;
+    uint8_t entityInstance;
+    uint8_t oem;
+    uint8_t deviceIDLen;
+    char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
+} __attribute__((packed));
+
+/** @struct SensorDataEntityRecordBody
+ *
+ *  Entity Association Record(body) - SDR Type 8
+ */
+struct SensorDataEntityRecordBody
+{
+    uint8_t entityId2;
+    uint8_t entityInstance2;
+    uint8_t entityId3;
+    uint8_t entityInstance3;
+    uint8_t entityId4;
+    uint8_t entityInstance4;
+} __attribute__((packed));
+
+namespace body
+{
+
+inline void set_entity_instance_number(uint8_t n,
+                                       SensorDataFullRecordBody* body)
+{
+    body->entity_instance &= 1 << 7;
+    body->entity_instance |= (n & ~(1 << 7));
+};
+inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
+{
+    body->entity_instance &= ~(1 << 7);
+};
+inline void set_entity_logical_container(SensorDataFullRecordBody* body)
+{
+    body->entity_instance |= 1 << 7;
+};
+
+inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 0;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 0);
+    };
+};
+inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 1;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 1);
+    }
+};
+inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 2;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 2);
+    }
+};
+inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 3;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 3);
+    }
+};
+inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 4;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 4);
+    }
+};
+inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 5;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 5);
+    }
+};
+inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 6;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 6);
+    }
+};
+inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
+{
+    if (enabled)
+    {
+        body->sensor_initialization |= 1 << 7;
+    }
+    else
+    {
+        body->sensor_initialization &= ~(1 << 7);
+    }
+};
+
+inline void set_percentage(SensorDataFullRecordBody* body)
+{
+    body->sensor_units_1 |= 1 << 0;
+};
+inline void unset_percentage(SensorDataFullRecordBody* body)
+{
+    body->sensor_units_1 &= ~(1 << 0);
+};
+inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
+{
+    body->sensor_units_1 &= ~(3 << 1);
+    body->sensor_units_1 |= (op & 0x3) << 1;
+};
+inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
+{
+    body->sensor_units_1 &= ~(7 << 3);
+    body->sensor_units_1 |= (unit & 0x7) << 3;
+};
+inline void set_analog_data_format(uint8_t format,
+                                   SensorDataFullRecordBody* body)
+{
+    body->sensor_units_1 &= ~(3 << 6);
+    body->sensor_units_1 |= (format & 0x3) << 6;
+};
+
+inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
+{
+    body->m_lsb = m & 0xff;
+    body->m_msb_and_tolerance &= ~(3 << 6);
+    body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
+};
+inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
+{
+    body->m_msb_and_tolerance &= ~0x3f;
+    body->m_msb_and_tolerance |= tol & 0x3f;
+};
+
+inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
+{
+    body->b_lsb = b & 0xff;
+    body->b_msb_and_accuracy_lsb &= ~(3 << 6);
+    body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
+};
+inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
+{
+    // bottom 6 bits
+    body->b_msb_and_accuracy_lsb &= ~0x3f;
+    body->b_msb_and_accuracy_lsb |= acc & 0x3f;
+    // top 4 bits
+    body->accuracy_and_sensor_direction &= 0x0f;
+    body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
+};
+inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
+{
+    body->accuracy_and_sensor_direction &= ~(3 << 2);
+    body->accuracy_and_sensor_direction |= (exp & 3) << 2;
+};
+inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
+{
+    body->accuracy_and_sensor_direction &= ~(3 << 0);
+    body->accuracy_and_sensor_direction |= (dir & 3);
+};
+
+inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
+{
+    body->r_b_exponents &= 0xf0;
+    body->r_b_exponents |= exp & 0x0f;
+};
+inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
+{
+    body->r_b_exponents &= 0x0f;
+    body->r_b_exponents |= (exp & 0x0f) << 4;
+};
+
+inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
+{
+    body->id_string_info &= ~(0x1f);
+    body->id_string_info |= len & 0x1f;
+};
+inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body)
+{
+    body->id_string_info &= ~(0x1f);
+    body->id_string_info |= len & 0x1f;
+};
+inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
+{
+    return body->id_string_info & 0x1f;
+};
+inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
+{
+    body->id_string_info &= ~(3 << 6);
+    body->id_string_info |= (type & 0x3) << 6;
+};
+inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body)
+{
+    body->id_string_info &= ~(3 << 6);
+    body->id_string_info |= (type & 0x3) << 6;
+};
+
+inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
+{
+    body->deviceIDLen &= ~(LENGTH_MASK);
+    body->deviceIDLen |= len & LENGTH_MASK;
+};
+
+inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
+{
+    return body->deviceIDLen & LENGTH_MASK;
+};
+
+inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
+{
+    body->discrete_reading_setting_mask[1] = mask & 0x3F;
+}
+
+} // namespace body
+
+// More types contained in section 43.17 Sensor Unit Type Codes,
+// IPMI spec v2 rev 1.1
+enum SensorUnitTypeCodes
+{
+    SENSOR_UNIT_UNSPECIFIED = 0,
+    SENSOR_UNIT_DEGREES_C = 1,
+    SENSOR_UNIT_VOLTS = 4,
+    SENSOR_UNIT_AMPERES = 5,
+    SENSOR_UNIT_WATTS = 6,
+    SENSOR_UNIT_JOULES = 7,
+    SENSOR_UNIT_RPM = 18,
+    SENSOR_UNIT_METERS = 34,
+    SENSOR_UNIT_REVOLUTIONS = 41,
+};
+
+struct SensorDataFullRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataRecordKey key;
+    SensorDataFullRecordBody body;
+} __attribute__((packed));
+
+/** @struct SensorDataComapactRecord
+ *
+ *  Compact Sensor Record - SDR Type 2
+ */
+struct SensorDataCompactRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataRecordKey key;
+    SensorDataCompactRecordBody body;
+} __attribute__((packed));
+
+/** @struct SensorDataEventRecord
+ *
+ *  Event Only Sensor Record - SDR Type 3
+ */
+struct SensorDataEventRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataRecordKey key;
+    SensorDataEventRecordBody body;
+} __attribute__((packed));
+
+/** @struct SensorDataFruRecord
+ *
+ *  FRU Device Locator Record - SDR Type 11
+ */
+struct SensorDataFruRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataFruRecordKey key;
+    SensorDataFruRecordBody body;
+} __attribute__((packed));
+
+/** @struct SensorDataEntityRecord
+ *
+ *  Entity Association Record - SDR Type 8
+ */
+struct SensorDataEntityRecord
+{
+    SensorDataRecordHeader header;
+    SensorDataEntityRecordKey key;
+    SensorDataEntityRecordBody body;
+} __attribute__((packed));
+
+} // namespace get_sdr
+
+namespace ipmi
+{
+
+namespace sensor
+{
+
+/**
+ * @brief Map offset to the corresponding bit in the assertion byte.
+ *
+ * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
+ * byte and offsets 8-14 in the second byte.
+ *
+ * @param[in] offset - offset number.
+ * @param[in/out] resp - get sensor reading response.
+ */
+inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp)
+{
+    if (offset > 7)
+    {
+        resp->discreteReadingSensorStates |= 1 << (offset - 8);
+    }
+    else
+    {
+        resp->thresholdLevelsStates |= 1 << offset;
+    }
+}
+
+/**
+ * @brief Set the reading field in the response.
+ *
+ * @param[in] offset - offset number.
+ * @param[in/out] resp - get sensor reading response.
+ */
+inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp)
+{
+    resp->reading = value;
+}
+
+/**
+ * @brief Map the value to the assertion bytes. The assertion states are stored
+ *        in 2 bytes.
+ *
+ * @param[in] value - value to mapped to the assertion byte.
+ * @param[in/out] resp - get sensor reading response.
+ */
+inline void setAssertionBytes(uint16_t value,
+                              ipmi::sensor::GetSensorResponse* resp)
+{
+    resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
+    resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
+}
+
+/**
+ * @brief Set the scanning enabled bit in the response.
+ *
+ * @param[in/out] resp - get sensor reading response.
+ */
+inline void enableScanning(ipmi::sensor::GetSensorResponse* resp)
+{
+    resp->readingOrStateUnavailable = false;
+    resp->scanningEnabled = true;
+    resp->allEventMessagesEnabled = false;
+}
+
+} // namespace sensor
+
+} // namespace ipmi
diff --git a/settings.cpp b/settings.cpp
new file mode 100644
index 0000000..4564fa4
--- /dev/null
+++ b/settings.cpp
@@ -0,0 +1,74 @@
+#include "settings.hpp"
+
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace settings
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+
+constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
+constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
+constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
+
+Objects::Objects(sdbusplus::bus_t& bus, const std::vector<Interface>& filter) :
+    bus(bus)
+{
+    ipmi::ObjectTree objectTree;
+    try
+    {
+        objectTree = ipmi::getSubTree(bus, filter);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Failed to call the getSubTree method: {ERROR}", "ERROR", e);
+        elog<InternalFailure>();
+    }
+
+    for (auto& iter : objectTree)
+    {
+        const auto& path = iter.first;
+        for (auto& interface : iter.second.begin()->second)
+        {
+            auto found = map.find(interface);
+            if (map.end() != found)
+            {
+                auto& paths = found->second;
+                paths.push_back(path);
+            }
+            else
+            {
+                map.emplace(std::move(interface), std::vector<Path>({path}));
+            }
+        }
+    }
+}
+
+Service Objects::service(const Path& path, const Interface& interface) const
+{
+    using Interfaces = std::vector<Interface>;
+    auto mapperCall =
+        bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetObject");
+    mapperCall.append(path);
+    mapperCall.append(Interfaces({interface}));
+
+    std::map<Service, Interfaces> result;
+    try
+    {
+        auto response = bus.call(mapperCall);
+        response.read(result);
+        return result.begin()->first;
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Invalid response from mapper: {ERROR}", "ERROR", e);
+        elog<InternalFailure>();
+    }
+}
+
+} // namespace settings
diff --git a/settings.hpp b/settings.hpp
new file mode 100644
index 0000000..a3505c3
--- /dev/null
+++ b/settings.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+
+#include <string>
+#include <tuple>
+
+namespace settings
+{
+
+using Path = std::string;
+using Service = std::string;
+using Interface = std::string;
+
+/** @class Objects
+ *  @brief Fetch paths of settings d-bus objects of interest, upon construction
+ */
+struct Objects
+{
+  public:
+    /** @brief Constructor - fetch settings objects
+     *
+     * @param[in] bus - The Dbus bus object
+     * @param[in] filter - A vector of settings interfaces the caller is
+     *            interested in.
+     */
+    Objects(sdbusplus::bus_t& bus, const std::vector<Interface>& filter);
+    Objects(const Objects&) = default;
+    Objects& operator=(const Objects&) = delete;
+    Objects(Objects&&) = delete;
+    Objects& operator=(Objects&&) = delete;
+    ~Objects() = default;
+
+    /** @brief Fetch d-bus service, given a path and an interface. The
+     *         service can't be cached because mapper returns unique
+     *         service names.
+     *
+     * @param[in] path - The Dbus object
+     * @param[in] interface - The Dbus interface
+     *
+     * @return std::string - the dbus service
+     */
+    Service service(const Path& path, const Interface& interface) const;
+
+    /** @brief map of settings objects */
+    std::map<Interface, std::vector<Path>> map;
+
+    /** @brief The Dbus bus object */
+    sdbusplus::bus_t& bus;
+};
+
+} // namespace settings
diff --git a/softoff/mainapp.cpp b/softoff/mainapp.cpp
new file mode 100644
index 0000000..0791615
--- /dev/null
+++ b/softoff/mainapp.cpp
@@ -0,0 +1,82 @@
+/**
+ * Copyright © 2016 IBM 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 "config.h"
+
+#include "softoff.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/exception.hpp>
+#include <xyz/openbmc_project/State/Host/error.hpp>
+
+// Return -1 on any errors to ensure we follow the calling targets OnFailure=
+// path
+int main(int, char**)
+{
+    using namespace phosphor::logging;
+
+    // Get a handle to system dbus.
+    auto bus = sdbusplus::bus::new_default();
+
+    // Add systemd object manager.
+    sdbusplus::server::manager_t(bus, SOFTOFF_OBJPATH);
+
+    // Get default event loop
+    auto event = sdeventplus::Event::get_default();
+
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+
+    // Claim the bus. Delaying it until sending SMS_ATN may result
+    // in a race condition between this available and IPMI trying to send
+    // message as a response to ack from host.
+    bus.request_name(SOFTOFF_BUSNAME);
+
+    // Create the SoftPowerOff object.
+    phosphor::ipmi::SoftPowerOff powerObj(bus, event.get(), SOFTOFF_OBJPATH);
+
+    // Wait for client requests until this application has processed
+    // at least one successful SoftPowerOff or we timed out
+    while (!powerObj.isCompleted() && !powerObj.isTimerExpired())
+    {
+        try
+        {
+            event.run(std::nullopt);
+        }
+        catch (const sdeventplus::SdEventError& e)
+        {
+            lg2::error("Failure in processing request: {ERROR}", "ERROR", e);
+            return 1;
+        }
+    }
+
+    // Log an error if we timed out after getting Ack for SMS_ATN and before
+    // getting the Host Shutdown response
+    if (powerObj.isTimerExpired() &&
+        (powerObj.responseReceived() ==
+         phosphor::ipmi::Base::SoftPowerOff::HostResponse::SoftOffReceived))
+    {
+        using error =
+            sdbusplus::error::xyz::openbmc_project::state::host::SoftOffTimeout;
+        using errorMetadata = xyz::openbmc_project::state::host::SoftOffTimeout;
+        report<error>(prev_entry<errorMetadata::TIMEOUT_IN_MSEC>());
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/softoff/meson.build b/softoff/meson.build
new file mode 100644
index 0000000..a723c51
--- /dev/null
+++ b/softoff/meson.build
@@ -0,0 +1,34 @@
+softpower_pre = [
+    boost,
+    ipmid_dep,
+    libsystemd_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+    sdeventplus_dep,
+    softoff_dbus,
+]
+
+softpower_lib = static_library(
+    'softpower_lib',
+    'softoff.cpp',
+    conf_h,
+    dependencies: softpower_pre,
+    include_directories: root_inc,
+)
+
+softpower_dep = declare_dependency(
+    dependencies: softpower_pre,
+    include_directories: root_inc,
+    link_with: softpower_lib,
+)
+
+executable(
+    'phosphor-softpoweroff',
+    'mainapp.cpp',
+    implicit_include_directories: false,
+    dependencies: softpower_dep,
+    include_directories: root_inc,
+    install: true,
+    install_dir: get_option('bindir'),
+)
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp
new file mode 100644
index 0000000..96695b9
--- /dev/null
+++ b/softoff/softoff.cpp
@@ -0,0 +1,136 @@
+/**
+ * Copyright © 2016 IBM 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 "config.h"
+
+#include "softoff.hpp"
+
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Control/Host/server.hpp>
+
+#include <chrono>
+namespace phosphor
+{
+namespace ipmi
+{
+
+using namespace sdbusplus::server::xyz::openbmc_project::control;
+
+void SoftPowerOff::sendHostShutDownCmd()
+{
+    auto ctrlHostPath =
+        std::string{CONTROL_HOST_OBJ_MGR} + '/' + HOST_NAME + '0';
+    auto host = ::ipmi::getService(this->bus, CONTROL_HOST_BUSNAME,
+                                   ctrlHostPath.c_str());
+
+    auto method = bus.new_method_call(host.c_str(), ctrlHostPath.c_str(),
+                                      CONTROL_HOST_BUSNAME, "Execute");
+
+    method.append(convertForMessage(Host::Command::SoftOff).c_str());
+    try
+    {
+        auto reply = bus.call(method);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in call to control host Execute: {ERROR}", "ERROR",
+                   e);
+        // TODO openbmc/openbmc#851 - Once available, throw returned error
+        throw std::runtime_error("Error in call to control host Execute");
+    }
+}
+
+// Function called on host control signals
+void SoftPowerOff::hostControlEvent(sdbusplus::message_t& msg)
+{
+    std::string cmdCompleted{};
+    std::string cmdStatus{};
+
+    msg.read(cmdCompleted, cmdStatus);
+
+    lg2::debug(
+        "Host control signal values, command: {COMMAND}, status:{STATUS}",
+        "COMMAND", cmdCompleted, "STATUS", cmdStatus);
+
+    if (Host::convertResultFromString(cmdStatus) == Host::Result::Success)
+    {
+        // Set our internal property indicating we got host attention
+        sdbusplus::server::xyz::openbmc_project::ipmi::internal::SoftPowerOff::
+            responseReceived(HostResponse::SoftOffReceived);
+
+        // Start timer for host shutdown
+        using namespace std::chrono;
+        auto time = duration_cast<microseconds>(
+            seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS));
+        auto r = startTimer(time);
+        if (r < 0)
+        {
+            lg2::error(
+                "Failure to start Host shutdown wait timer, ERRNO: {ERRNO}",
+                "ERRNO", lg2::hex, -r);
+        }
+        else
+        {
+            lg2::info("Timer started waiting for host to shutdown, "
+                      "TIMEOUT_IN_MSEC: {TIMEOUT_IN_MSEC}",
+                      "TIMEOUT_IN_MSEC",
+                      (duration_cast<milliseconds>(
+                           seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)))
+                          .count());
+        }
+    }
+    else
+    {
+        // An error on the initial attention is not considered an error, just
+        // exit normally and allow remaining shutdown targets to run
+        lg2::info("Timeout on host attention, continue with power down");
+        completed = true;
+    }
+    return;
+}
+
+// Starts a timer
+int SoftPowerOff::startTimer(const std::chrono::microseconds& usec)
+{
+    return timer.start(usec);
+}
+
+// Host Response handler
+auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse
+{
+    using namespace std::chrono;
+
+    if (response == HostResponse::HostShutdown)
+    {
+        // Disable the timer since Host has quiesced and we are
+        // done with soft power off part
+        auto r = timer.stop();
+        if (r < 0)
+        {
+            lg2::error("Failure to STOP the timer, ERRNO: {ERRNO}", "ERRNO",
+                       lg2::hex, -r);
+        }
+
+        // This marks the completion of soft power off sequence.
+        completed = true;
+    }
+
+    return sdbusplus::server::xyz::openbmc_project::ipmi::internal::
+        SoftPowerOff::responseReceived(response);
+}
+
+} // namespace ipmi
+} // namespace phosphor
diff --git a/softoff/softoff.hpp b/softoff/softoff.hpp
new file mode 100644
index 0000000..14742e1
--- /dev/null
+++ b/softoff/softoff.hpp
@@ -0,0 +1,145 @@
+#pragma once
+
+#include "config.h"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <sdbusplus/timer.hpp>
+#include <xyz/openbmc_project/Control/Host/server.hpp>
+#include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>
+
+#include <functional>
+namespace phosphor
+{
+namespace ipmi
+{
+
+namespace Base = sdbusplus::server::xyz::openbmc_project::ipmi::internal;
+using namespace sdbusplus::server::xyz::openbmc_project::control;
+
+namespace sdbusRule = sdbusplus::bus::match::rules;
+
+namespace
+{
+using SoftPowerOffInherit = sdbusplus::server::object_t<Base::SoftPowerOff>;
+}
+
+/** @class SoftPowerOff
+ *  @brief Responsible for coordinating Host SoftPowerOff operation
+ */
+class SoftPowerOff : public SoftPowerOffInherit
+{
+  public:
+    /** @brief Constructs SoftPowerOff object.
+     *
+     *  @param[in] bus       - system dbus handler
+     *  @param[in] event     - sd_event handler
+     *  @param[in] objPath   - The Dbus path hosting SoftPowerOff function
+     */
+    SoftPowerOff(sdbusplus::bus_t& bus, sd_event* event, const char* objPath) :
+        SoftPowerOffInherit(bus, objPath,
+                            SoftPowerOffInherit::action::defer_emit),
+        bus(bus), timer(event),
+        hostControlSignal(
+            bus,
+            sdbusRule::type::signal() + sdbusRule::member("CommandComplete") +
+                sdbusRule::path("/xyz/openbmc_project/control/host0") +
+                sdbusRule::interface(CONTROL_HOST_BUSNAME) +
+                sdbusRule::argN(0, convertForMessage(Host::Command::SoftOff)),
+            std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), this,
+                      std::placeholders::_1))
+    {
+        // Need to announce since we may get the response
+        // very quickly on host shutdown command
+        emit_object_added();
+
+        // The whole purpose of this application is to send a host shutdown
+        // command and watch for the soft power off to go through. We need
+        // the interface added signal emitted before we send the shutdown
+        // command just to attend to lightning fast response from host
+        sendHostShutDownCmd();
+    }
+
+    /** @brief Tells if the objective of this application is completed */
+    inline auto isCompleted()
+    {
+        return completed;
+    }
+
+    /** @brief Tells if the referenced timer is expired or not */
+    inline auto isTimerExpired()
+    {
+        return timer.isExpired();
+    }
+
+    /** @brief overloaded property setter function
+     *
+     *  @param[in] value - One of SoftOffReceived / HostShutdown
+     *
+     *  @return Success or exception thrown
+     */
+    HostResponse responseReceived(HostResponse value) override;
+
+    /** @brief Using the base class's getter method */
+    using Base::SoftPowerOff::responseReceived;
+
+    /** @brief Calls to start a timer
+     *
+     *  @param[in] usec - Time in microseconds
+     *
+     *  @return Success or exception thrown
+     */
+    int startTimer(const std::chrono::microseconds& usec);
+
+  private:
+    // Need this to send SMS_ATTN
+    // TODO : Switch over to using mapper service in a different patch
+    static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi";
+    static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1";
+    static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi";
+
+    /* @brief sdbusplus handle */
+    sdbusplus::bus_t& bus;
+
+    /** @brief Reference to Timer object */
+    sdbusplus::Timer timer;
+
+    /** @brief Marks the end of life of this application.
+     *
+     *  This is set to true if host gives appropriate responses
+     *  for the sequence of commands.
+     */
+    bool completed = false;
+
+    /** @brief Subscribe to host control signals
+     *
+     *  Protocol is to send the host power off request to the host
+     *  control interface and then wait for a signal indicating pass/fail
+     **/
+    sdbusplus::bus::match_t hostControlSignal;
+
+    /** @brief Sends host control command to tell host to shut down
+     *
+     *  After sending the command, wait for a signal indicating the status
+     *  of the command.
+     *
+     *  After receiving the initial response, start a timer for 30 minutes
+     *  to let host do a clean shutdown of partitions. When the response is
+     *  received from the host, it indicates that BMC can do a power off.
+     *  If BMC fails to get any response, then a hard power off would
+     *  be forced.
+     *
+     *  @return - Does not return anything. Error will result in exception
+     *            being thrown
+     */
+    void sendHostShutDownCmd();
+
+    /** @brief Callback function on host control signals
+     *
+     * @param[in]  msg       - Data associated with subscribed signal
+     *
+     */
+    void hostControlEvent(sdbusplus::message_t& msg);
+};
+} // namespace ipmi
+} // namespace phosphor
diff --git a/storageaddsel.cpp b/storageaddsel.cpp
new file mode 100644
index 0000000..2b9866f
--- /dev/null
+++ b/storageaddsel.cpp
@@ -0,0 +1,69 @@
+#include "error-HostEvent.hpp"
+#include "sensorhandler.hpp"
+
+#include <systemd/sd-bus.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <vector>
+
+using namespace std;
+using namespace phosphor::logging;
+using namespace sdbusplus::server::xyz::openbmc_project::logging;
+
+std::string readESEL(const char* fileName)
+{
+    std::string content;
+    std::ifstream handle(fileName);
+
+    if (handle.fail())
+    {
+        lg2::error("Failed to open eSEL, file name: {FILENAME}", "FILENAME",
+                   fileName);
+        return content;
+    }
+
+    handle.seekg(0, std::ios::end);
+    content.resize(handle.tellg());
+    handle.seekg(0, std::ios::beg);
+    handle.read(&content[0], content.size());
+    handle.close();
+
+    return content;
+}
+
+void createProcedureLogEntry(uint8_t procedureNum)
+{
+    // Read the eSEL data from the file.
+    static constexpr auto eSELFile = "/tmp/esel";
+    auto eSELData = readESEL(eSELFile);
+
+    // Each byte in eSEL is formatted as %02x with a space between bytes and
+    // insert '/0' at the end of the character array.
+    static constexpr auto byteSeparator = 3;
+    std::unique_ptr<char[]> data(
+        new char[(eSELData.size() * byteSeparator) + 1]());
+
+    for (size_t i = 0; i < eSELData.size(); i++)
+    {
+        sprintf(&data[i * byteSeparator], "%02x ", eSELData[i]);
+    }
+    data[eSELData.size() * byteSeparator] = '\0';
+
+    using error = sdbusplus::error::org::open_power::host::MaintenanceProcedure;
+    using metadata = org::open_power::host::MaintenanceProcedure;
+
+    report<error>(metadata::ESEL(data.get()),
+                  metadata::PROCEDURE(static_cast<uint32_t>(procedureNum)));
+}
diff --git a/storageaddsel.hpp b/storageaddsel.hpp
new file mode 100644
index 0000000..9183472
--- /dev/null
+++ b/storageaddsel.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <string>
+
+/** @brief Read eSEL data into a string
+ *
+ *  @param[in] filename - filename of file containing eSEL
+ *
+ *  @return On success return the eSEL data
+ */
+std::string readESEL(const char* filename);
+
+/** @brief Create a log entry with maintenance procedure
+ *
+ *  @param[in] procedureNum - procedure number associated with the log entry
+ */
+void createProcedureLogEntry(uint8_t procedureNum);
diff --git a/storagehandler.cpp b/storagehandler.cpp
new file mode 100644
index 0000000..d85673f
--- /dev/null
+++ b/storagehandler.cpp
@@ -0,0 +1,961 @@
+#include "config.h"
+
+#include "fruread.hpp"
+#include "read_fru_data.hpp"
+#include "selutility.hpp"
+#include "sensorhandler.hpp"
+#include "storageaddsel.hpp"
+
+#include <arpa/inet.h>
+#include <systemd/sd-bus.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/entity_map_json.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Logging/SEL/error.hpp>
+
+#include <algorithm>
+#include <chrono>
+#include <cstdio>
+#include <cstring>
+#include <filesystem>
+#include <optional>
+#include <string>
+#include <variant>
+
+void registerNetFnStorageFunctions() __attribute__((constructor));
+
+unsigned int g_sel_time = 0xFFFFFFFF;
+namespace ipmi
+{
+namespace sensor
+{
+extern const IdInfoMap sensors;
+} // namespace sensor
+} // namespace ipmi
+extern const ipmi::sensor::InvObjectIDMap invSensors;
+extern const FruMap frus;
+constexpr uint8_t eventDataSize = 3;
+namespace
+{
+constexpr auto SystemdTimeService = "org.freedesktop.timedate1";
+constexpr auto SystemdTimePath = "/org/freedesktop/timedate1";
+constexpr auto SystemdTimeInterface = "org.freedesktop.timedate1";
+
+constexpr auto TIME_INTERFACE = "xyz.openbmc_project.Time.EpochTime";
+constexpr auto BMC_TIME_PATH = "/xyz/openbmc_project/time/bmc";
+constexpr auto DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
+constexpr auto PROPERTY_ELAPSED = "Elapsed";
+} // namespace
+
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+using namespace phosphor::logging;
+using namespace ipmi::fru;
+using namespace xyz::openbmc_project::logging::sel;
+using SELCreated =
+    sdbusplus::error::xyz::openbmc_project::logging::sel::Created;
+
+using SELRecordID = uint16_t;
+using SELEntry = ipmi::sel::SELEventRecordFormat;
+using SELCacheMap = std::map<SELRecordID, SELEntry>;
+
+SELCacheMap selCacheMap __attribute__((init_priority(101)));
+bool selCacheMapInitialized;
+std::unique_ptr<sdbusplus::bus::match_t> selAddedMatch
+    __attribute__((init_priority(101)));
+std::unique_ptr<sdbusplus::bus::match_t> selRemovedMatch
+    __attribute__((init_priority(101)));
+std::unique_ptr<sdbusplus::bus::match_t> selUpdatedMatch
+    __attribute__((init_priority(101)));
+
+static inline uint16_t getLoggingId(const std::string& p)
+{
+    namespace fs = std::filesystem;
+    fs::path entryPath(p);
+    return std::stoul(entryPath.filename().string());
+}
+
+static inline std::string getLoggingObjPath(uint16_t id)
+{
+    return std::string(ipmi::sel::logBasePath) + "/" + std::to_string(id);
+}
+
+std::optional<std::pair<uint16_t, SELEntry>> parseLoggingEntry(
+    const std::string& p)
+{
+    try
+    {
+        auto id = getLoggingId(p);
+        ipmi::sel::GetSELEntryResponse record{};
+        record = ipmi::sel::convertLogEntrytoSEL(p);
+        return std::pair<uint16_t, SELEntry>({id, std::move(record.event)});
+    }
+    catch (const std::exception& e)
+    {
+        fprintf(stderr, "Failed to convert %s to SEL: %s\n", p.c_str(),
+                e.what());
+    }
+    return std::nullopt;
+}
+
+static void selAddedCallback(sdbusplus::message_t& m)
+{
+    sdbusplus::message::object_path objPath;
+    try
+    {
+        m.read(objPath);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to read object path");
+        return;
+    }
+    std::string p = objPath;
+    auto entry = parseLoggingEntry(p);
+    if (entry)
+    {
+        selCacheMap.insert(std::move(*entry));
+    }
+}
+
+static void selRemovedCallback(sdbusplus::message_t& m)
+{
+    sdbusplus::message::object_path objPath;
+    try
+    {
+        m.read(objPath);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to read object path");
+    }
+    try
+    {
+        std::string p = objPath;
+        selCacheMap.erase(getLoggingId(p));
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Invalid logging entry ID");
+    }
+}
+
+static void selUpdatedCallback(sdbusplus::message_t& m)
+{
+    std::string p = m.get_path();
+    auto entry = parseLoggingEntry(p);
+    if (entry)
+    {
+        selCacheMap.insert_or_assign(entry->first, std::move(entry->second));
+    }
+}
+
+void registerSelCallbackHandler()
+{
+    using namespace sdbusplus::bus::match::rules;
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    if (!selAddedMatch)
+    {
+        selAddedMatch = std::make_unique<sdbusplus::bus::match_t>(
+            bus, interfacesAdded(ipmi::sel::logWatchPath),
+            std::bind(selAddedCallback, std::placeholders::_1));
+    }
+    if (!selRemovedMatch)
+    {
+        selRemovedMatch = std::make_unique<sdbusplus::bus::match_t>(
+            bus, interfacesRemoved(ipmi::sel::logWatchPath),
+            std::bind(selRemovedCallback, std::placeholders::_1));
+    }
+    if (!selUpdatedMatch)
+    {
+        selUpdatedMatch = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            type::signal() + member("PropertiesChanged"s) +
+                interface("org.freedesktop.DBus.Properties"s) +
+                argN(0, ipmi::sel::logEntryIntf),
+            std::bind(selUpdatedCallback, std::placeholders::_1));
+    }
+}
+
+void initSELCache()
+{
+    registerSelCallbackHandler();
+    ipmi::sel::ObjectPaths paths;
+    try
+    {
+        ipmi::sel::readLoggingObjectPaths(paths);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to get logging object paths");
+        return;
+    }
+    for (const auto& p : paths)
+    {
+        auto entry = parseLoggingEntry(p);
+        if (entry)
+        {
+            selCacheMap.insert(std::move(*entry));
+        }
+    }
+    selCacheMapInitialized = true;
+}
+
+/**
+ * @enum Device access mode
+ */
+enum class AccessMode
+{
+    bytes, ///< Device is accessed by bytes
+    words  ///< Device is accessed by words
+};
+
+/** @brief implements the get SEL Info command
+ *  @returns IPMI completion code plus response data
+ *   - selVersion - SEL revision
+ *   - entries    - Number of log entries in SEL.
+ *   - freeSpace  - Free Space in bytes.
+ *   - addTimeStamp - Most recent addition timestamp
+ *   - eraseTimeStamp - Most recent erase timestamp
+ *   - operationSupport - Reserve & Delete SEL operations supported
+ */
+
+ipmi::RspType<uint8_t,  // SEL revision.
+              uint16_t, // number of log entries in SEL.
+              uint16_t, // free Space in bytes.
+              uint32_t, // most recent addition timestamp
+              uint32_t, // most recent erase timestamp.
+
+              bool,     // SEL allocation info supported
+              bool,     // reserve SEL supported
+              bool,     // partial Add SEL Entry supported
+              bool,     // delete SEL supported
+              uint3_t,  // reserved
+              bool      // overflow flag
+              >
+    ipmiStorageGetSelInfo()
+{
+    uint16_t entries = 0;
+    // Most recent addition timestamp.
+    uint32_t addTimeStamp = ipmi::sel::invalidTimeStamp;
+
+    if (!selCacheMapInitialized)
+    {
+        // In case the initSELCache() fails, try it again
+        initSELCache();
+    }
+    if (!selCacheMap.empty())
+    {
+        entries = static_cast<uint16_t>(selCacheMap.size());
+
+        try
+        {
+            auto objPath = getLoggingObjPath(selCacheMap.rbegin()->first);
+            addTimeStamp = static_cast<uint32_t>(
+                (ipmi::sel::getEntryTimeStamp(objPath).count()));
+        }
+        catch (const InternalFailure& e)
+        {}
+        catch (const std::runtime_error& e)
+        {
+            lg2::error("runtime error: {ERROR}", "ERROR", e);
+        }
+    }
+
+    constexpr uint8_t selVersion = ipmi::sel::selVersion;
+    constexpr uint16_t freeSpace = 0xFFFF;
+    constexpr uint32_t eraseTimeStamp = ipmi::sel::invalidTimeStamp;
+    constexpr uint3_t reserved{0};
+
+    return ipmi::responseSuccess(
+        selVersion, entries, freeSpace, addTimeStamp, eraseTimeStamp,
+        ipmi::sel::operationSupport::getSelAllocationInfo,
+        ipmi::sel::operationSupport::reserveSel,
+        ipmi::sel::operationSupport::partialAddSelEntry,
+        ipmi::sel::operationSupport::deleteSel, reserved,
+        ipmi::sel::operationSupport::overflow);
+}
+
+ipmi_ret_t getSELEntry(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
+                       ipmi_response_t response, ipmi_data_len_t data_len,
+                       ipmi_context_t)
+{
+    if (*data_len != sizeof(ipmi::sel::GetSELEntryRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto requestData =
+        reinterpret_cast<const ipmi::sel::GetSELEntryRequest*>(request);
+
+    if (requestData->reservationID != 0)
+    {
+        if (!checkSELReservation(requestData->reservationID))
+        {
+            *data_len = 0;
+            return IPMI_CC_INVALID_RESERVATION_ID;
+        }
+    }
+
+    if (!selCacheMapInitialized)
+    {
+        // In case the initSELCache() fails, try it again
+        initSELCache();
+    }
+
+    if (selCacheMap.empty())
+    {
+        *data_len = 0;
+        return IPMI_CC_SENSOR_INVALID;
+    }
+
+    SELCacheMap::const_iterator iter;
+
+    // Check for the requested SEL Entry.
+    if (requestData->selRecordID == ipmi::sel::firstEntry)
+    {
+        iter = selCacheMap.begin();
+    }
+    else if (requestData->selRecordID == ipmi::sel::lastEntry)
+    {
+        if (selCacheMap.size() > 1)
+        {
+            iter = selCacheMap.end();
+            --iter;
+        }
+        else
+        {
+            // Only one entry exists, return the first
+            iter = selCacheMap.begin();
+        }
+    }
+    else
+    {
+        iter = selCacheMap.find(requestData->selRecordID);
+        if (iter == selCacheMap.end())
+        {
+            *data_len = 0;
+            return IPMI_CC_SENSOR_INVALID;
+        }
+    }
+
+    ipmi::sel::GetSELEntryResponse record{0, iter->second};
+    // Identify the next SEL record ID
+    ++iter;
+    if (iter == selCacheMap.end())
+    {
+        record.nextRecordID = ipmi::sel::lastEntry;
+    }
+    else
+    {
+        record.nextRecordID = iter->first;
+    }
+
+    if (requestData->readLength == ipmi::sel::entireRecord)
+    {
+        std::memcpy(response, &record, sizeof(record));
+        *data_len = sizeof(record);
+    }
+    else
+    {
+        if (requestData->offset >= ipmi::sel::selRecordSize ||
+            requestData->readLength > ipmi::sel::selRecordSize)
+        {
+            *data_len = 0;
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+
+        auto diff = ipmi::sel::selRecordSize - requestData->offset;
+        auto readLength =
+            std::min(diff, static_cast<int>(requestData->readLength));
+
+        uint16_t nextRecordID = record.nextRecordID;
+        std::memcpy(response, &nextRecordID, sizeof(nextRecordID));
+
+        const ipmi::sel::SELEventRecordFormat* evt = &record.event;
+        std::memcpy(static_cast<uint8_t*>(response) + sizeof(nextRecordID),
+                    reinterpret_cast<const uint8_t*>(evt) + requestData->offset,
+                    readLength);
+        *data_len = sizeof(nextRecordID) + readLength;
+    }
+
+    return IPMI_CC_OK;
+}
+
+/** @brief implements the delete SEL entry command
+ * @request
+ *   - reservationID; // reservation ID.
+ *   - selRecordID;   // SEL record ID.
+ *
+ *  @returns ipmi completion code plus response data
+ *   - Record ID of the deleted record
+ */
+ipmi::RspType<uint16_t // deleted record ID
+              >
+    deleteSELEntry(uint16_t reservationID, uint16_t selRecordID)
+{
+    namespace fs = std::filesystem;
+
+    if (!checkSELReservation(reservationID))
+    {
+        return ipmi::responseInvalidReservationId();
+    }
+
+    // Per the IPMI spec, need to cancel the reservation when a SEL entry is
+    // deleted
+    cancelSELReservation();
+
+    if (!selCacheMapInitialized)
+    {
+        // In case the initSELCache() fails, try it again
+        initSELCache();
+    }
+
+    if (selCacheMap.empty())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    SELCacheMap::const_iterator iter;
+    uint16_t delRecordID = 0;
+
+    if (selRecordID == ipmi::sel::firstEntry)
+    {
+        delRecordID = selCacheMap.begin()->first;
+    }
+    else if (selRecordID == ipmi::sel::lastEntry)
+    {
+        delRecordID = selCacheMap.rbegin()->first;
+    }
+    else
+    {
+        delRecordID = selRecordID;
+    }
+
+    iter = selCacheMap.find(delRecordID);
+    if (iter == selCacheMap.end())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    std::string service;
+
+    auto objPath = getLoggingObjPath(iter->first);
+    try
+    {
+        service = ipmi::getService(bus, ipmi::sel::logDeleteIntf, objPath);
+    }
+    catch (const std::runtime_error& e)
+    {
+        lg2::error("runtime error: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    auto methodCall = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                          ipmi::sel::logDeleteIntf, "Delete");
+    try
+    {
+        auto reply = bus.call(methodCall);
+    }
+    catch (const std::exception& e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(delRecordID);
+}
+
+/** @brief implements the Clear SEL command
+ * @request
+ *   - reservationID   // Reservation ID.
+ *   - clr             // char array { 'C'(0x43h), 'L'(0x4Ch), 'R'(0x52h) }
+ *   - eraseOperation; // requested operation.
+ *
+ *  @returns ipmi completion code plus response data
+ *   - erase status
+ */
+
+ipmi::RspType<uint8_t // erase status
+              >
+    clearSEL(uint16_t reservationID, const std::array<char, 3>& clr,
+             uint8_t eraseOperation)
+{
+    static constexpr std::array<char, 3> clrOk = {'C', 'L', 'R'};
+    if (clr != clrOk)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (!checkSELReservation(reservationID))
+    {
+        return ipmi::responseInvalidReservationId();
+    }
+
+    /*
+     * Erasure status cannot be fetched from DBUS, so always return erasure
+     * status as `erase completed`.
+     */
+    if (eraseOperation == ipmi::sel::getEraseStatus)
+    {
+        return ipmi::responseSuccess(
+            static_cast<uint8_t>(ipmi::sel::eraseComplete));
+    }
+
+    // Check that initiate erase is correct
+    if (eraseOperation != ipmi::sel::initiateErase)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // Per the IPMI spec, need to cancel any reservation when the SEL is cleared
+    cancelSELReservation();
+
+    sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+    auto service = ipmi::getService(bus, ipmi::sel::logIntf, ipmi::sel::logObj);
+    auto method =
+        bus.new_method_call(service.c_str(), ipmi::sel::logObj,
+                            ipmi::sel::logIntf, ipmi::sel::logDeleteAllMethod);
+    try
+    {
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Error eraseAll: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(
+        static_cast<uint8_t>(ipmi::sel::eraseComplete));
+}
+
+/** @brief implements the get SEL time command
+ *  @returns IPMI completion code plus response data
+ *   -current time
+ */
+ipmi::RspType<uint32_t> // current time
+    ipmiStorageGetSelTime()
+{
+    using namespace std::chrono;
+    uint64_t bmc_time_usec = 0;
+    std::stringstream bmcTime;
+
+    try
+    {
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+        auto service = ipmi::getService(bus, TIME_INTERFACE, BMC_TIME_PATH);
+        auto propValue = ipmi::getDbusProperty(
+            bus, service, BMC_TIME_PATH, TIME_INTERFACE, PROPERTY_ELAPSED);
+        bmc_time_usec = std::get<uint64_t>(propValue);
+    }
+    catch (const InternalFailure& e)
+    {
+        lg2::error("Internal Failure: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("exception message: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    lg2::debug("BMC time: {BMC_TIME}", "BMC_TIME",
+               duration_cast<seconds>(microseconds(bmc_time_usec)).count());
+
+    // Time is really long int but IPMI wants just uint32. This works okay until
+    // the number of seconds since 1970 overflows uint32 size.. Still a whole
+    // lot of time here to even think about that.
+    return ipmi::responseSuccess(
+        duration_cast<seconds>(microseconds(bmc_time_usec)).count());
+}
+
+/** @brief implements the set SEL time command
+ *  @param selDeviceTime - epoch time
+ *        -local time as the number of seconds from 00:00:00, January 1, 1970
+ *  @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiStorageSetSelTime(uint32_t selDeviceTime)
+{
+    using namespace std::chrono;
+    microseconds usec{seconds(selDeviceTime)};
+
+    try
+    {
+        sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
+        bool ntp = std::get<bool>(
+            ipmi::getDbusProperty(bus, SystemdTimeService, SystemdTimePath,
+                                  SystemdTimeInterface, "NTP"));
+        if (ntp)
+        {
+            return ipmi::responseCommandNotAvailable();
+        }
+
+        auto service = ipmi::getService(bus, TIME_INTERFACE, BMC_TIME_PATH);
+        std::variant<uint64_t> value{(uint64_t)usec.count()};
+
+        // Set bmc time
+        auto method = bus.new_method_call(service.c_str(), BMC_TIME_PATH,
+                                          DBUS_PROPERTIES, "Set");
+
+        method.append(TIME_INTERFACE, PROPERTY_ELAPSED, value);
+        auto reply = bus.call(method);
+    }
+    catch (const InternalFailure& e)
+    {
+        lg2::error("Internal Failure: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("exception message: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess();
+}
+
+/** @brief implements the get SEL timezone command
+ *  @returns IPMI completion code plus response data
+ *   -current timezone
+ */
+ipmi::RspType<int16_t> ipmiStorageGetSelTimeUtcOffset()
+{
+    time_t timep;
+    struct tm* gmTime;
+    struct tm* localTime;
+
+    time(&timep);
+    localTime = localtime(&timep);
+    auto validLocalTime = mktime(localTime);
+    gmTime = gmtime(&timep);
+    auto validGmTime = mktime(gmTime);
+    auto timeEquation = (validLocalTime - validGmTime) / 60;
+
+    return ipmi::responseSuccess(timeEquation);
+}
+
+/** @brief implements the reserve SEL command
+ *  @returns IPMI completion code plus response data
+ *   - SEL reservation ID.
+ */
+ipmi::RspType<uint16_t> ipmiStorageReserveSel()
+{
+    return ipmi::responseSuccess(reserveSel());
+}
+
+/** @brief implements the Add SEL entry command
+ * @request
+ *
+ *   - recordID      ID used for SEL Record access
+ *   - recordType    Record Type
+ *   - timeStamp     Time when event was logged. LS byte first
+ *   - generatorID   software ID if event was generated from
+ *                   system software
+ *   - evmRev        event message format version
+ *   - sensorType    sensor type code for service that generated
+ *                   the event
+ *   - sensorNumber  number of sensors that generated the event
+ *   - eventDir     event dir
+ *   - eventData    event data field contents
+ *
+ *  @returns ipmi completion code plus response data
+ *   - RecordID of the Added SEL entry
+ */
+ipmi::RspType<uint16_t // recordID of the Added SEL entry
+              >
+    ipmiStorageAddSEL(uint16_t recordID, uint8_t recordType,
+                      [[maybe_unused]] uint32_t timeStamp, uint16_t generatorID,
+                      [[maybe_unused]] uint8_t evmRev,
+                      [[maybe_unused]] uint8_t sensorType, uint8_t sensorNumber,
+                      uint8_t eventDir,
+                      std::array<uint8_t, eventDataSize> eventData)
+{
+    std::string objpath;
+    static constexpr auto systemRecordType = 0x02;
+#ifdef OPEN_POWER_SUPPORT
+    // Hostboot sends SEL with OEM record type 0xDE to indicate that there is
+    // a maintenance procedure associated with eSEL record.
+    static constexpr auto procedureType = 0xDE;
+#endif
+    cancelSELReservation();
+    if (recordType == systemRecordType)
+    {
+        for (const auto& it : invSensors)
+        {
+            if (it.second.sensorID == sensorNumber)
+            {
+                objpath = it.first;
+                break;
+            }
+        }
+        auto selDataStr = ipmi::sel::toHexStr(eventData);
+
+        bool assert = (eventDir & 0x80) ? false : true;
+
+        recordID = report<SELCreated>(
+            Created::RECORD_TYPE(recordType),
+            Created::GENERATOR_ID(generatorID),
+            Created::SENSOR_DATA(selDataStr.c_str()),
+            Created::EVENT_DIR(assert), Created::SENSOR_PATH(objpath.c_str()));
+    }
+#ifdef OPEN_POWER_SUPPORT
+    else if (recordType == procedureType)
+    {
+        // In the OEM record type 0xDE, byte 11 in the SEL record indicate the
+        // procedure number.
+        createProcedureLogEntry(sensorType);
+    }
+#endif
+
+    return ipmi::responseSuccess(recordID);
+}
+
+bool isFruPresent(ipmi::Context::ptr& ctx, const std::string& fruPath)
+{
+    using namespace ipmi::fru;
+
+    std::string service;
+    boost::system::error_code ec =
+        getService(ctx, invItemInterface, invObjPath + fruPath, service);
+    if (!ec)
+    {
+        bool result;
+        ec = ipmi::getDbusProperty(ctx, service, invObjPath + fruPath,
+                                   invItemInterface, itemPresentProp, result);
+        if (!ec)
+        {
+            return result;
+        }
+    }
+
+    ipmi::ObjectValueTree managedObjects;
+    ec = getManagedObjects(ctx, "xyz.openbmc_project.EntityManager",
+                           "/xyz/openbmc_project/inventory", managedObjects);
+    if (!ec)
+    {
+        auto connection = managedObjects.find(fruPath);
+        if (connection != managedObjects.end())
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/** @brief implements the get FRU Inventory Area Info command
+ *
+ *  @returns IPMI completion code plus response data
+ *   - FRU Inventory area size in bytes,
+ *   - access bit
+ **/
+ipmi::RspType<uint16_t, // FRU Inventory area size in bytes,
+              uint8_t   // access size (bytes / words)
+              >
+    ipmiStorageGetFruInvAreaInfo(ipmi::Context::ptr ctx, uint8_t fruID)
+{
+    auto iter = frus.find(fruID);
+    if (iter == frus.end())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    auto path = iter->second[0].path;
+    if (!isFruPresent(ctx, path))
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    try
+    {
+        return ipmi::responseSuccess(
+            static_cast<uint16_t>(getFruAreaData(fruID).size()),
+            static_cast<uint8_t>(AccessMode::bytes));
+    }
+    catch (const InternalFailure& e)
+    {
+        lg2::error("Internal Failure: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+}
+
+/**@brief implements the Read FRU Data command
+ * @param fruDeviceId - FRU device ID. FFh = reserved
+ * @param offset      - FRU inventory offset to read
+ * @param readCount   - count to read
+ *
+ * @return IPMI completion code plus response data
+ * - returnCount - response data count.
+ * - data        -  response data
+ */
+ipmi::RspType<uint8_t,              // count returned
+              std::vector<uint8_t>> // FRU data
+    ipmiStorageReadFruData(uint8_t fruDeviceId, uint16_t offset,
+                           uint8_t readCount)
+{
+    if (fruDeviceId == 0xFF)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    auto iter = frus.find(fruDeviceId);
+    if (iter == frus.end())
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    try
+    {
+        const auto& fruArea = getFruAreaData(fruDeviceId);
+        auto size = fruArea.size();
+
+        if (offset >= size)
+        {
+            return ipmi::responseParmOutOfRange();
+        }
+
+        // Write the count of response data.
+        uint8_t returnCount;
+        if ((offset + readCount) <= size)
+        {
+            returnCount = readCount;
+        }
+        else
+        {
+            returnCount = size - offset;
+        }
+
+        std::vector<uint8_t> fruData((fruArea.begin() + offset),
+                                     (fruArea.begin() + offset + returnCount));
+
+        return ipmi::responseSuccess(returnCount, fruData);
+    }
+    catch (const InternalFailure& e)
+    {
+        lg2::error("Internal Failure: {ERROR}", "ERROR", e);
+        return ipmi::responseUnspecifiedError();
+    }
+}
+
+ipmi::RspType<uint8_t,  // SDR version
+              uint16_t, // record count LS first
+              uint16_t, // free space in bytes, LS first
+              uint32_t, // addition timestamp LS first
+              uint32_t, // deletion timestamp LS first
+              uint8_t>  // operation Support
+    ipmiGetRepositoryInfo()
+{
+    constexpr uint8_t sdrVersion = 0x51;
+    constexpr uint16_t freeSpace = 0xFFFF;
+    constexpr uint32_t additionTimestamp = 0x0;
+    constexpr uint32_t deletionTimestamp = 0x0;
+    constexpr uint8_t operationSupport = 0;
+
+    // Get SDR count. This returns the total number of SDRs in the device.
+    const auto& entityRecords =
+        ipmi::sensor::EntityInfoMapContainer::getContainer()
+            ->getIpmiEntityRecords();
+    uint16_t records =
+        ipmi::sensor::sensors.size() + frus.size() + entityRecords.size();
+
+    return ipmi::responseSuccess(sdrVersion, records, freeSpace,
+                                 additionTimestamp, deletionTimestamp,
+                                 operationSupport);
+}
+
+void registerNetFnStorageFunctions()
+{
+    selCacheMapInitialized = false;
+    initSELCache();
+    // Handlers with dbus-sdr handler implementation.
+    // Do not register the hander if it dynamic sensors stack is used.
+
+#ifndef FEATURE_DYNAMIC_SENSORS
+
+#ifndef FEATURE_DYNAMIC_STORAGES_ONLY
+    // <Get SEL Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelInfo, ipmi::Privilege::User,
+                          ipmiStorageGetSelInfo);
+
+    // <Get SEL Timezone>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelTimeUtcOffset,
+                          ipmi::Privilege::User,
+                          ipmiStorageGetSelTimeUtcOffset);
+
+    // <Get SEL Entry>
+    ipmi_register_callback(NETFUN_STORAGE, ipmi::storage::cmdGetSelEntry,
+                           nullptr, getSELEntry, PRIVILEGE_USER);
+
+    // <Delete SEL Entry>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdDeleteSelEntry,
+                          ipmi::Privilege::Operator, deleteSELEntry);
+
+    // <Add SEL Entry>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdAddSelEntry,
+                          ipmi::Privilege::Operator, ipmiStorageAddSEL);
+
+    // <Clear SEL>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdClearSel, ipmi::Privilege::Operator,
+                          clearSEL);
+
+    // <Get FRU Inventory Area Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetFruInventoryAreaInfo,
+                          ipmi::Privilege::User, ipmiStorageGetFruInvAreaInfo);
+
+    // <READ FRU Data>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdReadFruData,
+                          ipmi::Privilege::Operator, ipmiStorageReadFruData);
+
+#endif // FEATURE_DYNAMIC_STORAGES_ONLY
+
+    // <Get Repository Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSdrRepositoryInfo,
+                          ipmi::Privilege::User, ipmiGetRepositoryInfo);
+
+    // <Reserve SDR Repository>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdReserveSdrRepository,
+                          ipmi::Privilege::User, ipmiSensorReserveSdr);
+
+    // <Get SDR>
+    ipmi_register_callback(NETFUN_STORAGE, ipmi::storage::cmdGetSdr, nullptr,
+                           ipmi_sen_get_sdr, PRIVILEGE_USER);
+
+#endif
+
+    // Common Handers used by both implementation.
+
+    // <Reserve SEL>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdReserveSel, ipmi::Privilege::User,
+                          ipmiStorageReserveSel);
+
+    // <Get SEL Time>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelTime, ipmi::Privilege::User,
+                          ipmiStorageGetSelTime);
+
+    // <Set SEL Time>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdSetSelTime,
+                          ipmi::Privilege::Operator, ipmiStorageSetSelTime);
+
+    ipmi::fru::registerCallbackHandler();
+    return;
+}
diff --git a/subprojects/boost.wrap b/subprojects/boost.wrap
new file mode 100644
index 0000000..5912c6f
--- /dev/null
+++ b/subprojects/boost.wrap
@@ -0,0 +1,9 @@
+[wrap-file]
+directory = boost-1.84.0
+
+source_url = https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz
+source_hash = 4d27e9efed0f6f152dc28db6430b9d3dfb40c0345da7342eaa5a987dde57bd95
+source_filename = 1_84_0.tar.gz
+
+[provide]
+boost = boost_dep
diff --git a/subprojects/nlohmann_json.wrap b/subprojects/nlohmann_json.wrap
new file mode 100644
index 0000000..3745380
--- /dev/null
+++ b/subprojects/nlohmann_json.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+revision = HEAD
+url = https://github.com/nlohmann/json.git
+
+[provide]
+nlohmann_json = nlohmann_json_dep
diff --git a/subprojects/phosphor-dbus-interfaces.wrap b/subprojects/phosphor-dbus-interfaces.wrap
index 346aa0c..0bf731e 100644
--- a/subprojects/phosphor-dbus-interfaces.wrap
+++ b/subprojects/phosphor-dbus-interfaces.wrap
@@ -1,3 +1,4 @@
+
 [wrap-git]
 url = https://github.com/openbmc/phosphor-dbus-interfaces.git
 revision = HEAD
diff --git a/subprojects/phosphor-logging.wrap b/subprojects/phosphor-logging.wrap
index 71eee8b..6876a6e 100644
--- a/subprojects/phosphor-logging.wrap
+++ b/subprojects/phosphor-logging.wrap
@@ -1,5 +1,5 @@
 [wrap-git]
-url = https://github.com/openbmc/phosphor-logging.git
+url = https://github.com/openbmc/phosphor-logging
 revision = HEAD
 
 [provide]
diff --git a/subprojects/sdbusplus.wrap b/subprojects/sdbusplus.wrap
index 7b076d0..42cfcee 100644
--- a/subprojects/sdbusplus.wrap
+++ b/subprojects/sdbusplus.wrap
@@ -1,5 +1,5 @@
 [wrap-git]
-url = https://github.com/openbmc/sdbusplus.git
+url = https://github.com/openbmc/sdbusplus
 revision = HEAD
 
 [provide]
diff --git a/subprojects/sdeventplus.wrap b/subprojects/sdeventplus.wrap
new file mode 100644
index 0000000..a506404
--- /dev/null
+++ b/subprojects/sdeventplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdeventplus
+revision = HEAD
+
+[provide]
+sdeventplus = sdeventplus_dep
diff --git a/sys_info_param.cpp b/sys_info_param.cpp
new file mode 100644
index 0000000..79bb29c
--- /dev/null
+++ b/sys_info_param.cpp
@@ -0,0 +1,33 @@
+#include "sys_info_param.hpp"
+
+std::tuple<bool, std::string> SysInfoParamStore::lookup(
+    uint8_t paramSelector) const
+{
+    const auto iterator = params.find(paramSelector);
+    if (iterator == params.end())
+    {
+        return std::make_tuple(false, "");
+    }
+
+    auto& callback = iterator->second;
+    auto s = callback();
+    return std::make_tuple(true, s);
+}
+
+void SysInfoParamStore::update(uint8_t paramSelector, const std::string& s)
+{
+    // Add a callback that captures a copy of the string passed and returns it
+    // when invoked.
+
+    // clang-format off
+    update(paramSelector, [s]() {
+        return s;
+    });
+    // clang-format on
+}
+
+void SysInfoParamStore::update(uint8_t paramSelector,
+                               const std::function<std::string()>& callback)
+{
+    params[paramSelector] = callback;
+}
diff --git a/sys_info_param.hpp b/sys_info_param.hpp
new file mode 100644
index 0000000..5f6607d
--- /dev/null
+++ b/sys_info_param.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <cstdint>
+#include <functional>
+#include <map>
+#include <string>
+#include <tuple>
+
+/**
+ * Key-value store for string-type system info parameters.
+ */
+class SysInfoParamStoreIntf
+{
+  public:
+    virtual ~SysInfoParamStoreIntf() {}
+
+    /**
+     * Returns true if parameter is found. If and only if s is non-null,
+     * invokes the parameter's callback and writes the value.
+     *
+     * @param[in] paramSelector - the key to lookup.
+     * @return tuple of bool and string, true if parameter is found and
+     * string set accordingly.
+     */
+    virtual std::tuple<bool, std::string> lookup(
+        uint8_t paramSelector) const = 0;
+
+    /**
+     * Update a parameter by its code with a string value.
+     *
+     * @param[in] paramSelector - the key to update.
+     * @param[in] s - the value to set.
+     */
+    virtual void update(uint8_t paramSelector, const std::string& s) = 0;
+
+    /**
+     * Update a parameter by its code with a callback that is called to retrieve
+     * its value whenever called. Callback must be idempotent, as it may be
+     * called multiple times by the host to retrieve the parameter by chunks.
+     *
+     * @param[in] paramSelector - the key to update.
+     * @param[in] callback - the callback to use for parameter retrieval.
+     */
+    virtual void update(uint8_t paramSelector,
+                        const std::function<std::string()>& callback) = 0;
+
+    // TODO: Store "read-only" flag for each parameter.
+    // TODO: Function to erase a parameter?
+};
+
+/**
+ * Implement the system info parameters store as a map of callbacks.
+ */
+class SysInfoParamStore : public SysInfoParamStoreIntf
+{
+  public:
+    std::tuple<bool, std::string> lookup(uint8_t paramSelector) const override;
+    void update(uint8_t paramSelector, const std::string& s) override;
+    void update(uint8_t paramSelector,
+                const std::function<std::string()>& callback) override;
+
+  private:
+    std::map<uint8_t, std::function<std::string()>> params;
+};
diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp
new file mode 100644
index 0000000..c7206af
--- /dev/null
+++ b/systemintfcmds.cpp
@@ -0,0 +1,189 @@
+#include "config.h"
+
+#include "systemintfcmds.hpp"
+
+#include "host-cmd-manager.hpp"
+#include "host-interface.hpp"
+
+#include <ipmid-host/cmd.hpp>
+#include <ipmid/api.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <cstring>
+#include <fstream>
+
+void registerNetFnAppFunctions() __attribute__((constructor));
+
+using namespace sdbusplus::server::xyz::openbmc_project::control;
+
+// For accessing Host command manager
+using cmdManagerPtr = std::unique_ptr<phosphor::host::command::Manager>;
+extern cmdManagerPtr& ipmid_get_host_cmd_manager();
+
+//-------------------------------------------------------------------
+// Called by Host post response from Get_Message_Flags
+//-------------------------------------------------------------------
+ipmi::RspType<uint16_t,              // id
+              uint8_t,               // type
+              uint24_t,              //  manuf_id
+              uint32_t,              // timestamp
+              uint8_t,               // netfun
+              uint8_t,               // cmd
+              std::array<uint8_t, 4> // data
+              >
+    ipmiAppReadEventBuffer(ipmi::Context::ptr& ctx)
+{
+    // require this to be limited to system interface
+    if (ctx->channel != ipmi::channelSystemIface)
+    {
+        return ipmi::responseInvalidCommand();
+    }
+
+    constexpr uint16_t selOemId = 0x5555;
+    constexpr uint8_t selRecordTypeOem = 0xc0;
+
+    // read manufacturer ID from dev_id file
+    static uint24_t manufId{};
+    if (!manufId)
+    {
+        const char* filename = "/usr/share/ipmi-providers/dev_id.json";
+        std::ifstream devIdFile(filename);
+        if (devIdFile.is_open())
+        {
+            auto data = nlohmann::json::parse(devIdFile, nullptr, false);
+            if (!data.is_discarded())
+            {
+                manufId = data.value("manuf_id", 0);
+            }
+        }
+    }
+
+    constexpr uint32_t timestamp{0};
+
+    // per IPMI spec NetFuntion for OEM
+    constexpr uint8_t netfun = 0x3a;
+
+    // Read from the Command Manager queue. What gets returned is a
+    // pair of <command, data> that can be directly used here
+    const auto& [cmd, data0] = ipmid_get_host_cmd_manager()->getNextCommand();
+    constexpr uint8_t dataUnused = 0xff;
+
+    return ipmi::responseSuccess(
+        selOemId, selRecordTypeOem, manufId, timestamp, netfun, cmd,
+        std::to_array<uint8_t>({data0, dataUnused, dataUnused, dataUnused}));
+}
+
+//---------------------------------------------------------------------
+// Called by Host on seeing a SMS_ATN bit set. Return a hardcoded
+// value of 0x0 to indicate Event Message Buffer is not supported
+//-------------------------------------------------------------------
+ipmi::RspType<uint8_t> ipmiAppGetMessageFlags()
+{
+    // From IPMI spec V2.0 for Get Message Flags Command :
+    // bit:[1] from LSB : 1b = Event Message Buffer Full.
+    // Return as 0 if Event Message Buffer is not supported,
+    // or when the Event Message buffer is disabled.
+    // This path is used to communicate messages to the host
+    // from within the phosphor::host::command::Manager
+    constexpr uint8_t setEventMsgBufferNotSupported = 0x0;
+    return ipmi::responseSuccess(setEventMsgBufferNotSupported);
+}
+
+ipmi::RspType<bool,    // Receive Message Queue Interrupt Enabled
+              bool,    // Event Message Buffer Full Interrupt Enabled
+              bool,    // Event Message Buffer Enabled
+              bool,    // System Event Logging Enabled
+              uint1_t, // Reserved
+              bool,    // OEM 0 enabled
+              bool,    // OEM 1 enabled
+              bool     // OEM 2 enabled
+              >
+    ipmiAppGetBMCGlobalEnable()
+{
+    return ipmi::responseSuccess(true, false, false, true, 0, false, false,
+                                 false);
+}
+
+ipmi::RspType<> ipmiAppSetBMCGlobalEnable(
+    ipmi::Context::ptr ctx, bool receiveMessageQueueInterruptEnabled,
+    bool eventMessageBufferFullInterruptEnabled, bool eventMessageBufferEnabled,
+    bool systemEventLogEnable, uint1_t reserved, bool OEM0Enabled,
+    bool OEM1Enabled, bool OEM2Enabled)
+{
+    ipmi::ChannelInfo chInfo;
+
+    if (ipmi::getChannelInfo(ctx->channel, chInfo) != ipmi::ccSuccess)
+    {
+        lg2::error("Failed to get Channel Info, channel={CHANNEL}", "CHANNEL",
+                   ctx->channel);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    if (chInfo.mediumType !=
+        static_cast<uint8_t>(ipmi::EChannelMediumType::systemInterface))
+    {
+        lg2::error("Error - supported only in system interface");
+        return ipmi::responseCommandNotAvailable();
+    }
+
+    // Recv Message Queue and SEL are enabled by default.
+    // Event Message buffer are disabled by default (not supported).
+    // Any request that try to change the mask will be rejected
+    if (!receiveMessageQueueInterruptEnabled || !systemEventLogEnable ||
+        eventMessageBufferFullInterruptEnabled || eventMessageBufferEnabled ||
+        OEM0Enabled || OEM1Enabled || OEM2Enabled || reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    return ipmi::responseSuccess();
+}
+
+namespace
+{
+// Static storage to keep the object alive during process life
+std::unique_ptr<phosphor::host::command::Host> host
+    __attribute__((init_priority(101)));
+std::unique_ptr<sdbusplus::server::manager_t> objManager
+    __attribute__((init_priority(101)));
+} // namespace
+
+void registerNetFnAppFunctions()
+{
+    // <Read Event Message Buffer>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdReadEventMessageBuffer,
+                          ipmi::Privilege::Admin, ipmiAppReadEventBuffer);
+
+    // <Set BMC Global Enables>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetBmcGlobalEnables,
+                          ipmi::Privilege::Admin, ipmiAppSetBMCGlobalEnable);
+
+    // <Get BMC Global Enables>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetBmcGlobalEnables,
+                          ipmi::Privilege::User, ipmiAppGetBMCGlobalEnable);
+
+    // <Get Message Flags>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetMessageFlags, ipmi::Privilege::Admin,
+                          ipmiAppGetMessageFlags);
+
+    // Create new xyz.openbmc_project.host object on the bus
+    auto objPath = std::string{CONTROL_HOST_OBJ_MGR} + '/' + HOST_NAME + '0';
+
+    std::unique_ptr<sdbusplus::asio::connection>& sdbusp =
+        ipmid_get_sdbus_plus_handler();
+
+    // Add sdbusplus ObjectManager.
+    objManager = std::make_unique<sdbusplus::server::manager_t>(
+        *sdbusp, CONTROL_HOST_OBJ_MGR);
+
+    host = std::make_unique<phosphor::host::command::Host>(
+        *sdbusp, objPath.c_str());
+    sdbusp->request_name(CONTROL_HOST_BUSNAME);
+
+    return;
+}
diff --git a/systemintfcmds.hpp b/systemintfcmds.hpp
new file mode 100644
index 0000000..b263a96
--- /dev/null
+++ b/systemintfcmds.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <stdint.h>
+
+// These are per skiboot ipmi-sel code
+
+// Minor command for soft shurdown
+#define SOFT_OFF 0x00
+// Major command for Any kind of power ops
+#define CMD_POWER 0x04
+// Major command for the heartbeat operation (verify host is alive)
+#define CMD_HEARTBEAT 0xFF
diff --git a/test/dbus-sdr/sensorcommands_unittest.cpp b/test/dbus-sdr/sensorcommands_unittest.cpp
new file mode 100644
index 0000000..bcd2f44
--- /dev/null
+++ b/test/dbus-sdr/sensorcommands_unittest.cpp
@@ -0,0 +1,489 @@
+#include "dbus-sdr/sensorutils.hpp"
+
+#include <cmath>
+
+#include "gtest/gtest.h"
+
+// There is a surprising amount of slop in the math,
+// thanks to all the rounding and conversion.
+// The "x" byte value can drift by up to 2 away, I have seen.
+static constexpr int8_t expectedSlopX = 2;
+
+// Unlike expectedSlopX, this is a ratio, not an integer
+// It scales based on the range of "y"
+static constexpr double expectedSlopY = 0.01;
+
+// The algorithm here was copied from ipmitool
+// sdr_convert_sensor_reading() function
+// https://github.com/ipmitool/ipmitool/blob/42a023ff0726c80e8cc7d30315b987fe568a981d/lib/ipmi_sdr.c#L360
+double ipmitool_y_from_x(uint8_t x, int m, int k2_rExp, int b, int k1_bExp,
+                         bool bSigned)
+{
+    double result;
+
+    // Rename to exactly match names and types (except analog) from ipmitool
+    uint8_t val = x;
+    double k1 = k1_bExp;
+    double k2 = k2_rExp;
+    int analog = bSigned ? 2 : 0;
+
+    // Begin paste here
+    // Only change is to comment out complicated structure in switch statement
+
+    switch (/*sensor->cmn.unit.*/ analog)
+    {
+        case 0:
+            result = (double)(((m * val) + (b * pow(10, k1))) * pow(10, k2));
+            break;
+        case 1:
+            if (val & 0x80)
+                val++;
+            /* Deliberately fall through to case 2. */
+            [[fallthrough]];
+        case 2:
+            result =
+                (double)(((m * (int8_t)val) + (b * pow(10, k1))) * pow(10, k2));
+            break;
+        default:
+            /* Oops! This isn't an analog sensor. */
+            return 0.0;
+    }
+
+    // End paste here
+    // Ignoring linearization curves and postprocessing that follows,
+    // assuming all sensors are perfectly linear
+    return result;
+}
+
+void testValue(int x, double y, int16_t M, int8_t rExp, int16_t B, int8_t bExp,
+               bool bSigned, double yRange)
+{
+    double yRoundtrip;
+    int result;
+
+    // There is intentionally no exception catching here,
+    // because if getSensorAttributes() returned true,
+    // it is a promise that all of these should work.
+    if (bSigned)
+    {
+        int8_t expect = x;
+        int8_t actual =
+            ipmi::scaleIPMIValueFromDouble(y, M, rExp, B, bExp, bSigned);
+
+        result = actual;
+        yRoundtrip = ipmitool_y_from_x(actual, M, rExp, B, bExp, bSigned);
+
+        EXPECT_NEAR(actual, expect, expectedSlopX);
+    }
+    else
+    {
+        uint8_t expect = x;
+        uint8_t actual =
+            ipmi::scaleIPMIValueFromDouble(y, M, rExp, B, bExp, bSigned);
+
+        result = actual;
+        yRoundtrip = ipmitool_y_from_x(actual, M, rExp, B, bExp, bSigned);
+
+        EXPECT_NEAR(actual, expect, expectedSlopX);
+    }
+
+    // Scale the amount of allowed slop in y based on range, so ratio similar
+    double yTolerance = yRange * expectedSlopY;
+    // double yError = std::abs(y - yRoundtrip);
+
+    EXPECT_NEAR(y, yRoundtrip, yTolerance);
+
+    char szFormat[1024];
+    sprintf(szFormat,
+            "Value | xExpect %4d | xResult %4d "
+            "| M %5d | rExp %3d "
+            "| B %5d | bExp %3d | bSigned %1d | y %18.3f | yRoundtrip %18.3f\n",
+            x, result, M, (int)rExp, B, (int)bExp, (int)bSigned, y, yRoundtrip);
+    std::cout << szFormat;
+}
+
+void testBounds(double yMin, double yMax, bool bExpectedOutcome = true)
+{
+    int16_t mValue;
+    int8_t rExp;
+    int16_t bValue;
+    int8_t bExp;
+    bool bSigned;
+    bool result;
+
+    result = ipmi::getSensorAttributes(yMax, yMin, mValue, rExp, bValue, bExp,
+                                       bSigned);
+    EXPECT_EQ(result, bExpectedOutcome);
+
+    if (!result)
+    {
+        return;
+    }
+
+    char szFormat[1024];
+    sprintf(szFormat,
+            "Bounds | yMin %18.3f | yMax %18.3f | M %5d"
+            " | rExp %3d | B %5d | bExp %3d | bSigned %1d\n",
+            yMin, yMax, mValue, (int)rExp, bValue, (int)bExp, (int)bSigned);
+    std::cout << szFormat;
+
+    double y50p = (yMin + yMax) / 2.0;
+
+    // Average the average
+    double y25p = (yMin + y50p) / 2.0;
+    double y75p = (y50p + yMax) / 2.0;
+
+    // This range value is only used for tolerance checking, not computation
+    double yRange = yMax - yMin;
+
+    if (bSigned)
+    {
+        int8_t xMin = -128;
+        int8_t x25p = -64;
+        int8_t x50p = 0;
+        int8_t x75p = 64;
+        int8_t xMax = 127;
+
+        testValue(xMin, yMin, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(x25p, y25p, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(x50p, y50p, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(x75p, y75p, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(xMax, yMax, mValue, rExp, bValue, bExp, bSigned, yRange);
+    }
+    else
+    {
+        uint8_t xMin = 0;
+        uint8_t x25p = 64;
+        uint8_t x50p = 128;
+        uint8_t x75p = 192;
+        uint8_t xMax = 255;
+
+        testValue(xMin, yMin, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(x25p, y25p, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(x50p, y50p, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(x75p, y75p, mValue, rExp, bValue, bExp, bSigned, yRange);
+        testValue(xMax, yMax, mValue, rExp, bValue, bExp, bSigned, yRange);
+    }
+}
+
+void testRanges(void)
+{
+    // The ranges from the main TEST function
+    testBounds(0x0, 0xFF);
+    testBounds(-128, 127);
+    testBounds(0, 16000);
+    testBounds(0, 20);
+    testBounds(8000, 16000);
+    testBounds(-10, 10);
+    testBounds(0, 277);
+    testBounds(0, 0, false);
+    testBounds(10, 12);
+
+    // Additional test cases recommended to me by hardware people
+    testBounds(-40, 150);
+    testBounds(0, 1);
+    testBounds(0, 2);
+    testBounds(0, 4);
+    testBounds(0, 8);
+    testBounds(35, 65);
+    testBounds(0, 18);
+    testBounds(0, 25);
+    testBounds(0, 80);
+    testBounds(0, 500);
+
+    // Additional sanity checks
+    testBounds(0, 255);
+    testBounds(-255, 0);
+    testBounds(-255, 255);
+    testBounds(0, 1000);
+    testBounds(-1000, 0);
+    testBounds(-1000, 1000);
+    testBounds(0, 255000);
+    testBounds(-128000000, 127000000);
+    testBounds(-50000, 0);
+    testBounds(-40000, 10000);
+    testBounds(-30000, 20000);
+    testBounds(-20000, 30000);
+    testBounds(-10000, 40000);
+    testBounds(0, 50000);
+    testBounds(-1e3, 1e6);
+    testBounds(-1e6, 1e3);
+
+    // Extreme ranges are now possible
+    testBounds(0, 1e10);
+    testBounds(0, 1e11);
+    testBounds(0, 1e12);
+    testBounds(0, 1e13, false);
+    testBounds(-1e10, 0);
+    testBounds(-1e11, 0);
+    testBounds(-1e12, 0);
+    testBounds(-1e13, 0, false);
+    testBounds(-1e9, 1e9);
+    testBounds(-1e10, 1e10);
+    testBounds(-1e11, 1e11);
+    testBounds(-1e12, 1e12, false);
+
+    // Large multiplier but small offset
+    testBounds(1e4, 1e4 + 255);
+    testBounds(1e5, 1e5 + 255);
+    testBounds(1e6, 1e6 + 255);
+    testBounds(1e7, 1e7 + 255);
+    testBounds(1e8, 1e8 + 255);
+    testBounds(1e9, 1e9 + 255);
+    testBounds(1e10, 1e10 + 255, false);
+
+    // Input validation against garbage
+    testBounds(0, INFINITY, false);
+    testBounds(-INFINITY, 0, false);
+    testBounds(-INFINITY, INFINITY, false);
+    testBounds(0, NAN, false);
+    testBounds(NAN, 0, false);
+    testBounds(NAN, NAN, false);
+
+    // Noteworthy binary integers
+    testBounds(0, std::pow(2.0, 32.0) - 1.0);
+    testBounds(0, std::pow(2.0, 32.0));
+    testBounds(0.0 - std::pow(2.0, 31.0), std::pow(2.0, 31.0));
+    testBounds((0.0 - std::pow(2.0, 31.0)) - 1.0, std::pow(2.0, 31.0));
+
+    // Similar but negative (note additional commented-out below)
+    testBounds(-1e1, (-1e1) + 255);
+    testBounds(-1e2, (-1e2) + 255);
+
+    // Ranges of negative numbers (note additional commented-out below)
+    testBounds(-10400, -10000);
+    testBounds(-15000, -14000);
+    testBounds(-10000, -9000);
+    testBounds(-1000, -900);
+    testBounds(-1000, -800);
+    testBounds(-1000, -700);
+    testBounds(-1000, -740);
+
+    // Very small ranges (note additional commented-out below)
+    testBounds(0, 0.1);
+    testBounds(0, 0.01);
+    testBounds(0, 0.001);
+    testBounds(0, 0.0001);
+    testBounds(0, 0.000001, false);
+
+#if 0
+    // TODO(): The algorithm in this module is better than it was before,
+    // but the resulting value of X is still wrong under certain conditions,
+    // such as when the range between min and max is around 255,
+    // and the offset is fairly extreme compared to the multiplier.
+    // Not sure why this is, but these ranges are contrived,
+    // and real-world examples would most likely never be this way.
+    testBounds(-10290, -10000);
+    testBounds(-10280, -10000);
+    testBounds(-10275,-10000);
+    testBounds(-10270,-10000);
+    testBounds(-10265,-10000);
+    testBounds(-10260,-10000);
+    testBounds(-10255,-10000);
+    testBounds(-10250,-10000);
+    testBounds(-10245,-10000);
+    testBounds(-10256,-10000);
+    testBounds(-10512, -10000);
+    testBounds(-11024, -10000);
+
+    // TODO(): This also fails, due to extreme small range, loss of precision
+    testBounds(0, 0.00001);
+
+    // TODO(): Interestingly, if bSigned is forced false,
+    // causing "x" to have range of (0,255) instead of (-128,127),
+    // these test cases change from failing to passing!
+    // Not sure why this is, perhaps a mathematician might know.
+    testBounds(-10300, -10000);
+    testBounds(-1000,-750);
+    testBounds(-1e3, (-1e3) + 255);
+    testBounds(-1e4, (-1e4) + 255);
+    testBounds(-1e5, (-1e5) + 255);
+    testBounds(-1e6, (-1e6) + 255);
+#endif
+}
+
+TEST(sensorutils, TranslateToIPMI)
+{
+    /*bool getSensorAttributes(double maxValue, double minValue, int16_t
+       &mValue, int8_t &rExp, int16_t &bValue, int8_t &bExp, bool &bSigned); */
+    // normal unsigned sensor
+    double maxValue = 0xFF;
+    double minValue = 0x0;
+    int16_t mValue;
+    int8_t rExp;
+    int16_t bValue;
+    int8_t bExp;
+    bool bSigned;
+    bool result;
+
+    uint8_t scaledVal;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+    if (result)
+    {
+        EXPECT_EQ(bSigned, false);
+        EXPECT_EQ(mValue, 1);
+        EXPECT_EQ(rExp, 0);
+        EXPECT_EQ(bValue, 0);
+        EXPECT_EQ(bExp, 0);
+    }
+    double expected = 0x50;
+    scaledVal = ipmi::scaleIPMIValueFromDouble(0x50, mValue, rExp, bValue, bExp,
+                                               bSigned);
+    EXPECT_NEAR(scaledVal, expected, expected * 0.01);
+
+    // normal signed sensor
+    maxValue = 127;
+    minValue = -128;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+
+    if (result)
+    {
+        EXPECT_EQ(bSigned, true);
+        EXPECT_EQ(mValue, 1);
+        EXPECT_EQ(rExp, 0);
+        EXPECT_EQ(bValue, 0);
+        EXPECT_EQ(bExp, 0);
+    }
+
+    // check negative values
+    expected = 236; // 2s compliment -20
+    scaledVal = ipmi::scaleIPMIValueFromDouble(-20, mValue, rExp, bValue, bExp,
+                                               bSigned);
+    EXPECT_NEAR(scaledVal, expected, expected * 0.01);
+
+    // fan example
+    maxValue = 16000;
+    minValue = 0;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+    if (result)
+    {
+        EXPECT_EQ(bSigned, false);
+        EXPECT_EQ(mValue, floor((16000.0 / 0xFF) + 0.5));
+        EXPECT_EQ(rExp, 0);
+        EXPECT_EQ(bValue, 0);
+        EXPECT_EQ(bExp, 0);
+    }
+
+    // voltage sensor example
+    maxValue = 20;
+    minValue = 0;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+    if (result)
+    {
+        EXPECT_EQ(bSigned, false);
+        EXPECT_EQ(mValue, floor(((20.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
+        EXPECT_EQ(rExp, -3);
+        EXPECT_EQ(bValue, 0);
+        EXPECT_EQ(bExp, 0);
+    }
+    scaledVal = ipmi::scaleIPMIValueFromDouble(12.2, mValue, rExp, bValue, bExp,
+                                               bSigned);
+
+    expected = 12.2 / (mValue * std::pow(10, rExp));
+    EXPECT_NEAR(scaledVal, expected, expected * 0.01);
+
+    // shifted fan example
+    maxValue = 16000;
+    minValue = 8000;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+
+    if (result)
+    {
+        EXPECT_EQ(bSigned, false);
+        EXPECT_EQ(mValue, floor(((8000.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
+        EXPECT_EQ(rExp, -1);
+        EXPECT_EQ(bValue, 8);
+        EXPECT_EQ(bExp, 4);
+    }
+
+    // signed voltage sensor example
+    maxValue = 10;
+    minValue = -10;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+    if (result)
+    {
+        EXPECT_EQ(bSigned, true);
+        EXPECT_EQ(mValue, floor(((20.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
+        EXPECT_EQ(rExp, -3);
+        // Although this seems like a weird magic number,
+        // it is because the range (-128,127) is not symmetrical about zero,
+        // unlike the range (-10,10), so this introduces some distortion.
+        EXPECT_EQ(bValue, 392);
+        EXPECT_EQ(bExp, -1);
+    }
+
+    scaledVal =
+        ipmi::scaleIPMIValueFromDouble(5, mValue, rExp, bValue, bExp, bSigned);
+
+    expected = 5 / (mValue * std::pow(10, rExp));
+    EXPECT_NEAR(scaledVal, expected, expected * 0.01);
+
+    // reading = max example
+    maxValue = 277;
+    minValue = 0;
+
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+    if (result)
+    {
+        EXPECT_EQ(bSigned, false);
+    }
+
+    scaledVal = ipmi::scaleIPMIValueFromDouble(maxValue, mValue, rExp, bValue,
+                                               bExp, bSigned);
+
+    expected = 0xFF;
+    EXPECT_NEAR(scaledVal, expected, expected * 0.01);
+
+    // 0, 0 failure
+    maxValue = 0;
+    minValue = 0;
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, false);
+
+    // too close *success* (was previously failure!)
+    maxValue = 12;
+    minValue = 10;
+    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
+                                       bExp, bSigned);
+    EXPECT_EQ(result, true);
+    if (result)
+    {
+        EXPECT_EQ(bSigned, false);
+        EXPECT_EQ(mValue, floor(((2.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
+        EXPECT_EQ(rExp, -4);
+        EXPECT_EQ(bValue, 1);
+        EXPECT_EQ(bExp, 5);
+    }
+}
+
+TEST(sensorUtils, TestRanges)
+{
+    // Additional test ranges, each running through a series of values,
+    // to make sure the values of "x" and "y" go together and make sense,
+    // for the resulting scaling attributes from each range.
+    // Unlike the TranslateToIPMI test, exact matches of the
+    // getSensorAttributes() results (the coefficients) are not required,
+    // because they are tested through actual use, relating "x" to "y".
+    testRanges();
+}
diff --git a/test/entitymap_json_unittest.cpp b/test/entitymap_json_unittest.cpp
new file mode 100644
index 0000000..5f31e1b
--- /dev/null
+++ b/test/entitymap_json_unittest.cpp
@@ -0,0 +1,223 @@
+#include <ipmid/entity_map_json.hpp>
+#include <ipmid/types.hpp>
+#include <nlohmann/json.hpp>
+
+#include <utility>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace ipmi
+{
+namespace sensor
+{
+
+namespace
+{
+using ::testing::IsEmpty;
+
+TEST(ValidateJson, FailWithNonArrayReturnsEmpty)
+{
+    /* The entity map input json is expected to be an array of objects. */
+    auto j = R"(
+        {
+            "id" : 1,
+            "containerEntityId" : 2,
+            "containerEntityInstance" : 3,
+            "isList" : false,
+            "isLinked" : false,
+            "entities" : [
+                {"id" : 1, "instance" : 2},
+                {"id" : 1, "instance" : 3},
+                {"id" : 1, "instance" : 4},
+                {"id" : 1, "instance" : 5}
+            ]
+        }
+    )"_json;
+
+    EXPECT_THAT(buildJsonEntityMap(j), IsEmpty());
+}
+
+TEST(ValidateJson, FailWithMissingFieldReturnsEmpty)
+{
+    /* There are many required fields, let's just validate that if one is
+     * missing, it returns the empty map.
+     */
+    auto j = R"(
+        [
+            {
+                "id" : 1,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 2},
+                    {"id" : 1, "instance" : 3},
+                    {"id" : 1, "instance" : 4},
+                    {"id" : 1, "instance" : 5}
+                ]
+            }
+        ]
+    )"_json;
+
+    EXPECT_THAT(buildJsonEntityMap(j), IsEmpty());
+}
+
+TEST(ValidateJson, AllValidEntryReturnsExpectedMap)
+{
+    /* Boring test where we provide completely valid information and expect the
+     * resulting map contains that information.
+     */
+    auto j = R"(
+        [
+            {
+                "id" : 1,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "isLinked" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 2},
+                    {"id" : 1, "instance" : 3},
+                    {"id" : 1, "instance" : 4},
+                    {"id" : 1, "instance" : 5}
+                ]
+            }
+        ]
+    )"_json;
+
+    auto map = buildJsonEntityMap(j);
+    EXPECT_FALSE(map.find(1) == map.end());
+    auto entry = map.find(1);
+    EXPECT_EQ(entry->first, 1);
+
+    /* TODO: someone could write an equality operator for this object. */
+    EXPECT_EQ(entry->second.containerEntityId, 2);
+    EXPECT_EQ(entry->second.containerEntityInstance, 3);
+    EXPECT_FALSE(entry->second.isList);
+    EXPECT_FALSE(entry->second.isLinked);
+    ContainedEntitiesArray expected = {
+        std::make_pair(1, 2), std::make_pair(1, 3), std::make_pair(1, 4),
+        std::make_pair(1, 5)};
+    EXPECT_EQ(entry->second.containedEntities, expected);
+}
+
+TEST(ValidateJson, EntryHasInsufficientContainerEntryCountReturnsEmpty)
+{
+    /* The container must have four pairs. (I don't know why, and maybe this
+     * restriction will change).
+     */
+    auto j = R"(
+        [
+            {
+                "id" : 1,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "isLinked" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 2},
+                    {"id" : 1, "instance" : 3},
+                    {"id" : 1, "instance" : 4}
+                ]
+            }
+        ]
+    )"_json;
+
+    EXPECT_THAT(buildJsonEntityMap(j), IsEmpty());
+}
+
+TEST(ValidateJson, ThereAreTwoEntriesOneInvalidReturnsEmpty)
+{
+    /* If any entry in the file is corrupt, the file is disregarded. */
+    auto j = R"(
+        [
+            {
+                "id" : 1,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "isLinked" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 2},
+                    {"id" : 1, "instance" : 3},
+                    {"id" : 1, "instance" : 4},
+                    {"id" : 1, "instance" : 5}
+                ]
+            },
+            {
+                "id" : 2,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "isLinked" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 2},
+                    {"id" : 1, "instance" : 3},
+                    {"id" : 1, "instance" : 4}
+                ]
+            }
+        ]
+    )"_json;
+
+    EXPECT_THAT(buildJsonEntityMap(j), IsEmpty());
+}
+
+TEST(ValidateJson, ThereAreTwoEntriesBothValidReturnsBoth)
+{
+    /* The map supports more than one entry, just validate this. */
+    auto j = R"(
+        [
+            {
+                "id" : 1,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "isLinked" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 2},
+                    {"id" : 1, "instance" : 3},
+                    {"id" : 1, "instance" : 4},
+                    {"id" : 1, "instance" : 5}
+                ]
+            },
+            {
+                "id" : 2,
+                "containerEntityId" : 2,
+                "containerEntityInstance" : 3,
+                "isList" : false,
+                "isLinked" : false,
+                "entities" : [
+                    {"id" : 1, "instance" : 6},
+                    {"id" : 1, "instance" : 7},
+                    {"id" : 1, "instance" : 8},
+                    {"id" : 1, "instance" : 9}
+                ]
+            }
+        ]
+    )"_json;
+
+    auto map = buildJsonEntityMap(j);
+    EXPECT_FALSE(map.find(1) == map.end());
+    EXPECT_FALSE(map.find(2) == map.end());
+
+    auto entry = map.find(1);
+    EXPECT_EQ(entry->first, 1);
+    EXPECT_EQ(entry->second.containerEntityId, 2);
+    EXPECT_EQ(entry->second.containerEntityInstance, 3);
+    EXPECT_FALSE(entry->second.isList);
+    EXPECT_FALSE(entry->second.isLinked);
+    ContainedEntitiesArray expected = {
+        std::make_pair(1, 2), std::make_pair(1, 3), std::make_pair(1, 4),
+        std::make_pair(1, 5)};
+    EXPECT_EQ(entry->second.containedEntities, expected);
+
+    entry = map.find(2);
+    expected = {std::make_pair(1, 6), std::make_pair(1, 7),
+                std::make_pair(1, 8), std::make_pair(1, 9)};
+    EXPECT_EQ(entry->second.containedEntities, expected);
+}
+
+} // namespace
+} // namespace sensor
+} // namespace ipmi
diff --git a/test/meson.build b/test/meson.build
index 6fcfd04..949a121 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,38 +1,103 @@
-gtest_dep = dependency('gtest', main: true, disabler: true, required: false)
-gmock_dep = dependency('gmock', disabler: true, required: false)
-if not gtest_dep.found() or not gmock_dep.found()
-    gtest_proj = import('cmake').subproject('googletest', required: false)
+gtest = dependency('gtest', main: true, disabler: true, required: false)
+gmock = dependency('gmock', disabler: true, required: false)
+if not gtest.found() or not gmock.found()
+    gtest_opts = import('cmake').subproject_options()
+    gtest_opts.add_cmake_defines({'CMAKE_CXX_FLAGS': '-Wno-pedantic'})
+    gtest_proj = import('cmake').subproject(
+        'googletest',
+        options: gtest_opts,
+        required: false,
+    )
     if gtest_proj.found()
-        gtest_dep = declare_dependency(
+        gtest = declare_dependency(
             dependencies: [
                 dependency('threads'),
                 gtest_proj.dependency('gtest'),
                 gtest_proj.dependency('gtest_main'),
             ],
         )
-        gmock_dep = gtest_proj.dependency('gmock')
+        gmock = gtest_proj.dependency('gmock')
     else
-        assert(
-            not get_option('tests').enabled(),
-            'Googletest is required if tests are enabled',
-        )
+        assert(not get_option('tests').enabled(), 'Googletest is required')
     endif
 endif
 
-test_sources = ['../integrity_algo.cpp', '../crypt_algo.cpp']
+test(
+    'entitymap_json',
+    executable(
+        'entitymap_json',
+        'entitymap_json_unittest.cpp',
+        include_directories: root_inc,
+        build_by_default: false,
+        implicit_include_directories: false,
+        dependencies: [
+            entity_map_json_dep,
+            gmock,
+            gtest,
+            nlohmann_json_dep,
+            sdbusplus_dep,
+        ],
+    ),
+)
 
-tests = ['cipher.cpp']
+# Build/add oemrouter_unittest to test suite
+# Issue #3325
+# test('oemrouter',
+#  executable(
+#    'oemrouter',
+#    'oemrouter_unittest.cpp',
+#    include_directories: root_inc,
+#    build_by_default: false,
+#    implicit_include_directories: false,
+#    dependencies: [gtest, gmock]
+#  ))
 
-foreach t : tests
-    test(
-        t,
-        executable(
-            t.underscorify(),
-            t,
-            test_sources,
-            include_directories: ['..'],
-            dependencies: [gtest_dep, gmock_dep, libcrypto_dep],
-        ),
-        workdir: meson.current_source_dir(),
-    )
-endforeach
+# Build/add message packing/unpacking unit tests
+test(
+    'message',
+    executable(
+        'message',
+        'message/pack.cpp',
+        'message/payload.cpp',
+        'message/unpack.cpp',
+        include_directories: root_inc,
+        build_by_default: false,
+        override_options: ['b_lundef=true'],
+        implicit_include_directories: false,
+        dependencies: [
+            boost,
+            crypto,
+            gmock,
+            gtest,
+            libsystemd_dep,
+            phosphor_logging_dep,
+            sdbusplus_dep,
+        ],
+    ),
+)
+
+# Build/add closesession_unittest to test suite
+test(
+    'session/closesession',
+    executable(
+        'session_closesession',
+        'session/closesession_unittest.cpp',
+        include_directories: root_inc,
+        build_by_default: false,
+        implicit_include_directories: false,
+        dependencies: [gtest, gmock],
+    ),
+)
+
+# Build/add sensorcommands_unittest to test suite
+test(
+    'dbus-sdr/sensorcommands',
+    executable(
+        'dbus-sdr_sensorcommands',
+        'dbus-sdr/sensorcommands_unittest.cpp',
+        include_directories: root_inc,
+        build_by_default: false,
+        implicit_include_directories: false,
+        dependencies: [sensorutils_dep, gtest, gmock],
+    ),
+)
diff --git a/test/message/pack.cpp b/test/message/pack.cpp
new file mode 100644
index 0000000..57bff06
--- /dev/null
+++ b/test/message/pack.cpp
@@ -0,0 +1,497 @@
+/**
+ * Copyright © 2018 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 <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+
+#include <gtest/gtest.h>
+
+// TODO: Add testing of Payload response API
+
+TEST(PackBasics, Uint8)
+{
+    ipmi::message::Payload p;
+    uint8_t v = 4;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(v));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x04};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint16)
+{
+    ipmi::message::Payload p;
+    uint16_t v = 0x8604;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(v));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x04, 0x86};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint32)
+{
+    ipmi::message::Payload p;
+    uint32_t v = 0x02008604;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(v));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x04, 0x86, 0x00, 0x02};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint64)
+{
+    ipmi::message::Payload p;
+    uint64_t v = 0x1122334402008604ull;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(v));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint24)
+{
+    ipmi::message::Payload p;
+    uint24_t v = 0x112358;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), types::nrFixedBits<decltype(v)> / CHAR_BIT);
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x58, 0x23, 0x11};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint3Uint5)
+{
+    // individual bytes are packed low-order-bits first
+    // v1 will occupy [2:0], v2 will occupy [7:3]
+    ipmi::message::Payload p;
+    uint3_t v1 = 0x1;
+    uint5_t v2 = 0x19;
+    p.pack(v1, v2);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), (types::nrFixedBits<decltype(v1)> +
+                         types::nrFixedBits<decltype(v2)>) /
+                            CHAR_BIT);
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0xc9};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Boolx8)
+{
+    // individual bytes are packed low-order-bits first
+    // [v8, v7, v6, v5, v4, v3, v2, v1]
+    ipmi::message::Payload p;
+    bool v8 = true, v7 = true, v6 = false, v5 = false;
+    bool v4 = true, v3 = false, v2 = false, v1 = true;
+    p.pack(v1, v2, v3, v4, v5, v6, v7, v8);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(uint8_t));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0xc9};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Bitset8)
+{
+    // individual bytes are packed low-order-bits first
+    // a bitset for 8 bits fills the full byte
+    ipmi::message::Payload p;
+    std::bitset<8> v(0xc9);
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), v.size() / CHAR_BIT);
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0xc9};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Bitset3Bitset5)
+{
+    // individual bytes are packed low-order-bits first
+    // v1 will occupy [2:0], v2 will occupy [7:3]
+    ipmi::message::Payload p;
+    std::bitset<3> v1(0x1);
+    std::bitset<5> v2(0x19);
+    p.pack(v1, v2);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), (v1.size() + v2.size()) / CHAR_BIT);
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0xc9};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Bitset32)
+{
+    // individual bytes are packed low-order-bits first
+    // v1 will occupy 4 bytes, but in LSByte first order
+    // v1[7:0] v1[15:9] v1[23:16] v1[31:24]
+    ipmi::message::Payload p;
+    std::bitset<32> v(0x02008604);
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), v.size() / CHAR_BIT);
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x04, 0x86, 0x00, 0x02};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Tuple)
+{
+    // tuples are the new struct, pack a tuple
+    ipmi::message::Payload p;
+    auto v = std::make_tuple(static_cast<uint16_t>(0x8604), 'A');
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(uint16_t) + sizeof(char));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x04, 0x86, 0x41};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Array4xUint8)
+{
+    // an array of bytes will be output verbatim, low-order element first
+    ipmi::message::Payload p;
+    std::array<uint8_t, 4> v = {{0x02, 0x00, 0x86, 0x04}};
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+    // check that the bytes were correctly packed (in byte order)
+    ipmi::SecureBuffer k = {0x02, 0x00, 0x86, 0x04};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Array4xUint32)
+{
+    // an array of multi-byte values will be output in order low-order
+    // element first, each multi-byte element in LSByte order
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::message::Payload p;
+    std::array<uint32_t, 4> v = {
+        {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+    // check that the bytes were correctly packed (in byte order)
+    ipmi::SecureBuffer k = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+                            0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, VectorUint32)
+{
+    // a vector of multi-byte values will be output in order low-order
+    // element first, each multi-byte element in LSByte order
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::message::Payload p;
+    std::vector<uint32_t> v = {
+        {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+    // check that the bytes were correctly packed (in byte order)
+    ipmi::SecureBuffer k = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+                            0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, VectorUint8)
+{
+    // a vector of bytes will be output verbatim, low-order element first
+    ipmi::message::Payload p;
+    std::vector<uint8_t> v = {0x02, 0x00, 0x86, 0x04};
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+    // check that the bytes were correctly packed (in byte order)
+    ipmi::SecureBuffer k = {0x02, 0x00, 0x86, 0x04};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, VectorUnaligned)
+{
+    ipmi::message::Payload p;
+    EXPECT_EQ(p.pack(true, std::vector<uint8_t>{1}), 1);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer{0b1});
+}
+
+TEST(PackBasics, StringView)
+{
+    ipmi::message::Payload p;
+    EXPECT_EQ(p.pack(std::string_view{"\x24\x30\x11"}), 0);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0x24, 0x30, 0x11}));
+}
+
+TEST(PackBasics, StringViewUnaligned)
+{
+    ipmi::message::Payload p;
+    EXPECT_EQ(p.pack(true, std::string_view{"abc"}), 1);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0b1}));
+}
+
+TEST(PackBasics, OptionalEmpty)
+{
+    // an optional will only pack if the value is present
+    ipmi::message::Payload p;
+    std::optional<uint32_t> v;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), 0);
+    // check that the bytes were correctly packed (in byte order)
+    ipmi::SecureBuffer k = {};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, OptionalContainsValue)
+{
+    // an optional will only pack if the value is present
+    ipmi::message::Payload p;
+    std::optional<uint32_t> v(0x04860002);
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(uint32_t));
+    // check that the bytes were correctly packed (in byte order)
+    ipmi::SecureBuffer k = {0x02, 0x00, 0x86, 0x04};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Payload)
+{
+    ipmi::message::Payload p;
+    EXPECT_EQ(p.pack(true), 0);
+    EXPECT_EQ(p.pack(ipmi::message::Payload({0x24, 0x30})), 0);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0b1, 0x24, 0x30}));
+}
+
+TEST(PackBasics, PayloadUnaligned)
+{
+    ipmi::message::Payload p;
+    EXPECT_EQ(p.pack(true, ipmi::message::Payload({0x24})), 1);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0b1}));
+}
+
+TEST(PackBasics, PayloadOtherUnaligned)
+{
+    ipmi::message::Payload p, q;
+    q.appendBits(1, 1);
+    EXPECT_EQ(p.pack(true), 0);
+    EXPECT_EQ(p.pack(q), 1);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0b1}));
+}
+
+TEST(PackBasics, PrependPayload)
+{
+    ipmi::message::Payload p;
+    EXPECT_EQ(p.pack(true), 0);
+    EXPECT_EQ(p.prepend(ipmi::message::Payload({0x24, 0x30})), 0);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0x24, 0x30, 0b1}));
+}
+
+TEST(PackBasics, PrependPayloadUnaligned)
+{
+    ipmi::message::Payload p;
+    p.appendBits(1, 1);
+    EXPECT_EQ(p.prepend(ipmi::message::Payload({0x24})), 1);
+    p.drain();
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0b1}));
+}
+
+TEST(PackBasics, PrependPayloadOtherUnaligned)
+{
+    ipmi::message::Payload p, q;
+    q.appendBits(1, 1);
+    EXPECT_EQ(p.pack(true), 0);
+    EXPECT_EQ(p.prepend(q), 1);
+    EXPECT_EQ(p.raw, ipmi::SecureBuffer({0b1}));
+}
+
+TEST(PackAdvanced, Uints)
+{
+    // all elements will be processed in order, with each multi-byte
+    // element being processed LSByte first
+    // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+    // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+    // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+    ipmi::message::Payload p;
+    uint8_t v1 = 0x02;
+    uint16_t v2 = 0x0604;
+    uint32_t v3 = 0x44332211;
+    uint64_t v4 = 0xccbbaa9988776655ull;
+    p.pack(v1, v2, v3, v4);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(v1) + sizeof(v2) + sizeof(v3) + sizeof(v4));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, TupleInts)
+{
+    // all elements will be processed in order, with each multi-byte
+    // element being processed LSByte first
+    // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+    // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+    // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+    ipmi::message::Payload p;
+    uint8_t v1 = 0x02;
+    uint16_t v2 = 0x0604;
+    uint32_t v3 = 0x44332211;
+    uint64_t v4 = 0xccbbaa9988776655ull;
+    auto v = std::make_tuple(v1, v2, v3, v4);
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(v1) + sizeof(v2) + sizeof(v3) + sizeof(v4));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, VariantArray)
+{
+    ipmi::message::Payload p;
+    std::variant<std::array<uint8_t, 2>, uint32_t> variant;
+    auto data = std::array<uint8_t, 2>{2, 4};
+    variant = data;
+
+    p.pack(variant);
+    ASSERT_EQ(p.size(), sizeof(data));
+
+    // check that the bytes were correctly packed packed (LSB first)
+    ipmi::SecureBuffer k = {2, 4};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
+{
+    // each element will be added, filling the low-order bits first
+    // with multi-byte values getting added LSByte first
+    // v1 will occupy k[0][1:0]
+    // v2 will occupy k[0][2]
+    // v3[4:0] will occupy k[0][7:3], v3[6:5] will occupy k[1][1:0]
+    // v4 will occupy k[1][2]
+    // v5 will occupy k[1][7:3]
+    ipmi::message::Payload p;
+    uint2_t v1 = 2;          // binary 0b10
+    bool v2 = true;          // binary 0b1
+    std::bitset<7> v3(0x73); // binary 0b1110011
+    bool v4 = false;         // binary 0b0
+    uint5_t v5 = 27;         // binary 0b11011
+    // concat binary: 0b1101101110011110 -> 0xdb9e -> 0x9e 0xdb (LSByte first)
+    p.pack(v1, v2, v3, v4, v5);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(uint16_t));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x9e, 0xdb};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, UnalignedBitPacking)
+{
+    // unaligned multi-byte values will be packed the same as
+    // other bits, effectively building up a large value, low-order
+    // bits first, then outputting a stream of LSByte values
+    // v1 will occupy k[0][1:0]
+    // v2[5:0] will occupy k[0][7:2], v2[7:6] will occupy k[1][1:0]
+    // v3 will occupy k[1][2]
+    // v4[4:0] will occupy k[1][7:3] v4[12:5] will occupy k[2][7:0]
+    // v4[15:13] will occupy k[3][2:0]
+    // v5 will occupy k[3][3]
+    // v6[3:0] will occupy k[3][7:0] v6[11:4] will occupy k[4][7:0]
+    // v6[19:12] will occupy k[5][7:0] v6[27:20] will occupy k[6][7:0]
+    // v6[31:28] will occupy k[7][3:0]
+    // v7 will occupy k[7][7:4]
+    ipmi::message::Payload p;
+    uint2_t v1 = 2;           // binary 0b10
+    uint8_t v2 = 0xa5;        // binary 0b10100101
+    bool v3 = false;          // binary 0b0
+    uint16_t v4 = 0xa55a;     // binary 0b1010010101011010
+    bool v5 = true;           // binary 0b1
+    uint32_t v6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
+    uint4_t v7 = 9;           // binary 0b1001
+    // concat binary:
+    //   0b1001110110111100001110111101001111001101001010101101001010010110
+    //   -> 0x9dbc3bd3cd2ad296 -> 0x96 0xd2 0x2a 0xcd 0xd3 0x3b 0xbc 0x9d
+    p.pack(v1, v2, v3, v4, v5, v6, v7);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(uint64_t));
+    // check that the bytes were correctly packed (LSB first)
+    ipmi::SecureBuffer k = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, ComplexOptionalTuple)
+{
+    constexpr size_t macSize = 6;
+    // inspired from a real-world case of Get Session Info
+    constexpr uint8_t handle = 0x23;       // handle for active session
+    constexpr uint8_t maxSessions = 15;    // number of possible active sessions
+    constexpr uint8_t currentSessions = 4; // number of current active sessions
+    std::optional<                         // only returned for active session
+        std::tuple<uint8_t,                // user ID
+                   uint8_t,                // privilege
+                   uint4_t,                // channel number
+                   uint4_t                 // protocol (RMCP+)
+                   >>
+        activeSession;
+    std::optional<           // only returned for channel type LAN
+        std::tuple<uint32_t, // IPv4 address
+                   std::array<uint8_t, macSize>, // MAC address
+                   uint16_t                      // port
+                   >>
+        lanSession;
+
+    constexpr uint8_t userID = 7;
+    constexpr uint8_t priv = 4;
+    constexpr uint4_t channel = 2;
+    constexpr uint4_t protocol = 1;
+    activeSession.emplace(userID, priv, channel, protocol);
+    constexpr std::array<uint8_t, macSize> macAddr{0};
+    lanSession.emplace(0x0a010105, macAddr, 55327);
+
+    ipmi::message::Payload p;
+    p.pack(handle, maxSessions, currentSessions, activeSession, lanSession);
+    ASSERT_EQ(p.size(),
+              sizeof(handle) + sizeof(maxSessions) + sizeof(currentSessions) +
+                  3 * sizeof(uint8_t) + sizeof(uint32_t) +
+                  sizeof(uint8_t) * macSize + sizeof(uint16_t));
+    uint8_t protocol_channel =
+        (static_cast<uint8_t>(protocol) << 4) | static_cast<uint8_t>(channel);
+    ipmi::SecureBuffer k = {
+        handle, maxSessions, currentSessions, userID, priv, protocol_channel,
+        // ip addr
+        0x05, 0x01, 0x01, 0x0a,
+        // mac addr
+        0, 0, 0, 0, 0, 0,
+        // port
+        0x1f, 0xd8};
+    ASSERT_EQ(p.raw, k);
+}
diff --git a/test/message/payload.cpp b/test/message/payload.cpp
new file mode 100644
index 0000000..38977e4
--- /dev/null
+++ b/test/message/payload.cpp
@@ -0,0 +1,436 @@
+/**
+ * Copyright © 2018 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.
+ */
+#define SD_JOURNAL_SUPPRESS_LOCATION
+
+#include <systemd/sd-journal.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+
+#include <stdexcept>
+
+#include <gtest/gtest.h>
+
+TEST(Payload, InputSize)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    size_t input_size = i.size();
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    ASSERT_EQ(input_size, p.size());
+}
+
+TEST(Payload, OutputSize)
+{
+    ipmi::message::Payload p;
+    ASSERT_EQ(0, p.size());
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    p.pack(i);
+    ASSERT_EQ(i.size(), p.size());
+    p.pack(i);
+    p.pack(i);
+    ASSERT_EQ(3 * i.size(), p.size());
+}
+
+TEST(Payload, Resize)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p;
+    p.pack(i);
+    p.resize(16);
+    ASSERT_EQ(p.size(), 16);
+}
+
+TEST(Payload, Data)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p;
+    p.pack(i);
+    ASSERT_NE(nullptr, p.data());
+}
+
+TEST(PayloadResponse, Append)
+{
+    std::string s("0123456789abcdef");
+    ipmi::message::Payload p;
+    p.append(s.data(), s.data() + s.size());
+    ASSERT_EQ(s.size(), p.size());
+}
+
+TEST(PayloadResponse, AppendDrain)
+{
+    std::string s("0123456789abcdef");
+    ipmi::message::Payload p;
+    bool b = true;
+    // first pack a lone bit
+    p.pack(b);
+    p.append(s.data(), s.data() + s.size());
+    // append will 'drain' first, padding the lone bit into a full byte
+    ASSERT_EQ(s.size() + 1, p.size());
+}
+
+TEST(PayloadResponse, AppendBits)
+{
+    ipmi::message::Payload p;
+    p.appendBits(3, 0b101);
+    ASSERT_EQ(p.bitStream, 0b101);
+    p.appendBits(4, 0b1100);
+    ASSERT_EQ(p.bitStream, 0b1100101);
+    p.appendBits(1, 0b1);
+    ASSERT_EQ(p.bitStream, 0);
+    ASSERT_EQ(p.bitCount, 0);
+    // appended 8 bits, should be one byte
+    ASSERT_EQ(p.size(), 1);
+    ipmi::SecureBuffer k1 = {0b11100101};
+    ASSERT_EQ(p.raw, k1);
+    p.appendBits(7, 0b1110111);
+    // appended 7 more bits, should still be one byte
+    ASSERT_EQ(p.size(), 1);
+    p.drain();
+    // drain forces padding; should be two bytes now
+    ASSERT_EQ(p.size(), 2);
+    ipmi::SecureBuffer k2 = {0b11100101, 0b01110111};
+    ASSERT_EQ(p.raw, k2);
+}
+
+TEST(PayloadResponse, Drain16Bits)
+{
+    ipmi::message::Payload p;
+    p.bitStream = 0b1011010011001111;
+    p.bitCount = 16;
+    p.drain();
+    ASSERT_EQ(p.size(), 2);
+    ASSERT_EQ(p.bitCount, 0);
+    ASSERT_EQ(p.bitStream, 0);
+    ipmi::SecureBuffer k1 = {0b11001111, 0b10110100};
+    ASSERT_EQ(p.raw, k1);
+}
+
+TEST(PayloadResponse, Drain15Bits)
+{
+    ipmi::message::Payload p;
+    p.bitStream = 0b101101001100111;
+    p.bitCount = 15;
+    p.drain();
+    ASSERT_EQ(p.size(), 2);
+    ASSERT_EQ(p.bitCount, 0);
+    ASSERT_EQ(p.bitStream, 0);
+    ipmi::SecureBuffer k1 = {0b1100111, 0b1011010};
+    ASSERT_EQ(p.raw, k1);
+}
+
+TEST(PayloadResponse, Drain15BitsWholeBytesOnly)
+{
+    ipmi::message::Payload p;
+    p.bitStream = 0b101101001100111;
+    p.bitCount = 15;
+    p.drain(true);
+    // only the first whole byte should have been 'drained' into p.raw
+    ASSERT_EQ(p.size(), 1);
+    ASSERT_EQ(p.bitCount, 7);
+    ASSERT_EQ(p.bitStream, 0b1011010);
+    ipmi::SecureBuffer k1 = {0b1100111};
+    ASSERT_EQ(p.raw, k1);
+}
+
+TEST(PayloadRequest, Pop)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    const auto& [vb, ve] = p.pop<uint8_t>(4);
+    std::vector<uint8_t> v(vb, ve);
+    std::vector<uint8_t> k = {0xbf, 0x04, 0x86, 0x00};
+    ASSERT_EQ(v, k);
+}
+
+TEST(PayloadRequest, FillBits)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.fillBits(5);
+    ASSERT_FALSE(p.unpackError);
+    ASSERT_EQ(p.bitStream, 0xbf);
+    ASSERT_EQ(p.bitCount, 8);
+    // should still have 5 bits available, no change
+    p.fillBits(5);
+    ASSERT_FALSE(p.unpackError);
+    ASSERT_EQ(p.bitStream, 0xbf);
+    ASSERT_EQ(p.bitCount, 8);
+    // discard 5 bits (low order)
+    p.popBits(5);
+    // should add another byte into the stream (high order)
+    p.fillBits(5);
+    ASSERT_FALSE(p.unpackError);
+    ASSERT_EQ(p.bitStream, 0x25);
+    ASSERT_EQ(p.bitCount, 11);
+}
+
+TEST(PayloadRequest, FillBitsTooManyBits)
+{
+    ipmi::SecureBuffer i = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.fillBits(72);
+    ASSERT_TRUE(p.unpackError);
+}
+
+TEST(PayloadRequest, FillBitsNotEnoughBytes)
+{
+    ipmi::SecureBuffer i = {1, 2, 3, 4};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.fillBits(48);
+    ASSERT_TRUE(p.unpackError);
+}
+
+TEST(PayloadRequest, PopBits)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.fillBits(4);
+    uint8_t v = p.popBits(4);
+    ASSERT_FALSE(p.unpackError);
+    ASSERT_EQ(p.bitStream, 0x0b);
+    ASSERT_EQ(p.bitCount, 4);
+    ASSERT_EQ(v, 0x0f);
+}
+
+TEST(PayloadRequest, PopBitsNoFillBits)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.popBits(4);
+    ASSERT_TRUE(p.unpackError);
+}
+
+TEST(PayloadRequest, DiscardBits)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.fillBits(5);
+    ASSERT_FALSE(p.unpackError);
+    ASSERT_EQ(p.bitStream, 0xbf);
+    ASSERT_EQ(p.bitCount, 8);
+    p.discardBits();
+    ASSERT_FALSE(p.unpackError);
+    ASSERT_EQ(p.bitStream, 0);
+    ASSERT_EQ(p.bitCount, 0);
+}
+
+TEST(PayloadRequest, FullyUnpacked)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint32_t v1;
+    p.unpack(v1);
+    // still one remaining byte
+    ASSERT_FALSE(p.fullyUnpacked());
+    p.fillBits(3);
+    p.popBits(3);
+    // still five remaining bits
+    ASSERT_FALSE(p.fullyUnpacked());
+    p.fillBits(5);
+    p.popBits(5);
+    // fully unpacked, should be no errors
+    ASSERT_TRUE(p.fullyUnpacked());
+    p.fillBits(4);
+    // fullyUnpacked fails because an attempt to unpack too many bytes
+    ASSERT_FALSE(p.fullyUnpacked());
+}
+
+TEST(PayloadRequest, ResetInternal)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    p.fillBits(4);
+    p.unpackError = true;
+    p.reset();
+    ASSERT_EQ(p.rawIndex, 0);
+    ASSERT_EQ(p.bitStream, 0);
+    ASSERT_EQ(p.bitCount, 0);
+    ASSERT_FALSE(p.unpackError);
+}
+
+TEST(PayloadRequest, ResetUsage)
+{
+    // Payload.reset is used to rewind the unpacking to the initial
+    // state. This is needed so that OEM commands can unpack the group
+    // number or the IANA to determine which handler needs to be called
+    ipmi::SecureBuffer i = {0x04, 0x86};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint8_t v1;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint8_t k1 = 0x04;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    // do a reset on the payload
+    p.reset();
+    // unpack a uint16
+    uint16_t v2;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v2), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint16_t k2 = 0x8604;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v2, k2);
+}
+
+TEST(PayloadRequest, PartialPayload)
+{
+    ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint8_t v1;
+    ipmi::message::Payload localPayload;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, localPayload), 0);
+    // check that the payload was partially unpacked and not in error
+    ASSERT_FALSE(p.fullyUnpacked());
+    ASSERT_FALSE(p.unpackError);
+    // check that the 'extracted' payload is not fully unpacked
+    ASSERT_FALSE(localPayload.fullyUnpacked());
+    uint8_t k1 = 0xbf;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    uint32_t v2;
+    // unpack using the 'extracted' payload
+    ASSERT_EQ(localPayload.unpack(v2), 0);
+    ASSERT_TRUE(localPayload.fullyUnpacked());
+    uint32_t k2 = 0x02008604;
+    ASSERT_EQ(v2, k2);
+}
+
+std::vector<std::string> logs;
+
+extern "C"
+{
+int sd_journal_sendv(const struct iovec* iov, int /* n */)
+{
+    logs.push_back(std::string((char*)iov[0].iov_base, iov[0].iov_len));
+    return 0;
+}
+}
+
+class PayloadLogging : public testing::Test
+{
+  public:
+    void SetUp()
+    {
+        logs.clear();
+    }
+};
+
+TEST_F(PayloadLogging, TrailingOk)
+{
+    {
+        ipmi::message::Payload p({1, 2});
+    }
+    EXPECT_EQ(logs.size(), 0);
+}
+
+TEST_F(PayloadLogging, EnforcingUnchecked)
+{
+    {
+        ipmi::message::Payload p({1, 2});
+        p.trailingOk = false;
+    }
+    EXPECT_EQ(logs.size(), 1);
+}
+
+TEST_F(PayloadLogging, EnforcingUncheckedUnpacked)
+{
+    {
+        ipmi::message::Payload p({1, 2});
+        p.trailingOk = false;
+        uint8_t out;
+        p.unpack(out, out);
+    }
+    EXPECT_EQ(logs.size(), 1);
+}
+
+TEST_F(PayloadLogging, EnforcingUncheckedError)
+{
+    {
+        ipmi::message::Payload p({1, 2});
+        p.trailingOk = false;
+        uint32_t out;
+        p.unpack(out);
+    }
+    EXPECT_EQ(logs.size(), 0);
+}
+
+TEST_F(PayloadLogging, EnforcingChecked)
+{
+    {
+        ipmi::message::Payload p({1, 2});
+        p.trailingOk = false;
+        EXPECT_FALSE(p.fullyUnpacked());
+    }
+    EXPECT_EQ(logs.size(), 0);
+}
+
+TEST_F(PayloadLogging, EnforcingCheckedUnpacked)
+{
+    {
+        ipmi::message::Payload p({1, 2});
+        p.trailingOk = false;
+        uint8_t out;
+        p.unpack(out, out);
+        EXPECT_TRUE(p.fullyUnpacked());
+    }
+    EXPECT_EQ(logs.size(), 0);
+}
+
+TEST_F(PayloadLogging, EnforcingUnpackPayload)
+{
+    {
+        ipmi::message::Payload p;
+        {
+            ipmi::message::Payload q({1, 2});
+            q.trailingOk = false;
+            q.unpack(p);
+        }
+        EXPECT_EQ(logs.size(), 0);
+    }
+    EXPECT_EQ(logs.size(), 1);
+}
+
+TEST_F(PayloadLogging, EnforcingMove)
+{
+    {
+        ipmi::message::Payload p;
+        {
+            ipmi::message::Payload q({1, 2});
+            q.trailingOk = false;
+            p = std::move(q);
+        }
+        EXPECT_EQ(logs.size(), 0);
+    }
+    EXPECT_EQ(logs.size(), 1);
+}
+
+TEST_F(PayloadLogging, EnforcingException)
+{
+    try
+    {
+        ipmi::message::Payload p({1, 2});
+        p.trailingOk = false;
+        throw std::runtime_error("test");
+    }
+    catch (...)
+    {}
+    EXPECT_EQ(logs.size(), 0);
+}
diff --git a/test/message/unpack.cpp b/test/message/unpack.cpp
new file mode 100644
index 0000000..acc6088
--- /dev/null
+++ b/test/message/unpack.cpp
@@ -0,0 +1,897 @@
+/**
+ * Copyright © 2018 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 <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+
+#include <gtest/gtest.h>
+
+TEST(Uints, Uint8)
+{
+    ipmi::SecureBuffer i = {0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint8_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint8_t k = 0x04;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint8TooManyBytes)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint8_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint8_t k = 0x04;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint8InsufficientBytes)
+{
+    ipmi::SecureBuffer i = {};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint8_t v = 0;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that v is zero
+    ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint16)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint16_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint16_t k = 0x8604;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint16TooManyBytes)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint16_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint16_t k = 0x8604;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint16InsufficientBytes)
+{
+    ipmi::SecureBuffer i = {0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint16_t v = 0;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that v is zero
+    ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint32)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint32_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint32_t k = 0x02008604;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint32TooManyBytes)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint32_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint32_t k = 0x02008604;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint32InsufficientBytes)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint32_t v = 0;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that v is zero
+    ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint64)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint64_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint64_t k = 0x1122334402008604ull;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint64TooManyBytes)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44,
+                            0x33, 0x22, 0x11, 0x55};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint64_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint64_t k = 0x1122334402008604ull;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint64InsufficientBytes)
+{
+    ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint64_t v = 0;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that v is zero
+    ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint24)
+{
+    ipmi::SecureBuffer i = {0x58, 0x23, 0x11};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint24_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint24_t k = 0x112358;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(FixedInts, Uint24TooManyBytes)
+{
+    ipmi::SecureBuffer i = {0x58, 0x23, 0x11, 0x00};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint24_t v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint24_t k = 0x112358;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(FixedInts, Uint24InsufficientBytes)
+{
+    ipmi::SecureBuffer i = {0x58, 0x23};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint24_t v = 0;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that v is zero
+    ASSERT_EQ(v, 0);
+}
+
+TEST(FixedInts, Uint3Uint5)
+{
+    // individual bytes are unpacked low-order-bits first
+    // v1 will use [2:0], v2 will use [7:3]
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint3_t v1;
+    uint5_t v2;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint3_t k1 = 0x1;
+    uint5_t k2 = 0x19;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+}
+
+TEST(FixedInts, Uint3Uint4TooManyBits)
+{
+    // high order bit should not get unpacked
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint3_t v1;
+    uint4_t v2;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint3_t k1 = 0x1;
+    uint4_t k2 = 0x9;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+}
+
+TEST(FixedInts, Uint3Uint6InsufficientBits)
+{
+    // insufficient bits to unpack v2
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint3_t v1;
+    uint6_t v2;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v1, v2), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    uint3_t k1 = 0x1;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    // check that v2 is zero
+    ASSERT_EQ(v2, 0);
+}
+
+TEST(Bools, Boolx8)
+{
+    // individual bytes are unpacked low-order-bits first
+    // [v8, v7, v6, v5, v4, v3, v2, v1]
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    bool v8, v7, v6, v5;
+    bool v4, v3, v2, v1;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7, v8), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    // check that the bytes were correctly unpacked (LSB first)
+    bool k8 = true, k7 = true, k6 = false, k5 = false;
+    bool k4 = true, k3 = false, k2 = false, k1 = true;
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+    ASSERT_EQ(v3, k3);
+    ASSERT_EQ(v4, k4);
+    ASSERT_EQ(v5, k5);
+    ASSERT_EQ(v6, k6);
+    ASSERT_EQ(v7, k7);
+    ASSERT_EQ(v8, k8);
+}
+
+TEST(Bools, Boolx8TooManyBits)
+{
+    // high order bit should not get unpacked
+    // individual bytes are unpacked low-order-bits first
+    // [v7, v6, v5, v4, v3, v2, v1]
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    bool v7, v6, v5;
+    bool v4, v3, v2, v1;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that the bytes were correctly unpacked (LSB first)
+    bool k7 = true, k6 = false, k5 = false;
+    bool k4 = true, k3 = false, k2 = false, k1 = true;
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+    ASSERT_EQ(v3, k3);
+    ASSERT_EQ(v4, k4);
+    ASSERT_EQ(v5, k5);
+    ASSERT_EQ(v6, k6);
+    ASSERT_EQ(v7, k7);
+}
+
+TEST(Bools, Boolx8InsufficientBits)
+{
+    // individual bytes are unpacked low-order-bits first
+    // [v8, v7, v6, v5, v4, v3, v2, v1]
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    bool v9;
+    bool v8, v7, v6, v5;
+    bool v4, v3, v2, v1;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v1, v2, v3, v4, v5, v6, v7, v8, v9), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that the bytes were correctly unpacked (LSB first)
+    bool k8 = true, k7 = true, k6 = false, k5 = false;
+    bool k4 = true, k3 = false, k2 = false, k1 = true;
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+    ASSERT_EQ(v3, k3);
+    ASSERT_EQ(v4, k4);
+    ASSERT_EQ(v5, k5);
+    ASSERT_EQ(v6, k6);
+    ASSERT_EQ(v7, k7);
+    ASSERT_EQ(v8, k8);
+}
+
+TEST(Bitsets, Bitset8)
+{
+    // individual bytes are unpacked low-order-bits first
+    // a bitset for 8 bits fills the full byte
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<8> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::bitset<8> k(0xc9);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset7TooManyBits)
+{
+    // individual bytes are unpacked low-order-bits first
+    // a bitset for 8 bits fills the full byte
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<7> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::bitset<7> k(0x49);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset9InsufficientBits)
+{
+    // individual bytes are unpacked low-order-bits first
+    // a bitset for 8 bits fills the full byte
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<9> v;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::bitset<9> k(0);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset3Bitset5)
+{
+    // individual bytes are unpacked low-order-bits first
+    // v1 will use [2:0], v2 will use [7:3]
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<3> v1;
+    std::bitset<5> v2;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::bitset<3> k1(0x1);
+    std::bitset<5> k2(0x19);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+}
+
+TEST(Bitsets, Bitset3Bitset4TooManyBits)
+{
+    // high order bit should not get unpacked
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<3> v1;
+    std::bitset<4> v2;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::bitset<3> k1 = 0x1;
+    std::bitset<4> k2 = 0x9;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+}
+
+TEST(Bitsets, Bitset3Bitset6InsufficientBits)
+{
+    // insufficient bits to unpack v2
+    ipmi::SecureBuffer i = {0xc9};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<3> v1;
+    std::bitset<6> v2;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v1, v2), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::bitset<3> k1 = 0x1;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    // check that v2 is zero
+    ASSERT_EQ(v2, 0);
+}
+
+TEST(Bitsets, Bitset32)
+{
+    // individual bytes are unpacked low-order-bits first
+    // v1 will use 4 bytes, but in LSByte first order
+    // v1[7:0] v1[15:9] v1[23:16] v1[31:24]
+    ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<32> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::bitset<32> k(0xc29186b4);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset31TooManyBits)
+{
+    // high order bit should not get unpacked
+    ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<31> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::bitset<31> k(0x429186b4);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset33InsufficientBits)
+{
+    // insufficient bits to unpack v2
+    ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::bitset<33> v;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked (comprehends unpack errors)
+    ASSERT_FALSE(p.fullyUnpacked());
+    // check that v is zero
+    ASSERT_EQ(v, 0);
+}
+
+TEST(Arrays, Array4xUint8)
+{
+    // an array of bytes will be read verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::array<uint8_t, 4> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint8TooManyBytes)
+{
+    // last byte should not get unpacked
+    // an array of bytes will be read verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04, 0x22};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::array<uint8_t, 4> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint8InsufficientBytes)
+{
+    // last byte should not get unpacked
+    // an array of bytes will be read verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::array<uint8_t, 4> v;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    // arrays of uint8_t will be unpacked all at once
+    // so nothing will get unpacked
+    std::array<uint8_t, 4> k = {{0, 0, 0, 0}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint32)
+{
+    // an array of multi-byte values will be unpacked in order low-order
+    // element first, each multi-byte element in LSByte order
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+                            0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::array<uint32_t, 4> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::array<uint32_t, 4> k = {
+        {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint32TooManyBytes)
+{
+    // last byte should not get unpacked
+    // an array of multi-byte values will be unpacked in order low-order
+    // element first, each multi-byte element in LSByte order
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66,
+                            0x44, 0x22, 0x99, 0x77, 0x55, 0x33,
+                            0x78, 0x56, 0x34, 0x12, 0xaa};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::array<uint32_t, 4> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::array<uint32_t, 4> k = {
+        {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint32InsufficientBytes)
+{
+    // last value should not get unpacked
+    // an array of multi-byte values will be unpacked in order low-order
+    // element first, each multi-byte element in LSByte order
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+                            0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::array<uint32_t, 4> v;
+    // check that the number of bytes matches
+    ASSERT_NE(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    // arrays of uint32_t will be unpacked in a way that looks atomic
+    std::array<uint32_t, 4> k = {{0, 0, 0, 0}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorUint32)
+{
+    // a vector of multi-byte values will be unpacked in order low-order
+    // element first, each multi-byte element in LSByte order
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+                            0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::vector<uint32_t> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799, 0x12345678};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+// combination of TooManyBytes and InsufficientBytes because
+// vectors will attempt to unpack full <T>s until the end of the input
+TEST(Vectors, VectorUint32NonIntegralBytes)
+{
+    // last value should not get unpacked
+    // a vector of multi-byte values will be unpacked in order low-order
+    // element first, each multi-byte element in LSByte order,
+    // and will attempt to consume all bytes remaining
+    // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+    // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+    // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+    // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+    ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+                            0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::vector<uint32_t> v;
+    // check that the vector unpacks successfully
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    // arrays of uint32_t will be unpacked one at a time, so the
+    // last entry should not get unpacked properly
+    std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorUint8)
+{
+    // a vector of bytes will be unpacked verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::vector<uint8_t> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorEmptyOk)
+{
+    // an empty input vector to show that unpacking elements is okay
+    ipmi::SecureBuffer i{};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::vector<uint32_t> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::vector<uint32_t> k{};
+    // check that the unpacked vector is empty as expected
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorOfTuplesOk)
+{
+    // a vector of bytes will be unpacked verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::vector<std::tuple<uint8_t, uint8_t>> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::vector<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorOfTuplesInsufficientBytes)
+{
+    // a vector of bytes will be unpacked verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04, 0xb4};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::vector<std::tuple<uint8_t, uint8_t>> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was not fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::vector<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+// Cannot test TooManyBytes or InsufficientBytes for vector<uint8_t>
+// because it will always unpack whatever bytes are remaining
+// TEST(Vectors, VectorUint8TooManyBytes) {}
+// TEST(Vectors, VectorUint8InsufficientBytes) {}
+
+TEST(UnpackAdvanced, OptionalOk)
+{
+    // a vector of bytes will be unpacked verbatim, low-order element first
+    ipmi::SecureBuffer i = {0xbe, 0x02, 0x00, 0x86, 0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::optional<std::tuple<uint8_t, uint32_t>> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    std::optional<std::tuple<uint8_t, uint32_t>> k{{0xbe, 0x04860002}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(UnpackAdvanced, OptionalInsufficientBytes)
+{
+    // a vector of bytes will be unpacked verbatim, low-order element first
+    ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::optional<std::tuple<uint8_t, uint32_t>> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_FALSE(p.fullyUnpacked());
+    std::optional<std::tuple<uint8_t, uint32_t>> k;
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(UnpackAdvanced, Uints)
+{
+    // all elements will be unpacked in order, with each multi-byte
+    // element being processed LSByte first
+    // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+    // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+    // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+    ipmi::SecureBuffer i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint8_t v1;
+    uint16_t v2;
+    uint32_t v3;
+    uint64_t v4;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2, v3, v4), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint8_t k1 = 0x02;
+    uint16_t k2 = 0x0604;
+    uint32_t k3 = 0x44332211;
+    uint64_t k4 = 0xccbbaa9988776655ull;
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+    ASSERT_EQ(v3, k3);
+    ASSERT_EQ(v4, k4);
+}
+
+TEST(UnpackAdvanced, TupleInts)
+{
+    // all elements will be unpacked in order, with each multi-byte
+    // element being processed LSByte first
+    // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+    // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+    // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+    ipmi::SecureBuffer i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    std::tuple<uint8_t, uint16_t, uint32_t, uint64_t> v;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint8_t k1 = 0x02;
+    uint16_t k2 = 0x0604;
+    uint32_t k3 = 0x44332211;
+    uint64_t k4 = 0xccbbaa9988776655ull;
+    auto k = std::make_tuple(k1, k2, k3, k4);
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v, k);
+}
+
+TEST(UnpackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
+{
+    // each element will be unpacked, filling the low-order bits first
+    // with multi-byte values getting unpacked LSByte first
+    // v1 will use k[0][1:0]
+    // v2 will use k[0][2]
+    // v3[4:0] will use k[0][7:3], v3[6:5] will use k[1][1:0]
+    // v4 will use k[1][2]
+    // v5 will use k[1][7:3]
+    ipmi::SecureBuffer i = {0x9e, 0xdb};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint2_t v1;
+    bool v2;
+    std::bitset<7> v3;
+    bool v4;
+    uint5_t v5;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint2_t k1 = 2;          // binary 0b10
+    bool k2 = true;          // binary 0b1
+    std::bitset<7> k3(0x73); // binary 0b1110011
+    bool k4 = false;         // binary 0b0
+    uint5_t k5 = 27;         // binary 0b11011
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+    ASSERT_EQ(v3, k3);
+    ASSERT_EQ(v4, k4);
+    ASSERT_EQ(v5, k5);
+}
+
+TEST(UnpackAdvanced, UnalignedBitUnpacking)
+{
+    // unaligned multi-byte values will be unpacked the same as
+    // other bits, effectively reading from a large value, low-order
+    // bits first, then consuming the stream LSByte first
+    // v1 will use k[0][1:0]
+    // v2[5:0] will use k[0][7:2], v2[7:6] will use k[1][1:0]
+    // v3 will use k[1][2]
+    // v4[4:0] will use k[1][7:3] v4[12:5] will use k[2][7:0]
+    // v4[15:13] will use k[3][2:0]
+    // v5 will use k[3][3]
+    // v6[3:0] will use k[3][7:0] v6[11:4] will use k[4][7:0]
+    // v6[19:12] will use k[5][7:0] v6[27:20] will use k[6][7:0]
+    // v6[31:28] will use k[7][3:0]
+    // v7 will use k[7][7:4]
+    ipmi::SecureBuffer i = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
+    ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
+    uint2_t v1;
+    uint8_t v2;
+    bool v3;
+    uint16_t v4;
+    bool v5;
+    uint32_t v6;
+    uint4_t v7;
+    // check that the number of bytes matches
+    ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
+    // check that the payload was fully unpacked
+    ASSERT_TRUE(p.fullyUnpacked());
+    uint2_t k1 = 2;           // binary 0b10
+    uint8_t k2 = 0xa5;        // binary 0b10100101
+    bool k3 = false;          // binary 0b0
+    uint16_t k4 = 0xa55a;     // binary 0b1010010101011010
+    bool k5 = true;           // binary 0b1
+    uint32_t k6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
+    uint4_t k7 = 9;           // binary 0b1001
+    // check that the bytes were correctly unpacked (LSB first)
+    ASSERT_EQ(v1, k1);
+    ASSERT_EQ(v2, k2);
+    ASSERT_EQ(v3, k3);
+    ASSERT_EQ(v4, k4);
+    ASSERT_EQ(v5, k5);
+    ASSERT_EQ(v6, k6);
+    ASSERT_EQ(v7, k7);
+}
diff --git a/test/oemrouter_unittest.cpp b/test/oemrouter_unittest.cpp
new file mode 100644
index 0000000..f0c0a01
--- /dev/null
+++ b/test/oemrouter_unittest.cpp
@@ -0,0 +1,175 @@
+#include <ipmid/api.h>
+
+#include <include/ipmid/api-types.hpp>
+#include <ipmid/oemrouter.hpp>
+
+#include <cstring>
+
+#include <gtest/gtest.h>
+
+// Watch for correct singleton behavior.
+static oem::Router* singletonUnderTest;
+
+static ipmid_callback_t wildHandler;
+
+static ipmi_netfn_t lastNetFunction;
+
+// Fake ipmi_register_callback() for this test.
+void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                            ipmi_context_t context, ipmid_callback_t cb,
+                            ipmi_cmd_privilege_t priv)
+{
+    EXPECT_EQ(NETFUN_OEM_GROUP, netfn);
+    EXPECT_EQ(ipmi::cmdWildcard, cmd);
+    EXPECT_EQ(reinterpret_cast<void*>(singletonUnderTest), context);
+    EXPECT_EQ(PRIVILEGE_OEM, priv);
+    lastNetFunction = netfn;
+    wildHandler = cb;
+}
+
+namespace oem
+{
+
+namespace
+{
+void MakeRouter()
+{
+    if (!singletonUnderTest)
+    {
+        singletonUnderTest = mutableRouter();
+    }
+    ASSERT_EQ(singletonUnderTest, mutableRouter());
+}
+
+void ActivateRouter()
+{
+    MakeRouter();
+    singletonUnderTest->activate();
+    ASSERT_EQ(NETFUN_OEM_GROUP, lastNetFunction);
+}
+
+void RegisterWithRouter(Number oen, ipmi_cmd_t cmd, Handler cb)
+{
+    ActivateRouter();
+    singletonUnderTest->registerHandler(oen, cmd, cb);
+}
+
+uint8_t msgPlain[] = {0x56, 0x34, 0x12};
+uint8_t replyPlain[] = {0x56, 0x34, 0x12, 0x31, 0x41};
+uint8_t msgPlus2[] = {0x67, 0x45, 0x23, 0x10, 0x20};
+uint8_t msgBadOen[] = {0x57, 0x34, 0x12};
+
+void RegisterTwoWays(ipmi_cmd_t* nextCmd)
+{
+    Handler f = [](ipmi_cmd_t cmd, [[maybe_unused]] const uint8_t* reqBuf,
+                   uint8_t* replyBuf, size_t* dataLen) {
+        // Check inputs
+        EXPECT_EQ(0x78, cmd);
+        EXPECT_EQ(0, *dataLen); // Excludes OEN
+
+        // Generate reply.
+        *dataLen = 2;
+        std::memcpy(replyBuf, replyPlain + 3, *dataLen);
+        return 0;
+    };
+    RegisterWithRouter(0x123456, 0x78, f);
+
+    *nextCmd = ipmi::cmdWildcard;
+    Handler g = [nextCmd](ipmi_cmd_t cmd, const uint8_t* reqBuf,
+                          [[maybe_unused]] uint8_t* replyBuf, size_t* dataLen) {
+        // Check inputs
+        EXPECT_EQ(*nextCmd, cmd);
+        EXPECT_EQ(2, *dataLen); // Excludes OEN
+        if (2 != *dataLen)
+        {
+            return 0xE0;
+        }
+        EXPECT_EQ(msgPlus2[3], reqBuf[0]);
+        EXPECT_EQ(msgPlus2[4], reqBuf[1]);
+
+        // Generate reply.
+        *dataLen = 0;
+        return 0;
+    };
+    RegisterWithRouter(0x234567, ipmi::cmdWildcard, g);
+}
+} // namespace
+
+TEST(OemRouterTest, MakeRouterProducesConsistentSingleton)
+{
+    MakeRouter();
+}
+
+TEST(OemRouterTest, ActivateRouterSetsLastNetToOEMGROUP)
+{
+    lastNetFunction = 0;
+    ActivateRouter();
+}
+
+TEST(OemRouterTest, VerifiesSpecificCommandMatches)
+{
+    ipmi_cmd_t cmd;
+    uint8_t reply[256];
+    size_t dataLen;
+
+    RegisterTwoWays(&cmd);
+
+    dataLen = 3;
+    EXPECT_EQ(0, wildHandler(NETFUN_OEM_GROUP, 0x78, msgPlain, reply, &dataLen,
+                             nullptr));
+    EXPECT_EQ(5, dataLen);
+    EXPECT_EQ(replyPlain[0], reply[0]);
+    EXPECT_EQ(replyPlain[1], reply[1]);
+    EXPECT_EQ(replyPlain[2], reply[2]);
+    EXPECT_EQ(replyPlain[3], reply[3]);
+    EXPECT_EQ(replyPlain[4], reply[4]);
+}
+
+TEST(OemRouterTest, WildCardMatchesTwoRandomCodes)
+{
+    ipmi_cmd_t cmd;
+    uint8_t reply[256];
+    size_t dataLen;
+
+    RegisterTwoWays(&cmd);
+
+    // Check two random command codes.
+    dataLen = 5;
+    cmd = 0x89;
+    EXPECT_EQ(0, wildHandler(NETFUN_OEM_GROUP, cmd, msgPlus2, reply, &dataLen,
+                             nullptr));
+    EXPECT_EQ(3, dataLen);
+
+    dataLen = 5;
+    cmd = 0x67;
+    EXPECT_EQ(0, wildHandler(NETFUN_OEM_GROUP, cmd, msgPlus2, reply, &dataLen,
+                             nullptr));
+    EXPECT_EQ(3, dataLen);
+}
+
+TEST(OemRouterTest, CommandsAreRejectedIfInvalid)
+{
+    ipmi_cmd_t cmd;
+    uint8_t reply[256];
+    size_t dataLen;
+
+    RegisterTwoWays(&cmd);
+
+    // Message too short to include whole OEN?
+    dataLen = 2;
+    EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID,
+              wildHandler(NETFUN_OEM_GROUP, 0x78, msgPlain, reply, &dataLen,
+                          nullptr));
+
+    // Wrong specific command?
+    dataLen = 3;
+    EXPECT_EQ(IPMI_CC_INVALID, wildHandler(NETFUN_OEM_GROUP, 0x89, msgPlain,
+                                           reply, &dataLen, nullptr));
+
+    // Wrong OEN?
+    dataLen = 3;
+    EXPECT_EQ(IPMI_CC_INVALID, wildHandler(NETFUN_OEM_GROUP, 0x78, msgBadOen,
+                                           reply, &dataLen, nullptr));
+}
+
+} // namespace oem
diff --git a/test/session/closesession_unittest.cpp b/test/session/closesession_unittest.cpp
new file mode 100644
index 0000000..2b184ca
--- /dev/null
+++ b/test/session/closesession_unittest.cpp
@@ -0,0 +1,114 @@
+#include <ipmid/sessionhelper.hpp>
+
+#include <gtest/gtest.h>
+
+TEST(parseSessionInputPayloadTest, ValidObjectPath)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+
+    EXPECT_TRUE(
+        parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle));
+    EXPECT_EQ(0x12a4567d, sessionId);
+    EXPECT_EQ(0x8a, sessionHandle);
+}
+
+TEST(parseSessionInputPayloadTest, InvalidObjectPath)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+    // A valid object path will be like
+    // "/xyz/openbmc_project/ipmi/session/channel/sessionId_sessionHandle"
+    // Ex: "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a"
+    // SessionId    : 0X12a4567d
+    // SessionHandle: 0X8a
+    std::string objectPath = "/xyz/openbmc_project/ipmi/session/eth0/12a4567d";
+
+    EXPECT_FALSE(
+        parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle));
+}
+
+TEST(parseSessionInputPayloadTest, NoObjectPath)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+    std::string objectPath;
+
+    EXPECT_FALSE(
+        parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, ValidSessionId)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0x12a4567d;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_TRUE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, ValidSessionHandle)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0x8a;
+
+    EXPECT_TRUE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, InvalidSessionId)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0x1234b67d;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, InvalidSessionHandle)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0x9b;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, ZeroSessionId_ZeroSessionHandle)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, InvalidObjectPath)
+{
+    // A valid object path will be like
+    // "/xyz/openbmc_project/ipmi/session/channel/sessionId_sessionHandle"
+    // Ex: "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a"
+    // SessionId    : 0X12a4567d
+    // SessionHandle: 0X8a
+    std::string objectPath = "/xyz/openbmc_project/ipmi/session/eth0/12a4567d";
+    uint32_t sessionId = 0x12a4567d;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, NoObjectPath)
+{
+    std::string objectPath;
+    uint32_t sessionId = 0x12a4567d;
+    uint8_t sessionHandle = 0x8a;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
diff --git a/transport/meson.build b/transport/meson.build
new file mode 100644
index 0000000..9e5a241
--- /dev/null
+++ b/transport/meson.build
@@ -0,0 +1,3 @@
+if get_option('transport-implementation') == 'serial'
+    subdir('serialbridge')
+endif
diff --git a/transport/rmcpbridge/.clang-format b/transport/rmcpbridge/.clang-format
new file mode 100644
index 0000000..e5530e6
--- /dev/null
+++ b/transport/rmcpbridge/.clang-format
@@ -0,0 +1,136 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:  Align
+AlignTrailingComments:
+  Kind: Always
+  OverEmptyLines: 1
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Empty
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: true
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakBeforeMultilineStrings: false
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: None
+BraceWrapping:
+  AfterCaseLabel:  true
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterExternBlock: true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  BeforeCatch:     true
+  BeforeElse:      true
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction:   false
+  SplitEmptyRecord:     false
+  SplitEmptyNamespace:  false
+BreakAfterAttributes: Never
+BreakAfterReturnType: Automatic
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+BreakInheritanceList: AfterColon
+BreakStringLiterals: false
+BreakTemplateDeclarations: Yes
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeBlocks: Regroup
+IncludeCategories:
+  - Regex:           '^[<"](gtest|gmock)'
+    Priority:        7
+  - Regex:           '^"config.h"'
+    Priority:        -1
+  - Regex:           '^".*\.h"'
+    Priority:        1
+  - Regex:           '^".*\.hpp"'
+    Priority:        2
+  - Regex:           '^<.*\.h>'
+    Priority:        3
+  - Regex:           '^<.*\.hpp>'
+    Priority:        4
+  - Regex:           '^<.*'
+    Priority:        5
+  - Regex:           '.*'
+    Priority:        6
+IndentCaseLabels: true
+IndentExternBlock: NoIndent
+IndentRequiresClause: true
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+InsertNewlineAtEOF: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+LambdaBodyIndentation: Signature
+LineEnding: LF
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 25
+PenaltyBreakBeforeFirstCallParameter: 50
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 150
+PenaltyIndentedWhitespace: 1
+PointerAlignment: Left
+QualifierAlignment: Left
+ReferenceAlignment: Left
+ReflowComments:  true
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: Keyword
+SortIncludes: CaseSensitive
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: Never
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Latest
+TabWidth:        4
+UseTab:          Never
+...
+
diff --git a/transport/rmcpbridge/.clang-tidy b/transport/rmcpbridge/.clang-tidy
new file mode 100644
index 0000000..4b6eca0
--- /dev/null
+++ b/transport/rmcpbridge/.clang-tidy
@@ -0,0 +1,7 @@
+Checks: '
+    -*,
+    bugprone-unchecked-optional-access,
+    readability-identifier-naming
+'
+WarningsAsErrors: '*'
+HeaderFilterRegex: '(?!^subprojects).*'
diff --git a/transport/rmcpbridge/.gitignore b/transport/rmcpbridge/.gitignore
new file mode 100644
index 0000000..51ef08e
--- /dev/null
+++ b/transport/rmcpbridge/.gitignore
@@ -0,0 +1,3 @@
+/build*/
+/subprojects/*
+!subprojects/*.wrap
diff --git a/transport/rmcpbridge/LICENSE b/transport/rmcpbridge/LICENSE
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/transport/rmcpbridge/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
diff --git a/transport/rmcpbridge/OWNERS b/transport/rmcpbridge/OWNERS
new file mode 100644
index 0000000..05f2bbe
--- /dev/null
+++ b/transport/rmcpbridge/OWNERS
@@ -0,0 +1,48 @@
+# OWNERS
+# ------
+#
+# The OWNERS file maintains the list of individuals responsible for various
+# parts of this repository, including code review and approval.  We use the
+# Gerrit 'owners' plugin, which consumes this file, along with some extra
+# keywords for our own purposes and tooling.
+#
+# For details on the configuration used by 'owners' see:
+#  https://gerrit.googlesource.com/plugins/owners/+/refs/heads/master/owners/src/main/resources/Documentation/config.md
+#
+# An OWNERS file must be in the root of a repository but may also be present
+# in any subdirectory.  The contents of the subdirectory OWNERS file are
+# combined with parent directories unless 'inherit: false' is set.
+#
+# The owners file is YAML and has [up to] 4 top-level keywords.
+#   * owners: A list of individuals who have approval authority on the
+#     repository.
+#
+#   * reviewers: A list of individuals who have requested review notification
+#     on the repository.
+#
+#   * matchers: A list of specific file/path matchers for granular 'owners' and
+#     'reviewers'.  See 'owners' plugin documentation.
+#
+#   * openbmc: A list of openbmc-specific meta-data about owners and reviewers.
+#     - name: preferred name of the individual.
+#     - email: preferred email address of the individual.
+#     - discord: Discord nickname of the individual.
+#
+# It is expected that these 4 sections will be listed in the order above and
+# data within them will be kept sorted.
+
+owners:
+- rushtotom@gmail.com
+- vernon.mauery@gmail.com
+
+reviewers:
+
+matchers:
+
+openbmc:
+- name: Tom Joseph
+  email: rushtotom@gmail.com
+  discord: tomjose
+- name: Vernon Mauery
+  email: vernon.mauery@gmail.com
+  discord: vmauery
diff --git a/transport/rmcpbridge/README.md b/transport/rmcpbridge/README.md
new file mode 100644
index 0000000..89aba20
--- /dev/null
+++ b/transport/rmcpbridge/README.md
@@ -0,0 +1,13 @@
+# phosphor-net-ipmid
+
+## To Build
+
+To build this package, do the following steps:
+
+```sh
+1. ./bootstrap.sh
+2. ./configure ${CONFIGURE_FLAGS}
+3. make
+```
+
+To clean the repository run `./bootstrap.sh clean`.
diff --git a/auth_algo.cpp b/transport/rmcpbridge/auth_algo.cpp
similarity index 100%
rename from auth_algo.cpp
rename to transport/rmcpbridge/auth_algo.cpp
diff --git a/auth_algo.hpp b/transport/rmcpbridge/auth_algo.hpp
similarity index 100%
rename from auth_algo.hpp
rename to transport/rmcpbridge/auth_algo.hpp
diff --git a/comm_module.cpp b/transport/rmcpbridge/comm_module.cpp
similarity index 100%
rename from comm_module.cpp
rename to transport/rmcpbridge/comm_module.cpp
diff --git a/comm_module.hpp b/transport/rmcpbridge/comm_module.hpp
similarity index 100%
rename from comm_module.hpp
rename to transport/rmcpbridge/comm_module.hpp
diff --git a/command/channel_auth.cpp b/transport/rmcpbridge/command/channel_auth.cpp
similarity index 100%
rename from command/channel_auth.cpp
rename to transport/rmcpbridge/command/channel_auth.cpp
diff --git a/command/channel_auth.hpp b/transport/rmcpbridge/command/channel_auth.hpp
similarity index 100%
rename from command/channel_auth.hpp
rename to transport/rmcpbridge/command/channel_auth.hpp
diff --git a/command/guid.cpp b/transport/rmcpbridge/command/guid.cpp
similarity index 100%
rename from command/guid.cpp
rename to transport/rmcpbridge/command/guid.cpp
diff --git a/command/guid.hpp b/transport/rmcpbridge/command/guid.hpp
similarity index 100%
rename from command/guid.hpp
rename to transport/rmcpbridge/command/guid.hpp
diff --git a/command/open_session.cpp b/transport/rmcpbridge/command/open_session.cpp
similarity index 100%
rename from command/open_session.cpp
rename to transport/rmcpbridge/command/open_session.cpp
diff --git a/command/open_session.hpp b/transport/rmcpbridge/command/open_session.hpp
similarity index 100%
rename from command/open_session.hpp
rename to transport/rmcpbridge/command/open_session.hpp
diff --git a/command/payload_cmds.cpp b/transport/rmcpbridge/command/payload_cmds.cpp
similarity index 100%
rename from command/payload_cmds.cpp
rename to transport/rmcpbridge/command/payload_cmds.cpp
diff --git a/command/payload_cmds.hpp b/transport/rmcpbridge/command/payload_cmds.hpp
similarity index 100%
rename from command/payload_cmds.hpp
rename to transport/rmcpbridge/command/payload_cmds.hpp
diff --git a/command/rakp12.cpp b/transport/rmcpbridge/command/rakp12.cpp
similarity index 100%
rename from command/rakp12.cpp
rename to transport/rmcpbridge/command/rakp12.cpp
diff --git a/command/rakp12.hpp b/transport/rmcpbridge/command/rakp12.hpp
similarity index 100%
rename from command/rakp12.hpp
rename to transport/rmcpbridge/command/rakp12.hpp
diff --git a/command/rakp34.cpp b/transport/rmcpbridge/command/rakp34.cpp
similarity index 100%
rename from command/rakp34.cpp
rename to transport/rmcpbridge/command/rakp34.cpp
diff --git a/command/rakp34.hpp b/transport/rmcpbridge/command/rakp34.hpp
similarity index 100%
rename from command/rakp34.hpp
rename to transport/rmcpbridge/command/rakp34.hpp
diff --git a/command/session_cmds.cpp b/transport/rmcpbridge/command/session_cmds.cpp
similarity index 100%
rename from command/session_cmds.cpp
rename to transport/rmcpbridge/command/session_cmds.cpp
diff --git a/command/session_cmds.hpp b/transport/rmcpbridge/command/session_cmds.hpp
similarity index 100%
rename from command/session_cmds.hpp
rename to transport/rmcpbridge/command/session_cmds.hpp
diff --git a/command/sol_cmds.cpp b/transport/rmcpbridge/command/sol_cmds.cpp
similarity index 100%
rename from command/sol_cmds.cpp
rename to transport/rmcpbridge/command/sol_cmds.cpp
diff --git a/command/sol_cmds.hpp b/transport/rmcpbridge/command/sol_cmds.hpp
similarity index 100%
rename from command/sol_cmds.hpp
rename to transport/rmcpbridge/command/sol_cmds.hpp
diff --git a/command_table.cpp b/transport/rmcpbridge/command_table.cpp
similarity index 100%
rename from command_table.cpp
rename to transport/rmcpbridge/command_table.cpp
diff --git a/command_table.hpp b/transport/rmcpbridge/command_table.hpp
similarity index 100%
rename from command_table.hpp
rename to transport/rmcpbridge/command_table.hpp
diff --git a/crypt_algo.cpp b/transport/rmcpbridge/crypt_algo.cpp
similarity index 100%
rename from crypt_algo.cpp
rename to transport/rmcpbridge/crypt_algo.cpp
diff --git a/crypt_algo.hpp b/transport/rmcpbridge/crypt_algo.hpp
similarity index 100%
rename from crypt_algo.hpp
rename to transport/rmcpbridge/crypt_algo.hpp
diff --git a/endian.hpp b/transport/rmcpbridge/endian.hpp
similarity index 100%
rename from endian.hpp
rename to transport/rmcpbridge/endian.hpp
diff --git a/integrity_algo.cpp b/transport/rmcpbridge/integrity_algo.cpp
similarity index 100%
rename from integrity_algo.cpp
rename to transport/rmcpbridge/integrity_algo.cpp
diff --git a/integrity_algo.hpp b/transport/rmcpbridge/integrity_algo.hpp
similarity index 100%
rename from integrity_algo.hpp
rename to transport/rmcpbridge/integrity_algo.hpp
diff --git a/main.cpp b/transport/rmcpbridge/main.cpp
similarity index 100%
rename from main.cpp
rename to transport/rmcpbridge/main.cpp
diff --git a/main.hpp b/transport/rmcpbridge/main.hpp
similarity index 100%
rename from main.hpp
rename to transport/rmcpbridge/main.hpp
diff --git a/transport/rmcpbridge/meson.build b/transport/rmcpbridge/meson.build
new file mode 100644
index 0000000..0e449d4
--- /dev/null
+++ b/transport/rmcpbridge/meson.build
@@ -0,0 +1,120 @@
+project(
+    'phosphor-net-ipmid',
+    'cpp',
+    version: '1.0.0',
+    meson_version: '>=1.1.1',
+    default_options: [
+        'warning_level=3',
+        'werror=true',
+        'cpp_std=c++23',
+        'buildtype=debugoptimized',
+        'b_lto=true',
+    ],
+)
+
+conf_data = configuration_data()
+conf_data.set('RMCP_PING', get_option('rmcp_ping').allowed())
+conf_data.set('PAM_AUTHENTICATE', get_option('pam_authenticate').allowed())
+
+configure_file(output: 'config.h', configuration: conf_data)
+
+sdbusplus_dep = dependency('sdbusplus')
+phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
+phosphor_logging_dep = dependency('phosphor-logging')
+libsystemd_dep = dependency('libsystemd')
+libcrypto_dep = dependency('libcrypto')
+ipmid_dep = dependency('libipmid')
+userlayer_dep = dependency('libuserlayer')
+channellayer_dep = dependency('libchannellayer')
+
+# Project Arguments
+cpp = meson.get_compiler('cpp')
+if cpp.has_header('CLI/CLI.hpp')
+    cli11_dep = declare_dependency()
+else
+    cli11_dep = dependency('CLI11')
+endif
+
+add_project_arguments(
+    cpp.get_supported_arguments(
+        [
+            '-DBOOST_ERROR_CODE_HEADER_ONLY',
+            '-DBOOST_SYSTEM_NO_DEPRECATED',
+            '-DBOOST_COROUTINES_NO_DEPRECATION_WARNING',
+            '-DBOOST_ASIO_DISABLE_THREADS',
+            '-DBOOST_ALL_NO_LIB',
+        ],
+    ),
+    language: 'cpp',
+)
+
+deps = [
+    cli11_dep,
+    ipmid_dep,
+    userlayer_dep,
+    channellayer_dep,
+    libcrypto_dep,
+    libsystemd_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+]
+
+sources = [
+    'auth_algo.cpp',
+    'sessions_manager.cpp',
+    'message_parsers.cpp',
+    'message_handler.cpp',
+    'command_table.cpp',
+    'command/channel_auth.cpp',
+    'command/guid.cpp',
+    'command/open_session.cpp',
+    'command/rakp12.cpp',
+    'command/rakp34.cpp',
+    'command/session_cmds.cpp',
+    'comm_module.cpp',
+    'main.cpp',
+    'integrity_algo.cpp',
+    'crypt_algo.cpp',
+    'sd_event_loop.cpp',
+    'sol/sol_manager.cpp',
+    'sol/sol_context.cpp',
+    'command/sol_cmds.cpp',
+    'command/payload_cmds.cpp',
+    'sol_module.cpp',
+]
+
+executable(
+    'netipmid',
+    sources,
+    implicit_include_directories: true,
+    include_directories: ['command', 'sol'],
+    dependencies: deps,
+    install: true,
+    install_dir: get_option('bindir'),
+)
+
+systemd = dependency('systemd')
+systemd_system_unit_dir = systemd.get_variable(
+    'systemdsystemunitdir',
+    pkgconfig_define: ['prefix', get_option('prefix')],
+)
+
+configure_file(
+    input: 'phosphor-ipmi-net@.service',
+    output: 'phosphor-ipmi-net@.service',
+    copy: true,
+    install_dir: systemd_system_unit_dir,
+)
+
+configure_file(
+    input: 'phosphor-ipmi-net@.socket',
+    output: 'phosphor-ipmi-net@.socket',
+    copy: true,
+    install_dir: systemd_system_unit_dir,
+)
+
+build_tests = get_option('tests')
+if build_tests.allowed()
+    subdir('test')
+endif
diff --git a/transport/rmcpbridge/meson.options b/transport/rmcpbridge/meson.options
new file mode 100644
index 0000000..6f9cbaa
--- /dev/null
+++ b/transport/rmcpbridge/meson.options
@@ -0,0 +1,15 @@
+option('tests', type: 'feature', value: 'enabled', description: 'Build tests')
+
+option(
+    'rmcp_ping',
+    type: 'feature',
+    value: 'enabled',
+    description: 'Enable RMCP Ping support',
+)
+
+option(
+    'pam_authenticate',
+    type: 'feature',
+    value: 'enabled',
+    description: 'Enable Pam Authenticate',
+)
diff --git a/message.hpp b/transport/rmcpbridge/message.hpp
similarity index 100%
rename from message.hpp
rename to transport/rmcpbridge/message.hpp
diff --git a/message_handler.cpp b/transport/rmcpbridge/message_handler.cpp
similarity index 100%
rename from message_handler.cpp
rename to transport/rmcpbridge/message_handler.cpp
diff --git a/message_handler.hpp b/transport/rmcpbridge/message_handler.hpp
similarity index 100%
rename from message_handler.hpp
rename to transport/rmcpbridge/message_handler.hpp
diff --git a/message_parsers.cpp b/transport/rmcpbridge/message_parsers.cpp
similarity index 100%
rename from message_parsers.cpp
rename to transport/rmcpbridge/message_parsers.cpp
diff --git a/message_parsers.hpp b/transport/rmcpbridge/message_parsers.hpp
similarity index 100%
rename from message_parsers.hpp
rename to transport/rmcpbridge/message_parsers.hpp
diff --git a/phosphor-ipmi-net@.service b/transport/rmcpbridge/phosphor-ipmi-net@.service
similarity index 100%
rename from phosphor-ipmi-net@.service
rename to transport/rmcpbridge/phosphor-ipmi-net@.service
diff --git a/phosphor-ipmi-net@.socket b/transport/rmcpbridge/phosphor-ipmi-net@.socket
similarity index 100%
rename from phosphor-ipmi-net@.socket
rename to transport/rmcpbridge/phosphor-ipmi-net@.socket
diff --git a/prng.hpp b/transport/rmcpbridge/prng.hpp
similarity index 100%
rename from prng.hpp
rename to transport/rmcpbridge/prng.hpp
diff --git a/rmcp.hpp b/transport/rmcpbridge/rmcp.hpp
similarity index 100%
rename from rmcp.hpp
rename to transport/rmcpbridge/rmcp.hpp
diff --git a/sd_event_loop.cpp b/transport/rmcpbridge/sd_event_loop.cpp
similarity index 100%
rename from sd_event_loop.cpp
rename to transport/rmcpbridge/sd_event_loop.cpp
diff --git a/sd_event_loop.hpp b/transport/rmcpbridge/sd_event_loop.hpp
similarity index 100%
rename from sd_event_loop.hpp
rename to transport/rmcpbridge/sd_event_loop.hpp
diff --git a/session.hpp b/transport/rmcpbridge/session.hpp
similarity index 100%
rename from session.hpp
rename to transport/rmcpbridge/session.hpp
diff --git a/sessions_manager.cpp b/transport/rmcpbridge/sessions_manager.cpp
similarity index 100%
rename from sessions_manager.cpp
rename to transport/rmcpbridge/sessions_manager.cpp
diff --git a/sessions_manager.hpp b/transport/rmcpbridge/sessions_manager.hpp
similarity index 100%
rename from sessions_manager.hpp
rename to transport/rmcpbridge/sessions_manager.hpp
diff --git a/socket_channel.hpp b/transport/rmcpbridge/socket_channel.hpp
similarity index 100%
rename from socket_channel.hpp
rename to transport/rmcpbridge/socket_channel.hpp
diff --git a/sol/console_buffer.hpp b/transport/rmcpbridge/sol/console_buffer.hpp
similarity index 100%
rename from sol/console_buffer.hpp
rename to transport/rmcpbridge/sol/console_buffer.hpp
diff --git a/sol/sol_context.cpp b/transport/rmcpbridge/sol/sol_context.cpp
similarity index 100%
rename from sol/sol_context.cpp
rename to transport/rmcpbridge/sol/sol_context.cpp
diff --git a/sol/sol_context.hpp b/transport/rmcpbridge/sol/sol_context.hpp
similarity index 100%
rename from sol/sol_context.hpp
rename to transport/rmcpbridge/sol/sol_context.hpp
diff --git a/sol/sol_manager.cpp b/transport/rmcpbridge/sol/sol_manager.cpp
similarity index 100%
rename from sol/sol_manager.cpp
rename to transport/rmcpbridge/sol/sol_manager.cpp
diff --git a/sol/sol_manager.hpp b/transport/rmcpbridge/sol/sol_manager.hpp
similarity index 100%
rename from sol/sol_manager.hpp
rename to transport/rmcpbridge/sol/sol_manager.hpp
diff --git a/sol_module.cpp b/transport/rmcpbridge/sol_module.cpp
similarity index 100%
rename from sol_module.cpp
rename to transport/rmcpbridge/sol_module.cpp
diff --git a/sol_module.hpp b/transport/rmcpbridge/sol_module.hpp
similarity index 100%
rename from sol_module.hpp
rename to transport/rmcpbridge/sol_module.hpp
diff --git a/subprojects/CLI11.wrap b/transport/rmcpbridge/subprojects/CLI11.wrap
similarity index 100%
rename from subprojects/CLI11.wrap
rename to transport/rmcpbridge/subprojects/CLI11.wrap
diff --git a/subprojects/googletest.wrap b/transport/rmcpbridge/subprojects/googletest.wrap
similarity index 100%
rename from subprojects/googletest.wrap
rename to transport/rmcpbridge/subprojects/googletest.wrap
diff --git a/transport/rmcpbridge/subprojects/phosphor-dbus-interfaces.wrap b/transport/rmcpbridge/subprojects/phosphor-dbus-interfaces.wrap
new file mode 100644
index 0000000..346aa0c
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/phosphor-dbus-interfaces.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-dbus-interfaces.git
+revision = HEAD
+
+[provide]
+phosphor-dbus-interfaces = phosphor_dbus_interfaces_dep
diff --git a/subprojects/phosphor-host-ipmid.wrap b/transport/rmcpbridge/subprojects/phosphor-host-ipmid.wrap
similarity index 100%
rename from subprojects/phosphor-host-ipmid.wrap
rename to transport/rmcpbridge/subprojects/phosphor-host-ipmid.wrap
diff --git a/transport/rmcpbridge/subprojects/phosphor-logging.wrap b/transport/rmcpbridge/subprojects/phosphor-logging.wrap
new file mode 100644
index 0000000..71eee8b
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/phosphor-logging.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-logging.git
+revision = HEAD
+
+[provide]
+phosphor-logging = phosphor_logging_dep
diff --git a/transport/rmcpbridge/subprojects/sdbusplus.wrap b/transport/rmcpbridge/subprojects/sdbusplus.wrap
new file mode 100644
index 0000000..7b076d0
--- /dev/null
+++ b/transport/rmcpbridge/subprojects/sdbusplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdbusplus.git
+revision = HEAD
+
+[provide]
+sdbusplus = sdbusplus_dep
diff --git a/test/cipher.cpp b/transport/rmcpbridge/test/cipher.cpp
similarity index 100%
rename from test/cipher.cpp
rename to transport/rmcpbridge/test/cipher.cpp
diff --git a/transport/rmcpbridge/test/meson.build b/transport/rmcpbridge/test/meson.build
new file mode 100644
index 0000000..6fcfd04
--- /dev/null
+++ b/transport/rmcpbridge/test/meson.build
@@ -0,0 +1,38 @@
+gtest_dep = dependency('gtest', main: true, disabler: true, required: false)
+gmock_dep = dependency('gmock', disabler: true, required: false)
+if not gtest_dep.found() or not gmock_dep.found()
+    gtest_proj = import('cmake').subproject('googletest', required: false)
+    if gtest_proj.found()
+        gtest_dep = declare_dependency(
+            dependencies: [
+                dependency('threads'),
+                gtest_proj.dependency('gtest'),
+                gtest_proj.dependency('gtest_main'),
+            ],
+        )
+        gmock_dep = gtest_proj.dependency('gmock')
+    else
+        assert(
+            not get_option('tests').enabled(),
+            'Googletest is required if tests are enabled',
+        )
+    endif
+endif
+
+test_sources = ['../integrity_algo.cpp', '../crypt_algo.cpp']
+
+tests = ['cipher.cpp']
+
+foreach t : tests
+    test(
+        t,
+        executable(
+            t.underscorify(),
+            t,
+            test_sources,
+            include_directories: ['..'],
+            dependencies: [gtest_dep, gmock_dep, libcrypto_dep],
+        ),
+        workdir: meson.current_source_dir(),
+    )
+endforeach
diff --git a/transport/serialbridge/meson.build b/transport/serialbridge/meson.build
new file mode 100644
index 0000000..6919c75
--- /dev/null
+++ b/transport/serialbridge/meson.build
@@ -0,0 +1,41 @@
+CLI11_dep = dependency('CLI11')
+
+deps = [
+    dependency('libsystemd'),
+    dependency('systemd'),
+    sdeventplus_dep,
+    stdplus_dep,
+    sdbusplus_dep,
+    phosphor_logging_dep,
+    CLI11_dep,
+]
+
+serialbridged = executable(
+    'serialbridged',
+    'serialbridged.cpp',
+    'serialcmd.cpp',
+    dependencies: deps,
+    install: true,
+    install_dir: get_option('libexecdir'),
+)
+
+# Configure and install systemd unit files
+systemd = dependency('systemd')
+if systemd.found()
+    conf_data = configuration_data()
+    conf_data.set(
+        'BIN',
+        get_option('prefix') / get_option('libexecdir') / serialbridged.name(),
+    )
+    configure_file(
+        input: 'serialbridge@.service.in',
+        output: 'serialbridge@.service',
+        configuration: conf_data,
+        install: true,
+        install_dir: systemd.get_variable(pkgconfig: 'systemdsystemunitdir'),
+    )
+endif
+
+if not get_option('tests').disabled()
+    subdir('test')
+endif
diff --git a/transport/serialbridge/serialbridge@.service.in b/transport/serialbridge/serialbridge@.service.in
new file mode 100644
index 0000000..a7bfd45
--- /dev/null
+++ b/transport/serialbridge/serialbridge@.service.in
@@ -0,0 +1,18 @@
+[Unit]
+Description=Phosphor IPMI Serial DBus Bridge
+StartLimitBurst=3
+StartLimitIntervalSec=300
+After=phosphor-ipmi-host.service
+
+[Service]
+Restart=always
+RestartSec=10
+TimeoutStartSec=60
+TimeoutStopSec=60
+ExecStartPre=/bin/stty -F /dev/"%i" 115200 litout -crtscts -ixon -echo raw
+ExecStart=@BIN@ -d "%i"
+SyslogIdentifier=serialbridged-%i
+
+[Install]
+WantedBy=multi-user.target
+RequiredBy=
diff --git a/transport/serialbridge/serialbridged.cpp b/transport/serialbridge/serialbridged.cpp
new file mode 100644
index 0000000..b022dc6
--- /dev/null
+++ b/transport/serialbridge/serialbridged.cpp
@@ -0,0 +1,85 @@
+#include "serialcmd.hpp"
+
+#include <systemd/sd-daemon.h>
+
+#include <CLI/CLI.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/slot.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/source/io.hpp>
+#include <sdeventplus/source/signal.hpp>
+#include <stdplus/exception.hpp>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/fd/ops.hpp>
+#include <stdplus/signal.hpp>
+
+namespace serialbridge
+{
+
+using sdeventplus::source::IO;
+using sdeventplus::source::Signal;
+using stdplus::fd::OpenAccess;
+using stdplus::fd::OpenFlag;
+using stdplus::fd::OpenFlags;
+
+int execute(const std::string& channel, const bool& verbose)
+{
+    // Set up DBus and event loop
+    auto event = sdeventplus::Event::get_default();
+    auto bus = sdbusplus::bus::new_default();
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+
+    // Configure basic signal handling
+    auto exit_handler = [&event](Signal&, const struct signalfd_siginfo*) {
+        lg2::error("Interrupted, Exiting\n");
+        event.exit(0);
+    };
+    stdplus::signal::block(SIGINT);
+    Signal sig_init(event, SIGINT, exit_handler);
+    stdplus::signal::block(SIGTERM);
+    Signal sig_term(event, SIGTERM, exit_handler);
+
+    // Open an FD for the UART channel
+    stdplus::ManagedFd uart = stdplus::fd::open(
+        std::format("/dev/{}", channel.c_str()),
+        OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::NonBlock));
+    sdbusplus::slot_t slot(nullptr);
+
+    std::unique_ptr<SerialChannel> serialchannel =
+        std::make_unique<SerialChannel>(verbose);
+
+    // Add a reader to the bus for handling inbound IPMI
+    IO ioSource(event, uart.get(), EPOLLIN | EPOLLET,
+                stdplus::exception::ignore(
+                    [&serialchannel, &uart, &bus, &slot](IO&, int, uint32_t) {
+                        serialchannel->read(uart, bus, slot);
+                    }));
+
+    sd_notify(0, "READY=1");
+    return event.loop();
+}
+
+} // namespace serialbridge
+
+int main(int argc, char* argv[])
+{
+    std::string device;
+    bool verbose = 0;
+
+    // Parse input parameter
+    CLI::App app("Serial IPMI Bridge");
+    app.add_option("-d,--device", device, "select uart device");
+    app.add_option("-v,--verbose", verbose, "enable debug message");
+    CLI11_PARSE(app, argc, argv);
+
+    try
+    {
+        return serialbridge::execute(device, verbose);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("FAILED: {MSG}\n", "MSG", e);
+        return 1;
+    }
+}
diff --git a/transport/serialbridge/serialcmd.cpp b/transport/serialbridge/serialcmd.cpp
new file mode 100644
index 0000000..ec84f5c
--- /dev/null
+++ b/transport/serialbridge/serialcmd.cpp
@@ -0,0 +1,340 @@
+#include "serialcmd.hpp"
+
+#include <fmt/format.h>
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/exception.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/slot.hpp>
+#include <stdplus/exception.hpp>
+#include <stdplus/fd/ops.hpp>
+
+#include <numeric>
+#include <ranges>
+#include <unordered_map>
+
+namespace serialbridge
+{
+
+/**
+ * @brief Table of special characters
+ */
+static const std::unordered_map<uint8_t, uint8_t> characters = {
+    {bmStart, 0xB0},     /* start */
+    {bmStop, 0xB5},      /* stop */
+    {bmHandshake, 0xB6}, /* packet handshake */
+    {bmEscape, 0xBA},    /* data escape */
+    {0x1B, 0x3B}         /* escape */
+};
+
+/**
+ * @brief Calculate IPMI checksum
+ */
+uint8_t SerialChannel::calculateChecksum(std::span<uint8_t> data)
+{
+    uint8_t checksum;
+
+    checksum = std::accumulate(data.begin(), data.end(), 0);
+    checksum = (~checksum) + 1;
+
+    // return checksum
+    return checksum;
+}
+
+/**
+ * @brief Return unescaped character for the given one
+ */
+uint8_t SerialChannel::getUnescapedCharacter(uint8_t c)
+{
+    auto search =
+        std::find_if(characters.begin(), characters.end(),
+                     [c](const auto& map_set) { return map_set.second == c; });
+
+    if (search == characters.end())
+    {
+        return c;
+    }
+
+    return search->first;
+}
+
+/**
+ * @brief Process IPMI Serial Request State Machine
+ */
+int SerialChannel::consumeIpmiSerialPacket(
+    std::span<uint8_t>& escapedDataBytes,
+    std::vector<uint8_t>& unescapedDataBytes)
+{
+    unescapedDataBytes.reserve(escapedDataBytes.size());
+
+    for (auto c : escapedDataBytes)
+    {
+        if (c == bmStart) // START
+        {
+            msgState = MsgState::msgInProgress;
+        }
+        else if (msgState == MsgState::msgIdle)
+        {
+            continue;
+        }
+        else if (msgState == MsgState::msgInEscape)
+        {
+            uint8_t unescapedCharacter;
+            unescapedCharacter = getUnescapedCharacter(c);
+
+            if (unescapedCharacter == c)
+            {
+                // error, then reset
+                msgState = MsgState::msgIdle;
+                unescapedDataBytes.clear();
+                continue;
+            }
+
+            unescapedDataBytes.push_back(unescapedCharacter);
+            msgState = MsgState::msgInProgress;
+        }
+        else if (c == bmEscape)
+        {
+            msgState = MsgState::msgInEscape;
+            continue;
+        }
+        else if (c == bmStop) // STOP
+        {
+            msgState = MsgState::msgIdle;
+            return true;
+        }
+        else if (c == bmHandshake) // Handshake
+        {
+            unescapedDataBytes.clear();
+            continue;
+        }
+        else if (msgState == MsgState::msgInProgress)
+        {
+            unescapedDataBytes.push_back(c);
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @brief Encapsluate response to avoid escape character
+ */
+uint8_t SerialChannel::processEscapedCharacter(std::vector<uint8_t>& buffer,
+                                               const std::vector<uint8_t>& data)
+{
+    uint8_t checksum = 0;
+
+    std::ranges::for_each(data.begin(), data.end(),
+                          [&buffer, &checksum](const auto& c) {
+                              auto search = characters.find(c);
+                              if (search != characters.end())
+                              {
+                                  buffer.push_back(bmEscape);
+                                  buffer.push_back(search->second);
+                              }
+                              else
+                              {
+                                  buffer.push_back(c);
+                              }
+
+                              checksum += c;
+                          });
+
+    return checksum;
+}
+
+/**
+ * @brief Write function
+ */
+int SerialChannel::write(stdplus::Fd& uart, uint8_t rsAddr, uint8_t rqAddr,
+                         uint8_t seq, sdbusplus::message_t&& m)
+{
+    std::span<uint8_t> out;
+    uint8_t checksum;
+
+    try
+    {
+        if (m.is_method_error())
+        {
+            // Extra copy to workaround lack of `const sd_bus_error` constructor
+            auto error = *m.get_error();
+            throw sdbusplus::exception::SdBusError(&error, "ipmid response");
+        }
+
+        uint8_t netFn = 0xff;
+        uint8_t lun = 0xff;
+        uint8_t cmd = 0xff;
+        uint8_t cc = 0xff;
+        std::vector<uint8_t> data;
+
+        m.read(std::tie(netFn, lun, cmd, cc, data));
+
+        uint8_t netFnLun = (netFn << netFnShift) | (lun & lunMask);
+        uint8_t seqLun = (seq << netFnShift) | (lun & lunMask);
+
+        std::vector<uint8_t> connectionHeader = {rqAddr, netFnLun};
+        std::vector<uint8_t> messageHeader = {rsAddr, seqLun, cmd, cc};
+
+        // Reserve the buffer size to avoid relloc and copy
+        responseBuffer.clear();
+        responseBuffer.reserve(
+            sizeof(struct IpmiSerialHeader) + 2 * data.size() +
+            4); // 4 for bmStart & bmStop & 2 checksums
+
+        // bmStart
+        responseBuffer.push_back(bmStart);
+
+        // Assemble connection header and checksum
+        checksum = processEscapedCharacter(responseBuffer, connectionHeader);
+        responseBuffer.push_back(-checksum); // checksum1
+
+        // Assemble response message and checksum
+        checksum = processEscapedCharacter(responseBuffer, messageHeader);
+        checksum +=
+            processEscapedCharacter(responseBuffer, std::vector<uint8_t>(data));
+        responseBuffer.push_back(-checksum); // checksum2
+
+        // bmStop
+        responseBuffer.push_back(bmStop);
+
+        out = std::span<uint8_t>(responseBuffer.begin(), responseBuffer.end());
+
+        if (verbose)
+        {
+            lg2::info(
+                "Write serial request message with len={LEN}, netfn={NETFN}, "
+                "lun={LUN}, cmd={CMD}, seq={SEQ}",
+                "LEN", responseBuffer.size(), "NETFN", netFn, "LUN", lun, "CMD",
+                cmd, "SEQ", seq);
+
+            std::string msgData = "Tx: ";
+            for (auto c : responseBuffer)
+            {
+                msgData += std::format("{:#x} ", c);
+            }
+            lg2::info(msgData.c_str());
+        }
+
+        stdplus::fd::writeExact(uart, out);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("IPMI Response failure: {MSG}", "MSG", e);
+
+        return -1;
+    }
+
+    return out.size();
+}
+
+/**
+ * @brief Read function
+ */
+void SerialChannel::read(stdplus::Fd& uart, sdbusplus::bus_t& bus,
+                         sdbusplus::slot_t& outstanding)
+{
+    std::array<uint8_t, ipmiSerialMaxBufferSize> buffer;
+    auto ipmiSerialPacket = stdplus::fd::read(uart, buffer);
+
+    if (ipmiSerialPacket.empty())
+    {
+        return;
+    }
+
+    if (outstanding)
+    {
+        lg2::error("Canceling outstanding request \n");
+        outstanding = sdbusplus::slot_t(nullptr);
+    }
+
+    // process ipmi serial packet
+    if (!consumeIpmiSerialPacket(ipmiSerialPacket, requestBuffer))
+    {
+        lg2::info("Wait for more data ... \n");
+        return;
+    }
+
+    // validate ipmi serial packet length
+    if (requestBuffer.size() <
+        (sizeof(struct IpmiSerialHeader) + ipmiSerialChecksumSize))
+    {
+        lg2::error("Invalid request length, ignoring \n");
+        requestBuffer.clear();
+        return;
+    }
+
+    // validate checksum1
+    if (calculateChecksum(std::span<uint8_t>(requestBuffer.begin(),
+                                             ipmiSerialConnectionHeaderLength)))
+    {
+        lg2::error("Invalid request checksum 1 \n");
+        requestBuffer.clear();
+        return;
+    }
+
+    // validate checksum2
+    if (calculateChecksum(std::span<uint8_t>(
+            &requestBuffer[ipmiSerialConnectionHeaderLength],
+            requestBuffer.size() - ipmiSerialConnectionHeaderLength)))
+    {
+        lg2::error("Invalid request checksum 2 \n");
+        requestBuffer.clear();
+        return;
+    }
+
+    auto m = bus.new_method_call("xyz.openbmc_project.Ipmi.Host",
+                                 "/xyz/openbmc_project/Ipmi",
+                                 "xyz.openbmc_project.Ipmi.Server", "execute");
+
+    std::map<std::string, std::variant<int>> options;
+    struct IpmiSerialHeader* header =
+        reinterpret_cast<struct IpmiSerialHeader*>(requestBuffer.data());
+
+    uint8_t rsAddr = header->rsAddr;
+    uint8_t netFn = header->rsNetFnLUN >> netFnShift;
+    uint8_t lun = header->rsNetFnLUN & lunMask;
+    uint8_t rqAddr = header->rqAddr;
+    uint8_t seq = header->rqSeqLUN >> netFnShift;
+    uint8_t cmd = header->cmd;
+
+    std::span reqSpan{requestBuffer.begin(),
+                      requestBuffer.end() -
+                          ipmiSerialChecksumSize}; // remove checksum 2
+    m.append(netFn, lun, cmd, reqSpan.subspan(sizeof(IpmiSerialHeader)),
+             options);
+
+    if (verbose)
+    {
+        lg2::info("Read serial request message with len={LEN}, netFn={NETFN}, "
+                  "lun={LUN}, cmd={CMD}, seq={SEQ}",
+                  "LEN", requestBuffer.size(), "NETFN", netFn, "LUN", lun,
+                  "CMD", cmd, "SEQ", seq);
+
+        std::string msgData = "Rx: ";
+        for (auto c : requestBuffer)
+        {
+            msgData += std::format("{:#x} ", c);
+        }
+        lg2::info(msgData.c_str());
+    }
+
+    outstanding = m.call_async(stdplus::exception::ignore(
+        [&outstanding, this, &uart, _rsAddr{rsAddr}, _rqAddr{rqAddr},
+         _seq{seq}](sdbusplus::message_t&& m) {
+            outstanding = sdbusplus::slot_t(nullptr);
+
+            if (write(uart, _rsAddr, _rqAddr, _seq, std::move(m)) < 0)
+            {
+                lg2::error(
+                    "Occur an error while attempting to send the response.");
+            }
+        }));
+
+    requestBuffer.clear();
+
+    return;
+}
+
+} // namespace serialbridge
diff --git a/transport/serialbridge/serialcmd.hpp b/transport/serialbridge/serialcmd.hpp
new file mode 100644
index 0000000..985921c
--- /dev/null
+++ b/transport/serialbridge/serialcmd.hpp
@@ -0,0 +1,64 @@
+#pragma once
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/slot.hpp>
+#include <stdplus/fd/intf.hpp>
+
+namespace serialbridge
+{
+
+static constexpr auto bmStart = 0xA0;
+static constexpr auto bmStop = 0xA5;
+static constexpr auto bmHandshake = 0xA6;
+static constexpr auto bmEscape = 0xAA;
+
+static constexpr auto ipmiSerialConnectionHeaderLength = 3;
+static constexpr auto ipmiSerialChecksumSize = 1;
+static constexpr auto ipmiSerialMaxBufferSize = 256;
+
+/**
+ * @brief IPMI Serial Message Structure
+ */
+struct IpmiSerialHeader
+{
+    uint8_t rsAddr;
+    uint8_t rsNetFnLUN;
+    uint8_t checksum1;
+    uint8_t rqAddr;
+    uint8_t rqSeqLUN;
+    uint8_t cmd;
+} __attribute__((packed));
+
+class SerialChannel
+{
+  public:
+    static constexpr uint8_t netFnShift = 2;
+    static constexpr uint8_t lunMask = (1 << netFnShift) - 1;
+
+    SerialChannel(bool debug) : verbose(debug), msgState(MsgState::msgIdle) {};
+
+    int write(stdplus::Fd& uart, uint8_t rsAddr, uint8_t rqAddr, uint8_t seq,
+              sdbusplus::message_t&& m);
+    void read(stdplus::Fd& serial, sdbusplus::bus_t& bus,
+              sdbusplus::slot_t& outstanding);
+    uint8_t calculateChecksum(std::span<uint8_t> data);
+    uint8_t getUnescapedCharacter(uint8_t c);
+    int consumeIpmiSerialPacket(std::span<uint8_t>& escapedDataBytes,
+                                std::vector<uint8_t>& unescapedDataBytes);
+    uint8_t processEscapedCharacter(std::vector<uint8_t>& buffer,
+                                    const std::vector<uint8_t>& data);
+
+  private:
+    bool verbose;
+    enum class MsgState
+    {
+        msgIdle = 0,
+        msgInProgress,
+        msgInEscape,
+    };
+    MsgState msgState;
+    std::vector<uint8_t> requestBuffer;
+    std::vector<uint8_t> responseBuffer;
+};
+
+} // namespace serialbridge
diff --git a/transport/serialbridge/test/meson.build b/transport/serialbridge/test/meson.build
new file mode 100644
index 0000000..39835d2
--- /dev/null
+++ b/transport/serialbridge/test/meson.build
@@ -0,0 +1,44 @@
+gtest = dependency('gtest', main: true, disabler: true, required: false)
+gmock = dependency('gmock', disabler: true, required: false)
+if not gtest.found() or not gmock.found()
+    gtest_opts = import('cmake').subproject_options()
+    gtest_opts.add_cmake_defines({'CMAKE_CXX_FLAGS': '-Wno-pedantic'})
+    gtest_proj = import('cmake').subproject(
+        'googletest',
+        options: gtest_opts,
+        required: false,
+    )
+    if gtest_proj.found()
+        gtest = declare_dependency(
+            dependencies: [
+                dependency('threads'),
+                gtest_proj.dependency('gtest'),
+                gtest_proj.dependency('gtest_main'),
+            ],
+        )
+        gmock = gtest_proj.dependency('gmock')
+    else
+        assert(not get_option('tests').enabled(), 'Googletest is required')
+    endif
+endif
+
+# Build/add serial_unittest to test suite
+test(
+    'transport_serial',
+    executable(
+        'transport_serial_unittest',
+        'serial_unittest.cpp',
+        '../serialcmd.cpp',
+        include_directories: root_inc,
+        build_by_default: false,
+        implicit_include_directories: false,
+        dependencies: [
+            sdbusplus_dep,
+            stdplus_dep,
+            phosphor_logging_dep,
+            sdeventplus_dep,
+            gtest,
+            gmock,
+        ],
+    ),
+)
diff --git a/transport/serialbridge/test/serial_unittest.cpp b/transport/serialbridge/test/serial_unittest.cpp
new file mode 100644
index 0000000..3fb0227
--- /dev/null
+++ b/transport/serialbridge/test/serial_unittest.cpp
@@ -0,0 +1,84 @@
+#include <transport/serialbridge/serialcmd.hpp>
+
+#include <gtest/gtest.h>
+
+namespace serialbridge
+{
+
+/**
+ * @brief Table of special characters
+ */
+std::unordered_map<uint8_t, uint8_t> testsets = {
+    {bmStart, 0xB0},     /* start */
+    {bmStop, 0xB5},      /* stop */
+    {bmHandshake, 0xB6}, /* packet handshake */
+    {bmEscape, 0xBA},    /* data escape */
+    {0x1B, 0x3B}         /* escape */
+};
+
+TEST(TestSpecialCharact, getUnescapedCharact)
+{
+    uint8_t c;
+    auto channel = std::make_shared<SerialChannel>(0);
+
+    for (const auto& set : testsets)
+    {
+        c = channel->getUnescapedCharacter(set.second);
+        ASSERT_EQ(c, set.first);
+    }
+}
+
+TEST(TestSpecialCharact, processEscapedCharacter)
+{
+    std::vector<uint8_t> buffer;
+    uint8_t unescaped = 0xd0;
+    auto channel = std::make_shared<SerialChannel>(0);
+
+    channel->processEscapedCharacter(buffer, std::vector<uint8_t>{bmStart});
+
+    ASSERT_EQ(buffer.at(0), bmEscape);
+    ASSERT_EQ(buffer.at(1), testsets.at(bmStart));
+
+    buffer.clear();
+    channel->processEscapedCharacter(buffer, std::vector<uint8_t>{unescaped});
+
+    ASSERT_EQ(buffer.at(0), unescaped);
+}
+
+TEST(TestChecksum, calculateChecksum)
+{
+    std::array<uint8_t, 5> dataBytes{0x01, 0x10, 0x60, 0xf0, 0x50};
+    auto channel = std::make_shared<SerialChannel>(0);
+
+    uint8_t checksum =
+        channel->calculateChecksum(std::span<uint8_t>(dataBytes));
+
+    checksum += (~checksum) + 1;
+    ASSERT_EQ(checksum, 0);
+}
+
+TEST(TestIpmiSerialPacket, consumeIpmiSerialPacket)
+{
+    std::vector<uint8_t> dataBytes{bmStart, 0x20, 0x18, 0xc8, 0x81,
+                                   0xc,     0x46, 0x01, 0x2c, bmStop};
+    std::vector<uint8_t> dataBytesSplit1{bmStart, 0x20, 0x18, 0xc8};
+    std::vector<uint8_t> dataBytesSplit2{0x81, 0xc, 0x46, 0x01, 0x2c, bmStop};
+    std::span<uint8_t> input(dataBytes);
+    std::span<uint8_t> input1(dataBytesSplit1);
+    std::span<uint8_t> input2(dataBytesSplit2);
+    std::vector<uint8_t> output;
+
+    auto channel = std::make_shared<SerialChannel>(0);
+
+    auto result = channel->consumeIpmiSerialPacket(input, output);
+
+    ASSERT_EQ(result, true);
+
+    output.clear();
+    result = channel->consumeIpmiSerialPacket(input1, output);
+    ASSERT_EQ(result, false);
+    result = channel->consumeIpmiSerialPacket(input2, output);
+    ASSERT_EQ(result, true);
+}
+
+} // namespace serialbridge
diff --git a/transportconstants.hpp b/transportconstants.hpp
new file mode 100644
index 0000000..3f865c6
--- /dev/null
+++ b/transportconstants.hpp
@@ -0,0 +1,160 @@
+#pragma once
+
+#include <ipmid/api-types.hpp>
+#include <stdplus/zstring_view.hpp>
+
+#include <cstdint>
+
+namespace ipmi
+{
+namespace transport
+{
+
+using stdplus::operator""_zsv;
+
+// D-Bus Network Daemon definitions
+constexpr auto PATH_ROOT = "/xyz/openbmc_project/network"_zsv;
+constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface";
+constexpr auto INTF_IP = "xyz.openbmc_project.Network.IP";
+constexpr auto INTF_IP_CREATE = "xyz.openbmc_project.Network.IP.Create";
+constexpr auto INTF_MAC = "xyz.openbmc_project.Network.MACAddress";
+constexpr auto INTF_NEIGHBOR = "xyz.openbmc_project.Network.Neighbor";
+constexpr auto INTF_NEIGHBOR_CREATE_STATIC =
+    "xyz.openbmc_project.Network.Neighbor.CreateStatic";
+constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN";
+constexpr auto INTF_VLAN_CREATE = "xyz.openbmc_project.Network.VLAN.Create";
+
+/** @brief IPMI LAN Parameters */
+enum class LanParam : uint8_t
+{
+    SetStatus = 0,
+    AuthSupport = 1,
+    AuthEnables = 2,
+    IP = 3,
+    IPSrc = 4,
+    MAC = 5,
+    SubnetMask = 6,
+    Gateway1 = 12,
+    Gateway1MAC = 13,
+    VLANId = 20,
+    CiphersuiteSupport = 22,
+    CiphersuiteEntries = 23,
+    cipherSuitePrivilegeLevels = 24,
+    IPFamilySupport = 50,
+    IPFamilyEnables = 51,
+    IPv6Status = 55,
+    IPv6StaticAddresses = 56,
+    IPv6DynamicAddresses = 59,
+    IPv6RouterControl = 64,
+    IPv6StaticRouter1IP = 65,
+    IPv6StaticRouter1MAC = 66,
+    IPv6StaticRouter1PrefixLength = 67,
+    IPv6StaticRouter1PrefixValue = 68,
+};
+
+/** @brief IPMI IP Origin Types */
+enum class IPSrc : uint8_t
+{
+    Unspecified = 0,
+    Static = 1,
+    DHCP = 2,
+    BIOS = 3,
+    BMC = 4,
+};
+
+/** @brief IPMI Set Status */
+enum class SetStatus : uint8_t
+{
+    Complete = 0,
+    InProgress = 1,
+    Commit = 2,
+};
+
+/** @brief IPMI Family Suport Bits */
+namespace IPFamilySupportFlag
+{
+constexpr uint8_t IPv6Only = 0;
+constexpr uint8_t DualStack = 1;
+constexpr uint8_t IPv6Alerts = 2;
+} // namespace IPFamilySupportFlag
+
+/** @brief IPMI IPFamily Enables Flag */
+enum class IPFamilyEnables : uint8_t
+{
+    IPv4Only = 0,
+    IPv6Only = 1,
+    DualStack = 2,
+};
+
+/** @brief IPMI IPv6 Dyanmic Status Bits */
+namespace IPv6StatusFlag
+{
+constexpr uint8_t DHCP = 0;
+constexpr uint8_t SLAAC = 1;
+}; // namespace IPv6StatusFlag
+
+/** @brief IPMI IPv6 Source */
+enum class IPv6Source : uint8_t
+{
+    Static = 0,
+    SLAAC = 1,
+    DHCP = 2,
+};
+
+/** @brief IPMI IPv6 Address Status */
+enum class IPv6AddressStatus : uint8_t
+{
+    Active = 0,
+    Disabled = 1,
+};
+
+namespace IPv6RouterControlFlag
+{
+constexpr uint8_t Static = 0;
+constexpr uint8_t Dynamic = 1;
+}; // namespace IPv6RouterControlFlag
+
+// LAN Handler specific response codes
+constexpr Cc ccParamNotSupported = 0x80;
+constexpr Cc ccParamSetLocked = 0x81;
+constexpr Cc ccParamReadOnly = 0x82;
+
+// VLANs are a 12-bit value
+constexpr uint16_t VLAN_VALUE_MASK = 0x0fff;
+constexpr uint16_t VLAN_ENABLE_FLAG = 0x8000;
+
+// Arbitrary v4 Address Limits
+constexpr uint8_t MAX_IPV4_ADDRESSES = 2;
+
+// Arbitrary v6 Address Limits to prevent too much output in ipmitool
+constexpr uint8_t MAX_IPV6_STATIC_ADDRESSES = 15;
+constexpr uint8_t MAX_IPV6_DYNAMIC_ADDRESSES = 15;
+
+// Prefix length limits of phosphor-networkd
+constexpr uint8_t MIN_IPV4_PREFIX_LENGTH = 1;
+constexpr uint8_t MAX_IPV4_PREFIX_LENGTH = 32;
+constexpr uint8_t MIN_IPV6_PREFIX_LENGTH = 1;
+constexpr uint8_t MAX_IPV6_PREFIX_LENGTH = 128;
+
+/** @enum SolConfParam
+ *
+ *  using for Set/Get SOL configuration parameters command.
+ */
+enum class SolConfParam : uint8_t
+{
+    Progress,       //!< Set In Progress.
+    Enable,         //!< SOL Enable.
+    Authentication, //!< SOL Authentication.
+    Accumulate,     //!< Character Accumulate Interval & Send Threshold.
+    Retry,          //!< SOL Retry.
+    NonVbitrate,    //!< SOL non-volatile bit rate.
+    Vbitrate,       //!< SOL volatile bit rate.
+    Channel,        //!< SOL payload channel.
+    Port,           //!< SOL payload port.
+};
+
+constexpr uint8_t ipmiCCParamNotSupported = 0x80;
+constexpr uint8_t ipmiCCWriteReadParameter = 0x82;
+
+} // namespace transport
+} // namespace ipmi
diff --git a/transporthandler.cpp b/transporthandler.cpp
new file mode 100644
index 0000000..7218da9
--- /dev/null
+++ b/transporthandler.cpp
@@ -0,0 +1,1741 @@
+#include "transporthandler.hpp"
+
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <stdplus/net/addr/subnet.hpp>
+#include <stdplus/raw.hpp>
+
+#include <array>
+#include <fstream>
+
+using phosphor::logging::elog;
+using sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+using sdbusplus::error::xyz::openbmc_project::common::InvalidArgument;
+using sdbusplus::server::xyz::openbmc_project::network::EthernetInterface;
+using sdbusplus::server::xyz::openbmc_project::network::IP;
+using sdbusplus::server::xyz::openbmc_project::network::Neighbor;
+
+namespace cipher
+{
+
+std::vector<uint8_t> getCipherList()
+{
+    std::vector<uint8_t> cipherList;
+
+    std::ifstream jsonFile(cipher::configFile);
+    if (!jsonFile.is_open())
+    {
+        lg2::error("Channel Cipher suites file not found");
+        elog<InternalFailure>();
+    }
+
+    auto data = Json::parse(jsonFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        lg2::error("Parsing channel cipher suites JSON failed");
+        elog<InternalFailure>();
+    }
+
+    // Byte 1 is reserved
+    cipherList.push_back(0x00);
+
+    for (const auto& record : data)
+    {
+        cipherList.push_back(record.value(cipher, 0));
+    }
+
+    return cipherList;
+}
+} // namespace cipher
+
+namespace ipmi
+{
+namespace transport
+{
+
+/** @brief Valid address origins for IPv4 */
+const std::unordered_set<IP::AddressOrigin> originsV4 = {
+    IP::AddressOrigin::Static,
+    IP::AddressOrigin::DHCP,
+};
+
+static constexpr uint8_t oemCmdStart = 192;
+
+// Checks if the ifname is part of the networkd path
+// This assumes the path came from the network subtree PATH_ROOT
+bool ifnameInPath(std::string_view ifname, std::string_view path)
+{
+    constexpr auto rs = PATH_ROOT.size() + 1; // ROOT + separator
+    const auto is = rs + ifname.size();       // ROOT + sep + ifname
+    return path.size() > rs && path.substr(rs).starts_with(ifname) &&
+           (path.size() == is || path[is] == '/');
+}
+
+std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus,
+                                                   uint8_t channel)
+{
+    auto ifname = getChannelName(channel);
+    if (ifname.empty())
+    {
+        return std::nullopt;
+    }
+
+    // Enumerate all VLAN + ETHERNET interfaces
+    std::vector<std::string> interfaces = {INTF_VLAN, INTF_ETHERNET};
+    ipmi::ObjectTree objs =
+        ipmi::getSubTree(bus, interfaces, std::string{PATH_ROOT});
+
+    ChannelParams params;
+    for (const auto& [path, impls] : objs)
+    {
+        if (!ifnameInPath(ifname, path))
+        {
+            continue;
+        }
+        for (const auto& [service, intfs] : impls)
+        {
+            bool vlan = false;
+            bool ethernet = false;
+            for (const auto& intf : intfs)
+            {
+                if (intf == INTF_VLAN)
+                {
+                    vlan = true;
+                }
+                else if (intf == INTF_ETHERNET)
+                {
+                    ethernet = true;
+                }
+            }
+            if (params.service.empty() && (vlan || ethernet))
+            {
+                params.service = service;
+            }
+            if (params.ifPath.empty() && !vlan && ethernet)
+            {
+                params.ifPath = path;
+            }
+            if (params.logicalPath.empty() && vlan)
+            {
+                params.logicalPath = path;
+            }
+        }
+    }
+
+    // We must have a path for the underlying interface
+    if (params.ifPath.empty())
+    {
+        return std::nullopt;
+    }
+    // We don't have a VLAN so the logical path is the same
+    if (params.logicalPath.empty())
+    {
+        params.logicalPath = params.ifPath;
+    }
+
+    params.id = channel;
+    params.ifname = std::move(ifname);
+    return params;
+}
+
+ChannelParams getChannelParams(sdbusplus::bus_t& bus, uint8_t channel)
+{
+    auto params = maybeGetChannelParams(bus, channel);
+    if (!params)
+    {
+        lg2::error("Failed to get channel params: {CHANNEL}", "CHANNEL",
+                   channel);
+        elog<InternalFailure>();
+    }
+    return std::move(*params);
+}
+
+/** @brief Get / Set the Property value from phosphor-networkd EthernetInterface
+ */
+template <typename T>
+static T getEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
+                    const std::string& prop)
+{
+    return std::get<T>(getDbusProperty(bus, params.service, params.logicalPath,
+                                       INTF_ETHERNET, prop));
+}
+template <typename T>
+static void setEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
+                       const std::string& prop, const T& t)
+{
+    return setDbusProperty(bus, params.service, params.logicalPath,
+                           INTF_ETHERNET, prop, t);
+}
+
+/** @brief Determines the MAC of the ethernet interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return The configured mac address
+ */
+stdplus::EtherAddr getMACProperty(sdbusplus::bus_t& bus,
+                                  const ChannelParams& params)
+{
+    auto prop = getDbusProperty(bus, params.service, params.ifPath, INTF_MAC,
+                                "MACAddress");
+    return stdplus::fromStr<stdplus::EtherAddr>(std::get<std::string>(prop));
+}
+
+/** @brief Sets the system value for MAC address on the given interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] mac    - MAC address to apply
+ */
+void setMACProperty(sdbusplus::bus_t& bus, const ChannelParams& params,
+                    stdplus::EtherAddr mac)
+{
+    setDbusProperty(bus, params.service, params.ifPath, INTF_MAC, "MACAddress",
+                    stdplus::toStr(mac));
+}
+
+void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
+                          const std::string& path)
+{
+    if (path.empty())
+    {
+        return;
+    }
+    try
+    {
+        auto req = bus.new_method_call(service.c_str(), path.c_str(),
+                                       ipmi::DELETE_INTERFACE, "Delete");
+        bus.call_noreply(req);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        if (strcmp(e.name(),
+                   "xyz.openbmc_project.Common.Error.InternalFailure") != 0 &&
+            strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0)
+        {
+            // We want to rethrow real errors
+            throw;
+        }
+    }
+}
+
+/** @brief Sets the address info configured for the interface
+ *         If a previous address path exists then it will be removed
+ *         before the new address is added.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] address - The address of the new IP
+ *  @param[in] prefix  - The prefix of the new IP
+ */
+template <int family>
+void createIfAddr(sdbusplus::bus_t& bus, const ChannelParams& params,
+                  typename AddrFamily<family>::addr address, uint8_t prefix)
+{
+    auto newreq =
+        bus.new_method_call(params.service.c_str(), params.logicalPath.c_str(),
+                            INTF_IP_CREATE, "IP");
+    std::string protocol =
+        sdbusplus::common::xyz::openbmc_project::network::convertForMessage(
+            AddrFamily<family>::protocol);
+    stdplus::ToStrHandle<stdplus::ToStr<typename AddrFamily<family>::addr>> tsh;
+    newreq.append(protocol, tsh(address), prefix, "");
+    bus.call_noreply(newreq);
+}
+
+/** @brief Trivial helper for getting the IPv4 address from getIfAddrs()
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return The address and prefix if found
+ */
+auto getIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params)
+{
+    std::optional<IfAddr<AF_INET>> ifaddr4 = std::nullopt;
+    IP::AddressOrigin src;
+
+    try
+    {
+        src = std::get<bool>(
+                  getDbusProperty(bus, params.service, params.logicalPath,
+                                  INTF_ETHERNET, "DHCP4"))
+                  ? IP::AddressOrigin::DHCP
+                  : IP::AddressOrigin::Static;
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to get IPv4 source");
+        return ifaddr4;
+    }
+
+    for (uint8_t i = 0; i < MAX_IPV4_ADDRESSES; ++i)
+    {
+        ifaddr4 = getIfAddr<AF_INET>(bus, params, i, originsV4);
+        if (ifaddr4 && src == ifaddr4->origin)
+        {
+            break;
+        }
+        else
+        {
+            ifaddr4 = std::nullopt;
+        }
+    }
+    return ifaddr4;
+}
+
+/** @brief Reconfigures the IPv4 address info configured for the interface
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] address - The new address if specified
+ *  @param[in] prefix  - The new address prefix if specified
+ */
+void reconfigureIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params,
+                        std::optional<stdplus::In4Addr> address,
+                        std::optional<uint8_t> prefix)
+{
+    auto ifaddr = getIfAddr4(bus, params);
+    if (!ifaddr && !address)
+    {
+        lg2::error("Missing address for IPv4 assignment");
+        elog<InternalFailure>();
+    }
+    uint8_t fallbackPrefix = AddrFamily<AF_INET>::defaultPrefix;
+    auto addr = stdplus::In4Addr{};
+    if (ifaddr)
+    {
+        addr = ifaddr->address;
+        fallbackPrefix = ifaddr->prefix;
+        deleteObjectIfExists(bus, params.service, ifaddr->path);
+    }
+    addr = address.value_or(addr);
+    if (addr != stdplus::In4Addr{})
+    {
+        createIfAddr<AF_INET>(bus, params, addr,
+                              prefix.value_or(fallbackPrefix));
+    }
+}
+
+template <int family>
+std::optional<IfNeigh<family>> findGatewayNeighbor(sdbusplus::bus_t& bus,
+                                                   const ChannelParams& params,
+                                                   ObjectLookupCache& neighbors)
+{
+    auto gateway = getGatewayProperty<family>(bus, params);
+    if (!gateway)
+    {
+        return std::nullopt;
+    }
+
+    return findStaticNeighbor<family>(bus, params, *gateway, neighbors);
+}
+
+template <int family>
+std::optional<IfNeigh<family>> getGatewayNeighbor(sdbusplus::bus_t& bus,
+                                                  const ChannelParams& params)
+{
+    ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
+    return findGatewayNeighbor<family>(bus, params, neighbors);
+}
+
+template <int family>
+void reconfigureGatewayMAC(sdbusplus::bus_t& bus, const ChannelParams& params,
+                           stdplus::EtherAddr mac)
+{
+    auto gateway = getGatewayProperty<family>(bus, params);
+    if (!gateway)
+    {
+        lg2::error("Tried to set Gateway MAC without Gateway");
+        elog<InternalFailure>();
+    }
+
+    ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
+    auto neighbor =
+        findStaticNeighbor<family>(bus, params, *gateway, neighbors);
+    if (neighbor)
+    {
+        deleteObjectIfExists(bus, params.service, neighbor->path);
+    }
+
+    createNeighbor<family>(bus, params, *gateway, mac);
+}
+
+/** @brief Deconfigures the IPv6 address info configured for the interface
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The address index to operate on
+ */
+void deconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
+                        uint8_t idx)
+{
+    auto ifaddr = getIfAddr<AF_INET6>(bus, params, idx, originsV6Static);
+    if (ifaddr)
+    {
+        deleteObjectIfExists(bus, params.service, ifaddr->path);
+    }
+}
+
+/** @brief Reconfigures the IPv6 address info configured for the interface
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The address index to operate on
+ *  @param[in] address - The new address
+ *  @param[in] prefix  - The new address prefix
+ */
+void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
+                        uint8_t idx, stdplus::In6Addr address, uint8_t prefix)
+{
+    deconfigureIfAddr6(bus, params, idx);
+    createIfAddr<AF_INET6>(bus, params, address, prefix);
+}
+
+/** @brief Converts the AddressOrigin into an IPv6Source
+ *
+ *  @param[in] origin - The DBus Address Origin to convert
+ *  @return The IPv6Source version of the origin
+ */
+IPv6Source originToSourceType(IP::AddressOrigin origin)
+{
+    switch (origin)
+    {
+        case IP::AddressOrigin::Static:
+            return IPv6Source::Static;
+        case IP::AddressOrigin::DHCP:
+            return IPv6Source::DHCP;
+        case IP::AddressOrigin::SLAAC:
+            return IPv6Source::SLAAC;
+        default:
+        {
+            auto originStr = sdbusplus::common::xyz::openbmc_project::network::
+                convertForMessage(origin);
+            lg2::error("Invalid IP::AddressOrigin conversion to IPv6Source, "
+                       "origin: {ORIGIN}",
+                       "ORIGIN", originStr);
+            elog<InternalFailure>();
+        }
+    }
+}
+
+/** @brief Packs the IPMI message response with IPv6 address data
+ *
+ *  @param[out] ret     - The IPMI response payload to be packed
+ *  @param[in]  channel - The channel id corresponding to an ethernet interface
+ *  @param[in]  set     - The set selector for determining address index
+ *  @param[in]  origins - Set of valid origins for address filtering
+ */
+void getLanIPv6Address(message::Payload& ret, uint8_t channel, uint8_t set,
+                       const std::unordered_set<IP::AddressOrigin>& origins)
+{
+    auto source = IPv6Source::Static;
+    bool enabled = false;
+    stdplus::In6Addr addr{};
+    uint8_t prefix{};
+    auto status = IPv6AddressStatus::Disabled;
+
+    auto ifaddr = channelCall<getIfAddr<AF_INET6>>(channel, set, origins);
+    if (ifaddr)
+    {
+        source = originToSourceType(ifaddr->origin);
+        enabled = (origins == originsV6Static);
+        addr = ifaddr->address;
+        prefix = ifaddr->prefix;
+        status = IPv6AddressStatus::Active;
+    }
+
+    ret.pack(set);
+    ret.pack(types::enum_cast<uint4_t>(source), uint3_t{}, enabled);
+    ret.pack(stdplus::raw::asView<char>(addr));
+    ret.pack(prefix);
+    ret.pack(types::enum_cast<uint8_t>(status));
+}
+
+/** @brief Gets the vlan ID configured on the interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return VLAN id or the standard 0 for no VLAN
+ */
+uint16_t getVLANProperty(sdbusplus::bus_t& bus, const ChannelParams& params)
+{
+    // VLAN devices will always have a separate logical object
+    if (params.ifPath == params.logicalPath)
+    {
+        return 0;
+    }
+
+    auto vlan = std::get<uint32_t>(getDbusProperty(
+        bus, params.service, params.logicalPath, INTF_VLAN, "Id"));
+    if ((vlan & VLAN_VALUE_MASK) != vlan)
+    {
+        lg2::error("networkd returned an invalid vlan: {VLAN} "
+                   "(CH={CHANNEL}, IF={IFNAME})",
+                   "CHANNEL", params.id, "IFNAME", params.ifname, "VLAN", vlan);
+        elog<InternalFailure>();
+    }
+    return vlan;
+}
+
+/** @brief Deletes all of the possible configuration parameters for a channel
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ */
+void deconfigureChannel(sdbusplus::bus_t& bus, ChannelParams& params)
+{
+    // Delete all objects associated with the interface
+    ObjectTree objs =
+        ipmi::getSubTree(bus, std::vector<std::string>{DELETE_INTERFACE},
+                         std::string{PATH_ROOT});
+    for (const auto& [path, impls] : objs)
+    {
+        if (!ifnameInPath(params.ifname, path))
+        {
+            continue;
+        }
+        for (const auto& [service, intfs] : impls)
+        {
+            deleteObjectIfExists(bus, service, path);
+        }
+        // Update params to reflect the deletion of vlan
+        if (path == params.logicalPath)
+        {
+            params.logicalPath = params.ifPath;
+        }
+    }
+
+    // Clear out any settings on the lower physical interface
+    setEthProp(bus, params, "DHCP4", false);
+    setEthProp(bus, params, "DHCP6", false);
+    setEthProp(bus, params, "IPv6AcceptRA", false);
+}
+
+/** @brief Creates a new VLAN on the specified interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] vlan   - The id of the new vlan
+ */
+void createVLAN(sdbusplus::bus_t& bus, ChannelParams& params, uint16_t vlan)
+{
+    if (vlan == 0)
+    {
+        return;
+    }
+
+    auto req = bus.new_method_call(params.service.c_str(), PATH_ROOT.c_str(),
+                                   INTF_VLAN_CREATE, "VLAN");
+    req.append(params.ifname, static_cast<uint32_t>(vlan));
+    auto reply = bus.call(req);
+    sdbusplus::message::object_path newPath;
+    reply.read(newPath);
+    params.logicalPath = std::move(newPath);
+}
+
+/** @brief Performs the necessary reconfiguration to change the VLAN
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] vlan   - The new vlan id to use
+ */
+void reconfigureVLAN(sdbusplus::bus_t& bus, ChannelParams& params,
+                     uint16_t vlan)
+{
+    // Unfortunatetly we don't have built-in functions to migrate our interface
+    // customizations to new VLAN interfaces, or have some kind of decoupling.
+    // We therefore must retain all of our old information, setup the new VLAN
+    // configuration, then restore the old info.
+
+    // Save info from the old logical interface
+    bool dhcp4 = getEthProp<bool>(bus, params, "DHCP4");
+    bool dhcp6 = getEthProp<bool>(bus, params, "DHCP6");
+    bool ra = getEthProp<bool>(bus, params, "IPv6AcceptRA");
+    ObjectLookupCache ips(bus, params, INTF_IP);
+    auto ifaddr4 = findIfAddr<AF_INET>(bus, params, 0, originsV4, ips);
+    std::vector<IfAddr<AF_INET6>> ifaddrs6;
+    for (uint8_t i = 0; i < MAX_IPV6_STATIC_ADDRESSES; ++i)
+    {
+        auto ifaddr6 =
+            findIfAddr<AF_INET6>(bus, params, i, originsV6Static, ips);
+        if (!ifaddr6)
+        {
+            break;
+        }
+        ifaddrs6.push_back(std::move(*ifaddr6));
+    }
+    ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
+    auto neighbor4 = findGatewayNeighbor<AF_INET>(bus, params, neighbors);
+    auto neighbor6 = findGatewayNeighbor<AF_INET6>(bus, params, neighbors);
+
+    deconfigureChannel(bus, params);
+    createVLAN(bus, params, vlan);
+
+    // Re-establish the saved settings
+    setEthProp(bus, params, "DHCP4", dhcp4);
+    setEthProp(bus, params, "DHCP6", dhcp6);
+    setEthProp(bus, params, "IPv6AcceptRA", ra);
+    if (ifaddr4)
+    {
+        createIfAddr<AF_INET>(bus, params, ifaddr4->address, ifaddr4->prefix);
+    }
+    for (const auto& ifaddr6 : ifaddrs6)
+    {
+        createIfAddr<AF_INET6>(bus, params, ifaddr6.address, ifaddr6.prefix);
+    }
+    if (neighbor4)
+    {
+        createNeighbor<AF_INET>(bus, params, neighbor4->ip, neighbor4->mac);
+    }
+    if (neighbor6)
+    {
+        createNeighbor<AF_INET6>(bus, params, neighbor6->ip, neighbor6->mac);
+    }
+}
+
+// We need to store this value so it can be returned to the client
+// It is volatile so safe to store in daemon memory.
+static std::unordered_map<uint8_t, SetStatus> setStatus;
+
+// Until we have good support for fixed versions of IPMI tool
+// we need to return the VLAN id for disabled VLANs. The value is only
+// used for verification that a disable operation succeeded and will only
+// be sent if our system indicates that vlans are disabled.
+static std::unordered_map<uint8_t, uint16_t> lastDisabledVlan;
+
+/** @brief Gets the set status for the channel if it exists
+ *         Otherise populates and returns the default value.
+ *
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  @return A reference to the SetStatus for the channel
+ */
+SetStatus& getSetStatus(uint8_t channel)
+{
+    auto it = setStatus.find(channel);
+    if (it != setStatus.end())
+    {
+        return it->second;
+    }
+    return setStatus[channel] = SetStatus::Complete;
+}
+
+/** @brief Unpacks the trivially copyable type from the message */
+template <typename T>
+static T unpackT(message::Payload& req)
+{
+    std::array<uint8_t, sizeof(T)> bytes;
+    if (req.unpack(bytes) != 0)
+    {
+        throw ccReqDataLenInvalid;
+    }
+    return stdplus::raw::copyFrom<T>(bytes);
+}
+
+/** @brief Ensure the message is fully unpacked */
+static void unpackFinal(message::Payload& req)
+{
+    if (!req.fullyUnpacked())
+    {
+        throw ccReqDataTruncated;
+    }
+}
+
+/**
+ * Define placeholder command handlers for the OEM Extension bytes for the Set
+ * LAN Configuration Parameters and Get LAN Configuration Parameters
+ * commands. Using "weak" linking allows the placeholder setLanOem/getLanOem
+ * functions below to be overridden.
+ * To create handlers for your own proprietary command set:
+ *   Create/modify a phosphor-ipmi-host Bitbake append file within your Yocto
+ *   recipe
+ *   Create C++ file(s) that define IPMI handler functions matching the
+ *     function names below (i.e. setLanOem). The default name for the
+ *     transport IPMI commands is transporthandler_oem.cpp.
+ *   Add:
+ *      EXTRA_OEMESON:append = "-Dtransport-oem=enabled"
+ *   Create a do_configure:prepend()/do_install:append() method in your
+ *   bbappend file to copy the file to the build directory.
+ *   Add:
+ *   PROJECT_SRC_DIR := "${THISDIR}/${PN}"
+ *   # Copy the "strong" functions into the working directory, overriding the
+ *   # placeholder functions.
+ *   do_configure:prepend(){
+ *      cp -f ${PROJECT_SRC_DIR}/transporthandler_oem.cpp ${S}
+ *   }
+ *
+ *   # Clean up after complilation has completed
+ *   do_install:append(){
+ *      rm -f ${S}/transporthandler_oem.cpp
+ *   }
+ *
+ */
+
+/**
+ * Define the placeholder OEM commands as having weak linkage. Create
+ * setLanOem, and getLanOem functions in the transporthandler_oem.cpp
+ * file. The functions defined there must not have the "weak" attribute
+ * applied to them.
+ */
+RspType<> setLanOem(uint8_t channel, uint8_t parameter, message::Payload& req)
+    __attribute__((weak));
+RspType<message::Payload> getLanOem(uint8_t channel, uint8_t parameter,
+                                    uint8_t set, uint8_t block)
+    __attribute__((weak));
+
+RspType<> setLanOem(uint8_t, uint8_t, message::Payload& req)
+{
+    req.trailingOk = true;
+    return response(ccParamNotSupported);
+}
+
+RspType<message::Payload> getLanOem(uint8_t, uint8_t, uint8_t, uint8_t)
+{
+    return response(ccParamNotSupported);
+}
+
+/**
+ * @brief is a valid LAN channel.
+ *
+ * This function checks whether the input channel is a valid LAN channel or not.
+ *
+ * @param[in] channel: the channel number.
+ * @return nullopt if the channel is invalid, false if the channel is not a LAN
+ * channel, true if the channel is a LAN channel.
+ **/
+std::optional<bool> isLanChannel(uint8_t channel)
+{
+    ChannelInfo chInfo;
+    auto cc = getChannelInfo(channel, chInfo);
+    if (cc != ccSuccess)
+    {
+        return std::nullopt;
+    }
+
+    return chInfo.mediumType ==
+           static_cast<uint8_t>(EChannelMediumType::lan8032);
+}
+
+RspType<> setLanInt(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1,
+                    uint8_t parameter, message::Payload& req)
+{
+    const uint8_t channel = convertCurrentChannelNum(
+        static_cast<uint8_t>(channelBits), ctx->channel);
+    if (reserved1 || !isValidChannel(channel))
+    {
+        lg2::error("Set Lan - Invalid field in request");
+        req.trailingOk = true;
+        return responseInvalidFieldRequest();
+    }
+
+    if (!isLanChannel(channel).value_or(false))
+    {
+        lg2::error("Set Lan - Not a LAN channel");
+        return responseInvalidFieldRequest();
+    }
+
+    switch (static_cast<LanParam>(parameter))
+    {
+        case LanParam::SetStatus:
+        {
+            uint2_t flag;
+            uint6_t rsvd;
+            if (req.unpack(flag, rsvd) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+            if (rsvd)
+            {
+                return responseInvalidFieldRequest();
+            }
+            auto status = static_cast<SetStatus>(static_cast<uint8_t>(flag));
+            switch (status)
+            {
+                case SetStatus::Complete:
+                {
+                    getSetStatus(channel) = status;
+                    return responseSuccess();
+                }
+                case SetStatus::InProgress:
+                {
+                    auto& storedStatus = getSetStatus(channel);
+                    if (storedStatus == SetStatus::InProgress)
+                    {
+                        return response(ccParamSetLocked);
+                    }
+                    storedStatus = status;
+                    return responseSuccess();
+                }
+                case SetStatus::Commit:
+                    if (getSetStatus(channel) != SetStatus::InProgress)
+                    {
+                        return responseInvalidFieldRequest();
+                    }
+                    return responseSuccess();
+            }
+            return response(ccParamNotSupported);
+        }
+        case LanParam::AuthSupport:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
+        }
+        case LanParam::AuthEnables:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
+        }
+        case LanParam::IP:
+        {
+            if (channelCall<getEthProp<bool>>(channel, "DHCP4"))
+            {
+                return responseCommandNotAvailable();
+            }
+            auto ip = unpackT<stdplus::In4Addr>(req);
+            unpackFinal(req);
+            channelCall<reconfigureIfAddr4>(channel, ip, std::nullopt);
+            return responseSuccess();
+        }
+        case LanParam::IPSrc:
+        {
+            uint4_t flag;
+            uint4_t rsvd;
+            if (req.unpack(flag, rsvd) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+            if (rsvd)
+            {
+                return responseInvalidFieldRequest();
+            }
+            switch (static_cast<IPSrc>(static_cast<uint8_t>(flag)))
+            {
+                case IPSrc::DHCP:
+                    // The IPSrc IPMI command is only for IPv4
+                    // management. Modifying IPv6 state is done using
+                    // a completely different Set LAN Configuration
+                    // subcommand.
+                    channelCall<setEthProp<bool>>(channel, "DHCP4", true);
+                    return responseSuccess();
+                case IPSrc::Unspecified:
+                case IPSrc::Static:
+                    channelCall<setEthProp<bool>>(channel, "DHCP4", false);
+                    return responseSuccess();
+                case IPSrc::BIOS:
+                case IPSrc::BMC:
+                    return responseInvalidFieldRequest();
+            }
+            return response(ccParamNotSupported);
+        }
+        case LanParam::MAC:
+        {
+            auto mac = unpackT<stdplus::EtherAddr>(req);
+            unpackFinal(req);
+            channelCall<setMACProperty>(channel, mac);
+            return responseSuccess();
+        }
+        case LanParam::SubnetMask:
+        {
+            if (channelCall<getEthProp<bool>>(channel, "DHCP4"))
+            {
+                return responseCommandNotAvailable();
+            }
+            auto pfx = stdplus::maskToPfx(unpackT<stdplus::In4Addr>(req));
+            unpackFinal(req);
+            channelCall<reconfigureIfAddr4>(channel, std::nullopt, pfx);
+            return responseSuccess();
+        }
+        case LanParam::Gateway1:
+        {
+            if (channelCall<getEthProp<bool>>(channel, "DHCP4"))
+            {
+                return responseCommandNotAvailable();
+            }
+            auto gateway = unpackT<stdplus::In4Addr>(req);
+            unpackFinal(req);
+            channelCall<setGatewayProperty<AF_INET>>(channel, gateway);
+            return responseSuccess();
+        }
+        case LanParam::Gateway1MAC:
+        {
+            auto gatewayMAC = unpackT<stdplus::EtherAddr>(req);
+            unpackFinal(req);
+            channelCall<reconfigureGatewayMAC<AF_INET>>(channel, gatewayMAC);
+            return responseSuccess();
+        }
+        case LanParam::VLANId:
+        {
+            uint12_t vlanData;
+            uint3_t rsvd;
+            bool vlanEnable;
+
+            if (req.unpack(vlanData, rsvd, vlanEnable) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+
+            if (rsvd)
+            {
+                return responseInvalidFieldRequest();
+            }
+
+            uint16_t vlan = static_cast<uint16_t>(vlanData);
+
+            if (!vlanEnable)
+            {
+                lastDisabledVlan[channel] = vlan;
+                vlan = 0;
+            }
+            else if (vlan == 0 || vlan == VLAN_VALUE_MASK)
+            {
+                return responseInvalidFieldRequest();
+            }
+
+            channelCall<reconfigureVLAN>(channel, vlan);
+            return responseSuccess();
+        }
+        case LanParam::CiphersuiteSupport:
+        case LanParam::CiphersuiteEntries:
+        case LanParam::IPFamilySupport:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
+        }
+        case LanParam::IPFamilyEnables:
+        {
+            uint8_t enables;
+            if (req.unpack(enables) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+            switch (static_cast<IPFamilyEnables>(enables))
+            {
+                case IPFamilyEnables::DualStack:
+                    return responseSuccess();
+                case IPFamilyEnables::IPv4Only:
+                case IPFamilyEnables::IPv6Only:
+                    return response(ccParamNotSupported);
+            }
+            return response(ccParamNotSupported);
+        }
+        case LanParam::IPv6Status:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
+        }
+        case LanParam::IPv6StaticAddresses:
+        {
+            uint8_t set;
+            uint7_t rsvd;
+            bool enabled;
+            uint8_t prefix;
+            uint8_t status;
+            if (req.unpack(set, rsvd, enabled) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            auto ip = unpackT<stdplus::In6Addr>(req);
+            if (req.unpack(prefix, status) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+            if (rsvd)
+            {
+                return responseInvalidFieldRequest();
+            }
+            if (enabled)
+            {
+                if (prefix < MIN_IPV6_PREFIX_LENGTH ||
+                    prefix > MAX_IPV6_PREFIX_LENGTH)
+                {
+                    return responseParmOutOfRange();
+                }
+                channelCall<reconfigureIfAddr6>(channel, set, ip, prefix);
+            }
+            else
+            {
+                channelCall<deconfigureIfAddr6>(channel, set);
+            }
+            return responseSuccess();
+        }
+        case LanParam::IPv6DynamicAddresses:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
+        }
+        case LanParam::IPv6RouterControl:
+        {
+            std::bitset<8> control;
+            constexpr uint8_t reservedRACCBits = 0xfc;
+            if (req.unpack(control) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+            if (std::bitset<8> expected(
+                    control & std::bitset<8>(reservedRACCBits));
+                expected.any())
+            {
+                return response(ccParamNotSupported);
+            }
+
+            bool enableRA = control[IPv6RouterControlFlag::Dynamic];
+            channelCall<setEthProp<bool>>(channel, "IPv6AcceptRA", enableRA);
+            channelCall<setEthProp<bool>>(channel, "DHCP6", enableRA);
+            return responseSuccess();
+        }
+        case LanParam::IPv6StaticRouter1IP:
+        {
+            auto gateway = unpackT<stdplus::In6Addr>(req);
+            unpackFinal(req);
+            channelCall<setGatewayProperty<AF_INET6>>(channel, gateway);
+            return responseSuccess();
+        }
+        case LanParam::IPv6StaticRouter1MAC:
+        {
+            auto mac = unpackT<stdplus::EtherAddr>(req);
+            unpackFinal(req);
+            channelCall<reconfigureGatewayMAC<AF_INET6>>(channel, mac);
+            return responseSuccess();
+        }
+        case LanParam::IPv6StaticRouter1PrefixLength:
+        {
+            uint8_t prefix;
+            if (req.unpack(prefix) != 0)
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+            if (prefix != 0)
+            {
+                return responseInvalidFieldRequest();
+            }
+            return responseSuccess();
+        }
+        case LanParam::IPv6StaticRouter1PrefixValue:
+        {
+            unpackT<stdplus::In6Addr>(req);
+            unpackFinal(req);
+            // Accept any prefix value since our prefix length has to be 0
+            return responseSuccess();
+        }
+        case LanParam::cipherSuitePrivilegeLevels:
+        {
+            uint8_t rsvd;
+            std::array<uint4_t, ipmi::maxCSRecords> cipherSuitePrivs;
+
+            if (req.unpack(rsvd, cipherSuitePrivs))
+            {
+                return responseReqDataLenInvalid();
+            }
+            unpackFinal(req);
+
+            if (rsvd)
+            {
+                return responseInvalidFieldRequest();
+            }
+
+            uint8_t resp =
+                getCipherConfigObject(csPrivFileName, csPrivDefaultFileName)
+                    .setCSPrivilegeLevels(channel, cipherSuitePrivs);
+            if (!resp)
+            {
+                return responseSuccess();
+            }
+            else
+            {
+                req.trailingOk = true;
+                return response(resp);
+            }
+        }
+    }
+
+    if (parameter >= oemCmdStart)
+    {
+        return setLanOem(channel, parameter, req);
+    }
+
+    req.trailingOk = true;
+    return response(ccParamNotSupported);
+}
+
+RspType<> setLan(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1,
+                 uint8_t parameter, message::Payload& req)
+{
+    try
+    {
+        return setLanInt(ctx, channelBits, reserved1, parameter, req);
+    }
+    catch (ipmi::Cc cc)
+    {
+        return response(cc);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        if (std::string_view{InvalidArgument::errName} == e.name())
+        {
+            return responseInvalidFieldRequest();
+        }
+        throw;
+    }
+}
+
+RspType<message::Payload> getLan(Context::ptr ctx, uint4_t channelBits,
+                                 uint3_t reserved, bool revOnly,
+                                 uint8_t parameter, uint8_t set, uint8_t block)
+{
+    message::Payload ret;
+    constexpr uint8_t current_revision = 0x11;
+    ret.pack(current_revision);
+
+    if (revOnly)
+    {
+        return responseSuccess(std::move(ret));
+    }
+
+    const uint8_t channel = convertCurrentChannelNum(
+        static_cast<uint8_t>(channelBits), ctx->channel);
+    if (reserved || !isValidChannel(channel))
+    {
+        lg2::error("Get Lan - Invalid field in request");
+        return responseInvalidFieldRequest();
+    }
+
+    if (!isLanChannel(channel).value_or(false))
+    {
+        lg2::error("Set Lan - Not a LAN channel");
+        return responseInvalidFieldRequest();
+    }
+
+    static std::vector<uint8_t> cipherList;
+    static bool listInit = false;
+    if (!listInit)
+    {
+        try
+        {
+            cipherList = cipher::getCipherList();
+            listInit = true;
+        }
+        catch (const std::exception& e)
+        {}
+    }
+
+    switch (static_cast<LanParam>(parameter))
+    {
+        case LanParam::SetStatus:
+        {
+            SetStatus status;
+            try
+            {
+                status = setStatus.at(channel);
+            }
+            catch (const std::out_of_range&)
+            {
+                status = SetStatus::Complete;
+            }
+            ret.pack(types::enum_cast<uint2_t>(status), uint6_t{});
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::AuthSupport:
+        {
+            std::bitset<6> support;
+            ret.pack(support, uint2_t{});
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::AuthEnables:
+        {
+            std::bitset<6> enables;
+            ret.pack(enables, uint2_t{}); // Callback
+            ret.pack(enables, uint2_t{}); // User
+            ret.pack(enables, uint2_t{}); // Operator
+            ret.pack(enables, uint2_t{}); // Admin
+            ret.pack(enables, uint2_t{}); // OEM
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IP:
+        {
+            auto ifaddr = channelCall<getIfAddr4>(channel);
+            stdplus::In4Addr addr{};
+            if (ifaddr)
+            {
+                addr = ifaddr->address;
+            }
+            ret.pack(stdplus::raw::asView<char>(addr));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPSrc:
+        {
+            auto src = channelCall<getEthProp<bool>>(channel, "DHCP4")
+                           ? IPSrc::DHCP
+                           : IPSrc::Static;
+            ret.pack(types::enum_cast<uint4_t>(src), uint4_t{});
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::MAC:
+        {
+            auto mac = channelCall<getMACProperty>(channel);
+            ret.pack(stdplus::raw::asView<char>(mac));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::SubnetMask:
+        {
+            auto ifaddr = channelCall<getIfAddr4>(channel);
+            uint8_t prefix = AddrFamily<AF_INET>::defaultPrefix;
+            if (ifaddr)
+            {
+                prefix = ifaddr->prefix;
+            }
+            auto netmask = stdplus::pfxToMask<stdplus::In4Addr>(prefix);
+            ret.pack(stdplus::raw::asView<char>(netmask));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::Gateway1:
+        {
+            auto gateway = channelCall<getGatewayProperty<AF_INET>>(channel);
+            ret.pack(stdplus::raw::asView<char>(
+                gateway.value_or(stdplus::In4Addr{})));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::Gateway1MAC:
+        {
+            stdplus::EtherAddr mac{};
+            auto neighbor = channelCall<getGatewayNeighbor<AF_INET>>(channel);
+            if (neighbor)
+            {
+                mac = neighbor->mac;
+            }
+            ret.pack(stdplus::raw::asView<char>(mac));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::VLANId:
+        {
+            uint16_t vlan = channelCall<getVLANProperty>(channel);
+            if (vlan != 0)
+            {
+                vlan |= VLAN_ENABLE_FLAG;
+            }
+            else
+            {
+                vlan = lastDisabledVlan[channel];
+            }
+            ret.pack(vlan);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::CiphersuiteSupport:
+        {
+            if (getChannelSessionSupport(channel) ==
+                EChannelSessSupported::none)
+            {
+                return responseInvalidFieldRequest();
+            }
+            if (!listInit)
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(static_cast<uint8_t>(cipherList.size() - 1));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::CiphersuiteEntries:
+        {
+            if (getChannelSessionSupport(channel) ==
+                EChannelSessSupported::none)
+            {
+                return responseInvalidFieldRequest();
+            }
+            if (!listInit)
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(cipherList);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPFamilySupport:
+        {
+            std::bitset<8> support;
+            support[IPFamilySupportFlag::IPv6Only] = 0;
+            support[IPFamilySupportFlag::DualStack] = 1;
+            support[IPFamilySupportFlag::IPv6Alerts] = 1;
+            ret.pack(support);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPFamilyEnables:
+        {
+            ret.pack(static_cast<uint8_t>(IPFamilyEnables::DualStack));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6Status:
+        {
+            ret.pack(MAX_IPV6_STATIC_ADDRESSES);
+            ret.pack(MAX_IPV6_DYNAMIC_ADDRESSES);
+            std::bitset<8> support;
+            support[IPv6StatusFlag::DHCP] = 1;
+            support[IPv6StatusFlag::SLAAC] = 1;
+            ret.pack(support);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6StaticAddresses:
+        {
+            if (set >= MAX_IPV6_STATIC_ADDRESSES)
+            {
+                return responseParmOutOfRange();
+            }
+            getLanIPv6Address(ret, channel, set, originsV6Static);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6DynamicAddresses:
+        {
+            if (set >= MAX_IPV6_DYNAMIC_ADDRESSES)
+            {
+                return responseParmOutOfRange();
+            }
+            getLanIPv6Address(ret, channel, set, originsV6Dynamic);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6RouterControl:
+        {
+            std::bitset<8> control;
+            control[IPv6RouterControlFlag::Dynamic] =
+                channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA");
+            control[IPv6RouterControlFlag::Static] = 1;
+            ret.pack(control);
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6StaticRouter1IP:
+        {
+            stdplus::In6Addr gateway{};
+            if (!channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA"))
+            {
+                gateway =
+                    channelCall<getGatewayProperty<AF_INET6>>(channel).value_or(
+                        stdplus::In6Addr{});
+            }
+            ret.pack(stdplus::raw::asView<char>(gateway));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6StaticRouter1MAC:
+        {
+            stdplus::EtherAddr mac{};
+            auto neighbor = channelCall<getGatewayNeighbor<AF_INET6>>(channel);
+            if (neighbor)
+            {
+                mac = neighbor->mac;
+            }
+            ret.pack(stdplus::raw::asView<char>(mac));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6StaticRouter1PrefixLength:
+        {
+            ret.pack(uint8_t{0});
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPv6StaticRouter1PrefixValue:
+        {
+            ret.pack(stdplus::raw::asView<char>(stdplus::In6Addr{}));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::cipherSuitePrivilegeLevels:
+        {
+            std::array<uint4_t, ipmi::maxCSRecords> csPrivilegeLevels;
+
+            uint8_t resp =
+                getCipherConfigObject(csPrivFileName, csPrivDefaultFileName)
+                    .getCSPrivilegeLevels(channel, csPrivilegeLevels);
+            if (!resp)
+            {
+                constexpr uint8_t reserved1 = 0x00;
+                ret.pack(reserved1, csPrivilegeLevels);
+                return responseSuccess(std::move(ret));
+            }
+            else
+            {
+                return response(resp);
+            }
+        }
+    }
+
+    if (parameter >= oemCmdStart)
+    {
+        return getLanOem(channel, parameter, set, block);
+    }
+
+    return response(ccParamNotSupported);
+}
+
+constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
+constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol/";
+constexpr const uint16_t solDefaultPort = 623;
+
+RspType<> setSolConfParams(Context::ptr ctx, uint4_t channelBits,
+                           uint4_t /*reserved*/, uint8_t parameter,
+                           message::Payload& req)
+{
+    const uint8_t channel = convertCurrentChannelNum(
+        static_cast<uint8_t>(channelBits), ctx->channel);
+
+    if (!isValidChannel(channel))
+    {
+        lg2::error("Set Sol Config - Invalid channel in request");
+        return responseInvalidFieldRequest();
+    }
+
+    std::string solService{};
+    std::string solPathWitheEthName = solPath + ipmi::getChannelName(channel);
+
+    if (ipmi::getService(ctx, solInterface, solPathWitheEthName, solService))
+    {
+        lg2::error("Set Sol Config - Invalid solInterface, service: {SERVICE}, "
+                   "object path: {OBJPATH}, interface: {INTERFACE}",
+                   "SERVICE", solService, "OBJPATH", solPathWitheEthName,
+                   "INTERFACE", solInterface);
+        return responseInvalidFieldRequest();
+    }
+
+    switch (static_cast<SolConfParam>(parameter))
+    {
+        case SolConfParam::Progress:
+        {
+            uint8_t progress;
+            if (req.unpack(progress) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Progress", progress))
+            {
+                return responseUnspecifiedError();
+            }
+            break;
+        }
+        case SolConfParam::Enable:
+        {
+            bool enable;
+            uint7_t reserved2;
+
+            if (req.unpack(enable, reserved2) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Enable", enable))
+            {
+                return responseUnspecifiedError();
+            }
+            break;
+        }
+        case SolConfParam::Authentication:
+        {
+            uint4_t privilegeBits{};
+            uint2_t reserved2{};
+            bool forceAuth = false;
+            bool forceEncrypt = false;
+
+            if (req.unpack(privilegeBits, reserved2, forceAuth, forceEncrypt) !=
+                    0 ||
+                !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+
+            uint8_t privilege = static_cast<uint8_t>(privilegeBits);
+            if (privilege < static_cast<uint8_t>(Privilege::User) ||
+                privilege > static_cast<uint8_t>(Privilege::Oem))
+            {
+                return ipmi::responseInvalidFieldRequest();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Privilege", privilege))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "ForceEncryption",
+                                      forceEncrypt))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "ForceAuthentication",
+                                      forceAuth))
+            {
+                return responseUnspecifiedError();
+            }
+            break;
+        }
+        case SolConfParam::Accumulate:
+        {
+            uint8_t interval;
+            uint8_t threshold;
+            if (req.unpack(interval, threshold) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+
+            if (threshold == 0)
+            {
+                return responseInvalidFieldRequest();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "AccumulateIntervalMS",
+                                      interval))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Threshold", threshold))
+            {
+                return responseUnspecifiedError();
+            }
+            break;
+        }
+        case SolConfParam::Retry:
+        {
+            uint3_t countBits;
+            uint5_t reserved2;
+            uint8_t interval;
+
+            if (req.unpack(countBits, reserved2, interval) != 0 ||
+                !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+
+            uint8_t count = static_cast<uint8_t>(countBits);
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "RetryCount", count))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "RetryIntervalMS",
+                                      interval))
+            {
+                return responseUnspecifiedError();
+            }
+            break;
+        }
+        case SolConfParam::Port:
+        {
+            return response(ipmiCCWriteReadParameter);
+        }
+        case SolConfParam::NonVbitrate:
+        case SolConfParam::Vbitrate:
+        case SolConfParam::Channel:
+        default:
+            return response(ipmiCCParamNotSupported);
+    }
+    return responseSuccess();
+}
+
+RspType<message::Payload> getSolConfParams(
+    Context::ptr ctx, uint4_t channelBits, uint3_t /*reserved*/, bool revOnly,
+    uint8_t parameter, uint8_t /*set*/, uint8_t /*block*/)
+{
+    message::Payload ret;
+    constexpr uint8_t current_revision = 0x11;
+    ret.pack(current_revision);
+    if (revOnly)
+    {
+        return responseSuccess(std::move(ret));
+    }
+
+    const uint8_t channel = convertCurrentChannelNum(
+        static_cast<uint8_t>(channelBits), ctx->channel);
+
+    if (!isValidChannel(channel))
+    {
+        lg2::error("Get Sol Config - Invalid channel in request");
+        return responseInvalidFieldRequest();
+    }
+
+    std::string solService{};
+    std::string solPathWitheEthName = solPath + ipmi::getChannelName(channel);
+
+    if (ipmi::getService(ctx, solInterface, solPathWitheEthName, solService))
+    {
+        lg2::error("Set Sol Config - Invalid solInterface, service: {SERVICE}, "
+                   "object path: {OBJPATH}, interface: {INTERFACE}",
+                   "SERVICE", solService, "OBJPATH", solPathWitheEthName,
+                   "INTERFACE", solInterface);
+        return responseInvalidFieldRequest();
+    }
+
+    switch (static_cast<SolConfParam>(parameter))
+    {
+        case SolConfParam::Progress:
+        {
+            uint8_t progress;
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Progress", progress))
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(progress);
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Enable:
+        {
+            bool enable{};
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Enable", enable))
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(enable, uint7_t{});
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Authentication:
+        {
+            // 4bits, cast when pack
+            uint8_t privilege;
+            bool forceAuth = false;
+            bool forceEncrypt = false;
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Privilege", privilege))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "ForceAuthentication",
+                                      forceAuth))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "ForceEncryption",
+                                      forceEncrypt))
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(uint4_t{privilege}, uint2_t{}, forceAuth, forceEncrypt);
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Accumulate:
+        {
+            uint8_t interval{}, threshold{};
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "AccumulateIntervalMS",
+                                      interval))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "Threshold", threshold))
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(interval, threshold);
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Retry:
+        {
+            // 3bits, cast when cast
+            uint8_t count{};
+            uint8_t interval{};
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "RetryCount", count))
+            {
+                return responseUnspecifiedError();
+            }
+
+            if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
+                                      solInterface, "RetryIntervalMS",
+                                      interval))
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(uint3_t{count}, uint5_t{}, interval);
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Port:
+        {
+            auto port = solDefaultPort;
+            ret.pack(static_cast<uint16_t>(port));
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Channel:
+        {
+            ret.pack(channel);
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::NonVbitrate:
+        {
+            uint64_t baudRate;
+            uint8_t encodedBitRate = 0;
+            if (ipmi::getDbusProperty(
+                    ctx, "xyz.openbmc_project.Console.default",
+                    "/xyz/openbmc_project/console/default",
+                    "xyz.openbmc_project.Console.UART", "Baud", baudRate))
+            {
+                return ipmi::responseUnspecifiedError();
+            }
+            switch (baudRate)
+            {
+                case 9600:
+                    encodedBitRate = 0x06;
+                    break;
+                case 19200:
+                    encodedBitRate = 0x07;
+                    break;
+                case 38400:
+                    encodedBitRate = 0x08;
+                    break;
+                case 57600:
+                    encodedBitRate = 0x09;
+                    break;
+                case 115200:
+                    encodedBitRate = 0x0a;
+                    break;
+                default:
+                    break;
+            }
+            ret.pack(encodedBitRate);
+            return responseSuccess(std::move(ret));
+        }
+        case SolConfParam::Vbitrate:
+        default:
+            return response(ipmiCCParamNotSupported);
+    }
+
+    return response(ccParamNotSupported);
+}
+
+} // namespace transport
+} // namespace ipmi
+
+void registerNetFnTransportFunctions() __attribute__((constructor));
+
+void registerNetFnTransportFunctions()
+{
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+                          ipmi::transport::cmdSetLanConfigParameters,
+                          ipmi::Privilege::Admin, ipmi::transport::setLan);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+                          ipmi::transport::cmdGetLanConfigParameters,
+                          ipmi::Privilege::Operator, ipmi::transport::getLan);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+                          ipmi::transport::cmdSetSolConfigParameters,
+                          ipmi::Privilege::Admin,
+                          ipmi::transport::setSolConfParams);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+                          ipmi::transport::cmdGetSolConfigParameters,
+                          ipmi::Privilege::User,
+                          ipmi::transport::getSolConfParams);
+}
diff --git a/transporthandler.hpp b/transporthandler.hpp
new file mode 100644
index 0000000..de1bb66
--- /dev/null
+++ b/transporthandler.hpp
@@ -0,0 +1,452 @@
+#pragma once
+
+#include "app/channel.hpp"
+#include "transportconstants.hpp"
+#include "user_channel/cipher_mgmt.hpp"
+
+#include <ipmid/api-types.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+#include <ipmid/message/types.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/exception.hpp>
+#include <stdplus/net/addr/ether.hpp>
+#include <stdplus/net/addr/ip.hpp>
+#include <stdplus/str/conv.hpp>
+#include <stdplus/zstring_view.hpp>
+#include <user_channel/channel_layer.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
+#include <xyz/openbmc_project/Network/IP/server.hpp>
+#include <xyz/openbmc_project/Network/Neighbor/server.hpp>
+
+#include <cinttypes>
+#include <functional>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+
+namespace ipmi
+{
+namespace transport
+{
+
+/** @brief The dbus parameters for the interface corresponding to a channel
+ *         This helps reduce the number of mapper lookups we need for each
+ *         query and simplifies finding the VLAN interface if needed.
+ */
+struct ChannelParams
+{
+    /** @brief The channel ID */
+    int id;
+    /** @brief channel name for the interface */
+    std::string ifname;
+    /** @brief Name of the service on the bus */
+    std::string service;
+    /** @brief Lower level adapter path that is guaranteed to not be a VLAN */
+    std::string ifPath;
+    /** @brief Logical adapter path used for address assignment */
+    std::string logicalPath;
+};
+
+/** @brief Determines the ethernet interface name corresponding to a channel
+ *         Tries to map a VLAN object first so that the address information
+ *         is accurate. Otherwise it gets the standard ethernet interface.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  @return Ethernet interface service and object path if it exists
+ */
+std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus,
+                                                   uint8_t channel);
+
+/** @brief A trivial helper around maybeGetChannelParams() that throws an
+ *         exception when it is unable to acquire parameters for the channel.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  @return Ethernet interface service and object path
+ */
+ChannelParams getChannelParams(sdbusplus::bus_t& bus, uint8_t channel);
+
+/** @brief Trivializes using parameter getter functions by providing a bus
+ *         and channel parameters automatically.
+ *
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  ...
+ */
+template <auto func, typename... Args>
+auto channelCall(uint8_t channel, Args&&... args)
+{
+    sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
+    auto params = getChannelParams(bus, channel);
+    return std::invoke(func, bus, params, std::forward<Args>(args)...);
+}
+
+/** @brief Generic paramters for different address families */
+template <int family>
+struct AddrFamily
+{};
+
+/** @brief Parameter specialization for IPv4 */
+template <>
+struct AddrFamily<AF_INET>
+{
+    using addr = stdplus::In4Addr;
+    static constexpr auto protocol =
+        sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv4;
+    static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
+    static constexpr uint8_t defaultPrefix = 32;
+    static constexpr char propertyGateway[] = "DefaultGateway";
+};
+
+/** @brief Parameter specialization for IPv6 */
+template <>
+struct AddrFamily<AF_INET6>
+{
+    using addr = stdplus::In6Addr;
+    static constexpr auto protocol =
+        sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv6;
+    static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
+    static constexpr uint8_t defaultPrefix = 128;
+    static constexpr char propertyGateway[] = "DefaultGateway6";
+};
+
+/** @brief Interface Neighbor configuration parameters */
+template <int family>
+struct IfNeigh
+{
+    std::string path;
+    typename AddrFamily<family>::addr ip;
+    stdplus::EtherAddr mac;
+};
+
+/** @brief Interface IP Address configuration parameters */
+template <int family>
+struct IfAddr
+{
+    std::string path;
+    typename AddrFamily<family>::addr address;
+    sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin origin;
+    uint8_t prefix;
+};
+
+/** @brief Valid address origins for IPv6 */
+static inline const std::unordered_set<
+    sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>
+    originsV6Static = {sdbusplus::server::xyz::openbmc_project::network::IP::
+                           AddressOrigin::Static};
+static inline const std::unordered_set<
+    sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>
+    originsV6Dynamic = {
+        sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin::
+            DHCP,
+        sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin::
+            SLAAC,
+};
+
+/** @brief A lazy lookup mechanism for iterating over object properties stored
+ *         in DBus. This will only perform the object lookup when needed, and
+ *         retains a cache of previous lookups to speed up future iterations.
+ */
+class ObjectLookupCache
+{
+  public:
+    using PropertiesCache = std::unordered_map<std::string, PropertyMap>;
+
+    /** @brief Creates a new ObjectLookupCache for the interface on the bus
+     *         NOTE: The inputs to this object must outlive the object since
+     *         they are only referenced by it.
+     *
+     *  @param[in] bus    - The bus object used for lookups
+     *  @param[in] params - The parameters for the channel
+     *  @param[in] intf   - The interface we are looking up
+     */
+    ObjectLookupCache(sdbusplus::bus_t& bus, const ChannelParams& params,
+                      const char* intf) :
+        bus(bus), params(params), intf(intf),
+        objs(getAllDbusObjects(bus, params.logicalPath, intf, ""))
+    {}
+
+    class iterator : public ObjectTree::const_iterator
+    {
+      public:
+        using value_type = PropertiesCache::value_type;
+
+        iterator(ObjectTree::const_iterator it, ObjectLookupCache& container) :
+            ObjectTree::const_iterator(it), container(container),
+            ret(container.cache.end())
+        {}
+        value_type& operator*()
+        {
+            ret = container.get(ObjectTree::const_iterator::operator*().first);
+            return *ret;
+        }
+        value_type* operator->()
+        {
+            return &operator*();
+        }
+
+      private:
+        ObjectLookupCache& container;
+        PropertiesCache::iterator ret;
+    };
+
+    iterator begin() noexcept
+    {
+        return iterator(objs.begin(), *this);
+    }
+
+    iterator end() noexcept
+    {
+        return iterator(objs.end(), *this);
+    }
+
+  private:
+    sdbusplus::bus_t& bus;
+    const ChannelParams& params;
+    const char* const intf;
+    const ObjectTree objs;
+    PropertiesCache cache;
+
+    /** @brief Gets a cached copy of the object properties if possible
+     *         Otherwise performs a query on DBus to look them up
+     *
+     *  @param[in] path - The object path to lookup
+     *  @return An iterator for the specified object path + properties
+     */
+    PropertiesCache::iterator get(const std::string& path)
+    {
+        auto it = cache.find(path);
+        if (it != cache.end())
+        {
+            return it;
+        }
+        auto properties = getAllDbusProperties(bus, params.service, path, intf);
+        return cache.insert({path, std::move(properties)}).first;
+    }
+};
+
+/** @brief Searches the ip object lookup cache for an address matching
+ *         the input parameters. NOTE: The index lacks stability across address
+ *         changes since the network daemon has no notion of stable indicies.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The index of the desired address on the interface
+ *  @param[in] origins - The allowed origins for the address objects
+ *  @param[in] ips     - The object lookup cache holding all of the address info
+ *  @return The address and prefix if it was found
+ */
+template <int family>
+std::optional<IfAddr<family>> findIfAddr(
+    [[maybe_unused]] sdbusplus::bus_t& bus,
+    [[maybe_unused]] const ChannelParams& params, uint8_t idx,
+    const std::unordered_set<
+        sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>&
+        origins,
+    ObjectLookupCache& ips)
+{
+    for (const auto& [path, properties] : ips)
+    {
+        try
+        {
+            typename AddrFamily<family>::addr addr;
+            addr = stdplus::fromStr<typename AddrFamily<family>::addr>(
+                std::get<std::string>(properties.at("Address")));
+
+            sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin
+                origin = sdbusplus::server::xyz::openbmc_project::network::IP::
+                    convertAddressOriginFromString(
+                        std::get<std::string>(properties.at("Origin")));
+            if (origins.find(origin) == origins.end())
+            {
+                continue;
+            }
+
+            if (idx > 0)
+            {
+                idx--;
+                continue;
+            }
+
+            IfAddr<family> ifaddr;
+            ifaddr.path = path;
+            ifaddr.address = addr;
+            ifaddr.prefix = std::get<uint8_t>(properties.at("PrefixLength"));
+            ifaddr.origin = origin;
+
+            return ifaddr;
+        }
+        catch (...)
+        {
+            continue;
+        }
+    }
+
+    return std::nullopt;
+}
+/** @brief Trivial helper around findIfAddr that simplifies calls
+ *         for one off lookups. Don't use this if you intend to do multiple
+ *         lookups at a time.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The index of the desired address on the interface
+ *  @param[in] origins - The allowed origins for the address objects
+ *  @return The address and prefix if it was found
+ */
+template <int family>
+auto getIfAddr(
+    sdbusplus::bus_t& bus, const ChannelParams& params, uint8_t idx,
+    const std::unordered_set<
+        sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>&
+        origins)
+{
+    ObjectLookupCache ips(bus, params, INTF_IP);
+    return findIfAddr<family>(bus, params, idx, origins, ips);
+}
+
+/** @brief Reconfigures the IPv6 address info configured for the interface
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The address index to operate on
+ *  @param[in] address - The new address
+ *  @param[in] prefix  - The new address prefix
+ */
+void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
+                        uint8_t idx, stdplus::In6Addr address, uint8_t prefix);
+
+/** @brief Retrieves the current gateway for the address family on the system
+ *         NOTE: The gateway is per channel instead of the system wide one.
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return An address representing the gateway address if it exists
+ */
+template <int family>
+std::optional<typename AddrFamily<family>::addr> getGatewayProperty(
+    sdbusplus::bus_t& bus, const ChannelParams& params)
+{
+    auto objPath = "/xyz/openbmc_project/network/" + params.ifname;
+    auto gatewayStr = std::get<std::string>(
+        getDbusProperty(bus, params.service, objPath, INTF_ETHERNET,
+                        AddrFamily<family>::propertyGateway));
+    if (gatewayStr.empty())
+    {
+        return std::nullopt;
+    }
+    return stdplus::fromStr<typename AddrFamily<family>::addr>(gatewayStr);
+}
+
+template <int family>
+std::optional<IfNeigh<family>> findStaticNeighbor(
+    sdbusplus::bus_t&, const ChannelParams&,
+    typename AddrFamily<family>::addr ip, ObjectLookupCache& neighbors)
+{
+    using sdbusplus::server::xyz::openbmc_project::network::Neighbor;
+    const auto state =
+        sdbusplus::common::xyz::openbmc_project::network::convertForMessage(
+            Neighbor::State::Permanent);
+    for (const auto& [path, neighbor] : neighbors)
+    {
+        try
+        {
+            typename AddrFamily<family>::addr neighIP;
+            neighIP = stdplus::fromStr<typename AddrFamily<family>::addr>(
+                std::get<std::string>(neighbor.at("IPAddress")));
+
+            if (neighIP != ip)
+            {
+                continue;
+            }
+            if (state != std::get<std::string>(neighbor.at("State")))
+            {
+                continue;
+            }
+
+            IfNeigh<family> ret;
+            ret.path = path;
+            ret.ip = ip;
+            ret.mac = stdplus::fromStr<stdplus::EtherAddr>(
+                std::get<std::string>(neighbor.at("MACAddress")));
+
+            return ret;
+        }
+        catch (...)
+        {
+            continue;
+        }
+    }
+
+    return std::nullopt;
+}
+
+template <int family>
+void createNeighbor(sdbusplus::bus_t& bus, const ChannelParams& params,
+                    typename AddrFamily<family>::addr address,
+                    stdplus::EtherAddr mac)
+{
+    auto newreq =
+        bus.new_method_call(params.service.c_str(), params.logicalPath.c_str(),
+                            INTF_NEIGHBOR_CREATE_STATIC, "Neighbor");
+    stdplus::ToStrHandle<stdplus::ToStr<stdplus::EtherAddr>> macToStr;
+    stdplus::ToStrHandle<stdplus::ToStr<typename AddrFamily<family>::addr>>
+        addrToStr;
+    newreq.append(addrToStr(address), macToStr(mac));
+    bus.call_noreply(newreq);
+}
+
+/** @brief Deletes the dbus object. Ignores empty objects or objects that are
+ *         missing from the bus.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] service - The name of the service
+ *  @param[in] path    - The path of the object to delete
+ */
+void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
+                          const std::string& path);
+
+/** @brief Sets the value for the default gateway of the channel
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] gateway - Gateway address to apply
+ */
+template <int family>
+void setGatewayProperty(sdbusplus::bus_t& bus, const ChannelParams& params,
+                        typename AddrFamily<family>::addr address)
+{
+    // Save the old gateway MAC address if it exists so we can recreate it
+    auto gateway = getGatewayProperty<family>(bus, params);
+    std::optional<IfNeigh<family>> neighbor;
+    if (gateway)
+    {
+        ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
+        neighbor = findStaticNeighbor<family>(bus, params, *gateway, neighbors);
+    }
+
+    auto objPath = "/xyz/openbmc_project/network/" + params.ifname;
+    setDbusProperty(bus, params.service, objPath, INTF_ETHERNET,
+                    AddrFamily<family>::propertyGateway,
+                    stdplus::toStr(address));
+
+    // Restore the gateway MAC if we had one
+    if (neighbor)
+    {
+        deleteObjectIfExists(bus, params.service, neighbor->path);
+        createNeighbor<family>(bus, params, address, neighbor->mac);
+    }
+}
+
+} // namespace transport
+} // namespace ipmi
diff --git a/user_channel/channel_layer.cpp b/user_channel/channel_layer.cpp
new file mode 100644
index 0000000..26bc3fa
--- /dev/null
+++ b/user_channel/channel_layer.cpp
@@ -0,0 +1,152 @@
+/*
+// Copyright (c) 2018 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 "channel_layer.hpp"
+
+#include "channel_mgmt.hpp"
+#include "cipher_mgmt.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace ipmi
+{
+
+bool doesDeviceExist(const uint8_t chNum)
+{
+    // TODO: This is not the reliable way to find the device
+    // associated with ethernet interface as the channel number to
+    // eth association is not done. Need to revisit later
+    struct stat fileStat = {};
+    std::string devName("/sys/class/net/" + getChannelName(chNum));
+
+    if (stat(devName.data(), &fileStat) != 0)
+    {
+        lg2::debug("Ethernet device not found");
+        return false;
+    }
+
+    return true;
+}
+
+bool isValidPrivLimit(const uint8_t privLimit)
+{
+    // Callback privilege is deprecated in OpenBMC
+    // At present, "OEM Privilege" is not used in OpenBMC
+    return ((privLimit > PRIVILEGE_CALLBACK) && (privLimit < PRIVILEGE_OEM));
+}
+
+bool isValidAccessMode(const uint8_t accessMode)
+{
+    return (accessMode <= static_cast<uint8_t>(EChannelAccessMode::shared));
+}
+
+bool isValidChannel(const uint8_t chNum)
+{
+    return getChannelConfigObject().isValidChannel(chNum);
+}
+
+bool isValidAuthType(const uint8_t chNum, const EAuthType& authType)
+{
+    return getChannelConfigObject().isValidAuthType(chNum, authType);
+}
+
+EChannelSessSupported getChannelSessionSupport(const uint8_t chNum)
+{
+    return getChannelConfigObject().getChannelSessionSupport(chNum);
+}
+
+int getChannelActiveSessions(const uint8_t chNum)
+{
+    return getChannelConfigObject().getChannelActiveSessions(chNum);
+}
+
+size_t getChannelMaxTransferSize(uint8_t chNum)
+{
+    return getChannelConfigObject().getChannelMaxTransferSize(chNum);
+}
+
+Cc ipmiChannelInit()
+{
+    getChannelConfigObject();
+    getCipherConfigObject(csPrivFileName, csPrivDefaultFileName);
+    return ccSuccess;
+}
+
+Cc getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
+{
+    return getChannelConfigObject().getChannelInfo(chNum, chInfo);
+}
+
+Cc getChannelAccessData(const uint8_t chNum, ChannelAccess& chAccessData)
+{
+    return getChannelConfigObject().getChannelAccessData(chNum, chAccessData);
+}
+
+Cc setChannelAccessData(const uint8_t chNum, const ChannelAccess& chAccessData,
+                        const uint8_t setFlag)
+{
+    return getChannelConfigObject().setChannelAccessData(chNum, chAccessData,
+                                                         setFlag);
+}
+
+Cc getChannelAccessPersistData(const uint8_t chNum, ChannelAccess& chAccessData)
+{
+    return getChannelConfigObject().getChannelAccessPersistData(
+        chNum, chAccessData);
+}
+
+Cc setChannelAccessPersistData(const uint8_t chNum,
+                               const ChannelAccess& chAccessData,
+                               const uint8_t setFlag)
+{
+    return getChannelConfigObject().setChannelAccessPersistData(
+        chNum, chAccessData, setFlag);
+}
+
+Cc getChannelAuthTypeSupported(const uint8_t chNum, uint8_t& authTypeSupported)
+{
+    return getChannelConfigObject().getChannelAuthTypeSupported(
+        chNum, authTypeSupported);
+}
+
+Cc getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv,
+                             EAuthType& authType)
+{
+    return getChannelConfigObject().getChannelEnabledAuthType(
+        chNum, priv, authType);
+}
+
+std::string getChannelName(const uint8_t chNum)
+{
+    return getChannelConfigObject().getChannelName(chNum);
+}
+
+uint8_t getChannelByName(const std::string& chName)
+{
+    return getChannelConfigObject().getChannelByName(chName);
+}
+
+bool isValidPayloadType(const PayloadType payloadType)
+{
+    return (
+        payloadType == PayloadType::IPMI || payloadType == PayloadType::SOL ||
+        payloadType == PayloadType::OPEN_SESSION_REQUEST ||
+        payloadType == PayloadType::OPEN_SESSION_RESPONSE ||
+        payloadType == PayloadType::RAKP1 ||
+        payloadType == PayloadType::RAKP2 ||
+        payloadType == PayloadType::RAKP3 || payloadType == PayloadType::RAKP4);
+}
+} // namespace ipmi
diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp
new file mode 100644
index 0000000..37d2b90
--- /dev/null
+++ b/user_channel/channel_layer.hpp
@@ -0,0 +1,374 @@
+/*
+// Copyright (c) 2018 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.
+*/
+#pragma once
+#include <openssl/crypto.h>
+
+#include <ipmid/api.hpp>
+
+#include <array>
+#include <string>
+
+namespace ipmi
+{
+
+static constexpr uint8_t maxIpmiChannels = 16;
+static constexpr uint8_t currentChNum = 0xE;
+static constexpr uint8_t invalidChannel = 0xff;
+static constexpr const uint8_t ccActionNotSupportedForChannel = 0x82;
+static constexpr const uint8_t ccAccessModeNotSupportedForChannel = 0x83;
+
+/**
+ * @array of privilege levels
+ */
+extern const std::array<std::string, PRIVILEGE_OEM + 1> privList;
+
+/**
+ * @enum Channel Protocol Type (refer spec sec 6.4)
+ */
+enum class EChannelProtocolType : uint8_t
+{
+    na = 0x00,
+    ipmbV10 = 0x01,
+    icmbV11 = 0x02,
+    reserved = 0x03,
+    ipmiSmbus = 0x04,
+    kcs = 0x05,
+    smic = 0x06,
+    bt10 = 0x07,
+    bt15 = 0x08,
+    tMode = 0x09,
+    oem = 0x1C,
+};
+
+/**
+ * @enum Channel Medium Type (refer spec sec 6.5)
+ */
+enum class EChannelMediumType : uint8_t
+{
+    reserved = 0x00,
+    ipmb = 0x01,
+    icmbV10 = 0x02,
+    icmbV09 = 0x03,
+    lan8032 = 0x04,
+    serial = 0x05,
+    otherLan = 0x06,
+    pciSmbus = 0x07,
+    smbusV11 = 0x08,
+    smbusV20 = 0x09,
+    usbV1x = 0x0A,
+    usbV2x = 0x0B,
+    systemInterface = 0x0C,
+    oem = 0x60,
+    unknown = 0x82,
+};
+
+/**
+ * @enum Channel Session Type (refer spec sec 22.24 -
+ * response data byte 5)
+ */
+enum class EChannelSessSupported : uint8_t
+{
+    none = 0,
+    single = 1,
+    multi = 2,
+    any = 3,
+};
+
+/**
+ * @enum Channel Access Mode (refer spec sec 6.6)
+ */
+enum class EChannelAccessMode : uint8_t
+{
+    disabled = 0,
+    preboot = 1,
+    alwaysAvail = 2,
+    shared = 3,
+};
+
+/**
+ * @enum Authentication Types (refer spec sec 13.6 - IPMI
+ * Session Header)
+ */
+enum class EAuthType : uint8_t
+{
+    none = (1 << 0x0),
+    md2 = (1 << 0x1),
+    md5 = (1 << 0x2),
+    reserved = (1 << 0x3),
+    straightPasswd = (1 << 0x4),
+    oem = (1 << 0x5),
+};
+
+// TODO: Remove duplicate 'PayloadType' definition from netipmid's message.hpp
+// to phosphor-ipmi-host/include
+/**
+ * @enum Payload Types (refer spec sec 13.27.3)
+ */
+enum class PayloadType : uint8_t
+{
+    IPMI = 0x00,
+    SOL = 0x01,
+    OPEN_SESSION_REQUEST = 0x10,
+    OPEN_SESSION_RESPONSE = 0x11,
+    RAKP1 = 0x12,
+    RAKP2 = 0x13,
+    RAKP3 = 0x14,
+    RAKP4 = 0x15,
+    INVALID = 0xFF,
+};
+
+/**
+ * @enum Access mode for channel access set/get (refer spec
+ * sec 22.22 - request byte 2[7:6])
+ */
+typedef enum
+{
+    doNotSet = 0x00,
+    nvData = 0x01,
+    activeData = 0x02,
+    reserved = 0x03,
+} EChannelActionType;
+
+/**
+ * @enum Access set flag to determine changes that has to be updated
+ * in channel access data configuration.
+ */
+enum AccessSetFlag
+{
+    setAccessMode = (1 << 0),
+    setUserAuthEnabled = (1 << 1),
+    setMsgAuthEnabled = (1 << 2),
+    setAlertingEnabled = (1 << 3),
+    setPrivLimit = (1 << 4),
+};
+
+/** @struct ChannelAccess
+ *
+ *  Structure to store channel access related information, defined in IPMI
+ * specification and used in Get / Set channel access (refer spec sec 22.22
+ * & 22.23)
+ */
+struct ChannelAccess
+{
+    uint8_t accessMode;
+    bool userAuthDisabled;
+    bool perMsgAuthDisabled;
+    bool alertingDisabled;
+    uint8_t privLimit;
+};
+
+/** @struct ChannelInfo
+ *
+ *  Structure to store data about channel information, which identifies each
+ *  channel type and information as defined in IPMI specification. (refer spec
+ * sec 22.22 & 22.23)
+ */
+struct ChannelInfo
+{
+    uint8_t mediumType;
+    uint8_t protocolType;
+    uint8_t sessionSupported;
+    bool isIpmi; // Is session IPMI
+    // This is used in Get LAN Configuration parameter.
+    // This holds the supported AuthTypes for a given channel.
+    uint8_t authTypeSupported;
+};
+
+/** @brief determines valid channel
+ *
+ *  @param[in] chNum- channel number
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidChannel(const uint8_t chNum);
+
+/** @brief determines whether channel device exist
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return true if valid, false otherwise
+ */
+bool doesDeviceExist(const uint8_t chNum);
+
+/** @brief determines whether privilege limit is valid
+ *
+ *  @param[in] privLimit - Privilege limit
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidPrivLimit(const uint8_t privLimit);
+
+/** @brief determines whether access mode  is valid
+ *
+ *  @param[in] accessMode - Access mode
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidAccessMode(const uint8_t accessMode);
+
+/** @brief determines valid authentication type based on channel number
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] authType - authentication type
+ *
+ *  @return true if valid, false otherwise
+ */
+bool isValidAuthType(const uint8_t chNum, const EAuthType& authType);
+
+/** @brief determines supported session type of a channel
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return EChannelSessSupported - supported session type
+ */
+EChannelSessSupported getChannelSessionSupport(const uint8_t chNum);
+
+/** @brief determines number of active sessions on a channel
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return numer of active sessions
+ */
+int getChannelActiveSessions(const uint8_t chNum);
+
+/** @brief determines maximum transfer size for a channel
+ *
+ *  @param[in] chNum - channel number
+ *
+ *  @return maximum bytes that can be transferred on this channel
+ */
+size_t getChannelMaxTransferSize(uint8_t chNum);
+
+/** @brief initializes channel management
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiChannelInit();
+
+/** @brief provides channel info details
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] chInfo - channel info details
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo);
+
+/** @brief provides channel access data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] chAccessData -channel access data
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc getChannelAccessData(const uint8_t chNum, ChannelAccess& chAccessData);
+
+/** @brief provides function to convert current channel number (0xE)
+ *
+ *  @param[in] chNum - channel number as requested in commands.
+ *  @param[in] devChannel - channel number as provided by device (not 0xE)
+ *
+ *  @return same channel number or proper channel number for current channel
+ * number (0xE).
+ */
+static inline uint8_t convertCurrentChannelNum(const uint8_t chNum,
+                                               const uint8_t devChannel)
+{
+    if (chNum == currentChNum)
+    {
+        return devChannel;
+    }
+    return chNum;
+}
+
+/** @brief to set channel access data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] chAccessData - channel access data
+ *  @param[in] setFlag - flag to indicate updatable fields
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc setChannelAccessData(const uint8_t chNum, const ChannelAccess& chAccessData,
+                        const uint8_t setFlag);
+
+/** @brief to get channel access data persistent data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] chAccessData - channel access data
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc getChannelAccessPersistData(const uint8_t chNum,
+                               ChannelAccess& chAccessData);
+
+/** @brief to set channel access data persistent data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] chAccessData - channel access data
+ *  @param[in] setFlag - flag to indicate updatable fields
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc setChannelAccessPersistData(const uint8_t chNum,
+                               const ChannelAccess& chAccessData,
+                               const uint8_t setFlag);
+
+/** @brief provides supported authentication type for the channel
+ *
+ *  @param[in] chNum - channel number
+ *  @param[out] authTypeSupported - supported authentication type
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc getChannelAuthTypeSupported(const uint8_t chNum, uint8_t& authTypeSupported);
+
+/** @brief provides enabled authentication type for the channel
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] priv - privilege
+ *  @param[out] authType - enabled authentication type
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv,
+                             EAuthType& authType);
+
+/** @brief Retrieves the LAN channel name from the IPMI channel number
+ *
+ *  @param[in] chNum - IPMI channel number
+ *
+ *  @return the LAN channel name (i.e. eth0)
+ */
+std::string getChannelName(const uint8_t chNum);
+
+/** @brief Retrieves the LAN channel number from the IPMI channel name
+ *
+ *  @param[in] chName - IPMI channel name (i.e. eth0)
+ *
+ *  @return the LAN channel number
+ */
+uint8_t getChannelByName(const std::string& chName);
+
+/** @brief determines whether payload type is valid
+ *
+ *	@param[in] payload type - Payload Type
+ *
+ *	@return true if valid, false otherwise
+ */
+bool isValidPayloadType(const PayloadType payloadType);
+
+} // namespace ipmi
diff --git a/user_channel/channel_mgmt.cpp b/user_channel/channel_mgmt.cpp
new file mode 100644
index 0000000..8594d65
--- /dev/null
+++ b/user_channel/channel_mgmt.cpp
@@ -0,0 +1,1445 @@
+/*
+// Copyright (c) 2018 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 "channel_mgmt.hpp"
+
+#include "user_layer.hpp"
+
+#include <ifaddrs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/server/object.hpp>
+
+#include <cerrno>
+#include <exception>
+#include <filesystem>
+#include <fstream>
+#include <unordered_map>
+
+namespace ipmi
+{
+
+static constexpr const char* channelAccessDefaultFilename =
+    "/usr/share/ipmi-providers/channel_access.json";
+static constexpr const char* channelConfigDefaultFilename =
+    "/usr/share/ipmi-providers/channel_config.json";
+static constexpr const char* channelNvDataFilename =
+    "/var/lib/ipmi/channel_access_nv.json";
+static constexpr const char* channelVolatileDataFilename =
+    "/run/ipmi/channel_access_volatile.json";
+
+// TODO: Get the service name dynamically..
+static constexpr const char* networkIntfServiceName =
+    "xyz.openbmc_project.Network";
+static constexpr const char* networkIntfObjectBasePath =
+    "/xyz/openbmc_project/network";
+static constexpr const char* networkChConfigIntfName =
+    "xyz.openbmc_project.Channel.ChannelAccess";
+static constexpr const char* privilegePropertyString = "MaxPrivilege";
+static constexpr const char* dBusPropertiesInterface =
+    "org.freedesktop.DBus.Properties";
+static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
+static constexpr const char* interfaceAddedSignal = "InterfacesAdded";
+static constexpr const char* interfaceRemovedSignal = "InterfacesRemoved";
+
+// STRING DEFINES: Should sync with key's in JSON
+static constexpr const char* nameString = "name";
+static constexpr const char* isValidString = "is_valid";
+static constexpr const char* activeSessionsString = "active_sessions";
+static constexpr const char* maxTransferSizeString = "max_transfer_size";
+static constexpr const char* channelInfoString = "channel_info";
+static constexpr const char* mediumTypeString = "medium_type";
+static constexpr const char* protocolTypeString = "protocol_type";
+static constexpr const char* sessionSupportedString = "session_supported";
+static constexpr const char* isIpmiString = "is_ipmi";
+static constexpr const char* isManagementNIC = "is_management_nic";
+static constexpr const char* accessModeString = "access_mode";
+static constexpr const char* userAuthDisabledString = "user_auth_disabled";
+static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
+static constexpr const char* alertingDisabledString = "alerting_disabled";
+static constexpr const char* privLimitString = "priv_limit";
+
+// Default values
+static constexpr const char* defaultChannelName = "RESERVED";
+static constexpr const uint8_t defaultMediumType =
+    static_cast<uint8_t>(EChannelMediumType::reserved);
+static constexpr const uint8_t defaultProtocolType =
+    static_cast<uint8_t>(EChannelProtocolType::reserved);
+static constexpr const uint8_t defaultSessionSupported =
+    static_cast<uint8_t>(EChannelSessSupported::none);
+static constexpr const uint8_t defaultAuthType =
+    static_cast<uint8_t>(EAuthType::none);
+static constexpr const bool defaultIsIpmiState = false;
+static constexpr size_t smallChannelSize = 64;
+
+std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
+    __attribute__((init_priority(101)));
+
+std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
+    __attribute__((init_priority(101)));
+
+std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
+    __attribute__((init_priority(101)));
+
+// String mappings use in JSON config file
+static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
+    {"reserved", EChannelMediumType::reserved},
+    {"ipmb", EChannelMediumType::ipmb},
+    {"icmb-v1.0", EChannelMediumType::icmbV10},
+    {"icmb-v0.9", EChannelMediumType::icmbV09},
+    {"lan-802.3", EChannelMediumType::lan8032},
+    {"serial", EChannelMediumType::serial},
+    {"other-lan", EChannelMediumType::otherLan},
+    {"pci-smbus", EChannelMediumType::pciSmbus},
+    {"smbus-v1.0", EChannelMediumType::smbusV11},
+    {"smbus-v2.0", EChannelMediumType::smbusV20},
+    {"usb-1x", EChannelMediumType::usbV1x},
+    {"usb-2x", EChannelMediumType::usbV2x},
+    {"system-interface", EChannelMediumType::systemInterface},
+    {"oem", EChannelMediumType::oem},
+    {"unknown", EChannelMediumType::unknown}};
+
+static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
+    {interfaceKCS, "SMS"},
+    {interfaceLAN1, "eth0"},
+    {interfaceUnknown, "unknown"}};
+
+static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
+    {"na", EChannelProtocolType::na},
+    {"ipmb-1.0", EChannelProtocolType::ipmbV10},
+    {"icmb-2.0", EChannelProtocolType::icmbV11},
+    {"reserved", EChannelProtocolType::reserved},
+    {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
+    {"kcs", EChannelProtocolType::kcs},
+    {"smic", EChannelProtocolType::smic},
+    {"bt-10", EChannelProtocolType::bt10},
+    {"bt-15", EChannelProtocolType::bt15},
+    {"tmode", EChannelProtocolType::tMode},
+    {"oem", EChannelProtocolType::oem}};
+
+static std::array<std::string, 4> accessModeList = {
+    "disabled", "pre-boot", "always_available", "shared"};
+
+static std::array<std::string, 4> sessionSupportList = {
+    "session-less", "single-session", "multi-session", "session-based"};
+
+const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
+    "priv-reserved", "priv-callback", "priv-user",
+    "priv-operator", "priv-admin",    "priv-oem"};
+
+std::string ChannelConfig::getChannelName(const uint8_t chNum)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::error("Invalid channel number: {CHANNEL_ID}", "CHANNEL_ID", chNum);
+        throw std::invalid_argument("Invalid channel number");
+    }
+
+    return channelData[chNum].chName;
+}
+
+int ChannelConfig::convertToChannelNumberFromChannelName(
+    const std::string& chName)
+{
+    for (const auto& it : channelData)
+    {
+        if (it.chName == chName)
+        {
+            return it.chID;
+        }
+    }
+    lg2::error("Invalid channel name: {CHANNEL}", "CHANNEL", chName);
+    throw std::invalid_argument("Invalid channel name");
+
+    return -1;
+}
+
+std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
+{
+    const size_t length = strlen(networkIntfObjectBasePath);
+    if (((length + 1) >= path.size()) ||
+        path.compare(0, length, networkIntfObjectBasePath))
+    {
+        lg2::error("Invalid object path: {PATH}", "PATH", path);
+        throw std::invalid_argument("Invalid object path");
+    }
+    std::string chName(path, length + 1);
+    return chName;
+}
+
+void ChannelConfig::processChAccessPropChange(
+    const std::string& path, const DbusChObjProperties& chProperties)
+{
+    // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
+    std::string chName;
+    try
+    {
+        chName = getChannelNameFromPath(path);
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Exception: {MSG}", "MSG", e.what());
+        return;
+    }
+
+    // Get the MaxPrivilege property value from the signal
+    std::string intfPrivStr;
+    std::string propName;
+    for (const auto& prop : chProperties)
+    {
+        if (prop.first == privilegePropertyString)
+        {
+            propName = privilegePropertyString;
+            intfPrivStr = std::get<std::string>(prop.second);
+            break;
+        }
+    }
+
+    if (propName != privilegePropertyString)
+    {
+        lg2::error("Unknown signal caught.");
+        return;
+    }
+
+    if (intfPrivStr.empty())
+    {
+        lg2::error("Invalid privilege string for intf {INTF}", "INTF", chName);
+        return;
+    }
+
+    uint8_t intfPriv = 0;
+    int chNum;
+    try
+    {
+        intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
+        chNum = convertToChannelNumberFromChannelName(chName);
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Exception: {MSG}", "MSG", e.what());
+        return;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+    // skip updating the values, if this property change originated from IPMI.
+    if (signalFlag & (1 << chNum))
+    {
+        signalFlag &= ~(1 << chNum);
+        lg2::debug("Request originated from IPMI so ignoring signal");
+        return;
+    }
+
+    // Update both volatile & Non-volatile, if there is mismatch.
+    // as property change other than IPMI, has to update both volatile &
+    // non-volatile data.
+    checkAndReloadVolatileData();
+    checkAndReloadNVData();
+    if (channelData[chNum].chAccess.chNonVolatileData.privLimit != intfPriv)
+    {
+        // Update NV data
+        channelData[chNum].chAccess.chNonVolatileData.privLimit = intfPriv;
+        if (writeChannelPersistData() != 0)
+        {
+            lg2::error("Failed to update the persist data file");
+            return;
+        }
+
+        // Update Volatile data
+        if (channelData[chNum].chAccess.chVolatileData.privLimit != intfPriv)
+        {
+            channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
+            if (writeChannelVolatileData() != 0)
+            {
+                lg2::error("Failed to update the volatile data file");
+                return;
+            }
+        }
+    }
+
+    return;
+}
+
+ChannelConfig& getChannelConfigObject()
+{
+    static ChannelConfig channelConfig;
+    return channelConfig;
+}
+
+ChannelConfig::~ChannelConfig()
+{
+    if (signalHndlrObjectState)
+    {
+        chPropertiesSignal.reset();
+        chInterfaceAddedSignal.reset();
+        chInterfaceRemovedSignal.reset();
+        sigHndlrLock.unlock();
+    }
+}
+
+ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
+{
+    std::ofstream mutexCleanUpFile;
+    mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
+                          std::ofstream::out | std::ofstream::app);
+    if (!mutexCleanUpFile.good())
+    {
+        lg2::debug("Unable to open mutex cleanup file");
+        return;
+    }
+    mutexCleanUpFile.close();
+    mutexCleanupLock =
+        boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
+    if (mutexCleanupLock.try_lock())
+    {
+        boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
+        channelMutex =
+            std::make_unique<boost::interprocess::named_recursive_mutex>(
+                boost::interprocess::open_or_create, ipmiChannelMutex);
+        mutexCleanupLock.lock_sharable();
+    }
+    else
+    {
+        mutexCleanupLock.lock_sharable();
+        channelMutex =
+            std::make_unique<boost::interprocess::named_recursive_mutex>(
+                boost::interprocess::open_or_create, ipmiChannelMutex);
+    }
+
+    initChannelPersistData();
+
+    sigHndlrLock = boost::interprocess::file_lock(channelNvDataFilename);
+    // Register it for single object and single process either netipmid /
+    // host-ipmid
+    if (chPropertiesSignal == nullptr && sigHndlrLock.try_lock())
+    {
+        lg2::debug("Registering channel signal handler.");
+        chPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::path_namespace(
+                networkIntfObjectBasePath) +
+                sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
+                sdbusplus::bus::match::rules::interface(
+                    dBusPropertiesInterface) +
+                sdbusplus::bus::match::rules::argN(0, networkChConfigIntfName),
+            [&](sdbusplus::message_t& msg) {
+                DbusChObjProperties props;
+                std::string iface;
+                std::string path = msg.get_path();
+                msg.read(iface, props);
+                processChAccessPropChange(path, props);
+            });
+        signalHndlrObjectState = true;
+
+        chInterfaceAddedSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::member(interfaceAddedSignal) +
+                sdbusplus::bus::match::rules::argNpath(
+                    0, std::string(networkIntfObjectBasePath) + "/"),
+            [&](sdbusplus::message_t&) { initChannelPersistData(); });
+
+        chInterfaceRemovedSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::member(interfaceRemovedSignal) +
+                sdbusplus::bus::match::rules::argNpath(
+                    0, std::string(networkIntfObjectBasePath) + "/"),
+            [&](sdbusplus::message_t&) { initChannelPersistData(); });
+    }
+}
+
+bool ChannelConfig::isValidChannel(const uint8_t chNum)
+{
+    if (chNum >= maxIpmiChannels)
+    {
+        lg2::debug("Invalid channel ID - Out of range");
+        return false;
+    }
+
+    if (channelData[chNum].isChValid == false)
+    {
+        lg2::debug("Channel is not valid");
+    }
+
+    return channelData[chNum].isChValid;
+}
+
+EChannelSessSupported ChannelConfig::getChannelSessionSupport(
+    const uint8_t chNum)
+{
+    EChannelSessSupported chSessSupport =
+        (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
+    return chSessSupport;
+}
+
+bool ChannelConfig::isValidAuthType(const uint8_t chNum,
+                                    const EAuthType& authType)
+{
+    if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
+    {
+        lg2::debug("Invalid authentication type");
+        return false;
+    }
+
+    uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
+    if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
+    {
+        lg2::debug("Authentication type is not supported.");
+        return false;
+    }
+
+    return true;
+}
+
+int ChannelConfig::getChannelActiveSessions(const uint8_t chNum)
+{
+    // TODO: TEMPORARY FIX
+    // Channels active session count is managed separately
+    // by monitoring channel session which includes LAN and
+    // RAKP layer changes. This will be updated, once the
+    // authentication part is implemented.
+    return channelData[chNum].activeSessCount;
+}
+
+size_t ChannelConfig::getChannelMaxTransferSize(uint8_t chNum)
+{
+    return channelData[chNum].maxTransferSize;
+}
+
+Cc ChannelConfig::getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
+                sizeof(channelData[chNum].chInfo),
+                reinterpret_cast<uint8_t*>(&chInfo));
+    return ccSuccess;
+}
+
+Cc ChannelConfig::getChannelAccessData(const uint8_t chNum,
+                                       ChannelAccess& chAccessData)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Session-less channel doesn't have access data.");
+        return ccActionNotSupportedForChannel;
+    }
+
+    if (checkAndReloadVolatileData() != 0)
+    {
+        return ccUnspecifiedError;
+    }
+
+    std::copy_n(
+        reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
+        sizeof(channelData[chNum].chAccess.chVolatileData),
+        reinterpret_cast<uint8_t*>(&chAccessData));
+
+    return ccSuccess;
+}
+
+Cc ChannelConfig::setChannelAccessData(const uint8_t chNum,
+                                       const ChannelAccess& chAccessData,
+                                       const uint8_t setFlag)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Session-less channel doesn't have access data.");
+        return ccActionNotSupportedForChannel;
+    }
+
+    if ((setFlag & setAccessMode) &&
+        (!isValidAccessMode(chAccessData.accessMode)))
+    {
+        lg2::debug("Invalid access mode specified");
+        return ccAccessModeNotSupportedForChannel;
+    }
+    if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
+    {
+        lg2::debug("Invalid privilege limit specified");
+        return ccInvalidFieldRequest;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    if (checkAndReloadVolatileData() != 0)
+    {
+        return ccUnspecifiedError;
+    }
+
+    if (setFlag & setAccessMode)
+    {
+        channelData[chNum].chAccess.chVolatileData.accessMode =
+            chAccessData.accessMode;
+    }
+    if (setFlag & setUserAuthEnabled)
+    {
+        channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
+            chAccessData.userAuthDisabled;
+    }
+    if (setFlag & setMsgAuthEnabled)
+    {
+        channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
+            chAccessData.perMsgAuthDisabled;
+    }
+    if (setFlag & setAlertingEnabled)
+    {
+        channelData[chNum].chAccess.chVolatileData.alertingDisabled =
+            chAccessData.alertingDisabled;
+    }
+    if (setFlag & setPrivLimit)
+    {
+        channelData[chNum].chAccess.chVolatileData.privLimit =
+            chAccessData.privLimit;
+    }
+
+    // Write Volatile data to file
+    if (writeChannelVolatileData() != 0)
+    {
+        lg2::debug("Failed to update the channel volatile data");
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+Cc ChannelConfig::getChannelAccessPersistData(const uint8_t chNum,
+                                              ChannelAccess& chAccessData)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Session-less channel doesn't have access data.");
+        return ccActionNotSupportedForChannel;
+    }
+
+    if (checkAndReloadNVData() != 0)
+    {
+        return ccUnspecifiedError;
+    }
+
+    std::copy_n(reinterpret_cast<uint8_t*>(
+                    &channelData[chNum].chAccess.chNonVolatileData),
+                sizeof(channelData[chNum].chAccess.chNonVolatileData),
+                reinterpret_cast<uint8_t*>(&chAccessData));
+
+    return ccSuccess;
+}
+
+Cc ChannelConfig::setChannelAccessPersistData(const uint8_t chNum,
+                                              const ChannelAccess& chAccessData,
+                                              const uint8_t setFlag)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Session-less channel doesn't have access data.");
+        return ccActionNotSupportedForChannel;
+    }
+
+    if ((setFlag & setAccessMode) &&
+        (!isValidAccessMode(chAccessData.accessMode)))
+    {
+        lg2::debug("Invalid access mode specified");
+        return ccAccessModeNotSupportedForChannel;
+    }
+    if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
+    {
+        lg2::debug("Invalid privilege limit specified");
+        return ccInvalidFieldRequest;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    if (checkAndReloadNVData() != 0)
+    {
+        return ccUnspecifiedError;
+    }
+
+    if (setFlag & setAccessMode)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.accessMode =
+            chAccessData.accessMode;
+    }
+    if (setFlag & setUserAuthEnabled)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
+            chAccessData.userAuthDisabled;
+    }
+    if (setFlag & setMsgAuthEnabled)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
+            chAccessData.perMsgAuthDisabled;
+    }
+    if (setFlag & setAlertingEnabled)
+    {
+        channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
+            chAccessData.alertingDisabled;
+    }
+    if (setFlag & setPrivLimit)
+    {
+        // Send Update to network channel config interfaces over dbus
+        std::string privStr = convertToPrivLimitString(chAccessData.privLimit);
+        std::string networkIntfObj = std::string(networkIntfObjectBasePath) +
+                                     "/" + channelData[chNum].chName;
+        try
+        {
+            if (0 != setDbusProperty(networkIntfServiceName, networkIntfObj,
+                                     networkChConfigIntfName,
+                                     privilegePropertyString, privStr))
+            {
+                lg2::debug("Network interface '{INTERFACE}' does not exist",
+                           "INTERFACE", channelData[chNum].chName);
+                return ccUnspecifiedError;
+            }
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            lg2::error("Exception: Network interface does not exist");
+            return ccInvalidFieldRequest;
+        }
+        signalFlag |= (1 << chNum);
+        channelData[chNum].chAccess.chNonVolatileData.privLimit =
+            chAccessData.privLimit;
+    }
+
+    // Write persistent data to file
+    if (writeChannelPersistData() != 0)
+    {
+        lg2::debug("Failed to update the presist data file");
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+Cc ChannelConfig::getChannelAuthTypeSupported(const uint8_t chNum,
+                                              uint8_t& authTypeSupported)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
+    return ccSuccess;
+}
+
+Cc ChannelConfig::getChannelEnabledAuthType(
+    const uint8_t chNum, const uint8_t priv, EAuthType& authType)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Invalid channel");
+        return ccInvalidFieldRequest;
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Sessionless channel doesn't have access data.");
+        return ccInvalidFieldRequest;
+    }
+
+    if (!isValidPrivLimit(priv))
+    {
+        lg2::debug("Invalid privilege specified.");
+        return ccInvalidFieldRequest;
+    }
+
+    // TODO: Hardcoded for now. Need to implement.
+    authType = EAuthType::none;
+
+    return ccSuccess;
+}
+
+std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
+{
+    struct stat fileStat;
+    if (stat(fileName.c_str(), &fileStat) != 0)
+    {
+        lg2::debug("Error in getting last updated time stamp");
+        return -EIO;
+    }
+    return fileStat.st_mtime;
+}
+
+EChannelAccessMode ChannelConfig::convertToAccessModeIndex(
+    const std::string& mode)
+{
+    auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
+    if (iter == accessModeList.end())
+    {
+        lg2::error("Invalid access mode: {MODE_STR}", "MODE_STR", mode);
+        throw std::invalid_argument("Invalid access mode.");
+    }
+
+    return static_cast<EChannelAccessMode>(
+        std::distance(accessModeList.begin(), iter));
+}
+
+std::string ChannelConfig::convertToAccessModeString(const uint8_t value)
+{
+    if (accessModeList.size() <= value)
+    {
+        lg2::error("Invalid access mode: {MODE_IDX}", "MODE_IDX", value);
+        throw std::invalid_argument("Invalid access mode.");
+    }
+
+    return accessModeList.at(value);
+}
+
+CommandPrivilege ChannelConfig::convertToPrivLimitIndex(
+    const std::string& value)
+{
+    auto iter = std::find(privList.begin(), privList.end(), value);
+    if (iter == privList.end())
+    {
+        lg2::error("Invalid privilege: {PRIV_STR}", "PRIV_STR", value);
+        throw std::invalid_argument("Invalid privilege.");
+    }
+
+    return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
+}
+
+std::string ChannelConfig::convertToPrivLimitString(const uint8_t value)
+{
+    if (privList.size() <= value)
+    {
+        lg2::error("Invalid privilege: {PRIV_IDX.", "PRIV_IDX", value);
+        throw std::invalid_argument("Invalid privilege.");
+    }
+
+    return privList.at(value);
+}
+
+EChannelSessSupported ChannelConfig::convertToSessionSupportIndex(
+    const std::string& value)
+{
+    auto iter =
+        std::find(sessionSupportList.begin(), sessionSupportList.end(), value);
+    if (iter == sessionSupportList.end())
+    {
+        lg2::error("Invalid session supported: {SESS_STR}", "SESS_STR", value);
+        throw std::invalid_argument("Invalid session supported.");
+    }
+
+    return static_cast<EChannelSessSupported>(
+        std::distance(sessionSupportList.begin(), iter));
+}
+
+EChannelMediumType ChannelConfig::convertToMediumTypeIndex(
+    const std::string& value)
+{
+    std::unordered_map<std::string, EChannelMediumType>::iterator it =
+        mediumTypeMap.find(value);
+    if (it == mediumTypeMap.end())
+    {
+        lg2::error("Invalid medium type: {MEDIUM_STR}", "MEDIUM_STR", value);
+        throw std::invalid_argument("Invalid medium type.");
+    }
+
+    return static_cast<EChannelMediumType>(it->second);
+}
+
+EChannelProtocolType ChannelConfig::convertToProtocolTypeIndex(
+    const std::string& value)
+{
+    std::unordered_map<std::string, EChannelProtocolType>::iterator it =
+        protocolTypeMap.find(value);
+    if (it == protocolTypeMap.end())
+    {
+        lg2::error("Invalid protocol type: {PROTO_STR}", "PROTO_STR", value);
+        throw std::invalid_argument("Invalid protocol type.");
+    }
+
+    return static_cast<EChannelProtocolType>(it->second);
+}
+
+Json ChannelConfig::readJsonFile(const std::string& configFile)
+{
+    std::ifstream jsonFile(configFile);
+    if (!jsonFile.good())
+    {
+        lg2::info("JSON file '{FILE_NAME}' not found", "FILE_NAME", configFile);
+        return nullptr;
+    }
+
+    Json data = nullptr;
+    try
+    {
+        data = Json::parse(jsonFile, nullptr, false);
+    }
+    catch (const Json::parse_error& e)
+    {
+        lg2::debug("Corrupted channel config: {MSG}", "MSG", e.what());
+        throw std::runtime_error("Corrupted channel config file");
+    }
+
+    return data;
+}
+
+int ChannelConfig::writeJsonFile(const std::string& configFile,
+                                 const Json& jsonData)
+{
+    const std::string tmpFile = configFile + "_tmp";
+    int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
+                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+    if (fd < 0)
+    {
+        lg2::error("Error in creating json file '{FILE_NAME}'", "FILE_NAME",
+                   tmpFile);
+        return -EIO;
+    }
+    const auto& writeData = jsonData.dump();
+    if (write(fd, writeData.c_str(), writeData.size()) !=
+        static_cast<ssize_t>(writeData.size()))
+    {
+        close(fd);
+        lg2::error("Error in writing configuration file '{FILE_NAME}'",
+                   "FILE_NAME", tmpFile);
+        return -EIO;
+    }
+    close(fd);
+
+    if (std::rename(tmpFile.c_str(), configFile.c_str()) != 0)
+    {
+        lg2::error("Error in renaming temporary data file '{FILE_NAME}'",
+                   "FILE_NAME", tmpFile);
+        return -EIO;
+    }
+
+    return 0;
+}
+
+void ChannelConfig::setDefaultChannelConfig(const uint8_t chNum,
+                                            const std::string& chName)
+{
+    channelData[chNum].chName = chName;
+    channelData[chNum].chID = chNum;
+    channelData[chNum].isChValid = false;
+    channelData[chNum].activeSessCount = 0;
+    channelData[chNum].isManagementNIC = false;
+
+    channelData[chNum].chInfo.mediumType = defaultMediumType;
+    channelData[chNum].chInfo.protocolType = defaultProtocolType;
+    channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
+    channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
+    channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
+}
+
+uint8_t ChannelConfig::getManagementNICID()
+{
+    static bool idFound = false;
+    static uint8_t id = 0;
+
+    if (idFound)
+    {
+        return id;
+    }
+
+    for (uint8_t chIdx = 0; chIdx < maxIpmiChannels; chIdx++)
+    {
+        if (channelData[chIdx].isManagementNIC)
+        {
+            id = chIdx;
+            idFound = true;
+            break;
+        }
+    }
+
+    if (!idFound)
+    {
+        id = static_cast<uint8_t>(EChannelID::chanLan1);
+        idFound = true;
+    }
+    return id;
+}
+
+int ChannelConfig::loadChannelConfig()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    Json data = readJsonFile(channelConfigDefaultFilename);
+    if (data.empty())
+    {
+        lg2::debug("Error in opening IPMI Channel data file");
+        return -EIO;
+    }
+
+    channelData.fill(ChannelProperties{});
+
+    // Collect the list of NIC interfaces connected to the BMC. Use this
+    // information to only add IPMI channels that have active NIC interfaces.
+    struct ifaddrs *ifaddr = nullptr, *ifa = nullptr;
+    if (int err = getifaddrs(&ifaddr); err < 0)
+    {
+        lg2::debug("Unable to acquire network interfaces");
+        return -EIO;
+    }
+
+    for (int chNum = 0; chNum < maxIpmiChannels; chNum++)
+    {
+        try
+        {
+            std::string chKey = std::to_string(chNum);
+            Json jsonChData = data[chKey].get<Json>();
+            if (jsonChData.is_null())
+            {
+                // If user didn't want to configure specific channel (say
+                // reserved channel), then load that index with default values.
+                setDefaultChannelConfig(chNum, defaultChannelName);
+                continue;
+            }
+            Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
+            if (jsonChInfo.is_null())
+            {
+                lg2::error("Invalid/corrupted channel config file");
+                freeifaddrs(ifaddr);
+                return -EBADMSG;
+            }
+
+            bool channelFound = true;
+            // Confirm the LAN channel is present
+            if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
+            {
+                channelFound = false;
+                for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
+                {
+                    if (jsonChData[nameString].get<std::string>() ==
+                        ifa->ifa_name)
+                    {
+                        channelFound = true;
+                        break;
+                    }
+                }
+            }
+            ChannelProperties& chData = channelData[chNum];
+            chData.chID = chNum;
+            chData.chName = jsonChData[nameString].get<std::string>();
+            chData.isChValid = channelFound &&
+                               jsonChData[isValidString].get<bool>();
+            chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
+            chData.maxTransferSize =
+                jsonChData.value(maxTransferSizeString, smallChannelSize);
+            if (jsonChData.count(isManagementNIC) != 0)
+            {
+                chData.isManagementNIC =
+                    jsonChData[isManagementNIC].get<bool>();
+            }
+
+            std::string medTypeStr =
+                jsonChInfo[mediumTypeString].get<std::string>();
+            chData.chInfo.mediumType =
+                static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
+            std::string protoTypeStr =
+                jsonChInfo[protocolTypeString].get<std::string>();
+            chData.chInfo.protocolType =
+                static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
+            std::string sessStr =
+                jsonChInfo[sessionSupportedString].get<std::string>();
+            chData.chInfo.sessionSupported =
+                static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
+            chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
+            chData.chInfo.authTypeSupported = defaultAuthType;
+        }
+        catch (const Json::exception& e)
+        {
+            lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
+            freeifaddrs(ifaddr);
+
+            return -EBADMSG;
+        }
+        catch (const std::invalid_argument& e)
+        {
+            lg2::error("Corrupted config: {MSG}", "MSG", e.what());
+            freeifaddrs(ifaddr);
+            return -EBADMSG;
+        }
+    }
+    freeifaddrs(ifaddr);
+
+    return 0;
+}
+
+int ChannelConfig::readChannelVolatileData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    Json data = readJsonFile(channelVolatileDataFilename);
+    if (data == nullptr)
+    {
+        lg2::debug("Error in opening IPMI Channel data file");
+        return -EIO;
+    }
+    try
+    {
+        // Fill in global structure
+        for (auto it = data.begin(); it != data.end(); ++it)
+        {
+            std::string chKey = it.key();
+            uint8_t chNum = std::stoi(chKey, nullptr, 10);
+            if (chNum >= maxIpmiChannels)
+            {
+                lg2::debug("Invalid channel access entry in config file");
+                throw std::out_of_range("Out of range - channel number");
+            }
+            Json jsonChData = it.value();
+            if (!jsonChData.is_null())
+            {
+                std::string accModeStr =
+                    jsonChData[accessModeString].get<std::string>();
+                channelData[chNum].chAccess.chVolatileData.accessMode =
+                    static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
+                channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
+                    jsonChData[userAuthDisabledString].get<bool>();
+                channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
+                    jsonChData[perMsgAuthDisabledString].get<bool>();
+                channelData[chNum].chAccess.chVolatileData.alertingDisabled =
+                    jsonChData[alertingDisabledString].get<bool>();
+                std::string privStr =
+                    jsonChData[privLimitString].get<std::string>();
+                channelData[chNum].chAccess.chVolatileData.privLimit =
+                    static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
+            }
+            else
+            {
+                lg2::error(
+                    "Invalid/corrupted volatile channel access file '{FILE}'",
+                    "FILE", channelVolatileDataFilename);
+                throw std::runtime_error(
+                    "Corrupted volatile channel access file");
+            }
+        }
+    }
+    catch (const Json::exception& e)
+    {
+        lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
+        throw std::runtime_error("Corrupted volatile channel access file");
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Corrupted config: {MSG}", "MSG", e.what());
+        throw std::runtime_error("Corrupted volatile channel access file");
+    }
+
+    // Update the timestamp
+    voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
+    return 0;
+}
+
+int ChannelConfig::readChannelPersistData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    Json data = readJsonFile(channelNvDataFilename);
+    if (data == nullptr)
+    {
+        lg2::debug("Error in opening IPMI Channel data file");
+        return -EIO;
+    }
+    try
+    {
+        // Fill in global structure
+        for (auto it = data.begin(); it != data.end(); ++it)
+        {
+            std::string chKey = it.key();
+            uint8_t chNum = std::stoi(chKey, nullptr, 10);
+            if (chNum >= maxIpmiChannels)
+            {
+                lg2::debug("Invalid channel access entry in config file");
+                throw std::out_of_range("Out of range - channel number");
+            }
+            Json jsonChData = it.value();
+            if (!jsonChData.is_null())
+            {
+                std::string accModeStr =
+                    jsonChData[accessModeString].get<std::string>();
+                channelData[chNum].chAccess.chNonVolatileData.accessMode =
+                    static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
+                channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
+                    jsonChData[userAuthDisabledString].get<bool>();
+                channelData[chNum]
+                    .chAccess.chNonVolatileData.perMsgAuthDisabled =
+                    jsonChData[perMsgAuthDisabledString].get<bool>();
+                channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
+                    jsonChData[alertingDisabledString].get<bool>();
+                std::string privStr =
+                    jsonChData[privLimitString].get<std::string>();
+                channelData[chNum].chAccess.chNonVolatileData.privLimit =
+                    static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
+            }
+            else
+            {
+                lg2::error("Invalid/corrupted nv channel access file {FILE}",
+                           "FILE", channelNvDataFilename);
+                throw std::runtime_error("Corrupted nv channel access file");
+            }
+        }
+    }
+    catch (const Json::exception& e)
+    {
+        lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
+        throw std::runtime_error("Corrupted nv channel access file");
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Corrupted config: {MSG}", "MSG", e.what());
+        throw std::runtime_error("Corrupted nv channel access file");
+    }
+
+    // Update the timestamp
+    nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
+    return 0;
+}
+
+int ChannelConfig::writeChannelVolatileData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+    Json outData;
+
+    try
+    {
+        for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
+        {
+            if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
+            {
+                Json jsonObj;
+                std::string chKey = std::to_string(chNum);
+                std::string accModeStr = convertToAccessModeString(
+                    channelData[chNum].chAccess.chVolatileData.accessMode);
+                jsonObj[accessModeString] = accModeStr;
+                jsonObj[userAuthDisabledString] =
+                    channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
+                jsonObj[perMsgAuthDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chVolatileData.perMsgAuthDisabled;
+                jsonObj[alertingDisabledString] =
+                    channelData[chNum].chAccess.chVolatileData.alertingDisabled;
+                std::string privStr = convertToPrivLimitString(
+                    channelData[chNum].chAccess.chVolatileData.privLimit);
+                jsonObj[privLimitString] = privStr;
+
+                outData[chKey] = jsonObj;
+            }
+        }
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Corrupted config: {MSG}", "MSG", e.what());
+        return -EINVAL;
+    }
+
+    if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
+    {
+        lg2::debug("Error in write JSON data to file");
+        return -EIO;
+    }
+
+    // Update the timestamp
+    voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
+    return 0;
+}
+
+int ChannelConfig::writeChannelPersistData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+    Json outData;
+
+    try
+    {
+        for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
+        {
+            if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
+            {
+                Json jsonObj;
+                std::string chKey = std::to_string(chNum);
+                std::string accModeStr = convertToAccessModeString(
+                    channelData[chNum].chAccess.chNonVolatileData.accessMode);
+                jsonObj[accessModeString] = accModeStr;
+                jsonObj[userAuthDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chNonVolatileData.userAuthDisabled;
+                jsonObj[perMsgAuthDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chNonVolatileData.perMsgAuthDisabled;
+                jsonObj[alertingDisabledString] =
+                    channelData[chNum]
+                        .chAccess.chNonVolatileData.alertingDisabled;
+                std::string privStr = convertToPrivLimitString(
+                    channelData[chNum].chAccess.chNonVolatileData.privLimit);
+                jsonObj[privLimitString] = privStr;
+
+                outData[chKey] = jsonObj;
+            }
+        }
+    }
+    catch (const std::invalid_argument& e)
+    {
+        lg2::error("Corrupted config: {MSG}", "MSG", e.what());
+        return -EINVAL;
+    }
+
+    if (writeJsonFile(channelNvDataFilename, outData) != 0)
+    {
+        lg2::debug("Error in write JSON data to file");
+        return -EIO;
+    }
+
+    // Update the timestamp
+    nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
+    return 0;
+}
+
+int ChannelConfig::checkAndReloadNVData()
+{
+    std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
+    int ret = 0;
+    if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
+    {
+        try
+        {
+            ret = readChannelPersistData();
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Exception caught in readChannelPersistData: {MSG}",
+                       "MSG", e.what());
+            ret = -EIO;
+        }
+    }
+    return ret;
+}
+
+int ChannelConfig::checkAndReloadVolatileData()
+{
+    std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
+    int ret = 0;
+    if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
+    {
+        try
+        {
+            ret = readChannelVolatileData();
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Exception caught in readChannelVolatileData: {MSG}",
+                       "MSG", e.what());
+            ret = -EIO;
+        }
+    }
+    return ret;
+}
+
+int ChannelConfig::setDbusProperty(
+    const std::string& service, const std::string& objPath,
+    const std::string& interface, const std::string& property,
+    const DbusVariant& value)
+{
+    try
+    {
+        auto method =
+            bus.new_method_call(service.c_str(), objPath.c_str(),
+                                "org.freedesktop.DBus.Properties", "Set");
+
+        method.append(interface, property, value);
+
+        auto reply = bus.call(method);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::debug(
+            "set-property {SERVICE}:{OBJPATH}/{INTERFACE}.{PROP} failed: {MSG}",
+            "SERVICE", service, "OBJPATH", objPath, "INTERFACE", interface,
+            "PROP", property, "MSG", e);
+        return -EIO;
+    }
+
+    return 0;
+}
+
+int ChannelConfig::syncNetworkChannelConfig()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+    bool isUpdated = false;
+    for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
+    {
+        if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
+        {
+            std::string intfPrivStr;
+            uint8_t intfPriv = 0;
+            try
+            {
+                std::string networkIntfObj =
+                    std::string(networkIntfObjectBasePath) + "/" +
+                    channelData[chNum].chName;
+                auto propValue = ipmi::getDbusProperty(
+                    bus, networkIntfServiceName, networkIntfObj,
+                    networkChConfigIntfName, privilegePropertyString);
+
+                intfPrivStr = std::get<std::string>(propValue);
+                intfPriv =
+                    static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
+            }
+            catch (const std::bad_variant_access& e)
+            {
+                lg2::debug("Network interface '{INTERFACE}' does not exist",
+                           "INTERFACE", channelData[chNum].chName);
+                continue;
+            }
+            catch (const sdbusplus::exception_t& e)
+            {
+                lg2::debug("Network interface '{INTERFACE}' does not exist",
+                           "INTERFACE", channelData[chNum].chName);
+                continue;
+            }
+            catch (const std::invalid_argument& e)
+            {
+                lg2::debug("exception: Invalid privilege");
+                continue;
+            }
+
+            if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
+                intfPriv)
+            {
+                isUpdated = true;
+                channelData[chNum].chAccess.chNonVolatileData.privLimit =
+                    intfPriv;
+                channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
+            }
+        }
+    }
+
+    if (isUpdated)
+    {
+        // Write persistent data to file
+        if (writeChannelPersistData() != 0)
+        {
+            lg2::debug("Failed to update the persistent data file");
+            return -EIO;
+        }
+        // Write Volatile data to file
+        if (writeChannelVolatileData() != 0)
+        {
+            lg2::debug("Failed to update the channel volatile data");
+            return -EIO;
+        }
+    }
+
+    return 0;
+}
+
+void ChannelConfig::initChannelPersistData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        channelLock{*channelMutex};
+
+    /* Always read the channel config */
+    if (loadChannelConfig() != 0)
+    {
+        lg2::error("Failed to read channel config file");
+        throw std::ios_base::failure("Failed to load channel configuration");
+    }
+
+    /* Populate the channel persist data */
+    if (readChannelPersistData() != 0)
+    {
+        // Copy default NV data to RW location
+        std::filesystem::copy_file(channelAccessDefaultFilename,
+                                   channelNvDataFilename);
+
+        // Load the channel access NV data
+        if (readChannelPersistData() != 0)
+        {
+            lg2::error("Failed to read channel access NV data");
+            throw std::ios_base::failure(
+                "Failed to read channel access NV configuration");
+        }
+    }
+
+    // First check the volatile data file
+    // If not present, load the default values
+    if (readChannelVolatileData() != 0)
+    {
+        // Copy default volatile data to temporary location
+        // NV file(channelNvDataFilename) must have created by now.
+        std::filesystem::copy_file(channelNvDataFilename,
+                                   channelVolatileDataFilename);
+
+        // Load the channel access volatile data
+        if (readChannelVolatileData() != 0)
+        {
+            lg2::error("Failed to read channel access volatile data");
+            throw std::ios_base::failure(
+                "Failed to read channel access volatile configuration");
+        }
+    }
+
+    // Synchronize the channel config(priv) with network channel
+    // configuration(priv) over dbus
+    if (syncNetworkChannelConfig() != 0)
+    {
+        lg2::error(
+            "Failed to synchronize data with network channel config over dbus");
+        throw std::ios_base::failure(
+            "Failed to synchronize data with network channel config over dbus");
+    }
+
+    lg2::debug("Successfully completed channel data initialization.");
+    return;
+}
+
+} // namespace ipmi
diff --git a/user_channel/channel_mgmt.hpp b/user_channel/channel_mgmt.hpp
new file mode 100644
index 0000000..5ec5a16
--- /dev/null
+++ b/user_channel/channel_mgmt.hpp
@@ -0,0 +1,428 @@
+/*
+// Copyright (c) 2018 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.
+*/
+
+#pragma once
+#include "channel_layer.hpp"
+#include "ipmid/api-types.hpp"
+
+#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/interprocess/sync/named_recursive_mutex.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <cstdint>
+#include <ctime>
+#include <variant>
+
+namespace ipmi
+{
+
+using Json = nlohmann::json;
+
+using DbusVariant = std::variant<std::vector<std::string>, std::string, bool>;
+
+using DbusChObjProperties = std::vector<std::pair<std::string, DbusVariant>>;
+
+static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex";
+static constexpr const char* ipmiChMutexCleanupLockFile =
+    "/run/ipmi/ipmi_channel_mutex_cleanup";
+
+/** @struct ChannelAccessData
+ *
+ *  Structure to store both non-volatile and volatile channel access information
+ *  as used by IPMI specification (refer spec sec 22.22 to 22.24)
+ */
+struct ChannelAccessData
+{
+    ChannelAccess chNonVolatileData;
+    ChannelAccess chVolatileData;
+};
+
+/** @struct ChannelProperties
+ *
+ *  Structure for channel information - base structure to get all information
+ * about the channel.(refer spec sec 22.22 to 22.24)
+ */
+struct ChannelProperties
+{
+    std::string chName;
+    uint8_t chID;
+    bool isChValid;
+    uint8_t activeSessCount;
+    ChannelInfo chInfo;
+    ChannelAccessData chAccess;
+    size_t maxTransferSize;
+    bool isManagementNIC;
+};
+
+class ChannelConfig;
+
+ChannelConfig& getChannelConfigObject();
+
+class ChannelConfig
+{
+  public:
+    ChannelConfig(const ChannelConfig&) = delete;
+    ChannelConfig& operator=(const ChannelConfig&) = delete;
+    ChannelConfig(ChannelConfig&&) = delete;
+    ChannelConfig& operator=(ChannelConfig&&) = delete;
+
+    ~ChannelConfig();
+    ChannelConfig();
+
+    /** @brief determines valid channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return true if valid, false otherwise
+     */
+    bool isValidChannel(const uint8_t chNum);
+
+    /** @brief determines valid authentication type
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] authType - authentication type
+     *
+     *  @return true if valid, false otherwise
+     */
+    bool isValidAuthType(const uint8_t chNum, const EAuthType& authType);
+
+    /** @brief function to get channel name from channel number
+     *
+     *  @param[in] chNum - channel number index
+     *
+     *  @return network channel interface name
+     */
+    std::string getChannelName(const uint8_t chNum);
+
+    /** @brief function to get channel number from channel name
+     *
+     *  @param[in] chName - channel name
+     *
+     *  @return network channel interface number
+     */
+
+    uint8_t getChannelByName(const std::string& chName)
+    {
+        return convertToChannelNumberFromChannelName(chName);
+    }
+
+    /** @brief determines supported session type of a channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return EChannelSessSupported - supported session type
+     */
+    EChannelSessSupported getChannelSessionSupport(const uint8_t chNum);
+
+    /** @brief determines number of active sessions on a channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return numer of active sessions
+     */
+    int getChannelActiveSessions(const uint8_t chNum);
+
+    /** @brief determines maximum transfer size for a channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return maximum bytes that can be transferred on this channel
+     */
+    size_t getChannelMaxTransferSize(uint8_t chNum);
+
+    /** @brief provides channel info details
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] chInfo - channel info details
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo);
+
+    /** @brief provides channel access data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] chAccessData - channel access data
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc getChannelAccessData(const uint8_t chNum, ChannelAccess& chAccessData);
+
+    /** @brief to set channel access data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] chAccessData - channel access data
+     *  @param[in] setFlag - flag to indicate updatable fields
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setChannelAccessData(const uint8_t chNum,
+                            const ChannelAccess& chAccessData,
+                            const uint8_t setFlag);
+
+    /** @brief to get channel access data persistent data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] chAccessData - channel access data
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc getChannelAccessPersistData(const uint8_t chNum,
+                                   ChannelAccess& chAccessData);
+
+    /** @brief to set channel access data persistent data
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] chAccessData - channel access data
+     *  @param[in] setFlag - flag to indicate updatable fields
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setChannelAccessPersistData(const uint8_t chNum,
+                                   const ChannelAccess& chAccessData,
+                                   const uint8_t setFlag);
+
+    /** @brief provides supported authentication type for the channel
+     *
+     *  @param[in] chNum - channel number
+     *  @param[out] authTypeSupported - supported authentication type
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc getChannelAuthTypeSupported(const uint8_t chNum,
+                                   uint8_t& authTypeSupported);
+
+    /** @brief provides enabled authentication type for the channel
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] priv - privilege
+     *  @param[out] authType - enabled authentication type
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv,
+                                 EAuthType& authType);
+
+    /** @brief conver to channel privilege from system privilege
+     *
+     *  @param[in] value - privilege value
+     *
+     *  @return Channel privilege
+     */
+    CommandPrivilege convertToPrivLimitIndex(const std::string& value);
+
+    /** @brief function to write persistent channel configuration to config file
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeChannelPersistData();
+
+    /** @brief function to write volatile channel configuration to config file
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeChannelVolatileData();
+
+    /** @brief Returns the IPMI channel ID authorized to push IPMI privilege
+     * changes to phosphor-user-manager. Any channel access changes made on
+     * any other channel are ignored.
+     *
+     *  @return IPMI channel ID as defined in channel_config.json
+     */
+    uint8_t getManagementNICID();
+
+  private:
+    uint32_t signalFlag = 0;
+    std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
+        nullptr};
+    std::array<ChannelProperties, maxIpmiChannels> channelData;
+    std::time_t nvFileLastUpdatedTime;
+    std::time_t voltFileLastUpdatedTime;
+    boost::interprocess::file_lock mutexCleanupLock;
+    sdbusplus::bus_t bus;
+    bool signalHndlrObjectState = false;
+    boost::interprocess::file_lock sigHndlrLock;
+
+    /** @brief function to initialize persistent channel configuration
+     *
+     */
+    void initChannelPersistData();
+
+    /** @brief function to set default channel configuration based on channel
+     * number
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] chName - channel name
+     */
+    void setDefaultChannelConfig(const uint8_t chNum,
+                                 const std::string& chName);
+
+    /** @brief function to load all channel configuration
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int loadChannelConfig();
+
+    /** @brief function to read persistent channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int readChannelPersistData();
+
+    /** @brief function to read volatile channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int readChannelVolatileData();
+
+    /** @brief function to check and reload persistent channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int checkAndReloadNVData();
+
+    /** @brief function to check and reload volatile channel data
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int checkAndReloadVolatileData();
+
+    /** @brief function to sync channel privilege with system network channel
+     * privilege
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int syncNetworkChannelConfig();
+
+    /** @brief function to set D-Bus property value
+     *
+     *  @param[in] service - service name
+     *  @param[in] objPath - object path
+     *  @param[in] interface - interface
+     *  @param[in] property - property name
+     *  @param[in] value - property value
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int setDbusProperty(const std::string& service, const std::string& objPath,
+                        const std::string& interface,
+                        const std::string& property, const DbusVariant& value);
+
+    /** @brief function to read json config file
+     *
+     *  @param[in] configFile - configuration file name
+     *
+     *  @return Json object
+     */
+    Json readJsonFile(const std::string& configFile);
+
+    /** @brief function to write json config file
+     *
+     *  @param[in] configFile - configuration file name
+     *  @param[in] jsonData - json object
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeJsonFile(const std::string& configFile, const Json& jsonData);
+
+    /** @brief function to convert system access mode to Channel access mode
+     * type
+     *
+     *  @param[in] mode - access mode in string
+     *
+     *  @return Channel access mode.
+     */
+    EChannelAccessMode convertToAccessModeIndex(const std::string& mode);
+
+    /** @brief function to convert access mode value to string
+     *
+     *  @param[in] value - acess mode value
+     *
+     *  @return access mode in string
+     */
+    std::string convertToAccessModeString(const uint8_t value);
+
+    /** @brief function to convert privilege value to string
+     *
+     *  @param[in] value - privilege value
+     *
+     *  @return privilege in string
+     */
+    std::string convertToPrivLimitString(const uint8_t value);
+
+    /** @brief function to convert session support string to value type
+     *
+     *  @param[in] value - session support type in string
+     *
+     *  @return support session type
+     */
+    EChannelSessSupported convertToSessionSupportIndex(
+        const std::string& value);
+
+    /** @brief function to convert medium type string to value type
+     *
+     *  @param[in] value - medium type in string
+     *
+     *  @return channel medium type
+     */
+    EChannelMediumType convertToMediumTypeIndex(const std::string& value);
+
+    /** @brief function to convert protocol type string to value type
+     *
+     *  @param[in] value - protocol type in string
+     *
+     *  @return channel protocol  type
+     */
+    EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
+
+    /** @brief function to convert channel name to the IPMI channel number.
+     *
+     *  @param[in] chName - the channel name defined in the JSON input file
+     *  (i.e. LAN1)
+     *
+     *  @return IPMI channel number
+     */
+    int convertToChannelNumberFromChannelName(const std::string& chName);
+
+    /** @brief function to handle Channel access property update through the
+     * D-Bus handler.
+     *
+     *  @param[in] path - D-Bus path to the network element (i.e. eth0)
+     *  @param[in] chProperties - D-Bus channel properties
+     */
+    void processChAccessPropChange(const std::string& path,
+                                   const DbusChObjProperties& chProperties);
+
+    /** @brief function to retrieve last modification time for the named file
+     *
+     *  @param[in] fileName - the name of the file for which to acquire
+     *  timestamp data
+     *
+     *  @return time the file was last modified
+     */
+    std::time_t getUpdatedFileTime(const std::string& fileName);
+
+    /** @brief function to convert the DBus path to a network channel name
+     *
+     *  @param[in] path - The DBus path to the device
+     *
+     *  @return network channel name (i.e. eth0)
+     */
+    std::string getChannelNameFromPath(const std::string& path);
+};
+
+} // namespace ipmi
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp
new file mode 100644
index 0000000..cb4da6b
--- /dev/null
+++ b/user_channel/channelcommands.cpp
@@ -0,0 +1,420 @@
+/*
+// Copyright (c) 2018 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 "channel_layer.hpp"
+
+#include <ipmid/api.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <regex>
+
+namespace ipmi
+{
+
+/** @brief implements the set channel access command
+ *  @ param ctx - context pointer
+ *  @ param channel - channel number
+ *  @ param reserved - skip 4 bits
+ *  @ param accessMode - access mode for IPMI messaging
+ *  @ param usrAuth - user level authentication (enable/disable)
+ *  @ param msgAuth - per message authentication (enable/disable)
+ *  @ param alertDisabled - PEF alerting (enable/disable)
+ *  @ param chanAccess - channel access
+ *  @ param channelPrivLimit - channel privilege limit
+ *  @ param reserved - skip 3 bits
+ *  @ param channelPrivMode - channel priviledge mode
+ *
+ *  @ returns IPMI completion code
+ **/
+RspType<> ipmiSetChannelAccess(
+    Context::ptr ctx, uint4_t channel, uint4_t reserved1, uint3_t accessMode,
+    bool usrAuth, bool msgAuth, bool alertDisabled, uint2_t chanAccess,
+    uint4_t channelPrivLimit, uint2_t reserved2, uint2_t channelPrivMode)
+{
+    if (reserved1 || reserved2 ||
+        !isValidPrivLimit(static_cast<uint8_t>(channelPrivLimit)))
+    {
+        lg2::debug("Set channel access - Invalid field in request");
+        return responseInvalidFieldRequest();
+    }
+
+    const uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
+        (!isValidChannel(chNum)))
+    {
+        lg2::debug("Set channel access - No support on channel: {CHANNEL}",
+                   "CHANNEL", chNum);
+        return response(ccActionNotSupportedForChannel);
+    }
+
+    ChannelAccess chActData;
+    ChannelAccess chNVData;
+    uint8_t setActFlag = 0;
+    uint8_t setNVFlag = 0;
+    Cc compCode;
+
+    // cannot static cast directly from uint2_t to enum; must go via int
+    uint8_t channelAccessAction = static_cast<uint8_t>(chanAccess);
+    switch (static_cast<EChannelActionType>(channelAccessAction))
+    {
+        case doNotSet:
+            break;
+        case nvData:
+            chNVData.accessMode = static_cast<uint8_t>(accessMode);
+            chNVData.userAuthDisabled = usrAuth;
+            chNVData.perMsgAuthDisabled = msgAuth;
+            chNVData.alertingDisabled = alertDisabled;
+            setNVFlag |= (setAccessMode | setUserAuthEnabled |
+                          setMsgAuthEnabled | setAlertingEnabled);
+            break;
+
+        case activeData:
+            chActData.accessMode = static_cast<uint8_t>(accessMode);
+            chActData.userAuthDisabled = usrAuth;
+            chActData.perMsgAuthDisabled = msgAuth;
+            chActData.alertingDisabled = alertDisabled;
+            setActFlag |= (setAccessMode | setUserAuthEnabled |
+                           setMsgAuthEnabled | setAlertingEnabled);
+            break;
+
+        case reserved:
+        default:
+            lg2::debug("Set channel access - Invalid access set mode");
+            return response(ccAccessModeNotSupportedForChannel);
+    }
+
+    // cannot static cast directly from uint2_t to enum; must go via int
+    uint8_t channelPrivAction = static_cast<uint8_t>(channelPrivMode);
+    switch (static_cast<EChannelActionType>(channelPrivAction))
+    {
+        case doNotSet:
+            break;
+        case nvData:
+            chNVData.privLimit = static_cast<uint8_t>(channelPrivLimit);
+            setNVFlag |= setPrivLimit;
+            break;
+        case activeData:
+            chActData.privLimit = static_cast<uint8_t>(channelPrivLimit);
+
+            setActFlag |= setPrivLimit;
+            break;
+        case reserved:
+        default:
+            lg2::debug("Set channel access - Invalid access priv mode");
+            return response(ccAccessModeNotSupportedForChannel);
+    }
+
+    if (setNVFlag != 0)
+    {
+        compCode = setChannelAccessPersistData(chNum, chNVData, setNVFlag);
+        if (compCode != ccSuccess)
+        {
+            lg2::debug("Set channel access - Failed to set access data");
+            return response(compCode);
+        }
+    }
+
+    if (setActFlag != 0)
+    {
+        compCode = setChannelAccessData(chNum, chActData, setActFlag);
+        if (compCode != ccSuccess)
+        {
+            lg2::debug("Set channel access - Failed to set access data");
+            return response(compCode);
+        }
+    }
+
+    return responseSuccess();
+}
+
+/** @brief implements the get channel access command
+ *  @ param ctx - context pointer
+ *  @ param channel - channel number
+ *  @ param reserved1 - skip 4 bits
+ *  @ param reserved2 - skip 6 bits
+ *  @ param accessMode - get access mode
+ *
+ *  @returns ipmi completion code plus response data
+ *  - accessMode - get access mode
+ *  - usrAuthDisabled - user level authentication status
+ *  - msgAuthDisabled - message level authentication status
+ *  - alertDisabled - alerting status
+ *  - reserved - skip 2 bits
+ *  - privLimit - channel privilege limit
+ *  - reserved - skip 4 bits
+ * */
+ipmi ::RspType<uint3_t, // access mode,
+               bool,    // user authentication status,
+               bool,    // message authentication status,
+               bool,    // alerting status,
+               uint2_t, // reserved,
+
+               uint4_t, // channel privilege,
+               uint4_t  // reserved
+               >
+    ipmiGetChannelAccess(Context::ptr ctx, uint4_t channel, uint4_t reserved1,
+                         uint6_t reserved2, uint2_t accessSetMode)
+{
+    if (reserved1 || reserved2)
+    {
+        lg2::debug("Get channel access - Invalid field in request");
+        return responseInvalidFieldRequest();
+    }
+
+    if ((types::enum_cast<EChannelActionType>(accessSetMode) == doNotSet) ||
+        (types::enum_cast<EChannelActionType>(accessSetMode) == reserved))
+    {
+        lg2::debug("Get channel access - Invalid Access mode");
+        return responseInvalidFieldRequest();
+    }
+
+    const uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+
+    if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
+        (!isValidChannel(chNum)))
+    {
+        lg2::debug("Get channel access - No support on channel: {CHANNEL}",
+                   "CHANNEL", chNum);
+        return response(ccActionNotSupportedForChannel);
+    }
+
+    ChannelAccess chAccess = {};
+
+    Cc compCode = ipmi::ccUnspecifiedError;
+
+    if (types::enum_cast<EChannelActionType>(accessSetMode) == nvData)
+    {
+        compCode = getChannelAccessPersistData(chNum, chAccess);
+    }
+    else if (types::enum_cast<EChannelActionType>(accessSetMode) == activeData)
+    {
+        compCode = getChannelAccessData(chNum, chAccess);
+    }
+
+    if (compCode != ccSuccess)
+    {
+        return response(compCode);
+    }
+
+    constexpr uint2_t reservedOut1 = 0;
+    constexpr uint4_t reservedOut2 = 0;
+
+    return responseSuccess(
+        types::enum_cast<uint3_t>(chAccess.accessMode),
+        chAccess.userAuthDisabled, chAccess.perMsgAuthDisabled,
+        chAccess.alertingDisabled, reservedOut1,
+        types::enum_cast<uint4_t>(chAccess.privLimit), reservedOut2);
+}
+
+/** @brief implements the get channel info command
+ *  @ param ctx - context pointer
+ *  @ param channel - channel number
+ *  @ param reserved - skip 4 bits
+ *
+ *  @returns ipmi completion code plus response data
+ *  - chNum - the channel number for this request
+ *  - mediumType - see Table 6-3, Channel Medium Type Numbers
+ *  - protocolType - Table 6-2, Channel Protocol Type Numbers
+ *  - activeSessionCount - number of active sessions
+ *  - sessionType - channel support for sessions
+ *  - vendorId - vendor for this channel protocol (IPMI - 7154)
+ *  - auxChInfo - auxiliary info for channel
+ * */
+RspType<uint4_t,  // chNum
+        uint4_t,  // reserved
+        uint7_t,  // mediumType
+        bool,     // reserved
+        uint5_t,  // protocolType
+        uint3_t,  // reserved
+        uint6_t,  // activeSessionCount
+        uint2_t,  // sessionType
+        uint24_t, // Vendor IANA
+        uint16_t  // aux info
+        >
+    ipmiGetChannelInfo(Context::ptr ctx, uint4_t channel, uint4_t reserved)
+{
+    if (reserved)
+    {
+        lg2::debug("Get channel access - Invalid field in request");
+        return responseInvalidFieldRequest();
+    }
+
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Get channel Info - No support on channel: {CHANNEL}",
+                   "CHANNEL", chNum);
+        return responseInvalidFieldRequest();
+    }
+
+    ChannelInfo chInfo;
+    Cc compCode = getChannelInfo(chNum, chInfo);
+    if (compCode != ccSuccess)
+    {
+        lg2::error("Failed to get channel info, channel: {CHANNEL}, "
+                   "errno: {ERRNO}",
+                   "CHANNEL", chNum, "ERRNO", compCode);
+        return response(compCode);
+    }
+
+    constexpr uint4_t reserved1 = 0;
+    constexpr bool reserved2 = false;
+    constexpr uint3_t reserved3 = 0;
+    uint8_t mediumType = chInfo.mediumType;
+    uint8_t protocolType = chInfo.protocolType;
+    uint2_t sessionType = chInfo.sessionSupported;
+    uint6_t activeSessionCount = getChannelActiveSessions(chNum);
+    // IPMI Spec: The IPMI Enterprise Number is: 7154 (decimal)
+    constexpr uint24_t vendorId = 7154;
+    constexpr uint16_t auxChInfo = 0;
+
+    return responseSuccess(chNum, reserved1, mediumType, reserved2,
+                           protocolType, reserved3, activeSessionCount,
+                           sessionType, vendorId, auxChInfo);
+}
+
+namespace
+{
+constexpr uint16_t standardPayloadBit(PayloadType p)
+{
+    return (1 << static_cast<size_t>(p));
+}
+
+constexpr uint16_t sessionPayloadBit(PayloadType p)
+{
+    constexpr size_t sessionShift =
+        static_cast<size_t>(PayloadType::OPEN_SESSION_REQUEST);
+    return ((1 << static_cast<size_t>(p)) >> sessionShift);
+}
+} // namespace
+
+/** @brief implements get channel payload support command
+ *  @ param ctx - ipmi context pointer
+ *  @ param chNum - channel number
+ *  @ param reserved - skip 4 bits
+ *
+ *  @ returns IPMI completion code plus response data
+ *  - stdPayloadType - bitmask of supported standard payload types
+ *  - sessSetupPayloadType - bitmask of supported session setup payload types
+ *  - OEMPayloadType - bitmask of supported OEM payload types
+ *  - reserved - 2 bytes of 0
+ **/
+RspType<uint16_t, // stdPayloadType
+        uint16_t, // sessSetupPayloadType
+        uint16_t, // OEMPayloadType
+        uint16_t  // reserved
+        >
+    ipmiGetChannelPayloadSupport(Context::ptr ctx, uint4_t channel,
+                                 uint4_t reserved)
+{
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+
+    if (!doesDeviceExist(chNum) || !isValidChannel(chNum) || reserved)
+    {
+        lg2::debug("Get channel payload - Invalid field in request");
+        return responseInvalidFieldRequest();
+    }
+
+    // Session support is available in active LAN channels.
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Get channel payload - No support on channel");
+        return response(ccActionNotSupportedForChannel);
+    }
+    constexpr uint16_t stdPayloadType = standardPayloadBit(PayloadType::IPMI) |
+                                        standardPayloadBit(PayloadType::SOL);
+    constexpr uint16_t sessSetupPayloadType =
+        sessionPayloadBit(PayloadType::OPEN_SESSION_REQUEST) |
+        sessionPayloadBit(PayloadType::OPEN_SESSION_RESPONSE) |
+        sessionPayloadBit(PayloadType::RAKP1) |
+        sessionPayloadBit(PayloadType::RAKP2) |
+        sessionPayloadBit(PayloadType::RAKP3) |
+        sessionPayloadBit(PayloadType::RAKP4);
+    constexpr uint16_t OEMPayloadType = 0;
+    constexpr uint16_t rspRsvd = 0;
+    return responseSuccess(stdPayloadType, sessSetupPayloadType, OEMPayloadType,
+                           rspRsvd);
+}
+
+/** @brief implements the get channel payload version command
+ *  @param ctx - IPMI context pointer (for channel)
+ *  @param chNum - channel number to get info about
+ *  @param reserved - skip 4 bits
+ *  @param payloadTypeNum - to get payload type info
+
+ *  @returns IPMI completion code plus response data
+ *   - formatVersion - BCD encoded format version info
+ */
+
+RspType<uint8_t> // formatVersion
+    ipmiGetChannelPayloadVersion(Context::ptr ctx, uint4_t chNum,
+                                 uint4_t reserved, uint8_t payloadTypeNum)
+{
+    uint8_t channel =
+        convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);
+    constexpr uint8_t payloadTypeNotSupported = 0x80;
+
+    if (reserved || !isValidChannel(channel))
+    {
+        lg2::debug("Get channel payload version - Invalid field in request");
+        return responseInvalidFieldRequest();
+    }
+
+    if (getChannelSessionSupport(channel) == EChannelSessSupported::none)
+    {
+        lg2::debug("Get channel payload version - No support on channel");
+        return response(payloadTypeNotSupported);
+    }
+
+    if (!isValidPayloadType(static_cast<PayloadType>(payloadTypeNum)))
+    {
+        lg2::error("Get channel payload version - Payload type unavailable");
+
+        return response(payloadTypeNotSupported);
+    }
+
+    // BCD encoded version representation - 1.0
+    constexpr uint8_t formatVersion = 0x10;
+
+    return responseSuccess(formatVersion);
+}
+
+void registerChannelFunctions() __attribute__((constructor));
+void registerChannelFunctions()
+{
+    ipmiChannelInit();
+
+    registerHandler(prioOpenBmcBase, netFnApp, app::cmdSetChannelAccess,
+                    Privilege::Admin, ipmiSetChannelAccess);
+
+    registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelAccess,
+                    Privilege::User, ipmiGetChannelAccess);
+
+    registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelInfoCommand,
+                    Privilege::User, ipmiGetChannelInfo);
+
+    registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadSupport,
+                    Privilege::User, ipmiGetChannelPayloadSupport);
+
+    registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadVersion,
+                    Privilege::User, ipmiGetChannelPayloadVersion);
+}
+
+} // namespace ipmi
diff --git a/user_channel/cipher_mgmt.cpp b/user_channel/cipher_mgmt.cpp
new file mode 100644
index 0000000..c954f65
--- /dev/null
+++ b/user_channel/cipher_mgmt.cpp
@@ -0,0 +1,244 @@
+/*
+// Copyright (c) 2018 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 "cipher_mgmt.hpp"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <filesystem>
+#include <fstream>
+
+namespace ipmi
+{
+
+using Json = nlohmann::json;
+namespace fs = std::filesystem;
+
+CipherConfig& getCipherConfigObject(const std::string& csFileName,
+                                    const std::string& csDefaultFileName)
+{
+    static CipherConfig cipherConfig(csFileName, csDefaultFileName);
+    return cipherConfig;
+}
+
+CipherConfig::CipherConfig(const std::string& csFileName,
+                           const std::string& csDefaultFileName) :
+    cipherSuitePrivFileName(csFileName),
+    cipherSuiteDefaultPrivFileName(csDefaultFileName)
+{
+    loadCSPrivilegesToMap();
+}
+
+void CipherConfig::loadCSPrivilegesToMap()
+{
+    if (!fs::exists(cipherSuiteDefaultPrivFileName))
+    {
+        lg2::error("CS privilege levels default file does not exist...");
+    }
+    else
+    {
+        // read default privileges
+        Json data = readCSPrivilegeLevels(cipherSuiteDefaultPrivFileName);
+
+        // load default privileges
+        updateCSPrivilegesMap(data);
+
+        // check for user-saved privileges
+        if (fs::exists(cipherSuitePrivFileName))
+        {
+            data = readCSPrivilegeLevels(cipherSuitePrivFileName);
+            if (data != nullptr)
+            {
+                // update map with user-saved privileges by merging (overriding)
+                // values from the defaults
+                updateCSPrivilegesMap(data);
+            }
+        }
+    }
+}
+
+void CipherConfig::updateCSPrivilegesMap(const Json& jsonData)
+{
+    for (uint8_t chNum = 0; chNum < ipmi::maxIpmiChannels; chNum++)
+    {
+        std::string chKey = "Channel" + std::to_string(chNum);
+        for (uint8_t csNum = 0; csNum < maxCSRecords; csNum++)
+        {
+            auto csKey = "CipherID" + std::to_string(csNum);
+
+            if (jsonData.find(chKey) != jsonData.end())
+            {
+                csPrivilegeMap[{chNum, csNum}] = convertToPrivLimitIndex(
+                    static_cast<std::string>(jsonData[chKey][csKey]));
+            }
+        }
+    }
+}
+
+Json CipherConfig::readCSPrivilegeLevels(const std::string& csFileName)
+{
+    std::ifstream jsonFile(csFileName);
+    if (!jsonFile.good())
+    {
+        lg2::error("JSON file not found");
+        return nullptr;
+    }
+
+    Json data = nullptr;
+    try
+    {
+        data = Json::parse(jsonFile, nullptr, false);
+    }
+    catch (const Json::parse_error& e)
+    {
+        lg2::error(
+            "Corrupted cipher suite privilege levels config file: {ERROR}",
+            "ERROR", e);
+    }
+
+    return data;
+}
+
+int CipherConfig::writeCSPrivilegeLevels(const Json& jsonData)
+{
+    std::string tmpFile =
+        static_cast<std::string>(cipherSuitePrivFileName) + "_tmpXXXXXX";
+
+    std::vector<char> tmpRandomFile(tmpFile.length() + 1);
+    strncpy(tmpRandomFile.data(), tmpFile.c_str(), tmpFile.length() + 1);
+
+    int fd = mkstemp(tmpRandomFile.data());
+    fchmod(fd, 0644);
+
+    if (fd < 0)
+    {
+        lg2::error("Error opening CS privilege level config file: {FILE_NAME}",
+                   "FILE_NAME", tmpFile);
+        return -EIO;
+    }
+    const auto& writeData = jsonData.dump();
+    if (write(fd, writeData.c_str(), writeData.size()) !=
+        static_cast<ssize_t>(writeData.size()))
+    {
+        close(fd);
+        lg2::error("Error writing CS privilege level config file: {FILE_NAME}",
+                   "FILE_NAME", tmpFile);
+        unlink(tmpRandomFile.data());
+        return -EIO;
+    }
+    close(fd);
+
+    if (std::rename(tmpRandomFile.data(), cipherSuitePrivFileName.c_str()))
+    {
+        lg2::error("Error renaming CS privilege level config file: {FILE_NAME}",
+                   "FILE_NAME", tmpFile);
+        unlink(tmpRandomFile.data());
+        return -EIO;
+    }
+
+    return 0;
+}
+
+uint4_t CipherConfig::convertToPrivLimitIndex(const std::string& value)
+{
+    auto iter = std::find(ipmi::privList.begin(), ipmi::privList.end(), value);
+    if (iter == privList.end())
+    {
+        lg2::error("Invalid privilege: {PRIV_STR}", "PRIV_STR", value);
+        return ccUnspecifiedError;
+    }
+
+    return static_cast<uint4_t>(std::distance(ipmi::privList.begin(), iter));
+}
+
+std::string CipherConfig::convertToPrivLimitString(const uint4_t& value)
+{
+    return ipmi::privList.at(static_cast<size_t>(value));
+}
+
+ipmi::Cc CipherConfig::getCSPrivilegeLevels(
+    uint8_t chNum, std::array<uint4_t, maxCSRecords>& csPrivilegeLevels)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::error("Invalid channel number: {CHANNEL}", "CHANNEL", chNum);
+        return ccInvalidFieldRequest;
+    }
+
+    for (size_t csNum = 0; csNum < maxCSRecords; ++csNum)
+    {
+        csPrivilegeLevels[csNum] = csPrivilegeMap[{chNum, csNum}];
+    }
+    return ccSuccess;
+}
+
+ipmi::Cc CipherConfig::setCSPrivilegeLevels(
+    uint8_t chNum, const std::array<uint4_t, maxCSRecords>& requestData)
+{
+    if (!isValidChannel(chNum))
+    {
+        lg2::error("Invalid channel number: {CHANNEL}", "CHANNEL", chNum);
+        return ccInvalidFieldRequest;
+    }
+
+    Json jsonData;
+    if (!fs::exists(cipherSuitePrivFileName))
+    {
+        lg2::info("CS privilege levels user settings file does not "
+                  "exist. Creating...");
+    }
+    else
+    {
+        jsonData = readCSPrivilegeLevels(cipherSuitePrivFileName);
+        if (jsonData == nullptr)
+        {
+            return ccUnspecifiedError;
+        }
+    }
+
+    Json privData;
+    std::string csKey;
+    constexpr auto privMaxValue = static_cast<uint8_t>(ipmi::Privilege::Oem);
+    for (size_t csNum = 0; csNum < maxCSRecords; ++csNum)
+    {
+        csKey = "CipherID" + std::to_string(csNum);
+        auto priv = static_cast<uint8_t>(requestData[csNum]);
+
+        if (priv > privMaxValue)
+        {
+            return ccInvalidFieldRequest;
+        }
+        privData[csKey] = convertToPrivLimitString(priv);
+    }
+
+    std::string chKey = "Channel" + std::to_string(chNum);
+    jsonData[chKey] = privData;
+
+    if (writeCSPrivilegeLevels(jsonData))
+    {
+        lg2::error("Error in setting CS Privilege Levels.");
+        return ccUnspecifiedError;
+    }
+
+    updateCSPrivilegesMap(jsonData);
+    return ccSuccess;
+}
+
+} // namespace ipmi
diff --git a/user_channel/cipher_mgmt.hpp b/user_channel/cipher_mgmt.hpp
new file mode 100644
index 0000000..0bd6b1d
--- /dev/null
+++ b/user_channel/cipher_mgmt.hpp
@@ -0,0 +1,132 @@
+/*
+// Copyright (c) 2018 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.
+*/
+#pragma once
+#include "channel_layer.hpp"
+
+#include <ipmid/api-types.hpp>
+#include <ipmid/message/types.hpp>
+#include <nlohmann/json.hpp>
+
+#include <map>
+
+namespace ipmi
+{
+static const std::string csPrivDefaultFileName =
+    "/usr/share/ipmi-providers/cs_privilege_levels.json";
+
+static const std::string csPrivFileName =
+    "/var/lib/ipmi/cs_privilege_levels.json";
+
+static const size_t maxCSRecords = 16;
+
+using ChannelNumCipherIDPair = std::pair<uint8_t, uint8_t>;
+using privMap = std::map<ChannelNumCipherIDPair, uint4_t>;
+
+/** @class CipherConfig
+ *  @brief Class to provide cipher suite functionalities
+ */
+class CipherConfig
+{
+  public:
+    ~CipherConfig() = default;
+    explicit CipherConfig(const std::string& csFileName,
+                          const std::string& csDefaultFileName);
+    CipherConfig() = delete;
+
+    /** @brief function to get cipher suite privileges from config file
+     *
+     *  @param[in] chNum - channel number for which we want to get cipher suite
+     * privilege levels
+     *
+     *  @param[in] csPrivilegeLevels - gets filled by cipher suite privilege
+     * levels
+     *
+     *  @return 0 for success, non zero value for failure
+     */
+    ipmi::Cc getCSPrivilegeLevels(
+        uint8_t chNum, std::array<uint4_t, maxCSRecords>& csPrivilegeLevels);
+
+    /** @brief function to set/update cipher suite privileges in config file
+     *
+     *  @param[in] chNum - channel number for which we want to update cipher
+     * suite privilege levels
+     *
+     *  @param[in] csPrivilegeLevels - cipher suite privilege levels to update
+     * in config file
+     *
+     *  @return 0 for success, non zero value for failure
+     */
+    ipmi::Cc setCSPrivilegeLevels(
+        uint8_t chNum,
+        const std::array<uint4_t, maxCSRecords>& csPrivilegeLevels);
+
+  private:
+    std::string cipherSuitePrivFileName, cipherSuiteDefaultPrivFileName;
+
+    privMap csPrivilegeMap;
+
+    /** @brief function to read json config file
+     *
+     *  @return nlohmann::json object
+     */
+    nlohmann::json readCSPrivilegeLevels(const std::string& csFileName);
+
+    /** @brief function to write json config file
+     *
+     *  @param[in] jsonData - json object
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int writeCSPrivilegeLevels(const nlohmann::json& jsonData);
+
+    /** @brief convert to cipher suite privilege from string to value
+     *
+     *  @param[in] value - privilege value
+     *
+     *  @return cipher suite privilege index
+     */
+    uint4_t convertToPrivLimitIndex(const std::string& value);
+
+    /** @brief function to convert privilege value to string
+     *
+     *  @param[in] value - privilege value
+     *
+     *  @return privilege in string
+     */
+    std::string convertToPrivLimitString(const uint4_t& value);
+
+    /** @brief function to load CS Privilege Levels from json file/files to map
+     *
+     */
+    void loadCSPrivilegesToMap();
+
+    /** @brief function to update CS privileges map from json object data,
+     * jsonData
+     *
+     */
+    void updateCSPrivilegesMap(const nlohmann::json& jsonData);
+};
+
+/** @brief function to create static CipherConfig object
+ *
+ *  @param[in] csFileName - user setting cipher suite privilege file name
+ *  @param[in] csDefaultFileName - default cipher suite privilege file name
+ *
+ *  @return static CipherConfig object
+ */
+CipherConfig& getCipherConfigObject(const std::string& csFileName,
+                                    const std::string& csDefaultFileName);
+} // namespace ipmi
diff --git a/user_channel/file.hpp b/user_channel/file.hpp
new file mode 100644
index 0000000..5be3a18
--- /dev/null
+++ b/user_channel/file.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <stdio.h>
+
+#include <filesystem>
+namespace phosphor
+{
+namespace user
+{
+
+namespace fs = std::filesystem;
+
+/** @class File
+ *  @brief Responsible for handling file pointer
+ *  Needed by putspent(3)
+ */
+class File
+{
+  private:
+    /** @brief handler for operating on file */
+    FILE* fp = nullptr;
+
+    /** @brief File name. Needed in the case where the temp
+     *         needs to be removed
+     */
+    const std::string& name;
+
+    /** @brief Should the file be removed at exit */
+    bool removeOnExit = false;
+
+  public:
+    File() = delete;
+    File(const File&) = delete;
+    File& operator=(const File&) = delete;
+    File(File&&) = delete;
+    File& operator=(File&&) = delete;
+
+    /** @brief Opens file and uses it to do file operation
+     *
+     *  @param[in] name         - File name
+     *  @param[in] mode         - File open mode
+     *  @param[in] removeOnExit - File to be removed at exit or no
+     */
+    File(const std::string& name, const std::string& mode,
+         bool removeOnExit = false) : name(name), removeOnExit(removeOnExit)
+    {
+        fp = fopen(name.c_str(), mode.c_str());
+    }
+
+    /** @brief Opens file using provided file descriptor
+     *
+     *  @param[in] fd           - File descriptor
+     *  @param[in] name         - File name
+     *  @param[in] mode         - File open mode
+     *  @param[in] removeOnExit - File to be removed at exit or no
+     */
+    File(int fd, const std::string& name, const std::string& mode,
+         bool removeOnExit = false) : name(name), removeOnExit(removeOnExit)
+    {
+        fp = fdopen(fd, mode.c_str());
+    }
+
+    ~File()
+    {
+        if (fp)
+        {
+            fclose(fp);
+        }
+
+        // Needed for exception safety
+        if (removeOnExit && fs::exists(name))
+        {
+            fs::remove(name);
+        }
+    }
+
+    auto operator()()
+    {
+        return fp;
+    }
+};
+
+} // namespace user
+} // namespace phosphor
diff --git a/user_channel/meson.build b/user_channel/meson.build
new file mode 100644
index 0000000..701c86a
--- /dev/null
+++ b/user_channel/meson.build
@@ -0,0 +1,101 @@
+user_channel_inc = include_directories('.')
+
+channellayer_pre = declare_dependency(
+    include_directories: [root_inc, user_channel_inc],
+    dependencies: [
+        crypto,
+        ipmid_dep,
+        libsystemd_dep,
+        nlohmann_json_dep,
+        phosphor_dbus_interfaces_dep,
+        phosphor_logging_dep,
+    ],
+)
+
+channellayer_src = ['channel_layer.cpp', 'channel_mgmt.cpp', 'cipher_mgmt.cpp']
+
+channellayer_lib = library(
+    'channellayer',
+    channellayer_src,
+    implicit_include_directories: false,
+    dependencies: channellayer_pre,
+    version: meson.project_version(),
+    install: true,
+    install_dir: get_option('libdir'),
+    override_options: ['b_lundef=false'],
+)
+
+channellayer_dep = declare_dependency(
+    link_with: channellayer_lib,
+    dependencies: channellayer_pre,
+)
+
+import('pkgconfig').generate(
+    channellayer_lib,
+    name: 'libchannellayer',
+    version: meson.project_version(),
+    description: 'libchannellayer',
+)
+
+if get_option('libuserlayer').allowed()
+    userlayer_pre = declare_dependency(
+        include_directories: [root_inc, user_channel_inc],
+        dependencies: [
+            channellayer_dep,
+            crypto,
+            ipmid_dep,
+            libsystemd_dep,
+            nlohmann_json_dep,
+            pam,
+            phosphor_dbus_interfaces_dep,
+            phosphor_logging_dep,
+        ],
+    )
+
+    userlayer_src = ['user_layer.cpp', 'user_mgmt.cpp', 'passwd_mgr.cpp']
+
+    userlayer_lib = library(
+        'userlayer',
+        userlayer_src,
+        implicit_include_directories: false,
+        dependencies: userlayer_pre,
+        version: meson.project_version(),
+        install: true,
+        install_dir: get_option('libdir'),
+        override_options: ['b_lundef=false'],
+    )
+
+    userlayer_dep = declare_dependency(
+        link_with: userlayer_lib,
+        dependencies: userlayer_pre,
+    )
+
+    usercmds_pre = declare_dependency(
+        include_directories: [root_inc, user_channel_inc],
+        dependencies: [
+            phosphor_logging_dep,
+            ipmid_dep,
+            userlayer_dep,
+            channellayer_dep,
+        ],
+    )
+
+    usercmds_lib = library(
+        'usercmds',
+        'usercommands.cpp',
+        implicit_include_directories: false,
+        dependencies: usercmds_pre,
+        install: true,
+        install_dir: get_option('libdir') / 'ipmid-providers',
+        version: meson.project_version(),
+        override_options: ['b_lundef=false'],
+    )
+
+    import('pkgconfig').generate(
+        userlayer_lib,
+        name: 'libuserlayer',
+        version: meson.project_version(),
+        description: 'libuserlayer',
+    )
+
+endif
diff --git a/user_channel/passwd_mgr.cpp b/user_channel/passwd_mgr.cpp
new file mode 100644
index 0000000..929a83c
--- /dev/null
+++ b/user_channel/passwd_mgr.cpp
@@ -0,0 +1,603 @@
+/*
+// Copyright (c) 2018 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 "passwd_mgr.hpp"
+
+#include "file.hpp"
+#include "shadowlock.hpp"
+
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+#include <iomanip>
+
+namespace ipmi
+{
+
+static const char* passwdFileName = "/etc/ipmi_pass";
+static const char* encryptKeyFileName = "/etc/key_file";
+static const size_t maxKeySize = 8;
+
+constexpr mode_t modeMask =
+    (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO);
+
+#define META_PASSWD_SIG "=OPENBMC="
+
+/*
+ * Meta data struct for encrypted password file
+ */
+struct MetaPassStruct
+{
+    char signature[10];
+    unsigned char reseved[2];
+    size_t hashSize;
+    size_t ivSize;
+    size_t dataSize;
+    size_t padSize;
+    size_t macSize;
+};
+
+PasswdMgr::PasswdMgr()
+{
+    restrictFilesPermission();
+    initPasswordMap();
+}
+
+void PasswdMgr::restrictFilesPermission(void)
+{
+    struct stat st = {};
+    // Restrict file permission to owner read & write
+    if (stat(passwdFileName, &st) == 0)
+    {
+        if ((st.st_mode & modeMask) != (S_IRUSR | S_IWUSR))
+        {
+            if (chmod(passwdFileName, S_IRUSR | S_IWUSR) == -1)
+            {
+                lg2::debug("Error setting chmod for ipmi_pass file");
+            }
+        }
+    }
+
+    if (stat(encryptKeyFileName, &st) == 0)
+    {
+        if ((st.st_mode & modeMask) != (S_IRUSR | S_IWUSR))
+        {
+            if (chmod(encryptKeyFileName, S_IRUSR | S_IWUSR) == -1)
+            {
+                lg2::debug("Error setting chmod for ipmi_pass file");
+            }
+        }
+    }
+}
+
+SecureString PasswdMgr::getPasswdByUserName(const std::string& userName)
+{
+    checkAndReload();
+    auto iter = passwdMapList.find(userName);
+    if (iter == passwdMapList.end())
+    {
+        return SecureString();
+    }
+    return iter->second;
+}
+
+int PasswdMgr::updateUserEntry(const std::string& userName,
+                               const std::string& newUserName)
+{
+    std::time_t updatedTime = getUpdatedFileTime();
+    // Check file time stamp to know passwdMapList is up-to-date.
+    // If not up-to-date, then updatePasswdSpecialFile will read and
+    // check the user entry existance.
+    if (fileLastUpdatedTime == updatedTime && updatedTime != -EIO)
+    {
+        if (passwdMapList.find(userName) == passwdMapList.end())
+        {
+            lg2::debug("User not found");
+            return 0;
+        }
+    }
+
+    // Write passwdMap to Encryted file
+    if (updatePasswdSpecialFile(userName, newUserName) != 0)
+    {
+        lg2::debug("Passwd file update failed");
+        return -EIO;
+    }
+
+    lg2::debug("Passwd file updated successfully");
+    return 0;
+}
+
+void PasswdMgr::checkAndReload(void)
+{
+    std::time_t updatedTime = getUpdatedFileTime();
+    if (fileLastUpdatedTime != updatedTime && updatedTime != -1)
+    {
+        lg2::debug("Reloading password map list");
+        passwdMapList.clear();
+        initPasswordMap();
+    }
+}
+
+int PasswdMgr::encryptDecryptData(
+    bool doEncrypt, const EVP_CIPHER* cipher, uint8_t* key, size_t keyLen,
+    uint8_t* iv, size_t ivLen, uint8_t* inBytes, size_t inBytesLen,
+    uint8_t* mac, size_t* macLen, unsigned char* outBytes, size_t* outBytesLen)
+{
+    if (cipher == nullptr || key == nullptr || iv == nullptr ||
+        inBytes == nullptr || outBytes == nullptr || mac == nullptr ||
+        inBytesLen == 0 || (size_t)EVP_CIPHER_key_length(cipher) > keyLen ||
+        (size_t)EVP_CIPHER_iv_length(cipher) > ivLen)
+    {
+        lg2::debug("Error Invalid Inputs");
+        return -EINVAL;
+    }
+
+    if (!doEncrypt)
+    {
+        // verify MAC before decrypting the data.
+        std::array<uint8_t, EVP_MAX_MD_SIZE> calMac;
+        size_t calMacLen = calMac.size();
+        // calculate MAC for the encrypted message.
+        if (nullptr ==
+            HMAC(EVP_sha256(), key, keyLen, inBytes, inBytesLen, calMac.data(),
+                 reinterpret_cast<unsigned int*>(&calMacLen)))
+        {
+            lg2::debug("Error: Failed to calculate MAC");
+            return -EIO;
+        }
+        if (!((calMacLen == *macLen) &&
+              (std::memcmp(calMac.data(), mac, calMacLen) == 0)))
+        {
+            lg2::debug("Authenticated message doesn't match");
+            return -EBADMSG;
+        }
+    }
+
+    std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)> ctx(
+        EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
+
+    if (!ctx)
+    {
+        lg2::debug("Error: EVP_CIPHER_CTX is NULL");
+        return -ENOMEM;
+    }
+
+    EVP_CIPHER_CTX_set_padding(ctx.get(), 1);
+
+    // Set key & IV
+    int retval = EVP_CipherInit_ex(ctx.get(), cipher, nullptr, key, iv,
+                                   static_cast<int>(doEncrypt));
+    if (!retval)
+    {
+        lg2::debug("EVP_CipherInit_ex failed: {RET_VAL}", "RET_VAL", retval);
+        return -EIO;
+    }
+
+    int outLen = 0, outEVPLen = 0;
+    if ((retval = EVP_CipherUpdate(ctx.get(), outBytes + outLen, &outEVPLen,
+                                   inBytes, inBytesLen)))
+    {
+        outLen += outEVPLen;
+        if ((retval =
+                 EVP_CipherFinal(ctx.get(), outBytes + outLen, &outEVPLen)))
+        {
+            outLen += outEVPLen;
+            *outBytesLen = outLen;
+        }
+        else
+        {
+            lg2::debug("EVP_CipherFinal fails: {RET_VAL}", "RET_VAL", retval);
+            return -EIO;
+        }
+    }
+    else
+    {
+        lg2::debug("EVP_CipherUpdate fails: {RET_VAL}", "RET_VAL", retval);
+        return -EIO;
+    }
+
+    if (doEncrypt)
+    {
+        // Create MAC for the encrypted message
+        if (nullptr == HMAC(EVP_sha256(), key, keyLen, outBytes, *outBytesLen,
+                            mac, reinterpret_cast<unsigned int*>(macLen)))
+        {
+            lg2::debug("Failed to create authentication");
+            return -EIO;
+        }
+    }
+    return 0;
+}
+
+void PasswdMgr::initPasswordMap(void)
+{
+    // TODO  phosphor-host-ipmid#170 phosphor::user::shadow::Lock lock{};
+    SecureString dataBuf;
+
+    if (readPasswdFileData(dataBuf) != 0)
+    {
+        lg2::debug("Error in reading the encrypted pass file");
+        return;
+    }
+
+    if (dataBuf.size() != 0)
+    {
+        // populate the user list with password
+        char* outPtr = dataBuf.data();
+        char* nToken = nullptr;
+        char* linePtr = strtok_r(outPtr, "\n", &nToken);
+        size_t lineSize = 0;
+        while (linePtr != nullptr)
+        {
+            size_t userEPos = 0;
+            SecureString lineStr(linePtr);
+            if ((userEPos = lineStr.find(":")) != std::string::npos)
+            {
+                lineSize = lineStr.size();
+                passwdMapList.emplace(
+                    lineStr.substr(0, userEPos),
+                    lineStr.substr(userEPos + 1, lineSize - (userEPos + 1)));
+            }
+            linePtr = strtok_r(nullptr, "\n", &nToken);
+        }
+    }
+
+    // Update the timestamp
+    fileLastUpdatedTime = getUpdatedFileTime();
+    return;
+}
+
+int PasswdMgr::readPasswdFileData(SecureString& outBytes)
+{
+    std::array<uint8_t, maxKeySize> keyBuff;
+    std::ifstream keyFile(encryptKeyFileName, std::ios::in | std::ios::binary);
+    if (!keyFile.is_open())
+    {
+        lg2::debug("Error in opening encryption key file");
+        return -EIO;
+    }
+    keyFile.read(reinterpret_cast<char*>(keyBuff.data()), keyBuff.size());
+    if (keyFile.fail())
+    {
+        lg2::debug("Error in reading encryption key file");
+        return -EIO;
+    }
+
+    std::ifstream passwdFile(passwdFileName, std::ios::in | std::ios::binary);
+    if (!passwdFile.is_open())
+    {
+        lg2::debug("Error in opening ipmi password file");
+        return -EIO;
+    }
+
+    // calculate file size and read the data
+    passwdFile.seekg(0, std::ios::end);
+    ssize_t fileSize = passwdFile.tellg();
+    passwdFile.seekg(0, std::ios::beg);
+    std::vector<uint8_t> input(fileSize);
+    passwdFile.read(reinterpret_cast<char*>(input.data()), fileSize);
+    if (passwdFile.fail())
+    {
+        lg2::debug("Error in reading encryption key file");
+        return -EIO;
+    }
+
+    // verify the signature first
+    MetaPassStruct* metaData = reinterpret_cast<MetaPassStruct*>(input.data());
+    if (std::strncmp(metaData->signature, META_PASSWD_SIG,
+                     sizeof(metaData->signature)))
+    {
+        lg2::debug("Error signature mismatch in password file");
+        return -EBADMSG;
+    }
+
+    size_t inBytesLen = metaData->dataSize + metaData->padSize;
+    // If data is empty i.e no password map then return success
+    if (inBytesLen == 0)
+    {
+        lg2::debug("Empty password file");
+        return 0;
+    }
+
+    // compute the key needed to decrypt
+    std::array<uint8_t, EVP_MAX_KEY_LENGTH> key;
+    auto keyLen = key.size();
+    if (nullptr == HMAC(EVP_sha256(), keyBuff.data(), keyBuff.size(),
+                        input.data() + sizeof(*metaData), metaData->hashSize,
+                        key.data(), reinterpret_cast<unsigned int*>(&keyLen)))
+    {
+        lg2::debug("Failed to create MAC for authentication");
+        return -EIO;
+    }
+
+    // decrypt the data
+    uint8_t* iv = input.data() + sizeof(*metaData) + metaData->hashSize;
+    size_t ivLen = metaData->ivSize;
+    uint8_t* inBytes = iv + ivLen;
+    uint8_t* mac = inBytes + inBytesLen;
+    size_t macLen = metaData->macSize;
+
+    size_t outBytesLen = 0;
+    // Resize to actual data size
+    outBytes.resize(inBytesLen + EVP_MAX_BLOCK_LENGTH, '\0');
+    if (encryptDecryptData(false, EVP_aes_128_cbc(), key.data(), keyLen, iv,
+                           ivLen, inBytes, inBytesLen, mac, &macLen,
+                           reinterpret_cast<unsigned char*>(outBytes.data()),
+                           &outBytesLen) != 0)
+    {
+        lg2::debug("Error in decryption");
+        return -EIO;
+    }
+    // Resize the vector to outBytesLen
+    outBytes.resize(outBytesLen);
+
+    OPENSSL_cleanse(key.data(), keyLen);
+    OPENSSL_cleanse(iv, ivLen);
+
+    return 0;
+}
+
+int PasswdMgr::updatePasswdSpecialFile(const std::string& userName,
+                                       const std::string& newUserName)
+{
+    // TODO  phosphor-host-ipmid#170 phosphor::user::shadow::Lock lock{};
+
+    size_t bytesWritten = 0;
+    size_t inBytesLen = 0;
+    size_t isUsrFound = false;
+    const EVP_CIPHER* cipher = EVP_aes_128_cbc();
+    SecureString dataBuf;
+
+    // Read the encrypted file and get the file data
+    // Check user existance and return if not exist.
+    if (readPasswdFileData(dataBuf) != 0)
+    {
+        lg2::debug("Error in reading the encrypted pass file");
+        return -EIO;
+    }
+
+    if (dataBuf.size() != 0)
+    {
+        inBytesLen = dataBuf.size() + newUserName.size() +
+                     EVP_CIPHER_block_size(cipher);
+    }
+
+    SecureString inBytes(inBytesLen, '\0');
+    if (inBytesLen != 0)
+    {
+        char* outPtr = reinterpret_cast<char*>(dataBuf.data());
+        char* nToken = nullptr;
+        char* linePtr = strtok_r(outPtr, "\n", &nToken);
+        while (linePtr != nullptr)
+        {
+            size_t userEPos = 0;
+
+            SecureString lineStr(linePtr);
+            if ((userEPos = lineStr.find(":")) != std::string::npos)
+            {
+                if (userName.compare(lineStr.substr(0, userEPos)) == 0)
+                {
+                    isUsrFound = true;
+                    if (!newUserName.empty())
+                    {
+                        bytesWritten += std::snprintf(
+                            &inBytes[0] + bytesWritten,
+                            (inBytesLen - bytesWritten), "%s%s\n",
+                            newUserName.c_str(),
+                            lineStr.substr(userEPos, lineStr.size()).data());
+                    }
+                }
+                else
+                {
+                    bytesWritten += std::snprintf(&inBytes[0] + bytesWritten,
+                                                  (inBytesLen - bytesWritten),
+                                                  "%s\n", lineStr.data());
+                }
+            }
+            linePtr = strtok_r(nullptr, "\n", &nToken);
+        }
+        inBytesLen = bytesWritten;
+    }
+    if (!isUsrFound)
+    {
+        lg2::debug("User doesn't exist");
+        return 0;
+    }
+
+    // Read the key buff from key file
+    std::array<uint8_t, maxKeySize> keyBuff;
+    std::ifstream keyFile(encryptKeyFileName, std::ios::in | std::ios::binary);
+    if (!keyFile.good())
+    {
+        lg2::debug("Error in opening encryption key file");
+        return -EIO;
+    }
+    keyFile.read(reinterpret_cast<char*>(keyBuff.data()), keyBuff.size());
+    if (keyFile.fail())
+    {
+        lg2::debug("Error in reading encryption key file");
+        return -EIO;
+    }
+    keyFile.close();
+
+    // Read the original passwd file mode
+    struct stat st = {};
+    if (stat(passwdFileName, &st) != 0)
+    {
+        lg2::debug("Error in getting password file fstat()");
+        return -EIO;
+    }
+
+    // Create temporary file for write
+    std::string pwdFile(passwdFileName);
+    std::vector<char> tempFileName(pwdFile.begin(), pwdFile.end());
+    std::vector<char> fileTemplate = {'_', '_', 'X', 'X', 'X',
+                                      'X', 'X', 'X', '\0'};
+    tempFileName.insert(tempFileName.end(), fileTemplate.begin(),
+                        fileTemplate.end());
+    int fd = mkstemp((char*)tempFileName.data());
+    if (fd == -1)
+    {
+        lg2::debug("Error creating temp file");
+        return -EIO;
+    }
+
+    std::string strTempFileName(tempFileName.data());
+    // Open the temp file for writing from provided fd
+    // By "true", remove it at exit if still there.
+    // This is needed to cleanup the temp file at exception
+    phosphor::user::File temp(fd, strTempFileName, "w", true);
+    if ((temp)() == nullptr)
+    {
+        close(fd);
+        lg2::debug("Error creating temp file");
+        return -EIO;
+    }
+
+    // Set the file mode as read-write for owner only
+    if (fchmod(fileno((temp)()), S_IRUSR | S_IWUSR) < 0)
+    {
+        lg2::debug("Error setting fchmod for temp file");
+        return -EIO;
+    }
+
+    const EVP_MD* digest = EVP_sha256();
+    size_t hashLen = EVP_MD_block_size(digest);
+    std::vector<uint8_t> hash(hashLen);
+    size_t ivLen = EVP_CIPHER_iv_length(cipher);
+    std::vector<uint8_t> iv(ivLen);
+    std::array<uint8_t, EVP_MAX_KEY_LENGTH> key;
+    size_t keyLen = key.size();
+    std::array<uint8_t, EVP_MAX_MD_SIZE> mac;
+    size_t macLen = mac.size();
+
+    // Create random hash and generate hash key which will be used for
+    // encryption.
+    if (RAND_bytes(hash.data(), hashLen) != 1)
+    {
+        lg2::debug("Hash genertion failed, bailing out");
+        return -EIO;
+    }
+    if (nullptr ==
+        HMAC(digest, keyBuff.data(), keyBuff.size(), hash.data(), hashLen,
+             key.data(), reinterpret_cast<unsigned int*>(&keyLen)))
+    {
+        lg2::debug("Failed to create MAC for authentication");
+        return -EIO;
+    }
+
+    // Generate IV values
+    if (RAND_bytes(iv.data(), ivLen) != 1)
+    {
+        lg2::debug("UV genertion failed, bailing out");
+        return -EIO;
+    }
+
+    // Encrypt the input data
+    std::vector<uint8_t> outBytes(inBytesLen + EVP_MAX_BLOCK_LENGTH);
+    size_t outBytesLen = 0;
+    if (inBytesLen != 0)
+    {
+        if (encryptDecryptData(
+                true, EVP_aes_128_cbc(), key.data(), keyLen, iv.data(), ivLen,
+                reinterpret_cast<unsigned char*>(inBytes.data()), inBytesLen,
+                mac.data(), &macLen, outBytes.data(), &outBytesLen) != 0)
+        {
+            lg2::debug("Error while encrypting the data");
+            return -EIO;
+        }
+        outBytes[outBytesLen] = 0;
+    }
+    OPENSSL_cleanse(key.data(), keyLen);
+
+    // Update the meta password structure.
+    MetaPassStruct metaData = {META_PASSWD_SIG, {0, 0}, 0, 0, 0, 0, 0};
+    metaData.hashSize = hashLen;
+    metaData.ivSize = ivLen;
+    metaData.dataSize = bytesWritten;
+    metaData.padSize = outBytesLen - bytesWritten;
+    metaData.macSize = macLen;
+
+    if (fwrite(&metaData, 1, sizeof(metaData), (temp)()) != sizeof(metaData))
+    {
+        lg2::debug("Error in writing meta data");
+        return -EIO;
+    }
+
+    if (fwrite(&hash[0], 1, hashLen, (temp)()) != hashLen)
+    {
+        lg2::debug("Error in writing hash data");
+        return -EIO;
+    }
+
+    if (fwrite(&iv[0], 1, ivLen, (temp)()) != ivLen)
+    {
+        lg2::debug("Error in writing IV data");
+        return -EIO;
+    }
+
+    if (fwrite(&outBytes[0], 1, outBytesLen, (temp)()) != outBytesLen)
+    {
+        lg2::debug("Error in writing encrypted data");
+        return -EIO;
+    }
+
+    if (fwrite(&mac[0], 1, macLen, (temp)()) != macLen)
+    {
+        lg2::debug("Error in writing MAC data");
+        return -EIO;
+    }
+
+    if (fflush((temp)()))
+    {
+        lg2::debug("File fflush error while writing entries to special file");
+        return -EIO;
+    }
+
+    OPENSSL_cleanse(iv.data(), ivLen);
+
+    // Rename the tmp  file to actual file
+    if (std::rename(strTempFileName.data(), passwdFileName) != 0)
+    {
+        lg2::debug("Failed to rename tmp file to ipmi-pass");
+        return -EIO;
+    }
+
+    return 0;
+}
+
+std::time_t PasswdMgr::getUpdatedFileTime()
+{
+    struct stat fileStat = {};
+    if (stat(passwdFileName, &fileStat) != 0)
+    {
+        lg2::debug("Error - Getting passwd file time stamp");
+        return -EIO;
+    }
+    return fileStat.st_mtime;
+}
+
+} // namespace ipmi
diff --git a/user_channel/passwd_mgr.hpp b/user_channel/passwd_mgr.hpp
new file mode 100644
index 0000000..8932ac5
--- /dev/null
+++ b/user_channel/passwd_mgr.hpp
@@ -0,0 +1,133 @@
+/*
+// Copyright (c) 2018 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.
+*/
+#pragma once
+#include <openssl/evp.h>
+
+#include <ipmid/types.hpp>
+
+#include <ctime>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace ipmi
+{
+
+class PasswdMgr
+{
+  public:
+    ~PasswdMgr() = default;
+    PasswdMgr(const PasswdMgr&) = delete;
+    PasswdMgr& operator=(const PasswdMgr&) = delete;
+    PasswdMgr(PasswdMgr&&) = delete;
+    PasswdMgr& operator=(PasswdMgr&&) = delete;
+
+    /** @brief Constructs user password list
+     *
+     */
+    PasswdMgr();
+
+    /** @brief Get password for the user
+     *
+     *  @param[in] userName - user name
+     *
+     * @return password string. will return empty string, if unable to locate
+     * the user
+     */
+    SecureString getPasswdByUserName(const std::string& userName);
+
+    /** @brief Update / clear  username and password entry for the specified
+     * user
+     *
+     *  @param[in] userName - user name that has to be renamed / deleted
+     *  @param[in] newUserName - new user name. If empty, userName will be
+     *   deleted.
+     *
+     * @return error response
+     */
+    int updateUserEntry(const std::string& userName,
+                        const std::string& newUserName);
+
+  private:
+    using UserName = std::string;
+    using Password = SecureString;
+    std::unordered_map<UserName, Password> passwdMapList;
+    std::time_t fileLastUpdatedTime;
+
+    /** @brief restrict file permission
+     *
+     */
+    void restrictFilesPermission(void);
+    /** @brief check timestamp and reload password map if required
+     *
+     */
+    void checkAndReload(void);
+    /** @brief initializes passwdMapList by reading the encrypted file
+     *
+     * Initializes the passwordMapList members after decrypting the
+     * password file. passwordMapList will be used further in IPMI
+     * authentication.
+     */
+    void initPasswordMap(void);
+
+    /** @brief Function to read the encrypted password file data
+     *
+     *  @param[out] outBytes - vector to hold decrypted password file data
+     *
+     * @return error response
+     */
+    int readPasswdFileData(SecureString& outBytes);
+    /** @brief  Updates special password file by clearing the password entry
+     *  for the user specified.
+     *
+     *  @param[in] userName - user name that has to be renamed / deleted
+     *  @param[in] newUserName - new user name. If empty, userName will be
+     *   deleted.
+     *
+     * @return error response
+     */
+    int updatePasswdSpecialFile(const std::string& userName,
+                                const std::string& newUserName);
+    /** @brief encrypts or decrypt the data provided
+     *
+     *  @param[in] doEncrypt - do encrypt if set to true, else do decrypt.
+     *  @param[in] cipher - cipher to be used
+     *  @param[in] key - pointer to the key
+     *  @param[in] keyLen - Length of the key to be used
+     *  @param[in] iv - pointer to initialization vector
+     *  @param[in] ivLen - Length of the iv
+     *  @param[in] inBytes - input data to be encrypted / decrypted
+     *  @param[in] inBytesLen - input size to be encrypted / decrypted
+     *  @param[in] mac - message authentication code - to figure out corruption
+     *  @param[in] macLen - size of MAC
+     *  @param[in] outBytes - ptr to store output bytes
+     *  @param[in] outBytesLen - outbut data length.
+     *
+     * @return error response
+     */
+    int encryptDecryptData(
+        bool doEncrypt, const EVP_CIPHER* cipher, uint8_t* key, size_t keyLen,
+        uint8_t* iv, size_t ivLen, uint8_t* inBytes, size_t inBytesLen,
+        uint8_t* mac, size_t* macLen, uint8_t* outBytes, size_t* outBytesLen);
+
+    /** @brief  returns updated file time of passwd file entry.
+     *
+     * @return timestamp or -1 for error.
+     */
+    std::time_t getUpdatedFileTime();
+};
+
+} // namespace ipmi
diff --git a/user_channel/shadowlock.hpp b/user_channel/shadowlock.hpp
new file mode 100644
index 0000000..1dc5f3b
--- /dev/null
+++ b/user_channel/shadowlock.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <shadow.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+namespace phosphor
+{
+namespace user
+{
+namespace shadow
+{
+
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+using namespace phosphor::logging;
+
+/** @class Lock
+ *  @brief Responsible for locking and unlocking /etc/shadow
+ */
+class Lock
+{
+  public:
+    Lock(const Lock&) = delete;
+    Lock& operator=(const Lock&) = delete;
+    Lock(Lock&&) = delete;
+    Lock& operator=(Lock&&) = delete;
+
+    /** @brief Default constructor that just locks the shadow file */
+    Lock()
+    {
+        if (!lckpwdf())
+        {
+            lg2::error("Locking Shadow failed");
+            elog<InternalFailure>();
+        }
+    }
+    ~Lock()
+    {
+        if (!ulckpwdf())
+        {
+            lg2::error("Un-Locking Shadow failed");
+            elog<InternalFailure>();
+        }
+    }
+};
+
+} // namespace shadow
+} // namespace user
+} // namespace phosphor
diff --git a/user_channel/user_layer.cpp b/user_channel/user_layer.cpp
new file mode 100644
index 0000000..5a2e7e0
--- /dev/null
+++ b/user_channel/user_layer.cpp
@@ -0,0 +1,226 @@
+/*
+// Copyright (c) 2018 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 "user_layer.hpp"
+
+#include "passwd_mgr.hpp"
+#include "user_mgmt.hpp"
+
+namespace
+{
+ipmi::PasswdMgr passwdMgr;
+}
+
+namespace ipmi
+{
+
+Cc ipmiUserInit()
+{
+    getUserAccessObject();
+    return ccSuccess;
+}
+
+SecureString ipmiUserGetPassword(const std::string& userName)
+{
+    return passwdMgr.getPasswdByUserName(userName);
+}
+
+Cc ipmiClearUserEntryPassword(const std::string& userName)
+{
+    if (passwdMgr.updateUserEntry(userName, "") != 0)
+    {
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+Cc ipmiRenameUserEntryPassword(const std::string& userName,
+                               const std::string& newUserName)
+{
+    if (passwdMgr.updateUserEntry(userName, newUserName) != 0)
+    {
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+bool ipmiUserIsValidUserId(const uint8_t userId)
+{
+    return UserAccess::isValidUserId(userId);
+}
+
+bool ipmiUserIsValidPrivilege(const uint8_t priv)
+{
+    return UserAccess::isValidPrivilege(priv);
+}
+
+uint8_t ipmiUserGetUserId(const std::string& userName)
+{
+    return getUserAccessObject().getUserId(userName);
+}
+
+Cc ipmiUserSetUserName(const uint8_t userId, const char* userName)
+{
+    std::string newUser(userName, 0, ipmiMaxUserName);
+    return getUserAccessObject().setUserName(userId, newUser);
+}
+
+Cc ipmiUserSetUserName(const uint8_t userId, const std::string& userName)
+{
+    std::string newUser(userName, 0, ipmiMaxUserName);
+    return getUserAccessObject().setUserName(userId, newUser);
+}
+
+Cc ipmiUserGetUserName(const uint8_t userId, std::string& userName)
+{
+    return getUserAccessObject().getUserName(userId, userName);
+}
+
+Cc ipmiUserSetUserPassword(const uint8_t userId, const char* userPassword)
+{
+    return getUserAccessObject().setUserPassword(userId, userPassword);
+}
+
+Cc ipmiSetSpecialUserPassword(const std::string& userName,
+                              const SecureString& userPassword)
+{
+    return getUserAccessObject().setSpecialUserPassword(userName, userPassword);
+}
+
+Cc ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
+                        uint8_t& fixedUsers)
+{
+    maxChUsers = ipmiMaxUsers;
+    UsersTbl* userData = getUserAccessObject().getUsersTblPtr();
+    enabledUsers = 0;
+    fixedUsers = 0;
+    // user index 0 is reserved, starts with 1
+    for (size_t count = 1; count <= ipmiMaxUsers; ++count)
+    {
+        if (userData->user[count].userEnabled)
+        {
+            enabledUsers++;
+        }
+        if (userData->user[count].fixedUserName)
+        {
+            fixedUsers++;
+        }
+    }
+    return ccSuccess;
+}
+
+Cc ipmiUserUpdateEnabledState(const uint8_t userId, const bool& state)
+{
+    return getUserAccessObject().setUserEnabledState(userId, state);
+}
+
+Cc ipmiUserCheckEnabled(const uint8_t userId, bool& state)
+{
+    if (!UserAccess::isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+    UserInfo* userInfo = getUserAccessObject().getUserInfo(userId);
+    state = userInfo->userEnabled;
+    return ccSuccess;
+}
+
+Cc ipmiUserGetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
+                              PrivAccess& privAccess)
+{
+    if (!UserAccess::isValidChannel(chNum))
+    {
+        return ccInvalidFieldRequest;
+    }
+    if (!UserAccess::isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+    UserInfo* userInfo = getUserAccessObject().getUserInfo(userId);
+    privAccess.privilege = userInfo->userPrivAccess[chNum].privilege;
+    privAccess.ipmiEnabled = userInfo->userPrivAccess[chNum].ipmiEnabled;
+    privAccess.linkAuthEnabled =
+        userInfo->userPrivAccess[chNum].linkAuthEnabled;
+    privAccess.accessCallback = userInfo->userPrivAccess[chNum].accessCallback;
+    return ccSuccess;
+}
+
+Cc ipmiUserSetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
+                              const PrivAccess& privAccess,
+                              const bool& otherPrivUpdates)
+{
+    UserPrivAccess userPrivAccess;
+    userPrivAccess.privilege = privAccess.privilege;
+    if (otherPrivUpdates)
+    {
+        userPrivAccess.ipmiEnabled = privAccess.ipmiEnabled;
+        userPrivAccess.linkAuthEnabled = privAccess.linkAuthEnabled;
+        userPrivAccess.accessCallback = privAccess.accessCallback;
+    }
+    return getUserAccessObject().setUserPrivilegeAccess(
+        userId, chNum, userPrivAccess, otherPrivUpdates);
+}
+
+bool ipmiUserPamAuthenticate(std::string_view userName,
+                             std::string_view userPassword)
+{
+    return pamUserCheckAuthenticate(userName, userPassword);
+}
+
+Cc ipmiUserSetUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
+                                const uint8_t userId,
+                                const PayloadAccess& payloadAccess)
+{
+    if (!UserAccess::isValidChannel(chNum))
+    {
+        return ccInvalidFieldRequest;
+    }
+    if (!UserAccess::isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+
+    return getUserAccessObject().setUserPayloadAccess(chNum, operation, userId,
+                                                      payloadAccess);
+}
+
+Cc ipmiUserGetUserPayloadAccess(const uint8_t chNum, const uint8_t userId,
+                                PayloadAccess& payloadAccess)
+{
+    if (!UserAccess::isValidChannel(chNum))
+    {
+        return ccInvalidFieldRequest;
+    }
+    if (!UserAccess::isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+
+    UserInfo* userInfo = getUserAccessObject().getUserInfo(userId);
+
+    payloadAccess.stdPayloadEnables1 =
+        userInfo->payloadAccess[chNum].stdPayloadEnables1;
+    payloadAccess.stdPayloadEnables2Reserved =
+        userInfo->payloadAccess[chNum].stdPayloadEnables2Reserved;
+    payloadAccess.oemPayloadEnables1 =
+        userInfo->payloadAccess[chNum].oemPayloadEnables1;
+    payloadAccess.oemPayloadEnables2Reserved =
+        userInfo->payloadAccess[chNum].oemPayloadEnables2Reserved;
+
+    return ccSuccess;
+}
+
+} // namespace ipmi
diff --git a/user_channel/user_layer.hpp b/user_channel/user_layer.hpp
new file mode 100644
index 0000000..ad215e3
--- /dev/null
+++ b/user_channel/user_layer.hpp
@@ -0,0 +1,270 @@
+/*
+// Copyright (c) 2018 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.
+*/
+#pragma once
+
+#include <ipmid/api.hpp>
+#include <ipmid/types.hpp>
+
+#include <bitset>
+#include <string>
+
+namespace ipmi
+{
+
+// TODO: Has to be replaced with proper channel number assignment logic
+/**
+ * @enum Channel Id
+ */
+enum class EChannelID : uint8_t
+{
+    chanLan1 = 0x01
+};
+
+static constexpr uint8_t invalidUserId = 0xFF;
+static constexpr uint8_t reservedUserId = 0x0;
+static constexpr uint8_t ipmiMaxUserName = 16;
+static constexpr uint8_t ipmiMaxUsers = 15;
+static constexpr uint8_t ipmiMaxChannels = 16;
+static constexpr uint8_t maxIpmi20PasswordSize = 20;
+static constexpr uint8_t maxIpmi15PasswordSize = 16;
+static constexpr uint8_t payloadsPerByte = 8;
+
+/** @struct PrivAccess
+ *
+ *  User privilege related access data as per IPMI specification.(refer spec
+ * sec 22.26)
+ */
+struct PrivAccess
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t privilege:4;
+    uint8_t ipmiEnabled:1;
+    uint8_t linkAuthEnabled:1;
+    uint8_t accessCallback:1;
+    uint8_t reserved:1;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved:1;
+    uint8_t accessCallback:1;
+    uint8_t linkAuthEnabled:1;
+    uint8_t ipmiEnabled:1;
+    uint8_t privilege:4;
+#endif
+} __attribute__((packed));
+
+/** @struct UserPayloadAccess
+ *
+ *  Structure to denote payload access restrictions applicable for a
+ *  given user and channel. (refer spec sec 24.6)
+ */
+struct PayloadAccess
+{
+    std::bitset<payloadsPerByte> stdPayloadEnables1;
+    std::bitset<payloadsPerByte> stdPayloadEnables2Reserved;
+    std::bitset<payloadsPerByte> oemPayloadEnables1;
+    std::bitset<payloadsPerByte> oemPayloadEnables2Reserved;
+};
+
+/** @brief initializes user management
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserInit();
+
+/** @brief The ipmi get user password layer call
+ *
+ *  @param[in] userName - user name
+ *
+ *  @return password or empty string
+ */
+SecureString ipmiUserGetPassword(const std::string& userName);
+
+/** @brief The IPMI call to clear password entry associated with specified
+ * username
+ *
+ *  @param[in] userName - user name to be removed
+ *
+ *  @return 0 on success, non-zero otherwise.
+ */
+Cc ipmiClearUserEntryPassword(const std::string& userName);
+
+/** @brief The IPMI call to reuse password entry for the renamed user
+ *  to another one
+ *
+ *  @param[in] userName - user name which has to be renamed
+ *  @param[in] newUserName - new user name
+ *
+ *  @return 0 on success, non-zero otherwise.
+ */
+Cc ipmiRenameUserEntryPassword(const std::string& userName,
+                               const std::string& newUserName);
+
+/** @brief determines valid userId
+ *
+ *  @param[in] userId - user id
+ *
+ *  @return true if valid, false otherwise
+ */
+bool ipmiUserIsValidUserId(const uint8_t userId);
+
+/** @brief determines valid privilege level
+ *
+ *  @param[in] priv - privilege level
+ *
+ *  @return true if valid, false otherwise
+ */
+bool ipmiUserIsValidPrivilege(const uint8_t priv);
+
+/** @brief get user id corresponding to the user name
+ *
+ *  @param[in] userName - user name
+ *
+ *  @return userid. Will return 0xff if no user id found
+ */
+uint8_t ipmiUserGetUserId(const std::string& userName);
+
+/** @brief set's user name
+ *  This API is deprecated
+ */
+Cc ipmiUserSetUserName(const uint8_t userId, const char* userName)
+    __attribute__((deprecated));
+
+/** @brief set's user name
+ *
+ *  @param[in] userId - user id
+ *  @param[in] userName - user name
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserSetUserName(const uint8_t userId, const std::string& userName);
+
+/** @brief set user password
+ *
+ *  @param[in] userId - user id
+ *  @param[in] userPassword - New Password
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserSetUserPassword(const uint8_t userId, const char* userPassword);
+
+/** @brief set special user password (non-ipmi accounts)
+ *
+ *  @param[in] userName - user name
+ *  @param[in] userPassword - New Password
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiSetSpecialUserPassword(const std::string& userName,
+                              const SecureString& userPassword);
+
+/** @brief get user name
+ *
+ *  @param[in] userId - user id
+ *  @param[out] userName - user name
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserGetUserName(const uint8_t userId, std::string& userName);
+
+/** @brief provides available fixed, max, and enabled user counts
+ *
+ *  @param[out] maxChUsers - max channel users
+ *  @param[out] enabledUsers - enabled user count
+ *  @param[out] fixedUsers - fixed user count
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
+                        uint8_t& fixedUsers);
+
+/** @brief function to update user enabled state
+ *
+ *  @param[in] userId - user id
+ *..@param[in] state - state of the user to be updated, true - user enabled.
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserUpdateEnabledState(const uint8_t userId, const bool& state);
+
+/** @brief determines whether user is enabled
+ *
+ *  @param[in] userId - user id
+ *..@param[out] state - state of the user
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserCheckEnabled(const uint8_t userId, bool& state);
+
+/** @brief provides user privilege access data
+ *
+ *  @param[in] userId - user id
+ *  @param[in] chNum - channel number
+ *  @param[out] privAccess - privilege access data
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserGetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
+                              PrivAccess& privAccess);
+
+/** @brief sets user privilege access data
+ *
+ *  @param[in] userId - user id
+ *  @param[in] chNum - channel number
+ *  @param[in] privAccess - privilege access data
+ *  @param[in] otherPrivUpdate - flags to indicate other fields update
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserSetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
+                              const PrivAccess& privAccess,
+                              const bool& otherPrivUpdate);
+
+/** @brief check for user pam authentication. This is to determine, whether user
+ * is already locked out for failed login attempt
+ *
+ *  @param[in] username - username
+ *  @param[in] password - password
+ *
+ *  @return status
+ */
+bool ipmiUserPamAuthenticate(std::string_view userName,
+                             std::string_view userPassword);
+
+/** @brief sets user payload access data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] operation - ENABLE / DISABLE operation
+ *  @param[in] userId - user id
+ *  @param[in] payloadAccess - payload access data
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserSetUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
+                                const uint8_t userId,
+                                const PayloadAccess& payloadAccess);
+
+/** @brief provides user payload access data
+ *
+ *  @param[in] chNum - channel number
+ *  @param[in] userId - user id
+ *  @param[out] payloadAccess - payload access data
+ *
+ *  @return ccSuccess for success, others for failure.
+ */
+Cc ipmiUserGetUserPayloadAccess(const uint8_t chNum, const uint8_t userId,
+                                PayloadAccess& payloadAccess);
+
+} // namespace ipmi
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
new file mode 100644
index 0000000..29262cb
--- /dev/null
+++ b/user_channel/user_mgmt.cpp
@@ -0,0 +1,1748 @@
+/*
+// Copyright (c) 2018 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 "user_mgmt.hpp"
+
+#include "channel_layer.hpp"
+#include "channel_mgmt.hpp"
+
+#include <security/pam_appl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <boost/interprocess/sync/named_recursive_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <ipmid/types.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/User/Common/error.hpp>
+
+#include <cerrno>
+#include <fstream>
+#include <regex>
+#include <variant>
+
+namespace ipmi
+{
+
+// TODO: Move D-Bus & Object Manager related stuff, to common files
+// D-Bus property related
+static constexpr const char* dBusPropertiesInterface =
+    "org.freedesktop.DBus.Properties";
+static constexpr const char* getAllPropertiesMethod = "GetAll";
+static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
+static constexpr const char* setPropertiesMethod = "Set";
+
+// Object Manager related
+static constexpr const char* dBusObjManager =
+    "org.freedesktop.DBus.ObjectManager";
+static constexpr const char* getManagedObjectsMethod = "GetManagedObjects";
+// Object Manager signals
+static constexpr const char* intfAddedSignal = "InterfacesAdded";
+static constexpr const char* intfRemovedSignal = "InterfacesRemoved";
+
+static constexpr const char* ipmiUserMutex = "ipmi_usr_mutex";
+static constexpr const char* ipmiMutexCleanupLockFile =
+    "/run/ipmi/ipmi_usr_mutex_cleanup";
+static constexpr const char* ipmiUserSignalLockFile =
+    "/run/ipmi/ipmi_usr_signal_mutex";
+static constexpr const char* ipmiUserDataFile = "/var/lib/ipmi/ipmi_user.json";
+static constexpr const char* ipmiGrpName = "ipmi";
+static constexpr size_t privNoAccess = 0xF;
+static constexpr size_t privMask = 0xF;
+
+// User manager related
+static constexpr const char* userMgrService =
+    "xyz.openbmc_project.User.Manager";
+static constexpr const char* userMgrObjBasePath = "/xyz/openbmc_project/user";
+static constexpr const char* userObjBasePath = "/xyz/openbmc_project/user";
+static constexpr const char* userMgrInterface =
+    "xyz.openbmc_project.User.Manager";
+static constexpr const char* usersInterface =
+    "xyz.openbmc_project.User.Attributes";
+static constexpr const char* deleteUserInterface =
+    "xyz.openbmc_project.Object.Delete";
+
+static constexpr const char* createUserMethod = "CreateUser";
+static constexpr const char* deleteUserMethod = "Delete";
+static constexpr const char* renameUserMethod = "RenameUser";
+// User manager signal memebers
+static constexpr const char* userRenamedSignal = "UserRenamed";
+// Mgr interface properties
+static constexpr const char* allPrivProperty = "AllPrivileges";
+static constexpr const char* allGrpProperty = "AllGroups";
+// User interface properties
+static constexpr const char* userPrivProperty = "UserPrivilege";
+static constexpr const char* userGrpProperty = "UserGroups";
+static constexpr const char* userEnabledProperty = "UserEnabled";
+
+static std::array<std::string, (PRIVILEGE_OEM + 1)> ipmiPrivIndex = {
+    "priv-reserved", // PRIVILEGE_RESERVED - 0
+    "priv-callback", // PRIVILEGE_CALLBACK - 1
+    "priv-user",     // PRIVILEGE_USER - 2
+    "priv-operator", // PRIVILEGE_OPERATOR - 3
+    "priv-admin",    // PRIVILEGE_ADMIN - 4
+    "priv-custom"    // PRIVILEGE_OEM - 5
+};
+
+using namespace phosphor::logging;
+using Json = nlohmann::json;
+
+using PrivAndGroupType = std::variant<std::string, std::vector<std::string>>;
+
+using NoResource =
+    sdbusplus::error::xyz::openbmc_project::user::common::NoResource;
+
+using InternalFailure =
+    sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
+
+std::unique_ptr<sdbusplus::bus::match_t> userUpdatedSignal
+    __attribute__((init_priority(101)));
+std::unique_ptr<sdbusplus::bus::match_t> userMgrRenamedSignal
+    __attribute__((init_priority(101)));
+std::unique_ptr<sdbusplus::bus::match_t> userPropertiesSignal
+    __attribute__((init_priority(101)));
+
+void setDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                     const std::string& objPath, const std::string& interface,
+                     const std::string& property,
+                     const DbusUserPropVariant& value)
+{
+    try
+    {
+        auto method =
+            bus.new_method_call(service.c_str(), objPath.c_str(),
+                                dBusPropertiesInterface, setPropertiesMethod);
+        method.append(interface, property, value);
+        bus.call(method);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to set {PROPERTY}, path: {PATH}, "
+                   "interface: {INTERFACE}",
+                   "PROPERTY", property, "PATH", objPath, "INTERFACE",
+                   interface);
+        throw;
+    }
+}
+
+UserAccess& getUserAccessObject()
+{
+    static UserAccess userAccess;
+    return userAccess;
+}
+
+int getUserNameFromPath(const std::string& path, std::string& userName)
+{
+    sdbusplus::message::object_path objPath(path);
+    userName.assign(objPath.filename());
+    return 0;
+}
+
+void userUpdateHelper(UserAccess& usrAccess, const UserUpdateEvent& userEvent,
+                      const std::string& userName, const std::string& priv,
+                      const bool& enabled, const std::string& newUserName)
+{
+    UsersTbl* userData = usrAccess.getUsersTblPtr();
+    if (userEvent == UserUpdateEvent::userCreated)
+    {
+        if (usrAccess.addUserEntry(userName, priv, enabled) == false)
+        {
+            return;
+        }
+    }
+    else
+    {
+        // user index 0 is reserved, starts with 1
+        size_t usrIndex = 1;
+        for (; usrIndex <= ipmiMaxUsers; ++usrIndex)
+        {
+            std::string curName(
+                reinterpret_cast<char*>(userData->user[usrIndex].userName), 0,
+                ipmiMaxUserName);
+            if (userName == curName)
+            {
+                break; // found the entry
+            }
+        }
+        if (usrIndex > ipmiMaxUsers)
+        {
+            lg2::debug("User not found for signal, user name: {USER_NAME}, "
+                       "user event: {USER_EVENT}",
+                       "USER_NAME", userName, "USER_EVENT", userEvent);
+            return;
+        }
+        switch (userEvent)
+        {
+            case UserUpdateEvent::userDeleted:
+            {
+                usrAccess.deleteUserIndex(usrIndex);
+                break;
+            }
+            case UserUpdateEvent::userPrivUpdated:
+            {
+                uint8_t userPriv =
+                    static_cast<uint8_t>(
+                        UserAccess::convertToIPMIPrivilege(priv)) &
+                    privMask;
+                // Update all channels privileges, only if it is not equivalent
+                // to getUsrMgmtSyncIndex()
+                if (userData->user[usrIndex]
+                        .userPrivAccess[UserAccess::getUsrMgmtSyncIndex()]
+                        .privilege != userPriv)
+                {
+                    for (size_t chIndex = 0; chIndex < ipmiMaxChannels;
+                         ++chIndex)
+                    {
+                        userData->user[usrIndex]
+                            .userPrivAccess[chIndex]
+                            .privilege = userPriv;
+                    }
+                }
+                break;
+            }
+            case UserUpdateEvent::userRenamed:
+            {
+                std::fill(
+                    static_cast<uint8_t*>(userData->user[usrIndex].userName),
+                    static_cast<uint8_t*>(userData->user[usrIndex].userName) +
+                        sizeof(userData->user[usrIndex].userName),
+                    0);
+                std::strncpy(
+                    reinterpret_cast<char*>(userData->user[usrIndex].userName),
+                    newUserName.c_str(), ipmiMaxUserName);
+                ipmiRenameUserEntryPassword(userName, newUserName);
+                break;
+            }
+            case UserUpdateEvent::userStateUpdated:
+            {
+                userData->user[usrIndex].userEnabled = enabled;
+                break;
+            }
+            default:
+            {
+                lg2::error("Unhandled user event: {USER_EVENT}", "USER_EVENT",
+                           userEvent);
+                return;
+            }
+        }
+    }
+    usrAccess.writeUserData();
+    lg2::debug("User event handled successfully, user name: {USER_NAME}, "
+               "user event: {USER_EVENT}",
+               "USER_NAME", userName.c_str(), "USER_EVENT", userEvent);
+
+    return;
+}
+
+void userUpdatedSignalHandler(UserAccess& usrAccess, sdbusplus::message_t& msg)
+{
+    static sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
+    std::string signal = msg.get_member();
+    std::string userName, priv, newUserName;
+    std::vector<std::string> groups;
+    bool enabled = false;
+    UserUpdateEvent userEvent = UserUpdateEvent::reservedEvent;
+    if (signal == intfAddedSignal)
+    {
+        DbusUserObjPath objPath;
+        DbusUserObjValue objValue;
+        msg.read(objPath, objValue);
+        getUserNameFromPath(objPath.str, userName);
+        if (usrAccess.getUserObjProperties(objValue, groups, priv, enabled) !=
+            0)
+        {
+            return;
+        }
+        if (std::find(groups.begin(), groups.end(), ipmiGrpName) ==
+            groups.end())
+        {
+            return;
+        }
+        userEvent = UserUpdateEvent::userCreated;
+    }
+    else if (signal == intfRemovedSignal)
+    {
+        DbusUserObjPath objPath;
+        std::vector<std::string> interfaces;
+        msg.read(objPath, interfaces);
+        getUserNameFromPath(objPath.str, userName);
+        userEvent = UserUpdateEvent::userDeleted;
+    }
+    else if (signal == userRenamedSignal)
+    {
+        msg.read(userName, newUserName);
+        userEvent = UserUpdateEvent::userRenamed;
+    }
+    else if (signal == propertiesChangedSignal)
+    {
+        getUserNameFromPath(msg.get_path(), userName);
+    }
+    else
+    {
+        lg2::error("Unknown user update signal: {SIGNAL}", "SIGNAL", signal);
+        return;
+    }
+
+    if (signal.empty() || userName.empty() ||
+        (signal == userRenamedSignal && newUserName.empty()))
+    {
+        lg2::error("Invalid inputs received");
+        return;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*(usrAccess.userMutex)};
+    usrAccess.checkAndReloadUserData();
+
+    if (signal == propertiesChangedSignal)
+    {
+        std::string intfName;
+        DbusUserObjProperties chProperties;
+        msg.read(intfName, chProperties); // skip reading 3rd argument.
+        for (const auto& prop : chProperties)
+        {
+            userEvent = UserUpdateEvent::reservedEvent;
+            std::string member = prop.first;
+            if (member == userPrivProperty)
+            {
+                priv = std::get<std::string>(prop.second);
+                userEvent = UserUpdateEvent::userPrivUpdated;
+            }
+            else if (member == userGrpProperty)
+            {
+                groups = std::get<std::vector<std::string>>(prop.second);
+                userEvent = UserUpdateEvent::userGrpUpdated;
+            }
+            else if (member == userEnabledProperty)
+            {
+                enabled = std::get<bool>(prop.second);
+                userEvent = UserUpdateEvent::userStateUpdated;
+            }
+            // Process based on event type.
+            if (userEvent == UserUpdateEvent::userGrpUpdated)
+            {
+                if (std::find(groups.begin(), groups.end(), ipmiGrpName) ==
+                    groups.end())
+                {
+                    // remove user from ipmi user list.
+                    userUpdateHelper(usrAccess, UserUpdateEvent::userDeleted,
+                                     userName, priv, enabled, newUserName);
+                }
+                else
+                {
+                    DbusUserObjProperties properties;
+                    try
+                    {
+                        auto method = bus.new_method_call(
+                            userMgrService, msg.get_path(),
+                            dBusPropertiesInterface, getAllPropertiesMethod);
+                        method.append(usersInterface);
+                        auto reply = bus.call(method);
+                        reply.read(properties);
+                    }
+                    catch (const sdbusplus::exception_t& e)
+                    {
+                        lg2::debug("Failed to excute {METHOD}, path: {PATH}",
+                                   "METHOD", getAllPropertiesMethod, "PATH",
+                                   msg.get_path());
+                        return;
+                    }
+                    usrAccess.getUserProperties(properties, groups, priv,
+                                                enabled);
+                    // add user to ipmi user list.
+                    userUpdateHelper(usrAccess, UserUpdateEvent::userCreated,
+                                     userName, priv, enabled, newUserName);
+                }
+            }
+            else if (userEvent != UserUpdateEvent::reservedEvent)
+            {
+                userUpdateHelper(usrAccess, userEvent, userName, priv, enabled,
+                                 newUserName);
+            }
+        }
+    }
+    else if (userEvent != UserUpdateEvent::reservedEvent)
+    {
+        userUpdateHelper(usrAccess, userEvent, userName, priv, enabled,
+                         newUserName);
+    }
+    return;
+}
+
+UserAccess::~UserAccess()
+{
+    if (signalHndlrObject)
+    {
+        userUpdatedSignal.reset();
+        userMgrRenamedSignal.reset();
+        userPropertiesSignal.reset();
+        sigHndlrLock.unlock();
+    }
+}
+
+UserAccess::UserAccess() : bus(ipmid_get_sd_bus_connection())
+{
+    std::ofstream mutexCleanUpFile;
+    mutexCleanUpFile.open(ipmiMutexCleanupLockFile,
+                          std::ofstream::out | std::ofstream::app);
+    if (!mutexCleanUpFile.good())
+    {
+        lg2::debug("Unable to open mutex cleanup file");
+        return;
+    }
+    mutexCleanUpFile.close();
+    mutexCleanupLock = boost::interprocess::file_lock(ipmiMutexCleanupLockFile);
+    if (mutexCleanupLock.try_lock())
+    {
+        boost::interprocess::named_recursive_mutex::remove(ipmiUserMutex);
+    }
+    mutexCleanupLock.lock_sharable();
+    userMutex = std::make_unique<boost::interprocess::named_recursive_mutex>(
+        boost::interprocess::open_or_create, ipmiUserMutex);
+
+    cacheUserDataFile();
+    getSystemPrivAndGroups();
+}
+
+UserInfo* UserAccess::getUserInfo(const uint8_t userId)
+{
+    checkAndReloadUserData();
+    return &usersTbl.user[userId];
+}
+
+void UserAccess::setUserInfo(const uint8_t userId, UserInfo* userInfo)
+{
+    checkAndReloadUserData();
+    std::copy(reinterpret_cast<uint8_t*>(userInfo),
+              reinterpret_cast<uint8_t*>(userInfo) + sizeof(*userInfo),
+              reinterpret_cast<uint8_t*>(&usersTbl.user[userId]));
+    writeUserData();
+}
+
+bool UserAccess::isValidChannel(const uint8_t chNum)
+{
+    return (chNum < ipmiMaxChannels);
+}
+
+bool UserAccess::isValidUserId(const uint8_t userId)
+{
+    return ((userId <= ipmiMaxUsers) && (userId != reservedUserId));
+}
+
+bool UserAccess::isValidPrivilege(const uint8_t priv)
+{
+    // Callback privilege is deprecated in OpenBMC
+    return isValidPrivLimit(priv);
+}
+
+uint8_t UserAccess::getUsrMgmtSyncIndex()
+{
+    // Identify the IPMI channel used to assign system user privilege levels
+    // in phosphor-user-manager. The default value is IPMI Channel 1. To
+    // assign a different channel add:
+    //      "is_management_nic" : true
+    // into the channel_config.json file describing the assignment of the IPMI
+    // channels. It is only necessary to add the string above to ONE record in
+    // the channel_config.json file. All other records will be automatically
+    // assigned a "false" value.
+    return getChannelConfigObject().getManagementNICID();
+}
+
+CommandPrivilege UserAccess::convertToIPMIPrivilege(const std::string& value)
+{
+    auto iter = std::find(ipmiPrivIndex.begin(), ipmiPrivIndex.end(), value);
+    if (iter == ipmiPrivIndex.end())
+    {
+        if (value == "")
+        {
+            return static_cast<CommandPrivilege>(privNoAccess);
+        }
+        lg2::error("Error in converting to IPMI privilege: {PRIV}", "PRIV",
+                   value);
+        throw std::out_of_range("Out of range - convertToIPMIPrivilege");
+    }
+    else
+    {
+        return static_cast<CommandPrivilege>(
+            std::distance(ipmiPrivIndex.begin(), iter));
+    }
+}
+
+std::string UserAccess::convertToSystemPrivilege(const CommandPrivilege& value)
+{
+    if (value == static_cast<CommandPrivilege>(privNoAccess))
+    {
+        return "";
+    }
+    try
+    {
+        return ipmiPrivIndex.at(value);
+    }
+    catch (const std::out_of_range& e)
+    {
+        lg2::error("Error in converting to system privilege: {PRIV}", "PRIV",
+                   value);
+        throw std::out_of_range("Out of range - convertToSystemPrivilege");
+    }
+}
+
+bool UserAccess::isValidUserName(const std::string& userName)
+{
+    if (userName.empty())
+    {
+        lg2::error("userName is empty");
+        return false;
+    }
+    if (!std::regex_match(userName.c_str(),
+                          std::regex("[a-zA-Z_][a-zA-Z_0-9]*")))
+    {
+        lg2::error("Unsupported characters in user name");
+        return false;
+    }
+    if (userName == "root")
+    {
+        lg2::error("Invalid user name - root");
+        return false;
+    }
+    std::map<DbusUserObjPath, DbusUserObjValue> properties;
+    try
+    {
+        auto method =
+            bus.new_method_call(userMgrService, userMgrObjBasePath,
+                                dBusObjManager, getManagedObjectsMethod);
+        auto reply = bus.call(method);
+        reply.read(properties);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to excute {METHOD}, path: {PATH}", "METHOD",
+                   getManagedObjectsMethod, "PATH", userMgrObjBasePath);
+        return false;
+    }
+
+    sdbusplus::message::object_path tempUserPath(userObjBasePath);
+    tempUserPath /= userName;
+    std::string usersPath(tempUserPath);
+
+    if (properties.find(usersPath) != properties.end())
+    {
+        lg2::debug("Username {USER_NAME} already exists", "USER_NAME",
+                   userName);
+        return false;
+    }
+
+    return true;
+}
+
+/** @brief Information exchanged by pam module and application.
+ *
+ *  @param[in] numMsg - length of the array of pointers,msg.
+ *
+ *  @param[in] msg -  pointer  to an array of pointers to pam_message structure
+ *
+ *  @param[out] resp - struct pam response array
+ *
+ *  @param[in] appdataPtr - member of pam_conv structure
+ *
+ *  @return the response in pam response structure.
+ */
+
+static int pamFunctionConversation(int numMsg, const struct pam_message** msg,
+                                   struct pam_response** resp, void* appdataPtr)
+{
+    if (appdataPtr == nullptr)
+    {
+        return PAM_CONV_ERR;
+    }
+
+    if (numMsg <= 0 || numMsg >= PAM_MAX_NUM_MSG)
+    {
+        return PAM_CONV_ERR;
+    }
+
+    for (int i = 0; i < numMsg; ++i)
+    {
+        /* Ignore all PAM messages except prompting for hidden input */
+        if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF)
+        {
+            continue;
+        }
+
+        /* Assume PAM is only prompting for the password as hidden input */
+        /* Allocate memory only when PAM_PROMPT_ECHO_OFF is encounterred */
+
+        char* appPass = reinterpret_cast<char*>(appdataPtr);
+        size_t appPassSize = std::strlen(appPass);
+
+        if (appPassSize >= PAM_MAX_RESP_SIZE)
+        {
+            return PAM_CONV_ERR;
+        }
+
+        char* pass = reinterpret_cast<char*>(malloc(appPassSize + 1));
+        if (pass == nullptr)
+        {
+            return PAM_BUF_ERR;
+        }
+
+        void* ptr =
+            calloc(static_cast<size_t>(numMsg), sizeof(struct pam_response));
+        if (ptr == nullptr)
+        {
+            free(pass);
+            return PAM_BUF_ERR;
+        }
+
+        std::strncpy(pass, appPass, appPassSize + 1);
+
+        *resp = reinterpret_cast<pam_response*>(ptr);
+        resp[i]->resp = pass;
+
+        return PAM_SUCCESS;
+    }
+
+    return PAM_CONV_ERR;
+}
+
+/** @brief Updating the PAM password
+ *
+ *  @param[in] username - username in string
+ *
+ *  @param[in] password  - new password in string
+ *
+ *  @return status
+ */
+
+int pamUpdatePasswd(const char* username, const char* password)
+{
+    const struct pam_conv localConversation = {pamFunctionConversation,
+                                               const_cast<char*>(password)};
+    pam_handle_t* localAuthHandle = nullptr; // this gets set by pam_start
+
+    int retval =
+        pam_start("passwd", username, &localConversation, &localAuthHandle);
+
+    if (retval != PAM_SUCCESS)
+    {
+        return retval;
+    }
+
+    retval = pam_chauthtok(localAuthHandle, PAM_SILENT);
+    if (retval != PAM_SUCCESS)
+    {
+        pam_end(localAuthHandle, retval);
+        return retval;
+    }
+
+    return pam_end(localAuthHandle, PAM_SUCCESS);
+}
+
+bool pamUserCheckAuthenticate(std::string_view username,
+                              std::string_view password)
+{
+    const struct pam_conv localConversation = {
+        pamFunctionConversation, const_cast<char*>(password.data())};
+
+    pam_handle_t* localAuthHandle = nullptr; // this gets set by pam_start
+
+    if (pam_start("dropbear", username.data(), &localConversation,
+                  &localAuthHandle) != PAM_SUCCESS)
+    {
+        lg2::error("User Authentication Failure");
+        return false;
+    }
+
+    int retval = pam_authenticate(localAuthHandle,
+                                  PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
+
+    if (retval != PAM_SUCCESS)
+    {
+        lg2::debug("pam_authenticate returned failure: {ERROR}", "ERROR",
+                   retval);
+
+        pam_end(localAuthHandle, retval);
+        return false;
+    }
+
+    if (pam_acct_mgmt(localAuthHandle, PAM_DISALLOW_NULL_AUTHTOK) !=
+        PAM_SUCCESS)
+    {
+        pam_end(localAuthHandle, PAM_SUCCESS);
+        return false;
+    }
+
+    if (pam_end(localAuthHandle, PAM_SUCCESS) != PAM_SUCCESS)
+    {
+        return false;
+    }
+    return true;
+}
+
+Cc UserAccess::setSpecialUserPassword(const std::string& userName,
+                                      const SecureString& userPassword)
+{
+    if (pamUpdatePasswd(userName.c_str(), userPassword.c_str()) != PAM_SUCCESS)
+    {
+        lg2::debug("Failed to update password");
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+Cc UserAccess::setUserPassword(const uint8_t userId, const char* userPassword)
+{
+    std::string userName;
+    if (ipmiUserGetUserName(userId, userName) != ccSuccess)
+    {
+        lg2::debug("User Name not found, user Id: {USER_ID}", "USER_ID",
+                   userId);
+        return ccParmOutOfRange;
+    }
+
+    ipmi::SecureString passwd;
+    passwd.assign(reinterpret_cast<const char*>(userPassword), 0,
+                  maxIpmi20PasswordSize);
+    int retval = pamUpdatePasswd(userName.c_str(), passwd.c_str());
+
+    switch (retval)
+    {
+        case PAM_SUCCESS:
+        {
+            return ccSuccess;
+        }
+        case PAM_AUTHTOK_ERR:
+        {
+            lg2::debug("Bad authentication token");
+            return ccInvalidFieldRequest;
+        }
+        default:
+        {
+            lg2::debug("Failed to update password, user Id: {USER_ID}",
+                       "USER_ID", userId);
+            return ccUnspecifiedError;
+        }
+    }
+}
+
+Cc UserAccess::setUserEnabledState(const uint8_t userId,
+                                   const bool& enabledState)
+{
+    if (!isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    UserInfo* userInfo = getUserInfo(userId);
+    std::string userName;
+    userName.assign(reinterpret_cast<char*>(userInfo->userName), 0,
+                    ipmiMaxUserName);
+    if (userName.empty())
+    {
+        lg2::debug("User name not set / invalid");
+        return ccUnspecifiedError;
+    }
+    if (userInfo->userEnabled != enabledState)
+    {
+        sdbusplus::message::object_path tempUserPath(userObjBasePath);
+        tempUserPath /= userName;
+        std::string userPath(tempUserPath);
+        setDbusProperty(bus, userMgrService, userPath, usersInterface,
+                        userEnabledProperty, enabledState);
+        userInfo->userEnabled = enabledState;
+        try
+        {
+            writeUserData();
+        }
+        catch (const std::exception& e)
+        {
+            lg2::debug("Write user data failed");
+            return ccUnspecifiedError;
+        }
+    }
+    return ccSuccess;
+}
+
+Cc UserAccess::setUserPayloadAccess(
+    const uint8_t chNum, const uint8_t operation, const uint8_t userId,
+    const PayloadAccess& payloadAccess)
+{
+    constexpr uint8_t enable = 0x0;
+    constexpr uint8_t disable = 0x1;
+
+    if (!isValidChannel(chNum))
+    {
+        return ccInvalidFieldRequest;
+    }
+    if (!isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+    if (operation != enable && operation != disable)
+    {
+        return ccInvalidFieldRequest;
+    }
+    // Check operation & payloadAccess if required.
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    UserInfo* userInfo = getUserInfo(userId);
+
+    if (operation == enable)
+    {
+        userInfo->payloadAccess[chNum].stdPayloadEnables1 |=
+            payloadAccess.stdPayloadEnables1;
+
+        userInfo->payloadAccess[chNum].oemPayloadEnables1 |=
+            payloadAccess.oemPayloadEnables1;
+    }
+    else
+    {
+        userInfo->payloadAccess[chNum].stdPayloadEnables1 &=
+            ~(payloadAccess.stdPayloadEnables1);
+
+        userInfo->payloadAccess[chNum].oemPayloadEnables1 &=
+            ~(payloadAccess.oemPayloadEnables1);
+    }
+
+    try
+    {
+        writeUserData();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Write user data failed");
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+Cc UserAccess::setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
+                                      const UserPrivAccess& privAccess,
+                                      const bool& otherPrivUpdates)
+{
+    if (!isValidChannel(chNum))
+    {
+        return ccInvalidFieldRequest;
+    }
+    if (!isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    UserInfo* userInfo = getUserInfo(userId);
+    std::string userName;
+    userName.assign(reinterpret_cast<char*>(userInfo->userName), 0,
+                    ipmiMaxUserName);
+    if (userName.empty())
+    {
+        lg2::debug("User name not set / invalid");
+        return ccUnspecifiedError;
+    }
+    std::string priv = convertToSystemPrivilege(
+        static_cast<CommandPrivilege>(privAccess.privilege));
+    uint8_t syncIndex = getUsrMgmtSyncIndex();
+    if (chNum == syncIndex &&
+        privAccess.privilege != userInfo->userPrivAccess[syncIndex].privilege)
+    {
+        sdbusplus::message::object_path tempUserPath(userObjBasePath);
+        tempUserPath /= userName;
+        std::string userPath(tempUserPath);
+        setDbusProperty(bus, userMgrService, userPath, usersInterface,
+                        userPrivProperty, priv);
+    }
+    userInfo->userPrivAccess[chNum].privilege = privAccess.privilege;
+
+    if (otherPrivUpdates)
+    {
+        userInfo->userPrivAccess[chNum].ipmiEnabled = privAccess.ipmiEnabled;
+        userInfo->userPrivAccess[chNum].linkAuthEnabled =
+            privAccess.linkAuthEnabled;
+        userInfo->userPrivAccess[chNum].accessCallback =
+            privAccess.accessCallback;
+    }
+    try
+    {
+        writeUserData();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::debug("Write user data failed");
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+uint8_t UserAccess::getUserId(const std::string& userName)
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    checkAndReloadUserData();
+    // user index 0 is reserved, starts with 1
+    size_t usrIndex = 1;
+    for (; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        std::string curName(
+            reinterpret_cast<char*>(usersTbl.user[usrIndex].userName), 0,
+            ipmiMaxUserName);
+        if (userName == curName)
+        {
+            break; // found the entry
+        }
+    }
+    if (usrIndex > ipmiMaxUsers)
+    {
+        lg2::debug("Username {USER_NAME} not found", "USER_NAME", userName);
+        return invalidUserId;
+    }
+
+    return usrIndex;
+}
+
+Cc UserAccess::getUserName(const uint8_t userId, std::string& userName)
+{
+    if (!isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+    UserInfo* userInfo = getUserInfo(userId);
+    userName.assign(reinterpret_cast<char*>(userInfo->userName), 0,
+                    ipmiMaxUserName);
+    return ccSuccess;
+}
+
+bool UserAccess::isIpmiInAvailableGroupList()
+{
+    if (std::find(availableGroups.begin(), availableGroups.end(),
+                  ipmiGrpName) != availableGroups.end())
+    {
+        return true;
+    }
+    if (availableGroups.empty())
+    {
+        // available groups shouldn't be empty, re-query
+        getSystemPrivAndGroups();
+        if (std::find(availableGroups.begin(), availableGroups.end(),
+                      ipmiGrpName) != availableGroups.end())
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+Cc UserAccess::setUserName(const uint8_t userId, const std::string& userName)
+{
+    if (!isValidUserId(userId))
+    {
+        return ccParmOutOfRange;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    std::string oldUser;
+    getUserName(userId, oldUser);
+
+    if (oldUser == userName)
+    {
+        // requesting to set the same user name, return success.
+        return ccSuccess;
+    }
+
+    bool validUser = isValidUserName(userName);
+    UserInfo* userInfo = getUserInfo(userId);
+    if (userName.empty() && !oldUser.empty())
+    {
+        // Delete existing user
+        sdbusplus::message::object_path tempUserPath(userObjBasePath);
+        tempUserPath /= oldUser;
+        std::string userPath(tempUserPath);
+        try
+        {
+            auto method =
+                bus.new_method_call(userMgrService, userPath.c_str(),
+                                    deleteUserInterface, deleteUserMethod);
+            auto reply = bus.call(method);
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            lg2::debug("Failed to excute {METHOD}, path:{PATH}", "METHOD",
+                       deleteUserMethod, "PATH", userPath);
+            return ccUnspecifiedError;
+        }
+        deleteUserIndex(userId);
+    }
+    else if (oldUser.empty() && !userName.empty() && validUser)
+    {
+        try
+        {
+            if (!isIpmiInAvailableGroupList())
+            {
+                return ccUnspecifiedError;
+            }
+            // Create new user
+            auto method =
+                bus.new_method_call(userMgrService, userMgrObjBasePath,
+                                    userMgrInterface, createUserMethod);
+            method.append(userName.c_str(), availableGroups,
+                          ipmiPrivIndex[PRIVILEGE_USER], false);
+            auto reply = bus.call(method);
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            lg2::debug("Failed to excute {METHOD}, path: {PATH}", "METHOD",
+                       createUserMethod, "PATH", userMgrObjBasePath);
+            return ccUnspecifiedError;
+        }
+
+        std::memset(userInfo->userName, 0, sizeof(userInfo->userName));
+        std::memcpy(userInfo->userName,
+                    static_cast<const void*>(userName.data()), userName.size());
+        userInfo->userInSystem = true;
+        for (size_t chIndex = 0; chIndex < ipmiMaxChannels; chIndex++)
+        {
+            userInfo->userPrivAccess[chIndex].privilege =
+                static_cast<uint8_t>(PRIVILEGE_USER);
+        }
+    }
+    else if (oldUser != userName && validUser)
+    {
+        try
+        {
+            // User rename
+            auto method =
+                bus.new_method_call(userMgrService, userMgrObjBasePath,
+                                    userMgrInterface, renameUserMethod);
+            method.append(oldUser.c_str(), userName.c_str());
+            auto reply = bus.call(method);
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            lg2::debug("Failed to excute {METHOD}, path: {PATH}", "METHOD",
+                       renameUserMethod, "PATH", userMgrObjBasePath);
+            return ccUnspecifiedError;
+        }
+        std::fill(static_cast<uint8_t*>(userInfo->userName),
+                  static_cast<uint8_t*>(userInfo->userName) +
+                      sizeof(userInfo->userName),
+                  0);
+
+        std::memset(userInfo->userName, 0, sizeof(userInfo->userName));
+        std::memcpy(userInfo->userName,
+                    static_cast<const void*>(userName.data()), userName.size());
+
+        ipmiRenameUserEntryPassword(oldUser, userName);
+        userInfo->userInSystem = true;
+    }
+    else if (!validUser)
+    {
+        return ccInvalidFieldRequest;
+    }
+    try
+    {
+        writeUserData();
+    }
+    catch (const std::exception& e)
+    {
+        lg2::debug("Write user data failed");
+        return ccUnspecifiedError;
+    }
+    return ccSuccess;
+}
+
+static constexpr const char* jsonUserName = "user_name";
+static constexpr const char* jsonPriv = "privilege";
+static constexpr const char* jsonIpmiEnabled = "ipmi_enabled";
+static constexpr const char* jsonLinkAuthEnabled = "link_auth_enabled";
+static constexpr const char* jsonAccCallbk = "access_callback";
+static constexpr const char* jsonUserEnabled = "user_enabled";
+static constexpr const char* jsonUserInSys = "user_in_system";
+static constexpr const char* jsonFixedUser = "fixed_user_name";
+static constexpr const char* payloadEnabledStr = "payload_enabled";
+static constexpr const char* stdPayloadStr = "std_payload";
+static constexpr const char* oemPayloadStr = "OEM_payload";
+
+/** @brief to construct a JSON object from the given payload access details.
+ *
+ *  @param[in] stdPayload - stdPayloadEnables1 in a 2D-array. (input)
+ *  @param[in] oemPayload - oemPayloadEnables1 in a 2D-array. (input)
+ *
+ *  @details Sample output JSON object format :
+ *  "payload_enabled":{
+ *  "OEM_payload0":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload1":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload2":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload3":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload4":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload5":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload6":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "OEM_payload7":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload0":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload1":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload2":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload3":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload4":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload5":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload6":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  "std_payload7":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ *  }
+ */
+static const Json constructJsonPayloadEnables(
+    const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+        stdPayload,
+    const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+        oemPayload)
+{
+    Json jsonPayloadEnabled;
+
+    for (auto payloadNum = 0; payloadNum < payloadsPerByte; payloadNum++)
+    {
+        std::ostringstream stdPayloadStream;
+        std::ostringstream oemPayloadStream;
+
+        stdPayloadStream << stdPayloadStr << payloadNum;
+        oemPayloadStream << oemPayloadStr << payloadNum;
+
+        jsonPayloadEnabled.push_back(Json::object_t::value_type(
+            stdPayloadStream.str(), stdPayload[payloadNum]));
+
+        jsonPayloadEnabled.push_back(Json::object_t::value_type(
+            oemPayloadStream.str(), oemPayload[payloadNum]));
+    }
+    return jsonPayloadEnabled;
+}
+
+void UserAccess::readPayloadAccessFromUserInfo(
+    const UserInfo& userInfo,
+    std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& stdPayload,
+    std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& oemPayload)
+{
+    for (auto payloadNum = 0; payloadNum < payloadsPerByte; payloadNum++)
+    {
+        for (auto chIndex = 0; chIndex < ipmiMaxChannels; chIndex++)
+        {
+            stdPayload[payloadNum][chIndex] =
+                userInfo.payloadAccess[chIndex].stdPayloadEnables1[payloadNum];
+
+            oemPayload[payloadNum][chIndex] =
+                userInfo.payloadAccess[chIndex].oemPayloadEnables1[payloadNum];
+        }
+    }
+}
+
+void UserAccess::updatePayloadAccessInUserInfo(
+    const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+        stdPayload,
+    const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&,
+    UserInfo& userInfo)
+{
+    for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+    {
+        // Ensure that reserved/unsupported payloads are marked to zero.
+        userInfo.payloadAccess[chIndex].stdPayloadEnables1.reset();
+        userInfo.payloadAccess[chIndex].oemPayloadEnables1.reset();
+        userInfo.payloadAccess[chIndex].stdPayloadEnables2Reserved.reset();
+        userInfo.payloadAccess[chIndex].oemPayloadEnables2Reserved.reset();
+        // Update SOL status as it is the only supported payload currently.
+        userInfo.payloadAccess[chIndex]
+            .stdPayloadEnables1[static_cast<uint8_t>(ipmi::PayloadType::SOL)] =
+            stdPayload[static_cast<uint8_t>(ipmi::PayloadType::SOL)][chIndex];
+    }
+}
+
+void UserAccess::readUserData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+
+    std::ifstream iUsrData(ipmiUserDataFile, std::ios::in | std::ios::binary);
+    if (!iUsrData.good())
+    {
+        lg2::error("Error in reading IPMI user data file");
+        throw std::ios_base::failure("Error opening IPMI user data file");
+    }
+
+    Json jsonUsersTbl = Json::array();
+    jsonUsersTbl = Json::parse(iUsrData, nullptr, false);
+
+    if (jsonUsersTbl.size() != ipmiMaxUsers)
+    {
+        lg2::error("Error in reading IPMI user data file - User count issues");
+        throw std::runtime_error(
+            "Corrupted IPMI user data file - invalid user count");
+    }
+
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        Json userInfo = jsonUsersTbl[usrIndex - 1]; // json array starts with 0.
+        if (userInfo.is_null())
+        {
+            lg2::error("Error in reading IPMI user data file - "
+                       "user info corrupted");
+            throw std::runtime_error(
+                "Corrupted IPMI user data file - invalid user info");
+        }
+        std::string userName = userInfo[jsonUserName].get<std::string>();
+        std::strncpy(reinterpret_cast<char*>(usersTbl.user[usrIndex].userName),
+                     userName.c_str(), ipmiMaxUserName);
+
+        std::vector<std::string> privilege =
+            userInfo[jsonPriv].get<std::vector<std::string>>();
+        std::vector<bool> ipmiEnabled =
+            userInfo[jsonIpmiEnabled].get<std::vector<bool>>();
+        std::vector<bool> linkAuthEnabled =
+            userInfo[jsonLinkAuthEnabled].get<std::vector<bool>>();
+        std::vector<bool> accessCallback =
+            userInfo[jsonAccCallbk].get<std::vector<bool>>();
+
+        // Payload Enables Processing.
+        std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>
+            stdPayload = {};
+        std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>
+            oemPayload = {};
+        try
+        {
+            const auto jsonPayloadEnabled = userInfo.at(payloadEnabledStr);
+            for (auto payloadNum = 0; payloadNum < payloadsPerByte;
+                 payloadNum++)
+            {
+                std::ostringstream stdPayloadStream;
+                std::ostringstream oemPayloadStream;
+
+                stdPayloadStream << stdPayloadStr << payloadNum;
+                oemPayloadStream << oemPayloadStr << payloadNum;
+
+                stdPayload[payloadNum] =
+                    jsonPayloadEnabled[stdPayloadStream.str()]
+                        .get<std::array<bool, ipmiMaxChannels>>();
+                oemPayload[payloadNum] =
+                    jsonPayloadEnabled[oemPayloadStream.str()]
+                        .get<std::array<bool, ipmiMaxChannels>>();
+
+                if (stdPayload[payloadNum].size() != ipmiMaxChannels ||
+                    oemPayload[payloadNum].size() != ipmiMaxChannels)
+                {
+                    lg2::error("Error in reading IPMI user data file - "
+                               "payload properties corrupted");
+                    throw std::runtime_error(
+                        "Corrupted IPMI user data file - payload properties");
+                }
+            }
+        }
+        catch (const Json::out_of_range& e)
+        {
+            // Key not found in 'userInfo'; possibly an old JSON file. Use
+            // default values for all payloads, and SOL payload default is true.
+            stdPayload[static_cast<uint8_t>(ipmi::PayloadType::SOL)].fill(true);
+        }
+
+        if (privilege.size() != ipmiMaxChannels ||
+            ipmiEnabled.size() != ipmiMaxChannels ||
+            linkAuthEnabled.size() != ipmiMaxChannels ||
+            accessCallback.size() != ipmiMaxChannels)
+        {
+            lg2::error("Error in reading IPMI user data file - "
+                       "properties corrupted");
+            throw std::runtime_error(
+                "Corrupted IPMI user data file - properties");
+        }
+        for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+        {
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].privilege =
+                static_cast<uint8_t>(
+                    convertToIPMIPrivilege(privilege[chIndex]));
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].ipmiEnabled =
+                ipmiEnabled[chIndex];
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].linkAuthEnabled =
+                linkAuthEnabled[chIndex];
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].accessCallback =
+                accessCallback[chIndex];
+        }
+        updatePayloadAccessInUserInfo(stdPayload, oemPayload,
+                                      usersTbl.user[usrIndex]);
+        usersTbl.user[usrIndex].userEnabled =
+            userInfo[jsonUserEnabled].get<bool>();
+        usersTbl.user[usrIndex].userInSystem =
+            userInfo[jsonUserInSys].get<bool>();
+        usersTbl.user[usrIndex].fixedUserName =
+            userInfo[jsonFixedUser].get<bool>();
+    }
+
+    lg2::debug("User data read from IPMI data file");
+    iUsrData.close();
+    // Update the timestamp
+    fileLastUpdatedTime = getUpdatedFileTime();
+    return;
+}
+
+void UserAccess::writeUserData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+
+    Json jsonUsersTbl = Json::array();
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        Json jsonUserInfo;
+        jsonUserInfo[jsonUserName] = std::string(
+            reinterpret_cast<char*>(usersTbl.user[usrIndex].userName), 0,
+            ipmiMaxUserName);
+        std::vector<std::string> privilege(ipmiMaxChannels);
+        std::vector<bool> ipmiEnabled(ipmiMaxChannels);
+        std::vector<bool> linkAuthEnabled(ipmiMaxChannels);
+        std::vector<bool> accessCallback(ipmiMaxChannels);
+
+        std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>
+            stdPayload;
+        std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>
+            oemPayload;
+
+        for (size_t chIndex = 0; chIndex < ipmiMaxChannels; chIndex++)
+        {
+            privilege[chIndex] =
+                convertToSystemPrivilege(static_cast<CommandPrivilege>(
+                    usersTbl.user[usrIndex].userPrivAccess[chIndex].privilege));
+            ipmiEnabled[chIndex] =
+                usersTbl.user[usrIndex].userPrivAccess[chIndex].ipmiEnabled;
+            linkAuthEnabled[chIndex] =
+                usersTbl.user[usrIndex].userPrivAccess[chIndex].linkAuthEnabled;
+            accessCallback[chIndex] =
+                usersTbl.user[usrIndex].userPrivAccess[chIndex].accessCallback;
+        }
+        jsonUserInfo[jsonPriv] = privilege;
+        jsonUserInfo[jsonIpmiEnabled] = ipmiEnabled;
+        jsonUserInfo[jsonLinkAuthEnabled] = linkAuthEnabled;
+        jsonUserInfo[jsonAccCallbk] = accessCallback;
+        jsonUserInfo[jsonUserEnabled] = usersTbl.user[usrIndex].userEnabled;
+        jsonUserInfo[jsonUserInSys] = usersTbl.user[usrIndex].userInSystem;
+        jsonUserInfo[jsonFixedUser] = usersTbl.user[usrIndex].fixedUserName;
+
+        readPayloadAccessFromUserInfo(usersTbl.user[usrIndex], stdPayload,
+                                      oemPayload);
+        Json jsonPayloadEnabledInfo =
+            constructJsonPayloadEnables(stdPayload, oemPayload);
+        jsonUserInfo[payloadEnabledStr] = jsonPayloadEnabledInfo;
+
+        jsonUsersTbl.push_back(jsonUserInfo);
+    }
+
+    static std::string tmpFile{std::string(ipmiUserDataFile) + "_tmp"};
+    int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
+                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+    if (fd < 0)
+    {
+        lg2::error("Error in creating temporary IPMI user data file");
+        throw std::ios_base::failure(
+            "Error in creating temporary IPMI user data file");
+    }
+    const auto& writeStr = jsonUsersTbl.dump();
+    if (write(fd, writeStr.c_str(), writeStr.size()) !=
+        static_cast<ssize_t>(writeStr.size()))
+    {
+        close(fd);
+        lg2::error("Error in writing temporary IPMI user data file");
+        throw std::ios_base::failure(
+            "Error in writing temporary IPMI user data file");
+    }
+    close(fd);
+
+    if (std::rename(tmpFile.c_str(), ipmiUserDataFile) != 0)
+    {
+        lg2::error("Error in renaming temporary IPMI user data file");
+        throw std::runtime_error("Error in renaming IPMI user data file");
+    }
+    // Update the timestamp
+    fileLastUpdatedTime = getUpdatedFileTime();
+    return;
+}
+
+bool UserAccess::addUserEntry(const std::string& userName,
+                              const std::string& sysPriv, const bool& enabled)
+{
+    UsersTbl* userData = getUsersTblPtr();
+    size_t freeIndex = 0xFF;
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        std::string curName(
+            reinterpret_cast<char*>(userData->user[usrIndex].userName), 0,
+            ipmiMaxUserName);
+        if (userName == curName)
+        {
+            lg2::debug("Username {USER_NAME} exists", "USER_NAME", userName);
+            return false; // user name exists.
+        }
+
+        if ((!userData->user[usrIndex].userInSystem) &&
+            (userData->user[usrIndex].userName[0] == '\0') &&
+            (freeIndex == 0xFF))
+        {
+            freeIndex = usrIndex;
+        }
+    }
+    if (freeIndex == 0xFF)
+    {
+        lg2::error("No empty slots found");
+        return false;
+    }
+    std::strncpy(reinterpret_cast<char*>(userData->user[freeIndex].userName),
+                 userName.c_str(), ipmiMaxUserName);
+    uint8_t priv =
+        static_cast<uint8_t>(UserAccess::convertToIPMIPrivilege(sysPriv)) &
+        privMask;
+    for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+    {
+        userData->user[freeIndex].userPrivAccess[chIndex].privilege = priv;
+        userData->user[freeIndex].userPrivAccess[chIndex].ipmiEnabled = true;
+        userData->user[freeIndex].userPrivAccess[chIndex].linkAuthEnabled =
+            true;
+        userData->user[freeIndex].userPrivAccess[chIndex].accessCallback = true;
+    }
+    userData->user[freeIndex].userInSystem = true;
+    userData->user[freeIndex].userEnabled = enabled;
+
+    return true;
+}
+
+void UserAccess::deleteUserIndex(const size_t& usrIdx)
+{
+    UsersTbl* userData = getUsersTblPtr();
+
+    std::string userName(
+        reinterpret_cast<char*>(userData->user[usrIdx].userName), 0,
+        ipmiMaxUserName);
+    ipmiClearUserEntryPassword(userName);
+    std::fill(static_cast<uint8_t*>(userData->user[usrIdx].userName),
+              static_cast<uint8_t*>(userData->user[usrIdx].userName) +
+                  sizeof(userData->user[usrIdx].userName),
+              0);
+    for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+    {
+        userData->user[usrIdx].userPrivAccess[chIndex].privilege = privNoAccess;
+        userData->user[usrIdx].userPrivAccess[chIndex].ipmiEnabled = false;
+        userData->user[usrIdx].userPrivAccess[chIndex].linkAuthEnabled = false;
+        userData->user[usrIdx].userPrivAccess[chIndex].accessCallback = false;
+    }
+    userData->user[usrIdx].userInSystem = false;
+    userData->user[usrIdx].userEnabled = false;
+    return;
+}
+
+void UserAccess::checkAndReloadUserData()
+{
+    std::timespec updateTime = getUpdatedFileTime();
+    if ((updateTime.tv_sec != fileLastUpdatedTime.tv_sec ||
+         updateTime.tv_nsec != fileLastUpdatedTime.tv_nsec) ||
+        (updateTime.tv_sec == 0 && updateTime.tv_nsec == 0))
+    {
+        std::fill(reinterpret_cast<uint8_t*>(&usersTbl),
+                  reinterpret_cast<uint8_t*>(&usersTbl) + sizeof(usersTbl), 0);
+        readUserData();
+    }
+    return;
+}
+
+UsersTbl* UserAccess::getUsersTblPtr()
+{
+    // reload data before using it.
+    checkAndReloadUserData();
+    return &usersTbl;
+}
+
+void UserAccess::getSystemPrivAndGroups()
+{
+    std::map<std::string, PrivAndGroupType> properties;
+    try
+    {
+        auto method = bus.new_method_call(userMgrService, userMgrObjBasePath,
+                                          dBusPropertiesInterface,
+                                          getAllPropertiesMethod);
+        method.append(userMgrInterface);
+
+        auto reply = bus.call(method);
+        reply.read(properties);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::debug("Failed to excute {METHOD}, path: {PATH}", "METHOD",
+                   getAllPropertiesMethod, "PATH", userMgrObjBasePath);
+        return;
+    }
+    for (const auto& t : properties)
+    {
+        auto key = t.first;
+        if (key == allPrivProperty)
+        {
+            availablePrivileges = std::get<std::vector<std::string>>(t.second);
+        }
+        else if (key == allGrpProperty)
+        {
+            availableGroups = std::get<std::vector<std::string>>(t.second);
+        }
+    }
+    // TODO: Implement Supported Privilege & Groups verification logic
+    return;
+}
+
+std::timespec UserAccess::getUpdatedFileTime()
+{
+    struct stat fileStat;
+    if (stat(ipmiUserDataFile, &fileStat) != 0)
+    {
+        lg2::debug("Error in getting last updated time stamp");
+        return std::timespec{0, 0};
+    }
+    return fileStat.st_mtim;
+}
+
+void UserAccess::getUserProperties(const DbusUserObjProperties& properties,
+                                   std::vector<std::string>& usrGrps,
+                                   std::string& usrPriv, bool& usrEnabled)
+{
+    for (const auto& t : properties)
+    {
+        std::string key = t.first;
+        if (key == userPrivProperty)
+        {
+            usrPriv = std::get<std::string>(t.second);
+        }
+        else if (key == userGrpProperty)
+        {
+            usrGrps = std::get<std::vector<std::string>>(t.second);
+        }
+        else if (key == userEnabledProperty)
+        {
+            usrEnabled = std::get<bool>(t.second);
+        }
+    }
+    return;
+}
+
+int UserAccess::getUserObjProperties(const DbusUserObjValue& userObjs,
+                                     std::vector<std::string>& usrGrps,
+                                     std::string& usrPriv, bool& usrEnabled)
+{
+    auto usrObj = userObjs.find(usersInterface);
+    if (usrObj != userObjs.end())
+    {
+        getUserProperties(usrObj->second, usrGrps, usrPriv, usrEnabled);
+        return 0;
+    }
+    return -EIO;
+}
+
+void UserAccess::cacheUserDataFile()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    try
+    {
+        readUserData();
+    }
+    catch (const std::ios_base::failure& e)
+    { // File is empty, create it for the first time
+        std::fill(reinterpret_cast<uint8_t*>(&usersTbl),
+                  reinterpret_cast<uint8_t*>(&usersTbl) + sizeof(usersTbl), 0);
+        // user index 0 is reserved, starts with 1
+        for (size_t userIndex = 1; userIndex <= ipmiMaxUsers; ++userIndex)
+        {
+            for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+            {
+                usersTbl.user[userIndex].userPrivAccess[chIndex].privilege =
+                    privNoAccess;
+                usersTbl.user[userIndex]
+                    .payloadAccess[chIndex]
+                    .stdPayloadEnables1[static_cast<uint8_t>(
+                        ipmi::PayloadType::SOL)] = true;
+            }
+        }
+        writeUserData();
+    }
+    // Create lock file if it does not exist
+    int fd = open(ipmiUserSignalLockFile, O_CREAT | O_TRUNC | O_SYNC,
+                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+    if (fd < 0)
+    {
+        lg2::error("Error in creating IPMI user signal lock file");
+        throw std::ios_base::failure(
+            "Error in creating temporary IPMI user signal lock file");
+    }
+    close(fd);
+
+    sigHndlrLock = boost::interprocess::file_lock(ipmiUserSignalLockFile);
+    // Register it for single object and single process either netipmid /
+    // host-ipmid
+    if (userUpdatedSignal == nullptr && sigHndlrLock.try_lock())
+    {
+        lg2::debug("Registering signal handler");
+        userUpdatedSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::interface(dBusObjManager) +
+                sdbusplus::bus::match::rules::path(userMgrObjBasePath),
+            [&](sdbusplus::message_t& msg) {
+                userUpdatedSignalHandler(*this, msg);
+            });
+        userMgrRenamedSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::interface(userMgrInterface) +
+                sdbusplus::bus::match::rules::path(userMgrObjBasePath),
+            [&](sdbusplus::message_t& msg) {
+                userUpdatedSignalHandler(*this, msg);
+            });
+        userPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::path_namespace(userObjBasePath) +
+                sdbusplus::bus::match::rules::interface(
+                    dBusPropertiesInterface) +
+                sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
+                sdbusplus::bus::match::rules::argN(0, usersInterface),
+            [&](sdbusplus::message_t& msg) {
+                userUpdatedSignalHandler(*this, msg);
+            });
+        signalHndlrObject = true;
+    }
+    std::map<DbusUserObjPath, DbusUserObjValue> managedObjs;
+    try
+    {
+        auto method =
+            bus.new_method_call(userMgrService, userMgrObjBasePath,
+                                dBusObjManager, getManagedObjectsMethod);
+        auto reply = bus.call(method);
+        reply.read(managedObjs);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::debug("Failed to excute {METHOD}, path: {PATH}", "METHOD",
+                   getManagedObjectsMethod, "PATH", userMgrObjBasePath);
+        return;
+    }
+    bool updateRequired = false;
+    UsersTbl* userData = &usersTbl;
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIdx = 1; usrIdx <= ipmiMaxUsers; ++usrIdx)
+    {
+        if ((userData->user[usrIdx].userInSystem) &&
+            (userData->user[usrIdx].userName[0] != '\0'))
+        {
+            std::vector<std::string> usrGrps;
+            std::string usrPriv;
+
+            std::string userName(
+                reinterpret_cast<char*>(userData->user[usrIdx].userName), 0,
+                ipmiMaxUserName);
+            sdbusplus::message::object_path tempUserPath(userObjBasePath);
+            tempUserPath /= userName;
+            std::string usersPath(tempUserPath);
+
+            auto usrObj = managedObjs.find(usersPath);
+            if (usrObj != managedObjs.end())
+            {
+                bool usrEnabled = false;
+
+                // User exist. Lets check and update other fileds
+                getUserObjProperties(usrObj->second, usrGrps, usrPriv,
+                                     usrEnabled);
+                if (std::find(usrGrps.begin(), usrGrps.end(), ipmiGrpName) ==
+                    usrGrps.end())
+                {
+                    updateRequired = true;
+                    // Group "ipmi" is removed so lets remove user in IPMI
+                    deleteUserIndex(usrIdx);
+                }
+                else
+                {
+                    // Group "ipmi" is present so lets update other properties
+                    // in IPMI
+                    uint8_t priv = UserAccess::convertToIPMIPrivilege(usrPriv) &
+                                   privMask;
+                    // Update all channels priv, only if it is not equivalent to
+                    // getUsrMgmtSyncIndex()
+                    if (userData->user[usrIdx]
+                            .userPrivAccess[getUsrMgmtSyncIndex()]
+                            .privilege != priv)
+                    {
+                        updateRequired = true;
+                        for (size_t chIndex = 0; chIndex < ipmiMaxChannels;
+                             ++chIndex)
+                        {
+                            userData->user[usrIdx]
+                                .userPrivAccess[chIndex]
+                                .privilege = priv;
+                        }
+                    }
+                    if (userData->user[usrIdx].userEnabled != usrEnabled)
+                    {
+                        updateRequired = true;
+                        userData->user[usrIdx].userEnabled = usrEnabled;
+                    }
+                }
+
+                // We are done with this obj. lets delete from MAP
+                managedObjs.erase(usrObj);
+            }
+            else
+            {
+                updateRequired = true;
+                deleteUserIndex(usrIdx);
+            }
+        }
+    }
+
+    // Walk through remnaining managedObj users list
+    // Add them to ipmi data base
+    for (const auto& usrObj : managedObjs)
+    {
+        std::vector<std::string> usrGrps;
+        std::string usrPriv, userName;
+        bool usrEnabled = false;
+        std::string usrObjPath = std::string(usrObj.first);
+        if (getUserNameFromPath(usrObj.first.str, userName) != 0)
+        {
+            lg2::error("Error in user object path");
+            continue;
+        }
+        getUserObjProperties(usrObj.second, usrGrps, usrPriv, usrEnabled);
+        // Add 'ipmi' group users
+        if (std::find(usrGrps.begin(), usrGrps.end(), ipmiGrpName) !=
+            usrGrps.end())
+        {
+            updateRequired = true;
+            // CREATE NEW USER
+            if (true != addUserEntry(userName, usrPriv, usrEnabled))
+            {
+                break;
+            }
+        }
+    }
+
+    if (updateRequired)
+    {
+        // All userData slots update done. Lets write the data
+        writeUserData();
+    }
+
+    return;
+}
+} // namespace ipmi
diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp
new file mode 100644
index 0000000..74166c2
--- /dev/null
+++ b/user_channel/user_mgmt.hpp
@@ -0,0 +1,406 @@
+/*.
+// Copyright (c) 2018 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.
+*/
+#pragma once
+#include "user_layer.hpp"
+
+#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/interprocess/sync/named_recursive_mutex.hpp>
+#include <ipmid/api.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <cstdint>
+#include <ctime>
+#include <variant>
+
+namespace ipmi
+{
+
+using DbusUserPropVariant =
+    std::variant<std::vector<std::string>, std::string, bool>;
+
+using DbusUserObjPath = sdbusplus::message::object_path;
+
+using DbusUserObjProperties =
+    std::vector<std::pair<std::string, DbusUserPropVariant>>;
+
+using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>;
+
+/**
+ * @enum User update events.
+ */
+enum class UserUpdateEvent
+{
+    reservedEvent,
+    userCreated,
+    userDeleted,
+    userRenamed,
+    userGrpUpdated,
+    userPrivUpdated,
+    userStateUpdated
+};
+
+/** @struct UserPrivAccess
+ *
+ *  Structure for user privilege access (refer spec sec 22.22)
+ */
+struct UserPrivAccess
+{
+    uint8_t privilege;
+    bool ipmiEnabled;
+    bool linkAuthEnabled;
+    bool accessCallback;
+};
+
+/** @struct UserInfo
+ *
+ *  Structure for user related information
+ */
+struct UserInfo
+{
+    uint8_t userName[ipmiMaxUserName];
+    UserPrivAccess userPrivAccess[ipmiMaxChannels];
+    bool userEnabled;
+    bool userInSystem;
+    bool fixedUserName;
+    PayloadAccess payloadAccess[ipmiMaxChannels];
+};
+
+/** @struct UsersTbl
+ *
+ *  Structure for array of user related information
+ */
+struct UsersTbl
+{
+    //+1 to map with UserId directly. UserId 0 is reserved.
+    UserInfo user[ipmiMaxUsers + 1];
+};
+
+/** @brief PAM User Authentication check
+ *
+ *  @param[in] username - username in string
+ *  @param[in] password	- password in string
+ *
+ *  @return status
+ */
+bool pamUserCheckAuthenticate(std::string_view username,
+                              std::string_view password);
+
+class UserAccess;
+
+UserAccess& getUserAccessObject();
+
+class UserAccess
+{
+  public:
+    UserAccess(const UserAccess&) = delete;
+    UserAccess& operator=(const UserAccess&) = delete;
+    UserAccess(UserAccess&&) = delete;
+    UserAccess& operator=(UserAccess&&) = delete;
+
+    ~UserAccess();
+    UserAccess();
+
+    /** @brief determines valid channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return true if valid, false otherwise
+     */
+    static bool isValidChannel(const uint8_t chNum);
+
+    /** @brief determines valid userId
+     *
+     *  @param[in] userId - user id
+     *
+     *  @return true if valid, false otherwise
+     */
+    static bool isValidUserId(const uint8_t userId);
+
+    /** @brief determines valid user privilege
+     *
+     *  @param[in] priv - Privilege
+     *
+     *  @return true if valid, false otherwise
+     */
+    static bool isValidPrivilege(const uint8_t priv);
+
+    /** @brief determines sync index to be mapped with common-user-management
+     *
+     *  @return Index which will be used as sync index
+     */
+    static uint8_t getUsrMgmtSyncIndex();
+
+    /** @brief Converts system privilege to IPMI privilege
+     *
+     *  @param[in] value - Privilege in string
+     *
+     *  @return CommandPrivilege - IPMI privilege type
+     */
+    static CommandPrivilege convertToIPMIPrivilege(const std::string& value);
+
+    /** @brief Converts IPMI privilege to system privilege
+     *
+     *  @param[in] value - IPMI privilege
+     *
+     *  @return System privilege in string
+     */
+    static std::string convertToSystemPrivilege(const CommandPrivilege& value);
+
+    /** @brief determines whether user name is valid
+     *
+     *  @param[in] userNameInChar - user name
+     *
+     *  @return true if valid, false otherwise
+     */
+    bool isValidUserName(const std::string& userName);
+
+    /** @brief determines whether ipmi is in available groups list
+     *
+     * @return true if ipmi group is present, false otherwise
+     */
+    bool isIpmiInAvailableGroupList();
+
+    /** @brief provides user id of the user
+     *
+     *  @param[in] userName - user name
+     *
+     *  @return user id of the user, else invalid user id (0xFF), if user not
+     * found
+     */
+    uint8_t getUserId(const std::string& userName);
+
+    /** @brief provides user information
+     *
+     *  @param[in] userId - user id
+     *
+     *  @return UserInfo for the specified user id
+     */
+    UserInfo* getUserInfo(const uint8_t userId);
+
+    /** @brief sets user information
+     *
+     *  @param[in] userId - user id
+     *  @param[in] userInfo - user information
+     *
+     */
+    void setUserInfo(const uint8_t userId, UserInfo* userInfo);
+
+    /** @brief provides user name
+     *
+     *  @param[in] userId - user id
+     *  @param[out] userName - user name
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc getUserName(const uint8_t userId, std::string& userName);
+
+    /** @brief to set user name
+     *
+     *  @param[in] userId - user id
+     *  @param[in] userName - user name
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setUserName(const uint8_t userId, const std::string& userName);
+
+    /** @brief to set user enabled state
+     *
+     *  @param[in] userId - user id
+     *  @param[in] enabledState - enabled state of the user
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setUserEnabledState(const uint8_t userId, const bool& enabledState);
+
+    /** @brief to set user password
+     *
+     *  @param[in] userId - user id
+     *  @param[in] userPassword  - new password of the user
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setUserPassword(const uint8_t userId, const char* userPassword);
+
+    /** @brief to set special user password
+     *
+     *  @param[in] userName - user name
+     *  @param[in] userPassword  - new password of the user
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setSpecialUserPassword(const std::string& userName,
+                              const SecureString& userPassword);
+
+    /** @brief to set user privilege and access details
+     *
+     *  @param[in] userId - user id
+     *  @param[in] chNum - channel number
+     *  @param[in] privAccess - privilege access
+     *  @param[in] otherPrivUpdates - other privilege update flag to update ipmi
+     * enable, link authentication and access callback
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
+                              const UserPrivAccess& privAccess,
+                              const bool& otherPrivUpdates);
+
+    /** @brief to get user payload access details from userInfo entry.
+     *
+     *  @param[in] userInfo    - userInfo entry in usersTbl.
+     *  @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
+     *  @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
+     *
+     *  @details Update the given 2D-arrays using the payload access details
+     *  available in the given userInfo entry (from usersTbl).
+     *  This 2D-array will be mapped to a JSON object (which will be written to
+     *  a JSON file subsequently).
+     */
+    void readPayloadAccessFromUserInfo(
+        const UserInfo& userInfo,
+        std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+            stdPayload,
+        std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+            oemPayload);
+
+    /** @brief to update user payload access details in userInfo entry.
+     *
+     *  @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
+     *  @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
+     *  @param[out] userInfo  - userInfo entry in usersTbl.
+     *
+     *  @details Update user payload access details of a given userInfo
+     *  entry (in usersTbl) with the information provided in given 2D-arrays.
+     *  This 2D-array was created out of a JSON object (which was created by
+     *  parsing a JSON file).
+     */
+    void updatePayloadAccessInUserInfo(
+        const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+            stdPayload,
+        const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+            oemPayload,
+        UserInfo& userInfo);
+
+    /** @brief to set user payload access details
+     *
+     *  @param[in] chNum - channel number
+     *  @param[in] operation - Enable / Disable
+     *  @param[in] userId - user id
+     *  @param[in] payloadAccess - payload access
+     *
+     *  @return ccSuccess for success, others for failure.
+     */
+    Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
+                            const uint8_t userId,
+                            const PayloadAccess& payloadAccess);
+
+    /** @brief reads user management related data from configuration file
+     *
+     */
+    void readUserData();
+
+    /** @brief writes user management related data to configuration file
+     *
+     */
+    void writeUserData();
+
+    /** @brief Funtion which checks and reload configuration file data if
+     * needed.
+     *
+     */
+    void checkAndReloadUserData();
+
+    /** @brief provides user details from D-Bus user property data
+     *
+     *  @param[in] properties - D-Bus user property
+     *  @param[out] usrGrps - user group details
+     *  @param[out] usrPriv - user privilege
+     *  @param[out] usrEnabled - enabled state of the user.
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    void getUserProperties(const DbusUserObjProperties& properties,
+                           std::vector<std::string>& usrGrps,
+                           std::string& usrPriv, bool& usrEnabled);
+
+    /** @brief provides user details from D-Bus user object data
+     *
+     *  @param[in] userObjs - D-Bus user object
+     *  @param[out] usrGrps - user group details
+     *  @param[out] usrPriv - user privilege
+     *  @param[out] usrEnabled - enabled state of the user.
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int getUserObjProperties(const DbusUserObjValue& userObjs,
+                             std::vector<std::string>& usrGrps,
+                             std::string& usrPriv, bool& usrEnabled);
+
+    /** @brief function to add user entry information to the configuration
+     *
+     *  @param[in] userName - user name
+     *  @param[in] priv - privilege of the user
+     *  @param[in] enabled - enabled state of the user
+     *
+     *  @return true for success, false for failure
+     */
+    bool addUserEntry(const std::string& userName, const std::string& priv,
+                      const bool& enabled);
+
+    /** @brief function to delete user entry based on user index
+     *
+     *  @param[in] usrIdx - user index
+     *
+     */
+    void deleteUserIndex(const size_t& usrIdx);
+
+    /** @brief function to get users table
+     *
+     */
+    UsersTbl* getUsersTblPtr();
+
+    std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
+        nullptr};
+
+  private:
+    UsersTbl usersTbl;
+    std::vector<std::string> availablePrivileges;
+    std::vector<std::string> availableGroups;
+    sdbusplus::bus_t bus;
+    std::timespec fileLastUpdatedTime;
+    bool signalHndlrObject = false;
+    boost::interprocess::file_lock sigHndlrLock;
+    boost::interprocess::file_lock mutexCleanupLock;
+
+    /** @brief function to get user configuration file timestamp
+     *
+     *  @return time stamp or -EIO for failure
+     */
+    std::timespec getUpdatedFileTime();
+
+    /** @brief function to available system privileges and groups
+     *
+     */
+    void getSystemPrivAndGroups();
+
+    /** @brief function to init user data from configuration & D-Bus objects
+     * and to register for signals
+     *
+     */
+    void cacheUserDataFile();
+};
+
+} // namespace ipmi
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp
new file mode 100644
index 0000000..3e1b3ca
--- /dev/null
+++ b/user_channel/usercommands.cpp
@@ -0,0 +1,679 @@
+/*
+// Copyright (c) 2018 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 "usercommands.hpp"
+
+#include "channel_layer.hpp"
+#include "user_layer.hpp"
+
+#include <security/pam_appl.h>
+
+#include <ipmid/api.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <regex>
+
+namespace ipmi
+{
+
+static constexpr uint8_t enableOperation = 0x00;
+static constexpr uint8_t disableOperation = 0x01;
+
+/** @brief implements the set user access command
+ *  @param ctx - IPMI context pointer (for channel)
+ *  @param channel - channel number
+ *  @param ipmiEnabled - indicates ipmi messaging state
+ *  @param linkAuthEnabled - indicates link authentication state
+ *  @param accessCallback - indicates callback state
+ *  @param bitsUpdate - indicates update request
+ *  @param userId - user id
+ *  @param reserved1 - skip 2 bits
+ *  @param privilege - user privilege
+ *  @param reserved2 - skip 4 bits
+ *  @param sessionLimit - optional - unused for now
+ *
+ *  @returns ipmi completion code
+ */
+ipmi::RspType<> ipmiSetUserAccess(
+    ipmi::Context::ptr ctx, uint4_t channel, uint1_t ipmiEnabled,
+    uint1_t linkAuthEnabled, uint1_t accessCallback, uint1_t bitsUpdate,
+
+    uint6_t userId, uint2_t reserved1,
+
+    uint4_t privilege, uint4_t reserved2,
+
+    std::optional<uint8_t> sessionLimit)
+{
+    uint8_t sessLimit = sessionLimit.value_or(0);
+    if (reserved1 || reserved2 || sessLimit ||
+        !ipmiUserIsValidPrivilege(static_cast<uint8_t>(privilege)))
+    {
+        lg2::debug("Set user access - Invalid field in request");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    if (!isValidChannel(chNum))
+    {
+        lg2::debug("Set user access - Invalid channel request");
+        return ipmi::response(invalidChannel);
+    }
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Set user access - No support on channel");
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
+    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
+    {
+        lg2::debug("Set user access - Parameter out of range");
+        return ipmi::responseParmOutOfRange();
+    }
+
+    PrivAccess privAccess = {};
+    if (bitsUpdate)
+    {
+        privAccess.ipmiEnabled = static_cast<uint8_t>(ipmiEnabled);
+        privAccess.linkAuthEnabled = static_cast<uint8_t>(linkAuthEnabled);
+        privAccess.accessCallback = static_cast<uint8_t>(accessCallback);
+    }
+    privAccess.privilege = static_cast<uint8_t>(privilege);
+    return ipmi::response(
+        ipmiUserSetPrivilegeAccess(static_cast<uint8_t>(userId), chNum,
+                                   privAccess, static_cast<bool>(bitsUpdate)));
+}
+
+/** @brief implements the set user access command
+ *  @param ctx - IPMI context pointer (for channel)
+ *  @param channel - channel number
+ *  @param reserved1 - skip 4 bits
+ *  @param userId - user id
+ *  @param reserved2 - skip 2 bits
+ *
+ *  @returns ipmi completion code plus response data
+ *   - maxChUsers - max channel users
+ *   - reserved1 - skip 2 bits
+ *   - enabledUsers - enabled users count
+ *   - enabledStatus - enabled status
+ *   - fixedUsers - fixed users count
+ *   - reserved2 - skip 2 bits
+ *   - privilege - user privilege
+ *   - ipmiEnabled - ipmi messaging state
+ *   - linkAuthEnabled - link authenticatin state
+ *   - accessCallback - callback state
+ *   - reserved - skip 1 bit
+ */
+ipmi::RspType<uint6_t, // max channel users
+              uint2_t, // reserved1
+
+              uint6_t, // enabled users count
+              uint2_t, // enabled status
+
+              uint6_t, // fixed users count
+              uint2_t, // reserved2
+
+              uint4_t, // privilege
+              uint1_t, // ipmi messaging state
+              uint1_t, // link authentication state
+              uint1_t, // access callback state
+              uint1_t  // reserved3
+              >
+    ipmiGetUserAccess(ipmi::Context::ptr ctx, uint4_t channel,
+                      uint4_t reserved1,
+
+                      uint6_t userId, uint2_t reserved2)
+{
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+
+    if (reserved1 || reserved2 || !isValidChannel(chNum))
+    {
+        lg2::debug("Get user access - Invalid field in request");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        lg2::debug("Get user access - No support on channel");
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
+    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
+    {
+        lg2::debug("Get user access - Parameter out of range");
+        return ipmi::responseParmOutOfRange();
+    }
+
+    uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0;
+    ipmi::Cc retStatus;
+    retStatus = ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers);
+    if (retStatus != ccSuccess)
+    {
+        return ipmi::response(retStatus);
+    }
+
+    bool enabledState = false;
+    retStatus =
+        ipmiUserCheckEnabled(static_cast<uint8_t>(userId), enabledState);
+    if (retStatus != ccSuccess)
+    {
+        return ipmi::response(retStatus);
+    }
+
+    uint2_t enabledStatus = enabledState ? userIdEnabledViaSetPassword
+                                         : userIdDisabledViaSetPassword;
+    PrivAccess privAccess{};
+    retStatus = ipmiUserGetPrivilegeAccess(static_cast<uint8_t>(userId), chNum,
+                                           privAccess);
+    if (retStatus != ccSuccess)
+    {
+        return ipmi::response(retStatus);
+    }
+    constexpr uint2_t res2Bits = 0;
+    return ipmi::responseSuccess(
+        static_cast<uint6_t>(maxChUsers), res2Bits,
+
+        static_cast<uint6_t>(enabledUsers), enabledStatus,
+
+        static_cast<uint6_t>(fixedUsers), res2Bits,
+
+        static_cast<uint4_t>(privAccess.privilege),
+        static_cast<uint1_t>(privAccess.ipmiEnabled),
+        static_cast<uint1_t>(privAccess.linkAuthEnabled),
+        static_cast<uint1_t>(privAccess.accessCallback),
+        static_cast<uint1_t>(privAccess.reserved));
+}
+
+/** @brief implementes the get user name command
+ *  @param[in] ctx - ipmi command context
+ *  @param[in] userId - 6-bit user ID
+ *  @param[in] reserved - 2-bits reserved
+ *  @param[in] name - 16-byte array for username
+
+ *  @returns ipmi response
+ */
+ipmi::RspType<> ipmiSetUserName(
+    [[maybe_unused]] ipmi::Context::ptr ctx, uint6_t id, uint2_t reserved,
+    const std::array<uint8_t, ipmi::ipmiMaxUserName>& name)
+{
+    if (reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    uint8_t userId = static_cast<uint8_t>(id);
+    if (!ipmiUserIsValidUserId(userId))
+    {
+        lg2::debug("Set user name - Invalid user id");
+        return ipmi::responseParmOutOfRange();
+    }
+
+    size_t nameLen = strnlen(reinterpret_cast<const char*>(name.data()),
+                             ipmi::ipmiMaxUserName);
+    const std::string strUserName(reinterpret_cast<const char*>(name.data()),
+                                  nameLen);
+
+    ipmi::Cc res = ipmiUserSetUserName(userId, strUserName);
+    return ipmi::response(res);
+}
+
+/** @brief implementes the get user name command
+ *  @param[in] ctx - ipmi command context
+ *  @param[in] userId - 6-bit user ID
+ *  @param[in] reserved - 2-bits reserved
+
+ *  @returns ipmi response with 16-byte username
+ */
+ipmi::RspType<std::array<uint8_t, ipmi::ipmiMaxUserName>> // user name
+    ipmiGetUserName([[maybe_unused]] ipmi::Context::ptr ctx, uint6_t id,
+                    uint2_t reserved)
+{
+    if (reserved)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    uint8_t userId = static_cast<uint8_t>(id);
+    std::string userName;
+    if (ipmiUserGetUserName(userId, userName) != ccSuccess)
+    { // Invalid User ID
+        lg2::debug("User Name not found, user Id: {USER_ID}", "USER_ID",
+                   userId);
+        return ipmi::responseParmOutOfRange();
+    }
+    // copy the std::string into a fixed array
+    if (userName.size() > ipmi::ipmiMaxUserName)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    std::array<uint8_t, ipmi::ipmiMaxUserName> userNameFixed;
+    std::fill(userNameFixed.begin(), userNameFixed.end(), 0);
+    std::copy(userName.begin(), userName.end(), userNameFixed.begin());
+    return ipmi::responseSuccess(std::move(userNameFixed));
+}
+
+/** @brief implementes the get user name command
+ *  @param[in] ctx - ipmi command context
+ *  @param[in] userId - 6-bit user ID
+ *  @param[in] reserved - 2-bits reserved
+
+ *  @returns ipmi response with 16-byte username
+ */
+ipmi::RspType<> // user name
+    ipmiSetUserPassword([[maybe_unused]] ipmi::Context::ptr ctx, uint6_t id,
+                        bool reserved1, bool pwLen20, uint2_t operation,
+                        uint6_t reserved2, SecureBuffer& userPassword)
+{
+    if (reserved1 || reserved2)
+    {
+        lg2::debug("Invalid data field in request");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    static constexpr uint2_t opDisableUser = 0x00;
+    static constexpr uint2_t opEnableUser = 0x01;
+    static constexpr uint2_t opSetPassword = 0x02;
+    static constexpr uint2_t opTestPassword = 0x03;
+
+    // If set / test password operation then password size has to be 16 or 20
+    // bytes based on the password size bit
+    if (((operation == opSetPassword) || (operation == opTestPassword)) &&
+        ((pwLen20 && (userPassword.size() != maxIpmi20PasswordSize)) ||
+         (!pwLen20 && (userPassword.size() != maxIpmi15PasswordSize))))
+    {
+        lg2::debug("Invalid Length");
+        return ipmi::responseReqDataLenInvalid();
+    }
+
+    size_t passwordLength = userPassword.size();
+
+    uint8_t userId = static_cast<uint8_t>(id);
+    std::string userName;
+    if (ipmiUserGetUserName(userId, userName) != ccSuccess)
+    {
+        lg2::debug("User Name not found, user Id: {USER_ID}", "USER_ID",
+                   userId);
+        return ipmi::responseParmOutOfRange();
+    }
+
+    if (operation == opSetPassword)
+    {
+        // turn the non-nul terminated SecureBuffer into a SecureString
+        SecureString password(
+            reinterpret_cast<const char*>(userPassword.data()), passwordLength);
+        ipmi::Cc res = ipmiUserSetUserPassword(userId, password.data());
+        return ipmi::response(res);
+    }
+    else if (operation == opEnableUser || operation == opDisableUser)
+    {
+        ipmi::Cc res =
+            ipmiUserUpdateEnabledState(userId, static_cast<bool>(operation));
+        return ipmi::response(res);
+    }
+    else if (operation == opTestPassword)
+    {
+        SecureString password = ipmiUserGetPassword(userName);
+        // extend with zeros, if needed
+        if (password.size() < passwordLength)
+        {
+            password.resize(passwordLength, '\0');
+        }
+        SecureString testPassword(
+            reinterpret_cast<const char*>(userPassword.data()), passwordLength);
+        // constant time string compare: always compare exactly as many bytes
+        // as the length of the input, resizing the actual password to match,
+        // maintaining a knowledge if the sizes differed originally
+        static const std::array<char, maxIpmi20PasswordSize> empty = {'\0'};
+        size_t cmpLen = testPassword.size();
+        bool pwLenDiffers = password.size() != cmpLen;
+        const char* cmpPassword = nullptr;
+        if (pwLenDiffers)
+        {
+            cmpPassword = empty.data();
+        }
+        else
+        {
+            cmpPassword = password.data();
+        }
+        bool pwBad = CRYPTO_memcmp(cmpPassword, testPassword.data(), cmpLen);
+        pwBad |= pwLenDiffers;
+        if (pwBad)
+        {
+            lg2::debug("Test password failed, user Id: {USER_ID}", "USER_ID",
+                       userId);
+            return ipmi::response(ipmiCCPasswdFailMismatch);
+        }
+        return ipmi::responseSuccess();
+    }
+    return ipmi::responseInvalidFieldRequest();
+}
+
+/** @brief implements the get channel authentication command
+ *  @param ctx - IPMI context pointer (for channel)
+ *  @param extData - get IPMI 2.0 extended data
+ *  @param reserved1 - skip 3 bits
+ *  @param chNum - channel number to get info about
+ *  @param reserved2 - skip 4 bits
+ *  @param privLevel - requested privilege level
+
+ *  @returns ipmi completion code plus response data
+ *   - channel number
+ *   - rmcpAuthTypes - RMCP auth types (IPMI 1.5)
+ *   - reserved1
+ *   - extDataSupport - true for IPMI 2.0 extensions
+ *   - anonymousLogin - true for anonymous login enabled
+ *   - nullUsers - true for null user names enabled
+ *   - nonNullUsers - true for non-null usernames enabled
+ *   - userAuth - false for user authentication enabled
+ *   - perMessageAuth - false for per message authentication enabled
+ *   - KGStatus - true for Kg required for authentication
+ *   - reserved2
+ *   - rmcp - RMCP (IPMI 1.5) connection support
+ *   - rmcpp - RMCP+ (IPMI 2.0) connection support
+ *   - reserved3
+ *   - oemID - OEM IANA of any OEM auth support
+ *   - oemAuxillary - OEM data for auth
+ */
+ipmi::RspType<uint8_t,  // channel number
+              uint6_t,  // rmcpAuthTypes
+              bool,     // reserved1
+              bool,     // extDataSupport
+              bool,     // anonymousLogin
+              bool,     // nullUsers
+              bool,     // nonNullUsers
+              bool,     // userAuth
+              bool,     // perMessageAuth
+              bool,     // KGStatus
+              uint2_t,  // reserved2
+              bool,     // rmcp
+              bool,     // rmcpp
+              uint6_t,  // reserved3
+              uint24_t, // oemID
+              uint8_t   // oemAuxillary
+              >
+    ipmiGetChannelAuthenticationCapabilities(
+        ipmi::Context::ptr ctx, uint4_t chNum, uint3_t reserved1,
+        [[maybe_unused]] bool extData, uint4_t privLevel, uint4_t reserved2)
+{
+    uint8_t channel =
+        convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);
+
+    if (reserved1 || reserved2 || !isValidChannel(channel) ||
+        !isValidPrivLimit(static_cast<uint8_t>(privLevel)))
+    {
+        lg2::debug("Get channel auth capabilities - Invalid field in request");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (getChannelSessionSupport(channel) == EChannelSessSupported::none)
+    {
+        lg2::debug("Get channel auth capabilities - No support on channel");
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
+
+    constexpr bool extDataSupport = true; // true for IPMI 2.0 extensions
+    constexpr bool reserved3 = false;
+    constexpr uint6_t rmcpAuthTypes = 0;  // IPMI 1.5 auth types - not supported
+    constexpr uint2_t reserved4 = 0;
+    constexpr bool KGStatus = false;      // Not supporting now.
+    constexpr bool perMessageAuth = false; // Per message auth - enabled
+    constexpr bool userAuth = false;       // User authentication - enabled
+    constexpr bool nullUsers = false;      // Null user names - not supported
+    constexpr bool anonymousLogin = false; // Anonymous login - not supported
+    constexpr uint6_t reserved5 = 0;
+    constexpr bool rmcpp = true;           // IPMI 2.0 - supported
+    constexpr bool rmcp = false;           // IPMI 1.5 - not supported
+    constexpr uint24_t oemID = 0;
+    constexpr uint8_t oemAuxillary = 0;
+
+    bool nonNullUsers = 0;
+    uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0;
+    ipmi::ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers);
+    nonNullUsers = enabledUsers > 0;
+
+    return ipmi::responseSuccess(
+        channel, rmcpAuthTypes, reserved3, extDataSupport, anonymousLogin,
+        nullUsers, nonNullUsers, userAuth, perMessageAuth, KGStatus, reserved4,
+        rmcp, rmcpp, reserved5, oemID, oemAuxillary);
+}
+
+/** @brief implements the set user payload access command.
+ *  @param ctx - IPMI context pointer (for channel)
+ *  @param channel - channel number (4 bits)
+ *  @param reserved1 - skip 4 bits
+ *  @param userId - user id (6 bits)
+ *  @param operation - access ENABLE /DISABLE. (2 bits)
+ *  @param stdPayload0 - IPMI - reserved. (1 bit)
+ *  @param stdPayload1 - SOL.             (1 bit)
+ *  @param stdPayload2 -                  (1 bit)
+ *  @param stdPayload3 -                  (1 bit)
+ *  @param stdPayload4 -                  (1 bit)
+ *  @param stdPayload5 -                  (1 bit)
+ *  @param stdPayload6 -                  (1 bit)
+ *  @param stdPayload7 -                  (1 bit)
+ *  @param stdPayloadEnables2Reserved -   (8 bits)
+ *  @param oemPayload0 -                  (1 bit)
+ *  @param oemPayload1 -                  (1 bit)
+ *  @param oemPayload2 -                  (1 bit)
+ *  @param oemPayload3 -                  (1 bit)
+ *  @param oemPayload4 -                  (1 bit)
+ *  @param oemPayload5 -                  (1 bit)
+ *  @param oemPayload6 -                  (1 bit)
+ *  @param oemPayload7 -                  (1 bit)
+ *  @param oemPayloadEnables2Reserved -   (8 bits)
+ *
+ *  @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiSetUserPayloadAccess(
+    ipmi::Context::ptr ctx,
+
+    uint4_t channel, uint4_t reserved,
+
+    uint6_t userId, uint2_t operation,
+
+    bool stdPayload0ipmiReserved, bool stdPayload1SOL, bool stdPayload2,
+    bool stdPayload3, bool stdPayload4, bool stdPayload5, bool stdPayload6,
+    bool stdPayload7,
+
+    uint8_t stdPayloadEnables2Reserved,
+
+    bool oemPayload0, bool oemPayload1, bool oemPayload2, bool oemPayload3,
+    bool oemPayload4, bool oemPayload5, bool oemPayload6, bool oemPayload7,
+
+    uint8_t oemPayloadEnables2Reserved)
+{
+    auto chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    // Validate the reserved args. Only SOL payload is supported as on date.
+    if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 ||
+        stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 ||
+        oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 ||
+        oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 ||
+        stdPayloadEnables2Reserved || oemPayloadEnables2Reserved ||
+        !isValidChannel(chNum))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if ((operation != enableOperation && operation != disableOperation))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
+    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    PayloadAccess payloadAccess = {};
+    payloadAccess.stdPayloadEnables1[1] = stdPayload1SOL;
+
+    return ipmi::response(ipmiUserSetUserPayloadAccess(
+        chNum, static_cast<uint8_t>(operation), static_cast<uint8_t>(userId),
+        payloadAccess));
+}
+
+/** @brief implements the get user payload access command
+ *  This command returns information about user payload enable settings
+ *  that were set using the 'Set User Payload Access' Command.
+ *
+ *  @param ctx - IPMI context pointer (for channel)
+ *  @param channel - channel number
+ *  @param reserved1 - skip 4 bits
+ *  @param userId - user id
+ *  @param reserved2 - skip 2 bits
+ *
+ *  @returns IPMI completion code plus response data
+ *   - stdPayload0ipmiReserved - IPMI payload (reserved).
+ *   - stdPayload1SOL - SOL payload
+ *   - stdPayload2
+ *   - stdPayload3
+ *   - stdPayload4
+ *   - stdPayload5
+ *   - stdPayload6
+ *   - stdPayload7
+
+ *   - stdPayloadEnables2Reserved - Reserved.
+
+ *   - oemPayload0
+ *   - oemPayload1
+ *   - oemPayload2
+ *   - oemPayload3
+ *   - oemPayload4
+ *   - oemPayload5
+ *   - oemPayload6
+ *   - oemPayload7
+
+ *  - oemPayloadEnables2Reserved - Reserved
+ */
+ipmi::RspType<bool,    // stdPayload0ipmiReserved
+              bool,    // stdPayload1SOL
+              bool,    // stdPayload2
+              bool,    // stdPayload3
+              bool,    // stdPayload4
+              bool,    // stdPayload5
+              bool,    // stdPayload6
+              bool,    // stdPayload7
+
+              uint8_t, // stdPayloadEnables2Reserved
+
+              bool,    // oemPayload0
+              bool,    // oemPayload1
+              bool,    // oemPayload2
+              bool,    // oemPayload3
+              bool,    // oemPayload4
+              bool,    // oemPayload5
+              bool,    // oemPayload6
+              bool,    // oemPayload7
+
+              uint8_t  // oemPayloadEnables2Reserved
+              >
+    ipmiGetUserPayloadAccess(ipmi::Context::ptr ctx,
+
+                             uint4_t channel, uint4_t reserved1,
+
+                             uint6_t userId, uint2_t reserved2)
+{
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+
+    if (reserved1 || reserved2 || !isValidChannel(chNum))
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
+    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
+    {
+        return ipmi::responseParmOutOfRange();
+    }
+
+    ipmi::Cc retStatus;
+    PayloadAccess payloadAccess = {};
+    retStatus = ipmiUserGetUserPayloadAccess(
+        chNum, static_cast<uint8_t>(userId), payloadAccess);
+    if (retStatus != ccSuccess)
+    {
+        return ipmi::response(retStatus);
+    }
+    constexpr uint8_t res8bits = 0;
+    return ipmi::responseSuccess(
+        payloadAccess.stdPayloadEnables1.test(0),
+        payloadAccess.stdPayloadEnables1.test(1),
+        payloadAccess.stdPayloadEnables1.test(2),
+        payloadAccess.stdPayloadEnables1.test(3),
+        payloadAccess.stdPayloadEnables1.test(4),
+        payloadAccess.stdPayloadEnables1.test(5),
+        payloadAccess.stdPayloadEnables1.test(6),
+        payloadAccess.stdPayloadEnables1.test(7),
+
+        res8bits,
+
+        payloadAccess.oemPayloadEnables1.test(0),
+        payloadAccess.oemPayloadEnables1.test(1),
+        payloadAccess.oemPayloadEnables1.test(2),
+        payloadAccess.oemPayloadEnables1.test(3),
+        payloadAccess.oemPayloadEnables1.test(4),
+        payloadAccess.oemPayloadEnables1.test(5),
+        payloadAccess.oemPayloadEnables1.test(6),
+        payloadAccess.oemPayloadEnables1.test(7),
+
+        res8bits);
+}
+
+void registerUserIpmiFunctions() __attribute__((constructor));
+void registerUserIpmiFunctions()
+{
+    post_work([]() { ipmiUserInit(); });
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetUserAccessCommand,
+                          ipmi::Privilege::Admin, ipmiSetUserAccess);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetUserAccessCommand,
+                          ipmi::Privilege::Admin, ipmiGetUserAccess);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetUserNameCommand,
+                          ipmi::Privilege::Admin, ipmiGetUserName);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetUserName, ipmi::Privilege::Admin,
+                          ipmiSetUserName);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetUserPasswordCommand,
+                          ipmi::Privilege::Admin, ipmiSetUserPassword);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetChannelAuthCapabilities,
+                          ipmi::Privilege::Callback,
+                          ipmiGetChannelAuthenticationCapabilities);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdSetUserPayloadAccess,
+                          ipmi::Privilege::Admin, ipmiSetUserPayloadAccess);
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetUserPayloadAccess,
+                          ipmi::Privilege::Operator, ipmiGetUserPayloadAccess);
+
+    return;
+}
+} // namespace ipmi
diff --git a/user_channel/usercommands.hpp b/user_channel/usercommands.hpp
new file mode 100644
index 0000000..a1fb7b9
--- /dev/null
+++ b/user_channel/usercommands.hpp
@@ -0,0 +1,36 @@
+/*
+// Copyright (c) 2018 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.
+*/
+
+#pragma once
+#include <cstdint>
+
+namespace ipmi
+{
+
+/**
+ * @enum IPMI set password return codes (refer spec sec 22.30)
+ */
+enum ipmi_set_password_return_codes : uint8_t
+{
+    ipmiCCPasswdFailMismatch = 0x80,
+    ipmiCCPasswdFailWrongSize = 0x81,
+};
+
+static constexpr uint8_t userIdEnabledViaSetPassword = 0x1;
+static constexpr uint8_t userIdDisabledViaSetPassword = 0x2;
+
+void registerUserIpmiFunctions();
+} // namespace ipmi
diff --git a/whitelist-filter.cpp b/whitelist-filter.cpp
new file mode 100644
index 0000000..7fe4e22
--- /dev/null
+++ b/whitelist-filter.cpp
@@ -0,0 +1,253 @@
+#include <ipmiallowlist.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <settings.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Control/Security/RestrictionMode/server.hpp>
+
+#include <algorithm>
+#include <array>
+
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+
+namespace ipmi
+{
+
+// put the filter provider in an unnamed namespace
+namespace
+{
+
+/** @class AllowlistFilter
+ *
+ * Class that implements an IPMI message filter based
+ * on incoming interface and a restriction mode setting
+ */
+class AllowlistFilter
+{
+  public:
+    AllowlistFilter();
+    ~AllowlistFilter() = default;
+    AllowlistFilter(const AllowlistFilter&) = delete;
+    AllowlistFilter(AllowlistFilter&&) = delete;
+    AllowlistFilter& operator=(const AllowlistFilter&) = delete;
+    AllowlistFilter& operator=(AllowlistFilter&&) = delete;
+
+  private:
+    void postInit();
+    void cacheRestrictedMode(const std::vector<std::string>& devices);
+    void handleRestrictedModeChange(
+        sdbusplus::message_t& m,
+        const std::map<std::string, size_t>& deviceList);
+    ipmi::Cc filterMessage(ipmi::message::Request::ptr request);
+
+    std::vector<bool> restrictedMode;
+    std::shared_ptr<sdbusplus::asio::connection> bus;
+    std::unique_ptr<settings::Objects> objects;
+    std::unique_ptr<sdbusplus::bus::match_t> modeChangeMatch;
+
+    static constexpr const char restrictionModeIntf[] =
+        "xyz.openbmc_project.Control.Security.RestrictionMode";
+};
+
+AllowlistFilter::AllowlistFilter()
+{
+    bus = getSdBus();
+
+    lg2::info("Loading allowlist filter");
+    ipmi::registerFilter(ipmi::prioOpenBmcBase,
+                         [this](ipmi::message::Request::ptr request) {
+                             return filterMessage(request);
+                         });
+
+    // wait until io->run is going to fetch RestrictionMode
+    post_work([this]() { postInit(); });
+}
+
+/** @brief Get RestrictionMode of the devices which has RestrictionMode support
+ * enabled
+ *  @param[in] devices - vector of devices object path
+ *  @returns void.
+ */
+
+void AllowlistFilter::cacheRestrictedMode(
+    const std::vector<std::string>& devices)
+{
+    using namespace sdbusplus::server::xyz::openbmc_project::control::security;
+    std::string restrictionModeSetting;
+    std::string restrictionModeService;
+
+    for (auto& dev : devices)
+    {
+        try
+        {
+            restrictionModeSetting = dev;
+            restrictionModeService =
+                objects->service(restrictionModeSetting, restrictionModeIntf);
+        }
+        catch (const std::out_of_range& e)
+        {
+            lg2::error(
+                "Could not look up restriction mode interface from cache");
+            return;
+        }
+
+        std::string mode;
+        try
+        {
+            auto propValue = ipmi::getDbusProperty(
+                *bus, restrictionModeService, restrictionModeSetting,
+                restrictionModeIntf, "RestrictionMode");
+            mode = std::get<std::string>(propValue);
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error("Error in RestrictionMode Get");
+            // Fail-safe to true.
+            size_t index = std::distance(&*std::begin(devices), &dev);
+            restrictedMode[index] = true;
+        }
+
+        auto restrictionMode = RestrictionMode::convertModesFromString(mode);
+
+        bool restrictMode =
+            (restrictionMode == RestrictionMode::Modes::Allowlist);
+        restrictedMode.emplace_back(restrictMode);
+
+        lg2::info("Set restrictedMode = {RESTRICTED_MODE}", "RESTRICTED_MODE",
+                  restrictMode);
+    }
+}
+
+/** @brief Update RestrictionMode if any changes in RestrictionMode
+ *  @param[in] m - sdbusplus message. Using this to get Updated Mode dbus path
+ *  @param[in] deviceList - map to store devices path and their index
+ *  @returns void.
+ */
+
+void AllowlistFilter::handleRestrictedModeChange(
+    sdbusplus::message_t& m, const std::map<std::string, size_t>& deviceList)
+{
+    using namespace sdbusplus::server::xyz::openbmc_project::control::security;
+    std::string intf;
+    std::vector<std::pair<std::string, ipmi::Value>> propertyList;
+    m.read(intf, propertyList);
+
+    std::string path = m.get_path();
+    size_t hostId = 0;
+    auto it = deviceList.find(path);
+
+    if (it == deviceList.end())
+    {
+        lg2::error("Key not found in deviceList ");
+    }
+    else
+    {
+        hostId = it->second;
+    }
+
+    for (const auto& property : propertyList)
+    {
+        if (property.first == "RestrictionMode")
+        {
+            RestrictionMode::Modes restrictionMode =
+                RestrictionMode::convertModesFromString(
+                    std::get<std::string>(property.second));
+            bool restrictMode =
+                (restrictionMode == RestrictionMode::Modes::Allowlist);
+            restrictedMode[hostId] = restrictMode;
+
+            lg2::info("Updated restrictedMode = {RESTRICTED_MODE}",
+                      "RESTRICTED_MODE", restrictMode);
+        }
+    }
+}
+
+/** @brief Get and Update RestrictionModes of supported devices
+ *  @param[in] void
+ *  @returns void.
+ */
+
+void AllowlistFilter::postInit()
+{
+    objects = std::make_unique<settings::Objects>(
+        *bus, std::vector<settings::Interface>({restrictionModeIntf}));
+    if (!objects)
+    {
+        lg2::error(
+            "Failed to create settings object; defaulting to restricted mode");
+        return;
+    }
+
+    std::vector<std::string> devices;
+    try
+    {
+        devices = objects->map.at(restrictionModeIntf);
+    }
+    catch (const std::out_of_range& e)
+    {
+        lg2::error("Could not look up restriction mode interface from cache");
+        return;
+    }
+
+    // Initialize restricted mode
+    cacheRestrictedMode(devices);
+    // Wait for changes on Restricted mode
+    std::map<std::string, size_t> deviceList;
+
+    for (size_t index = 0; index < devices.size(); index++)
+    {
+        deviceList.emplace(devices[index], index);
+    }
+
+    std::string filterStr;
+    std::string devicesDbusPath{"/xyz/openbmc_project/control"};
+
+    filterStr = sdbusplus::bus::match::rules::propertiesChangedNamespace(
+        devicesDbusPath, restrictionModeIntf);
+
+    modeChangeMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *bus, filterStr, [this, deviceList](sdbusplus::message_t& m) {
+            handleRestrictedModeChange(m, deviceList);
+        });
+}
+
+/** @brief Filter IPMI messages with RestrictedMode
+ *  @param[in] request - IPMI messahe request
+ *  @returns IPMI completion code success or error.
+ */
+
+ipmi::Cc AllowlistFilter::filterMessage(ipmi::message::Request::ptr request)
+{
+    /* Getting hostIdx for all IPMI devices like hosts, debugcard and other
+   devices from ipmi::message::Request and call postInit() to get the
+   restriction mode for all the IPMI commands */
+
+    size_t hostIdx = request->ctx->hostIdx;
+
+    if (request->ctx->channel == ipmi::channelSystemIface &&
+        restrictedMode[hostIdx])
+    {
+        if (!std::binary_search(
+                allowlist.cbegin(), allowlist.cend(),
+                std::make_pair(request->ctx->netFn, request->ctx->cmd)))
+        {
+            lg2::error("Net function not allowlisted, "
+                       "NetFn: {NETFN}, Cmd: {CMD}",
+                       "NETFN", lg2::hex, request->ctx->netFn, "CMD", lg2::hex,
+                       request->ctx->cmd);
+
+            return ipmi::ccInsufficientPrivilege;
+        }
+    }
+    return ipmi::ccSuccess;
+}
+
+// instantiate the AllowlistFilter when this shared object is loaded
+AllowlistFilter allowlistFilter;
+
+} // namespace
+
+} // namespace ipmi
diff --git a/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff.interface.yaml b/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff.interface.yaml
new file mode 100644
index 0000000..9e34734
--- /dev/null
+++ b/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff.interface.yaml
@@ -0,0 +1,35 @@
+description: >
+    Implement the Soft Power Off function. On receiving the SMS_ATTN from BMC,
+    Host will respond with a GetMessageFlags command and the BMC will respond
+    with a static data indicating that Event Message Buffer is full. Host then
+    sends 'ReadEvent' command and BMC responds with an architected packet
+    mentioning that the type is SOFT_OFF. Host then goes ahead and starts to
+    quiesce. Once that is done, Host will send a hard power off command to BMC
+    and then BMC will issue a hard power off.
+
+properties:
+    - name: ResponseReceived
+      type: enum[self.HostResponse]
+      default: NotApplicable
+      description: >
+          When the response is received for 'SMS_ATN', this is set to
+          'SoftOffReceived' and is set to 'HostShutdown' when Host sends a Power
+          Off request.
+
+enumerations:
+    - name: HostResponse
+      description: >
+          Possible response types from Host for a Soft Power Off function.
+      values:
+          - name: NotApplicable
+            description: >
+                Default initial value.
+          - name: SoftOffReceived
+            description: >
+                Host has received the SMS_ATN from BMC indicating that Host
+                needs to do a Soft Power Off.
+          - name: HostShutdown
+            description: >
+                Host has sufficiently quiesced and acknowledged the shutdown
+                request such that the hardware shutdown sequence can safely be
+                performed.
diff --git a/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/meson.build b/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/meson.build
new file mode 100644
index 0000000..56c2019
--- /dev/null
+++ b/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/meson.build
@@ -0,0 +1,69 @@
+sdbuspp_prog = find_program('sdbus++')
+
+domain = 'xyz.openbmc_project.Ipmi.Internal.SoftPowerOff'
+if_yaml_file = files('../SoftPowerOff.interface.yaml')
+
+if_cpp = custom_target(
+    'server.cpp',
+    output: 'server.cpp',
+    input: if_yaml_file,
+    capture: true,
+    command: [sdbuspp_prog, '-r', root, 'interface', 'server-cpp', domain],
+)
+
+if_hpp = custom_target(
+    'server.hpp',
+    output: 'server.hpp',
+    input: if_yaml_file,
+    capture: true,
+    command: [sdbuspp_prog, '-r', root, 'interface', 'server-header', domain],
+    install: true,
+    install_dir: get_option('includedir') / 'xyz/openbmc_project/Ipmi/Internal/SoftPowerOff',
+)
+
+if_common_hpp = custom_target(
+    'common.hpp',
+    output: 'common.hpp',
+    input: if_yaml_file,
+    capture: true,
+    command: [sdbuspp_prog, '-r', root, 'interface', 'common-header', domain],
+    install: true,
+    install_dir: get_option('includedir') / 'xyz/openbmc_project/Ipmi/Internal/SoftPowerOff',
+)
+
+softoff_dbus_deps = [
+    dependency('phosphor-dbus-interfaces'),
+    dependency('sdbusplus'),
+]
+
+softoff_dbus_lib = library(
+    'softoff-dbus',
+    [if_cpp, if_hpp, if_common_hpp],
+    implicit_include_directories: false,
+    include_directories: root_inc,
+    version: meson.project_version(),
+    dependencies: softoff_dbus_deps,
+    override_options: ['b_lundef=false'],
+    install: true,
+)
+
+softoff_dbus = declare_dependency(
+    dependencies: softoff_dbus_deps,
+    sources: [if_hpp, if_common_hpp],
+    link_with: softoff_dbus_lib,
+)
+
+softoff_dbus_reqs = []
+foreach dep : softoff_dbus_deps
+    if dep.type_name() == 'pkgconfig'
+        softoff_dbus_reqs += dep
+    endif
+endforeach
+
+import('pkgconfig').generate(
+    name: 'softoff-dbus',
+    description: 'SoftPowerOff DBus Bindings',
+    version: meson.project_version(),
+    libraries: softoff_dbus,
+    requires: softoff_dbus_reqs,
+)
