/* 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/io_context.hpp>
#include <boost/asio/write.hpp>
#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>

#include <filesystem>
#include <fstream>
#include <list>
#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_context 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(
        i2cTargetDescriptor, 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 + 1) % ipmbMaxOutstandingRequestsCount;

        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(ipmbi2cTargetFd, 0, SEEK_SET);
    ssize_t r = read(ipmbi2cTargetFd, buffer.data(), ipmbMaxFrameLength);

    // Handle error cases.
    if (r < 0)
    {
        goto end;
    }

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

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

    // validate 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, ipmbBmcTargetAddress, 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 bmcTargetAddress = getBmcTargetAddress();

                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, bmcTargetAddress, 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, bmcTargetAddress, 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:
    i2cTargetDescriptor.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_context& io,
                         uint8_t ipmbBmcTargetAddress,
                         uint8_t ipmbRqTargetAddress, uint8_t channelIdx,
                         std::shared_ptr<IpmbCommandFilter> commandFilter) :
    i2cTargetDescriptor(io), ipmbBmcTargetAddress(ipmbBmcTargetAddress),
    ipmbRqTargetAddress(ipmbRqTargetAddress), channelIdx(channelIdx),
    commandFilter(commandFilter)
{}

int IpmbChannel::ipmbChannelInit(const char* ipmbI2cTarget)
{
    // extract bus id from target path and save
    std::string ipmbI2cTargetStr(ipmbI2cTarget);
    auto findHyphen = ipmbI2cTargetStr.find("-");
    std::string busStr = ipmbI2cTargetStr.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 target-path config");
        return -1;
    }

    // Check if sysfs has device. If not, enable I2C target driver by command
    // echo "ipmb-dev 0x1010" > /sys/bus/i2c/devices/i2c-0/new_device
    bool hasSysfs = std::filesystem::exists(ipmbI2cTarget);
    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 target device for read write
    ipmbi2cTargetFd = open(ipmbI2cTarget, O_RDWR | O_NONBLOCK | O_CLOEXEC);
    if (ipmbi2cTargetFd < 0)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "ipmbChannelInit: error opening ipmbI2cTarget");
        return -1;
    }

    i2cTargetDescriptor.assign(ipmbi2cTargetFd);

    i2cTargetDescriptor.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::ipmbChannelUpdateTargetAddress(const uint8_t newBmcTargetAddr)
{
    if (ipmbi2cTargetFd > 0)
    {
        i2cTargetDescriptor.close();
        close(ipmbi2cTargetFd);
        ipmbi2cTargetFd = 0;
    }

    // disable old I2C target 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>(
            "ipmbChannelUpdateTargetAddress: error opening deviceFile to delete "
            "sysfs");
        return -1;
    }
    deviceFile << para;
    deviceFile.close();

    // enable new I2C target 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 + (newBmcTargetAddr >> 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>(
            "ipmbChannelUpdateTargetAddress: error opening deviceFile to create "
            "sysfs");
        return -1;
    }
    deviceFile << para;
    deviceFile.close();

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

    // start to receive i2c data as target
    i2cTargetDescriptor.assign(ipmbi2cTargetFd);
    i2cTargetDescriptor.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();
        });

    ipmbBmcTargetAddress = newBmcTargetAddr;

    return 0;
}

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

uint8_t IpmbChannel::getBmcTargetAddress()
{
    return ipmbBmcTargetAddress;
}

uint8_t IpmbChannel::getRqTargetAddress()
{
    return ipmbRqTargetAddress;
}

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{};
    if (request->ipmbToi2cConstruct(buffer) != 0)
    {
        makeRequestInvalid(*request);
        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(i2cTargetDescriptor,
                                     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& targetPath = 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(targetPath.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 bmcTargetAddress = channel->getBmcTargetAddress();
        uint8_t rqTargetAddress = channel->getRqTargetAddress();

        // construct the request to add it to outstanding request list
        std::shared_ptr<IpmbRequest> request = std::make_shared<IpmbRequest>(
            rqTargetAddress, netfn, ipmbRsLun, bmcTargetAddress, 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 addUpdateTargetAddrHandler()
{
    // callback to handle dbus signal of updating target addr
    std::function<void(sdbusplus::message_t&)> updateTargetAddrHandler =
        [](sdbusplus::message_t& message) {
            uint8_t reqChannel, busId, targetAddr;

            // 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>(
                    "addUpdateTargetAddrHandler: invalid obj path");
                return;
            }

            message.read(reqChannel, busId, targetAddr);

            IpmbChannel* channel = getChannel(reqChannel);

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

            channel->ipmbChannelUpdateTargetAddress(targetAddr);
        };

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

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 bmcTargetAddress = channel->getBmcTargetAddress();
            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,
                                              bmcTargetAddress, 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()
{
    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;
    }

    addUpdateTargetAddrHandler();

    addSendBroadcastHandler();

    io.run();
    return 0;
}
