LeakGPIODetector: cover the deassert case

Extend the service targets to handle the de-assert case for both warning
and critical levels.

Tested:

Error inject the leak to assert then back to deassert.
```
<7> Updating detector RackDripPan state to xyz.openbmc_project.State.Leak.Detector.DetectorState.Abnormal
<3> OPENBMC_MESSAGE_ID={"xyz.openbmc_project.State.Leak.Detector.LeakDetectedCritical":{"DETECTOR_NAME":"/xyz/openbmc_project/state/leak/detector/RackDripPan","_SOURCE":{"COLUMN":75,"FILE":"/usr/src/debug/dbus-sensors/0.1+git/src/leakdetector/LeakEvents.cpp","FUNCTION":"void leak::Events::generateLeakEvent(leak::Events::generateLeakEvent(sdbusplus::message::object_path, sdbusplus::common::xyz::openbmc_project::state::leak::Detector::DetectorState, leak::config::DetectorLevel)::_ZN4leak6Events17generateLeakEventEN9sdbusplus7message7details19string_path_wrapperENS1_6common3xyz15openbmc_project5state4leak8Detector13DetectorStateENS_6config13DetectorLevelE.Frame*)","LINE":51,"PID":1207}}}
<3> Critical leak detected for /xyz/openbmc_project/state/leak/detector/RackDripPan
<7> Starting systemd target xyz.openbmc_project.leakdetector.critical.assert@RackDripPan.service
<7> Started xyz.openbmc_project.leakdetector.critical.assert@RackDripPan.service with /org/freedesktop/systemd1/job/37428
<7> Updating detector RackDripPan state to xyz.openbmc_project.State.Leak.Detector.DetectorState.Normal
<3> OPENBMC_MESSAGE_ID={"xyz.openbmc_project.State.Leak.Detector.LeakDetectedNormal":{"DETECTOR_NAME":"/xyz/openbmc_project/state/leak/detector/RackDripPan","_SOURCE":{"COLUMN":78,"FILE":"/usr/src/debug/dbus-sensors/0.1+git/src/leakdetector/LeakEvents.cpp","FUNCTION":"void leak::Events::generateLeakEvent(leak::Events::generateLeakEvent(sdbusplus::message::object_path, sdbusplus::common::xyz::openbmc_project::state::leak::Detector::DetectorState, leak::config::DetectorLevel)::_ZN4leak6Events17generateLeakEventEN9sdbusplus7message7details19string_path_wrapperENS1_6common3xyz15openbmc_project5state4leak8Detector13DetectorStateENS_6config13DetectorLevelE.Frame*)","LINE":36,"PID":1207}}}
<7> Starting systemd target xyz.openbmc_project.leakdetector.critical.deassert@RackDripPan.service
<7> Started xyz.openbmc_project.leakdetector.critical.deassert@RackDripPan.service with /org/freedesktop/systemd1/job/37806

```

Change-Id: Ie0f24a510ee864244afbb078bdceebbf3b316e8c
Signed-off-by: Yang Chen <yang.chen@quantatw.com>
diff --git a/src/leakdetector/LeakGPIODetector.cpp b/src/leakdetector/LeakGPIODetector.cpp
index f21d1b5..aedffa1 100644
--- a/src/leakdetector/LeakGPIODetector.cpp
+++ b/src/leakdetector/LeakGPIODetector.cpp
@@ -10,7 +10,7 @@
 #include <functional>
 #include <string>
 #include <string_view>
-#include <utility>
+#include <tuple>
 
 namespace leak
 {
@@ -19,13 +19,17 @@
 {
 
 /** @brief Leak level to systemd target service map */
-static constexpr std::array<std::pair<config::DetectorLevel, std::string_view>,
-                            2>
-    leakActionTargets = {{{config::DetectorLevel::warning,
-                           "xyz.openbmc_project.leakdetector.warning@"},
-                          {config::DetectorLevel::critical,
-                           "xyz.openbmc_project.leakdetector.critical@"}}};
-
+static constexpr std::array<
+    std::tuple<config::DetectorLevel, std::string_view, std::string_view>, 4>
+    leakActionTargets = {
+        {{config::DetectorLevel::warning, "assert",
+          "xyz.openbmc_project.leakdetector.warning.assert@"},
+         {config::DetectorLevel::warning, "deassert",
+          "xyz.openbmc_project.leakdetector.warning.deassert@"},
+         {config::DetectorLevel::critical, "assert",
+          "xyz.openbmc_project.leakdetector.critical.assert@"},
+         {config::DetectorLevel::critical, "deassert",
+          "xyz.openbmc_project.leakdetector.critical.deassert@"}}};
 } // namespace config
 
 static auto getObjectPath(const std::string& detectorName)
@@ -67,18 +71,20 @@
 
         co_await leakEvents.generateLeakEvent(getObjectPath(config.name),
                                               state_, config.level);
-        if (state_ != DetectorIntf::DetectorState::Normal)
+        std::string action = (state_ == DetectorIntf::DetectorState::Normal)
+                                 ? "deassert"
+                                 : "assert";
+
+        for (const auto& [level, action_str, serviceSuffix] :
+             config::leakActionTargets)
         {
-            for (const auto& [level, serviceSuffix] : config::leakActionTargets)
+            if (config.level == level && action_str == action)
             {
-                if (config.level == level)
-                {
-                    auto target = std::string(serviceSuffix) + config.name +
-                                  ".service";
-                    debug("Starting systemd target {TARGET}", "TARGET", target);
-                    co_await systemd::SystemdInterface::startUnit(ctx, target);
-                    break;
-                }
+                auto target = std::string(serviceSuffix) + config.name +
+                              ".service";
+                debug("Starting systemd target {TARGET}", "TARGET", target);
+                co_await systemd::SystemdInterface::startUnit(ctx, target);
+                break;
             }
         }
     }