fb-ipmi-oem: yosemitev2: Add Ipmi implementation for read post codes

Added implementation to handle read post code BIC request from host to BMC and
send the response back to host.

TESTED : Built Facebook YosemiteV2 images and loaded on the target hardware.
Verified all the host's postcodes in BMC.

Signed-off-by: Kumar Thangavel <thangavel.k@hcl.com>
Change-Id: Iee9a224b381db5ab9e244b9ae2999a602e520a36
diff --git a/include/biccommands.hpp b/include/biccommands.hpp
index 6613a54..5493304 100644
--- a/include/biccommands.hpp
+++ b/include/biccommands.hpp
@@ -1,3 +1,10 @@
 
 // Command for getting device id
 constexpr uint8_t cmdOemBicInfo = 0x01;
+
+// Command for getting post code
+constexpr uint8_t cmdOemSendPostBufferToBMC = 0x08;
+
+const char* dbusObj = "/xyz/openbmc_project/state/boot/raw";
+
+const char* dbusService = "xyz.openbmc_project.State.Boot.Raw";
diff --git a/src/biccommands.cpp b/src/biccommands.cpp
index 4c6ea4e..1dc907d 100644
--- a/src/biccommands.cpp
+++ b/src/biccommands.cpp
@@ -23,6 +23,7 @@
 #include <phosphor-logging/log.hpp>
 
 #include <vector>
+#include <variant>
 #include <iostream>
 
 namespace ipmi
@@ -65,6 +66,51 @@
                                  res->cc, res->payload);
 }
 
+//----------------------------------------------------------------------
+// ipmiOemPostCodeHandler (CMD_OEM_BIC_POST_BUFFER_INFO)
+// This Function will handle BIC incomming postcode from multi-host for
+// netfn=0x38 and cmd=0x08 send the response back to the sender.
+//----------------------------------------------------------------------
+
+ipmi::RspType<std::array<uint8_t, 3>, uint8_t>
+    ipmiOemPostCodeHandler(ipmi::Context::ptr ctx, std::array<uint8_t, 3> iana,
+                           uint8_t interface, uint8_t data)
+{
+    // creating bus connection
+    auto conn = getSdBus();
+
+    try
+    {
+        // storing post code as varaint
+        std::variant<uint64_t> postCode = static_cast<uint64_t>(data);
+
+        // creating dbus objects for 1 to N process
+        std::string dbusObjStr = dbusObj + std::to_string((ctx->hostIdx + 1));
+
+        // creating method call to update postd value
+        auto method = conn->new_method_call(
+            "xyz.openbmc_project.State.Boot.Raw", dbusObjStr.c_str(),
+            "org.freedesktop.DBus.Properties", "Set");
+
+        // Adding paramters to method call
+        method.append(dbusService, "Value", postCode);
+
+        // Invoke method call function
+        auto reply = conn->call(method);
+
+        // sending the success response with headers
+        return ipmi::responseSuccess(iana, interface);
+    }
+    catch (std::exception& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "post code handler error\n");
+
+        // sending the Error response
+        return ipmi::responseResponseError();
+    }
+}
+
 static void registerBICFunctions(void)
 {
 
@@ -74,6 +120,9 @@
     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
                           cmdOemBicInfo, ipmi::Privilege::User,
                           ipmiOemBicHandler);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
+                          cmdOemSendPostBufferToBMC, ipmi::Privilege::User,
+                          ipmiOemPostCodeHandler);
     return;
 }