Implement Get Message Flags Command

Enable command that Get Message Flag can set right bit about
watchdog.

Tested:
Set watchdog timer
(Pre-timeout interrupt is Messaging, Initial Countdown is 2 second).
ipmitool raw 0x06 0x24 0x5 0x30 0x1 0x3e 0x14 0x00
Start watchdog timer.
ipmitool mc watchdog reset
After watchdog timer expired,
restart host and excute Get Message Flag Command.
ipmitool raw 0x06 0x31
Expect return "0x0b".

Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Change-Id: Ib545034edfd0087e45d6a97125495e365989d7d3
diff --git a/src/bridgingcommands.cpp b/src/bridgingcommands.cpp
index 9cc8879..88d29b4 100644
--- a/src/bridgingcommands.cpp
+++ b/src/bridgingcommands.cpp
@@ -14,15 +14,24 @@
 // limitations under the License.
 */
 
+#include <bitset>
 #include <bridgingcommands.hpp>
 #include <cstring>
 #include <ipmid/api.hpp>
+#include <ipmid/utils.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/bus/match.hpp>
 #include <sdbusplus/message.hpp>
 #include <vector>
 
+static constexpr const char *wdtService = "xyz.openbmc_project.Watchdog";
+static constexpr const char *wdtInterface =
+    "xyz.openbmc_project.State.Watchdog";
+static constexpr const char *wdtObjPath = "/xyz/openbmc_project/watchdog/host0";
+static constexpr const char *wdtInterruptFlagProp =
+    "PreTimeoutInterruptOccurFlag";
+
 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";
@@ -390,38 +399,6 @@
     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)
@@ -461,16 +438,50 @@
     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)
+std::size_t Bridging::getResponseQueueSize()
 {
-    ipmi_ret_t retCode = IPMI_CC_OK;
-    retCode = bridging.getMessageFlagsHandler(request, response, dataLen);
+    return responseQueue.size();
+}
 
-    return retCode;
+/**
+@brief This command is used to retrive present message available states.
+
+@return IPMI completion code plus Flags as response data on success.
+**/
+ipmi::RspType<std::bitset<8>> ipmiAppGetMessageFlags()
+{
+    std::bitset<8> getMsgFlagsRes;
+
+    getMsgFlagsRes.set(getMsgFlagEventMessageBit);
+
+    // set message fields
+    if (bridging.getResponseQueueSize() > 0)
+    {
+        getMsgFlagsRes.set(getMsgFlagReceiveMessageBit);
+    }
+    else
+    {
+        getMsgFlagsRes.reset(getMsgFlagReceiveMessageBit);
+    }
+
+    try
+    {
+        std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+        ipmi::Value variant = ipmi::getDbusProperty(
+            *dbus, wdtService, wdtObjPath, wdtInterface, wdtInterruptFlagProp);
+        if (std::get<bool>(variant))
+        {
+            getMsgFlagsRes.set(getMsgFlagWatchdogPreTimeOutBit);
+        }
+    }
+    catch (sdbusplus::exception::SdBusError &e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "ipmiAppGetMessageFlags, dbus call exception");
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess(getMsgFlagsRes);
 }
 
 ipmi_ret_t ipmiAppClearMessageFlags(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
@@ -494,9 +505,9 @@
         NETFUN_APP, Bridging::IpmiAppBridgingCmds::ipmiCmdClearMessageFlags,
         NULL, ipmiAppClearMessageFlags, PRIVILEGE_USER);
 
-    ipmi_register_callback(
-        NETFUN_APP, Bridging::IpmiAppBridgingCmds::ipmiCmdGetMessageFlags, NULL,
-        ipmiAppGetMessageFlags, PRIVILEGE_USER);
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetMessageFlags, ipmi::Privilege::User,
+                          ipmiAppGetMessageFlags);
 
     ipmi_register_callback(NETFUN_APP,
                            Bridging::IpmiAppBridgingCmds::ipmiCmdGetMessage,