host_monitor_app: Restrict the criteria of adding S0/S5 checkpoints

Only the 2 cases below will be considered to add S0/S5 checkpoints.

- S0: `Off`->`Running`
- S5: `Running`->`Off`

Tested:
```
boot-time-monitor[259]: [powerMatcher] CurrentHostState has changed from xyz.openbmc_project.State.Host.HostState.Running to xyz.openbmc_project.State.Host.HostState.Off
...
boot-time-monitor[259]: [powerMatcher] CurrentHostState has changed from xyz.openbmc_project.State.Host.HostState.Off to xyz.openbmc_project.State.Host.HostState.Running
```

Google-Bug-Id: 296787899
Google-Bug-Id: 296791279
Change-Id: I1542a85b1671008a4970c9e0e80af7d70aaceeed
Signed-off-by: Michael Shen <gpgpgp@google.com>
diff --git a/src/host_monitor_app.cpp b/src/host_monitor_app.cpp
index f76e92d..9440c12 100644
--- a/src/host_monitor_app.cpp
+++ b/src/host_monitor_app.cpp
@@ -19,6 +19,11 @@
 namespace boot_time_monitor
 {
 
+using BasicVariantType =
+    std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
+                 double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;
+
+constexpr std::string_view kHostService = "xyz.openbmc_project.State.Host";
 constexpr std::string_view kHostPath = "/xyz/openbmc_project/state/host0";
 constexpr std::string_view kHostIface = "xyz.openbmc_project.State.Host";
 constexpr std::string_view kHostProperty = "CurrentHostState";
@@ -39,6 +44,26 @@
     bootManager = std::make_shared<BootManager>(util, cpCSV, durCSV);
     dbusHandler = std::make_shared<DbusHandler>(bus, kObjPath.data(),
                                                 bootManager, util);
+    // Initialize preHostState
+    static std::string preHostState;
+    auto method = bus.new_method_call(kHostService.data(), kHostPath.data(),
+                                      "org.freedesktop.DBus.Properties", "Get");
+    method.append(kHostIface.data(), kHostProperty.data());
+    BasicVariantType result;
+    try
+    {
+        bus.call(method).read(result);
+        preHostState = std::get<std::string>(result);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        fmt::print(stderr, "[{}] Failed to get `CurrentHostState`. ERROR={}\n",
+                   __FUNCTION__, e.what());
+        fmt::print(
+            stderr,
+            "[{}] Initialized `preHostState` to empty string as default value\n",
+            __FUNCTION__);
+    }
 
     powerMatcher = std::make_unique<sdbusplus::bus::match::match>(
         bus,
@@ -58,14 +83,23 @@
         auto findState = values.find(kHostProperty.data());
         if (findState != values.end())
         {
-            if (std::get<std::string>(findState->second) == kHostStateRunning)
+            const std::string curHostState =
+                std::get<std::string>(findState->second);
+            fmt::print(
+                stderr,
+                "[powerMatcher] CurrentHostState has changed from {} to {}\n",
+                preHostState, curHostState);
+            if (preHostState == kHostStateOff &&
+                curHostState == kHostStateRunning)
             {
                 bootManager->setCheckpoint(kS0.data(), 0, 0);
             }
-            else if (std::get<std::string>(findState->second) == kHostStateOff)
+            else if (preHostState == kHostStateRunning &&
+                     curHostState == kHostStateOff)
             {
                 bootManager->setCheckpoint(kS5.data(), 0, 0);
             }
+            preHostState = curHostState;
         }
         });
 }