diff --git a/include/oemcommands.hpp b/include/oemcommands.hpp
index a382716..a6ece9c 100644
--- a/include/oemcommands.hpp
+++ b/include/oemcommands.hpp
@@ -52,6 +52,7 @@
 static constexpr Cmd cmdSetShutdownPolicy = 0x60;
 static constexpr Cmd cmdGetShutdownPolicy = 0x62;
 static constexpr Cmd cmdGetMultiNodePresence = 0x63;
+static constexpr Cmd cmdGetBufferSize = 0x66;
 static constexpr Cmd cmdSetFanConfig = 0x89;
 static constexpr Cmd cmdGetFanConfig = 0x8a;
 static constexpr Cmd cmdSetFanSpeedOffset = 0x8c;
diff --git a/src/firmware-update.cpp b/src/firmware-update.cpp
index d949a33..d3236d5 100644
--- a/src/firmware-update.cpp
+++ b/src/firmware-update.cpp
@@ -7,7 +7,7 @@
 #include <unistd.h>
 
 #include <boost/algorithm/string.hpp>
-#include <boost/asio.hpp>
+#include <boost/container/flat_map.hpp>
 #include <boost/process/child.hpp>
 #include <boost/uuid/random_generator.hpp>
 #include <boost/uuid/uuid_io.hpp>
@@ -20,35 +20,98 @@
 #include <ipmid/api.hpp>
 #include <ipmid/utils.hpp>
 #include <map>
+#include <phosphor-logging/log.hpp>
 #include <random>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/bus/match.hpp>
 #include <sdbusplus/server/object.hpp>
 #include <sdbusplus/timer.hpp>
-#include <sstream>
 #ifdef INTEL_PFR_ENABLED
 #include <spiDev.hpp>
 #endif
 
+static constexpr bool DEBUG = true;
+static void registerFirmwareFunctions() __attribute__((constructor));
+
 namespace ipmi
 {
 namespace firmware
 {
 constexpr Cmd cmdGetFwVersionInfo = 0x20;
+constexpr Cmd cmdGetFwSecurityVersionInfo = 0x21;
+constexpr Cmd cmdGetFwUpdateChannelInfo = 0x22;
+constexpr Cmd cmdGetBmcExecutionContext = 0x23;
 constexpr Cmd cmdFwGetRootCertData = 0x25;
+constexpr Cmd cmdGetFwUpdateRandomNumber = 0x26;
+constexpr Cmd cmdSetFirmwareUpdateMode = 0x27;
+constexpr Cmd cmdExitFirmwareUpdateMode = 0x28;
+constexpr Cmd cmdGetSetFwUpdateControl = 0x29;
+constexpr Cmd cmdGetFirmwareUpdateStatus = 0x2A;
+constexpr Cmd cmdSetFirmwareUpdateOptions = 0x2B;
 constexpr Cmd cmdFwImageWriteData = 0x2c;
 } // namespace firmware
 } // namespace ipmi
 
+namespace ipmi
+{
+// Custom completion codes
+constexpr Cc ccUsbAttachOrDetachFailed = 0x80;
+constexpr Cc ccNotSupportedInPresentState = 0xD5;
+
+static inline auto responseUsbAttachOrDetachFailed()
+{
+    return response(ccUsbAttachOrDetachFailed);
+}
+static inline auto responseNotSupportedInPresentState()
+{
+    return response(ccNotSupportedInPresentState);
+}
+} // namespace ipmi
+
+static constexpr const char *bmcStateIntf = "xyz.openbmc_project.State.BMC";
+static constexpr const char *bmcStatePath = "/xyz/openbmc_project/state/bmc0";
+static constexpr const char *bmcStateReady =
+    "xyz.openbmc_project.State.BMC.BMCState.Ready";
+static constexpr const char *bmcStateUpdateInProgress =
+    "xyz.openbmc_project.State.BMC.BMCState.UpdateInProgress";
+
+static constexpr char firmwareBufferFile[] = "/tmp/fw-download.bin";
+static std::chrono::steady_clock::time_point fwRandomNumGenTs;
+static constexpr auto fwRandomNumExpirySeconds = std::chrono::seconds(30);
+static constexpr size_t fwRandomNumLength = 8;
+static std::array<uint8_t, fwRandomNumLength> fwRandomNum;
+constexpr char usbCtrlPath[] = "/usr/bin/usb-ctrl";
+constexpr char fwUpdateMountPoint[] = "/tmp/usb-fwupd.mnt";
+constexpr char fwUpdateUsbVolImage[] = "/tmp/usb-fwupd.img";
+constexpr char fwUpdateUSBDevName[] = "fw-usb-mass-storage-dev";
+constexpr size_t fwPathMaxLength = 255;
+
 #ifdef INTEL_PFR_ENABLED
 uint32_t imgLength = 0;
 uint32_t imgType = 0;
 bool block0Mapped = false;
 static constexpr uint32_t perBlock0MagicNum = 0xB6EAFD19;
 
+static constexpr const char *bmcActivePfmMTDDev = "/dev/mtd/pfm";
+static constexpr const char *bmcRecoveryImgMTDDev = "/dev/mtd/rc-image";
+static constexpr size_t pfmBaseOffsetInImage = 0x400;
+static constexpr size_t rootkeyOffsetInPfm = 0xA0;
+static constexpr size_t cskKeyOffsetInPfm = 0x124;
+static constexpr size_t cskSignatureOffsetInPfm = 0x19c;
+static constexpr size_t certKeyLen = 96;
+static constexpr size_t cskSignatureLen = 96;
+
 static constexpr const char *versionIntf =
     "xyz.openbmc_project.Software.Version";
 
+enum class FwGetRootCertDataTag : uint8_t
+{
+    activeRootKey = 1,
+    recoveryRootKey,
+    activeCSK,
+    recoveryCSK,
+};
+
 enum class FWDeviceIDTag : uint8_t
 {
     bmcActiveImage = 1,
@@ -60,269 +123,349 @@
                     "/xyz/openbmc_project/software/bmc_active"},
                    {FWDeviceIDTag::bmcRecoveryImage,
                     "/xyz/openbmc_project/software/bmc_recovery"}};
+#endif // INTEL_PFR_ENABLED
 
-#endif
+enum class ChannelIdTag : uint8_t
+{
+    reserved = 0,
+    kcs = 1,
+    ipmb = 2,
+    rmcpPlus = 3
+};
 
-static constexpr const char *bmcStateIntf = "xyz.openbmc_project.State.BMC";
-static constexpr const char *bmcStatePath = "/xyz/openbmc_project/state/bmc0";
-static constexpr const char *bmcStateReady =
-    "xyz.openbmc_project.State.BMC.BMCState.Ready";
-static constexpr const char *bmcStateUpdateInProgress =
-    "xyz.openbmc_project.State.BMC.BMCState.UpdateInProgress";
+enum class BmcExecutionContext : uint8_t
+{
+    reserved = 0,
+    linuxOs = 0x10,
+    bootLoader = 0x11,
+};
 
-static constexpr const char *secondaryFitImageStartAddr = "22480000";
-static uint8_t getActiveBootImage(void);
-static void register_netfn_firmware_functions() __attribute__((constructor));
-
-// oem return code for firmware update control
-constexpr ipmi_ret_t IPMI_CC_REQ_INVALID_PHASE = 0xd5;
-constexpr ipmi_ret_t IPMI_CC_USB_ATTACH_FAIL = 0x80;
-
-static constexpr bool DEBUG = false;
-
-static constexpr char FW_UPDATE_SERVER_DBUS_NAME[] =
-    "xyz.openbmc_project.fwupdate1.server";
-
-static constexpr char FW_UPDATE_SERVER_PATH[] =
-    "/xyz/openbmc_project/fwupdate1";
-static constexpr char FW_UPDATE_SERVER_INFO_PATH[] =
-    "/xyz/openbmc_project/fwupdate1/info";
-static constexpr char FW_UPDATE_ACTIVE_INFO_PATH[] =
-    "/xyz/openbmc_project/fwupdate1/info/bmc_active";
-static constexpr char FW_UPDATE_BACKUP_INFO_PATH[] =
-    "/xyz/openbmc_project/fwupdate1/info/bmc_backup";
-
-static constexpr char FW_UPDATE_INTERFACE[] = "xyz.openbmc_project.fwupdate1";
-static constexpr char FW_UPDATE_INFO_INTERFACE[] =
-    "xyz.openbmc_project.fwupdate1.fwinfo";
-static constexpr char FW_UPDATE_SECURITY_INTERFACE[] =
-    "xyz.openbmc_project.fwupdate1.security";
+enum class FwUpdateCtrlReq : uint8_t
+{
+    getCurrentControlStatus = 0x00,
+    imageTransferStart = 0x01,
+    imageTransferComplete = 0x02,
+    imageTransferAbort = 0x03,
+    setFirmwareFilename = 0x04,
+    attachUsbDevice = 0x05,
+    detachUsbDevice = 0x06
+};
 
 constexpr std::size_t operator""_MB(unsigned long long v)
 {
     return 1024u * 1024u * v;
 }
-static constexpr int FIRMWARE_BUFFER_MAX_SIZE = 32_MB;
+static constexpr size_t maxFirmwareImageSize = 32_MB;
 
-static constexpr char FIRMWARE_BUFFER_FILE[] = "/tmp/fw-download.bin";
-static bool local_download_is_active(void)
+static bool localDownloadInProgress(void)
 {
     struct stat sb;
-    if (stat(FIRMWARE_BUFFER_FILE, &sb) < 0)
+    if (stat(firmwareBufferFile, &sb) < 0)
+    {
         return false;
+    }
     return true;
 }
 
-class fw_update_status_cache
+class TransferHashCheck
+{
+  public:
+    enum class HashCheck : uint8_t
+    {
+        notRequested = 0,
+        requested,
+        sha2Success,
+        sha2Failed = 0xe2,
+    };
+
+  protected:
+    EVP_MD_CTX *ctx;
+    std::vector<uint8_t> expectedHash;
+    enum HashCheck check;
+    bool started;
+
+  public:
+    TransferHashCheck() : check(HashCheck::notRequested), started(false)
+    {
+    }
+    ~TransferHashCheck()
+    {
+        if (ctx)
+        {
+            EVP_MD_CTX_destroy(ctx);
+            ctx = NULL;
+        }
+    }
+    void init(const std::vector<uint8_t> &expected)
+    {
+        expectedHash = expected;
+        check = HashCheck::requested;
+        ctx = EVP_MD_CTX_create();
+        EVP_DigestInit(ctx, EVP_sha256());
+    }
+    void hash(const std::vector<uint8_t> &data)
+    {
+        if (!started)
+        {
+            started = true;
+        }
+        EVP_DigestUpdate(ctx, data.data(), data.size());
+    }
+    void clear()
+    {
+        // if not started, nothing to clear
+        if (started)
+        {
+            if (ctx)
+            {
+                EVP_MD_CTX_destroy(ctx);
+            }
+            if (check != HashCheck::notRequested)
+            {
+                check = HashCheck::requested;
+            }
+            ctx = EVP_MD_CTX_create();
+            EVP_DigestInit(ctx, EVP_sha256());
+        }
+    }
+    enum HashCheck verify()
+    {
+        if (check == HashCheck::requested)
+        {
+            unsigned int len = 0;
+            std::vector<uint8_t> digest(EVP_MD_size(EVP_sha256()));
+            EVP_DigestFinal(ctx, digest.data(), &len);
+            if (digest == expectedHash)
+            {
+                phosphor::logging::log<phosphor::logging::level::INFO>(
+                    "Transfer sha2 verify passed.");
+                check = HashCheck::sha2Success;
+            }
+            else
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Transfer sha2 verify failed.");
+                check = HashCheck::sha2Failed;
+            }
+        }
+        return check;
+    }
+    uint8_t status() const
+    {
+        return static_cast<uint8_t>(check);
+    }
+};
+
+class MappedFile
+{
+  public:
+    MappedFile(const std::string &fname) : addr(nullptr), fsize(0)
+    {
+        std::error_code ec;
+        size_t sz = std::filesystem::file_size(fname, ec);
+        int fd = open(fname.c_str(), O_RDONLY);
+        if (!ec || fd < 0)
+        {
+            return;
+        }
+        void *tmp = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
+        close(fd);
+        if (tmp == MAP_FAILED)
+        {
+            return;
+        }
+        addr = tmp;
+        fsize = sz;
+    }
+
+    ~MappedFile()
+    {
+        if (addr)
+        {
+            munmap(addr, fsize);
+        }
+    }
+    const uint8_t *data() const
+    {
+        return static_cast<const uint8_t *>(addr);
+    }
+    size_t size() const
+    {
+        return fsize;
+    }
+
+  private:
+    size_t fsize;
+    void *addr;
+};
+
+class FwUpdateStatusCache
 {
   public:
     enum
     {
-        FW_STATE_INIT = 0,
-        FW_STATE_IDLE,
-        FW_STATE_DOWNLOAD,
-        FW_STATE_VERIFY,
-        FW_STATE_WRITE,
-        FW_STATE_READY,
-        FW_STATE_ERROR = 0x0f,
-        FW_STATE_AC_CYCLE_REQUIRED = 0x83,
+        fwStateInit = 0,
+        fwStateIdle,
+        fwStateDownload,
+        fwStateVerify,
+        fwStateProgram,
+        fwStateUpdateSuccess,
+        fwStateError = 0x0f,
+        fwStateAcCycleRequired = 0x83,
     };
-    uint8_t state()
+    uint8_t getState()
     {
-        if (DEBUG)
-            std::cerr << "fw-state: 0x" << std::hex << (int)_state << '\n';
-        if ((_state == FW_STATE_IDLE || _state == FW_STATE_INIT) &&
-            local_download_is_active())
+        if ((fwUpdateState == fwStateIdle || fwUpdateState == fwStateInit) &&
+            localDownloadInProgress())
         {
-            _state = FW_STATE_DOWNLOAD;
-            _percent = 0;
+            fwUpdateState = fwStateDownload;
+            progressPercent = 0;
         }
-        return _state;
+        return fwUpdateState;
+    }
+    void resetStatusCache()
+    {
+        unlink(firmwareBufferFile);
+    }
+    void setState(const uint8_t state)
+    {
+        switch (state)
+        {
+            case fwStateInit:
+            case fwStateIdle:
+            case fwStateError:
+                resetStatusCache();
+                break;
+            case fwStateDownload:
+            case fwStateVerify:
+            case fwStateProgram:
+            case fwStateUpdateSuccess:
+                break;
+            default:
+                // Error
+                break;
+        }
+        fwUpdateState = state;
     }
     uint8_t percent()
     {
-        return _percent;
+        return progressPercent;
     }
-    std::string msg()
+    void updateActivationPercent(const std::string &objPath)
     {
-        return _msg;
-    }
-    std::string get_software_obj_path()
-    {
-        return _software_obj_path;
-    }
-    void set_software_obj_path(std::string &obj_path)
-    {
-        _software_obj_path = obj_path;
-        _state = FW_STATE_WRITE;
-        _percent = 0;
-        _match = std::make_shared<sdbusplus::bus::match::match>(
-            *_bus,
+        std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+        fwUpdateState = fwStateProgram;
+        progressPercent = 0;
+        match = std::make_shared<sdbusplus::bus::match::match>(
+            *busp,
             sdbusplus::bus::match::rules::propertiesChanged(
-                _software_obj_path,
-                "xyz.openbmc_project.Software.ActivationProgress"),
+                objPath, "xyz.openbmc_project.Software.ActivationProgress"),
             [&](sdbusplus::message::message &msg) {
-                if (DEBUG)
-                    std::cerr << "propertiesChanged lambda\n";
                 std::map<std::string, ipmi::DbusVariant> props;
-                std::vector<std::string> inval;
+                std::vector<std::string> inVal;
                 std::string iface;
-                msg.read(iface, props, inval);
-                _parse_props(props);
+                try
+                {
+                    msg.read(iface, props, inVal);
+                }
+                catch (const std::exception &e)
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "Exception caught in get ActivationProgress");
+                    return;
+                }
+
+                auto it = props.find("Progress");
+                if (it != props.end())
+                {
+                    progressPercent = std::get<uint8_t>(it->second);
+                    if (progressPercent == 100)
+                    {
+                        fwUpdateState = fwStateUpdateSuccess;
+                    }
+                }
             });
     }
-    uint8_t activation_timer_timeout()
+    uint8_t activationTimerTimeout()
     {
-        std::cerr << "activation_timer_timout(): increase percentage...\n";
-        _percent = _percent + 5;
-        if (_percent >= 95)
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "activationTimerTimeout: Increase percentage...",
+            phosphor::logging::entry("PERCENT:%d", progressPercent));
+        progressPercent = progressPercent + 5;
+        if (progressPercent >= 95)
         {
             /*changing the state to ready to update firmware utility */
-            _state = FW_STATE_READY;
+            fwUpdateState = fwStateUpdateSuccess;
         }
-        std::cerr << " _percent = " << (int)_percent << "\n";
-        return _percent;
+        return progressPercent;
     }
     /* API for changing state to ERROR  */
     void firmwareUpdateAbortState()
     {
-        unlink(FIRMWARE_BUFFER_FILE);
+        unlink(firmwareBufferFile);
         // changing the state to error
-        _state = FW_STATE_ERROR;
+        fwUpdateState = fwStateError;
     }
     void setDeferRestart(bool deferRestart)
     {
-        _deferRestart = deferRestart;
+        deferRestartState = deferRestart;
     }
     void setInhibitDowngrade(bool inhibitDowngrade)
     {
-        _inhibitDowngrade = inhibitDowngrade;
+        inhibitDowngradeState = inhibitDowngrade;
     }
     bool getDeferRestart()
     {
-        return _deferRestart;
+        return deferRestartState;
     }
     bool getInhibitDowngrade()
     {
-        return _inhibitDowngrade;
+        return inhibitDowngradeState;
     }
 
   protected:
-    void _parse_props(std::map<std::string, ipmi::DbusVariant> &properties)
-    {
-        if (DEBUG)
-            std::cerr << "propertiesChanged (" << properties.size()
-                      << " elements)";
-        for (const auto &t : properties)
-        {
-            auto key = t.first;
-            auto value = t.second;
-            if (key == "state")
-            {
-                auto state = std::get<std::string>(value);
-                if (DEBUG)
-                    std::cerr << ", state=" << state;
-                if (state == "INIT")
-                    _state = FW_STATE_INIT;
-                else if (state == "IDLE")
-                    _state = FW_STATE_IDLE;
-                else if (state == "DOWNLOAD")
-                    _state = FW_STATE_DOWNLOAD;
-                else if (state == "VERIFY")
-                    _state = FW_STATE_VERIFY;
-                else if (state == "WRITE")
-                    _state = FW_STATE_WRITE;
-                else if (state == "READY")
-                    _state = FW_STATE_READY;
-                else if (state == "ERROR")
-                    _state = FW_STATE_ERROR;
-                else if (state == "AC_CYCLE_REQUIRED")
-                    _state = FW_STATE_AC_CYCLE_REQUIRED;
-                else
-                {
-                    _state = FW_STATE_ERROR;
-                    _msg = "internal error";
-                }
-            }
-            else if (key == "percent")
-            {
-                _percent = std::get<int32_t>(value);
-                if (DEBUG)
-                    std::cerr << ", pct=" << (int)_percent;
-            }
-            else if (key == "msg")
-            {
-                _msg = std::get<std::string>(value);
-                if (DEBUG)
-                    std::cerr << ", msg='" << _msg << '\'';
-            }
-            else if (key == "Progress")
-            {
-                _percent = std::get<uint8_t>(value);
-                ;
-                if (_percent == 100)
-                    _state = FW_STATE_READY;
-            }
-        }
-        if ((_state == FW_STATE_IDLE || _state == FW_STATE_INIT) &&
-            local_download_is_active())
-        {
-            _state = FW_STATE_DOWNLOAD;
-            _percent = 0;
-        }
-        if (DEBUG)
-            std::cerr << '\n';
-    }
-
-    std::shared_ptr<sdbusplus::asio::connection> _bus;
-    std::shared_ptr<sdbusplus::bus::match::match> _match;
-    uint8_t _state = 0;
-    uint8_t _percent = 0;
-    bool _deferRestart = false;
-    bool _inhibitDowngrade = false;
-    std::string _msg;
-
-  private:
-    std::string _software_obj_path;
+    std::shared_ptr<sdbusplus::asio::connection> busp;
+    std::shared_ptr<sdbusplus::bus::match::match> match;
+    uint8_t fwUpdateState = 0;
+    uint8_t progressPercent = 0;
+    bool deferRestartState = false;
+    bool inhibitDowngradeState = false;
 };
 
-static fw_update_status_cache fw_update_status;
+static FwUpdateStatusCache fwUpdateStatus;
+std::shared_ptr<TransferHashCheck> xferHashCheck;
 
-static std::chrono::steady_clock::time_point fw_random_number_timestamp;
-static constexpr int FW_RANDOM_NUMBER_LENGTH = 8;
-static constexpr auto FW_RANDOM_NUMBER_TTL = std::chrono::seconds(30);
-static uint8_t fw_random_number[FW_RANDOM_NUMBER_LENGTH];
-
-static ipmi_ret_t ipmi_firmware_get_fw_random_number(
-    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)
+static void activateImage(const std::string &objPath)
 {
-    std::random_device rd;
-    std::default_random_engine gen(rd());
-    std::uniform_int_distribution<> dist{0, 255};
-
-    if (*data_len != 0)
+    // If flag is false  means to reboot
+    if (fwUpdateStatus.getDeferRestart() == false)
     {
-        *data_len = 0;
-        return IPMI_CC_REQ_DATA_LEN_INVALID;
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "activating Image: ",
+            phosphor::logging::entry("OBJPATH =%s", objPath.c_str()));
+        std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
+        bus->async_method_call(
+            [](const boost::system::error_code ec) {
+                if (ec)
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "async_method_call error: activateImage failed");
+                    return;
+                }
+            },
+            "xyz.openbmc_project.Software.BMC.Updater", objPath,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Software.Activation", "RequestedActivation",
+            std::variant<std::string>("xyz.openbmc_project.Software.Activation."
+                                      "RequestedActivations.Active"));
     }
-
-    fw_random_number_timestamp = std::chrono::steady_clock::now();
-
-    uint8_t *msg_reply = static_cast<uint8_t *>(response);
-    for (int i = 0; i < FW_RANDOM_NUMBER_LENGTH; i++)
-        fw_random_number[i] = msg_reply[i] = dist(gen);
-
-    if (DEBUG)
-        std::cerr << "FW Rand Num: 0x" << std::hex << (int)msg_reply[0] << " 0x"
-                  << (int)msg_reply[1] << " 0x" << (int)msg_reply[2] << " 0x"
-                  << (int)msg_reply[3] << " 0x" << (int)msg_reply[4] << " 0x"
-                  << (int)msg_reply[5] << " 0x" << (int)msg_reply[6] << " 0x"
-                  << (int)msg_reply[7] << '\n';
-
-    *data_len = FW_RANDOM_NUMBER_LENGTH;
-
-    return IPMI_CC_OK;
+    else
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "Firmware image activation is deferred.");
+    }
+    fwUpdateStatus.setState(
+        static_cast<uint8_t>(FwUpdateStatusCache::fwStateUpdateSuccess));
 }
 
 static bool getFirmwareUpdateMode()
@@ -370,422 +513,130 @@
     }
 }
 
-/** @brief Set Firmware Update Mode
- *
- *  This function sets BMC into firmware update mode
- *  after validating Random number obtained from the Get
- *  Firmware Update Random Number command
- *
- *  @parameter
- *   -  randNum - Random number(token)
- *  @returns IPMI completion code
- **/
-ipmi::RspType<> ipmiSetFirmwareUpdateMode(
-    std::array<uint8_t, FW_RANDOM_NUMBER_LENGTH> &randNum)
-{
-    /* Firmware Update Random number is valid for 30 seconds only */
-    auto timeElapsed =
-        (std::chrono::steady_clock::now() - fw_random_number_timestamp);
-    if (std::chrono::duration_cast<std::chrono::microseconds>(timeElapsed)
-            .count() > std::chrono::duration_cast<std::chrono::microseconds>(
-                           FW_RANDOM_NUMBER_TTL)
-                           .count())
-    {
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "Firmware update random number expired.");
-        return ipmi::responseInvalidFieldRequest();
-    }
-
-    /* Validate random number */
-    for (int i = 0; i < FW_RANDOM_NUMBER_LENGTH; i++)
-    {
-        if (fw_random_number[i] != randNum[i])
-        {
-            phosphor::logging::log<phosphor::logging::level::INFO>(
-                "Invalid random number specified.");
-            return ipmi::responseInvalidFieldRequest();
-        }
-    }
-
-    try
-    {
-        if (getFirmwareUpdateMode())
-        {
-            phosphor::logging::log<phosphor::logging::level::INFO>(
-                "Already firmware update is in progress.");
-            return ipmi::responseBusy();
-        }
-    }
-    catch (const std::exception &e)
-    {
-        return ipmi::responseUnspecifiedError();
-    }
-
-    // FIXME? c++ doesn't off an option for exclusive file creation
-    FILE *fp = fopen(FIRMWARE_BUFFER_FILE, "wx");
-    if (!fp)
-    {
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "Unable to open file.");
-        return ipmi::responseUnspecifiedError();
-    }
-    fclose(fp);
-
-    try
-    {
-        setFirmwareUpdateMode(true);
-    }
-    catch (const std::exception &e)
-    {
-        unlink(FIRMWARE_BUFFER_FILE);
-        return ipmi::responseUnspecifiedError();
-    }
-
-    return ipmi::responseSuccess();
-}
-
-/** @brief implements exit firmware update mode command
- *  @param None
- *
- *  @returns IPMI completion code
- */
-ipmi::RspType<> ipmiFirmwareExitFwUpdateMode()
-{
-
-    if (DEBUG)
-    {
-        std::cerr << "Exit FW update mode \n";
-    }
-    switch (fw_update_status.state())
-    {
-        case fw_update_status_cache::FW_STATE_INIT:
-        case fw_update_status_cache::FW_STATE_IDLE:
-            return ipmi::responseInvalidFieldRequest();
-            break;
-        case fw_update_status_cache::FW_STATE_DOWNLOAD:
-        case fw_update_status_cache::FW_STATE_VERIFY:
-            break;
-        case fw_update_status_cache::FW_STATE_WRITE:
-            break;
-        case fw_update_status_cache::FW_STATE_READY:
-        case fw_update_status_cache::FW_STATE_ERROR:
-            break;
-        case fw_update_status_cache::FW_STATE_AC_CYCLE_REQUIRED:
-            return ipmi::responseInvalidFieldRequest();
-            break;
-    }
-    fw_update_status.firmwareUpdateAbortState();
-
-    try
-    {
-        setFirmwareUpdateMode(false);
-    }
-    catch (const std::exception &e)
-    {
-        return ipmi::responseUnspecifiedError();
-    }
-
-    return ipmi::responseSuccess();
-}
-
-static void post_transfer_complete_handler(
-    std::unique_ptr<sdbusplus::bus::match::match> &fw_update_matcher);
-static bool request_start_firmware_update(const std::string &uri)
-{
-    if (DEBUG)
-        std::cerr << "request start firmware update()\n";
-
-    // fwupdate URIs start with file:// or usb:// or tftp:// etc. By the time
-    // the code gets to this point, the file should be transferred start the
-    // request (creating a new file in /tmp/images causes the update manager to
-    // check if it is ready for activation)
-    static std::unique_ptr<sdbusplus::bus::match::match> fw_update_matcher;
-    post_transfer_complete_handler(fw_update_matcher);
-    std::filesystem::rename(
-        uri, "/tmp/images/" +
-                 boost::uuids::to_string(boost::uuids::random_generator()()));
-    return true;
-}
-
-class transfer_hash_check
-{
-  public:
-    enum hash_check
-    {
-        CHECK_NOT_REQUESTED = 0,
-        CHECK_REQUESTED,
-        CHECK_PASSED_SHA2,
-        CHECK_RESVD1,
-        CHECK_FAILED_SHA2 = 0xe2,
-        CHECK_RESVD2 = 0xe3,
-    };
-
-  protected:
-    EVP_MD_CTX *_ctx;
-    std::vector<uint8_t> _expected;
-    enum hash_check _check;
-    bool _started;
-
-  public:
-    transfer_hash_check() : _check(CHECK_NOT_REQUESTED), _started(false)
-    {
-    }
-    ~transfer_hash_check()
-    {
-        if (_ctx)
-        {
-            EVP_MD_CTX_destroy(_ctx);
-            _ctx = NULL;
-        }
-    }
-    void init(const std::vector<uint8_t> &expected)
-    {
-        _expected = expected;
-        _check = CHECK_REQUESTED;
-        _ctx = EVP_MD_CTX_create();
-        EVP_DigestInit(_ctx, EVP_sha256());
-    }
-    void hash(const std::vector<uint8_t> &data)
-    {
-        if (!_started)
-            _started = true;
-        EVP_DigestUpdate(_ctx, data.data(), data.size());
-    }
-    void clear()
-    {
-        // if not started, nothing to clear
-        if (_started)
-        {
-            if (_ctx)
-                EVP_MD_CTX_destroy(_ctx);
-            if (_check != CHECK_NOT_REQUESTED)
-                _check = CHECK_REQUESTED;
-            _ctx = EVP_MD_CTX_create();
-            EVP_DigestInit(_ctx, EVP_sha256());
-        }
-    }
-    enum hash_check check()
-    {
-        if (_check == CHECK_REQUESTED)
-        {
-            unsigned int len;
-            std::vector<uint8_t> digest(EVP_MD_size(EVP_sha256()));
-            EVP_DigestFinal(_ctx, digest.data(), &len);
-            if (digest == _expected)
-            {
-                if (DEBUG)
-                    std::cerr << "transfer sha2 check passed\n";
-                _check = CHECK_PASSED_SHA2;
-            }
-            else
-            {
-                if (DEBUG)
-                    std::cerr << "transfer sha2 check failed\n";
-                _check = CHECK_FAILED_SHA2;
-            }
-        }
-        return _check;
-    }
-    uint8_t status() const
-    {
-        return static_cast<uint8_t>(_check);
-    }
-};
-
-std::shared_ptr<transfer_hash_check> xfer_hash_check;
-
-static void activate_image(const char *obj_path)
-{
-    // If flag is false  means to reboot
-    if (fw_update_status.getDeferRestart() == false)
-    {
-
-        if (DEBUG)
-        {
-            std::cerr << "activateImage()...\n";
-            std::cerr << "obj_path = " << obj_path << "\n";
-        }
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "activating Image: ",
-            phosphor::logging::entry("OBJPATH =%s", obj_path));
-        std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-        bus->async_method_call(
-            [](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    phosphor::logging::log<phosphor::logging::level::ERR>(
-                        "async_method_call error: activate_image failed");
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Software.BMC.Updater", obj_path,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Software.Activation", "RequestedActivation",
-            std::variant<std::string>("xyz.openbmc_project.Software.Activation."
-                                      "RequestedActivations.Active"));
-    }
-    else
-    {
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "Firmware image activation is deferred.");
-    }
-}
-
-static void post_transfer_complete_handler(
-    std::unique_ptr<sdbusplus::bus::match::match> &fw_update_matcher)
+static void postTransferCompleteHandler(
+    std::unique_ptr<sdbusplus::bus::match::match> &fwUpdateMatchSignal)
 {
     // Setup timer for watching signal
     static phosphor::Timer timer(
-        [&fw_update_matcher]() { fw_update_matcher = nullptr; });
+        [&fwUpdateMatchSignal]() { fwUpdateMatchSignal = nullptr; });
 
-    static phosphor::Timer activation_status_timer([]() {
-        if (fw_update_status.activation_timer_timeout() >= 95)
+    static phosphor::Timer activationStatusTimer([]() {
+        if (fwUpdateStatus.activationTimerTimeout() >= 95)
         {
-            activation_status_timer.stop();
+            activationStatusTimer.stop();
+            fwUpdateStatus.setState(
+                static_cast<uint8_t>(FwUpdateStatusCache::fwStateVerify));
         }
     });
 
     timer.start(std::chrono::microseconds(5000000), false);
 
     // callback function for capturing signal
-    auto callback = [&fw_update_matcher](sdbusplus::message::message &m) {
-        if (DEBUG)
-            std::cerr << "[complete] Match fired\n";
+    auto callback = [&](sdbusplus::message::message &m) {
         bool flag = false;
 
         std::vector<std::pair<
             std::string,
             std::vector<std::pair<std::string, std::variant<std::string>>>>>
-            interfaces_properties;
-
-        sdbusplus::message::object_path obj_path;
+            intfPropsPair;
+        sdbusplus::message::object_path objPath;
 
         try
         {
-            m.read(obj_path, interfaces_properties); // Read in the object path
-                                                     // that was just created
+            m.read(objPath, intfPropsPair); // Read in the object path
+                                            // that was just created
         }
-        catch (std::exception &e)
+        catch (const std::exception &e)
         {
-            std::cerr
-                << "[complete] Failed at post_transfer_complete-handler : "
-                << e.what() << "\n";
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Exception caught in reading created object path.");
+            return;
         }
         // constructing response message
-        if (DEBUG)
-            std::cerr << "[complete] obj path = " << obj_path.str << "\n";
-        for (auto &interface : interfaces_properties)
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "New Interface Added.",
+            phosphor::logging::entry("OBJPATH=%s", objPath.str.c_str()));
+        for (auto &interface : intfPropsPair)
         {
-            if (DEBUG)
-                std::cerr << "[complete] interface = " << interface.first
-                          << "\n";
-
             if (interface.first == "xyz.openbmc_project.Software.Activation")
             {
-                // cancel timer only when
-                // xyz.openbmc_project.Software.Activation interface is
-                // added
+                // There are chances of getting two signals for
+                // InterfacesAdded. So cross check and discrad second instance.
+                if (fwUpdateMatchSignal == nullptr)
+                {
+                    return;
+                }
+                // Found our interface, disable callbacks
+                fwUpdateMatchSignal = nullptr;
 
-                if (DEBUG)
-                    std::cerr << "[complete] Attempt to cancel timer...\n";
+                phosphor::logging::log<phosphor::logging::level::INFO>(
+                    "Start activationStatusTimer for status.");
                 try
                 {
                     timer.stop();
-                    activation_status_timer.start(
+                    activationStatusTimer.start(
                         std::chrono::microseconds(3000000), true);
                 }
-                catch (std::exception &e)
+                catch (const std::exception &e)
                 {
-                    std::cerr << "[complete] cancel timer error: " << e.what()
-                              << "\n";
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "Exception caught in start activationStatusTimer.",
+                        phosphor::logging::entry("ERROR=%s", e.what()));
                 }
 
-                fw_update_status.set_software_obj_path(obj_path.str);
-                activate_image(obj_path.str.c_str());
-                if (DEBUG)
-                    std::cerr << "[complete] returned from activeImage()\n";
-
-                fw_update_matcher = nullptr;
+                fwUpdateStatus.updateActivationPercent(objPath.str);
+                activateImage(objPath.str);
             }
         }
     };
 
     // Adding matcher
-    fw_update_matcher = std::make_unique<sdbusplus::bus::match::match>(
+    fwUpdateMatchSignal = std::make_unique<sdbusplus::bus::match::match>(
         *getSdBus(),
         "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
         "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
         callback);
 }
-
-class MappedFile
+static bool startFirmwareUpdate(const std::string &uri)
 {
-  public:
-    MappedFile(const std::string &fname) : addr(nullptr), fsize(0)
-    {
-        std::error_code ec;
-        size_t sz = std::filesystem::file_size(fname, ec);
-        int fd = open(fname.c_str(), O_RDONLY);
-        if (!ec || fd < 0)
-        {
-            return;
-        }
-        void *tmp = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
-        close(fd);
-        if (tmp == MAP_FAILED)
-        {
-            return;
-        }
-        addr = tmp;
-        fsize = sz;
-    }
+    // fwupdate URIs start with file:// or usb:// or tftp:// etc. By the time
+    // the code gets to this point, the file should be transferred start the
+    // request (creating a new file in /tmp/images causes the update manager to
+    // check if it is ready for activation)
+    static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatchSignal;
+    postTransferCompleteHandler(fwUpdateMatchSignal);
+    std::filesystem::rename(
+        uri, "/tmp/images/" +
+                 boost::uuids::to_string(boost::uuids::random_generator()()));
+    return true;
+}
 
-    ~MappedFile()
-    {
-        if (addr)
-        {
-            munmap(addr, fsize);
-        }
-    }
-    const uint8_t *data() const
-    {
-        return static_cast<const uint8_t *>(addr);
-    }
-    size_t size() const
-    {
-        return fsize;
-    }
-
-  private:
-    size_t fsize;
-    void *addr;
-};
-
-static int transfer_from_file(const std::string &uri, bool move = true)
+static int transferImageFromFile(const std::string &uri, bool move = true)
 {
     std::error_code ec;
-    if (DEBUG)
-        std::cerr << "transfer_from_file(" << uri << ")\n";
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Transfer Image From File.",
+        phosphor::logging::entry("URI=%s", uri.c_str()));
     if (move)
     {
-        std::filesystem::rename(uri, FIRMWARE_BUFFER_FILE, ec);
+        std::filesystem::rename(uri, firmwareBufferFile, ec);
     }
     else
     {
-        std::filesystem::copy(uri, FIRMWARE_BUFFER_FILE,
+        std::filesystem::copy(uri, firmwareBufferFile,
                               std::filesystem::copy_options::overwrite_existing,
                               ec);
     }
-    if (xfer_hash_check)
+    if (xferHashCheck)
     {
         MappedFile mappedfw(uri);
-        xfer_hash_check->hash(
+        xferHashCheck->hash(
             {mappedfw.data(), mappedfw.data() + mappedfw.size()});
     }
     if (ec.value())
     {
-        std::cerr << "cp/mv returns: " << ec.message() << "(" << ec.value()
-                  << ")\n";
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Image copy failed.");
     }
     return ec.value();
 }
@@ -798,265 +649,116 @@
     return execProg.exit_code();
 }
 
-constexpr char USB_CTRL_PATH[] = "/usr/bin/usb-ctrl";
-constexpr char FWUPDATE_MOUNT_POINT[] = "/tmp/usb-fwupd.mnt";
-constexpr char FWUPDATE_USB_VOL_IMG[] = "/tmp/usb-fwupd.img";
-constexpr char FWUPDATE_USB_DEV_NAME[] = "fw-usb-mass-storage-dev";
-constexpr size_t fwPathMaxLength = 255;
-static int transfer_from_usb(const std::string &uri)
+static int transferImageFromUsb(const std::string &uri)
 {
     int ret, sysret;
     char fwpath[fwPathMaxLength];
-    if (DEBUG)
-        std::cerr << "transfer_from_usb(" << uri << ")\n";
-    ret = executeCmd(USB_CTRL_PATH, "mount", FWUPDATE_USB_VOL_IMG,
-                     FWUPDATE_MOUNT_POINT);
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Transfer Image From USB.",
+        phosphor::logging::entry("URI=%s", uri.c_str()));
+    ret = executeCmd(usbCtrlPath, "mount", fwUpdateUsbVolImage,
+                     fwUpdateMountPoint);
     if (ret)
     {
         return ret;
     }
 
-    std::string usb_path = std::string(FWUPDATE_MOUNT_POINT) + "/" + uri;
-    ret = transfer_from_file(usb_path, false);
+    std::string usb_path = std::string(fwUpdateMountPoint) + "/" + uri;
+    ret = transferImageFromFile(usb_path, false);
 
-    executeCmd(USB_CTRL_PATH, "cleanup", FWUPDATE_USB_VOL_IMG,
-               FWUPDATE_MOUNT_POINT);
+    executeCmd(usbCtrlPath, "cleanup", fwUpdateUsbVolImage, fwUpdateMountPoint);
     return ret;
 }
 
-static bool transfer_firmware_from_uri(const std::string &uri)
+static bool transferFirmwareFromUri(const std::string &uri)
 {
-    static constexpr char FW_URI_FILE[] = "file://";
-    static constexpr char FW_URI_USB[] = "usb://";
-    if (DEBUG)
-        std::cerr << "transfer_firmware_from_uri(" << uri << ")\n";
-    if (boost::algorithm::starts_with(uri, FW_URI_FILE))
+    static constexpr char fwUriFile[] = "file://";
+    static constexpr char fwUriUsb[] = "usb://";
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Transfer Image From URI.",
+        phosphor::logging::entry("URI=%s", uri.c_str()));
+    if (boost::algorithm::starts_with(uri, fwUriFile))
     {
-        std::string fname = uri.substr(sizeof(FW_URI_FILE) - 1);
-        if (fname != FIRMWARE_BUFFER_FILE)
+        std::string fname = uri.substr(sizeof(fwUriFile) - 1);
+        if (fname != firmwareBufferFile)
         {
-            return 0 == transfer_from_file(fname);
+            return 0 == transferImageFromFile(fname);
         }
         return true;
     }
-    if (boost::algorithm::starts_with(uri, FW_URI_USB))
+    if (boost::algorithm::starts_with(uri, fwUriUsb))
     {
-        std::string fname = uri.substr(sizeof(FW_URI_USB) - 1);
-        return 0 == transfer_from_usb(fname);
+        std::string fname = uri.substr(sizeof(fwUriUsb) - 1);
+        return 0 == transferImageFromUsb(fname);
     }
     return false;
 }
 
 /* Get USB-mass-storage device status: inserted => true, ejected => false */
-static int usb_get_status()
+static bool getUsbStatus()
 {
-    static constexpr char usb_gadget_base[] = "/sys/kernel/config/usb_gadget/";
-    auto usb_device =
-        std::filesystem::path(usb_gadget_base) / FWUPDATE_USB_DEV_NAME;
-    std::error_code ec;
-    return std::filesystem::exists(usb_device, ec) && !ec;
+    std::filesystem::path usbDevPath =
+        std::filesystem::path("/sys/kernel/config/usb_gadget") /
+        fwUpdateUSBDevName;
+    return (std::filesystem::exists(usbDevPath) ? true : false);
 }
 
 /* Insert the USB-mass-storage device status: success => 0, failure => non-0 */
-static int usb_attach_device()
+static int attachUsbDevice()
 {
-    if (usb_get_status())
+    if (getUsbStatus())
     {
         return 1;
     }
-    int ret =
-        executeCmd(USB_CTRL_PATH, "setup", FWUPDATE_USB_VOL_IMG,
-                   std::to_string(FIRMWARE_BUFFER_MAX_SIZE / 1_MB).c_str());
+    int ret = executeCmd(usbCtrlPath, "setup", fwUpdateUsbVolImage,
+                         std::to_string(maxFirmwareImageSize / 1_MB).c_str());
     if (!ret)
     {
-        ret = executeCmd(USB_CTRL_PATH, "insert", FWUPDATE_USB_DEV_NAME,
-                         FWUPDATE_USB_VOL_IMG);
+        ret = executeCmd(usbCtrlPath, "insert", fwUpdateUSBDevName,
+                         fwUpdateUsbVolImage);
     }
     return ret;
 }
 
 /* Eject the USB-mass-storage device status: success => 0, failure => non-0 */
-static int usb_detach_device()
+static int detachUsbDevice()
 {
-    if (!usb_get_status())
+    if (!getUsbStatus())
     {
         return 1;
     }
-    return executeCmd(USB_CTRL_PATH, "eject", FWUPDATE_USB_DEV_NAME);
+    return executeCmd(usbCtrlPath, "eject", fwUpdateUSBDevName);
 }
-
-constexpr uint8_t controls_init = 0x00;
-constexpr uint8_t controls_transfer_started = 0x01;
-constexpr uint8_t controls_transfer_completed = 0x02;
-constexpr uint8_t controls_transfer_aborted = 0x04;
-constexpr uint8_t controls_usb_attached = 0x08;
-
-struct fw_update_control_request
+static uint8_t getActiveBootImage(ipmi::Context::ptr ctx)
 {
-    enum knob
+    constexpr uint8_t primaryImage = 0x01;
+    constexpr uint8_t secondaryImage = 0x02;
+    constexpr const char *secondaryFitImageStartAddr = "22480000";
+
+    uint8_t bootImage = primaryImage;
+    boost::system::error_code ec;
+    std::string value = ctx->bus->yield_method_call<std::string>(
+        ctx->yield, ec, "xyz.openbmc_project.U_Boot.Environment.Manager",
+        "/xyz/openbmc_project/u_boot/environment/mgr",
+        "xyz.openbmc_project.U_Boot.Environment.Manager", "Read", "bootcmd");
+    if (ec)
     {
-        CTRL_GET = 0,
-        CTRL_XFER_START,
-        CTRL_XFER_COMPLETE,
-        CTRL_XFER_ABORT,
-        CTRL_SET_FILENAME,
-        CTRL_USB_ATTACH,
-        CTRL_USB_DETACH,
-    } __attribute__((packed));
-    enum knob control;
-    uint8_t nlen;
-    char filename[fwPathMaxLength];
-} __attribute__((packed));
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Failed to read the bootcmd value");
+        return ipmi::ccUnspecifiedError;
+    }
 
-static ipmi_ret_t ipmi_firmware_control(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)
-{
-    static std::string fw_xfer_uri;
-
-    if (DEBUG)
-        std::cerr << "FW update control\n";
-    *data_len = 0;
-
-    static uint8_t controls = controls_init;
-    ipmi_ret_t rc = IPMI_CC_OK;
-    auto ctrl_req = reinterpret_cast<fw_update_control_request *>(request);
-    auto ctrl_resp = reinterpret_cast<uint8_t *>(response);
-
-    if (usb_get_status())
+    /* cheking for secondary FitImage Address 22480000  */
+    if (value.find(secondaryFitImageStartAddr) != std::string::npos)
     {
-        controls |= controls_usb_attached;
+        bootImage = secondaryImage;
     }
     else
     {
-        controls &= ~controls_usb_attached;
+        bootImage = primaryImage;
     }
 
-    switch (ctrl_req->control)
-    {
-        case fw_update_control_request::CTRL_GET:
-            break;
-        case fw_update_control_request::CTRL_XFER_START:
-        {
-            controls |= controls_transfer_started;
-            // reset buffer to empty (truncate file)
-            std::ofstream out(FIRMWARE_BUFFER_FILE,
-                              std::ofstream::binary | std::ofstream::trunc);
-            fw_xfer_uri = std::string("file://") + FIRMWARE_BUFFER_FILE;
-            if (xfer_hash_check)
-            {
-                xfer_hash_check->clear();
-            }
-#ifdef INTEL_PFR_ENABLED
-            imgLength = 0;
-            imgType = 0;
-            block0Mapped = false;
-#endif
-            if (DEBUG)
-                std::cerr << "transfer start\n";
-        }
-        break;
-        case fw_update_control_request::CTRL_XFER_COMPLETE:
-        {
-            if (usb_get_status())
-            {
-                rc = IPMI_CC_REQ_INVALID_PHASE;
-            }
-            // finish transfer based on URI
-            if (!transfer_firmware_from_uri(fw_xfer_uri))
-            {
-                rc = IPMI_CC_UNSPECIFIED_ERROR;
-                break;
-            }
-            // transfer complete
-            if (xfer_hash_check)
-            {
-                if (transfer_hash_check::CHECK_PASSED_SHA2 !=
-                    xfer_hash_check->check())
-                {
-                    if (DEBUG)
-                        std::cerr << "xfer_hash_check returns not "
-                                     "CHECK_PASSED_SHA2\n";
-                    rc = IPMI_CC_UNSPECIFIED_ERROR;
-                    break;
-                }
-            }
-            // start the request
-            if (!request_start_firmware_update(FIRMWARE_BUFFER_FILE))
-            {
-                if (DEBUG)
-                    std::cerr
-                        << "request_start_firmware_update returns failure\n";
-                rc = IPMI_CC_UNSPECIFIED_ERROR;
-            }
-            if (rc == IPMI_CC_OK)
-            {
-                controls |= controls_transfer_completed;
-            }
-        }
-        break;
-        case fw_update_control_request::CTRL_XFER_ABORT:
-            if (DEBUG)
-                std::cerr << "send abort request\n";
-            if (usb_get_status())
-            {
-                if (0 != usb_detach_device())
-                {
-                    rc = IPMI_CC_USB_ATTACH_FAIL;
-                }
-            }
-            fw_update_status.firmwareUpdateAbortState();
-            controls |= controls_transfer_aborted;
-            break;
-        case fw_update_control_request::CTRL_SET_FILENAME:
-            fw_xfer_uri.clear();
-            fw_xfer_uri.insert(0, ctrl_req->filename, ctrl_req->nlen);
-            break;
-        case fw_update_control_request::CTRL_USB_ATTACH:
-            if (usb_get_status())
-            {
-                rc = IPMI_CC_INVALID_FIELD_REQUEST;
-            }
-            else if (0 != usb_attach_device())
-            {
-                rc = IPMI_CC_USB_ATTACH_FAIL;
-            }
-            else
-            {
-                rc = IPMI_CC_OK;
-            }
-            break;
-        case fw_update_control_request::CTRL_USB_DETACH:
-            if (!usb_get_status())
-            {
-                rc = IPMI_CC_INVALID_FIELD_REQUEST;
-            }
-            if (0 != usb_detach_device())
-            {
-                rc = IPMI_CC_USB_ATTACH_FAIL;
-            }
-            else
-            {
-                rc = IPMI_CC_OK;
-            }
-            break;
-        default:
-            if (DEBUG)
-                std::cerr << "control byte " << std::hex << ctrl_req->control
-                          << " unknown\n";
-            rc = IPMI_CC_INVALID_FIELD_REQUEST;
-            break;
-    }
-
-    if (rc == IPMI_CC_OK)
-    {
-        *ctrl_resp = controls;
-        *data_len = sizeof(*ctrl_resp);
-    }
-
-    return rc;
+    return bootImage;
 }
 
 #ifdef INTEL_PFR_ENABLED
@@ -1142,434 +844,16 @@
 
     return ipmi::responseSuccess(fwVerInfoList.size(), fwVerInfoList);
 }
-#endif
-
-struct fw_security_revision_info
+using fwSecurityVersionInfoType = std::tuple<uint8_t,  // ID Tag
+                                             uint8_t,  // BKC Version
+                                             uint8_t>; // SVN Version
+ipmi::RspType<uint8_t, std::vector<fwSecurityVersionInfoType>>
+    ipmiGetFwSecurityVersionInfo()
 {
-    uint8_t id_tag;
-    uint16_t sec_rev;
-} __attribute__((packed));
-
-static ipmi_ret_t ipmi_firmware_get_fw_security_revision(
-    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)
-{
-    if (DEBUG)
-        std::cerr << "Get FW security revision info\n";
-
-    // Byte 1 - Count (N) Number of devices data is being returned for.
-    // Byte 2 - ID Tag 00 – reserved 01 – BMC Active Image 02 – BBU Active Image
-    //                 03 – BMC Backup Image 04 – BBU Backup Image 05 – BBR
-    //                 Image
-    // Byte 3 - Major Version Number
-    // Byte 4 - Minor Version Number
-    // Bytes 5:8 - Build Number
-    // Bytes 9:12 - Build Timestamp Format: LSB first, same format as SEL
-    // timestamp
-    // Bytes 13:16 - Update Timestamp
-    // Bytes - 17:(15xN) - Repeat of 2 through 16
-
-    uint8_t count = 0;
-    auto ret_count = reinterpret_cast<uint8_t *>(response);
-    auto info =
-        reinterpret_cast<struct fw_security_revision_info *>(ret_count + 1);
-
-    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    for (uint8_t id_tag = 1; id_tag < 6; id_tag++)
-    {
-        const char *fw_path;
-        switch (id_tag)
-        {
-            case 1:
-                fw_path = FW_UPDATE_ACTIVE_INFO_PATH;
-                break;
-            case 2:
-                fw_path = FW_UPDATE_BACKUP_INFO_PATH;
-                break;
-            case 3:
-            case 4:
-            case 5:
-                continue; // skip for now
-                break;
-        }
-        auto method =
-            bus->new_method_call(FW_UPDATE_SERVER_DBUS_NAME, fw_path,
-                                 "org.freedesktop.DBus.Properties", "GetAll");
-        method.append(FW_UPDATE_INFO_INTERFACE, "security_version");
-        ipmi::DbusVariant sec_rev;
-        try
-        {
-            auto reply = bus->call(method);
-
-            if (reply.is_method_error())
-                continue;
-
-            reply.read(sec_rev);
-        }
-        catch (sdbusplus::exception::SdBusError &e)
-        {
-            std::cerr << "SDBus Error: " << e.what();
-            return IPMI_CC_UNSPECIFIED_ERROR;
-        }
-
-        info->id_tag = id_tag;
-        info->sec_rev = std::get<int>(sec_rev);
-        count++;
-        info++;
-    }
-    *ret_count = count;
-
-    // Status code.
-    ipmi_ret_t rc = IPMI_CC_OK;
-    *data_len = sizeof(count) + count * sizeof(*info);
-
-    return rc;
+    // TODO: Need to add support.
+    return ipmi::responseInvalidCommand();
 }
 
-struct fw_channel_size
-{
-    uint8_t channel_id;
-    uint32_t channel_size;
-} __attribute__((packed));
-
-enum
-{
-    CHANNEL_RESVD = 0,
-    CHANNEL_KCS,
-    CHANNEL_RMCP_PLUS,
-    CHANNEL_USB_DATA,
-    CHANNEL_USB_MASS_STORAGE,
-} channel_transfer_type;
-
-static constexpr uint8_t channelListSize = 2;
-/** @brief implements Maximum Firmware Transfer size command
- *  @parameter
- *   -  none
- *  @returns IPMI completion code plus response data
- *   - count - channel count
- *   - channelList - channel list information
- */
-ipmi::RspType<uint8_t, // channel count
-              std::array<std::tuple<uint8_t, uint32_t>,
-                         channelListSize> // channel
-                                          // list
-              >
-    ipmiFirmwareMaxTransferSize()
-{
-    constexpr uint8_t KCSMaxBufSize = 128;
-    constexpr uint32_t RMCPPLUSMaxBufSize = 50 * 1024;
-    if (DEBUG)
-        std::cerr << "Get FW max transfer size\n";
-    // Byte 1 - Count (N) Number of devices data is being returned for.
-    // Byte 2 - ID Tag 00 – reserved 01 – kcs 02 – rmcp+,
-    //                 03 – usb data, 04 – usb mass storage
-    // Byte 3-6 - transfer size (little endian)
-    // Bytes - 7:(5xN) - Repeat of 2 through 6
-    constexpr std::array<std::tuple<uint8_t, uint32_t>, channelListSize>
-        channelList = {{{CHANNEL_KCS, KCSMaxBufSize},
-                        {CHANNEL_RMCP_PLUS, RMCPPLUSMaxBufSize}}};
-    return ipmi::responseSuccess(channelListSize, channelList);
-}
-
-enum
-{
-    EXEC_CTX_RESVD = 0,
-    EXEC_CTX_FULL_LINUX = 0x10,
-    EXEC_CTX_SAFE_MODE_LINUX = 0x11,
-} bmc_execution_context;
-
-struct fw_execution_context
-{
-    uint8_t context;
-    uint8_t image_selection;
-} __attribute__((packed));
-
-static ipmi_ret_t ipmi_firmware_get_fw_execution_context(
-    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)
-{
-    if (DEBUG)
-        std::cerr << "Get FW execution context\n";
-
-    // Byte 1 - execution context
-    //          0x10 - full linux stack, 0x11 - safe-mode linux stack
-    // Byte 2 - current image selection
-    //          1 - primary, 2 - secondary
-
-    auto info = reinterpret_cast<struct fw_execution_context *>(response);
-    info->context = EXEC_CTX_FULL_LINUX;
-
-    info->image_selection = getActiveBootImage();
-
-    // Status code.
-    ipmi_ret_t rc = IPMI_CC_OK;
-    *data_len = sizeof(*info);
-
-    return rc;
-}
-
-uint8_t getActiveBootImage(void)
-{
-    // 0x01 -  primaryImage
-    constexpr uint8_t primaryImage = 0x01;
-    // 0x02 -  secondaryImage
-    constexpr uint8_t secondaryImage = 0x02;
-    uint8_t bootImage = primaryImage;
-
-    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    auto method = bus->new_method_call(
-        "xyz.openbmc_project.U_Boot.Environment.Manager",
-        "/xyz/openbmc_project/u_boot/environment/mgr",
-        "xyz.openbmc_project.U_Boot.Environment.Manager", "Read");
-    method.append("bootcmd");
-    std::string value;
-    try
-    {
-        auto reply = bus->call(method);
-        reply.read(value);
-    }
-    catch (sdbusplus::exception::SdBusError &e)
-    {
-        std::cerr << "SDBus Error: " << e.what();
-        return IPMI_CC_UNSPECIFIED_ERROR;
-    }
-    /* cheking for secondary FitImage Address 22480000  */
-    if (value.find(secondaryFitImageStartAddr) != std::string::npos)
-    {
-        bootImage = secondaryImage;
-    }
-    else
-    {
-        bootImage = primaryImage;
-    }
-
-    return bootImage;
-}
-/** @brief implements firmware get status command
- *  @parameter
- *   -  none
- *  @returns IPMI completion code plus response data
- *   - status     -  processing status
- *   - percentage -  percentage completion
- *   - check      -  channel integrity check status
- **/
-ipmi::RspType<uint8_t, // status
-              uint8_t, // percentage
-              uint8_t  // check
-              >
-    ipmiFrmwareGetStatus()
-
-{
-    if (DEBUG)
-        std::cerr << "Get FW update status\n";
-    // Byte 1 - status (0=init, 1=idle, 2=download, 3=validate, 4=write,
-    //                  5=ready, f=error, 83=ac cycle required)
-    // Byte 2 - percent
-    // Byte 3 - integrity check status (0=none, 1=req, 2=sha2ok, e2=sha2fail)
-    uint8_t status = fw_update_status.state();
-    uint8_t percent = fw_update_status.percent();
-    uint8_t check = xfer_hash_check ? xfer_hash_check->status() : 0;
-
-    // Status code.
-    return ipmi::responseSuccess(status, percent, check);
-}
-
-static constexpr uint8_t FW_UPDATE_OPTIONS_NO_DOWNREV = (1 << 0);
-static constexpr uint8_t FW_UPDATE_OPTIONS_DEFER_RESTART = (1 << 1);
-static constexpr uint8_t FW_UPDATE_OPTIONS_SHA2_CHECK = (1 << 2);
-static constexpr uint8_t FW_UPDATE_OPTIONS_RESVD1 = (1 << 3);
-struct fw_update_options_request
-{
-    uint8_t mask;
-    uint8_t options;
-} __attribute__((packed));
-
-uint32_t fw_update_options = 0;
-static ipmi_ret_t ipmi_firmware_update_options(
-    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)
-{
-    if (DEBUG)
-        std::cerr << "Get/set FW update options\n";
-
-    // request:
-    // Byte 1 - mask
-    // Byte 2 - options
-    // Byte 3-34 - optional integrity check expected value
-    // response:
-    // Byte 1 - set options
-
-    auto fw_options =
-        reinterpret_cast<struct fw_update_options_request *>(request);
-
-    const char *path = FW_UPDATE_SERVER_INFO_PATH;
-    const char *iface = FW_UPDATE_SECURITY_INTERFACE;
-    if ((fw_options->mask & FW_UPDATE_OPTIONS_NO_DOWNREV) &&
-        (fw_options->options & FW_UPDATE_OPTIONS_NO_DOWNREV) !=
-            (fw_update_options & FW_UPDATE_OPTIONS_NO_DOWNREV))
-    {
-        if (fw_options->options & FW_UPDATE_OPTIONS_NO_DOWNREV)
-        {
-            fw_update_options |= FW_UPDATE_OPTIONS_NO_DOWNREV;
-            /*setting flag to flase for deferring downgrade support*/
-            fw_update_status.setInhibitDowngrade(true);
-        }
-        else
-        {
-            fw_update_options &= ~FW_UPDATE_OPTIONS_NO_DOWNREV;
-            /*setting flag to true for downgrade support*/
-            fw_update_status.setInhibitDowngrade(false);
-        }
-    }
-    if ((fw_options->mask & FW_UPDATE_OPTIONS_DEFER_RESTART) &&
-        (fw_options->options & FW_UPDATE_OPTIONS_DEFER_RESTART) !=
-            (fw_update_options & FW_UPDATE_OPTIONS_DEFER_RESTART))
-    {
-        if (fw_options->options & FW_UPDATE_OPTIONS_DEFER_RESTART)
-        {
-            fw_update_options |= FW_UPDATE_OPTIONS_DEFER_RESTART;
-            /* setting flag to true to stop image activation */
-            fw_update_status.setDeferRestart(true);
-        }
-        else
-        {
-            /* setting flag to false for image activation */
-            fw_update_options &= ~FW_UPDATE_OPTIONS_DEFER_RESTART;
-            fw_update_status.setDeferRestart(false);
-        }
-    }
-    if (fw_options->mask & FW_UPDATE_OPTIONS_SHA2_CHECK)
-    {
-        auto hash_size = EVP_MD_size(EVP_sha256());
-        if (fw_options->options & FW_UPDATE_OPTIONS_SHA2_CHECK)
-        {
-            if (*data_len != (sizeof(*fw_options) + hash_size))
-            {
-                *data_len = 0;
-                return IPMI_CC_REQ_DATA_LEN_INVALID;
-            }
-            xfer_hash_check = std::make_shared<transfer_hash_check>();
-            auto exp_hash = reinterpret_cast<uint8_t *>(fw_options + 1);
-            xfer_hash_check->init({exp_hash, exp_hash + hash_size});
-            fw_update_options |= FW_UPDATE_OPTIONS_SHA2_CHECK;
-        }
-        else
-        {
-            fw_update_options &= ~FW_UPDATE_OPTIONS_SHA2_CHECK;
-            // delete the xfer_hash_check object
-            xfer_hash_check.reset();
-        }
-    }
-    auto options_rsp = reinterpret_cast<uint8_t *>(response);
-    *options_rsp = fw_update_options;
-
-    if (DEBUG)
-        std::cerr << "current fw_update_options = " << std::hex
-                  << fw_update_options << '\n';
-    // Status code.
-    *data_len = sizeof(*options_rsp);
-    return IPMI_CC_OK;
-}
-
-struct fw_cert_info
-{
-    uint16_t cert_len;
-    uint64_t serial;
-    uint8_t subject_len;
-    char subject[255];
-} __attribute__((packed));
-
-static ipmi_ret_t ipmi_firmware_get_root_cert_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)
-{
-    if (DEBUG)
-        std::cerr << "Get FW root cert info\n";
-
-    // request:
-    // Byte 1 - certificate ID: request which certificate (ignored)
-
-    // response:
-    // Byte 1-2  - certificate length (little endian)
-    // Byte 3-10 - serial number (little endian)
-    // Byte 11   - subject length
-    // Byte 12-N - subject data
-
-    auto cert_info = reinterpret_cast<struct fw_cert_info *>(response);
-    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
-    auto method = bus->new_method_call(
-        FW_UPDATE_SERVER_DBUS_NAME, FW_UPDATE_SERVER_INFO_PATH,
-        "org.freedesktop.DBus.Properties", "GetAll");
-    method.append(FW_UPDATE_SECURITY_INTERFACE);
-    std::string subject;
-    uint64_t serial;
-    std::string cert;
-    try
-    {
-        auto reply = bus->call(method);
-
-        std::vector<std::pair<std::string, ipmi::DbusVariant>> properties;
-        reply.read(properties);
-
-        for (const auto &t : properties)
-        {
-            auto key = t.first;
-            auto value = t.second;
-            if (key == "certificate_subject")
-            {
-                subject = std::get<std::string>(value);
-            }
-            else if (key == "cetificate_serial")
-            {
-                serial = std::get<uint64_t>(value);
-            }
-            else if (key == "certificate")
-            {
-                cert = std::get<std::string>(value);
-            }
-        }
-    }
-    catch (sdbusplus::exception::SdBusError &e)
-    {
-        std::cerr << "SDBus Error: " << e.what();
-        return IPMI_CC_UNSPECIFIED_ERROR;
-    }
-
-    cert_info->cert_len = cert.size();
-    cert_info->serial = serial;
-    // truncate subject so it fits in the 255-byte array (if necessary)
-    if (subject.size() > sizeof(cert_info->subject))
-        subject.resize(sizeof(cert_info->subject));
-    cert_info->subject_len = subject.size();
-    std::copy(subject.begin(), subject.end(), cert_info->subject);
-
-    // Status code.
-    ipmi_ret_t rc = IPMI_CC_OK;
-    // make sure to account for the *actual* size of the subject
-    *data_len = sizeof(*cert_info) - sizeof(cert_info->subject) +
-                cert_info->subject_len;
-
-    return rc;
-}
-
-#ifdef INTEL_PFR_ENABLED
-enum class FwGetRootCertDataTag : uint8_t
-{
-    activeRootKey = 1,
-    recoveryRootKey,
-    activeCSK,
-    recoveryCSK,
-};
-
-static constexpr char *bmcActivePfmMTDDev = "/dev/mtd/pfm";
-static constexpr char *bmcRecoveryImgMTDDev = "/dev/mtd/rc-image";
-static constexpr size_t pfmBaseOffsetInImage = 0x400;
-static constexpr size_t rootkeyOffsetInPfm = 0xA0;
-static constexpr size_t cskKeyOffsetInPfm = 0x124;
-static constexpr size_t cskSignatureOffsetInPfm = 0x19c;
-static constexpr size_t certKeyLen = 96;
-static constexpr size_t cskSignatureLen = 96;
-
 ipmi::RspType<std::array<uint8_t, certKeyLen>,
               std::optional<std::array<uint8_t, cskSignatureLen>>>
     ipmiGetFwRootCertData(uint8_t certId)
@@ -1637,7 +921,440 @@
 
     return ipmi::responseSuccess(certKey, std::nullopt);
 }
+#endif // INTEL_PFR_ENABLED
+
+static constexpr uint8_t channelListSize = 3;
+/** @brief implements Maximum Firmware Transfer size command
+ *  @parameter
+ *   -  none
+ *  @returns IPMI completion code plus response data
+ *   - count - channel count
+ *   - channelList - channel list information
+ */
+ipmi::RspType<uint8_t, // channel count
+              std::array<std::tuple<uint8_t, uint32_t>,
+                         channelListSize> // Channel List
+              >
+    ipmiFirmwareMaxTransferSize()
+{
+    constexpr size_t kcsMaxBufSize = 128;
+    constexpr size_t rmcpPlusMaxBufSize = 50 * 1024;
+    constexpr size_t ipmbMaxBufSize = 4 * 1024;
+    // Byte 1 - Count (N) Number of devices data is being returned for.
+    // Byte 2 - ID Tag 00 – reserved 01 – kcs 02 – rmcp+, 03 - ipmb
+    // Byte 3-6 - transfer size (little endian)
+    // Bytes - 7:(5xN) - Repeat of 2 through 6
+    constexpr std::array<std::tuple<uint8_t, uint32_t>, channelListSize>
+        channelList = {
+            {{static_cast<uint8_t>(ChannelIdTag::kcs), kcsMaxBufSize},
+             {static_cast<uint8_t>(ChannelIdTag::ipmb), ipmbMaxBufSize},
+             {static_cast<uint8_t>(ChannelIdTag::rmcpPlus),
+              rmcpPlusMaxBufSize}}};
+
+    return ipmi::responseSuccess(channelListSize, channelList);
+}
+
+ipmi::RspType<uint8_t, uint8_t>
+    ipmiGetBmcExecutionContext(ipmi::Context::ptr ctx)
+{
+    // Byte 1 - Current execution context
+    //          0x10 - Linux OS, 0x11 - Bootloader, Forced-firmware updat mode
+    // Byte 2 - Partition pointer
+    //          0x01 - primary, 0x02 - secondary
+    uint8_t partitionPtr = getActiveBootImage(ctx);
+
+    return ipmi::responseSuccess(
+        static_cast<uint8_t>(BmcExecutionContext::linuxOs), partitionPtr);
+}
+
+/** @brief Get Firmware Update Random Number
+ *
+ *  This function generate the random number used for
+ *  setting the firmware update mode as authentication key.
+ *
+ *  @parameter : None
+ *  @returns IPMI completion code along with
+ *   - random number
+ **/
+ipmi::RspType<std::array<uint8_t, fwRandomNumLength>>
+    ipmiGetFwUpdateRandomNumber()
+{
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Generate FW update random number");
+    std::random_device rd;
+    std::default_random_engine gen(rd());
+    std::uniform_int_distribution<> dist{0, 255};
+
+    fwRandomNumGenTs = std::chrono::steady_clock::now();
+
+    for (int i = 0; i < fwRandomNumLength; i++)
+    {
+        fwRandomNum[i] = dist(gen);
+    }
+
+    return ipmi::responseSuccess(fwRandomNum);
+}
+
+/** @brief Set Firmware Update Mode
+ *
+ *  This function sets BMC into firmware update mode
+ *  after validating Random number obtained from the Get
+ *  Firmware Update Random Number command
+ *
+ *  @parameter
+ *   -  randNum - Random number(token)
+ *  @returns IPMI completion code
+ **/
+ipmi::RspType<>
+    ipmiSetFirmwareUpdateMode(std::array<uint8_t, fwRandomNumLength> &randNum)
+{
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Start FW update mode");
+    /* Firmware Update Random number is valid for 30 seconds only */
+    auto timeElapsed = (std::chrono::steady_clock::now() - fwRandomNumGenTs);
+    if (std::chrono::duration_cast<std::chrono::microseconds>(timeElapsed)
+            .count() > std::chrono::duration_cast<std::chrono::microseconds>(
+                           fwRandomNumExpirySeconds)
+                           .count())
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "Firmware update random number expired.");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    /* Validate random number */
+    for (int i = 0; i < fwRandomNumLength; i++)
+    {
+        if (fwRandomNum[i] != randNum[i])
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "Invalid random number specified.");
+            return ipmi::responseInvalidFieldRequest();
+        }
+    }
+
+    try
+    {
+        if (getFirmwareUpdateMode())
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "Already firmware update is in progress.");
+            return ipmi::responseBusy();
+        }
+    }
+    catch (const std::exception &e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    // FIXME? c++ doesn't off an option for exclusive file creation
+    FILE *fp = fopen(firmwareBufferFile, "wx");
+    if (!fp)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "Unable to open file.");
+        return ipmi::responseUnspecifiedError();
+    }
+    fclose(fp);
+
+    try
+    {
+        setFirmwareUpdateMode(true);
+    }
+    catch (const std::exception &e)
+    {
+        unlink(firmwareBufferFile);
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess();
+}
+
+/** @brief implements exit firmware update mode command
+ *  @param None
+ *
+ *  @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiExitFirmwareUpdateMode()
+{
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Exit FW update mode");
+    switch (fwUpdateStatus.getState())
+    {
+        case FwUpdateStatusCache::fwStateInit:
+        case FwUpdateStatusCache::fwStateIdle:
+            return ipmi::responseInvalidFieldRequest();
+            break;
+        case FwUpdateStatusCache::fwStateDownload:
+        case FwUpdateStatusCache::fwStateVerify:
+            break;
+        case FwUpdateStatusCache::fwStateProgram:
+            break;
+        case FwUpdateStatusCache::fwStateUpdateSuccess:
+        case FwUpdateStatusCache::fwStateError:
+            break;
+        case FwUpdateStatusCache::fwStateAcCycleRequired:
+            return ipmi::responseInvalidFieldRequest();
+            break;
+    }
+    fwUpdateStatus.firmwareUpdateAbortState();
+
+    try
+    {
+        setFirmwareUpdateMode(false);
+    }
+    catch (const std::exception &e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess();
+}
+
+/** @brief implements Get/Set Firmware Update Control
+ *  @parameter
+ *   - Byte 1: Control Byte
+ *   - Byte 2: Firmware filename length (Optional)
+ *   - Byte 3:N: Firmware filename data (Optional)
+ *  @returns IPMI completion code plus response data
+ *   - Byte 2: Current control status
+ **/
+ipmi::RspType<bool, bool, bool, bool, uint4_t>
+    ipmiGetSetFirmwareUpdateControl(const uint8_t controlReq,
+                                    const std::optional<std::string> &fileName)
+{
+    static std::string fwXferUriPath;
+    static bool imageTransferStarted = false;
+    static bool imageTransferCompleted = false;
+    static bool imageTransferAborted = false;
+
+    if ((controlReq !=
+         static_cast<uint8_t>(FwUpdateCtrlReq::setFirmwareFilename)) &&
+        (fileName))
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Invalid request field (Filename).");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    static bool usbAttached = getUsbStatus();
+
+    switch (static_cast<FwUpdateCtrlReq>(controlReq))
+    {
+        case FwUpdateCtrlReq::getCurrentControlStatus:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Get status");
+            break;
+        case FwUpdateCtrlReq::imageTransferStart:
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Set transfer start");
+            imageTransferStarted = true;
+            // reset buffer to empty (truncate file)
+            std::ofstream out(firmwareBufferFile,
+                              std::ofstream::binary | std::ofstream::trunc);
+            fwXferUriPath = std::string("file://") + firmwareBufferFile;
+            if (xferHashCheck)
+            {
+                xferHashCheck->clear();
+            }
+            // Setting state to download
+            fwUpdateStatus.setState(
+                static_cast<uint8_t>(FwUpdateStatusCache::fwStateDownload));
+#ifdef INTEL_PFR_ENABLED
+            imgLength = 0;
+            imgType = 0;
+            block0Mapped = false;
 #endif
+        }
+        break;
+        case FwUpdateCtrlReq::imageTransferComplete:
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Set transfer complete.");
+            if (usbAttached)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "USB should be detached to perform this operation.");
+                return ipmi::responseNotSupportedInPresentState();
+            }
+            // finish transfer based on URI
+            if (!transferFirmwareFromUri(fwXferUriPath))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "transferFirmwareFromUri failed.");
+                return ipmi::responseUnspecifiedError();
+            }
+            // transfer complete
+            if (xferHashCheck)
+            {
+                if (TransferHashCheck::HashCheck::sha2Success !=
+                    xferHashCheck->verify())
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "xferHashCheck failed.");
+                    return ipmi::responseUnspecifiedError();
+                }
+            }
+            // Set state to verify and start the update
+            fwUpdateStatus.setState(
+                static_cast<uint8_t>(FwUpdateStatusCache::fwStateVerify));
+            // start the request
+            if (!startFirmwareUpdate(firmwareBufferFile))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "startFirmwareUpdate failed.");
+                return ipmi::responseUnspecifiedError();
+            }
+            imageTransferCompleted = true;
+        }
+        break;
+        case FwUpdateCtrlReq::imageTransferAbort:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Set transfer abort.");
+            if (usbAttached)
+            {
+                if (detachUsbDevice())
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "Detach USB device failed.");
+                    return ipmi::responseUsbAttachOrDetachFailed();
+                }
+                usbAttached = false;
+            }
+            // During abort request reset the state to Init by cleaning update
+            // file.
+            fwUpdateStatus.firmwareUpdateAbortState();
+            imageTransferAborted = true;
+            break;
+        case FwUpdateCtrlReq::setFirmwareFilename:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Set filename.");
+            if (!fileName || ((*fileName).length() == 0))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Invalid Filename specified.");
+                return ipmi::responseInvalidFieldRequest();
+            }
+
+            fwXferUriPath = *fileName;
+            break;
+        case FwUpdateCtrlReq::attachUsbDevice:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Attach USB device.");
+            if (usbAttached)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "USB device is already attached.");
+                return ipmi::responseInvalidFieldRequest();
+            }
+            if (attachUsbDevice())
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Attach USB device failed.");
+                return ipmi::responseUsbAttachOrDetachFailed();
+            }
+            usbAttached = true;
+            break;
+        case FwUpdateCtrlReq::detachUsbDevice:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "ipmiGetSetFirmwareUpdateControl: Detach USB device.");
+            if (!usbAttached)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "USB device is not attached.");
+                return ipmi::responseInvalidFieldRequest();
+            }
+            if (detachUsbDevice())
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Detach USB device failed.");
+                return ipmi::responseUsbAttachOrDetachFailed();
+            }
+            usbAttached = false;
+            break;
+        default:
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Invalid control option specified.");
+            return ipmi::responseInvalidFieldRequest();
+    }
+
+    return ipmi::responseSuccess(imageTransferStarted, imageTransferCompleted,
+                                 imageTransferAborted, usbAttached, uint4_t(0));
+}
+
+/** @brief implements firmware get status command
+ *  @parameter
+ *   -  none
+ *  @returns IPMI completion code plus response data
+ *   - status     -  processing status
+ *   - percentage -  percentage completion
+ *   - check      -  channel integrity check status
+ **/
+ipmi::RspType<uint8_t, // status
+              uint8_t, // percentage
+              uint8_t  // check
+              >
+    ipmiGetFirmwareUpdateStatus()
+
+{
+    // Byte 1 - status (0=init, 1=idle, 2=download, 3=validate, 4=write,
+    //                  5=ready, f=error, 83=ac cycle required)
+    // Byte 2 - percent
+    // Byte 3 - integrity check status (0=none, 1=req, 2=sha2ok, e2=sha2fail)
+    uint8_t status = fwUpdateStatus.getState();
+    uint8_t percent = fwUpdateStatus.percent();
+    uint8_t check = xferHashCheck ? xferHashCheck->status() : 0;
+
+    // Status code.
+    return ipmi::responseSuccess(status, percent, check);
+}
+
+ipmi::RspType<bool, bool, bool, uint5_t> ipmiSetFirmwareUpdateOptions(
+    bool noDowngradeMask, bool deferRestartMask, bool sha2CheckMask,
+    uint5_t reserved1, bool noDowngrade, bool deferRestart, bool sha2Check,
+    uint5_t reserved2, std::optional<std::vector<uint8_t>> integrityCheckVal)
+{
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Set firmware update options.");
+    bool noDowngradeState = fwUpdateStatus.getInhibitDowngrade();
+    bool deferRestartState = fwUpdateStatus.getDeferRestart();
+    bool sha2CheckState = xferHashCheck ? true : false;
+
+    if (noDowngradeMask && (noDowngradeState != noDowngrade))
+    {
+        fwUpdateStatus.setInhibitDowngrade(noDowngrade);
+        noDowngradeState = noDowngrade;
+    }
+    if (deferRestartMask && (deferRestartState != deferRestart))
+    {
+        fwUpdateStatus.setDeferRestart(deferRestart);
+        deferRestartState = deferRestart;
+    }
+    if (sha2CheckMask)
+    {
+        if (sha2Check)
+        {
+            auto hashSize = EVP_MD_size(EVP_sha256());
+            if ((*integrityCheckVal).size() != hashSize)
+            {
+                phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                    "Invalid size of Hash specified.");
+                return ipmi::responseInvalidFieldRequest();
+            }
+            xferHashCheck = std::make_shared<TransferHashCheck>();
+            xferHashCheck->init(*integrityCheckVal);
+        }
+        else
+        {
+            // delete the xferHashCheck object
+            xferHashCheck.reset();
+        }
+        sha2CheckState = sha2CheckMask;
+    }
+    return ipmi::responseSuccess(noDowngradeState, deferRestartState,
+                                 sha2CheckState, reserved1);
+}
 
 ipmi::RspType<uint32_t>
     ipmiFwImageWriteData(const std::vector<uint8_t> &writeData)
@@ -1650,14 +1367,14 @@
         return ipmi::responseReqDataLenInvalid();
     }
 
-    if (fw_update_status.state() != fw_update_status_cache::FW_STATE_DOWNLOAD)
+    if (fwUpdateStatus.getState() != FwUpdateStatusCache::fwStateDownload)
     {
-        phosphor::logging::log<phosphor::logging::level::DEBUG>(
+        phosphor::logging::log<phosphor::logging::level::ERR>(
             "Invalid firmware update state.");
         return ipmi::response(ccCmdNotSupportedInPresentState);
     }
 
-    std::ofstream out(FIRMWARE_BUFFER_FILE,
+    std::ofstream out(firmwareBufferFile,
                       std::ofstream::binary | std::ofstream::app);
     if (!out)
     {
@@ -1668,7 +1385,7 @@
 
     uint64_t fileDataLen = out.tellp();
 
-    if ((fileDataLen + writeDataLen) > FIRMWARE_BUFFER_MAX_SIZE)
+    if ((fileDataLen + writeDataLen) > maxFirmwareImageSize)
     {
         phosphor::logging::log<phosphor::logging::level::DEBUG>(
             "Firmware image size exceeds the limit");
@@ -1679,9 +1396,9 @@
     out.write(data, writeDataLen);
     out.close();
 
-    if (xfer_hash_check)
+    if (xferHashCheck)
     {
-        xfer_hash_check->hash(writeData);
+        xferHashCheck->hash(writeData);
     }
 
 #ifdef INTEL_PFR_ENABLED
@@ -1704,7 +1421,7 @@
     {
         struct PFRImageBlock0 block0Data = {0};
 
-        std::ifstream inFile(FIRMWARE_BUFFER_FILE,
+        std::ifstream inFile(firmwareBufferFile,
                              std::ios::binary | std::ios::in);
         inFile.read(reinterpret_cast<char *>(&block0Data), sizeof(block0Data));
         inFile.close();
@@ -1728,129 +1445,81 @@
     return ipmi::responseSuccess(writeDataLen);
 }
 
-struct intc_app_get_buffer_size_resp
-{
-    uint8_t kcs_size;
-    uint8_t ipmb_size;
-} __attribute__((packed));
-
-static constexpr int KCS_MAX_BUFFER_SIZE = 63;
-static constexpr int IPMB_MAX_BUFFER_SIZE = 128;
-static ipmi_ret_t ipmi_intel_app_get_buffer_size(
-    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 msg_reply =
-        reinterpret_cast<intc_app_get_buffer_size_resp *>(response);
-    // for now this is hard coded; really this number is dependent on
-    // the BMC kcs driver as well as the host kcs driver....
-    // we can't know the latter.
-    msg_reply->kcs_size = KCS_MAX_BUFFER_SIZE / 4;
-    msg_reply->ipmb_size = IPMB_MAX_BUFFER_SIZE / 4;
-    *data_len = sizeof(*msg_reply);
-
-    return IPMI_CC_OK;
-}
-
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_VERSION_INFO = 0x20;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_SEC_VERSION_INFO = 0x21;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_UPD_CHAN_INFO = 0x22;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_BMC_EXEC_CTX = 0x23;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_ROOT_CERT_INFO = 0x24;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_FW_UPDATE_RAND_NUM = 0x26;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_SET_FW_UPDATE_MODE = 0x27;
-static constexpr ipmi_cmd_t cmdFirmwareExitFirmwareUpdateMode = 0x28;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_UPDATE_CONTROL = 0x29;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_STATUS = 0x2a;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_SET_FW_UPDATE_OPTIONS = 0x2b;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_TIMESTAMP = 0x2d;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_UPDATE_ERR_MSG = 0xe0;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_REMOTE_FW_INFO = 0xf0;
-
-static constexpr ipmi_netfn_t NETFUN_INTC_APP = 0x30;
-static constexpr ipmi_cmd_t IPMI_CMD_INTC_GET_BUFFER_SIZE = 0x66;
-
-static void register_netfn_firmware_functions()
+static void registerFirmwareFunctions()
 {
     // guarantee that we start with an already timed out timestamp
-    fw_random_number_timestamp =
-        std::chrono::steady_clock::now() - FW_RANDOM_NUMBER_TTL;
+    fwRandomNumGenTs =
+        std::chrono::steady_clock::now() - fwRandomNumExpirySeconds;
+    fwUpdateStatus.setState(
+        static_cast<uint8_t>(FwUpdateStatusCache::fwStateInit));
 
-    unlink(FIRMWARE_BUFFER_FILE);
-
-    // <Get BT Interface Capabilities>
-    if (DEBUG)
-        std::cerr << "Registering firmware update commands\n";
+    unlink(firmwareBufferFile);
 
 #ifdef INTEL_PFR_ENABLED
     // Following commands are supported only for PFR enabled platforms
     // CMD:0x20 - Get Firmware Version Information
+    // CMD:0x21 - Get Firmware Security Version Information
+    // CMD:0x25 - Get Root Certificate Data
 
     // get firmware version information
     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
                           ipmi::firmware::cmdGetFwVersionInfo,
                           ipmi::Privilege::Admin, ipmiGetFwVersionInfo);
-#endif
+
     // get firmware security version information
-    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_FW_SEC_VERSION_INFO,
-                           NULL, ipmi_firmware_get_fw_security_revision,
-                           PRIVILEGE_ADMIN);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdGetFwSecurityVersionInfo,
+                          ipmi::Privilege::Admin, ipmiGetFwSecurityVersionInfo);
 
-    // get channel information (max transfer sizes)
-    ipmi::registerHandler(ipmi::prioOemBase, NETFUN_FIRMWARE,
-                          IPMI_CMD_FW_GET_FW_UPD_CHAN_INFO,
-                          ipmi::Privilege::Admin, ipmiFirmwareMaxTransferSize);
-
-    // get bmc execution context
-    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_BMC_EXEC_CTX, NULL,
-                           ipmi_firmware_get_fw_execution_context,
-                           PRIVILEGE_ADMIN);
-
-    // get root certificate information
-    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_ROOT_CERT_INFO,
-                           NULL, ipmi_firmware_get_root_cert_info,
-                           PRIVILEGE_ADMIN);
-#ifdef INTEL_PFR_ENABLED
     // get root certificate data
     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
                           ipmi::firmware::cmdFwGetRootCertData,
                           ipmi::Privilege::Admin, ipmiGetFwRootCertData);
 #endif
 
-    // generate bmc fw update random number (for enter fw tranfer mode)
-    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_GET_FW_UPDATE_RAND_NUM,
-                           NULL, ipmi_firmware_get_fw_random_number,
-                           PRIVILEGE_ADMIN);
+    // get firmware update channel information (max transfer sizes)
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdGetFwUpdateChannelInfo,
+                          ipmi::Privilege::Admin, ipmiFirmwareMaxTransferSize);
 
-    // Set Firmware Update Mode(0x27)
-    ipmi::registerHandler(ipmi::prioOemBase, NETFUN_FIRMWARE,
-                          IPMI_CMD_FW_SET_FW_UPDATE_MODE,
+    // get bmc execution context
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdGetBmcExecutionContext,
+                          ipmi::Privilege::Admin, ipmiGetBmcExecutionContext);
+
+    // Get Firmware Update Random number
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdGetFwUpdateRandomNumber,
+                          ipmi::Privilege::Admin, ipmiGetFwUpdateRandomNumber);
+
+    // Set Firmware Update Mode
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdSetFirmwareUpdateMode,
                           ipmi::Privilege::Admin, ipmiSetFirmwareUpdateMode);
 
-    // exit firmware update mode
+    // Exit Firmware Update Mode
     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
-                          cmdFirmwareExitFirmwareUpdateMode,
-                          ipmi::Privilege::Admin, ipmiFirmwareExitFwUpdateMode);
+                          ipmi::firmware::cmdExitFirmwareUpdateMode,
+                          ipmi::Privilege::Admin, ipmiExitFirmwareUpdateMode);
 
-    // firmware control mechanism (set filename, usb, etc.)
-    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_UPDATE_CONTROL, NULL,
-                           ipmi_firmware_control, PRIVILEGE_ADMIN);
+    // Get/Set Firmware Update Control
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdGetSetFwUpdateControl,
+                          ipmi::Privilege::Admin,
+                          ipmiGetSetFirmwareUpdateControl);
 
-    // get firmware update status
-    ipmi::registerHandler(ipmi::prioOemBase, NETFUN_FIRMWARE,
-                          IPMI_CMD_FW_GET_STATUS, ipmi::Privilege::Admin,
-                          ipmiFrmwareGetStatus);
-    // set firmware update options (no downgrade, etc.)
-    ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_SET_FW_UPDATE_OPTIONS,
-                           NULL, ipmi_firmware_update_options, PRIVILEGE_ADMIN);
+    // Get Firmware Update Status
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdGetFirmwareUpdateStatus,
+                          ipmi::Privilege::Admin, ipmiGetFirmwareUpdateStatus);
 
+    // Set Firmware Update Options
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
+                          ipmi::firmware::cmdSetFirmwareUpdateOptions,
+                          ipmi::Privilege::Admin, ipmiSetFirmwareUpdateOptions);
     // write image data
     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
                           ipmi::firmware::cmdFwImageWriteData,
                           ipmi::Privilege::Admin, ipmiFwImageWriteData);
-
-    // get buffer size is used by fw update (exclusively?)
-    ipmi_register_callback(NETFUN_INTC_APP, IPMI_CMD_INTC_GET_BUFFER_SIZE, NULL,
-                           ipmi_intel_app_get_buffer_size, PRIVILEGE_USER);
     return;
 }
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index 209edd8..9980397 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -3445,6 +3445,25 @@
     return ipmi::responseSuccess(result);
 }
 
+/** @brief implements the maximum size of
+ *  bridgeable messages used between KCS and
+ *  IPMB interfacesget security mode command.
+ *
+ *  @returns IPMI completion code with following data
+ *   - KCS Buffer Size (In multiples of four bytes)
+ *   - IPMB Buffer Size (In multiples of four bytes)
+ **/
+ipmi::RspType<uint8_t, uint8_t> ipmiOEMGetBufferSize()
+{
+    // for now this is hard coded; really this number is dependent on
+    // the BMC kcs driver as well as the host kcs driver....
+    // we can't know the latter.
+    uint8_t kcsMaxBufferSize = 63 / 4;
+    uint8_t ipmbMaxBufferSize = 128 / 4;
+
+    return ipmi::responseSuccess(kcsMaxBufferSize, ipmbMaxBufferSize);
+}
+
 static void registerOEMFunctions(void)
 {
     phosphor::logging::log<phosphor::logging::level::INFO>(
@@ -3611,6 +3630,10 @@
     registerHandler(prioOemBase, intel::netFnGeneral,
                     intel::general::cmdGetPSUVersion, Privilege::User,
                     ipmiOEMGetPSUVersion);
+
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdGetBufferSize, Privilege::User,
+                    ipmiOEMGetBufferSize);
 }
 
 } // namespace ipmi
