diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7b0a80..70514df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,8 +19,12 @@
 add_definitions (-DBOOST_NO_TYPEID)
 add_definitions (-DBOOST_ASIO_DISABLE_THREADS)
 add_definitions (-DBOOST_COROUTINES_NO_DEPRECATION_WARNING)
+add_definitions (-Wno-psabi)
 
 if (NOT YOCTO)
+    # headers that can't be built without yocto
+    include_directories (non-yocto)
+
     configure_file (CMakeLists.txt.in 3rdparty/CMakeLists.txt)
     execute_process (
         COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
@@ -79,9 +83,17 @@
 
 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
 
+#
+# import OpenSSL (crypto)
+find_package (OpenSSL REQUIRED)
+include_directories (${OPENSSL_INCLUDE_DIR})
+
 add_library (
     zinteloemcmds SHARED src/oemcommands.cpp src/sensorcommands.cpp
     src/storagecommands.cpp src/multinodecommands.cpp src/firmware-update.cpp
+    src/smbioshandler.cpp src/smbiosmdrv2handler.cpp
+    src/manufacturingcommands.cpp src/bmccontrolservices.cpp
+    src/bridgingcommands.cpp
 )
 set_target_properties (zinteloemcmds PROPERTIES VERSION "0.1.0")
 set_target_properties (zinteloemcmds PROPERTIES SOVERSION "0")
@@ -91,5 +103,6 @@
 target_link_libraries (zinteloemcmds intel_dbus)
 target_link_libraries (zinteloemcmds -luserlayer)
 target_link_libraries (zinteloemcmds -lchannellayer)
+target_link_libraries (zinteloemcmds ${OPENSSL_CRYPTO_LIBRARY})
 
 install (TARGETS zinteloemcmds DESTINATION lib/ipmid-providers)
diff --git a/include/bridgingcommands.hpp b/include/bridgingcommands.hpp
new file mode 100644
index 0000000..e277b58
--- /dev/null
+++ b/include/bridgingcommands.hpp
@@ -0,0 +1,347 @@
+/*
+// 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 <sdbusplus/message.hpp>
+#include <sdbusplus/server/interface.hpp>
+
+/**
+ * @brief Response queue defines
+ */
+constexpr int responseQueueMaxSize = 20;
+
+/**
+ * @brief Ipmb misc
+ */
+constexpr uint8_t ipmbLunMask = 0x03;
+constexpr uint8_t ipmbSeqMask = 0x3F;
+constexpr uint8_t ipmbMeSlaveAddress = 0x2C;
+constexpr uint8_t ipmbMeChannelNum = 1;
+
+/**
+ * @brief Ipmb getters
+ */
+constexpr uint8_t ipmbNetFnGet(uint8_t netFnLun)
+{
+    return netFnLun >> 2;
+}
+
+constexpr uint8_t ipmbLunFromNetFnLunGet(uint8_t netFnLun)
+{
+    return netFnLun & ipmbLunMask;
+}
+
+constexpr uint8_t ipmbSeqGet(uint8_t seqNumLun)
+{
+    return seqNumLun >> 2;
+}
+
+constexpr uint8_t ipmbLunFromSeqLunGet(uint8_t seqNumLun)
+{
+    return seqNumLun & ipmbLunMask;
+}
+
+/**
+ * @brief Ipmb setters
+ */
+constexpr uint8_t ipmbNetFnLunSet(uint8_t netFn, uint8_t lun)
+{
+    return ((netFn << 2) | (lun & ipmbLunMask));
+}
+
+constexpr uint8_t ipmbSeqLunSet(uint8_t seq, uint8_t lun)
+{
+    return ((seq << 2) | (lun & ipmbLunMask));
+}
+
+constexpr size_t ipmbMaxDataSize = 256;
+constexpr size_t ipmbConnectionHeaderLength = 3;
+constexpr size_t ipmbResponseDataHeaderLength = 4;
+constexpr size_t ipmbRequestDataHeaderLength = 3;
+constexpr size_t ipmbChecksum2StartOffset = 3;
+constexpr size_t ipmbChecksumSize = 1;
+constexpr size_t ipmbMinFrameLength = 7;
+constexpr size_t ipmbMaxFrameLength = ipmbConnectionHeaderLength +
+                                      ipmbResponseDataHeaderLength +
+                                      ipmbChecksumSize + ipmbMaxDataSize;
+
+/**
+ * @brief Channel types
+ */
+constexpr uint8_t targetChannelIpmb = 0x1;
+constexpr uint8_t targetChannelIcmb10 = 0x2;
+constexpr uint8_t targetChannelIcmb09 = 0x3;
+constexpr uint8_t targetChannelLan = 0x4;
+constexpr uint8_t targetChannelSerialModem = 0x5;
+constexpr uint8_t targetChannelOtherLan = 0x6;
+constexpr uint8_t targetChannelPciSmbus = 0x7;
+constexpr uint8_t targetChannelSmbus10 = 0x8;
+constexpr uint8_t targetChannelSmbus20 = 0x9;
+constexpr uint8_t targetChannelSystemInterface = 0xC;
+
+/**
+ * @brief Channel modes
+ */
+constexpr uint8_t modeNoTracking = 0x0;
+constexpr uint8_t modeTrackRequest = 0x1;
+constexpr uint8_t modeSendRaw = 0x2;
+
+/**
+ * @brief Command specific codes
+ */
+constexpr ipmi_return_codes ipmiGetMessageCmdDataNotAvailable =
+    static_cast<ipmi_return_codes>(0x80);
+
+/**
+ * @brief Ipmb frame
+ */
+typedef struct
+{
+    /// @brief IPMB frame header
+    union
+    {
+        /// @brief IPMB request header
+        struct
+        {
+            /** @brief IPMB Connection Header Format */
+            uint8_t address;
+            uint8_t rsNetFnLUN;
+            uint8_t checksum1;
+            /** @brief IPMB Header */
+            uint8_t rqSA;
+            uint8_t rqSeqLUN;
+            uint8_t cmd;
+            uint8_t data[];
+        } Req;
+        /// @brief IPMB response header
+        struct
+        {
+            uint8_t address;
+            /** @brief IPMB Connection Header Format */
+            uint8_t rqNetFnLUN;
+            uint8_t checksum1;
+            /** @brief IPMB Header */
+            uint8_t rsSA;
+            uint8_t rsSeqLUN;
+            uint8_t cmd;
+            uint8_t completionCode;
+            uint8_t data[];
+        } Resp;
+    } Header;
+} __attribute__((packed)) ipmbHeader;
+
+/**
+ * @brief Ipmb messages
+ */
+struct IpmbRequest
+{
+    uint8_t address;
+    uint8_t netFn;
+    uint8_t rsLun;
+    uint8_t rqSA;
+    uint8_t seq;
+    uint8_t rqLun;
+    uint8_t cmd;
+    std::vector<uint8_t> data;
+
+    IpmbRequest(const ipmbHeader *ipmbBuffer, size_t bufferLength);
+
+    void prepareRequest(sdbusplus::message::message &mesg);
+};
+
+struct IpmbResponse
+{
+    uint8_t address;
+    uint8_t netFn;
+    uint8_t rqLun;
+    uint8_t rsSA;
+    uint8_t seq;
+    uint8_t rsLun;
+    uint8_t cmd;
+    uint8_t completionCode;
+    std::vector<uint8_t> data;
+
+    IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun, uint8_t rsSA,
+                 uint8_t seq, uint8_t rsLun, uint8_t cmd,
+                 uint8_t completionCode, std::vector<uint8_t> &inputData);
+
+    void ipmbToi2cConstruct(uint8_t *buffer, size_t *bufferLength);
+};
+
+/**
+ * @brief Send Message Request
+ */
+typedef struct
+{
+    uint8_t channelData;
+    uint8_t data[];
+
+    constexpr uint8_t channelNumGet()
+    {
+        return (channelData & 0xF);
+    }
+
+    constexpr uint8_t authenticationGet()
+    {
+        return ((channelData & 0x10) >> 4);
+    }
+
+    constexpr uint8_t encryptionGet()
+    {
+        return ((channelData & 0x20) >> 5);
+    }
+
+    constexpr uint8_t modeGet()
+    {
+        return ((channelData & 0xC0) >> 6);
+    }
+} __attribute__((packed)) sSendMessageReq;
+
+/**
+ * @brief Get Message Response
+ */
+typedef struct
+{
+    uint8_t channelData;
+    uint8_t data[];
+
+    constexpr void channelNumSet(uint8_t num)
+    {
+        channelData |= num & 0xF;
+    }
+
+    constexpr void privilegeLvlSet(CommandPrivilege privLvl)
+    {
+        channelData |= static_cast<uint8_t>(privLvl) & 0xF0;
+    }
+} __attribute__((packed)) sGetMessageRes;
+
+/**
+ * @brief Get Message Flags Response
+ */
+typedef struct
+{
+    uint8_t flags;
+
+    constexpr void receiveMessageBitSet(uint8_t value)
+    {
+        flags |= (value & 1);
+    }
+
+    constexpr void eventMessageBitSet(uint8_t value)
+    {
+        flags |= (value & 1) << 1;
+    }
+
+    constexpr void watchdogTimeoutBitSet(uint8_t value)
+    {
+        flags |= (value & 1) << 3;
+    }
+
+    constexpr void oem0BitSet(uint8_t value)
+    {
+        flags |= (value & 1) << 5;
+    }
+
+    constexpr void oem1BitSet(uint8_t value)
+    {
+        flags |= (value & 1) << 6;
+    }
+
+    constexpr void oem2BitSet(uint8_t value)
+    {
+        flags |= (value & 1) << 7;
+    }
+} __attribute__((packed)) sGetMessageFlagsResp;
+
+/**
+ * @brief Clear Message Flags Request
+ */
+typedef struct
+{
+    uint8_t flags;
+
+    constexpr uint8_t receiveMessageBitGet()
+    {
+        return (flags & 0x1);
+    }
+
+    constexpr uint8_t eventMessageBitGet()
+    {
+        return ((flags & 0x2) >> 1);
+    }
+
+    constexpr uint8_t watchdogTimeoutBitGet()
+    {
+        return ((flags & 0x8) >> 3);
+    }
+
+    constexpr uint8_t oem0BitGet()
+    {
+        return ((flags & 0x20) >> 5);
+    }
+
+    constexpr uint8_t oem1BitGet()
+    {
+        return ((flags & 0x40) >> 6);
+    }
+
+    constexpr uint8_t oem2BitGet()
+    {
+        return ((flags & 0x80) >> 7);
+    }
+} __attribute__((packed)) sClearMessageFlagsReq;
+
+/** @class Bridging
+ *
+ *  @brief Implement commands to support IPMI bridging.
+ */
+class Bridging
+{
+  public:
+    Bridging();
+
+    ipmi_return_codes sendMessageHandler(ipmi_request_t request,
+                                         ipmi_response_t response,
+                                         ipmi_data_len_t dataLen);
+
+    ipmi_return_codes getMessageHandler(ipmi_request_t request,
+                                        ipmi_response_t response,
+                                        ipmi_data_len_t dataLen);
+
+    ipmi_return_codes clearMessageFlagsHandler(ipmi_request_t request,
+                                               ipmi_response_t response,
+                                               ipmi_data_len_t dataLen);
+
+    ipmi_return_codes getMessageFlagsHandler(ipmi_request_t request,
+                                             ipmi_response_t response,
+                                             ipmi_data_len_t dataLen);
+
+    enum IpmiAppBridgingCmds
+    {
+        ipmiCmdClearMessageFlags = 0x30,
+        ipmiCmdGetMessageFlags = 0x31,
+        ipmiCmdGetMessage = 0x33,
+        ipmiCmdSendMessage = 0x34,
+    };
+
+  private:
+    std::vector<IpmbResponse> responseQueue;
+    sdbusplus::bus::bus dbus;
+
+    ipmi_return_codes handleIpmbChannel(sSendMessageReq *sendMsgReq,
+                                        ipmi_response_t response,
+                                        ipmi_data_len_t dataLen);
+};
diff --git a/include/manufacturingcommands.hpp b/include/manufacturingcommands.hpp
new file mode 100644
index 0000000..bc70d84
--- /dev/null
+++ b/include/manufacturingcommands.hpp
@@ -0,0 +1,291 @@
+/*
+// 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-types.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/timer.hpp>
+#include <variantvisitors.hpp>
+#include <vector>
+
+#define FAN_SENSOR_NOT_PRESENT (0 << 0)
+#define FAN_SENSOR_PRESENT (1 << 0)
+#define FAN_NOT_PRESENT (0 << 1)
+#define FAN_PRESENT (1 << 1)
+
+namespace ipmi
+{
+
+// TODO: Service names may change. Worth to consider dynamic detection.
+static constexpr const char* fanService = "xyz.openbmc_project.FanSensor";
+static constexpr const char* gpioService = "xyz.openbmc_project.Gpio";
+static constexpr const char* ledServicePrefix =
+    "xyz.openbmc_project.LED.Controller.";
+
+static constexpr const char* ledPathPrefix =
+    "/xyz/openbmc_project/led/physical/";
+static constexpr const char* fanPwmPath =
+    "/xyz/openbmc_project/sensors/fan_pwm/Pwm_";
+static constexpr const char* fanTachPathPrefix =
+    "/xyz/openbmc_project/sensors/fan_tach/Fan_";
+
+static constexpr const char* fanIntf = "xyz.openbmc_project.Sensor.Value";
+static constexpr const char* gpioIntf = "xyz.openbmc_project.Control.Gpio";
+static constexpr const char* ledIntf = "xyz.openbmc_project.Led.Physical";
+
+static constexpr const char* busPropertyIntf =
+    "org.freedesktop.DBus.Properties";
+static constexpr const char* ledStateStr =
+    "xyz.openbmc_project.Led.Physical.Action."; // Comes with postfix Off/On
+static constexpr const char* smGetSignalPathPrefix =
+    "/xyz/openbmc_project/control/gpio/";
+
+/** @enum MtmLvl
+.*
+ *  Manufacturing command access levels
+ */
+enum class MtmLvl
+{
+    mtmNotRunning = 0x00,
+    mtmExpired = 0x01,
+    mtmAvailable = 0x02,
+};
+
+enum class SmActionGet : uint8_t
+{
+    sample = 0,
+    ignore = 1,
+    revert = 2
+};
+
+enum class SmActionSet : uint8_t
+{
+    forceDeasserted = 0,
+    forceAsserted = 1,
+    revert = 2
+};
+
+enum class SmSignalGet : uint8_t
+{
+    smPowerButton = 0,
+    smResetButton = 1,
+    smSleepButton,
+    smNmiButton = 3,
+    smChassisIntrusion = 4,
+    smPowerGood,
+    smPowerRequestGet,
+    smSleepRequestGet,
+    smFrbTimerHaltGet,
+    smForceUpdate,
+    smRingIndication,
+    smCarrierDetect,
+    smIdentifyButton = 0xc,
+    smFanPwmGet = 0xd,
+    smSignalReserved,
+    smFanTachometerGet = 0xf,
+    smNcsiDiag = 0x10,
+    smFpLcpLeftButton = 0x11,
+    smFpLcpRightButton,
+    smFpLcpEnterButton,
+    smGetSignalMax
+};
+
+enum class SmSignalSet : uint8_t
+{
+    smPowerLed = 0,
+    smPowerFaultLed,
+    smClusterLed,
+    smDiskFaultLed,
+    smCoolingFaultLed,
+    smFanPowerSpeed = 5,
+    smPowerRequestSet,
+    smSleepRequestSet,
+    smAcpiSci,
+    smSpeaker,
+    smFanPackFaultLed,
+    smCpuFailLed,
+    smDimmFailLed,
+    smIdentifyLed,
+    smHddLed,
+    smSystemReadyLed,
+    smLcdBacklight = 0x10,
+    smSetSignalMax
+};
+
+struct SetSmSignalReq
+{
+    SmSignalSet Signal;
+    uint8_t Instance;
+    SmActionSet Action;
+    uint8_t Value;
+};
+
+struct GetSmSignalReq
+{
+    SmSignalGet Signal;
+    uint8_t Instance;
+    SmActionGet Action;
+};
+
+struct GetSmSignalRsp
+{
+    uint8_t SigVal;
+    uint8_t SigVal1;
+    uint8_t SigVal2;
+};
+
+class LedProperty
+{
+    SmSignalSet signal;
+    std::string name;
+    std::string prevState;
+    std::string currentState;
+    bool isLocked;
+
+  public:
+    LedProperty(SmSignalSet signal_, std::string name_) :
+        signal(signal_), name(name_), prevState(""), isLocked(false)
+    {
+    }
+
+    LedProperty() = delete;
+
+    SmSignalSet getSignal() const
+    {
+        return signal;
+    }
+
+    void setLock(const bool& lock)
+    {
+        isLocked = lock;
+    }
+    void setPrevState(const std::string& state)
+    {
+        prevState = state;
+    }
+    void setCurrState(const std::string& state)
+    {
+        currentState = state;
+    }
+    std::string getCurrState() const
+    {
+        return currentState;
+    }
+    bool getLock() const
+    {
+        return isLocked;
+    }
+    std::string getPrevState() const
+    {
+        return prevState;
+    }
+    std::string getName() const
+    {
+        return name;
+    }
+};
+
+/** @class Manufacturing
+ *
+ *  @brief Implemet commands to support Manufacturing Test Mode.
+ */
+class Manufacturing
+{
+    std::string path;
+    std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
+    std::vector<LedProperty> ledPropertyList;
+    void initData();
+
+  public:
+    Manufacturing();
+
+    ipmi_return_codes detectAccessLvl(ipmi_request_t request,
+                                      ipmi_data_len_t req_len);
+
+    LedProperty* findLedProperty(const SmSignalSet& signal)
+    {
+        auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
+                               [&signal](const LedProperty& led) {
+                                   return led.getSignal() == signal;
+                               });
+        if (it != ledPropertyList.end())
+        {
+            return &(*it);
+        }
+        return nullptr;
+    }
+
+    std::string getLedPropertyName(const SmSignalSet signal)
+    {
+        LedProperty* led = findLedProperty(signal);
+        if (led != nullptr)
+        {
+            return led->getName();
+        }
+        else
+        {
+            return "";
+        }
+    }
+
+    int8_t getProperty(const char* service, std::string path,
+                       const char* interface, std::string propertyName,
+                       ipmi::Value* value);
+    int8_t setProperty(const char* service, std::string path,
+                       const char* interface, std::string propertyName,
+                       ipmi::Value value);
+    int8_t disablePidControlService(const bool disable);
+
+    void revertTimerHandler();
+
+    std::tuple<uint8_t, ipmi_ret_t, uint8_t> proccessSignal(SmSignalGet signal,
+                                                            SmActionGet action);
+
+    std::string getGpioPathForSmSignal(uint8_t gpioInstane)
+    {
+        return smGetSignalPathPrefix + gpioPaths[gpioInstane];
+    }
+
+    MtmLvl getAccessLvl(void)
+    {
+        static MtmLvl mtmMode = MtmLvl::mtmNotRunning;
+        if (mtmMode != MtmLvl::mtmExpired)
+        {
+            ipmi::Value mode;
+            if (getProperty("xyz.openbmc_project.SpeciaMode",
+                            "/xyz/openbmc_project/security/specialMode",
+                            "xyz.openbmc_project.Security.SpecialMode",
+                            "SpecialMode", &mode) != 0)
+            {
+                mtmMode = MtmLvl::mtmExpired;
+                return mtmMode;
+            }
+            mtmMode = static_cast<MtmLvl>(std::get<std::uint8_t>(mode));
+        }
+        return mtmMode;
+    }
+
+    std::vector<SmSignalGet> revertSmSignalGetVector;
+    bool revertFanPWM = false;
+    bool revertLedCallback = false;
+    phosphor::Timer revertTimer;
+};
+
+} // namespace ipmi
diff --git a/include/oemcommands.hpp b/include/oemcommands.hpp
index 2d2042d..e0e6903 100644
--- a/include/oemcommands.hpp
+++ b/include/oemcommands.hpp
@@ -366,3 +366,73 @@
     maxPwm = 0x3,
     cfm = 0x4
 };
+
+// FIXME: this stuff needs to be rewritten
+enum IPMI_INTEL_OEM_RETURN_CODES
+{
+    IPMI_CC_OEM_PAYLOAD_ACTIVE = 0x80,
+    IPMI_CC_OEM_INVALID_PCIE_SLOTID = 0x80,
+    IPMI_CC_OEM_PARAMETER_NOT_SUPPORTED = 0x80,
+    IPMI_CC_OEM_PAYLOAD_ALREADY_DEACTIVATED = 0x80,
+    IPMI_CC_OEM_SET_IN_PROCESS = 0x81,
+    IPMI_CC_OEM_PAYLOAD_DISABLE = 0x81,
+    IPMI_CC_OEM_LOST_ARBITRATION = 0x81,
+    IPMI_CC_OEM_INVALID_CABLE_PORT_INDEX = 0x81,
+    IPMI_CC_OEM_HEALTH_STATUS_NOT_AVAILABLE = 0x81,
+    IPMI_CC_OEM_BUS_ERROR = 0x82,
+    IPMI_CC_OEM_READ_ONLY = 0x82,
+    IPMI_CC_OEM_WRITE_ONLY = 0x82,
+    IPMI_CC_OEM_NO_CABLE_PRESENT = 0x82,
+    IPMI_CC_OEM_DATA_COLLECTION_IN_PROGRESS = 0x82,
+    IPMI_CC_OEM_PAYLOAD_ACTIVATION_LIMIT_REACH = 0x82,
+    IPMI_CC_OEM_NACK_ON_WRITE = 0x83,
+    IPMI_CC_OEM_DATA_COLLECTION_FAILED = 0x83,
+    IPMI_CC_OEM_CAN_NOT_ACTIVATE_WITH_ENCRYPTION = 0x83,
+    IPMI_CC_OEM_CAN_NOT_ACTIVATE_WITHOUT_ENCRYPTION = 0x84,
+    IPMI_CC_OEM_INVALID_CHECKSUM = 0x85,
+    IPMI_CC_OEM_NO_CABLED_PCIE_PORTS_AVAILABLE = 0xC2,
+};
+
+enum IPMI_RETURN_CODE_EXT
+{
+    IPMI_CC_INVALID_LUN = 0xC2,
+    IPMI_CC_STORGE_LEAK = 0xC4,
+    IPMI_CC_REQUEST_DATA_TRUNCATED = 0xC6,
+    IPMI_CC_REQUEST_DATA_FIELD_LENGTH_LIMIT_EXCEEDED = 0xC8,
+    IPMI_CC_CANNOT_RETURN_NUMBER_OF_REQUESTED_DATA_BYTES = 0xCA,
+    IPMI_CC_REQUEST_SENSOR_DATA_RECORD_NOT_FOUND = 0xCB,
+    IPMI_CC_DESTINATION_UNAVAILABLE = 0xD3,
+    IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE = 0xD5,
+};
+
+constexpr unsigned char NETFUN_INTEL_APP_OEM = 0x3E;
+
+enum IPMI_NETFN_INTEL_OEM_APP_CMD
+{
+    MDR_STATUS = 0x20,
+    MDR_COMPLETE = 0x21,
+    MDR_EVENT = 0x22,
+    MDR_READ = 0x23,
+    MDR_WRITE = 0x24,
+    MDR_LOCK = 0x25,
+    MDRII_AGENT_STATUS = 0x30,
+    MDRII_GET_DIR = 0x31,
+    MDRII_GET_DATA_INFO = 0x32,
+    MDRII_LOCK_DATA = 0x33,
+    MDRII_UNLOCK_DATA = 0x34,
+    MDRII_GET_DATA_BLOCK = 0x35,
+    MDRII_SEND_DIR = 0x38,
+    MDRII_SEND_DATA_INFO_OFFER = 0x39,
+    MDRII_SEND_DATA_INFO = 0x3a,
+    MDRII_DATA_START = 0x3b,
+    MDRII_DATA_DONE = 0x3c,
+    MDRII_SEND_DATA_BLOCK = 0x3d,
+};
+
+enum class IPMINetFnIntelOemGeneralCmds
+{
+    GetSmSignal = 0x14,
+    SetSmSignal = 0x15,
+    BmcControlServices = 0xC0,
+    SetSensorOverride = 0xEE,
+};
diff --git a/include/smbioshandler.hpp b/include/smbioshandler.hpp
new file mode 100644
index 0000000..4e403ca
--- /dev/null
+++ b/include/smbioshandler.hpp
@@ -0,0 +1,100 @@
+/*
+// 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 <cstddef>
+#include <cstdint>
+#include <oemcommands.hpp>
+
+#include "ipmid/api.h"
+
+constexpr uint16_t msgPayloadSize = 1024 * 60;
+
+typedef enum
+{
+    regionLockUnlocked = 0,
+    regionLockStrict,
+    regionLockPreemptable
+} MDRLockType;
+
+typedef struct
+{
+    uint8_t DirVer;
+    uint8_t MDRType;
+    uint16_t timestamp;
+    uint16_t DataSize;
+} __attribute__((packed)) MDRSmbios_Header;
+
+typedef struct
+{
+    uint8_t MdrVersion;
+    uint8_t regionId;
+    bool valid;
+    uint8_t updateCount;
+    uint8_t lockPolicy;
+    uint16_t regionLength;
+    uint16_t regionUsed;
+    uint8_t CRC8;
+} __attribute__((packed)) MDRState;
+
+struct RegionStatusRequest
+{
+    uint8_t regionId;
+} __attribute__((packed));
+
+struct RegionStatusResponse
+{
+    MDRState State;
+} __attribute__((packed));
+
+struct RegionCompleteRequest
+{
+    uint8_t sessionId;
+    uint8_t regionId;
+} __attribute__((packed));
+
+struct RegionReadRequest
+{
+    uint8_t regionId;
+    uint8_t length;
+    uint16_t offset;
+} __attribute__((packed));
+
+struct RegionReadResponse
+{
+    uint8_t length;
+    uint8_t updateCount;
+    uint8_t data[msgPayloadSize];
+} __attribute__((packed));
+
+struct RegionWriteRequest
+{
+    uint8_t sessionId;
+    uint8_t regionId;
+    uint8_t length;
+    uint16_t offset;
+    uint8_t data[msgPayloadSize];
+} __attribute__((packed));
+
+struct RegionLockRequest
+{
+    uint8_t sessionId;
+    uint8_t regionId;
+    uint8_t lockPolicy;
+    uint16_t msTimeout;
+} __attribute__((packed));
+
+constexpr size_t maxMDRId = 5;
diff --git a/include/smbiosmdrv2.hpp b/include/smbiosmdrv2.hpp
new file mode 100644
index 0000000..9736ee8
--- /dev/null
+++ b/include/smbiosmdrv2.hpp
@@ -0,0 +1,205 @@
+/*
+// 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.h>
+
+#include <oemcommands.hpp>
+
+constexpr uint8_t maxDirEntries = 4;
+constexpr uint16_t msgPayloadSize = 1024 * 60;
+constexpr uint32_t smbiosTableStorageSize = 64 * 1024;
+constexpr uint32_t mdriiSMSize = 0x00100000;
+
+struct DataIdStruct
+{
+    uint8_t dataInfo[16];
+} __attribute__((packed));
+
+struct Mdr2DirEntry
+{
+    DataIdStruct Id;
+    uint32_t size;
+    uint32_t dataSetSize;
+    uint32_t dataVersion;
+    uint32_t timestamp;
+} __attribute__((packed));
+
+// ====================== MDR II Pull Command Structures ======================
+// MDR II Pull Agent status inquiry command
+struct MDRiiGetAgentStatus
+{
+    uint16_t agentId;
+    uint8_t dirVersion;
+} __attribute__((packed));
+
+// MDR II status inquiry response
+struct MDRiiAgentStatusResponse
+{
+    uint8_t mdrVersion;
+    uint8_t agentVersion;
+    uint8_t dirVersion;
+    uint8_t dirEntries;
+    uint8_t dataRequest;
+} __attribute__((packed));
+
+// MDR II Pull Agent directory information inquiry command
+struct MDRiiGetDirRequest
+{
+    uint16_t agentId;
+    uint8_t dirIndex;
+} __attribute__((packed));
+
+// MDR II directory information inquiry response
+struct MDRiiGetDirResponse
+{
+    uint8_t mdrVersion;
+    uint8_t dirVersion;
+    uint8_t returnedEntries;
+    uint8_t remainingEntries;
+    uint8_t data[1];
+} __attribute__((packed));
+
+// MDR II Pull Agent data set information inquiry command
+struct MDRiiGetDataInfoRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+} __attribute__((packed));
+
+// MDR II data set information inquiry response
+struct MDRiiGetDataInfoResponse
+{
+    uint8_t mdrVersion;
+    DataIdStruct dataSetId;
+    uint8_t validFlag;
+    uint32_t dataLength;
+    uint32_t dataVersion;
+    uint32_t timeStamp;
+} __attribute__((packed));
+
+// MDR II Pull Agent lock data set command
+struct MDRiiLockDataRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+    uint16_t timeout;
+} __attribute__((packed));
+
+// MDR II Pull Agent lock data set response
+struct MDRiiLockDataResponse
+{
+    uint8_t mdrVersion;
+    uint16_t lockHandle;
+    uint32_t dataLength;
+    uint32_t xferAddress;
+    uint32_t xferLength;
+} __attribute__((packed));
+
+// MDR II Pull Agent unlock data set command
+struct MDRiiUnlockDataRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+} __attribute__((packed));
+
+// MDR II Pull Agent get data block command
+struct MDRiiGetDataBlockRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+    uint32_t xferOffset;
+    uint32_t xferLength;
+} __attribute__((packed));
+
+// MDR II Pull Agent get data block response
+struct MDRiiGetDataBlockResponse
+{
+    uint32_t xferLength;
+    uint32_t checksum;
+    uint8_t data[msgPayloadSize];
+} __attribute__((packed));
+
+// ====================== MDR II Push Command Structures ======================
+// MDR II Push Agent send dir info command
+struct MDRiiSendDirRequest
+{
+    uint16_t agentId;
+    uint8_t dirVersion;
+    uint8_t dirIndex;
+    uint8_t returnedEntries;
+    uint8_t remainingEntries;
+    Mdr2DirEntry data[1]; // place holder for N directory entries
+} __attribute__((packed));
+
+// MDR II Push Agent offer data set info command
+struct MDRiiOfferDataInfo
+{
+    uint16_t agentId;
+} __attribute__((packed));
+
+// MDR II Client send data set info offer response
+struct MDRiiOfferDataInfoResponse
+{
+    DataIdStruct dataSetInfo;
+} __attribute__((packed));
+
+// MDR II Push Agent send data set info command
+struct MDRiiSendDataInfoRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+    uint8_t validFlag;
+    uint32_t dataLength;
+    uint32_t dataVersion; // Roughly equivalent to the "file name"
+    uint32_t
+        timeStamp; // More info on the identity of this particular set of data
+} __attribute__((packed));
+
+// MDR II Push Agent send data start command
+struct MDRiiDataStartRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+    uint32_t dataLength;
+    uint32_t xferAddress;
+    uint32_t xferLength;
+    uint16_t timeout;
+} __attribute__((packed));
+
+// MDR II Client send data start response
+struct MDRiiDataStartResponse
+{
+    uint8_t xferStartAck;
+    uint16_t sessionHandle;
+} __attribute__((packed));
+
+// MDR II
+struct MDRiiDataDoneRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+} __attribute__((packed));
+
+// MDR II Push Agent send data block command
+struct MDRiiSendDataBlockRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+    uint32_t xferOffset;
+    uint32_t xferLength;
+    uint32_t checksum;
+} __attribute__((packed));
diff --git a/include/smbiosmdrv2handler.hpp b/include/smbiosmdrv2handler.hpp
new file mode 100644
index 0000000..636cbdb
--- /dev/null
+++ b/include/smbiosmdrv2handler.hpp
@@ -0,0 +1,401 @@
+/*
+// 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.h>
+#include <sys/mman.h>
+
+#include <oemcommands.hpp>
+#include <sdbusplus/timer.hpp>
+
+static constexpr const char *mdrType2File = "/var/lib/smbios/smbios2";
+static constexpr const char *smbiosPath = "/var/lib/smbios";
+static constexpr const size_t msgPayloadSize =
+    1024 * 60; // Total size will transfer for smbios table
+static constexpr const size_t mdriiSMSize = 0x00100000;
+
+static constexpr const uint16_t smbiosAgentId =
+    0x0101; // Agent ID for smbios entry
+static constexpr const int firstAgentIndex = 1;
+
+static constexpr const uint8_t maxDirEntries = 4; // Maximum directory entries
+static constexpr const uint32_t mdr2SMSize =
+    0x00100000; // Size of VGA share memory
+static constexpr const uint32_t mdr2SMBaseAddress =
+    0x9FF00000; // Base address of VGA share memory
+
+static constexpr const uint8_t mdrTypeII = 2; // MDR V2 type
+
+static constexpr const uint8_t mdr2Version = 2;        // MDR V2 versoin
+static constexpr const uint8_t smbiosAgentVersion = 1; // Agent version of
+                                                       // smbios
+
+static constexpr const uint32_t pageMask =
+    0xf000; // To make data become n times of page
+static constexpr const int smbiosDirIndex = 0; // SMBIOS directory index
+
+static constexpr const uint32_t smbiosTableVersion =
+    15; // Version of smbios table
+static constexpr const uint32_t smbiosTableTimestamp =
+    0x45464748; // Time stamp when smbios table created
+static constexpr const size_t smbiosSMMemoryOffset =
+    0; // Offset of VGA share memory
+static constexpr const size_t smbiosSMMemorySize =
+    1024 * 1024; // Total size of VGA share memory
+static constexpr const size_t smbiosTableStorageSize =
+    64 * 1024; // Total size of smbios table
+static constexpr const uint32_t defaultTimeout = 200;
+static constexpr const uint8_t sysClock = 100;
+static constexpr const int lastAgentIndex = -1;
+static constexpr const uint16_t lastAgentId = 0xFFFF;
+constexpr const uint32_t invalidChecksum = 0xffffffff;
+constexpr const char *dbusProperties = "org.freedesktop.DBus.Properties";
+constexpr const char *mdrv2Path = "/xyz/openbmc_project/Smbios/MDR_V2";
+constexpr const char *mdrv2Interface = "xyz.openbmc_project.Smbios.MDR_V2";
+
+enum class MDR2SMBIOSStatusEnum
+{
+    mdr2Init = 0,
+    mdr2Loaded = 1,
+    mdr2Updated = 2,
+    mdr2Updating = 3
+};
+
+enum class DirDataRequestEnum
+{
+    dirDataNotRequested = 0x00,
+    dirDataRequested = 0x01
+};
+
+enum MDR2DirLockEnum
+{
+    mdr2DirUnlock = 0,
+    mdr2DirLock = 1
+};
+
+#pragma pack(push)
+#pragma pack(1)
+
+struct MDRSMBIOSHeader
+{
+    uint8_t dirVer;
+    uint8_t mdrType;
+    uint32_t timestamp;
+    uint32_t dataSize;
+};
+
+struct DataIdStruct
+{
+    uint8_t dataInfo[16];
+};
+
+struct Mdr2DirEntry
+{
+    DataIdStruct id;
+    uint32_t size;
+    uint32_t dataSetSize;
+    uint32_t dataVersion;
+    uint32_t timestamp;
+};
+
+struct Mdr2DirLocalStruct
+{
+    Mdr2DirEntry common;
+    MDR2SMBIOSStatusEnum stage;
+    MDR2DirLockEnum lock;
+    uint16_t lockHandle;
+    uint32_t xferBuff;
+    uint32_t xferSize;
+    uint32_t maxDataSize;
+    uint8_t *dataStorage;
+};
+
+struct Mdr2DirStruct
+{
+    uint8_t agentVersion;
+    uint8_t dirVersion;
+    uint8_t dirEntries;
+    uint8_t status; // valid / locked / etc
+    uint8_t remoteDirVersion;
+    uint16_t sessionHandle;
+    Mdr2DirLocalStruct dir[maxDirEntries];
+};
+
+// Three members include dataSetSize, dataVersion and timestamp
+static constexpr const size_t syncDirCommonSize = 3;
+
+// ====================== MDR II Pull Command Structures ======================
+// MDR II Pull Agent status inquiry command
+struct MDRiiGetAgentStatus
+{
+    uint16_t agentId;
+    uint8_t dirVersion;
+};
+
+// MDR II status inquiry response
+struct MDRiiAgentStatusResponse
+{
+    uint8_t mdrVersion;
+    uint8_t agentVersion;
+    uint8_t dirVersion;
+    uint8_t dirEntries;
+    uint8_t dataRequest;
+};
+
+struct MDRiiGetDirRequest
+{
+    uint16_t agentId;
+    uint8_t dirIndex;
+};
+
+// MDR II directory information inquiry response
+struct MDRiiGetDirResponse
+{
+    uint8_t mdrVersion;
+    uint8_t dirVersion;
+    uint8_t returnedEntries;
+    uint8_t remainingEntries;
+    uint8_t data[1];
+};
+
+struct MDRiiGetDataInfoRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+};
+
+// MDR II data set information inquiry response
+struct MDRiiGetDataInfoResponse
+{
+    uint8_t mdrVersion;
+    DataIdStruct dataSetId;
+    uint8_t validFlag;
+    uint32_t dataLength;
+    uint32_t dataVersion;
+    uint32_t timeStamp;
+};
+
+// MDR II Pull Agent get data block command
+struct MDRiiGetDataBlockRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+    uint32_t xferOffset;
+    uint32_t xferLength;
+};
+
+// MDR II Pull Agent get data block response
+struct MDRiiGetDataBlockResponse
+{
+    uint32_t xferLength;
+    uint32_t checksum;
+    uint8_t data[msgPayloadSize];
+};
+
+// ====================== MDR II Push Command Structures ======================
+// MDR II Push Agent send dir info command
+struct MDRiiSendDirRequest
+{
+    uint16_t agentId;
+    uint8_t dirVersion;
+    uint8_t dirIndex;
+    uint8_t returnedEntries;
+    uint8_t remainingEntries;
+    Mdr2DirEntry data[1]; // place holder for N directory entries
+};
+
+struct MDRiiOfferDataInfo
+{
+    uint16_t agentId;
+};
+
+// MDR II Client send data set info offer response
+struct MDRiiOfferDataInfoResponse
+{
+    DataIdStruct dataSetInfo;
+};
+
+// MDR II Push Agent send data set info command
+struct MDRiiSendDataInfoRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+    uint8_t validFlag;
+    uint32_t dataLength;
+    uint32_t dataVersion; // Roughly equivalent to the "file name"
+    uint32_t
+        timeStamp; // More info on the identity of this particular set of data
+};
+
+// MDR II Push Agent send data block command
+struct MDRiiSendDataBlockRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+    uint32_t xferOffset;
+    uint32_t xferLength;
+    uint32_t checksum;
+};
+
+// MDR II Pull Agent lock data set command
+struct MDRiiLockDataRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+    uint16_t timeout;
+};
+
+// MDR II Pull Agent lock data set response
+struct MDRiiLockDataResponse
+{
+    uint8_t mdrVersion;
+    uint16_t lockHandle;
+    uint32_t dataLength;
+    uint32_t xferAddress;
+    uint32_t xferLength;
+};
+
+// MDR II Pull Agent unlock data set command
+struct MDRiiUnlockDataRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+};
+
+// MDR II Push Agent send data start command
+struct MDRiiDataStartRequest
+{
+    uint16_t agentId;
+    DataIdStruct dataSetInfo;
+    uint32_t dataLength;
+    uint32_t xferAddress;
+    uint32_t xferLength;
+    uint16_t timeout;
+};
+
+// MDR II Client send data start response
+struct MDRiiDataStartResponse
+{
+    uint8_t xferStartAck;
+    uint16_t sessionHandle;
+};
+
+// MDR II
+struct MDRiiDataDoneRequest
+{
+    uint16_t agentId;
+    uint16_t lockHandle;
+};
+
+#pragma pack(pop)
+
+class SharedMemoryArea
+{
+  public:
+    SharedMemoryArea(uint32_t addr, uint32_t areaSize) :
+        vPtr(nullptr), physicalAddr(addr), size(areaSize)
+    {
+        Initialize(addr, areaSize);
+    }
+
+    ~SharedMemoryArea()
+    {
+        if ((vPtr != nullptr) && (vPtr != MAP_FAILED))
+        {
+            if (0 != munmap(vPtr, size))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Ummap share memory failed");
+            }
+        }
+    }
+
+    void *vPtr;
+
+  private:
+    uint32_t physicalAddr;
+    uint32_t size;
+
+    void Initialize(uint32_t addr, uint32_t areaSize);
+};
+
+class MDRV2
+{
+  public:
+    MDRV2()
+    {
+        timer =
+            std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
+    }
+
+    int agentLookup(const uint16_t &agentId);
+    int findLockHandle(const uint16_t &lockHandle);
+    int syncDirCommonData(uint8_t idIndex, uint32_t size,
+                          const std::string &service);
+    int findDataId(const uint8_t *dataInfo, const size_t &len,
+                   const std::string &service);
+    uint16_t getSessionHandle(Mdr2DirStruct *dir);
+    bool smbiosIsUpdating(uint8_t index);
+    uint32_t calcChecksum32(uint8_t *buf, uint32_t len);
+    bool storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data);
+    bool smbiosUnlock(uint8_t index);
+    void timeoutHandler();
+    bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
+                       uint16_t timeout);
+    int sdplusMdrv2GetProperty(const std::string &name,
+                               sdbusplus::message::variant<uint8_t> &value,
+                               const std::string &service);
+
+    Mdr2DirStruct smbiosDir{smbiosAgentVersion,
+                            1,
+                            1,
+                            1,
+                            0,
+                            0,
+                            {40,
+                             41,
+                             42,
+                             43,
+                             44,
+                             45,
+                             46,
+                             47,
+                             48,
+                             49,
+                             50,
+                             51,
+                             52,
+                             53,
+                             54,
+                             0x42,
+                             0,
+                             smbiosTableStorageSize,
+                             smbiosTableVersion,
+                             smbiosTableTimestamp,
+                             MDR2SMBIOSStatusEnum::mdr2Init,
+                             MDR2DirLockEnum::mdr2DirUnlock,
+                             0,
+                             smbiosSMMemoryOffset,
+                             smbiosSMMemorySize,
+                             smbiosTableStorageSize,
+                             smbiosTableStorage}};
+    std::unique_ptr<SharedMemoryArea> area;
+    std::unique_ptr<phosphor::Timer> timer;
+
+  private:
+    uint8_t lockIndex = 0;
+    uint8_t smbiosTableStorage[smbiosTableStorageSize];
+};
diff --git a/include/variantvisitors.hpp b/include/variantvisitors.hpp
new file mode 100644
index 0000000..f8dbb0c
--- /dev/null
+++ b/include/variantvisitors.hpp
@@ -0,0 +1,27 @@
+/*
+// Copyright (c) 2017 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>
+#include <limits>
+#include <sdbusplus/bus.hpp>
+namespace ipmi
+{
+
+using DbusVariant =
+    sdbusplus::message::variant<std::string, bool, uint8_t, uint16_t, int16_t,
+                                uint32_t, int32_t, uint64_t, int64_t, double>;
+} // namespace ipmi
diff --git a/non-yocto/phosphor-logging/elog-errors.hpp b/non-yocto/phosphor-logging/elog-errors.hpp
new file mode 100644
index 0000000..b87236a
--- /dev/null
+++ b/non-yocto/phosphor-logging/elog-errors.hpp
@@ -0,0 +1,2528 @@
+// This file was autogenerated.  Do not edit!
+// See elog-gen.py for more details
+#pragma once
+
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/exception.hpp>
+#include <string>
+#include <tuple>
+#include <type_traits>
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Dump
+{
+namespace Create
+{
+namespace Error
+{
+struct QuotaExceeded;
+} // namespace Error
+} // namespace Create
+} // namespace Dump
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace Inventory
+{
+namespace Error
+{
+struct Fan;
+} // namespace Error
+} // namespace Inventory
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Device
+{
+namespace Error
+{
+struct ReadFailure;
+} // namespace Error
+} // namespace Device
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Host
+{
+namespace Error
+{
+struct SoftOffTimeout;
+} // namespace Error
+} // namespace Host
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace File
+{
+namespace Error
+{
+struct Open;
+} // namespace Error
+} // namespace File
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Inventory
+{
+namespace Error
+{
+struct Nonfunctional;
+} // namespace Error
+} // namespace Inventory
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Control
+{
+namespace Device
+{
+namespace Error
+{
+struct WriteFailure;
+} // namespace Error
+} // namespace Device
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace File
+{
+namespace Error
+{
+struct Seek;
+} // namespace Error
+} // namespace File
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace Error
+{
+struct UserNameDoesNotExist;
+} // namespace Error
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace File
+{
+namespace Error
+{
+struct Write;
+} // namespace Error
+} // namespace File
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Inventory
+{
+namespace Error
+{
+struct NotPresent;
+} // namespace Error
+} // namespace Inventory
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Error
+{
+struct InternalFailure;
+} // namespace Error
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace Error
+{
+struct Device;
+} // namespace Error
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Sensor
+{
+namespace Threshold
+{
+namespace Error
+{
+struct CriticalLow;
+} // namespace Error
+} // namespace Threshold
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Sensor
+{
+namespace Threshold
+{
+namespace Error
+{
+struct CriticalHigh;
+} // namespace Error
+} // namespace Threshold
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Sensor
+{
+namespace Device
+{
+namespace Error
+{
+struct ReadFailure;
+} // namespace Error
+} // namespace Device
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Control
+{
+namespace Host
+{
+namespace Error
+{
+struct CommandNotSupported;
+} // namespace Error
+} // namespace Host
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace Error
+{
+struct UserNameGrpPrivFail;
+} // namespace Error
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace Error
+{
+struct GPIO;
+} // namespace Error
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Error
+{
+struct InvalidArgument;
+} // namespace Error
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace Error
+{
+struct NoResource;
+} // namespace Error
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Device
+{
+namespace Error
+{
+struct WriteFailure;
+} // namespace Error
+} // namespace Device
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Error
+{
+struct InsufficientPermission;
+} // namespace Error
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Dump
+{
+namespace Create
+{
+namespace Error
+{
+struct Disabled;
+} // namespace Error
+} // namespace Create
+} // namespace Dump
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace Error
+{
+struct IPMISensor;
+} // namespace Error
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Error
+{
+struct Timeout;
+} // namespace Error
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace Error
+{
+struct Inventory;
+} // namespace Error
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace Error
+{
+struct IIC;
+} // namespace Error
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace ThermalEvent
+{
+namespace Error
+{
+struct GPU;
+} // namespace Error
+} // namespace ThermalEvent
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace Power
+{
+namespace Error
+{
+struct Fault;
+} // namespace Error
+} // namespace Power
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace Error
+{
+struct UserNameExists;
+} // namespace Error
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace ThermalEvent
+{
+namespace Error
+{
+struct Processor;
+} // namespace Error
+} // namespace ThermalEvent
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace phosphor
+{
+
+namespace logging
+{
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Control
+{
+namespace Host
+{
+namespace _CommandNotSupported
+{
+
+} // namespace _CommandNotSupported
+
+struct CommandNotSupported
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Host
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Control::Host::Error::CommandNotSupported>
+{
+    using type = xyz::openbmc_project::Control::Host::CommandNotSupported;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Sensor
+{
+namespace Threshold
+{
+namespace _CriticalHigh
+{
+
+struct SENSOR_DATA
+{
+    static constexpr auto str = "SENSOR_DATA=%s";
+    static constexpr auto str_short = "SENSOR_DATA";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr SENSOR_DATA(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _CriticalHigh
+
+struct CriticalHigh
+{
+    static constexpr auto L = level::ERR;
+    using SENSOR_DATA = _CriticalHigh::SENSOR_DATA;
+    using metadata_types = std::tuple<SENSOR_DATA>;
+};
+
+} // namespace Threshold
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Sensor::Threshold::Error::CriticalHigh>
+{
+    using type = xyz::openbmc_project::Sensor::Threshold::CriticalHigh;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Sensor
+{
+namespace Threshold
+{
+namespace _CriticalLow
+{
+
+struct SENSOR_DATA
+{
+    static constexpr auto str = "SENSOR_DATA=%s";
+    static constexpr auto str_short = "SENSOR_DATA";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr SENSOR_DATA(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _CriticalLow
+
+struct CriticalLow
+{
+    static constexpr auto L = level::ERR;
+    using SENSOR_DATA = _CriticalLow::SENSOR_DATA;
+    using metadata_types = std::tuple<SENSOR_DATA>;
+};
+
+} // namespace Threshold
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Sensor::Threshold::Error::CriticalLow>
+{
+    using type = xyz::openbmc_project::Sensor::Threshold::CriticalLow;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace ThermalEvent
+{
+namespace _Processor
+{
+
+} // namespace _Processor
+
+struct Processor
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace ThermalEvent
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::State::Shutdown::
+                              ThermalEvent::Error::Processor>
+{
+    using type = xyz::openbmc_project::State::Shutdown::ThermalEvent::Processor;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace ThermalEvent
+{
+namespace _GPU
+{
+
+} // namespace _GPU
+
+struct GPU
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace ThermalEvent
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::State::Shutdown::ThermalEvent::Error::GPU>
+{
+    using type = xyz::openbmc_project::State::Shutdown::ThermalEvent::GPU;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Dump
+{
+namespace Create
+{
+namespace _Disabled
+{
+
+} // namespace _Disabled
+
+struct Disabled
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Create
+} // namespace Dump
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Dump::Create::Error::Disabled>
+{
+    using type = xyz::openbmc_project::Dump::Create::Disabled;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Dump
+{
+namespace Create
+{
+namespace _QuotaExceeded
+{
+
+struct REASON
+{
+    static constexpr auto str = "REASON = %s";
+    static constexpr auto str_short = "REASON ";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr REASON(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _QuotaExceeded
+
+struct QuotaExceeded
+{
+    static constexpr auto L = level::ERR;
+    using REASON = _QuotaExceeded::REASON;
+    using metadata_types = std::tuple<REASON>;
+};
+
+} // namespace Create
+} // namespace Dump
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded>
+{
+    using type = xyz::openbmc_project::Dump::Create::QuotaExceeded;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace _Timeout
+{
+
+struct TIMEOUT_IN_MSEC
+{
+    static constexpr auto str = "TIMEOUT_IN_MSEC=%llu";
+    static constexpr auto str_short = "TIMEOUT_IN_MSEC";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint64_t>;
+    explicit constexpr TIMEOUT_IN_MSEC(uint64_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Timeout
+
+struct Timeout
+{
+    static constexpr auto L = level::ERR;
+    using TIMEOUT_IN_MSEC = _Timeout::TIMEOUT_IN_MSEC;
+    using metadata_types = std::tuple<TIMEOUT_IN_MSEC>;
+};
+
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Error::Timeout>
+{
+    using type = xyz::openbmc_project::Common::Timeout;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace _InternalFailure
+{
+
+} // namespace _InternalFailure
+
+struct InternalFailure
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>
+{
+    using type = xyz::openbmc_project::Common::InternalFailure;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace _InvalidArgument
+{
+
+struct ARGUMENT_NAME
+{
+    static constexpr auto str = "ARGUMENT_NAME=%s";
+    static constexpr auto str_short = "ARGUMENT_NAME";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr ARGUMENT_NAME(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct ARGUMENT_VALUE
+{
+    static constexpr auto str = "ARGUMENT_VALUE=%s";
+    static constexpr auto str_short = "ARGUMENT_VALUE";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr ARGUMENT_VALUE(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _InvalidArgument
+
+struct InvalidArgument
+{
+    static constexpr auto L = level::ERR;
+    using ARGUMENT_NAME = _InvalidArgument::ARGUMENT_NAME;
+    using ARGUMENT_VALUE = _InvalidArgument::ARGUMENT_VALUE;
+    using metadata_types = std::tuple<ARGUMENT_NAME, ARGUMENT_VALUE>;
+};
+
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument>
+{
+    using type = xyz::openbmc_project::Common::InvalidArgument;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace _InsufficientPermission
+{
+
+} // namespace _InsufficientPermission
+
+struct InsufficientPermission
+{
+    static constexpr auto L = level::INFO;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Error::InsufficientPermission>
+{
+    using type = xyz::openbmc_project::Common::InsufficientPermission;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace _UserNameExists
+{
+
+} // namespace _UserNameExists
+
+struct UserNameExists
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameExists>
+{
+    using type = xyz::openbmc_project::User::Common::UserNameExists;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace _UserNameDoesNotExist
+{
+
+} // namespace _UserNameDoesNotExist
+
+struct UserNameDoesNotExist
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameDoesNotExist>
+{
+    using type = xyz::openbmc_project::User::Common::UserNameDoesNotExist;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace _UserNameGrpPrivFail
+{
+
+struct REASON
+{
+    static constexpr auto str = "REASON = %s";
+    static constexpr auto str_short = "REASON ";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr REASON(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _UserNameGrpPrivFail
+
+struct UserNameGrpPrivFail
+{
+    static constexpr auto L = level::ERR;
+    using REASON = _UserNameGrpPrivFail::REASON;
+    using metadata_types = std::tuple<REASON>;
+};
+
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameGrpPrivFail>
+{
+    using type = xyz::openbmc_project::User::Common::UserNameGrpPrivFail;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace User
+{
+namespace Common
+{
+namespace _NoResource
+{
+
+struct REASON
+{
+    static constexpr auto str = "REASON = %s";
+    static constexpr auto str_short = "REASON ";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr REASON(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _NoResource
+
+struct NoResource
+{
+    static constexpr auto L = level::ERR;
+    using REASON = _NoResource::REASON;
+    using metadata_types = std::tuple<REASON>;
+};
+
+} // namespace Common
+} // namespace User
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource>
+{
+    using type = xyz::openbmc_project::User::Common::NoResource;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace File
+{
+namespace _Open
+{
+
+struct ERRNO
+{
+    static constexpr auto str = "ERRNO=%d";
+    static constexpr auto str_short = "ERRNO";
+    using type = std::tuple<std::decay_t<decltype(str)>, int32_t>;
+    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct PATH
+{
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Open
+
+struct Open
+{
+    static constexpr auto L = level::ERR;
+    using ERRNO = _Open::ERRNO;
+    using PATH = _Open::PATH;
+    using metadata_types = std::tuple<ERRNO, PATH>;
+};
+
+} // namespace File
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::File::Error::Open>
+{
+    using type = xyz::openbmc_project::Common::File::Open;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace File
+{
+namespace _Seek
+{
+
+struct OFFSET
+{
+    static constexpr auto str = "OFFSET=%ll";
+    static constexpr auto str_short = "OFFSET";
+    using type = std::tuple<std::decay_t<decltype(str)>, int64_t>;
+    explicit constexpr OFFSET(int64_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct WHENCE
+{
+    static constexpr auto str = "WHENCE=%d";
+    static constexpr auto str_short = "WHENCE";
+    using type = std::tuple<std::decay_t<decltype(str)>, int32_t>;
+    explicit constexpr WHENCE(int32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct ERRNO
+{
+    static constexpr auto str = "ERRNO=%d";
+    static constexpr auto str_short = "ERRNO";
+    using type = std::tuple<std::decay_t<decltype(str)>, int32_t>;
+    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct PATH
+{
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Seek
+
+struct Seek
+{
+    static constexpr auto L = level::ERR;
+    using OFFSET = _Seek::OFFSET;
+    using WHENCE = _Seek::WHENCE;
+    using ERRNO = _Seek::ERRNO;
+    using PATH = _Seek::PATH;
+    using metadata_types = std::tuple<OFFSET, WHENCE, ERRNO, PATH>;
+};
+
+} // namespace File
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::File::Error::Seek>
+{
+    using type = xyz::openbmc_project::Common::File::Seek;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace File
+{
+namespace _Write
+{
+
+struct ERRNO
+{
+    static constexpr auto str = "ERRNO=%d";
+    static constexpr auto str_short = "ERRNO";
+    using type = std::tuple<std::decay_t<decltype(str)>, int32_t>;
+    explicit constexpr ERRNO(int32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct PATH
+{
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Write
+
+struct Write
+{
+    static constexpr auto L = level::ERR;
+    using ERRNO = _Write::ERRNO;
+    using PATH = _Write::PATH;
+    using metadata_types = std::tuple<ERRNO, PATH>;
+};
+
+} // namespace File
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::File::Error::Write>
+{
+    using type = xyz::openbmc_project::Common::File::Write;
+};
+
+} // namespace details
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Device
+{
+namespace _Callout
+{
+
+struct CALLOUT_ERRNO_TEST
+{
+    static constexpr auto str = "CALLOUT_ERRNO_TEST=%d";
+    static constexpr auto str_short = "CALLOUT_ERRNO_TEST";
+    using type = std::tuple<std::decay_t<decltype(str)>, int32_t>;
+    explicit constexpr CALLOUT_ERRNO_TEST(int32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct CALLOUT_DEVICE_PATH_TEST
+{
+    static constexpr auto str = "CALLOUT_DEVICE_PATH_TEST=%s";
+    static constexpr auto str_short = "CALLOUT_DEVICE_PATH_TEST";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr CALLOUT_DEVICE_PATH_TEST(const char* a) :
+        _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Callout
+
+struct Callout : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Device.Callout";
+    static constexpr auto errDesc = "Generic device callout";
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO_TEST = _Callout::CALLOUT_ERRNO_TEST;
+    using CALLOUT_DEVICE_PATH_TEST = _Callout::CALLOUT_DEVICE_PATH_TEST;
+    using metadata_types =
+        std::tuple<CALLOUT_ERRNO_TEST, CALLOUT_DEVICE_PATH_TEST>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Device
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _Device
+{
+
+struct CALLOUT_ERRNO
+{
+    static constexpr auto str = "CALLOUT_ERRNO=%d";
+    static constexpr auto str_short = "CALLOUT_ERRNO";
+    using type = std::tuple<std::decay_t<decltype(str)>, int32_t>;
+    explicit constexpr CALLOUT_ERRNO(int32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct CALLOUT_DEVICE_PATH
+{
+    static constexpr auto str = "CALLOUT_DEVICE_PATH=%s";
+    static constexpr auto str_short = "CALLOUT_DEVICE_PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr CALLOUT_DEVICE_PATH(const char* a) :
+        _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Device
+
+struct Device
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO = _Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH = _Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Callout::Error::Device>
+{
+    using type = xyz::openbmc_project::Common::Callout::Device;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _GPIO
+{
+
+struct CALLOUT_GPIO_NUM
+{
+    static constexpr auto str = "CALLOUT_GPIO_NUM=%u";
+    static constexpr auto str_short = "CALLOUT_GPIO_NUM";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint32_t>;
+    explicit constexpr CALLOUT_GPIO_NUM(uint32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _GPIO
+
+struct GPIO
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_GPIO_NUM = _GPIO::CALLOUT_GPIO_NUM;
+    using CALLOUT_ERRNO =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types =
+        std::tuple<CALLOUT_GPIO_NUM, CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>
+{
+    using type = xyz::openbmc_project::Common::Callout::GPIO;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _IIC
+{
+
+struct CALLOUT_IIC_BUS
+{
+    static constexpr auto str = "CALLOUT_IIC_BUS=%s";
+    static constexpr auto str_short = "CALLOUT_IIC_BUS";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr CALLOUT_IIC_BUS(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct CALLOUT_IIC_ADDR
+{
+    static constexpr auto str = "CALLOUT_IIC_ADDR=0x%hx";
+    static constexpr auto str_short = "CALLOUT_IIC_ADDR";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint16_t>;
+    explicit constexpr CALLOUT_IIC_ADDR(uint16_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _IIC
+
+struct IIC
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_IIC_BUS = _IIC::CALLOUT_IIC_BUS;
+    using CALLOUT_IIC_ADDR = _IIC::CALLOUT_IIC_ADDR;
+    using CALLOUT_ERRNO =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_IIC_BUS, CALLOUT_IIC_ADDR,
+                                      CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Callout::Error::IIC>
+{
+    using type = xyz::openbmc_project::Common::Callout::IIC;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _Inventory
+{
+
+struct CALLOUT_INVENTORY_PATH
+{
+    static constexpr auto str = "CALLOUT_INVENTORY_PATH=%s";
+    static constexpr auto str_short = "CALLOUT_INVENTORY_PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr CALLOUT_INVENTORY_PATH(const char* a) :
+        _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Inventory
+
+struct Inventory
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_INVENTORY_PATH = _Inventory::CALLOUT_INVENTORY_PATH;
+    using metadata_types = std::tuple<CALLOUT_INVENTORY_PATH>;
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Callout::Error::Inventory>
+{
+    using type = xyz::openbmc_project::Common::Callout::Inventory;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _IPMISensor
+{
+
+struct CALLOUT_IPMI_SENSOR_NUM
+{
+    static constexpr auto str = "CALLOUT_IPMI_SENSOR_NUM=%u";
+    static constexpr auto str_short = "CALLOUT_IPMI_SENSOR_NUM";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint32_t>;
+    explicit constexpr CALLOUT_IPMI_SENSOR_NUM(uint32_t a) :
+        _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _IPMISensor
+
+struct IPMISensor
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_IPMI_SENSOR_NUM = _IPMISensor::CALLOUT_IPMI_SENSOR_NUM;
+    using metadata_types = std::tuple<CALLOUT_IPMI_SENSOR_NUM>;
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Callout::Error::IPMISensor>
+{
+    using type = xyz::openbmc_project::Common::Callout::IPMISensor;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Device
+{
+namespace _ReadFailure
+{
+
+} // namespace _ReadFailure
+
+struct ReadFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Device
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Device::Error::ReadFailure>
+{
+    using type = xyz::openbmc_project::Common::Device::ReadFailure;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Device
+{
+namespace _WriteFailure
+{
+
+} // namespace _WriteFailure
+
+struct WriteFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Device
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Common::Device::Error::WriteFailure>
+{
+    using type = xyz::openbmc_project::Common::Device::WriteFailure;
+};
+
+} // namespace details
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Elog
+{
+namespace _TestErrorTwo
+{
+
+struct DEV_ADDR
+{
+    static constexpr auto str = "DEV_ADDR=0x%.8X";
+    static constexpr auto str_short = "DEV_ADDR";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint32_t>;
+    explicit constexpr DEV_ADDR(uint32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct DEV_ID
+{
+    static constexpr auto str = "DEV_ID=%u";
+    static constexpr auto str_short = "DEV_ID";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint32_t>;
+    explicit constexpr DEV_ID(uint32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct DEV_NAME
+{
+    static constexpr auto str = "DEV_NAME=%s";
+    static constexpr auto str_short = "DEV_NAME";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr DEV_NAME(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _TestErrorTwo
+
+struct TestErrorTwo : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Elog.TestErrorTwo";
+    static constexpr auto errDesc = "This is test error two";
+    static constexpr auto L = level::ERR;
+    using DEV_ADDR = _TestErrorTwo::DEV_ADDR;
+    using DEV_ID = _TestErrorTwo::DEV_ID;
+    using DEV_NAME = _TestErrorTwo::DEV_NAME;
+    using metadata_types = std::tuple<DEV_ADDR, DEV_ID, DEV_NAME>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Elog
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Elog
+{
+namespace _AutoTestSimple
+{
+
+struct STRING
+{
+    static constexpr auto str = "STRING=%s";
+    static constexpr auto str_short = "STRING";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr STRING(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _AutoTestSimple
+
+struct AutoTestSimple : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Elog.AutoTestSimple";
+    static constexpr auto errDesc = "This is a simple test error.";
+    static constexpr auto L = level::ERR;
+    using STRING = _AutoTestSimple::STRING;
+    using metadata_types = std::tuple<STRING>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Elog
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Elog
+{
+namespace _TestCallout
+{
+
+struct DEV_ADDR
+{
+    static constexpr auto str = "DEV_ADDR=0x%.8X";
+    static constexpr auto str_short = "DEV_ADDR";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint32_t>;
+    explicit constexpr DEV_ADDR(uint32_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _TestCallout
+
+struct TestCallout : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Elog.TestCallout";
+    static constexpr auto errDesc = "This is test error TestCallout";
+    static constexpr auto L = level::ERR;
+    using DEV_ADDR = _TestCallout::DEV_ADDR;
+    using CALLOUT_ERRNO_TEST = example::xyz::openbmc_project::Example::Device::
+        Callout::CALLOUT_ERRNO_TEST;
+    using CALLOUT_DEVICE_PATH_TEST = example::xyz::openbmc_project::Example::
+        Device::Callout::CALLOUT_DEVICE_PATH_TEST;
+    using metadata_types =
+        std::tuple<DEV_ADDR, CALLOUT_ERRNO_TEST, CALLOUT_DEVICE_PATH_TEST>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Elog
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace Inventory
+{
+namespace _Fan
+{
+
+} // namespace _Fan
+
+struct Fan
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Inventory
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::State::Shutdown::Inventory::Error::Fan>
+{
+    using type = xyz::openbmc_project::State::Shutdown::Inventory::Fan;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Shutdown
+{
+namespace Power
+{
+namespace _Fault
+{
+
+} // namespace _Fault
+
+struct Fault
+{
+    static constexpr auto L = level::ERR;
+    using metadata_types = std::tuple<>;
+};
+
+} // namespace Power
+} // namespace Shutdown
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::State::Shutdown::Power::Error::Fault>
+{
+    using type = xyz::openbmc_project::State::Shutdown::Power::Fault;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Sensor
+{
+namespace Device
+{
+namespace _ReadFailure
+{
+
+} // namespace _ReadFailure
+
+struct ReadFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Device
+} // namespace Sensor
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Sensor::Device::Error::ReadFailure>
+{
+    using type = xyz::openbmc_project::Sensor::Device::ReadFailure;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace Host
+{
+namespace _SoftOffTimeout
+{
+
+} // namespace _SoftOffTimeout
+
+struct SoftOffTimeout
+{
+    static constexpr auto L = level::ERR;
+    using TIMEOUT_IN_MSEC =
+        xyz::openbmc_project::Common::Timeout::TIMEOUT_IN_MSEC;
+    using metadata_types = std::tuple<TIMEOUT_IN_MSEC>;
+};
+
+} // namespace Host
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::State::Host::Error::SoftOffTimeout>
+{
+    using type = xyz::openbmc_project::State::Host::SoftOffTimeout;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Inventory
+{
+namespace _NotPresent
+{
+
+} // namespace _NotPresent
+
+struct NotPresent
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_INVENTORY_PATH = xyz::openbmc_project::Common::Callout::
+        Inventory::CALLOUT_INVENTORY_PATH;
+    using metadata_types = std::tuple<CALLOUT_INVENTORY_PATH>;
+};
+
+} // namespace Inventory
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Inventory::Error::NotPresent>
+{
+    using type = xyz::openbmc_project::Inventory::NotPresent;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Inventory
+{
+namespace _Nonfunctional
+{
+
+} // namespace _Nonfunctional
+
+struct Nonfunctional
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_INVENTORY_PATH = xyz::openbmc_project::Common::Callout::
+        Inventory::CALLOUT_INVENTORY_PATH;
+    using metadata_types = std::tuple<CALLOUT_INVENTORY_PATH>;
+};
+
+} // namespace Inventory
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Inventory::Error::Nonfunctional>
+{
+    using type = xyz::openbmc_project::Inventory::Nonfunctional;
+};
+
+} // namespace details
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Control
+{
+namespace Device
+{
+namespace _WriteFailure
+{
+
+} // namespace _WriteFailure
+
+struct WriteFailure
+{
+    static constexpr auto L = level::ERR;
+    using CALLOUT_ERRNO =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_ERRNO;
+    using CALLOUT_DEVICE_PATH =
+        xyz::openbmc_project::Common::Callout::Device::CALLOUT_DEVICE_PATH;
+    using metadata_types = std::tuple<CALLOUT_ERRNO, CALLOUT_DEVICE_PATH>;
+};
+
+} // namespace Device
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+
+namespace details
+{
+
+template <>
+struct map_exception_type<
+    sdbusplus::xyz::openbmc_project::Control::Device::Error::WriteFailure>
+{
+    using type = xyz::openbmc_project::Control::Device::WriteFailure;
+};
+
+} // namespace details
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Elog
+{
+namespace _TestErrorOne
+{
+
+struct ERRNUM
+{
+    static constexpr auto str = "ERRNUM=0x%.4X";
+    static constexpr auto str_short = "ERRNUM";
+    using type = std::tuple<std::decay_t<decltype(str)>, uint16_t>;
+    explicit constexpr ERRNUM(uint16_t a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct FILE_PATH
+{
+    static constexpr auto str = "FILE_PATH=%s";
+    static constexpr auto str_short = "FILE_PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr FILE_PATH(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+struct FILE_NAME
+{
+    static constexpr auto str = "FILE_NAME=%s";
+    static constexpr auto str_short = "FILE_NAME";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr FILE_NAME(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _TestErrorOne
+
+struct TestErrorOne : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Elog.TestErrorOne";
+    static constexpr auto errDesc = "this is test error one";
+    static constexpr auto L = level::INFO;
+    using ERRNUM = _TestErrorOne::ERRNUM;
+    using FILE_PATH = _TestErrorOne::FILE_PATH;
+    using FILE_NAME = _TestErrorOne::FILE_NAME;
+    using DEV_ADDR =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_ADDR;
+    using DEV_ID =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_ID;
+    using DEV_NAME =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_NAME;
+    using metadata_types =
+        std::tuple<ERRNUM, FILE_PATH, FILE_NAME, DEV_ADDR, DEV_ID, DEV_NAME>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Elog
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Foo
+{
+namespace _Foo
+{
+
+struct FOO_DATA
+{
+    static constexpr auto str = "FOO_DATA=%s";
+    static constexpr auto str_short = "FOO_DATA";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr FOO_DATA(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Foo
+
+struct Foo : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Foo.Foo";
+    static constexpr auto errDesc = "this is test error Foo";
+    static constexpr auto L = level::INFO;
+    using FOO_DATA = _Foo::FOO_DATA;
+    using ERRNUM =
+        example::xyz::openbmc_project::Example::Elog::TestErrorOne::ERRNUM;
+    using FILE_PATH =
+        example::xyz::openbmc_project::Example::Elog::TestErrorOne::FILE_PATH;
+    using FILE_NAME =
+        example::xyz::openbmc_project::Example::Elog::TestErrorOne::FILE_NAME;
+    using DEV_ADDR =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_ADDR;
+    using DEV_ID =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_ID;
+    using DEV_NAME =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_NAME;
+    using metadata_types = std::tuple<FOO_DATA, ERRNUM, FILE_PATH, FILE_NAME,
+                                      DEV_ADDR, DEV_ID, DEV_NAME>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Foo
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+namespace example
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Example
+{
+namespace Bar
+{
+namespace _Bar
+{
+
+struct BAR_DATA
+{
+    static constexpr auto str = "BAR_DATA=%s";
+    static constexpr auto str_short = "BAR_DATA";
+    using type = std::tuple<std::decay_t<decltype(str)>, const char*>;
+    explicit constexpr BAR_DATA(const char* a) : _entry(entry(str, a)){};
+    type _entry;
+};
+
+} // namespace _Bar
+
+struct Bar : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "example.xyz.openbmc_project.Example.Bar.Bar";
+    static constexpr auto errDesc = "this is test error Bar";
+    static constexpr auto L = level::INFO;
+    using BAR_DATA = _Bar::BAR_DATA;
+    using FOO_DATA = example::xyz::openbmc_project::Example::Foo::Foo::FOO_DATA;
+    using ERRNUM =
+        example::xyz::openbmc_project::Example::Elog::TestErrorOne::ERRNUM;
+    using FILE_PATH =
+        example::xyz::openbmc_project::Example::Elog::TestErrorOne::FILE_PATH;
+    using FILE_NAME =
+        example::xyz::openbmc_project::Example::Elog::TestErrorOne::FILE_NAME;
+    using DEV_ADDR =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_ADDR;
+    using DEV_ID =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_ID;
+    using DEV_NAME =
+        example::xyz::openbmc_project::Example::Elog::TestErrorTwo::DEV_NAME;
+    using metadata_types = std::tuple<BAR_DATA, FOO_DATA, ERRNUM, FILE_PATH,
+                                      FILE_NAME, DEV_ADDR, DEV_ID, DEV_NAME>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Bar
+} // namespace Example
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace example
+
+} // namespace logging
+
+} // namespace phosphor
diff --git a/non-yocto/xyz/openbmc_project/Common/error.hpp b/non-yocto/xyz/openbmc_project/Common/error.hpp
new file mode 100644
index 0000000..d7c38e2
--- /dev/null
+++ b/non-yocto/xyz/openbmc_project/Common/error.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include <sdbusplus/exception.hpp>
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Common
+{
+namespace Error
+{
+
+struct Timeout final : public sdbusplus::exception_t
+{
+    static constexpr auto errName = "xyz.openbmc_project.Common.Error.Timeout";
+    static constexpr auto errDesc = "Operation timed out.";
+    static constexpr auto errWhat =
+        "xyz.openbmc_project.Common.Error.Timeout: Operation timed out.";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+struct InternalFailure final : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "xyz.openbmc_project.Common.Error.InternalFailure";
+    static constexpr auto errDesc = "The operation failed internally.";
+    static constexpr auto errWhat =
+        "xyz.openbmc_project.Common.Error.InternalFailure: The operation "
+        "failed internally.";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+struct InvalidArgument final : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "xyz.openbmc_project.Common.Error.InvalidArgument";
+    static constexpr auto errDesc = "Invalid argument was given.";
+    static constexpr auto errWhat =
+        "xyz.openbmc_project.Common.Error.InvalidArgument: Invalid argument "
+        "was given.";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+struct InsufficientPermission final : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "xyz.openbmc_project.Common.Error.InsufficientPermission";
+    static constexpr auto errDesc =
+        "Insufficient permission to perform operation";
+    static constexpr auto errWhat =
+        "xyz.openbmc_project.Common.Error.InsufficientPermission: Insufficient "
+        "permission to perform operation";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+} // namespace Error
+} // namespace Common
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
diff --git a/non-yocto/xyz/openbmc_project/Smbios/MDR_V2/error.hpp b/non-yocto/xyz/openbmc_project/Smbios/MDR_V2/error.hpp
new file mode 100644
index 0000000..e26c13d
--- /dev/null
+++ b/non-yocto/xyz/openbmc_project/Smbios/MDR_V2/error.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <sdbusplus/exception.hpp>
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Smbios
+{
+namespace MDR_V2
+{
+namespace Error
+{
+
+struct InvalidParameter final : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "xyz.openbmc_project.Smbios.MDR_V2.Error.InvalidParameter";
+    static constexpr auto errDesc = "An invalid parameter is attempted.";
+    static constexpr auto errWhat =
+        "xyz.openbmc_project.Smbios.MDR_V2.Error.InvalidParameter: An invalid "
+        "parameter is attempted.";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+struct UpdateInProgress final : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "xyz.openbmc_project.Smbios.MDR_V2.Error.UpdateInProgress";
+    static constexpr auto errDesc = "Update is in progress.";
+    static constexpr auto errWhat = "xyz.openbmc_project.Smbios.MDR_V2.Error."
+                                    "UpdateInProgress: Update is in progress.";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+struct InvalidId final : public sdbusplus::exception_t
+{
+    static constexpr auto errName =
+        "xyz.openbmc_project.Smbios.MDR_V2.Error.InvalidId";
+    static constexpr auto errDesc = "An invalid Id is attempted.";
+    static constexpr auto errWhat = "xyz.openbmc_project.Smbios.MDR_V2.Error."
+                                    "InvalidId: An invalid Id is attempted.";
+
+    const char* name() const noexcept override;
+    const char* description() const noexcept override;
+    const char* what() const noexcept override;
+};
+
+} // namespace Error
+} // namespace MDR_V2
+} // namespace Smbios
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
diff --git a/src/bmccontrolservices.cpp b/src/bmccontrolservices.cpp
new file mode 100644
index 0000000..2bebab5
--- /dev/null
+++ b/src/bmccontrolservices.cpp
@@ -0,0 +1,153 @@
+/*
+// 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 "oemcommands.hpp"
+
+#include <openssl/hmac.h>
+
+#include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+
+void register_netfn_bmc_control_functions() __attribute__((constructor));
+
+enum ipmi_bmc_control_services_return_codes
+{
+    ipmiCCBmcControlInvalidBitMask = 0xCC,
+    ipmiCCBmcControlPasswdInvalid = 0xCD,
+    ipmiCCBmcControlInvalidChannel = 0xD4,
+};
+
+// TODO: Add other services, once they are supported
+static const std::unordered_map<uint8_t, std::string> bmcServices = {
+    {3, "netipmid"},
+    {5, "web"},
+    {6, "ssh"},
+};
+
+static constexpr const char* objectManagerIntf =
+    "org.freedesktop.DBus.ObjectManager";
+static constexpr const char* serviceConfigBasePath =
+    "/xyz/openbmc_project/control/service";
+static constexpr const char* serviceConfigAttrIntf =
+    "xyz.openbmc_project.Control.Service.Attributes";
+static constexpr const char* serviceStateProperty = "State";
+static std::string disableServiceValue = "disabled";
+
+static ipmi_ret_t disableBmcServices(const std::string& objName)
+{
+    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+    static std::string serviceCfgMgr{};
+    if (serviceCfgMgr.empty())
+    {
+        try
+        {
+            serviceCfgMgr = ipmi::getService(*dbus, objectManagerIntf,
+                                             serviceConfigBasePath);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            serviceCfgMgr.clear();
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Error: In fetching disabling service manager name");
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+    }
+    auto path = std::string(serviceConfigBasePath) + "/" + objName;
+    try
+    {
+        ipmi::setDbusProperty(*dbus, serviceCfgMgr, path, serviceConfigAttrIntf,
+                              serviceStateProperty,
+                              ipmi::Value(disableServiceValue));
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "Disabling service",
+            phosphor::logging::entry("PATH=%s", path.c_str()),
+            phosphor::logging::entry("MGR_NAME=%s", serviceCfgMgr.c_str()));
+        return IPMI_CC_OK;
+    }
+    catch (const sdbusplus::exception_t&)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error: Disabling service",
+            phosphor::logging::entry("PATH=%s", path.c_str()),
+            phosphor::logging::entry("MGR_NAME=%s", serviceCfgMgr.c_str()));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+}
+
+static constexpr size_t controlPasswdSize = 32;
+
+ipmi::RspType<> bmcIntelControlServices(
+    ipmi::Context::ptr ctx,
+    const std::array<uint8_t, controlPasswdSize>& passwd, uint8_t stdServices,
+    uint8_t oemServices)
+{
+    // Execute this command only in KCS interface
+    if (ctx->channel != interfaceKCS)
+    {
+        return ipmi::response(ipmiCCBmcControlInvalidChannel);
+    }
+
+    static std::string hashData("Intel 0penBMC");
+    static std::vector<uint8_t> hashedValue = {
+        0x89, 0x6A, 0xAB, 0x7D, 0xB0, 0x5A, 0x2D, 0x92, 0x41, 0xAD, 0x92,
+        0xEE, 0xD4, 0x82, 0xDE, 0x62, 0x66, 0x16, 0xC1, 0x08, 0xFD, 0x23,
+        0xC6, 0xD8, 0x75, 0xB3, 0x52, 0x53, 0x31, 0x3C, 0x7F, 0x69};
+    std::vector<uint8_t> hashedOutput(EVP_MAX_MD_SIZE, 0);
+    unsigned int outputLen = 0;
+    HMAC(EVP_sha256(), passwd.data(), passwd.size(),
+         reinterpret_cast<const uint8_t*>(hashData.c_str()), hashData.length(),
+         &hashedOutput[0], &outputLen);
+    hashedOutput.resize(outputLen);
+
+    if (hashedOutput != hashedValue)
+    {
+        return ipmi::response(ipmiCCBmcControlPasswdInvalid);
+    }
+
+    if (stdServices == 0 && oemServices == 0)
+    {
+        return ipmi::response(ipmiCCBmcControlInvalidBitMask);
+    }
+
+    ipmi_ret_t retVal = IPMI_CC_OK;
+    for (size_t bitIndex = 0; bitIndex < 8; ++bitIndex)
+    {
+        if (stdServices & (1 << bitIndex))
+        {
+            auto it = bmcServices.find(bitIndex);
+            if (it == bmcServices.end())
+            {
+                return ipmi::response(ipmiCCBmcControlInvalidBitMask);
+            }
+            retVal = disableBmcServices(it->second);
+            if (retVal != IPMI_CC_OK)
+            {
+                return ipmi::response(retVal);
+            }
+        }
+    }
+    return ipmi::responseSuccess();
+}
+
+void register_netfn_bmc_control_functions()
+{
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, netfnIntcOEMGeneral,
+                          static_cast<ipmi_cmd_t>(
+                              IPMINetFnIntelOemGeneralCmds::BmcControlServices),
+                          ipmi::Privilege::User, bmcIntelControlServices);
+}
diff --git a/src/bridgingcommands.cpp b/src/bridgingcommands.cpp
new file mode 100644
index 0000000..0c727f6
--- /dev/null
+++ b/src/bridgingcommands.cpp
@@ -0,0 +1,514 @@
+/*
+// 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 <ipmid/api.h>
+
+#include <bridgingcommands.hpp>
+#include <cstring>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <vector>
+
+static constexpr const char *ipmbBus = "xyz.openbmc_project.Ipmi.Channel.Ipmb";
+static constexpr const char *ipmbObj = "/xyz/openbmc_project/Ipmi/Channel/Ipmb";
+static constexpr const char *ipmbIntf = "org.openbmc.Ipmb";
+
+static Bridging bridging;
+
+/**
+ * @brief utils for checksum
+ */
+static bool ipmbChecksumValidate(uint8_t *data, uint8_t length)
+{
+    if (data == nullptr)
+    {
+        return false;
+    }
+
+    uint8_t checksum = 0;
+
+    for (uint8_t idx = 0; idx < length; idx++)
+    {
+        checksum += data[idx];
+    }
+
+    if (0 == checksum)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+static uint8_t ipmbChecksumCompute(uint8_t *data, uint8_t length)
+{
+    if (data == nullptr)
+    {
+        return 0;
+    }
+
+    uint8_t checksum = 0;
+
+    for (uint8_t idx = 0; idx < length; idx++)
+    {
+        checksum += data[idx];
+    }
+
+    checksum = (~checksum) + 1;
+    return checksum;
+}
+
+static inline bool ipmbConnectionHeaderChecksumValidate(ipmbHeader *ipmbHeader)
+{
+    return ipmbChecksumValidate(reinterpret_cast<uint8_t *>(ipmbHeader),
+                                ipmbConnectionHeaderLength);
+}
+
+static inline bool ipmbDataChecksumValidate(ipmbHeader *ipmbHeader,
+                                            uint8_t length)
+{
+    return ipmbChecksumValidate(
+        (reinterpret_cast<uint8_t *>(ipmbHeader) + ipmbConnectionHeaderLength),
+        (length - ipmbConnectionHeaderLength));
+}
+
+static bool isFrameValid(ipmbHeader *frame, uint8_t length)
+{
+    if ((length < ipmbMinFrameLength) || (length > ipmbMaxFrameLength))
+    {
+        return false;
+    }
+
+    if (false == ipmbConnectionHeaderChecksumValidate(frame))
+    {
+        return false;
+    }
+
+    if (false == ipmbDataChecksumValidate(frame, length))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+IpmbRequest::IpmbRequest(const ipmbHeader *ipmbBuffer, size_t bufferLength)
+{
+    address = ipmbBuffer->Header.Req.address;
+    netFn = ipmbNetFnGet(ipmbBuffer->Header.Req.rsNetFnLUN);
+    rsLun = ipmbLunFromNetFnLunGet(ipmbBuffer->Header.Req.rsNetFnLUN);
+    rqSA = ipmbBuffer->Header.Req.rqSA;
+    seq = ipmbSeqGet(ipmbBuffer->Header.Req.rqSeqLUN);
+    rqLun = ipmbLunFromSeqLunGet(ipmbBuffer->Header.Req.rqSeqLUN);
+    cmd = ipmbBuffer->Header.Req.cmd;
+
+    size_t dataLength =
+        bufferLength - (ipmbConnectionHeaderLength +
+                        ipmbRequestDataHeaderLength + ipmbChecksumSize);
+
+    if (dataLength > 0)
+    {
+        data.insert(data.end(), ipmbBuffer->Header.Req.data,
+                    &ipmbBuffer->Header.Req.data[dataLength]);
+    }
+}
+
+IpmbResponse::IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun,
+                           uint8_t rsSA, uint8_t seq, uint8_t rsLun,
+                           uint8_t cmd, uint8_t completionCode,
+                           std::vector<uint8_t> &inputData) :
+    address(address),
+    netFn(netFn), rqLun(rqLun), rsSA(rsSA), seq(seq), rsLun(rsLun), cmd(cmd),
+    completionCode(completionCode)
+{
+    data.reserve(ipmbMaxDataSize);
+
+    if (inputData.size() > 0)
+    {
+        data = std::move(inputData);
+    }
+}
+
+void IpmbResponse::ipmbToi2cConstruct(uint8_t *buffer, size_t *bufferLength)
+{
+    ipmbHeader *ipmbBuffer = (ipmbHeader *)buffer;
+
+    ipmbBuffer->Header.Resp.address = address;
+    ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun);
+    ipmbBuffer->Header.Resp.rsSA = rsSA;
+    ipmbBuffer->Header.Resp.rsSeqLUN = ipmbSeqLunSet(seq, rsLun);
+    ipmbBuffer->Header.Resp.cmd = cmd;
+    ipmbBuffer->Header.Resp.completionCode = completionCode;
+
+    ipmbBuffer->Header.Resp.checksum1 = ipmbChecksumCompute(
+        buffer, ipmbConnectionHeaderLength - ipmbChecksumSize);
+
+    if (data.size() > 0)
+    {
+        std::copy(
+            data.begin(), data.end(),
+            &buffer[ipmbConnectionHeaderLength + ipmbResponseDataHeaderLength]);
+    }
+
+    *bufferLength = data.size() + ipmbResponseDataHeaderLength +
+                    ipmbConnectionHeaderLength + ipmbChecksumSize;
+
+    buffer[*bufferLength - ipmbChecksumSize] =
+        ipmbChecksumCompute(&buffer[ipmbChecksum2StartOffset],
+                            (ipmbResponseDataHeaderLength + data.size()));
+}
+
+void IpmbRequest::prepareRequest(sdbusplus::message::message &mesg)
+{
+    mesg.append(ipmbMeChannelNum, netFn, rqLun, cmd, data);
+}
+
+Bridging::Bridging() : dbus(ipmid_get_sd_bus_connection())
+{
+}
+
+ipmi_return_codes Bridging::handleIpmbChannel(sSendMessageReq *sendMsgReq,
+                                              ipmi_response_t response,
+                                              ipmi_data_len_t dataLen)
+{
+    if ((*dataLen < (sizeof(sSendMessageReq) + ipmbMinFrameLength)) ||
+        (*dataLen > (sizeof(sSendMessageReq) + ipmbMaxFrameLength)))
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto sendMsgReqData = reinterpret_cast<ipmbHeader *>(sendMsgReq->data);
+
+    // TODO: check privilege lvl. Bridging to ME requires Administrator lvl
+
+    // allow bridging to ME only
+    if (sendMsgReqData->Header.Req.address != ipmbMeSlaveAddress)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "handleIpmbChannel, IPMB address invalid");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // check allowed modes
+    if (sendMsgReq->modeGet() != modeNoTracking &&
+        sendMsgReq->modeGet() != modeTrackRequest)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "handleIpmbChannel, mode not supported");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // check if request contains valid IPMB frame
+    if (!isFrameValid(sendMsgReqData, (*dataLen - sizeof(sSendMessageReq))))
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "handleIpmbChannel, IPMB frame invalid");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    auto ipmbRequest =
+        IpmbRequest(sendMsgReqData, (*dataLen - sizeof(sSendMessageReq)));
+
+    std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
+        ipmbResponse;
+
+    // send request to IPMB
+    try
+    {
+        auto mesg =
+            dbus.new_method_call(ipmbBus, ipmbObj, ipmbIntf, "sendRequest");
+        ipmbRequest.prepareRequest(mesg);
+        auto ret = dbus.call(mesg);
+        ret.read(ipmbResponse);
+    }
+    catch (sdbusplus::exception::SdBusError &e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "handleIpmbChannel, dbus call exception");
+        *dataLen = 0;
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    std::vector<uint8_t> dataReceived(0);
+    int status = -1;
+    uint8_t netFn = 0, lun = 0, cmd = 0, cc = 0;
+
+    std::tie(status, netFn, lun, cmd, cc, dataReceived) = ipmbResponse;
+
+    auto respReceived =
+        IpmbResponse(ipmbRequest.rqSA, netFn, lun, ipmbRequest.address,
+                     ipmbRequest.seq, lun, cmd, cc, dataReceived);
+
+    // check IPMB layer status
+    if (status)
+    {
+        phosphor::logging::log<phosphor::logging::level::WARNING>(
+            "handleIpmbChannel, ipmb returned non zero status");
+        *dataLen = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    auto sendMsgRes = reinterpret_cast<uint8_t *>(response);
+
+    switch (sendMsgReq->modeGet())
+    {
+        case modeNoTracking:
+            if (responseQueue.size() == responseQueueMaxSize)
+            {
+                *dataLen = 0;
+                return IPMI_CC_BUSY;
+            }
+            responseQueue.insert(responseQueue.end(), std::move(respReceived));
+            *dataLen = 0;
+            return IPMI_CC_OK;
+
+            break;
+        case modeTrackRequest:
+            respReceived.ipmbToi2cConstruct(sendMsgRes, dataLen);
+            return IPMI_CC_OK;
+
+            break;
+        default:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "handleIpmbChannel, mode not supported");
+            *dataLen = 0;
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    *dataLen = 0;
+    return IPMI_CC_UNSPECIFIED_ERROR;
+}
+
+ipmi_return_codes Bridging::sendMessageHandler(ipmi_request_t request,
+                                               ipmi_response_t response,
+                                               ipmi_data_len_t dataLen)
+{
+    ipmi_return_codes retCode = IPMI_CC_OK;
+
+    if (*dataLen < sizeof(sSendMessageReq))
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto sendMsgReq = reinterpret_cast<sSendMessageReq *>(request);
+
+    // check message fields:
+    // encryption not supported
+    if (sendMsgReq->encryptionGet() != 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "sendMessageHandler, encryption not supported");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // authentication not supported
+    if (sendMsgReq->authenticationGet() != 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "sendMessageHandler, authentication not supported");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    switch (sendMsgReq->channelNumGet())
+    {
+        // we only handle ipmb for now
+        case targetChannelIpmb:
+        case targetChannelOtherLan:
+            retCode = handleIpmbChannel(sendMsgReq, response, dataLen);
+            break;
+        // fall through to default
+        case targetChannelIcmb10:
+        case targetChannelIcmb09:
+        case targetChannelLan:
+        case targetChannelSerialModem:
+        case targetChannelPciSmbus:
+        case targetChannelSmbus10:
+        case targetChannelSmbus20:
+        case targetChannelSystemInterface:
+        default:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "sendMessageHandler, TargetChannel invalid");
+            *dataLen = 0;
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    return retCode;
+}
+
+ipmi_return_codes Bridging::getMessageHandler(ipmi_request_t request,
+                                              ipmi_response_t response,
+                                              ipmi_data_len_t dataLen)
+{
+    if (*dataLen != 0)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto getMsgRes = reinterpret_cast<sGetMessageRes *>(response);
+    auto getMsgResData = static_cast<uint8_t *>(getMsgRes->data);
+
+    std::memset(getMsgRes, 0, sizeof(sGetMessageRes));
+
+    auto respQueueItem = responseQueue.begin();
+
+    if (respQueueItem == responseQueue.end())
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "getMessageHandler, no data available");
+        *dataLen = 0;
+        return ipmiGetMessageCmdDataNotAvailable;
+    }
+
+    // set message fields
+    getMsgRes->privilegeLvlSet(SYSTEM_INTERFACE);
+    getMsgRes->channelNumSet(targetChannelSystemInterface);
+
+    // construct response
+    respQueueItem->ipmbToi2cConstruct(getMsgResData, dataLen);
+    responseQueue.erase(respQueueItem);
+
+    *dataLen = *dataLen + sizeof(sGetMessageRes);
+    return IPMI_CC_OK;
+}
+
+ipmi_return_codes Bridging::getMessageFlagsHandler(ipmi_request_t request,
+                                                   ipmi_response_t response,
+                                                   ipmi_data_len_t dataLen)
+{
+    if (*dataLen != 0)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto getMsgFlagsRes = reinterpret_cast<sGetMessageFlagsResp *>(response);
+
+    std::memset(getMsgFlagsRes, 0, sizeof(sGetMessageFlagsResp));
+
+    // preserve current (legacy) behaviour
+    getMsgFlagsRes->eventMessageBitSet(1);
+
+    // set message fields
+    if (responseQueue.size() > 0)
+    {
+        getMsgFlagsRes->receiveMessageBitSet(1);
+    }
+    else
+    {
+        getMsgFlagsRes->receiveMessageBitSet(0);
+    }
+
+    *dataLen = sizeof(sGetMessageFlagsResp);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_return_codes Bridging::clearMessageFlagsHandler(ipmi_request_t request,
+                                                     ipmi_response_t response,
+                                                     ipmi_data_len_t dataLen)
+{
+    if (*dataLen != sizeof(sClearMessageFlagsReq))
+    {
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto clearMsgFlagsReq = reinterpret_cast<sClearMessageFlagsReq *>(request);
+
+    if (clearMsgFlagsReq->receiveMessageBitGet() == 1)
+    {
+        responseQueue.clear();
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiAppSendMessage(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                              ipmi_request_t request, ipmi_response_t response,
+                              ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.sendMessageHandler(request, response, dataLen);
+
+    return retCode;
+}
+
+ipmi_ret_t ipmiAppGetMessage(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.getMessageHandler(request, response, dataLen);
+
+    return retCode;
+}
+
+ipmi_ret_t ipmiAppGetMessageFlags(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                                  ipmi_request_t request,
+                                  ipmi_response_t response,
+                                  ipmi_data_len_t dataLen,
+                                  ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.getMessageFlagsHandler(request, response, dataLen);
+
+    return retCode;
+}
+
+ipmi_ret_t ipmiAppClearMessageFlags(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                                    ipmi_request_t request,
+                                    ipmi_response_t response,
+                                    ipmi_data_len_t dataLen,
+                                    ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.clearMessageFlagsHandler(request, response, dataLen);
+
+    *dataLen = 0;
+
+    return retCode;
+}
+
+static void register_bridging_functions() __attribute__((constructor));
+static void register_bridging_functions()
+{
+    ipmi_register_callback(
+        NETFUN_APP, Bridging::IpmiAppBridgingCmds::ipmiCmdClearMessageFlags,
+        NULL, ipmiAppClearMessageFlags, PRIVILEGE_USER);
+
+    ipmi_register_callback(
+        NETFUN_APP, Bridging::IpmiAppBridgingCmds::ipmiCmdGetMessageFlags, NULL,
+        ipmiAppGetMessageFlags, PRIVILEGE_USER);
+
+    ipmi_register_callback(NETFUN_APP,
+                           Bridging::IpmiAppBridgingCmds::ipmiCmdGetMessage,
+                           NULL, ipmiAppGetMessage, PRIVILEGE_USER);
+
+    ipmi_register_callback(NETFUN_APP,
+                           Bridging::IpmiAppBridgingCmds::ipmiCmdSendMessage,
+                           NULL, ipmiAppSendMessage, PRIVILEGE_USER);
+
+    return;
+}
diff --git a/src/manufacturingcommands.cpp b/src/manufacturingcommands.cpp
new file mode 100644
index 0000000..7bbb970
--- /dev/null
+++ b/src/manufacturingcommands.cpp
@@ -0,0 +1,628 @@
+/*
+// 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/process/child.hpp>
+#include <ipmid/api.hpp>
+#include <manufacturingcommands.hpp>
+#include <oemcommands.hpp>
+
+namespace ipmi
+{
+
+Manufacturing mtm;
+
+static auto revertTimeOut =
+    std::chrono::duration_cast<std::chrono::microseconds>(
+        std::chrono::seconds(60)); // 1 minute timeout
+
+static constexpr const char* idButtonPath =
+    "/xyz/openbmc_project/Chassis/Buttons/ID0";
+static constexpr const char* idButtonInterface =
+    "xyz.openbmc_project.Chassis.Buttons.ID";
+static constexpr const char* idButtonMemberPressed = "Pressed";
+
+static constexpr const char* callbackMgrService =
+    "xyz.openbmc_project.CallbackManager";
+static constexpr const char* callbackMgrIntf =
+    "xyz.openbmc_project.CallbackManager";
+static constexpr const char* callbackMgrObjPath =
+    "/xyz/openbmc_project/CallbackManager";
+static constexpr const char* retriggerLedUpdate = "RetriggerLEDUpdate";
+
+const static constexpr char* systemDService = "org.freedesktop.systemd1";
+const static constexpr char* systemDObjPath = "/org/freedesktop/systemd1";
+const static constexpr char* systemDMgrIntf =
+    "org.freedesktop.systemd1.Manager";
+const static constexpr char* pidControlService = "phosphor-pid-control.service";
+
+// TODO: Temporary place to test the working code. Will be moved to
+// gpio daemon
+constexpr const char* passthroughPath = "/usr/bin/set-passthrough.sh";
+void disablePassthrough(bool value)
+{
+    boost::process::child c(passthroughPath, value ? "0" : "1");
+    c.wait();
+}
+
+ipmi_ret_t ledStoreAndSet(SmSignalSet signal, std::string setState)
+{
+    LedProperty* ledProp = mtm.findLedProperty(signal);
+    if (ledProp == nullptr)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+
+    std::string ledName = ledProp->getName();
+    std::string ledService = ledServicePrefix + ledName;
+    std::string ledPath = ledPathPrefix + ledName;
+    ipmi::Value presentState;
+
+    if (false == ledProp->getLock())
+    {
+        if (mtm.getProperty(ledService.c_str(), ledPath.c_str(), ledIntf,
+                            "State", &presentState) != 0)
+        {
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        ledProp->setPrevState(std::get<std::string>(presentState));
+        ledProp->setLock(true);
+        if (signal == SmSignalSet::smPowerFaultLed ||
+            signal == SmSignalSet::smSystemReadyLed)
+        {
+            mtm.revertLedCallback = true;
+        }
+    }
+    if (mtm.setProperty(ledService.c_str(), ledPath.c_str(), ledIntf, "State",
+                        ledStateStr + setState) != 0)
+    {
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ledRevert(SmSignalSet signal)
+{
+    LedProperty* ledProp = mtm.findLedProperty(signal);
+    if (ledProp == nullptr)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    if (true == ledProp->getLock())
+    {
+        ledProp->setLock(false);
+        if (signal == SmSignalSet::smPowerFaultLed ||
+            signal == SmSignalSet::smSystemReadyLed)
+        {
+            try
+            {
+                ipmi::method_no_args::callDbusMethod(
+                    *getSdBus(), callbackMgrService, callbackMgrObjPath,
+                    callbackMgrIntf, retriggerLedUpdate);
+            }
+            catch (sdbusplus::exception_t& e)
+            {
+                return IPMI_CC_UNSPECIFIED_ERROR;
+            }
+            mtm.revertLedCallback = false;
+        }
+        else
+        {
+            std::string ledName = ledProp->getName();
+            std::string ledService = ledServicePrefix + ledName;
+            std::string ledPath = ledPathPrefix + ledName;
+            if (mtm.setProperty(ledService.c_str(), ledPath.c_str(), ledIntf,
+                                "State", ledProp->getPrevState()) != 0)
+            {
+                return IPMI_CC_UNSPECIFIED_ERROR;
+            }
+        }
+    }
+    return IPMI_CC_OK;
+}
+
+void Manufacturing::initData()
+{
+    gpioPaths[(uint8_t)SmSignalGet::smPowerButton] = "Power_Button";
+    gpioPaths[(uint8_t)SmSignalGet::smResetButton] = "Reset_Button";
+    gpioPaths[(uint8_t)SmSignalGet::smIdentifyButton] = "ID_Button";
+    gpioPaths[(uint8_t)SmSignalGet::smFpLcpEnterButton] = "Lcp_Enter_Button";
+    gpioPaths[(uint8_t)SmSignalGet::smFpLcpLeftButton] = "Lcp_Left_Button";
+    gpioPaths[(uint8_t)SmSignalGet::smFpLcpRightButton] = "Lcp_Right_Button";
+    gpioPaths[(uint8_t)SmSignalGet::smNmiButton] = "Nmi_Button";
+
+    ledPropertyList.push_back(
+        LedProperty(SmSignalSet::smPowerFaultLed, "status_amber"));
+    ledPropertyList.push_back(
+        LedProperty(SmSignalSet::smSystemReadyLed, "status_green"));
+    ledPropertyList.push_back(
+        LedProperty(SmSignalSet::smIdentifyLed, "identify"));
+}
+
+void Manufacturing::revertTimerHandler()
+{
+    for (const auto& signal : revertSmSignalGetVector)
+    {
+        mtm.setProperty(gpioService,
+                        mtm.getGpioPathForSmSignal((uint8_t)signal), gpioIntf,
+                        "Ignore", false);
+    }
+    revertSmSignalGetVector.clear();
+    disablePassthrough(false);
+    if (revertFanPWM)
+    {
+        revertFanPWM = false;
+        disablePidControlService(false);
+    }
+
+    for (const auto& ledProperty : ledPropertyList)
+    {
+        const std::string& ledName = ledProperty.getName();
+        ledRevert(ledProperty.getSignal());
+    }
+}
+
+Manufacturing::Manufacturing() :
+    revertTimer([&](void) { revertTimerHandler(); })
+{
+    initData();
+}
+
+int8_t Manufacturing::getProperty(const char* service, std::string path,
+                                  const char* interface,
+                                  std::string propertyName, ipmi::Value* reply)
+{
+    try
+    {
+        *reply = ipmi::getDbusProperty(*getSdBus(), service, path.c_str(),
+                                       interface, propertyName);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "ERROR: getProperty");
+        return -1;
+    }
+
+    return 0;
+}
+
+int8_t Manufacturing::setProperty(const char* service, std::string path,
+                                  const char* interface,
+                                  std::string propertyName, ipmi::Value value)
+{
+    try
+    {
+        ipmi::setDbusProperty(*getSdBus(), service, path.c_str(), interface,
+                              propertyName, value);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "ERROR: setProperty");
+        return -1;
+    }
+
+    return 0;
+}
+
+int8_t Manufacturing::disablePidControlService(const bool disable)
+{
+    try
+    {
+        auto dbus = getSdBus();
+        auto method = dbus->new_method_call(systemDService, systemDObjPath,
+                                            systemDMgrIntf,
+                                            disable ? "StopUnit" : "StartUnit");
+        method.append(pidControlService, "replace");
+        auto reply = dbus->call(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "ERROR: phosphor-pid-control service start or stop failed");
+        return -1;
+    }
+    return 0;
+}
+
+std::tuple<uint8_t, ipmi_ret_t, uint8_t>
+    Manufacturing::proccessSignal(SmSignalGet signal, SmActionGet action)
+{
+    int8_t ret = 0;
+    uint8_t retCode = 0;
+    uint8_t dataLen = 0;
+    uint8_t value = 0;
+    ipmi::Value reply;
+
+    switch (action)
+    {
+        case SmActionGet::sample:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "case SmActionGet::sample");
+            break;
+        case SmActionGet::ignore:
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "case SmActionGet::ignore");
+            if (std::find(revertSmSignalGetVector.begin(),
+                          revertSmSignalGetVector.end(),
+                          signal) == revertSmSignalGetVector.end())
+            {
+                // Todo: Needs to be replaced with pass-through of particular
+                // pin
+                disablePassthrough(true);
+                ret = mtm.setProperty(
+                    gpioService, mtm.getGpioPathForSmSignal((uint8_t)signal),
+                    gpioIntf, "Ignore", true);
+                if (ret < 0)
+                {
+                    dataLen = 0;
+                    retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                }
+                revertSmSignalGetVector.push_back(signal);
+                revertTimer.start(revertTimeOut);
+            }
+        }
+        break;
+        case SmActionGet::revert:
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "case SmActionGet::revert");
+            auto iter = std::find(revertSmSignalGetVector.begin(),
+                                  revertSmSignalGetVector.end(), signal);
+            if (iter != revertSmSignalGetVector.end())
+            {
+                ret = mtm.setProperty(
+                    gpioService, mtm.getGpioPathForSmSignal((uint8_t)signal),
+                    gpioIntf, "Ignore", false);
+                if (ret < 0)
+                {
+                    dataLen = 0;
+                    retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                }
+                revertSmSignalGetVector.erase(iter);
+                // Todo: Needs to be replaced with pass-through of particular
+                // pin
+                disablePassthrough(true);
+                if (revertSmSignalGetVector.size() == 0)
+                {
+                    revertTimer.stop();
+                }
+            }
+        }
+        break;
+
+        default:
+            dataLen = 0;
+            retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+            break;
+    }
+
+    if (ret == 0) // No error happend, cmd will return with gpio value
+    {
+        ret = mtm.getProperty(gpioService,
+                              mtm.getGpioPathForSmSignal((uint8_t)signal),
+                              gpioIntf, "SampledValue", &reply);
+        if (ret < 0)
+        {
+            dataLen = 0;
+            retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+        else
+        {
+            dataLen = 1;
+            value = std::get<bool>(reply);
+        }
+    }
+
+    return std::make_tuple(dataLen, retCode, value);
+}
+
+ipmi_ret_t ipmi_app_mtm_get_signal(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_ret_t retCode = IPMI_CC_OK;
+    int8_t ret = 0;
+    GetSmSignalReq* pReq = NULL;
+    GetSmSignalRsp* pRsp = NULL;
+
+    pReq = static_cast<GetSmSignalReq*>(request);
+    pRsp = static_cast<GetSmSignalRsp*>(response);
+
+    ipmi::Value reply;
+
+    if ((*data_len == sizeof(*pReq)) &&
+        (mtm.getAccessLvl() >= MtmLvl::mtmAvailable))
+    {
+        switch (pReq->Signal)
+        {
+            case SmSignalGet::smFanPwmGet:
+            {
+                std::string fullPath =
+                    fanPwmPath + std::to_string(pReq->Instance);
+                ret = mtm.getProperty(fanService, fullPath, fanIntf, "Value",
+                                      &reply);
+                if (ret < 0)
+                {
+                    *data_len = 0;
+                    retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                    break;
+                }
+                *data_len = 1;
+                pRsp->SigVal = std::get<double>(reply);
+            }
+            break;
+            case SmSignalGet::smFanTachometerGet:
+            {
+                // Full path calculation pattern:
+                // Instance 1 path is
+                // /xyz/openbmc_project/sensors/fan_tach/Fan_1a Instance 2 path
+                // is /xyz/openbmc_project/sensors/fan_tach/Fan_1b Instance 3
+                // path is /xyz/openbmc_project/sensors/fan_tach/Fan_2a
+                // and so on...
+                std::string fullPath = fanTachPathPrefix;
+                std::string fanAb = (pReq->Instance % 2) == 0 ? "b" : "a";
+                if (0 == pReq->Instance)
+                {
+                    *data_len = 0;
+                    retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                    break;
+                }
+                else if (0 == pReq->Instance / 2)
+                {
+                    fullPath += std::string("1") + fanAb;
+                }
+                else
+                {
+                    fullPath += std::to_string(pReq->Instance / 2) + fanAb;
+                }
+
+                ret = mtm.getProperty(fanService, fullPath, fanIntf, "Value",
+                                      &reply);
+                if (ret < 0)
+                {
+                    *data_len = 0;
+                    retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                    break;
+                }
+
+                uint16_t value = std::get<double>(reply);
+                *data_len = sizeof(*pRsp);
+
+                pRsp->SigVal = FAN_PRESENT | FAN_SENSOR_PRESENT;
+                pRsp->SigVal1 = value & 0x00FF;
+                pRsp->SigVal2 = (value >> 8) & 0xFF;
+            }
+            break;
+            case SmSignalGet::smResetButton:      // gpio32
+            case SmSignalGet::smPowerButton:      // gpio34
+            case SmSignalGet::smFpLcpEnterButton: // gpio51
+            case SmSignalGet::smFpLcpLeftButton:  // gpio52
+            case SmSignalGet::smFpLcpRightButton: // gpio53
+            case SmSignalGet::smNmiButton:        // gpio217
+            case SmSignalGet::smIdentifyButton:   // gpio218
+                std::tie(*data_len, retCode, pRsp->SigVal) =
+                    mtm.proccessSignal(pReq->Signal, pReq->Action);
+                *data_len = sizeof(pRsp->SigVal);
+                break;
+            default:
+                *data_len = 0;
+                retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                break;
+        }
+    }
+    else
+    {
+        *data_len = 0;
+        retCode = IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    return retCode;
+}
+
+ipmi_ret_t ipmi_app_mtm_set_signal(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)
+{
+    uint8_t ret = 0;
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    SetSmSignalReq* pReq = static_cast<SetSmSignalReq*>(request);
+    std::string ledName;
+    ///////////////////  Signal to led configuration ////////////////
+    //        {SM_SYSTEM_READY_LED, STAT_GRN_LED},    GPIOS4  gpio148
+    //        {SM_POWER_FAULT_LED, STAT_AMB_LED},     GPIOS5  gpio149
+    //        {SM_IDENTIFY_LED, IDENTIFY_LED},        GPIOS6  gpio150
+    //        {SM_SPEAKER, SPEAKER},                  GPIOAB0 gpio216
+    /////////////////////////////////////////////////////////////////
+    if ((*data_len == sizeof(*pReq)) &&
+        (mtm.getAccessLvl() >= MtmLvl::mtmAvailable))
+    {
+        switch (pReq->Signal)
+        {
+            case SmSignalSet::smPowerFaultLed:
+            case SmSignalSet::smSystemReadyLed:
+            case SmSignalSet::smIdentifyLed:
+                switch (pReq->Action)
+                {
+                    case SmActionSet::forceDeasserted:
+                    {
+                        phosphor::logging::log<phosphor::logging::level::INFO>(
+                            "case SmActionSet::forceDeasserted");
+
+                        retCode =
+                            ledStoreAndSet(pReq->Signal, std::string("Off"));
+                        if (retCode != IPMI_CC_OK)
+                        {
+                            break;
+                        }
+                        mtm.revertTimer.start(revertTimeOut);
+                    }
+                    break;
+                    case SmActionSet::forceAsserted:
+                    {
+                        phosphor::logging::log<phosphor::logging::level::INFO>(
+                            "case SmActionSet::forceAsserted");
+
+                        retCode =
+                            ledStoreAndSet(pReq->Signal, std::string("On"));
+                        if (retCode != IPMI_CC_OK)
+                        {
+                            break;
+                        }
+                        mtm.revertTimer.start(revertTimeOut);
+                        if (SmSignalSet::smPowerFaultLed == pReq->Signal)
+                        {
+                            // Deassert "system ready"
+                            retCode =
+                                ledStoreAndSet(SmSignalSet::smSystemReadyLed,
+                                               std::string("Off"));
+                            if (retCode != IPMI_CC_OK)
+                            {
+                                break;
+                            }
+                        }
+                        else if (SmSignalSet::smSystemReadyLed == pReq->Signal)
+                        {
+                            // Deassert "fault led"
+                            retCode =
+                                ledStoreAndSet(SmSignalSet::smPowerFaultLed,
+                                               std::string("Off"));
+                            if (retCode != IPMI_CC_OK)
+                            {
+                                break;
+                            }
+                        }
+                    }
+                    break;
+                    case SmActionSet::revert:
+                    {
+                        phosphor::logging::log<phosphor::logging::level::INFO>(
+                            "case SmActionSet::revert");
+                        retCode = ledRevert(pReq->Signal);
+                        if (retCode != IPMI_CC_OK)
+                        {
+                            break;
+                        }
+                    }
+                    break;
+                    default:
+                    {
+                        retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                    }
+                    break;
+                }
+                break;
+            case SmSignalSet::smFanPowerSpeed:
+            {
+                if (((pReq->Action == SmActionSet::forceAsserted) &&
+                     (*data_len != sizeof(*pReq)) && (pReq->Value > 100)) ||
+                    pReq->Instance == 0)
+                {
+                    retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                    break;
+                }
+                uint8_t pwmValue = 0;
+                switch (pReq->Action)
+                {
+                    case SmActionSet::revert:
+                    {
+                        if (mtm.revertFanPWM)
+                        {
+                            ret = mtm.disablePidControlService(false);
+                            if (ret < 0)
+                            {
+                                retCode = IPMI_CC_UNSPECIFIED_ERROR;
+                                break;
+                            }
+                            mtm.revertFanPWM = false;
+                        }
+                    }
+                    break;
+                    case SmActionSet::forceAsserted:
+                    {
+                        pwmValue = pReq->Value;
+                    } // fall-through
+                    case SmActionSet::forceDeasserted:
+                    {
+                        if (!mtm.revertFanPWM)
+                        {
+                            ret = mtm.disablePidControlService(true);
+                            if (ret < 0)
+                            {
+                                retCode = IPMI_CC_UNSPECIFIED_ERROR;
+                                break;
+                            }
+                            mtm.revertFanPWM = true;
+                        }
+                        mtm.revertTimer.start(revertTimeOut);
+                        std::string fanPwmInstancePath =
+                            fanPwmPath + std::to_string(pReq->Instance);
+
+                        ret = mtm.setProperty(
+                            fanService, fanPwmInstancePath.c_str(), fanIntf,
+                            "Value", static_cast<double>(pwmValue));
+                        if (ret < 0)
+                        {
+                            retCode = IPMI_CC_UNSPECIFIED_ERROR;
+                        }
+                    }
+                    break;
+                    default:
+                    {
+                        retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+                    }
+                    break;
+                }
+            }
+            break;
+            default:
+            {
+                retCode = IPMI_CC_INVALID_FIELD_REQUEST;
+            }
+            break;
+        }
+    }
+    else
+    {
+        retCode = IPMI_CC_ILLEGAL_COMMAND;
+    }
+
+    *data_len = 0; // Only CC is return for SetSmSignal cmd
+    return retCode;
+}
+
+} // namespace ipmi
+
+void register_mtm_commands() __attribute__((constructor));
+void register_mtm_commands()
+{
+    ipmi_register_callback(
+        netfnIntcOEMGeneral,
+        static_cast<ipmi_cmd_t>(IPMINetFnIntelOemGeneralCmds::GetSmSignal),
+        NULL, ipmi::ipmi_app_mtm_get_signal, PRIVILEGE_USER);
+
+    ipmi_register_callback(
+        netfnIntcOEMGeneral,
+        static_cast<ipmi_cmd_t>(IPMINetFnIntelOemGeneralCmds::SetSmSignal),
+        NULL, ipmi::ipmi_app_mtm_set_signal, PRIVILEGE_USER);
+
+    return;
+}
diff --git a/src/smbioshandler.cpp b/src/smbioshandler.cpp
new file mode 100644
index 0000000..7510493
--- /dev/null
+++ b/src/smbioshandler.cpp
@@ -0,0 +1,501 @@
+/*
+// 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 <ipmid/api.h>
+
+#include <commandutils.hpp>
+#include <cstdint>
+#include <iostream>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <smbioshandler.hpp>
+#include <string>
+#include <vector>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+using InternalFailure =
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+using level = phosphor::logging::level;
+
+constexpr const char* DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
+constexpr const char* MDRV1_PATH = "/xyz/openbmc_project/Smbios/MDR_V1";
+constexpr const char* MDRV1_INTERFACE = "xyz.openbmc_project.Smbios.MDR_V1";
+
+static void register_netfn_smbios_functions() __attribute__((constructor));
+static sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+ipmi_ret_t cmd_region_status(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)
+{
+    auto requestData = reinterpret_cast<const RegionStatusRequest*>(request);
+    std::vector<uint8_t> status;
+
+    if (*data_len != sizeof(RegionStatusRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    uint8_t regionId = requestData->regionId - 1;
+    *data_len = 0;
+
+    if (regionId >= maxMDRId)
+    {
+        phosphor::logging::log<level::ERR>("Invalid region");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV1_INTERFACE, MDRV1_PATH);
+
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      MDRV1_INTERFACE, "RegionStatus");
+    method.append(regionId);
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error get region status",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV1_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(status);
+
+    if (status.size() != sizeof(MDRState))
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error get region status, return length invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    *data_len = static_cast<size_t>(status.size());
+    auto dataOut = reinterpret_cast<uint8_t*>(response);
+    std::copy(&status[0], &status[*data_len], dataOut);
+    return IPMI_CC_OK;
+}
+
+int sdplus_mdrv1_get_property(
+    const std::string& name,
+    sdbusplus::message::variant<uint8_t, uint16_t>& value, std::string& service)
+{
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      DBUS_PROPERTIES, "Get");
+    method.append(MDRV1_INTERFACE, name);
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error getting property, sdbusplus call failed");
+        return -1;
+    }
+    reply.read(value);
+
+    return 0;
+}
+
+static int set_regionId(uint8_t regionId, std::string& service)
+{
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      DBUS_PROPERTIES, "Set");
+    sdbusplus::message::variant<uint8_t> value{regionId};
+    method.append(MDRV1_INTERFACE, "RegionId", value);
+    auto region = bus.call(method);
+    if (region.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error setting regionID, sdbusplus call failed");
+        return -1;
+    }
+    return 0;
+}
+
+ipmi_ret_t cmd_region_complete(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)
+{
+    auto requestData = reinterpret_cast<const RegionCompleteRequest*>(request);
+    uint8_t status;
+
+    sdbusplus::message::variant<uint8_t, uint16_t> value;
+
+    if (*data_len != sizeof(RegionCompleteRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    uint8_t regionId = requestData->regionId - 1;
+    *data_len = 0;
+
+    if (regionId >= maxMDRId)
+    {
+        phosphor::logging::log<level::ERR>("Invalid region");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV1_INTERFACE, MDRV1_PATH);
+
+    if (set_regionId(regionId, service) < 0)
+    {
+        phosphor::logging::log<level::ERR>("Error setting regionId");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting lockPolicy");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (regionLockUnlocked ==
+        sdbusplus::message::variant_ns::get<uint8_t>(value))
+    {
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+
+    if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting sessionId");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (requestData->sessionId !=
+        sdbusplus::message::variant_ns::get<uint8_t>(value))
+    {
+        return IPMI_CC_OEM_SET_IN_PROCESS;
+    }
+
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      MDRV1_INTERFACE, "RegionComplete");
+
+    method.append(regionId);
+
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error set region complete",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV1_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(status);
+
+    if (status != 0)
+        phosphor::logging::log<level::ERR>(
+            "Error set region complete, unexpected error");
+    return IPMI_CC_UNSPECIFIED_ERROR;
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_region_read(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)
+{
+    auto requestData = reinterpret_cast<const RegionReadRequest*>(request);
+    auto responseData = reinterpret_cast<RegionReadResponse*>(response);
+    sdbusplus::message::variant<uint8_t, uint16_t> regUsedVal;
+    sdbusplus::message::variant<uint8_t, uint16_t> lockPolicyVal;
+    std::vector<uint8_t> res;
+
+    if (*data_len < sizeof(RegionReadRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    uint8_t regionId = requestData->regionId - 1;
+
+    *data_len = 0;
+
+    if (regionId >= maxMDRId)
+    {
+        phosphor::logging::log<level::ERR>("Invalid region");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV1_INTERFACE, MDRV1_PATH);
+    // TODO to make sure the interface can get correct LockPolicy even
+    // regionId changed by another task.
+    if (set_regionId(regionId, service) < 0)
+    {
+        phosphor::logging::log<level::ERR>("Error setting regionId");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (0 > sdplus_mdrv1_get_property("RegionUsed", regUsedVal, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting regionUsed");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (requestData->offset + requestData->length >
+        sdbusplus::message::variant_ns::get<uint16_t>(regUsedVal))
+    {
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    if (0 > sdplus_mdrv1_get_property("LockPolicy", lockPolicyVal, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting lockPolicy");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (regionLockUnlocked !=
+        sdbusplus::message::variant_ns::get<uint8_t>(lockPolicyVal))
+    {
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      MDRV1_INTERFACE, "RegionRead");
+
+    method.append(regionId, requestData->length, requestData->offset);
+
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error read region data",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV1_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(res);
+
+    *data_len = responseData->length = res[0];
+    responseData->updateCount = res[1];
+
+    if ((*data_len == 0) || (*data_len >= 254))
+    {
+        phosphor::logging::log<level::ERR>(
+            "Data length send from service is invalid");
+        *data_len = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    *data_len += 2 * sizeof(uint8_t);
+    std::copy(&res[2], &res[*data_len], responseData->data);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_region_write(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)
+{
+    auto requestData = reinterpret_cast<const RegionWriteRequest*>(request);
+    uint8_t regionId = requestData->regionId - 1;
+    std::string res;
+    std::vector<uint8_t> writeData;
+    uint16_t index;
+    uint8_t tmp[255];
+
+    size_t minInputLen = &requestData->data[0] - &requestData->sessionId + 1;
+    if (*data_len < minInputLen)
+    { // this command need at least 6 bytes input
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    sdbusplus::message::variant<uint8_t, uint16_t> value;
+
+    *data_len = 0;
+
+    if (regionId >= maxMDRId)
+    {
+        phosphor::logging::log<level::ERR>("Invalid region");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV1_INTERFACE, MDRV1_PATH);
+
+    if (set_regionId(regionId, service) < 0)
+    {
+        phosphor::logging::log<level::ERR>("Error setting regionId");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting lockPolicy");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (regionLockUnlocked ==
+        sdbusplus::message::variant_ns::get<uint8_t>(value))
+    {
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+
+    if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting sessionId");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (requestData->sessionId !=
+        sdbusplus::message::variant_ns::get<uint8_t>(value))
+    {
+        return IPMI_CC_OEM_SET_IN_PROCESS;
+    }
+
+    std::copy(&(requestData->length), &(requestData->data[requestData->length]),
+              tmp);
+    writeData.push_back(regionId);
+    for (index = 0; index < minInputLen + requestData->length - 2; index++)
+    {
+        writeData.push_back(tmp[index]);
+    }
+
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      MDRV1_INTERFACE, "RegionWrite");
+
+    method.append(writeData);
+
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error write region data",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV1_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(res);
+
+    if (res == "NoData")
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    else if (res != "Success")
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error write region data, unexpected error");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_region_lock(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)
+{
+    auto requestData = reinterpret_cast<const RegionLockRequest*>(request);
+    uint8_t regionId = requestData->regionId - 1;
+    sdbusplus::message::variant<uint8_t, uint16_t> value;
+    auto res = reinterpret_cast<uint8_t*>(response);
+    uint8_t lockResponse;
+
+    if (*data_len != sizeof(RegionLockRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (regionId >= maxMDRId)
+    {
+        phosphor::logging::log<level::ERR>("Invalid region");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV1_INTERFACE, MDRV1_PATH);
+
+    if (set_regionId(regionId, service) < 0)
+    {
+        phosphor::logging::log<level::ERR>("Error setting regionId");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
+    {
+        phosphor::logging::log<level::ERR>("Error getting lockPolicy");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (requestData->lockPolicy == regionLockUnlocked)
+    {
+        if (regionLockUnlocked ==
+            sdbusplus::message::variant_ns::get<uint8_t>(value))
+        {
+            return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+        }
+    }
+    if (regionLockUnlocked !=
+        sdbusplus::message::variant_ns::get<uint8_t>(value))
+    {
+        if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
+        {
+            phosphor::logging::log<level::ERR>("Error getting sessionId");
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        if (requestData->sessionId !=
+            sdbusplus::message::variant_ns::get<uint8_t>(value))
+        {
+            if (requestData->lockPolicy != regionLockStrict)
+            {
+                return IPMI_CC_OEM_SET_IN_PROCESS;
+            }
+        }
+    }
+    auto method = bus.new_method_call(service.c_str(), MDRV1_PATH,
+                                      MDRV1_INTERFACE, "RegionLock");
+
+    method.append(requestData->sessionId, regionId, requestData->lockPolicy,
+                  requestData->msTimeout);
+
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<level::ERR>(
+            "Error lock region ",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV1_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(lockResponse);
+
+    *data_len = sizeof(lockResponse);
+    *res = lockResponse;
+    return IPMI_CC_OK;
+}
+
+static void register_netfn_smbios_functions(void)
+{
+    // MDR V1 Command
+    // <Get MDR Status Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_STATUS, NULL,
+                           cmd_region_status, PRIVILEGE_OPERATOR);
+
+    // <Update Complete Status Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_COMPLETE, NULL,
+                           cmd_region_complete, PRIVILEGE_OPERATOR);
+
+    // <Read MDR Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_READ, NULL,
+                           cmd_region_read, PRIVILEGE_OPERATOR);
+
+    // <Write MDR Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_WRITE, NULL,
+                           cmd_region_write, PRIVILEGE_OPERATOR);
+
+    // <Lock MDR Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_LOCK, NULL,
+                           cmd_region_lock, PRIVILEGE_OPERATOR);
+}
diff --git a/src/smbiosmdrv2.cpp b/src/smbiosmdrv2.cpp
new file mode 100644
index 0000000..93ad412
--- /dev/null
+++ b/src/smbiosmdrv2.cpp
@@ -0,0 +1,1106 @@
+/*
+// 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 <errno.h>
+#include <ipmid/api.h>
+
+#include <commandutils.hpp>
+#include <cstdint>
+#include <ipmid/utils.hpp>
+#include <phosphor-ipmi-host/ipmid.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <smbiosmdrv2.hpp>
+#include <string>
+#include <vector>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+constexpr const char* DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
+constexpr const char* MDRV2_PATH = "/xyz/openbmc_project/Smbios/MDR_V2";
+constexpr const char* MDRV2_INTERFACE = "xyz.openbmc_project.Smbios.MDR_V2";
+constexpr const int LAST_AGENT_INDEX = -1;
+constexpr const uint16_t LAST_AGENT_ID = 0xFFFF;
+
+static void register_netfn_smbiosmdrv2_functions() __attribute__((constructor));
+static sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+int agentLookup(const uint16_t& agentId, const std::string& service)
+{
+    int agentIndex = -1;
+
+    if (LAST_AGENT_ID == agentId)
+    {
+        return LAST_AGENT_INDEX;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "AgentLookup");
+    method.append(agentId);
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get agent index, sdbusplus call failed");
+        return -1;
+    }
+    reply.read(agentIndex);
+
+    return agentIndex;
+}
+
+int findLockHandle(const uint16_t& lockHandle, const std::string& service)
+{
+    int idIndex = -1;
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "FindLockHandle");
+    method.append(lockHandle);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error find lock handle",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return -1;
+    }
+    reply.read(idIndex);
+
+    return idIndex;
+}
+
+int sdplusMdrv2GetProperty(const std::string& name,
+                           sdbusplus::message::variant<uint8_t>& value,
+                           const std::string& service)
+{
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, DBUS_PROPERTIES, "Get");
+    method.append(MDRV2_INTERFACE, name);
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get property, sdbusplus call failed");
+        return -1;
+    }
+    reply.read(value);
+
+    return 0;
+}
+
+int findDataId(const uint8_t* dataInfo, const size_t& len,
+               const std::string& service)
+{
+    int idIndex = -1;
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "FindIdIndex");
+    std::vector<uint8_t> info;
+    for (int index = 0; index < len; index++)
+    {
+        info.push_back(dataInfo[index]);
+    }
+    method.append(info);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error find id index",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return -1;
+    }
+    reply.read(idIndex);
+
+    return idIndex;
+}
+
+ipmi_ret_t cmd_mdr2_agent_status(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiGetAgentStatus*>(request);
+    auto dataOut = reinterpret_cast<uint8_t*>(response);
+    std::vector<uint8_t> status;
+
+    if (*data_len != sizeof(MDRiiGetAgentStatus))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "AgentStatus");
+    method.append(requestData->dirVersion);
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get agent status",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(status);
+
+    if (status.size() != sizeof(MDRiiAgentStatusResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get agent status response length not valid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    *data_len = static_cast<size_t>(status.size());
+    std::copy(&status[0], &status[*data_len], dataOut);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_get_dir(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiGetDirRequest*>(request);
+    auto dataOut = reinterpret_cast<uint8_t*>(response);
+    std::vector<uint8_t> dirInfo;
+
+    if (*data_len != sizeof(MDRiiGetDirRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::variant<uint8_t> value = 0;
+    if (0 != sdplusMdrv2GetProperty("DirEntries", value, service))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error getting DirEnries");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (requestData->dirIndex >
+        sdbusplus::message::variant_ns::get<uint8_t>(value))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDir");
+
+    method.append(requestData->dirIndex);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get dir",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(dirInfo);
+
+    if (dirInfo.size() < sizeof(MDRiiGetDirResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get dir, response length invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    auto responseData = reinterpret_cast<MDRiiGetDirResponse*>(dirInfo.data());
+
+    *data_len = dirInfo.size();
+
+    if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
+                                     // than MAX_IPMI_BUFFER
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Data length send from service is invalid");
+        *data_len = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    std::copy(&dirInfo[0], &dirInfo[*data_len], dataOut);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_get_data_info(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiGetDataInfoRequest*>(request);
+    auto dataOut = reinterpret_cast<uint8_t*>(response);
+    std::vector<uint8_t> res;
+
+    if (*data_len < sizeof(MDRiiGetDataInfoRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        findDataId(requestData->dataSetInfo.dataInfo,
+                   sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDataInfo");
+
+    method.append(idIndex);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get data info",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(res);
+
+    if (res.size() != sizeof(MDRiiGetDataInfoResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get data info response length not invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    *data_len = static_cast<size_t>(res.size());
+    std::copy(&res[0], &res[*data_len], dataOut);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_lock_data(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiLockDataRequest*>(request);
+    auto responseData = reinterpret_cast<MDRiiLockDataResponse*>(response);
+
+    std::tuple<bool, uint8_t, uint16_t, uint32_t, uint32_t, uint32_t> res;
+
+    if (*data_len < sizeof(MDRiiLockDataRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        findDataId(requestData->dataSetInfo.dataInfo,
+                   sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "LockData");
+
+    method.append((uint8_t)idIndex, requestData->timeout);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        if (reply.get_errno() == EBUSY)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Lock Data failed - cannot lock idIndex");
+            return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+        }
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error lock data",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(res);
+
+    if (std::get<0>(res) == false)
+    {
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+
+    *data_len = sizeof(MDRiiLockDataResponse);
+
+    responseData->mdrVersion = std::get<1>(res);
+    responseData->lockHandle = std::get<2>(res);
+    responseData->dataLength = std::get<3>(res);
+    responseData->xferAddress = std::get<4>(res);
+    responseData->xferLength = std::get<5>(res);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_unlock_data(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiUnlockDataRequest*>(request);
+    std::string resStatus;
+
+    if (*data_len != sizeof(MDRiiUnlockDataRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = findLockHandle(requestData->lockHandle, service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "UnLockData");
+    method.append((uint8_t)idIndex);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        if (reply.get_errno() == EBUSY)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Unlock Data failed - cannot unlock idIndex");
+            return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+        }
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error unlock data",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(resStatus);
+
+    if (resStatus != "success")
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Agent unlock Invalid lock status.");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_get_data_block(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiGetDataBlockRequest*>(request);
+    auto responseData = reinterpret_cast<MDRiiGetDataBlockResponse*>(response);
+    std::tuple<uint8_t, uint32_t, uint32_t, std::vector<uint8_t>> res;
+    std::vector<uint8_t> resData;
+    uint8_t status = 1;
+
+    if (*data_len != sizeof(MDRiiGetDataBlockRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = findLockHandle(requestData->lockHandle, service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDataBlock");
+    method.append((uint8_t)idIndex, requestData->xferOffset,
+                  requestData->xferLength);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get data block",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(res);
+
+    // Get the status of get data block, 0 means succeed
+    status = std::get<0>(res);
+    if (status == 1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Request data offset is outside of range.");
+        return IPMI_CC_CANNOT_RETURN_NUMBER_OF_REQUESTED_DATA_BYTES;
+    }
+    else if (status != 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get data block unexpected error.");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    responseData->xferLength = std::get<1>(res);
+    if (responseData->xferLength > requestData->xferLength)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get data block unexpected error.");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    responseData->checksum = std::get<2>(res);
+
+    resData = std::get<3>(res);
+
+    *data_len = sizeof(responseData->xferLength) +
+                sizeof(responseData->checksum) + resData.size();
+
+    if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
+                                     // than MAX_IPMI_BUFFER
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Data length send from service is invalid");
+        *data_len = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    std::copy(resData.begin(), resData.end(), responseData->data);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_send_dir(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiSendDirRequest*>(request);
+    std::vector<uint8_t> idVector;
+    bool teminate = false;
+
+    if (*data_len != sizeof(MDRiiSendDirRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if ((requestData->dirIndex + requestData->returnedEntries) > maxDirEntries)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Too many directory entries");
+        return IPMI_CC_STORGE_LEAK;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "SendDir");
+    method.append(requestData->dirVersion, requestData->dirIndex,
+                  requestData->returnedEntries, requestData->remainingEntries);
+    uint8_t* reqPoint;
+    for (int index = 0; index < requestData->returnedEntries; index++)
+    {
+        reqPoint = (uint8_t*)&(requestData->data[index]);
+        std::copy(reqPoint, sizeof(Mdr2DirEntry) + reqPoint, idVector.data());
+    }
+    method.append(idVector);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send dir",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(teminate);
+
+    *data_len = 1;
+    if (teminate == false)
+        *(static_cast<uint8_t*>(response)) = 0;
+    else
+        *(static_cast<uint8_t*>(response)) = 1;
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_data_info_offer(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiOfferDataInfo*>(request);
+    auto dataOut = reinterpret_cast<uint8_t*>(response);
+    std::vector<uint8_t> dataInfo;
+
+    if (*data_len != sizeof(MDRiiOfferDataInfo))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDataOffer");
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        if (reply.get_errno() == EBUSY)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data info offer failed - not available to update data "
+                "into agent at present");
+            return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+        }
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send data info offer",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(dataInfo);
+    if (dataInfo.size() != sizeof(MDRiiOfferDataInfoResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send data info offer, return length invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    *data_len = dataInfo.size();
+    std::copy(dataInfo.begin(), dataInfo.end(), dataOut);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_send_data_info(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiSendDataInfoRequest*>(request);
+    bool entryChanged = true;
+
+    if (*data_len != sizeof(MDRiiSendDataInfoRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (requestData->dataLength > smbiosTableStorageSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Requested data length is out of SMBIOS Table storage size.");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        findDataId(requestData->dataSetInfo.dataInfo,
+                   sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "SendDataInfo");
+
+    method.append((uint8_t)idIndex, requestData->validFlag,
+                  requestData->dataLength, requestData->dataVersion,
+                  requestData->timeStamp);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send data info",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(entryChanged);
+
+    *data_len = 1;
+
+    if (entryChanged)
+    {
+        *(static_cast<uint8_t*>(response)) = 1;
+    }
+    else
+    {
+        *(static_cast<uint8_t*>(response)) = 0;
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_data_start(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiDataStartRequest*>(request);
+    auto responseData = reinterpret_cast<MDRiiDataStartResponse*>(response);
+    std::vector<uint8_t> idVector;
+
+    if (*data_len != sizeof(MDRiiDataStartRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (requestData->dataLength > smbiosTableStorageSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Requested data length is out of SMBIOS Table storage size.");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if ((requestData->xferLength + requestData->xferAddress) > mdriiSMSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid data address and size");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        findDataId(requestData->dataSetInfo.dataInfo,
+                   sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "DataStart");
+
+    for (uint8_t infoIndex = 0; infoIndex < sizeof(DataIdStruct); infoIndex++)
+    {
+        idVector.push_back(requestData->dataSetInfo.dataInfo[infoIndex]);
+    }
+    method.append((uint8_t)idIndex, idVector, requestData->dataLength,
+                  requestData->xferAddress, requestData->xferLength,
+                  requestData->timeout);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        int errNumber = reply.get_errno();
+        if (errNumber == ENOMEM)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data start failed - cannot map share memory");
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        else if (errNumber == EINVAL)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Invalid data address and size");
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+        }
+        else
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Error Send Data Start",
+                phosphor::logging::entry("SERVICE=%s", service.c_str()),
+                phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+    }
+    uint8_t xferStartAck = 0;
+    uint16_t sessionHandle = 0;
+    reply.read(xferStartAck, sessionHandle);
+    responseData->sessionHandle = sessionHandle;
+    responseData->xferStartAck = xferStartAck;
+    if (responseData->xferStartAck == 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Send data start unexpected error");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    *data_len = sizeof(MDRiiDataStartResponse);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_data_done(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiDataDoneRequest*>(request);
+    std::string resStatus;
+
+    if (*data_len != sizeof(MDRiiDataDoneRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = findLockHandle(requestData->lockHandle, service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "DataDone");
+    method.append((uint8_t)idIndex);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        if (reply.get_errno() == EBUSY)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data done failed - cannot unlock idIndex");
+            return IPMI_CC_DESTINATION_UNAVAILABLE;
+        }
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error Send Data done",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    reply.read(resStatus);
+
+    if (resStatus != "success")
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Data done failure.");
+        return IPMI_CC_DESTINATION_UNAVAILABLE;
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_send_data_block(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiSendDataBlockRequest*>(request);
+    std::string resStatus;
+
+    if (*data_len != sizeof(MDRiiSendDataBlockRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, MDRV2_INTERFACE, MDRV2_PATH);
+
+    int agentIndex = agentLookup(requestData->agentId, service);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = findLockHandle(requestData->lockHandle, service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "SendDataBlock");
+    method.append((uint8_t)idIndex, requestData->xferOffset,
+                  requestData->xferLength, requestData->checksum);
+
+    sdbusplus::message::message reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        int errNumber = reply.get_errno();
+        if (errNumber == EINVAL)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data block Invalid checksum");
+            return IPMI_CC_OEM_INVALID_CHECKSUM;
+        }
+        else if (errNumber == ENOBUFS)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data block Invalid offset/length");
+            return IPMI_CC_REQUEST_DATA_FIELD_LENGTH_LIMIT_EXCEEDED;
+        }
+        else if (errNumber == EBUSY)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data block failed, other data is updating");
+            return IPMI_CC_DESTINATION_UNAVAILABLE;
+        }
+        else
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Error Send data block",
+                phosphor::logging::entry("SERVICE=%s", service.c_str()),
+                phosphor::logging::entry("PATH=%s", MDRV2_PATH));
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+    }
+    reply.read(resStatus);
+
+    if (resStatus != "success")
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "send data block failure.");
+        return IPMI_CC_DESTINATION_UNAVAILABLE;
+    }
+
+    return IPMI_CC_OK;
+}
+
+static void register_netfn_smbiosmdrv2_functions(void)
+{
+    // MDR V2 Command
+    // <Get MDRII Status Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_AGENT_STATUS,
+                           NULL, cmd_mdr2_agent_status, PRIVILEGE_OPERATOR);
+
+    // <Get MDRII Directory Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DIR, NULL,
+                           cmd_mdr2_get_dir, PRIVILEGE_OPERATOR);
+
+    // <Get MDRII Data Info Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_INFO,
+                           NULL, cmd_mdr2_get_data_info, PRIVILEGE_OPERATOR);
+
+    // <Lock MDRII Data Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_LOCK_DATA, NULL,
+                           cmd_mdr2_lock_data, PRIVILEGE_OPERATOR);
+
+    // <Unlock MDRII Data Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_UNLOCK_DATA,
+                           NULL, cmd_mdr2_unlock_data, PRIVILEGE_OPERATOR);
+
+    // <Get MDRII Data Block Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_BLOCK,
+                           NULL, cmd_mdr2_get_data_block, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Directory Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DIR, NULL,
+                           cmd_mdr2_send_dir, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Info Offer>
+    ipmi_register_callback(
+        NETFUN_INTEL_APP_OEM,
+        IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO_OFFER, NULL,
+        cmd_mdr2_data_info_offer, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Info>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO,
+                           NULL, cmd_mdr2_send_data_info, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Start>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_START, NULL,
+                           cmd_mdr2_data_start, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Done>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_DONE, NULL,
+                           cmd_mdr2_data_done, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Block>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_BLOCK,
+                           NULL, cmd_mdr2_send_data_block, PRIVILEGE_OPERATOR);
+}
diff --git a/src/smbiosmdrv2handler.cpp b/src/smbiosmdrv2handler.cpp
new file mode 100644
index 0000000..da3712a
--- /dev/null
+++ b/src/smbiosmdrv2handler.cpp
@@ -0,0 +1,1444 @@
+/*
+// 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 <errno.h>
+#include <fcntl.h>
+#include <ipmid/api.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <commandutils.hpp>
+#include <cstdint>
+#include <fstream>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <smbiosmdrv2handler.hpp>
+#include <string>
+#include <vector>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Smbios/MDR_V2/error.hpp>
+
+std::unique_ptr<MDRV2> mdrv2 = nullptr;
+
+namespace variant_ns = sdbusplus::message::variant_ns;
+
+static void register_netfn_smbiosmdrv2_functions() __attribute__((constructor));
+static sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+int MDRV2::agentLookup(const uint16_t &agentId)
+{
+    int agentIndex = -1;
+
+    if (lastAgentId == agentId)
+    {
+        return lastAgentIndex;
+    }
+
+    if (agentId == smbiosAgentId)
+    {
+        return firstAgentIndex;
+    }
+
+    return agentIndex;
+}
+
+int MDRV2::sdplusMdrv2GetProperty(const std::string &name,
+                                  sdbusplus::message::variant<uint8_t> &value,
+                                  const std::string &service)
+{
+    sdbusplus::message::message method =
+        bus.new_method_call(service.c_str(), mdrv2Path, dbusProperties, "Get");
+    method.append(mdrv2Interface, name);
+
+    sdbusplus::message::message reply = bus.call(method);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(value);
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get property, sdbusplus call failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+int MDRV2::syncDirCommonData(uint8_t idIndex, uint32_t size,
+                             const std::string &service)
+{
+    std::vector<uint32_t> commonData;
+    sdbusplus::message::message method =
+        bus.new_method_call(service.c_str(), mdrv2Path, mdrv2Interface,
+                            "SynchronizeDirectoryCommonData");
+    method.append(idIndex, size);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(commonData);
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error sync dir common data with service");
+        return -1;
+    }
+
+    if (commonData.size() < syncDirCommonSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error sync dir common data - data length invalid");
+        return -1;
+    }
+    smbiosDir.dir[idIndex].common.dataSetSize = commonData.at(0);
+    smbiosDir.dir[idIndex].common.dataVersion = commonData.at(1);
+    smbiosDir.dir[idIndex].common.timestamp = commonData.at(2);
+
+    return 0;
+}
+
+int MDRV2::findDataId(const uint8_t *dataInfo, const size_t &len,
+                      const std::string &service)
+{
+    int idIndex = -1;
+
+    if (dataInfo == nullptr)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error dataInfo, input is null point");
+        return -1;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "FindIdIndex");
+    std::vector<uint8_t> info;
+    info.resize(len);
+    std::copy(dataInfo, dataInfo + len, info.data());
+    method.append(info);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(idIndex);
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error find id index",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return -1;
+    }
+
+    return idIndex;
+}
+
+uint16_t MDRV2::getSessionHandle(Mdr2DirStruct *dir)
+{
+    if (dir == NULL)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Empty dir point");
+        return 0;
+    }
+    dir->sessionHandle++;
+    if (dir->sessionHandle == 0)
+    {
+        dir->sessionHandle = 1;
+    }
+
+    return dir->sessionHandle;
+}
+
+int MDRV2::findLockHandle(const uint16_t &lockHandle)
+{
+    int idIndex = -1;
+
+    for (int index = 0; index < smbiosDir.dirEntries; index++)
+    {
+        if (lockHandle == smbiosDir.dir[index].lockHandle)
+        {
+            return index;
+        }
+    }
+
+    return idIndex;
+}
+
+bool MDRV2::smbiosIsUpdating(uint8_t index)
+{
+    if (index > maxDirEntries)
+    {
+        return false;
+    }
+    if (smbiosDir.dir[index].stage == MDR2SMBIOSStatusEnum::mdr2Updating)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+uint32_t MDRV2::calcChecksum32(uint8_t *buf, uint32_t len)
+{
+    uint32_t sum = 0;
+
+    if (buf == nullptr)
+    {
+        return invalidChecksum;
+    }
+
+    for (uint32_t index = 0; index < len; index++)
+    {
+        sum += buf[index];
+    }
+
+    return sum;
+}
+
+ipmi_ret_t cmd_mdr2_agent_status(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiGetAgentStatus *>(request);
+    auto responseData = reinterpret_cast<MDRiiAgentStatusResponse *>(response);
+
+    if (*data_len != sizeof(MDRiiGetAgentStatus))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    responseData->mdrVersion = mdr2Version;
+    responseData->agentVersion = smbiosAgentVersion;
+    responseData->dirVersion = mdrv2->smbiosDir.dirVersion;
+    responseData->dirEntries = mdrv2->smbiosDir.dirEntries;
+
+    if (mdrv2->smbiosDir.remoteDirVersion != requestData->dirVersion)
+    {
+        mdrv2->smbiosDir.remoteDirVersion = requestData->dirVersion;
+        responseData->dataRequest =
+            static_cast<uint8_t>(DirDataRequestEnum::dirDataRequested);
+    }
+    else
+    {
+        responseData->dataRequest =
+            static_cast<uint8_t>(DirDataRequestEnum::dirDataNotRequested);
+    }
+
+    *data_len = sizeof(MDRiiAgentStatusResponse);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_get_dir(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiGetDirRequest *>(request);
+    auto dataOut = reinterpret_cast<uint8_t *>(response);
+    std::vector<uint8_t> dirInfo;
+
+    if (*data_len != sizeof(MDRiiGetDirRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::variant<uint8_t> value = 0;
+    if (0 != mdrv2->sdplusMdrv2GetProperty("DirectoryEntries", value, service))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error getting DirEnries");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    if (requestData->dirIndex > variant_ns::get<uint8_t>(value))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "GetDirectoryInformation");
+
+    method.append(requestData->dirIndex);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(dirInfo);
+    }
+    catch (sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+               InvalidParameter)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get dir - Invalid parameter");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get dir",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    if (dirInfo.size() < sizeof(MDRiiGetDirResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get dir, response length invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    auto responseData = reinterpret_cast<MDRiiGetDirResponse *>(dirInfo.data());
+
+    *data_len = dirInfo.size();
+
+    if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
+                                     // than MAX_IPMI_BUFFER
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Data length send from service is invalid");
+        *data_len = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    std::copy(&dirInfo[0], &dirInfo[*data_len], dataOut);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_send_dir(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiSendDirRequest *>(request);
+    std::vector<uint8_t> idVector;
+    bool teminate = false;
+
+    if (*data_len != sizeof(MDRiiSendDirRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if ((requestData->dirIndex + requestData->returnedEntries) > maxDirEntries)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Too many directory entries");
+        return IPMI_CC_STORGE_LEAK;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "SendDirectoryInformation");
+    method.append(requestData->dirVersion, requestData->dirIndex,
+                  requestData->returnedEntries, requestData->remainingEntries);
+    uint8_t *reqPoint;
+    for (int index = 0; index < requestData->returnedEntries; index++)
+    {
+        reqPoint = (uint8_t *)&(requestData->data[index]);
+        std::copy(reqPoint, sizeof(Mdr2DirEntry) + reqPoint, idVector.data());
+    }
+    method.append(idVector);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(teminate);
+    }
+    catch (sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+               InvalidParameter)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send dir - Invalid parameter");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send dir",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    *data_len = 1;
+    if (teminate == false)
+        *(static_cast<uint8_t *>(response)) = 0;
+    else
+        *(static_cast<uint8_t *>(response)) = 1;
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_get_data_info(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiGetDataInfoRequest *>(request);
+    auto dataOut = reinterpret_cast<uint8_t *>(response);
+    std::vector<uint8_t> res;
+
+    if (*data_len < sizeof(MDRiiGetDataInfoRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        mdrv2->findDataId(requestData->dataSetInfo.dataInfo,
+                          sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "GetDataInformation");
+
+    method.append(idIndex);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(res);
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error get data info",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    if (res.size() != sizeof(MDRiiGetDataInfoResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get data info response length not invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    *data_len = static_cast<size_t>(res.size());
+    std::copy(&res[0], &res[*data_len], dataOut);
+
+    return IPMI_CC_OK;
+}
+
+// Offer a agent ID to get the "Data Set ID"
+ipmi_ret_t cmd_mdr2_data_info_offer(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiOfferDataInfo *>(request);
+    auto dataOut = reinterpret_cast<uint8_t *>(response);
+    std::vector<uint8_t> dataInfo;
+
+    if (*data_len != sizeof(MDRiiOfferDataInfo))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "GetDataOffer");
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(dataInfo);
+    }
+    catch (
+        sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::UpdateInProgress
+            &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Send data info offer failed - not available to update data "
+            "into agent at present");
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send data info offer",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    if (dataInfo.size() != sizeof(MDRiiOfferDataInfoResponse))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send data info offer, return length invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    *data_len = dataInfo.size();
+    std::copy(dataInfo.begin(), dataInfo.end(), dataOut);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_send_data_info(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiSendDataInfoRequest *>(request);
+    bool entryChanged = true;
+
+    if (*data_len != sizeof(MDRiiSendDataInfoRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (requestData->dataLength > smbiosTableStorageSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Requested data length is out of SMBIOS Table storage size.");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        mdrv2->findDataId(requestData->dataSetInfo.dataInfo,
+                          sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "SendDataInformation");
+
+    method.append((uint8_t)idIndex, requestData->validFlag,
+                  requestData->dataLength, requestData->dataVersion,
+                  requestData->timeStamp);
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(entryChanged);
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error send data info",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    *data_len = 1;
+
+    if (entryChanged)
+    {
+        *(static_cast<uint8_t *>(response)) = 1;
+    }
+    else
+    {
+        *(static_cast<uint8_t *>(response)) = 0;
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_get_data_block(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiGetDataBlockRequest *>(request);
+    auto responseData = reinterpret_cast<MDRiiGetDataBlockResponse *>(response);
+    std::tuple<uint8_t, uint32_t, uint32_t, std::vector<uint8_t>> res;
+    std::vector<uint8_t> resData;
+    uint8_t status = 1;
+
+    if (*data_len != sizeof(MDRiiGetDataBlockRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = mdrv2->findLockHandle(requestData->lockHandle);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if (requestData->xferOffset >= mdrv2->smbiosDir.dir[idIndex].common.size)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Offset is outside of range.");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    size_t outSize =
+        (requestData->xferLength > mdrv2->smbiosDir.dir[idIndex].xferSize)
+            ? mdrv2->smbiosDir.dir[idIndex].xferSize
+            : requestData->xferLength;
+    if (outSize > UINT_MAX - requestData->xferOffset)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Out size and offset are out of range");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    if ((requestData->xferOffset + outSize) >
+        mdrv2->smbiosDir.dir[idIndex].common.size)
+    {
+        outSize =
+            mdrv2->smbiosDir.dir[idIndex].common.size - requestData->xferOffset;
+    }
+
+    responseData->xferLength = outSize;
+    if (responseData->xferLength > requestData->xferLength)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get data block unexpected error.");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    if ((requestData->xferOffset + outSize) >
+        UINT_MAX -
+            reinterpret_cast<size_t>(mdrv2->smbiosDir.dir[idIndex].dataStorage))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Input data to calculate checksum is out of range");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    uint32_t u32Checksum = mdrv2->calcChecksum32(
+        mdrv2->smbiosDir.dir[idIndex].dataStorage + requestData->xferOffset,
+        outSize);
+    if (u32Checksum == invalidChecksum)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Get data block failed - invalid checksum");
+        return IPMI_CC_OEM_INVALID_CHECKSUM;
+    }
+    responseData->checksum = u32Checksum;
+
+    *data_len = sizeof(responseData->xferLength) +
+                sizeof(responseData->checksum) + outSize;
+
+    if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
+                                     // than MAX_IPMI_BUFFER
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Data length send from service is invalid");
+        *data_len = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    std::copy(
+        &mdrv2->smbiosDir.dir[idIndex].dataStorage[requestData->xferOffset],
+        &mdrv2->smbiosDir.dir[idIndex]
+             .dataStorage[requestData->xferOffset + outSize],
+        responseData->data);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_send_data_block(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)
+{
+    auto requestData =
+        reinterpret_cast<const MDRiiSendDataBlockRequest *>(request);
+
+    if (*data_len != sizeof(MDRiiSendDataBlockRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = mdrv2->findLockHandle(requestData->lockHandle);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if (mdrv2->smbiosIsUpdating(idIndex))
+    {
+        if (requestData->xferOffset > UINT_MAX - requestData->xferLength)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Offset and length are out of range");
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+        }
+        if (((requestData->xferOffset + requestData->xferLength) >
+             mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
+            ((requestData->xferOffset + requestData->xferLength) >
+             mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data block Invalid offset/length");
+            return IPMI_CC_REQUEST_DATA_FIELD_LENGTH_LIMIT_EXCEEDED;
+        }
+        if (reinterpret_cast<size_t>(
+                mdrv2->smbiosDir.dir[idIndex].dataStorage) >
+            UINT_MAX - requestData->xferOffset)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Offset is out of range");
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+        }
+        uint8_t *destAddr =
+            mdrv2->smbiosDir.dir[idIndex].dataStorage + requestData->xferOffset;
+        uint8_t *sourceAddr = reinterpret_cast<uint8_t *>(mdrv2->area->vPtr);
+        uint32_t calcChecksum =
+            mdrv2->calcChecksum32(sourceAddr, requestData->xferLength);
+        if (calcChecksum != requestData->checksum)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Send data block Invalid checksum");
+            return IPMI_CC_OEM_INVALID_CHECKSUM;
+        }
+        else
+        {
+            if (reinterpret_cast<size_t>(sourceAddr) >
+                UINT_MAX - requestData->xferLength)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Length is out of range");
+                return IPMI_CC_PARM_OUT_OF_RANGE;
+            }
+            std::copy(sourceAddr, sourceAddr + requestData->xferLength,
+                      destAddr);
+        }
+    }
+    else
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Send data block failed, other data is updating");
+        return IPMI_CC_DESTINATION_UNAVAILABLE;
+    }
+
+    return IPMI_CC_OK;
+}
+
+bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data)
+{
+    std::ofstream smbiosFile(mdrType2File,
+                             std::ios_base::binary | std::ios_base::trunc);
+    if (!smbiosFile.good())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Write data from flash error - Open MDRV2 table file failure");
+        return false;
+    }
+
+    try
+    {
+        smbiosFile.write(reinterpret_cast<char *>(mdrHdr),
+                         sizeof(MDRSMBIOSHeader));
+        smbiosFile.write(reinterpret_cast<char *>(data), mdrHdr->dataSize);
+    }
+    catch (std::ofstream::failure &e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Write data from flash error - write data error");
+        return false;
+    }
+
+    return true;
+}
+
+void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
+{
+    int memDriver = 0;
+
+    // open mem driver for the system memory access
+    memDriver = open("/dev/vgasharedmem", O_RDONLY);
+    if (memDriver < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Cannot access mem driver");
+        throw std::system_error(EIO, std::generic_category());
+    }
+
+    // map the system memory
+    vPtr = mmap(NULL,                       // where to map to: don't mind
+                areaSize,                   // how many bytes ?
+                PROT_READ,                  // want to read and write
+                MAP_SHARED,                 // no copy on write
+                memDriver,                  // handle to /dev/mem
+                (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
+
+    close(memDriver);
+    if (vPtr == MAP_FAILED)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Failed to map share memory");
+        throw std::system_error(EIO, std::generic_category());
+    }
+    size = areaSize;
+    physicalAddr = addr;
+}
+
+bool MDRV2::smbiosUnlock(uint8_t index)
+{
+    bool ret;
+    switch (smbiosDir.dir[index].stage)
+    {
+        case MDR2SMBIOSStatusEnum::mdr2Updating:
+            smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
+            smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
+
+            timer->stop();
+            smbiosDir.dir[index].lockHandle = 0;
+            ret = true;
+            break;
+
+        case MDR2SMBIOSStatusEnum::mdr2Updated:
+        case MDR2SMBIOSStatusEnum::mdr2Loaded:
+            smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
+
+            timer->stop();
+
+            smbiosDir.dir[index].lockHandle = 0;
+            ret = true;
+            break;
+
+        default:
+            break;
+    }
+
+    return ret;
+}
+
+bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
+                          uint16_t timeout)
+{
+    bool ret = false;
+    uint32_t u32Status = 0;
+
+    if (timeout == 0)
+    {
+        timeout = defaultTimeout;
+    }
+    std::chrono::microseconds usec(timeout * sysClock);
+
+    switch (smbiosDir.dir[index].stage)
+    {
+        case MDR2SMBIOSStatusEnum::mdr2Updating:
+            if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
+            {
+                smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
+                timer->start(usec);
+                lockIndex = index;
+
+                *session = getSessionHandle(&smbiosDir);
+                smbiosDir.dir[index].lockHandle = *session;
+                ret = true;
+            }
+            break;
+        case MDR2SMBIOSStatusEnum::mdr2Init:
+            if (flag)
+            {
+                smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
+                smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
+                timer->start(usec);
+                lockIndex = index;
+
+                *session = getSessionHandle(&smbiosDir);
+                smbiosDir.dir[index].lockHandle = *session;
+                ret = true;
+            }
+            break;
+
+        case MDR2SMBIOSStatusEnum::mdr2Updated:
+        case MDR2SMBIOSStatusEnum::mdr2Loaded:
+            if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
+            {
+                if (flag)
+                {
+                    smbiosDir.dir[index].stage =
+                        MDR2SMBIOSStatusEnum::mdr2Updating;
+                    smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
+                }
+                else
+                {
+                    smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
+                }
+
+                timer->start(usec);
+                lockIndex = index;
+
+                *session = getSessionHandle(&smbiosDir);
+                smbiosDir.dir[index].lockHandle = *session;
+                ret = true;
+            }
+            break;
+
+        default:
+            break;
+    }
+    return ret;
+}
+
+void MDRV2::timeoutHandler()
+{
+    smbiosUnlock(lockIndex);
+    mdrv2->area.reset(nullptr);
+}
+
+ipmi_ret_t cmd_mdr2_lock_data(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiLockDataRequest *>(request);
+    auto responseData = reinterpret_cast<MDRiiLockDataResponse *>(response);
+    uint16_t session = 0;
+
+    std::tuple<bool, uint8_t, uint16_t, uint32_t, uint32_t, uint32_t> res;
+
+    if (*data_len < sizeof(MDRiiLockDataRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    int idIndex =
+        mdrv2->findDataId(requestData->dataSetInfo.dataInfo,
+                          sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if (!mdrv2->smbiosTryLock(0, idIndex, &session, requestData->timeout))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Lock Data failed - cannot lock idIndex");
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+
+    *data_len = sizeof(MDRiiLockDataResponse);
+
+    responseData->mdrVersion = mdr2Version;
+    responseData->lockHandle = session;
+    responseData->dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
+    responseData->xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
+    responseData->xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_unlock_data(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)
+{
+    phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
+    auto requestData =
+        reinterpret_cast<const MDRiiUnlockDataRequest *>(request);
+
+    if (*data_len != sizeof(MDRiiUnlockDataRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = mdrv2->findLockHandle(requestData->lockHandle);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if (!mdrv2->smbiosUnlock(idIndex))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unlock Data failed - cannot unlock idIndex");
+        return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_data_start(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiDataStartRequest *>(request);
+    auto responseData = reinterpret_cast<MDRiiDataStartResponse *>(response);
+    std::vector<uint8_t> idVector;
+    uint16_t session = 0;
+
+    if (*data_len != sizeof(MDRiiDataStartRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (requestData->dataLength > smbiosTableStorageSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Requested data length is out of SMBIOS Table storage size.");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if ((requestData->xferLength + requestData->xferAddress) > mdriiSMSize)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid data address and size");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex =
+        mdrv2->findDataId(requestData->dataSetInfo.dataInfo,
+                          sizeof(requestData->dataSetInfo.dataInfo), service);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if (mdrv2->smbiosTryLock(1, idIndex, &session, requestData->timeout))
+    {
+        try
+        {
+            mdrv2->area = std::make_unique<SharedMemoryArea>(
+                requestData->xferAddress, requestData->xferLength);
+        }
+        catch (const std::system_error &e)
+        {
+            mdrv2->smbiosUnlock(idIndex);
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Unable to access share memory");
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        mdrv2->smbiosDir.dir[idIndex].common.size = requestData->dataLength;
+        mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
+        if (-1 ==
+            mdrv2->syncDirCommonData(
+                idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Unable to sync data to service");
+            return IPMI_CC_RESPONSE_ERROR;
+        }
+    }
+    else
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Canot lock smbios");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    responseData->sessionHandle = session;
+    responseData->xferStartAck = 1;
+
+    *data_len = sizeof(MDRiiDataStartResponse);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t cmd_mdr2_data_done(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)
+{
+    auto requestData = reinterpret_cast<const MDRiiDataDoneRequest *>(request);
+
+    if (*data_len != sizeof(MDRiiDataDoneRequest))
+    {
+        *data_len = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    *data_len = 0;
+
+    if (mdrv2 == nullptr)
+    {
+        mdrv2 = std::make_unique<MDRV2>();
+    }
+
+    int agentIndex = mdrv2->agentLookup(requestData->agentId);
+    if (agentIndex == -1)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unknown agent id",
+            phosphor::logging::entry("ID=%x", requestData->agentId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    int idIndex = mdrv2->findLockHandle(requestData->lockHandle);
+
+    if ((idIndex < 0) || (idIndex >= maxDirEntries))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    if (!mdrv2->smbiosUnlock(idIndex))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Send data done failed - cannot unlock idIndex");
+        return IPMI_CC_DESTINATION_UNAVAILABLE;
+    }
+
+    mdrv2->area.reset(nullptr);
+    MDRSMBIOSHeader mdr2Smbios;
+    mdr2Smbios.mdrType = mdrTypeII;
+    mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
+    mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
+    mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
+
+    if (access(smbiosPath, 0) == -1)
+    {
+        int flag = mkdir(smbiosPath, S_IRWXU);
+        if (flag != 0)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "create folder failed for writting smbios file");
+        }
+    }
+    if (!mdrv2->storeDatatoFlash(
+            &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "MDR2 Store data to flash failed");
+        return IPMI_CC_DESTINATION_UNAVAILABLE;
+    }
+
+    bool status = false;
+    std::string service = ipmi::getService(bus, mdrv2Interface, mdrv2Path);
+    sdbusplus::message::message method = bus.new_method_call(
+        service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
+
+    try
+    {
+        sdbusplus::message::message reply = bus.call(method);
+        reply.read(status);
+    }
+    catch (sdbusplus::exception_t &)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error Sync data with service",
+            phosphor::logging::entry("SERVICE=%s", service.c_str()),
+            phosphor::logging::entry("PATH=%s", mdrv2Path));
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    if (!status)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Sync data with service failure");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    return IPMI_CC_OK;
+}
+
+static void register_netfn_smbiosmdrv2_functions(void)
+{
+    // MDR V2 Command
+    // <Get MDRII Status Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_AGENT_STATUS,
+                           NULL, cmd_mdr2_agent_status, PRIVILEGE_OPERATOR);
+
+    // <Get MDRII Directory Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DIR, NULL,
+                           cmd_mdr2_get_dir, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Directory Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DIR, NULL,
+                           cmd_mdr2_send_dir, PRIVILEGE_OPERATOR);
+
+    // <Get MDRII Data Info Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_INFO,
+                           NULL, cmd_mdr2_get_data_info, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Info Offer>
+    ipmi_register_callback(
+        NETFUN_INTEL_APP_OEM,
+        IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO_OFFER, NULL,
+        cmd_mdr2_data_info_offer, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Info>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO,
+                           NULL, cmd_mdr2_send_data_info, PRIVILEGE_OPERATOR);
+
+    // <Get MDRII Data Block Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_BLOCK,
+                           NULL, cmd_mdr2_get_data_block, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Block>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_BLOCK,
+                           NULL, cmd_mdr2_send_data_block, PRIVILEGE_OPERATOR);
+
+    // <Lock MDRII Data Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_LOCK_DATA, NULL,
+                           cmd_mdr2_lock_data, PRIVILEGE_OPERATOR);
+
+    // <Unlock MDRII Data Command>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_UNLOCK_DATA,
+                           NULL, cmd_mdr2_unlock_data, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Start>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_START, NULL,
+                           cmd_mdr2_data_start, PRIVILEGE_OPERATOR);
+
+    // <Send MDRII Data Done>
+    ipmi_register_callback(NETFUN_INTEL_APP_OEM,
+                           IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_DONE, NULL,
+                           cmd_mdr2_data_done, PRIVILEGE_OPERATOR);
+}
