diff --git a/src/bridgingcommands.cpp b/src/bridgingcommands.cpp
new file mode 100644
index 0000000..0c727f6
--- /dev/null
+++ b/src/bridgingcommands.cpp
@@ -0,0 +1,514 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// 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 <ipmid/api.h>
+
+#include <bridgingcommands.hpp>
+#include <cstring>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <vector>
+
+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 *ipmbIntf = "org.openbmc.Ipmb";
+
+static Bridging bridging;
+
+/**
+ * @brief utils for checksum
+ */
+static bool ipmbChecksumValidate(uint8_t *data, uint8_t length)
+{
+    if (data == nullptr)
+    {
+        return false;
+    }
+
+    uint8_t checksum = 0;
+
+    for (uint8_t idx = 0; idx < length; idx++)
+    {
+        checksum += data[idx];
+    }
+
+    if (0 == checksum)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+static uint8_t ipmbChecksumCompute(uint8_t *data, uint8_t length)
+{
+    if (data == nullptr)
+    {
+        return 0;
+    }
+
+    uint8_t checksum = 0;
+
+    for (uint8_t idx = 0; idx < length; idx++)
+    {
+        checksum += data[idx];
+    }
+
+    checksum = (~checksum) + 1;
+    return checksum;
+}
+
+static inline bool ipmbConnectionHeaderChecksumValidate(ipmbHeader *ipmbHeader)
+{
+    return ipmbChecksumValidate(reinterpret_cast<uint8_t *>(ipmbHeader),
+                                ipmbConnectionHeaderLength);
+}
+
+static inline bool ipmbDataChecksumValidate(ipmbHeader *ipmbHeader,
+                                            uint8_t length)
+{
+    return ipmbChecksumValidate(
+        (reinterpret_cast<uint8_t *>(ipmbHeader) + ipmbConnectionHeaderLength),
+        (length - ipmbConnectionHeaderLength));
+}
+
+static bool isFrameValid(ipmbHeader *frame, uint8_t length)
+{
+    if ((length < ipmbMinFrameLength) || (length > ipmbMaxFrameLength))
+    {
+        return false;
+    }
+
+    if (false == ipmbConnectionHeaderChecksumValidate(frame))
+    {
+        return false;
+    }
+
+    if (false == ipmbDataChecksumValidate(frame, length))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+IpmbRequest::IpmbRequest(const ipmbHeader *ipmbBuffer, size_t bufferLength)
+{
+    address = ipmbBuffer->Header.Req.address;
+    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]);
+    }
+}
+
+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,
+                           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::ipmbToi2cConstruct(uint8_t *buffer, size_t *bufferLength)
+{
+    ipmbHeader *ipmbBuffer = (ipmbHeader *)buffer;
+
+    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(
+        buffer, ipmbConnectionHeaderLength - ipmbChecksumSize);
+
+    if (data.size() > 0)
+    {
+        std::copy(
+            data.begin(), data.end(),
+            &buffer[ipmbConnectionHeaderLength + ipmbResponseDataHeaderLength]);
+    }
+
+    *bufferLength = data.size() + ipmbResponseDataHeaderLength +
+                    ipmbConnectionHeaderLength + ipmbChecksumSize;
+
+    buffer[*bufferLength - ipmbChecksumSize] =
+        ipmbChecksumCompute(&buffer[ipmbChecksum2StartOffset],
+                            (ipmbResponseDataHeaderLength + data.size()));
+}
+
+void IpmbRequest::prepareRequest(sdbusplus::message::message &mesg)
+{
+    mesg.append(ipmbMeChannelNum, netFn, rqLun, cmd, data);
+}
+
+Bridging::Bridging() : dbus(ipmid_get_sd_bus_connection())
+{
+}
+
+ipmi_return_codes Bridging::handleIpmbChannel(sSendMessageReq *sendMsgReq,
+                                              ipmi_response_t response,
+                                              ipmi_data_len_t dataLen)
+{
+    if ((*dataLen < (sizeof(sSendMessageReq) + ipmbMinFrameLength)) ||
+        (*dataLen > (sizeof(sSendMessageReq) + ipmbMaxFrameLength)))
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto sendMsgReqData = reinterpret_cast<ipmbHeader *>(sendMsgReq->data);
+
+    // TODO: check privilege lvl. Bridging to ME requires Administrator lvl
+
+    // allow bridging to ME only
+    if (sendMsgReqData->Header.Req.address != ipmbMeSlaveAddress)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "handleIpmbChannel, IPMB address invalid");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // check allowed modes
+    if (sendMsgReq->modeGet() != modeNoTracking &&
+        sendMsgReq->modeGet() != modeTrackRequest)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "handleIpmbChannel, mode not supported");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // check if request contains valid IPMB frame
+    if (!isFrameValid(sendMsgReqData, (*dataLen - sizeof(sSendMessageReq))))
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "handleIpmbChannel, IPMB frame invalid");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    auto ipmbRequest =
+        IpmbRequest(sendMsgReqData, (*dataLen - sizeof(sSendMessageReq)));
+
+    std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
+        ipmbResponse;
+
+    // send request to IPMB
+    try
+    {
+        auto mesg =
+            dbus.new_method_call(ipmbBus, ipmbObj, ipmbIntf, "sendRequest");
+        ipmbRequest.prepareRequest(mesg);
+        auto ret = dbus.call(mesg);
+        ret.read(ipmbResponse);
+    }
+    catch (sdbusplus::exception::SdBusError &e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "handleIpmbChannel, dbus call exception");
+        *dataLen = 0;
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    std::vector<uint8_t> dataReceived(0);
+    int status = -1;
+    uint8_t netFn = 0, lun = 0, cmd = 0, cc = 0;
+
+    std::tie(status, netFn, lun, cmd, cc, dataReceived) = ipmbResponse;
+
+    auto respReceived =
+        IpmbResponse(ipmbRequest.rqSA, netFn, lun, ipmbRequest.address,
+                     ipmbRequest.seq, lun, cmd, cc, dataReceived);
+
+    // check IPMB layer status
+    if (status)
+    {
+        phosphor::logging::log<phosphor::logging::level::WARNING>(
+            "handleIpmbChannel, ipmb returned non zero status");
+        *dataLen = 0;
+        return IPMI_CC_RESPONSE_ERROR;
+    }
+
+    auto sendMsgRes = reinterpret_cast<uint8_t *>(response);
+
+    switch (sendMsgReq->modeGet())
+    {
+        case modeNoTracking:
+            if (responseQueue.size() == responseQueueMaxSize)
+            {
+                *dataLen = 0;
+                return IPMI_CC_BUSY;
+            }
+            responseQueue.insert(responseQueue.end(), std::move(respReceived));
+            *dataLen = 0;
+            return IPMI_CC_OK;
+
+            break;
+        case modeTrackRequest:
+            respReceived.ipmbToi2cConstruct(sendMsgRes, dataLen);
+            return IPMI_CC_OK;
+
+            break;
+        default:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "handleIpmbChannel, mode not supported");
+            *dataLen = 0;
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    *dataLen = 0;
+    return IPMI_CC_UNSPECIFIED_ERROR;
+}
+
+ipmi_return_codes Bridging::sendMessageHandler(ipmi_request_t request,
+                                               ipmi_response_t response,
+                                               ipmi_data_len_t dataLen)
+{
+    ipmi_return_codes retCode = IPMI_CC_OK;
+
+    if (*dataLen < sizeof(sSendMessageReq))
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto sendMsgReq = reinterpret_cast<sSendMessageReq *>(request);
+
+    // check message fields:
+    // encryption not supported
+    if (sendMsgReq->encryptionGet() != 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "sendMessageHandler, encryption not supported");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    // authentication not supported
+    if (sendMsgReq->authenticationGet() != 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "sendMessageHandler, authentication not supported");
+        *dataLen = 0;
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    switch (sendMsgReq->channelNumGet())
+    {
+        // we only handle ipmb for now
+        case targetChannelIpmb:
+        case targetChannelOtherLan:
+            retCode = handleIpmbChannel(sendMsgReq, response, dataLen);
+            break;
+        // fall through to default
+        case targetChannelIcmb10:
+        case targetChannelIcmb09:
+        case targetChannelLan:
+        case targetChannelSerialModem:
+        case targetChannelPciSmbus:
+        case targetChannelSmbus10:
+        case targetChannelSmbus20:
+        case targetChannelSystemInterface:
+        default:
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "sendMessageHandler, TargetChannel invalid");
+            *dataLen = 0;
+            return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    return retCode;
+}
+
+ipmi_return_codes Bridging::getMessageHandler(ipmi_request_t request,
+                                              ipmi_response_t response,
+                                              ipmi_data_len_t dataLen)
+{
+    if (*dataLen != 0)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto getMsgRes = reinterpret_cast<sGetMessageRes *>(response);
+    auto getMsgResData = static_cast<uint8_t *>(getMsgRes->data);
+
+    std::memset(getMsgRes, 0, sizeof(sGetMessageRes));
+
+    auto respQueueItem = responseQueue.begin();
+
+    if (respQueueItem == responseQueue.end())
+    {
+        phosphor::logging::log<phosphor::logging::level::INFO>(
+            "getMessageHandler, no data available");
+        *dataLen = 0;
+        return ipmiGetMessageCmdDataNotAvailable;
+    }
+
+    // set message fields
+    getMsgRes->privilegeLvlSet(SYSTEM_INTERFACE);
+    getMsgRes->channelNumSet(targetChannelSystemInterface);
+
+    // construct response
+    respQueueItem->ipmbToi2cConstruct(getMsgResData, dataLen);
+    responseQueue.erase(respQueueItem);
+
+    *dataLen = *dataLen + sizeof(sGetMessageRes);
+    return IPMI_CC_OK;
+}
+
+ipmi_return_codes Bridging::getMessageFlagsHandler(ipmi_request_t request,
+                                                   ipmi_response_t response,
+                                                   ipmi_data_len_t dataLen)
+{
+    if (*dataLen != 0)
+    {
+        *dataLen = 0;
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto getMsgFlagsRes = reinterpret_cast<sGetMessageFlagsResp *>(response);
+
+    std::memset(getMsgFlagsRes, 0, sizeof(sGetMessageFlagsResp));
+
+    // preserve current (legacy) behaviour
+    getMsgFlagsRes->eventMessageBitSet(1);
+
+    // set message fields
+    if (responseQueue.size() > 0)
+    {
+        getMsgFlagsRes->receiveMessageBitSet(1);
+    }
+    else
+    {
+        getMsgFlagsRes->receiveMessageBitSet(0);
+    }
+
+    *dataLen = sizeof(sGetMessageFlagsResp);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_return_codes Bridging::clearMessageFlagsHandler(ipmi_request_t request,
+                                                     ipmi_response_t response,
+                                                     ipmi_data_len_t dataLen)
+{
+    if (*dataLen != sizeof(sClearMessageFlagsReq))
+    {
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    auto clearMsgFlagsReq = reinterpret_cast<sClearMessageFlagsReq *>(request);
+
+    if (clearMsgFlagsReq->receiveMessageBitGet() == 1)
+    {
+        responseQueue.clear();
+    }
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiAppSendMessage(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                              ipmi_request_t request, ipmi_response_t response,
+                              ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.sendMessageHandler(request, response, dataLen);
+
+    return retCode;
+}
+
+ipmi_ret_t ipmiAppGetMessage(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.getMessageHandler(request, response, dataLen);
+
+    return retCode;
+}
+
+ipmi_ret_t ipmiAppGetMessageFlags(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                                  ipmi_request_t request,
+                                  ipmi_response_t response,
+                                  ipmi_data_len_t dataLen,
+                                  ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.getMessageFlagsHandler(request, response, dataLen);
+
+    return retCode;
+}
+
+ipmi_ret_t ipmiAppClearMessageFlags(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+                                    ipmi_request_t request,
+                                    ipmi_response_t response,
+                                    ipmi_data_len_t dataLen,
+                                    ipmi_context_t context)
+{
+    ipmi_ret_t retCode = IPMI_CC_OK;
+    retCode = bridging.clearMessageFlagsHandler(request, response, dataLen);
+
+    *dataLen = 0;
+
+    return retCode;
+}
+
+static void register_bridging_functions() __attribute__((constructor));
+static void register_bridging_functions()
+{
+    ipmi_register_callback(
+        NETFUN_APP, Bridging::IpmiAppBridgingCmds::ipmiCmdClearMessageFlags,
+        NULL, ipmiAppClearMessageFlags, PRIVILEGE_USER);
+
+    ipmi_register_callback(
+        NETFUN_APP, Bridging::IpmiAppBridgingCmds::ipmiCmdGetMessageFlags, NULL,
+        ipmiAppGetMessageFlags, PRIVILEGE_USER);
+
+    ipmi_register_callback(NETFUN_APP,
+                           Bridging::IpmiAppBridgingCmds::ipmiCmdGetMessage,
+                           NULL, ipmiAppGetMessage, PRIVILEGE_USER);
+
+    ipmi_register_callback(NETFUN_APP,
+                           Bridging::IpmiAppBridgingCmds::ipmiCmdSendMessage,
+                           NULL, ipmiAppSendMessage, PRIVILEGE_USER);
+
+    return;
+}
