#include <ipmid/api.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <boost/algorithm/string.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/process/child.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <chrono>
#include <commandutils.hpp>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <iostream>
#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>
#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,
    bmcRecoveryImage,
};

const static boost::container::flat_map<FWDeviceIDTag, const char *>
    fwVersionIdMap{{FWDeviceIDTag::bmcActiveImage,
                    "/xyz/openbmc_project/software/bmc_active"},
                   {FWDeviceIDTag::bmcRecoveryImage,
                    "/xyz/openbmc_project/software/bmc_recovery"}};
#endif // INTEL_PFR_ENABLED

enum class ChannelIdTag : uint8_t
{
    reserved = 0,
    kcs = 1,
    ipmb = 2,
    rmcpPlus = 3
};

enum class BmcExecutionContext : uint8_t
{
    reserved = 0,
    linuxOs = 0x10,
    bootLoader = 0x11,
};

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 size_t maxFirmwareImageSize = 32_MB;

static bool localDownloadInProgress(void)
{
    struct stat sb;
    if (stat(firmwareBufferFile, &sb) < 0)
    {
        return false;
    }
    return true;
}

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
    {
        fwStateInit = 0,
        fwStateIdle,
        fwStateDownload,
        fwStateVerify,
        fwStateProgram,
        fwStateUpdateSuccess,
        fwStateError = 0x0f,
        fwStateAcCycleRequired = 0x83,
    };
    uint8_t getState()
    {
        if ((fwUpdateState == fwStateIdle || fwUpdateState == fwStateInit) &&
            localDownloadInProgress())
        {
            fwUpdateState = fwStateDownload;
            progressPercent = 0;
        }
        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 progressPercent;
    }
    void updateActivationPercent(const std::string &objPath)
    {
        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(
                objPath, "xyz.openbmc_project.Software.ActivationProgress"),
            [&](sdbusplus::message::message &msg) {
                std::map<std::string, ipmi::DbusVariant> props;
                std::vector<std::string> inVal;
                std::string iface;
                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 activationTimerTimeout()
    {
        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 */
            fwUpdateState = fwStateUpdateSuccess;
        }
        return progressPercent;
    }
    /* API for changing state to ERROR  */
    void firmwareUpdateAbortState()
    {
        unlink(firmwareBufferFile);
        // changing the state to error
        fwUpdateState = fwStateError;
    }
    void setDeferRestart(bool deferRestart)
    {
        deferRestartState = deferRestart;
    }
    void setInhibitDowngrade(bool inhibitDowngrade)
    {
        inhibitDowngradeState = inhibitDowngrade;
    }
    bool getDeferRestart()
    {
        return deferRestartState;
    }
    bool getInhibitDowngrade()
    {
        return inhibitDowngradeState;
    }

  protected:
    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 FwUpdateStatusCache fwUpdateStatus;
std::shared_ptr<TransferHashCheck> xferHashCheck;

static void activateImage(const std::string &objPath)
{
    // If flag is false  means to reboot
    if (fwUpdateStatus.getDeferRestart() == false)
    {
        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"));
    }
    else
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "Firmware image activation is deferred.");
    }
    fwUpdateStatus.setState(
        static_cast<uint8_t>(FwUpdateStatusCache::fwStateUpdateSuccess));
}

static bool getFirmwareUpdateMode()
{
    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
    try
    {
        auto service = ipmi::getService(*busp, bmcStateIntf, bmcStatePath);
        ipmi::Value state = ipmi::getDbusProperty(
            *busp, service, bmcStatePath, bmcStateIntf, "CurrentBMCState");
        std::string bmcState = std::get<std::string>(state);
        return (bmcState == bmcStateUpdateInProgress);
    }
    catch (const std::exception &e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught while getting BMC state.",
            phosphor::logging::entry("EXCEPTION=%s", e.what()));
        throw;
    }
}

static void setFirmwareUpdateMode(const bool mode)
{

    std::string bmcState(bmcStateReady);
    if (mode)
    {
        bmcState = bmcStateUpdateInProgress;
    }

    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
    try
    {
        auto service = ipmi::getService(*busp, bmcStateIntf, bmcStatePath);
        ipmi::setDbusProperty(*busp, service, bmcStatePath, bmcStateIntf,
                              "CurrentBMCState", bmcState);
    }
    catch (const std::exception &e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught while setting BMC state.",
            phosphor::logging::entry("EXCEPTION=%s", e.what()));
        throw;
    }
}

static void postTransferCompleteHandler(
    std::unique_ptr<sdbusplus::bus::match::match> &fwUpdateMatchSignal)
{
    // Setup timer for watching signal
    static phosphor::Timer timer(
        [&fwUpdateMatchSignal]() { fwUpdateMatchSignal = nullptr; });

    static phosphor::Timer activationStatusTimer([]() {
        if (fwUpdateStatus.activationTimerTimeout() >= 95)
        {
            activationStatusTimer.stop();
            fwUpdateStatus.setState(
                static_cast<uint8_t>(FwUpdateStatusCache::fwStateVerify));
        }
    });

    timer.start(std::chrono::microseconds(5000000), false);

    // callback function for capturing signal
    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>>>>>
            intfPropsPair;
        sdbusplus::message::object_path objPath;

        try
        {
            m.read(objPath, intfPropsPair); // Read in the object path
                                            // that was just created
        }
        catch (const std::exception &e)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Exception caught in reading created object path.");
            return;
        }
        // constructing response message
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "New Interface Added.",
            phosphor::logging::entry("OBJPATH=%s", objPath.str.c_str()));
        for (auto &interface : intfPropsPair)
        {
            if (interface.first == "xyz.openbmc_project.Software.Activation")
            {
                // 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;

                phosphor::logging::log<phosphor::logging::level::INFO>(
                    "Start activationStatusTimer for status.");
                try
                {
                    timer.stop();
                    activationStatusTimer.start(
                        std::chrono::microseconds(3000000), true);
                }
                catch (const std::exception &e)
                {
                    phosphor::logging::log<phosphor::logging::level::ERR>(
                        "Exception caught in start activationStatusTimer.",
                        phosphor::logging::entry("ERROR=%s", e.what()));
                }

                fwUpdateStatus.updateActivationPercent(objPath.str);
                activateImage(objPath.str);
            }
        }
    };

    // Adding matcher
    fwUpdateMatchSignal = std::make_unique<sdbusplus::bus::match::match>(
        *getSdBus(),
        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
        "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
        callback);
}
static bool startFirmwareUpdate(const std::string &uri)
{
    // 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;
}

static int transferImageFromFile(const std::string &uri, bool move = true)
{
    std::error_code ec;
    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, firmwareBufferFile, ec);
    }
    else
    {
        std::filesystem::copy(uri, firmwareBufferFile,
                              std::filesystem::copy_options::overwrite_existing,
                              ec);
    }
    if (xferHashCheck)
    {
        MappedFile mappedfw(uri);
        xferHashCheck->hash(
            {mappedfw.data(), mappedfw.data() + mappedfw.size()});
    }
    if (ec.value())
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Image copy failed.");
    }
    return ec.value();
}

template <typename... ArgTypes>
static int executeCmd(const char *path, ArgTypes &&... tArgs)
{
    boost::process::child execProg(path, const_cast<char *>(tArgs)...);
    execProg.wait();
    return execProg.exit_code();
}

static int transferImageFromUsb(const std::string &uri)
{
    int ret, sysret;
    char fwpath[fwPathMaxLength];
    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(fwUpdateMountPoint) + "/" + uri;
    ret = transferImageFromFile(usb_path, false);

    executeCmd(usbCtrlPath, "cleanup", fwUpdateUsbVolImage, fwUpdateMountPoint);
    return ret;
}

static bool transferFirmwareFromUri(const std::string &uri)
{
    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(fwUriFile) - 1);
        if (fname != firmwareBufferFile)
        {
            return 0 == transferImageFromFile(fname);
        }
        return true;
    }
    if (boost::algorithm::starts_with(uri, fwUriUsb))
    {
        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 bool getUsbStatus()
{
    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 attachUsbDevice()
{
    if (getUsbStatus())
    {
        return 1;
    }
    int ret = executeCmd(usbCtrlPath, "setup", fwUpdateUsbVolImage,
                         std::to_string(maxFirmwareImageSize / 1_MB).c_str());
    if (!ret)
    {
        ret = executeCmd(usbCtrlPath, "insert", fwUpdateUSBDevName,
                         fwUpdateUsbVolImage);
    }
    return ret;
}

/* Eject the USB-mass-storage device status: success => 0, failure => non-0 */
static int detachUsbDevice()
{
    if (!getUsbStatus())
    {
        return 1;
    }
    return executeCmd(usbCtrlPath, "eject", fwUpdateUSBDevName);
}
static uint8_t getActiveBootImage(ipmi::Context::ptr ctx)
{
    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)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Failed to read the bootcmd value");
        return ipmi::ccUnspecifiedError;
    }

    /* cheking for secondary FitImage Address 22480000  */
    if (value.find(secondaryFitImageStartAddr) != std::string::npos)
    {
        bootImage = secondaryImage;
    }
    else
    {
        bootImage = primaryImage;
    }

    return bootImage;
}

#ifdef INTEL_PFR_ENABLED
using fwVersionInfoType = std::tuple<uint8_t,   // ID Tag
                                     uint8_t,   // Major Version Number
                                     uint8_t,   // Minor Version Number
                                     uint32_t,  // Build Number
                                     uint32_t,  // Build Timestamp
                                     uint32_t>; // Update Timestamp
ipmi::RspType<uint8_t, std::vector<fwVersionInfoType>> ipmiGetFwVersionInfo()
{
    // Byte 1 - Count (N) Number of devices data is being returned for.
    // Bytes  2:16 - Device firmare information(fwVersionInfoType)
    // Bytes - 17:(15xN) - Repeat of 2 through 16

    std::vector<fwVersionInfoType> fwVerInfoList;
    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
    for (const auto &fwDev : fwVersionIdMap)
    {
        std::string verStr;
        try
        {
            auto service = ipmi::getService(*busp, versionIntf, fwDev.second);

            ipmi::Value result = ipmi::getDbusProperty(
                *busp, service, fwDev.second, versionIntf, "Version");
            verStr = std::get<std::string>(result);
        }
        catch (const std::exception &e)
        {
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "Failed to fetch Version property",
                phosphor::logging::entry("ERROR=%s", e.what()),
                phosphor::logging::entry("PATH=%s", fwDev.second),
                phosphor::logging::entry("INTERFACE=%s", versionIntf));
            continue;
        }

        if (verStr.empty())
        {
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "Version is empty.",
                phosphor::logging::entry("PATH=%s", fwDev.second),
                phosphor::logging::entry("INTERFACE=%s", versionIntf));
            continue;
        }

        // BMC Version format: <major>.<minor>-<build bum>-<build hash>
        std::vector<std::string> splitVer;
        boost::split(splitVer, verStr, boost::is_any_of(".-"));
        if (splitVer.size() < 3)
        {
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "Invalid Version format.",
                phosphor::logging::entry("Version=%s", verStr.c_str()),
                phosphor::logging::entry("PATH=%s", fwDev.second));
            continue;
        }

        uint8_t majorNum = 0;
        uint8_t minorNum = 0;
        uint32_t buildNum = 0;
        try
        {
            majorNum = std::stoul(splitVer[0], nullptr, 16);
            minorNum = std::stoul(splitVer[1], nullptr, 16);
            buildNum = std::stoul(splitVer[2], nullptr, 16);
        }
        catch (const std::exception &e)
        {
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "Failed to convert stoul.",
                phosphor::logging::entry("ERROR=%s", e.what()));
            continue;
        }

        // Build Timestamp - Not supported.
        // Update Timestamp - TODO: Need to check with CPLD team.
        fwVerInfoList.emplace_back(
            fwVersionInfoType(static_cast<uint8_t>(fwDev.first), majorNum,
                              minorNum, buildNum, 0, 0));
    }

    return ipmi::responseSuccess(fwVerInfoList.size(), fwVerInfoList);
}
using fwSecurityVersionInfoType = std::tuple<uint8_t,  // ID Tag
                                             uint8_t,  // BKC Version
                                             uint8_t>; // SVN Version
ipmi::RspType<uint8_t, std::vector<fwSecurityVersionInfoType>>
    ipmiGetFwSecurityVersionInfo()
{
    // TODO: Need to add support.
    return ipmi::responseInvalidCommand();
}

ipmi::RspType<std::array<uint8_t, certKeyLen>,
              std::optional<std::array<uint8_t, cskSignatureLen>>>
    ipmiGetFwRootCertData(uint8_t certId)
{
    size_t certKeyOffset = 0;
    size_t cskSigOffset = 0;
    std::string mtdDev;

    switch (static_cast<FwGetRootCertDataTag>(certId))
    {
        case FwGetRootCertDataTag::activeRootKey:
        {
            mtdDev = bmcActivePfmMTDDev;
            certKeyOffset = rootkeyOffsetInPfm;
            break;
        }
        case FwGetRootCertDataTag::recoveryRootKey:
        {
            mtdDev = bmcRecoveryImgMTDDev;
            certKeyOffset = pfmBaseOffsetInImage + rootkeyOffsetInPfm;
            break;
        }
        case FwGetRootCertDataTag::activeCSK:
        {
            mtdDev = bmcActivePfmMTDDev;
            certKeyOffset = cskKeyOffsetInPfm;
            cskSigOffset = cskSignatureOffsetInPfm;
            break;
        }
        case FwGetRootCertDataTag::recoveryCSK:
        {
            mtdDev = bmcRecoveryImgMTDDev;
            certKeyOffset = pfmBaseOffsetInImage + cskKeyOffsetInPfm;
            cskSigOffset = pfmBaseOffsetInImage + cskSignatureOffsetInPfm;
            break;
        }
        default:
        {
            return ipmi::responseInvalidFieldRequest();
        }
    }

    std::array<uint8_t, certKeyLen> certKey = {0};

    try
    {
        SPIDev spiDev(mtdDev);
        spiDev.spiReadData(certKeyOffset, certKeyLen, certKey.data());

        if (cskSigOffset)
        {
            std::array<uint8_t, cskSignatureLen> cskSignature = {0};
            spiDev.spiReadData(cskSigOffset, cskSignatureLen,
                               cskSignature.data());
            return ipmi::responseSuccess(certKey, cskSignature);
        }
    }
    catch (const std::exception &e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in ipmiGetFwRootCertData",
            phosphor::logging::entry("MSG=%s", e.what()));
        return ipmi::responseUnspecifiedError();
    }

    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)
{
    const uint8_t ccCmdNotSupportedInPresentState = 0xD5;
    size_t writeDataLen = writeData.size();

    if (!writeDataLen)
    {
        return ipmi::responseReqDataLenInvalid();
    }

    if (fwUpdateStatus.getState() != FwUpdateStatusCache::fwStateDownload)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Invalid firmware update state.");
        return ipmi::response(ccCmdNotSupportedInPresentState);
    }

    std::ofstream out(firmwareBufferFile,
                      std::ofstream::binary | std::ofstream::app);
    if (!out)
    {
        phosphor::logging::log<phosphor::logging::level::DEBUG>(
            "Error while opening file.");
        return ipmi::responseUnspecifiedError();
    }

    uint64_t fileDataLen = out.tellp();

    if ((fileDataLen + writeDataLen) > maxFirmwareImageSize)
    {
        phosphor::logging::log<phosphor::logging::level::DEBUG>(
            "Firmware image size exceeds the limit");
        return ipmi::responseInvalidFieldRequest();
    }

    const char *data = reinterpret_cast<const char *>(writeData.data());
    out.write(data, writeDataLen);
    out.close();

    if (xferHashCheck)
    {
        xferHashCheck->hash(writeData);
    }

#ifdef INTEL_PFR_ENABLED
    /* PFR image block 0 - As defined in HAS */
    struct PFRImageBlock0
    {
        uint32_t tag;
        uint32_t pcLength;
        uint32_t pcType;
        uint32_t reserved1;
        uint8_t hash256[32];
        uint8_t hash384[48];
        uint8_t reserved2[32];
    } __attribute__((packed));

    /* Get the PFR block 0 data and read the uploaded image
     * information( Image type, length etc) */
    if (((fileDataLen + writeDataLen) >= sizeof(PFRImageBlock0)) &&
        (!block0Mapped))
    {
        struct PFRImageBlock0 block0Data = {0};

        std::ifstream inFile(firmwareBufferFile,
                             std::ios::binary | std::ios::in);
        inFile.read(reinterpret_cast<char *>(&block0Data), sizeof(block0Data));
        inFile.close();

        uint32_t magicNum = block0Data.tag;

        /* Validate the magic number */
        if (magicNum != perBlock0MagicNum)
        {
            phosphor::logging::log<phosphor::logging::level::DEBUG>(
                "PFR image magic number not matched");
            return ipmi::responseInvalidFieldRequest();
        }
        // Note:imgLength, imgType and block0Mapped are in global scope, as
        // these are used in cascaded updates.
        imgLength = block0Data.pcLength;
        imgType = block0Data.pcType;
        block0Mapped = true;
    }
#endif // end of INTEL_PFR_ENABLED
    return ipmi::responseSuccess(writeDataLen);
}

static void registerFirmwareFunctions()
{
    // guarantee that we start with an already timed out timestamp
    fwRandomNumGenTs =
        std::chrono::steady_clock::now() - fwRandomNumExpirySeconds;
    fwUpdateStatus.setState(
        static_cast<uint8_t>(FwUpdateStatusCache::fwStateInit));

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

    // get firmware security version information
    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
                          ipmi::firmware::cmdGetFwSecurityVersionInfo,
                          ipmi::Privilege::Admin, ipmiGetFwSecurityVersionInfo);

    // get root certificate data
    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
                          ipmi::firmware::cmdFwGetRootCertData,
                          ipmi::Privilege::Admin, ipmiGetFwRootCertData);
#endif

    // get firmware update channel information (max transfer sizes)
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
                          ipmi::firmware::cmdGetFwUpdateChannelInfo,
                          ipmi::Privilege::Admin, ipmiFirmwareMaxTransferSize);

    // 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
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnFirmware,
                          ipmi::firmware::cmdExitFirmwareUpdateMode,
                          ipmi::Privilege::Admin, ipmiExitFirmwareUpdateMode);

    // 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, 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);
    return;
}
