/* 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::message 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::message &)> updateSlaveAddrHandler =
        [](sdbusplus::message::message &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::match>(
        static_cast<sdbusplus::bus::bus &>(*conn),
        "type='signal',member='updateBmcSlaveAddr',", updateSlaveAddrHandler);
}

void addSendBroadcastHandler()
{
    // callback to handle dbus signal of sending broadcast message
    std::function<void(sdbusplus::message::message &)> sendBroadcastHandler =
        [](sdbusplus::message::message &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::match>(
        static_cast<sdbusplus::bus::bus &>(*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;
}
