diff --git a/CMakeLists.txt b/CMakeLists.txt
index 59114a2..0e33cec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,7 +104,7 @@
 add_library (zinteloemcmds
              SHARED src/oemcommands.cpp src/sensorcommands.cpp src/biosconfigcommands.cpp
              src/storagecommands.cpp src/multinodecommands.cpp
-             src/firmware-update.cpp src/appcommands.cpp src/smbioshandler.cpp
+             src/firmware-update.cpp src/appcommands.cpp
              src/smbiosmdrv2handler.cpp src/manufacturingcommands.cpp
              src/bmccontrolservices.cpp src/bridgingcommands.cpp
              src/ipmi_to_redfish_hooks.cpp src/me_to_redfish_hooks.cpp
@@ -130,14 +130,12 @@
         "Enables unsecure features required by validation. Note: must
         be turned off for production images."
         OFF)
-option (MDR_V1_SUPPORT "Support these MDR Verseion 1 IPMI OEM commands" OFF)
 
 target_compile_definitions (
     zinteloemcmds PRIVATE
     $<$<BOOL:${INTEL_PFR_ENABLED}>: -DINTEL_PFR_ENABLED>
     $<$<BOOL:${BMC_VALIDATION_UNSECURE_FEATURE}>:
     -DBMC_VALIDATION_UNSECURE_FEATURE>
-    $<$<BOOL:${MDR_V1_SUPPORT}>: -DMDR_V1_SUPPORT>
     $<$<BOOL:${USING_ENTITY_MANAGER_DECORATORS}>:
     -DUSING_ENTITY_MANAGER_DECORATORS>
 )
diff --git a/include/smbioshandler.hpp b/include/smbioshandler.hpp
deleted file mode 100644
index 97ecbb7..0000000
--- a/include/smbioshandler.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-
-#pragma once
-#include "ipmid/api.h"
-
-#include <oemcommands.hpp>
-
-#include <cstddef>
-#include <cstdint>
-
-constexpr uint16_t msgPayloadSize = 1024 * 60;
-
-typedef enum
-{
-    regionLockUnlocked = 0,
-    regionLockStrict,
-    regionLockPreemptable
-} MDRLockType;
-
-typedef struct
-{
-    uint8_t DirVer;
-    uint8_t MDRType;
-    uint16_t timestamp;
-    uint16_t DataSize;
-} __attribute__((packed)) MDRSmbios_Header;
-
-typedef struct
-{
-    uint8_t MdrVersion;
-    uint8_t regionId;
-    bool valid;
-    uint8_t updateCount;
-    uint8_t lockPolicy;
-    uint16_t regionLength;
-    uint16_t regionUsed;
-    uint8_t CRC8;
-} __attribute__((packed)) MDRState;
-
-struct RegionStatusRequest
-{
-    uint8_t regionId;
-} __attribute__((packed));
-
-struct RegionStatusResponse
-{
-    MDRState State;
-} __attribute__((packed));
-
-struct RegionCompleteRequest
-{
-    uint8_t sessionId;
-    uint8_t regionId;
-} __attribute__((packed));
-
-struct RegionReadRequest
-{
-    uint8_t regionId;
-    uint8_t length;
-    uint16_t offset;
-} __attribute__((packed));
-
-struct RegionReadResponse
-{
-    uint8_t length;
-    uint8_t updateCount;
-    uint8_t data[msgPayloadSize];
-} __attribute__((packed));
-
-struct RegionWriteRequest
-{
-    uint8_t sessionId;
-    uint8_t regionId;
-    uint8_t length;
-    uint16_t offset;
-    uint8_t data[msgPayloadSize];
-} __attribute__((packed));
-
-struct RegionLockRequest
-{
-    uint8_t sessionId;
-    uint8_t regionId;
-    uint8_t lockPolicy;
-    uint16_t msTimeout;
-} __attribute__((packed));
-
-constexpr size_t maxMDRId = 5;
diff --git a/src/smbioshandler.cpp b/src/smbioshandler.cpp
deleted file mode 100644
index cc882be..0000000
--- a/src/smbioshandler.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
-// 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 <commandutils.hpp>
-#include <ipmid/api.hpp>
-#include <ipmid/utils.hpp>
-#include <phosphor-logging/elog-errors.hpp>
-#include <phosphor-logging/log.hpp>
-#include <smbioshandler.hpp>
-#include <types.hpp>
-#include <xyz/openbmc_project/Common/error.hpp>
-
-#include <cstdint>
-#include <iostream>
-#include <string>
-#include <vector>
-
-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 constexpr uint8_t maxDataLen = 254;
-
-static void register_netfn_smbios_functions() __attribute__((constructor));
-
-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::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    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, ipmi::DbusVariant& value,
-                              std::string& service)
-{
-    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    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)
-{
-    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
-                                       DBUS_PROPERTIES, "Set");
-    ipmi::DbusVariant 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;
-
-    ipmi::DbusVariant 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::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    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 == std::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 != std::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);
-    ipmi::DbusVariant regUsedVal;
-    ipmi::DbusVariant 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::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    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->length >= maxDataLen) ||
-        (requestData->offset + requestData->length >
-         std::get<uint16_t>(regUsedVal)))
-    {
-        phosphor::logging::log<level::INFO>(
-            "Invalid data request",
-            phosphor::logging::entry("OFFSET=%d", requestData->offset),
-            phosphor::logging::entry("LENGTH=%d", requestData->length),
-            phosphor::logging::entry("REGUSED=%d",
-                                     std::get<uint16_t>(regUsedVal)));
-        return IPMI_CC_INVALID_FIELD_REQUEST;
-    }
-
-    if (0 > sdplus_mdrv1_get_property("LockPolicy", lockPolicyVal, service))
-    {
-        phosphor::logging::log<level::ERR>("Error getting lockPolicy");
-        return IPMI_CC_UNSPECIFIED_ERROR;
-    }
-    if (regionLockUnlocked != std::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 >= maxDataLen))
-    {
-        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;
-    }
-
-    ipmi::DbusVariant value;
-
-    *data_len = 0;
-
-    if (regionId >= maxMDRId)
-    {
-        phosphor::logging::log<level::ERR>("Invalid region");
-        return IPMI_CC_PARM_OUT_OF_RANGE;
-    }
-
-    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    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 == std::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 != std::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;
-    ipmi::DbusVariant 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::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    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 == std::get<uint8_t>(value))
-        {
-            return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
-        }
-    }
-    if (regionLockUnlocked != std::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 != std::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)
-{
-#ifdef MDR_V1_SUPPORT
-    // MDR V1 Command
-    // <Get MDR Status Command>
-    ipmi_register_callback(ipmi::intel::netFnApp,
-                           ipmi::intel::app::cmdMdrStatus, NULL,
-                           cmd_region_status, PRIVILEGE_OPERATOR);
-
-    // <Update Complete Status Command>
-    ipmi_register_callback(ipmi::intel::netFnApp,
-                           ipmi::intel::app::cmdMdrComplete, NULL,
-                           cmd_region_complete, PRIVILEGE_OPERATOR);
-
-    // <Read MDR Command>
-    ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrRead,
-                           NULL, cmd_region_read, PRIVILEGE_OPERATOR);
-
-    // <Write MDR Command>
-    ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrWrite,
-                           NULL, cmd_region_write, PRIVILEGE_OPERATOR);
-
-    // <Lock MDR Command>
-    ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrLock,
-                           NULL, cmd_region_lock, PRIVILEGE_OPERATOR);
-#endif
-}
