/* Copyright 2018 Intel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "ipmbbridged.hpp"

#include "ipmbdefines.hpp"
#include "ipmbutils.hpp"

#include <boost/algorithm/string/replace.hpp>
#include <boost/asio/write.hpp>
#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <tuple>
#include <unordered_map>

/**
 * @brief Dbus
 */
static constexpr const char *ipmbBus = "xyz.openbmc_project.Ipmi.Channel.Ipmb";
static constexpr const char *ipmbObj = "/xyz/openbmc_project/Ipmi/Channel/Ipmb";
static constexpr const char *ipmbDbusIntf = "org.openbmc.Ipmb";

boost::asio::io_service io;
auto conn = std::make_shared<sdbusplus::asio::connection>(io);

static std::list<IpmbChannel> ipmbChannels;
static const std::unordered_map<std::string, ipmbChannelType>
    ipmbChannelTypeMap = {{"me", ipmbChannelType::me},
                          {"ipmb", ipmbChannelType::ipmb}};

/**
 * @brief Ipmb request class methods
 */
IpmbRequest::IpmbRequest()
{
    data.reserve(ipmbMaxDataSize);
}

IpmbRequest::IpmbRequest(uint8_t address, uint8_t netFn, uint8_t rsLun,
                         uint8_t rqSA, uint8_t seq, uint8_t rqLun, uint8_t cmd,
                         const std::vector<uint8_t> &inputData) :
    address(address),
    netFn(netFn), rsLun(rsLun), rqSA(rqSA), seq(seq), rqLun(rqLun), cmd(cmd),
    timer(io)
{
    data.reserve(ipmbMaxDataSize);
    state = ipmbRequestState::invalid;

    if (inputData.size() > 0)
    {
        data = std::move(inputData);
    }
}

void IpmbRequest::i2cToIpmbConstruct(IPMB_HEADER *ipmbBuffer,
                                     size_t bufferLength)
{
    // constructing ipmb request from i2c buffer
    netFn = ipmbNetFnGet(ipmbBuffer->Header.Req.rsNetFnLUN);
    rsLun = ipmbLunFromNetFnLunGet(ipmbBuffer->Header.Req.rsNetFnLUN);
    rqSA = ipmbBuffer->Header.Req.rqSA;
    seq = ipmbSeqGet(ipmbBuffer->Header.Req.rqSeqLUN);
    rqLun = ipmbLunFromSeqLunGet(ipmbBuffer->Header.Req.rqSeqLUN);
    cmd = ipmbBuffer->Header.Req.cmd;

    size_t dataLength =
        bufferLength - (ipmbConnectionHeaderLength +
                        ipmbRequestDataHeaderLength + ipmbChecksumSize);

    if (dataLength > 0)
    {
        data.insert(data.end(), ipmbBuffer->Header.Req.data,
                    &ipmbBuffer->Header.Req.data[dataLength]);
    }
}

int IpmbRequest::ipmbToi2cConstruct(std::vector<uint8_t> &buffer)
{
    /* Add one byte for length byte as per required by driver */
    size_t bufferLength = 1 + data.size() + ipmbRequestDataHeaderLength +
                          ipmbConnectionHeaderLength + ipmbChecksumSize;

    if (bufferLength > ipmbMaxFrameLength)
    {
        return -1;
    }

    buffer.resize(bufferLength);
    static_assert(ipmbMaxFrameLength >= sizeof(IPMB_HEADER));
    IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer.data());
    ipmbPkt->len = bufferLength - 1;
    IPMB_HEADER *ipmbBuffer = &(ipmbPkt->hdr);

    // constructing buffer from ipmb request
    ipmbBuffer->Header.Req.address = address;
    ipmbBuffer->Header.Req.rsNetFnLUN = ipmbNetFnLunSet(netFn, rsLun);
    ipmbBuffer->Header.Req.rqSA = rqSA;
    ipmbBuffer->Header.Req.rqSeqLUN = ipmbSeqLunSet(seq, rqLun);
    ipmbBuffer->Header.Req.cmd = cmd;

    ipmbBuffer->Header.Req.checksum1 = ipmbChecksumCompute(
        (uint8_t *)ipmbBuffer, ipmbConnectionHeaderLength - ipmbChecksumSize);

    if (data.size() > 0)
    {
        std::copy(data.begin(), data.end(), ipmbBuffer->Header.Req.data);
    }

    buffer[bufferLength - ipmbChecksumSize] =
        ipmbChecksumCompute((uint8_t *)ipmbBuffer + ipmbChecksum2StartOffset,
                            (ipmbRequestDataHeaderLength + data.size()));

    return 0;
}

std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
    IpmbRequest::returnMatchedResponse()
{
    return std::make_tuple(
        static_cast<int>(ipmbResponseStatus::success), matchedResponse->netFn,
        matchedResponse->rsLun, matchedResponse->cmd,
        matchedResponse->completionCode, matchedResponse->data);
}

static std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
    returnStatus(ipmbResponseStatus status)
{
    // we only want to send status here, other fields are not relevant
    return std::make_tuple(static_cast<int>(status), 0, 0, 0, 0,
                           std::vector<uint8_t>(0));
}

/**
 * @brief Ipmb response class methods
 */
IpmbResponse::IpmbResponse()
{
    data.reserve(ipmbMaxDataSize);
}

IpmbResponse::IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun,
                           uint8_t rsSA, uint8_t seq, uint8_t rsLun,
                           uint8_t cmd, uint8_t completionCode,
                           const std::vector<uint8_t> &inputData) :
    address(address),
    netFn(netFn), rqLun(rqLun), rsSA(rsSA), seq(seq), rsLun(rsLun), cmd(cmd),
    completionCode(completionCode)
{
    data.reserve(ipmbMaxDataSize);

    if (inputData.size() > 0)
    {
        data = std::move(inputData);
    }
}

void IpmbResponse::i2cToIpmbConstruct(IPMB_HEADER *ipmbBuffer,
                                      size_t bufferLength)
{
    netFn = ipmbNetFnGet(ipmbBuffer->Header.Resp.rqNetFnLUN);
    rqLun = ipmbLunFromNetFnLunGet(ipmbBuffer->Header.Resp.rqNetFnLUN);
    rsSA = ipmbBuffer->Header.Resp.rsSA;
    seq = ipmbSeqGet(ipmbBuffer->Header.Resp.rsSeqLUN);
    rsLun = ipmbLunFromSeqLunGet(ipmbBuffer->Header.Resp.rsSeqLUN);
    cmd = ipmbBuffer->Header.Resp.cmd;
    completionCode = ipmbBuffer->Header.Resp.completionCode;

    size_t dataLength =
        bufferLength - (ipmbConnectionHeaderLength +
                        ipmbResponseDataHeaderLength + ipmbChecksumSize);

    if (dataLength > 0)
    {
        data.insert(data.end(), ipmbBuffer->Header.Resp.data,
                    &ipmbBuffer->Header.Resp.data[dataLength]);
    }
}

std::shared_ptr<std::vector<uint8_t>> IpmbResponse::ipmbToi2cConstruct()
{
    /* Add one byte for length byte as per required by driver */
    size_t bufferLength = 1 + data.size() + ipmbResponseDataHeaderLength +
                          ipmbConnectionHeaderLength + ipmbChecksumSize;

    if (bufferLength > ipmbMaxFrameLength)
    {
        return nullptr;
    }

    std::shared_ptr<std::vector<uint8_t>> buffer =
        std::make_shared<std::vector<uint8_t>>(bufferLength);

    IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer->data());
    ipmbPkt->len = bufferLength - 1;
    IPMB_HEADER *ipmbBuffer = &(ipmbPkt->hdr);

    ipmbBuffer->Header.Resp.address = address;
    ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun);
    ipmbBuffer->Header.Resp.rsSA = rsSA;
    ipmbBuffer->Header.Resp.rsSeqLUN = ipmbSeqLunSet(seq, rsLun);
    ipmbBuffer->Header.Resp.cmd = cmd;
    ipmbBuffer->Header.Resp.completionCode = completionCode;

    ipmbBuffer->Header.Resp.checksum1 = ipmbChecksumCompute(
        (uint8_t *)ipmbBuffer, ipmbConnectionHeaderLength - ipmbChecksumSize);

    if (data.size() > 0)
    {
        std::copy(data.begin(), data.end(), ipmbBuffer->Header.Resp.data);
    }

    (*buffer)[bufferLength - ipmbChecksumSize] =
        ipmbChecksumCompute((uint8_t *)ipmbBuffer + ipmbChecksum2StartOffset,
                            (ipmbResponseDataHeaderLength + data.size()));

    return buffer;
}

bool IpmbCommandFilter::isBlocked(const uint8_t reqNetFn, const uint8_t cmd)
{
    auto blockedCmd = unhandledCommands.find({reqNetFn, cmd});

    if (blockedCmd != unhandledCommands.end())
    {
        return true;
    }

    return false;
}

void IpmbCommandFilter::addFilter(const uint8_t reqNetFn, const uint8_t cmd)
{
    if (unhandledCommands.insert({reqNetFn, cmd}).second)
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "addFilter: added command to filter",
            phosphor::logging::entry("netFn = %d", reqNetFn),
            phosphor::logging::entry("cmd = %d", cmd));
    }
}

/**
 * @brief Ipmb channel
 */
void IpmbChannel::ipmbSendI2cFrame(std::shared_ptr<std::vector<uint8_t>> buffer,
                                   size_t retriesAttempted = 0)
{
    IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer->data());
    uint8_t targetAddr = ipmbIsResponse(&(ipmbPkt->hdr))
                             ? ipmbPkt->hdr.Header.Resp.address
                             : ipmbPkt->hdr.Header.Req.address;
    boost::asio::async_write(
        i2cSlaveDescriptor, boost::asio::buffer(*buffer),
        [this, buffer, retriesAttempted,
         targetAddr](const boost::system::error_code &ec, size_t bytesSent) {
            if (ec)
            {
                size_t currentRetryCnt = retriesAttempted;

                if (currentRetryCnt > ipmbI2cNumberOfRetries)
                {
                    std::string msgToLog =
                        "ipmbSendI2cFrame: send to I2C failed after retries."
                        " busId=" +
                        std::to_string(ipmbBusId) +
                        ", targetAddr=" + std::to_string(targetAddr) +
                        ", error=" + ec.message();
                    phosphor::logging::log<phosphor::logging::level::ERR>(
                        msgToLog.c_str());
                    return;
                }
                currentRetryCnt++;
                ipmbSendI2cFrame(buffer, currentRetryCnt);
            }
        });
}

/**
 * @brief Ipmb Outstanding Requests
 */
void IpmbChannel::makeRequestInvalid(IpmbRequest &request)
{
    // change request state to invalid and remove it from outstanding requests
    // list
    request.state = ipmbRequestState::invalid;
    outstandingRequests[request.seq] = nullptr;
}

void IpmbChannel::makeRequestValid(std::shared_ptr<IpmbRequest> request)
{
    // change request state to valid and add it to outstanding requests list
    request->state = ipmbRequestState::valid;
    outstandingRequests[request->seq] = request;
}

bool IpmbChannel::seqNumGet(uint8_t &seq)
{
    static uint8_t seqNum = 0;

    for (int i = 0; i < ipmbMaxOutstandingRequestsCount; i++)
    {
        seqNum = ++seqNum & ipmbSeqMask;
        if (seqNum == ipmbMaxOutstandingRequestsCount)
        {
            seqNum = 0;
        }

        if (outstandingRequests[seqNum] == nullptr)
        {
            seq = seqNum;
            return true;
        }
    }

    return false;
}

void IpmbChannel::responseMatch(std::unique_ptr<IpmbResponse> &response)
{
    std::shared_ptr<IpmbRequest> request = outstandingRequests[response->seq];

    if (request != nullptr)
    {
        if (((ipmbRespNetFn(request->netFn)) == (response->netFn)) &&
            ((request->rqLun) == (response->rqLun)) &&
            ((request->rsLun) == (response->rsLun)) &&
            ((request->cmd) == (response->cmd)))
        {
            // match, response is corresponding to previously sent request
            request->state = ipmbRequestState::matched;
            request->timer->cancel();
            request->matchedResponse = std::move(response);
        }
    }
}

void IpmbChannel::processI2cEvent()
{
    std::array<uint8_t, ipmbMaxFrameLength> buffer{};
    IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer.data());
    IPMB_HEADER *ipmbFrame = &(ipmbPkt->hdr);

    lseek(ipmbi2cSlaveFd, 0, SEEK_SET);
    int r = read(ipmbi2cSlaveFd, buffer.data(), ipmbMaxFrameLength);

    /* Substract first byte len size from total frame length */
    r--;

    if ((r < ipmbMinFrameLength) || (r > ipmbMaxFrameLength))
    {
        goto end;
    }

    // valiate the frame
    if (!isFrameValid(ipmbFrame, r))
    {
        goto end;
    }

    // if it is message received from ipmb channel, send out dbus signal
    if (getChannelType() == ipmbChannelType::ipmb)
    {
        auto ipmbMessageReceived = IpmbRequest();
        ipmbMessageReceived.i2cToIpmbConstruct(ipmbFrame, r);
        sdbusplus::message_t msg =
            conn->new_signal(ipmbObj, ipmbDbusIntf, "receiveBroadcast");
        msg.append(ipmbMessageReceived.netFn, ipmbMessageReceived.cmd,
                   ipmbMessageReceived.data);
        msg.signal_send();
    }

    // copy frame to ipmib message buffer
    if (ipmbIsResponse(ipmbFrame))
    {
        std::unique_ptr<IpmbResponse> ipmbMessageReceived =
            std::make_unique<IpmbResponse>();

        ipmbMessageReceived->i2cToIpmbConstruct(ipmbFrame, r);

        // try to match response with outstanding request
        responseMatch(ipmbMessageReceived);
    }
    else
    {
        // if command is blocked - respond with 'invalid command'
        // completion code
        if (commandFilter)
        {
            uint8_t netFn = ipmbNetFnGet(ipmbFrame->Header.Req.rsNetFnLUN);
            uint8_t cmd = ipmbFrame->Header.Req.cmd;
            uint8_t rqSA = ipmbFrame->Header.Req.rqSA;

            if (commandFilter->isBlocked(netFn, cmd))
            {
                uint8_t seq = ipmbSeqGet(ipmbFrame->Header.Req.rqSeqLUN);
                uint8_t lun =
                    ipmbLunFromSeqLunGet(ipmbFrame->Header.Req.rqSeqLUN);

                // prepare generic response
                auto ipmbResponse = IpmbResponse(
                    rqSA, ipmbRespNetFn(netFn), lun, ipmbBmcSlaveAddress, seq,
                    ipmbRsLun, cmd, ipmbIpmiInvalidCmd, {});

                auto buffer = ipmbResponse.ipmbToi2cConstruct();
                if (buffer)
                {
                    ipmbSendI2cFrame(buffer);
                }

                goto end;
            }
        }

        auto ipmbMessageReceived = IpmbRequest();
        ipmbMessageReceived.i2cToIpmbConstruct(ipmbFrame, r);

        int devId = getDevIndex();

        std::map<std::string, std::variant<int>> options{
            {"rqSA", ipmbAddressTo7BitSet(ipmbMessageReceived.rqSA)},
            {"hostId", devId}};

        using IpmiDbusRspType = std::tuple<uint8_t, uint8_t, uint8_t, uint8_t,
                                           std::vector<uint8_t>>;
        conn->async_method_call(
            [this, rqLun{ipmbMessageReceived.rqLun},
             seq{ipmbMessageReceived.seq}, address{ipmbMessageReceived.rqSA}](
                const boost::system::error_code &ec,
                const IpmiDbusRspType &response) {
                const auto &[netfn, lun, cmd, cc, payload] = response;
                if (ec)
                {
                    phosphor::logging::log<phosphor::logging::level::ERR>(
                        "processI2cEvent: error getting response from IPMI");
                    return;
                }

                uint8_t bmcSlaveAddress = getBmcSlaveAddress();

                if (payload.size() > ipmbMaxDataSize)
                {
                    phosphor::logging::log<phosphor::logging::level::ERR>(
                        "processI2cEvent: response exceeding maximum size");

                    // prepare generic response
                    auto ipmbResponse = IpmbResponse(
                        address, netfn, rqLun, bmcSlaveAddress, seq, ipmbRsLun,
                        cmd, ipmbIpmiCmdRespNotProvided, {});

                    auto buffer = ipmbResponse.ipmbToi2cConstruct();
                    if (buffer)
                    {
                        ipmbSendI2cFrame(buffer);
                    }

                    return;
                }

                if (!(netfn & ipmbNetFnResponseMask))
                {
                    // we are not expecting request here
                    phosphor::logging::log<phosphor::logging::level::ERR>(
                        "processI2cEvent: got a request instead of response");
                    return;
                }

                // if command is not supported, add it to filter
                if (cc == ipmbIpmiInvalidCmd)
                {
                    addFilter(ipmbReqNetFnFromRespNetFn(netfn), cmd);
                }

                // payload is empty after constructor invocation
                auto ipmbResponse =
                    IpmbResponse(address, netfn, rqLun, bmcSlaveAddress, seq,
                                 lun, cmd, cc, payload);

                auto buffer = ipmbResponse.ipmbToi2cConstruct();
                if (!buffer)
                {
                    phosphor::logging::log<phosphor::logging::level::ERR>(
                        "processI2cEvent: error constructing a request");
                    return;
                }

                ipmbSendI2cFrame(buffer);
            },
            "xyz.openbmc_project.Ipmi.Host", "/xyz/openbmc_project/Ipmi",
            "xyz.openbmc_project.Ipmi.Server", "execute",
            ipmbMessageReceived.netFn, ipmbMessageReceived.rsLun,
            ipmbMessageReceived.cmd, ipmbMessageReceived.data, options);
    }

end:
    i2cSlaveDescriptor.async_wait(
        boost::asio::posix::descriptor_base::wait_read,
        [this](const boost::system::error_code &ec) {
            if (ec)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "Error: processI2cEvent()");
                return;
            }

            processI2cEvent();
        });
}

IpmbChannel::IpmbChannel(boost::asio::io_service &io,
                         uint8_t ipmbBmcSlaveAddress,
                         uint8_t ipmbRqSlaveAddress, uint8_t channelIdx,
                         std::shared_ptr<IpmbCommandFilter> commandFilter) :
    i2cSlaveDescriptor(io),
    ipmbBmcSlaveAddress(ipmbBmcSlaveAddress),
    ipmbRqSlaveAddress(ipmbRqSlaveAddress), channelIdx(channelIdx),
    commandFilter(commandFilter)
{
}

int IpmbChannel::ipmbChannelInit(const char *ipmbI2cSlave)
{
    // extract bus id from slave path and save
    std::string ipmbI2cSlaveStr(ipmbI2cSlave);
    auto findHyphen = ipmbI2cSlaveStr.find("-");
    std::string busStr = ipmbI2cSlaveStr.substr(findHyphen + 1);
    try
    {
        ipmbBusId = std::stoi(busStr);
    }
    catch (const std::invalid_argument &)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbChannelInit: invalid bus id in slave-path config");
        return -1;
    }

    // Check if sysfs has device. If not, enable I2C slave driver by command
    // echo "ipmb-dev 0x1010" > /sys/bus/i2c/devices/i2c-0/new_device
    bool hasSysfs = std::filesystem::exists(ipmbI2cSlave);
    if (!hasSysfs)
    {
        std::string deviceFileName =
            "/sys/bus/i2c/devices/i2c-" + busStr + "/new_device";
        std::string para = "ipmb-dev 0x1010"; // init with BMC addr 0x20
        std::fstream deviceFile;
        deviceFile.open(deviceFileName, std::ios::out);
        if (!deviceFile.good())
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "ipmbChannelInit: error opening deviceFile");
            return -1;
        }
        deviceFile << para;
        deviceFile.close();
    }

    // open fd to i2c slave device for read write
    ipmbi2cSlaveFd = open(ipmbI2cSlave, O_RDWR | O_NONBLOCK | O_CLOEXEC);
    if (ipmbi2cSlaveFd < 0)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbChannelInit: error opening ipmbI2cSlave");
        return -1;
    }

    i2cSlaveDescriptor.assign(ipmbi2cSlaveFd);

    i2cSlaveDescriptor.async_wait(
        boost::asio::posix::descriptor_base::wait_read,
        [this](const boost::system::error_code &ec) {
            if (ec)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "Error: processI2cEvent()");
                return;
            }

            processI2cEvent();
        });

    return 0;
}

int IpmbChannel::ipmbChannelUpdateSlaveAddress(const uint8_t newBmcSlaveAddr)
{
    if (ipmbi2cSlaveFd > 0)
    {
        i2cSlaveDescriptor.close();
        close(ipmbi2cSlaveFd);
        ipmbi2cSlaveFd = 0;
    }

    // disable old I2C slave driver by command:
    //     echo "0x1010" > /sys/bus/i2c/devices/i2c-0/delete_device
    std::string deviceFileName;
    std::string para;
    std::fstream deviceFile;
    deviceFileName = "/sys/bus/i2c/devices/i2c-" + std::to_string(ipmbBusId) +
                     "/delete_device";
    para = "0x1010"; // align with removed ipmb0 definition in dts file
    deviceFile.open(deviceFileName, std::ios::out);
    if (!deviceFile.good())
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbChannelUpdateSlaveAddress: error opening deviceFile to delete "
            "sysfs");
        return -1;
    }
    deviceFile << para;
    deviceFile.close();

    // enable new I2C slave driver by command:
    //      echo "ipmb-dev 0x1012" > /sys/bus/i2c/devices/i2c-0/new_device
    deviceFileName =
        "/sys/bus/i2c/devices/i2c-" + std::to_string(ipmbBusId) + "/new_device";
    std::ostringstream hex;
    uint16_t addr = 0x1000 + (newBmcSlaveAddr >> 1);
    hex << std::hex << static_cast<uint16_t>(addr);
    const std::string &addressHexStr = hex.str();
    para = "ipmb-dev 0x" + addressHexStr;
    deviceFile.open(deviceFileName, std::ios::out);
    if (!deviceFile.good())
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbChannelUpdateSlaveAddress: error opening deviceFile to create "
            "sysfs");
        return -1;
    }
    deviceFile << para;
    deviceFile.close();

    // open fd to i2c slave device
    std::string ipmbI2cSlaveStr = "/dev/ipmb-" + std::to_string(ipmbBusId);
    ipmbi2cSlaveFd = open(ipmbI2cSlaveStr.c_str(), O_RDWR | O_NONBLOCK);
    if (ipmbi2cSlaveFd < 0)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbChannelInit: error opening ipmbI2cSlave");
        return -1;
    }

    // start to receive i2c data as slave
    i2cSlaveDescriptor.assign(ipmbi2cSlaveFd);
    i2cSlaveDescriptor.async_wait(
        boost::asio::posix::descriptor_base::wait_read,
        [this](const boost::system::error_code &ec) {
            if (ec)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "Error: processI2cEvent()");
                return;
            }

            processI2cEvent();
        });

    ipmbBmcSlaveAddress = newBmcSlaveAddr;

    return 0;
}

uint8_t IpmbChannel::getBusId()
{
    return ipmbBusId;
}

uint8_t IpmbChannel::getBmcSlaveAddress()
{
    return ipmbBmcSlaveAddress;
}

uint8_t IpmbChannel::getRqSlaveAddress()
{
    return ipmbRqSlaveAddress;
}

uint8_t IpmbChannel::getDevIndex()
{
    return channelIdx >> 2;
}

uint8_t IpmbChannel::getChannelIdx()
{
    return channelIdx;
}

ipmbChannelType IpmbChannel::getChannelType()
{
    return static_cast<ipmbChannelType>((channelIdx & 3));
}

void IpmbChannel::addFilter(const uint8_t respNetFn, const uint8_t cmd)
{
    if (commandFilter)
    {
        commandFilter->addFilter(respNetFn, cmd);
    }
}

std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
    IpmbChannel::requestAdd(boost::asio::yield_context &yield,
                            std::shared_ptr<IpmbRequest> request)
{
    makeRequestValid(request);

    std::vector<uint8_t> buffer(0);
    if (request->ipmbToi2cConstruct(buffer) != 0)
    {
        return returnStatus(ipmbResponseStatus::error);
    }

    for (int i = 0; i < ipmbNumberOfTries; i++)
    {
        boost::system::error_code ec;
        int i2cRetryCnt = 0;

        for (; i2cRetryCnt < ipmbI2cNumberOfRetries; i2cRetryCnt++)
        {
            boost::asio::async_write(i2cSlaveDescriptor,
                                     boost::asio::buffer(buffer), yield[ec]);

            if (ec)
            {
                continue; // retry
            }
            break;
        }

        if (i2cRetryCnt == ipmbI2cNumberOfRetries)
        {
            std::string msgToLog =
                "requestAdd: Sent to I2C failed after retries."
                " busId=" +
                std::to_string(ipmbBusId) + ", error=" + ec.message();
            phosphor::logging::log<phosphor::logging::level::INFO>(
                msgToLog.c_str());
        }

        request->timer->expires_after(
            std::chrono::milliseconds(ipmbRequestRetryTimeout));
        request->timer->async_wait(yield[ec]);

        if (ec && ec != boost::asio::error::operation_aborted)
        {
            // unexpected error - invalidate request and return generic error
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "requestAdd: async_wait error");
            makeRequestInvalid(*request);
            return returnStatus(ipmbResponseStatus::error);
        }

        if (request->state == ipmbRequestState::matched)
        {
            // matched response, send it to client application
            makeRequestInvalid(*request);
            return request->returnMatchedResponse();
        }
    }

    makeRequestInvalid(*request);
    return returnStatus(ipmbResponseStatus::timeout);
}

static IpmbChannel *getChannel(uint8_t reqChannel)
{
    auto channel =
        std::find_if(ipmbChannels.begin(), ipmbChannels.end(),
                     [reqChannel](IpmbChannel &channel) {
                         return channel.getChannelIdx() == reqChannel;
                     });
    if (channel != ipmbChannels.end())
    {
        return &(*channel);
    }

    return nullptr;
}

static int initializeChannels()
{
    std::shared_ptr<IpmbCommandFilter> commandFilter =
        std::make_shared<IpmbCommandFilter>();

    constexpr const char *configFilePath =
        "/usr/share/ipmbbridge/ipmb-channels.json";
    std::ifstream configFile(configFilePath);
    if (!configFile.is_open())
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "initializeChannels: Cannot open config path");
        return -1;
    }
    try
    {
        uint8_t devIndex = 0;
        auto data = nlohmann::json::parse(configFile, nullptr);
        for (const auto &channelConfig : data["channels"])
        {
            const std::string &typeConfig = channelConfig["type"];
            const std::string &slavePath = channelConfig["slave-path"];
            uint8_t bmcAddr = channelConfig["bmc-addr"];
            uint8_t reqAddr = channelConfig["remote-addr"];

            ipmbChannelType type = ipmbChannelTypeMap.at(typeConfig);

            if (channelConfig.contains("devIndex"))
            {
                devIndex = channelConfig["devIndex"];
            }

            auto channel = ipmbChannels.emplace(
                ipmbChannels.end(), io, bmcAddr, reqAddr,
                ((devIndex << 2) | static_cast<uint8_t>(type)), commandFilter);
            if (channel->ipmbChannelInit(slavePath.c_str()) < 0)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "initializeChannels: channel initialization failed");
                return -1;
            }
        }
    }
    catch (const nlohmann::json::exception &e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "initializeChannels: Error parsing config file");
        return -1;
    }
    catch (const std::out_of_range &e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "initializeChannels: Error invalid type");
        return -1;
    }
    return 0;
}

auto ipmbHandleRequest = [](boost::asio::yield_context yield,
                            uint8_t reqChannel, uint8_t netfn, uint8_t lun,
                            uint8_t cmd, std::vector<uint8_t> dataReceived) {
    IpmbChannel *channel = getChannel(reqChannel);

    if (channel == nullptr)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbHandleRequest: requested channel does not exist");
        return returnStatus(ipmbResponseStatus::invalid_param);
    }

    // check outstanding request list for valid sequence number
    uint8_t seqNum = 0;
    bool seqValid = channel->seqNumGet(seqNum);
    if (!seqValid)
    {
        phosphor::logging::log<phosphor::logging::level::WARNING>(
            "ipmbHandleRequest: cannot add more requests to the list");
        return returnStatus(ipmbResponseStatus::busy);
    }

    uint8_t bmcSlaveAddress = channel->getBmcSlaveAddress();
    uint8_t rqSlaveAddress = channel->getRqSlaveAddress();

    // construct the request to add it to outstanding request list
    std::shared_ptr<IpmbRequest> request = std::make_shared<IpmbRequest>(
        rqSlaveAddress, netfn, ipmbRsLun, bmcSlaveAddress, seqNum, lun, cmd,
        dataReceived);

    if (!request->timer)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbHandleRequest: timer object does not exist");
        return returnStatus(ipmbResponseStatus::error);
    }

    return channel->requestAdd(yield, request);
};

void addUpdateSlaveAddrHandler()
{
    // callback to handle dbus signal of updating slave addr
    std::function<void(sdbusplus::message_t &)> updateSlaveAddrHandler =
        [](sdbusplus::message_t &message) {
            uint8_t reqChannel, busId, slaveAddr;

            // valid source of signal, check whether from multi-node manager
            std::string pathName = message.get_path();
            if (pathName != "/xyz/openbmc_project/MultiNode/Status")
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "addUpdateSlaveAddrHandler: invalid obj path");
                return;
            }

            message.read(reqChannel, busId, slaveAddr);

            IpmbChannel *channel = getChannel(reqChannel);

            if (channel == nullptr ||
                channel->getChannelType() != ipmbChannelType::ipmb)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "addUpdateSlaveAddrHandler: invalid channel");
                return;
            }
            if (busId != channel->getBusId())
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "addUpdateSlaveAddrHandler: invalid busId");
                return;
            }
            if (channel->getBmcSlaveAddress() == slaveAddr)
            {
                phosphor::logging::log<phosphor::logging::level::INFO>(
                    "addUpdateSlaveAddrHandler: channel bmc slave addr is "
                    "unchanged, do nothing");
                return;
            }

            channel->ipmbChannelUpdateSlaveAddress(slaveAddr);
        };

    static auto match = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t &>(*conn),
        "type='signal',member='updateBmcSlaveAddr',", updateSlaveAddrHandler);
}

void addSendBroadcastHandler()
{
    // callback to handle dbus signal of sending broadcast message
    std::function<void(sdbusplus::message_t &)> sendBroadcastHandler =
        [](sdbusplus::message_t &message) {
            uint8_t reqChannel, netFn, lun, cmd;
            std::vector<uint8_t> dataReceived;
            message.read(reqChannel, netFn, lun, cmd, dataReceived);

            IpmbChannel *channel = getChannel(reqChannel);

            if (channel == nullptr)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "addSendBroadcastMsgHandler: requested channel does not "
                    "exist");
                return;
            }

            uint8_t bmcSlaveAddress = channel->getBmcSlaveAddress();
            uint8_t seqNum = 0; // seqNum is not used in broadcast msg
            uint8_t targetAddr = broadcastAddress;

            std::shared_ptr<IpmbRequest> request =
                std::make_shared<IpmbRequest>(targetAddr, netFn, ipmbRsLun,
                                              bmcSlaveAddress, seqNum, lun, cmd,
                                              dataReceived);

            std::shared_ptr<std::vector<uint8_t>> buffer =
                std::make_shared<std::vector<uint8_t>>();

            if (request->ipmbToi2cConstruct(*buffer) != 0)
            {
                return;
            }

            channel->ipmbSendI2cFrame(buffer);
        };

    static auto match = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t &>(*conn),
        "type='signal',member='sendBroadcast',", sendBroadcastHandler);
}

/**
 * @brief Main
 */
int main(int argc, char *argv[])
{
    conn->request_name(ipmbBus);

    auto server = sdbusplus::asio::object_server(conn);

    std::shared_ptr<sdbusplus::asio::dbus_interface> ipmbIface =
        server.add_interface(ipmbObj, ipmbDbusIntf);

    ipmbIface->register_method("sendRequest", std::move(ipmbHandleRequest));
    ipmbIface->initialize();

    if (initializeChannels() < 0)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Error initializeChannels");
        return -1;
    }

    addUpdateSlaveAddrHandler();

    addSendBroadcastHandler();

    io.run();
    return 0;
}
