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);
+}
