oem-ibm: Setting the slot power state to Off

The commit sets the slot power state to off when the
host powers off. The host only powers on the slots and
the BMC needs to turn all the slots off when the host powers off.

Tested by powering off and using busctl commands to verify the
power state.

Change-Id: I3eb531105ea58e06d0dc5ffdf35491e2e0c63b2e
Signed-off-by: Pavithra Barithaya <pavithrabarithaya07@gmail.com>
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index 319d1f7..7b73242 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -93,6 +93,54 @@
                 }
             }
         });
+
+        powerStateOffMatch = std::make_unique<sdbusplus::bus::match::match>(
+            pldm::utils::DBusHandler::getBus(),
+            propertiesChanged("/xyz/openbmc_project/state/chassis0",
+                              "xyz.openbmc_project.State.Chassis"),
+            [this](sdbusplus::message_t& msg) {
+            pldm::utils::DbusChangedProps props{};
+            std::string intf;
+            msg.read(intf, props);
+            const auto itr = props.find("CurrentPowerState");
+            if (itr != props.end())
+            {
+                pldm::utils::PropertyValue value = itr->second;
+                auto propVal = std::get<std::string>(value);
+                if (propVal ==
+                    "xyz.openbmc_project.State.Chassis.PowerState.Off")
+                {
+                    static constexpr auto searchpath =
+                        "/xyz/openbmc_project/inventory/system/chassis/motherboard";
+                    int depth = 0;
+                    std::vector<std::string> powerInterface = {
+                        "xyz.openbmc_project.State.Decorator.PowerState"};
+                    pldm::utils::GetSubTreeResponse response =
+                        pldm::utils::DBusHandler().getSubtree(searchpath, depth,
+                                                              powerInterface);
+                    for (const auto& [objPath, serviceMap] : response)
+                    {
+                        pldm::utils::DBusMapping dbusMapping{
+                            objPath,
+                            "xyz.openbmc_project.State.Decorator.PowerState",
+                            "PowerState", "string"};
+                        value =
+                            "xyz.openbmc_project.State.Decorator.PowerState.State.Off";
+                        try
+                        {
+                            pldm::utils::DBusHandler().setDbusProperty(
+                                dbusMapping, value);
+                        }
+                        catch (const std::exception& e)
+                        {
+                            error(
+                                "Unable to set the slot power state to Off error - {ERROR}",
+                                "ERROR", e);
+                        }
+                    }
+                }
+            }
+        });
     }
 
     int getOemStateSensorReadingsHandler(
@@ -288,6 +336,9 @@
     /** @brief D-Bus property changed signal match */
     std::unique_ptr<sdbusplus::bus::match_t> hostOffMatch;
 
+    /** @brief D-Bus property changed signal match */
+    std::unique_ptr<sdbusplus::bus::match_t> powerStateOffMatch;
+
     /** @brief Timer used for monitoring surveillance pings from host */
     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;