Make use of new IPMI method call API

tested: checked communication by injecting I2C traffic via aardvark,
everything is working fine
aardvark<->I2C<->IPMB<->IPMI

Change-Id: Ie2a982e710473cfa594838328730b98affc2cb39
Signed-off-by: Dawid Frycki <dawid.frycki@intel.com>
diff --git a/ipmbbridged.cpp b/ipmbbridged.cpp
index b37c867..2018e28 100644
--- a/ipmbbridged.cpp
+++ b/ipmbbridged.cpp
@@ -34,7 +34,6 @@
  */
 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 *hostIpmiIntf = "org.openbmc.HostIpmi";
 static constexpr const char *ipmbDbusIntf = "org.openbmc.Ipmb";
 
 boost::asio::io_service io;
@@ -55,7 +54,7 @@
 
 IpmbRequest::IpmbRequest(uint8_t address, uint8_t netFn, uint8_t rsLun,
                          uint8_t rqSA, uint8_t seq, uint8_t rqLun, uint8_t cmd,
-                         std::vector<uint8_t> &inputData) :
+                         const std::vector<uint8_t> &inputData) :
     address(address),
     netFn(netFn), rsLun(rsLun), rqSA(rqSA), seq(seq), rqLun(rqLun), cmd(cmd),
     timer(io)
@@ -69,14 +68,6 @@
     }
 }
 
-void IpmbRequest::incomingMessageHandler()
-{
-    sdbusplus::message::message mesg =
-        conn->new_signal(ipmbObj, hostIpmiIntf, "ReceivedMessage");
-    mesg.append(seq, netFn, rsLun, cmd, data);
-    mesg.signal_send();
-}
-
 void IpmbRequest::i2cToIpmbConstruct(IPMB_HEADER *ipmbBuffer,
                                      size_t bufferLength)
 {
@@ -152,14 +143,6 @@
                            std::vector<uint8_t>(0));
 }
 
-// TODO w/a to differentiate channel origin of incoming IPMI response: saving
-// channel number at two oldest unused bits of seq
-void IpmbRequest::addChannelToSeq(const ipmbChannelType &channelType)
-{
-    uint8_t newSeq = (seq | ((static_cast<uint8_t>(channelType) & 0x3) << 6));
-    seq = newSeq;
-}
-
 /**
  * @brief Ipmb response class methods
  */
@@ -171,7 +154,7 @@
 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) :
+                           const std::vector<uint8_t> &inputData) :
     address(address),
     netFn(netFn), rqLun(rqLun), rsSA(rsSA), seq(seq), rsLun(rsLun), cmd(cmd),
     completionCode(completionCode)
@@ -206,18 +189,20 @@
     }
 }
 
-int IpmbResponse::ipmbToi2cConstruct(std::vector<uint8_t> &buffer)
+std::shared_ptr<std::vector<uint8_t>> IpmbResponse::ipmbToi2cConstruct()
 {
     size_t bufferLength = data.size() + ipmbResponseDataHeaderLength +
                           ipmbConnectionHeaderLength + ipmbChecksumSize;
 
     if (bufferLength > ipmbMaxFrameLength)
     {
-        return -1;
+        return nullptr;
     }
 
-    buffer.resize(bufferLength);
-    auto ipmbBuffer = reinterpret_cast<IPMB_HEADER *>(buffer.data());
+    std::shared_ptr<std::vector<uint8_t>> buffer =
+        std::make_shared<std::vector<uint8_t>>(bufferLength);
+
+    auto ipmbBuffer = reinterpret_cast<IPMB_HEADER *>(buffer->data());
 
     ipmbBuffer->Header.Resp.address = address;
     ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun);
@@ -227,18 +212,18 @@
     ipmbBuffer->Header.Resp.completionCode = completionCode;
 
     ipmbBuffer->Header.Resp.checksum1 = ipmbChecksumCompute(
-        buffer.data(), ipmbConnectionHeaderLength - ipmbChecksumSize);
+        buffer->data(), ipmbConnectionHeaderLength - ipmbChecksumSize);
 
     if (data.size() > 0)
     {
         std::copy(data.begin(), data.end(), ipmbBuffer->Header.Resp.data);
     }
 
-    buffer[bufferLength - ipmbChecksumSize] =
-        ipmbChecksumCompute(buffer.data() + ipmbChecksum2StartOffset,
+    (*buffer)[bufferLength - ipmbChecksumSize] =
+        ipmbChecksumCompute(buffer->data() + ipmbChecksum2StartOffset,
                             (ipmbResponseDataHeaderLength + data.size()));
 
-    return 0;
+    return buffer;
 }
 
 bool IpmbCommandFilter::isBlocked(const uint8_t reqNetFn, const uint8_t cmd)
@@ -274,7 +259,7 @@
         i2cMasterSocket,
         boost::asio::buffer(buffer->data() + ipmbAddressSize,
                             buffer->size() - ipmbAddressSize),
-        [this, buffer, retriesAttempted](const boost::system::error_code ec,
+        [this, buffer, retriesAttempted](const boost::system::error_code &ec,
                                          size_t bytesSent) {
             if (ec)
             {
@@ -394,18 +379,15 @@
                 uint8_t seq = ipmbSeqGet(ipmbFrame->Header.Req.rqSeqLUN);
                 uint8_t lun =
                     ipmbLunFromSeqLunGet(ipmbFrame->Header.Req.rqSeqLUN);
-                std::vector<uint8_t> data;
 
                 // prepare generic response
                 auto ipmbResponse =
                     IpmbResponse(ipmbRqSlaveAddress, ipmbRespNetFn(netFn), lun,
                                  ipmbBmcSlaveAddress, seq, ipmbRsLun, cmd,
-                                 ipmbIpmiInvalidCommand, data);
+                                 ipmbIpmiInvalidCmd, {});
 
-                std::shared_ptr<std::vector<uint8_t>> buffer =
-                    std::make_shared<std::vector<uint8_t>>();
-
-                if (ipmbResponse.ipmbToi2cConstruct(*buffer) == 0)
+                auto buffer = ipmbResponse.ipmbToi2cConstruct();
+                if (buffer)
                 {
                     ipmbResponseSend(buffer);
                 }
@@ -415,15 +397,79 @@
         }
 
         auto ipmbMessageReceived = IpmbRequest();
-
         ipmbMessageReceived.i2cToIpmbConstruct(ipmbFrame, r);
 
-        // TODO w/a to differentiate channel origin of incoming IPMI
-        // response: extracting channel number from seq
-        ipmbMessageReceived.addChannelToSeq(getChannelType());
+        std::map<std::string, std::variant<int>> options{
+            {"rqSA", ipmbAddressTo7BitSet(ipmbRqSlaveAddress)}};
+        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}](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;
+                }
 
-        // send request to the client
-        ipmbMessageReceived.incomingMessageHandler();
+                uint8_t rqSlaveAddress = getRqSlaveAddress();
+                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(
+                        rqSlaveAddress, netfn, rqLun, bmcSlaveAddress, seq,
+                        ipmbRsLun, cmd, ipmbIpmiCmdRespNotProvided, {});
+
+                    auto buffer = ipmbResponse.ipmbToi2cConstruct();
+                    if (buffer)
+                    {
+                        ipmbResponseSend(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(rqSlaveAddress, 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;
+                }
+
+                ipmbResponseSend(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:
@@ -656,62 +702,6 @@
     return 0;
 }
 
-/**
- * @brief Dbus callbacks
- */
-auto ipmbSendMessage = [](uint8_t seq, uint8_t netfn, uint8_t lun, uint8_t cmd,
-                          uint8_t cc, std::vector<uint8_t> &dataReceived) {
-    int64_t status = -1;
-    std::shared_ptr<std::vector<uint8_t>> buffer =
-        std::make_shared<std::vector<uint8_t>>();
-
-    if (dataReceived.size() > ipmbMaxDataSize)
-    {
-        return status;
-    }
-
-    if (netfn & ipmbNetFnResponseMask)
-    {
-        IpmbChannel *channel = getChannel(getChannelFromSeq(seq));
-        if (channel == nullptr)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "ipmbSendMessage: channel does not exist");
-            return status;
-        }
-
-        // if command is not supported, add it to filter
-        if (cc == ipmbIpmiInvalidCommand)
-        {
-            channel->addFilter(ipmbReqNetFnFromRespNetFn(netfn), cmd);
-        }
-
-        uint8_t rqSlaveAddress = channel->getRqSlaveAddress();
-        uint8_t bmcSlaveAddress = channel->getBmcSlaveAddress();
-
-        // response received
-        // dataReceived is empty after constructor invocation
-        std::unique_ptr<IpmbResponse> ipmbMessageReceived =
-            std::make_unique<IpmbResponse>(rqSlaveAddress, netfn, lun,
-                                           bmcSlaveAddress, seq, lun, cmd, cc,
-                                           dataReceived);
-
-        status = ipmbMessageReceived->ipmbToi2cConstruct(*buffer);
-        if (status != 0)
-        {
-            return status;
-        }
-
-        channel->ipmbResponseSend(buffer);
-        return status;
-    }
-
-    // we are not expecting request here
-    phosphor::logging::log<phosphor::logging::level::ERR>(
-        "ipmbSendMessage: got a request");
-    return status;
-};
-
 auto ipmbHandleRequest = [](boost::asio::yield_context yield,
                             uint8_t reqChannel, uint8_t netfn, uint8_t lun,
                             uint8_t cmd, std::vector<uint8_t> dataReceived) {
@@ -760,14 +750,10 @@
 
     auto server = sdbusplus::asio::object_server(conn);
 
-    std::shared_ptr<sdbusplus::asio::dbus_interface> ipmiIface =
-        server.add_interface(ipmbObj, hostIpmiIntf);
     std::shared_ptr<sdbusplus::asio::dbus_interface> ipmbIface =
         server.add_interface(ipmbObj, ipmbDbusIntf);
 
-    ipmiIface->register_method("sendMessage", std::move(ipmbSendMessage));
     ipmbIface->register_method("sendRequest", std::move(ipmbHandleRequest));
-    ipmiIface->initialize();
     ipmbIface->initialize();
 
     if (initializeChannels() < 0)
diff --git a/ipmbbridged.hpp b/ipmbbridged.hpp
index 317fdab..4d24790 100644
--- a/ipmbbridged.hpp
+++ b/ipmbbridged.hpp
@@ -145,13 +145,6 @@
     me = 1
 };
 
-// TODO w/a to differentiate channel origin of incoming IPMI response:
-// extracting channel number from 2 oldest bits of seq
-constexpr ipmbChannelType getChannelFromSeq(const uint8_t &seq)
-{
-    return static_cast<ipmbChannelType>((seq & 0xC0) >> 6);
-}
-
 /**
  * @brief IpmbResponse declaration
  */
@@ -171,11 +164,11 @@
 
     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);
+                 uint8_t completionCode, const std::vector<uint8_t> &inputData);
 
     void i2cToIpmbConstruct(IPMB_HEADER *ipmbBuffer, size_t bufferLength);
 
-    int ipmbToi2cConstruct(std::vector<uint8_t> &buffer);
+    std::shared_ptr<std::vector<uint8_t>> ipmbToi2cConstruct();
 };
 
 /**
@@ -202,13 +195,11 @@
 
     IpmbRequest(uint8_t address, uint8_t netFn, uint8_t rsLun, uint8_t rqSA,
                 uint8_t seq, uint8_t rqLun, uint8_t cmd,
-                std::vector<uint8_t> &inputData);
+                const std::vector<uint8_t> &inputData);
 
     IpmbRequest(const IpmbRequest &) = delete;
     IpmbRequest &operator=(IpmbRequest const &) = delete;
 
-    void incomingMessageHandler();
-
     std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
         returnMatchedResponse();
 
@@ -218,10 +209,6 @@
     void i2cToIpmbConstruct(IPMB_HEADER *ipmbBuffer, size_t bufferLength);
 
     int ipmbToi2cConstruct(std::vector<uint8_t> &buffer);
-
-    // TODO w/a to differentiate channel origin of incoming IPMI response:
-    // saving channel number at two oldest unused bits of seq
-    void addChannelToSeq(const ipmbChannelType &channelType);
 };
 
 /**
@@ -247,7 +234,8 @@
  * @brief Command filtering defines
  */
 
-constexpr uint8_t ipmbIpmiInvalidCommand = 0xC1;
+constexpr uint8_t ipmbIpmiInvalidCmd = 0xC1;
+constexpr uint8_t ipmbIpmiCmdRespNotProvided = 0xCE;
 
 constexpr uint8_t ipmbReqNetFnFromRespNetFn(uint8_t reqNetFn)
 {