responder: add state effecter for system power off
Add a handler to respond to a set effecter meant to request the BMC to
turn the system power off.
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Change-Id: I03c974cd34a18c84a7a9bd81412cc1844b195694
diff --git a/libpldm/states.h b/libpldm/states.h
index a64a7ae..ca20acd 100644
--- a/libpldm/states.h
+++ b/libpldm/states.h
@@ -11,6 +11,7 @@
*/
enum pldm_state_set_ids {
PLDM_BOOT_PROGRESS_STATE = 196,
+ PLDM_SYSTEM_POWER_STATE = 260,
};
/** @brief PLDM enums for the boot progress state set
@@ -20,6 +21,12 @@
PLDM_BOOT_COMPLETED = 2,
};
+/** @brief PLDM enums for system power states
+ */
+enum pldm_system_power_states {
+ PLDM_OFF_SOFT_GRACEFUL = 9,
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index 9db93ce..ec168f4 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -72,7 +72,9 @@
{PLDM_BOOT_COMPLETED,
"xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
"BootComplete"s}}},
- };
+ {PLDM_SYSTEM_POWER_STATE,
+ {{PLDM_OFF_SOFT_GRACEFUL,
+ "xyz.openbmc_project.State.Chassis.Transition.Off"s}}}};
using namespace phosphor::logging;
using namespace pldm::responder::pdr;
using namespace pldm::responder::effecter::dbus_mapping;
@@ -168,6 +170,50 @@
return PLDM_ERROR;
}
return PLDM_SUCCESS;
+ }},
+ {PLDM_SYSTEM_POWER_STATE,
+ [&](const std::string& objPath, const uint8_t currState) {
+ auto stateSet =
+ stateNumToDbusProp.find(PLDM_SYSTEM_POWER_STATE);
+ if (stateSet == stateNumToDbusProp.end())
+ {
+ log<level::ERR>("Couldn't find D-Bus mapping for "
+ "PLDM_SYSTEM_POWER_STATE",
+ entry("EFFECTER_ID=%d", effecterId));
+ return PLDM_ERROR;
+ }
+ auto iter = stateSet->second.find(
+ stateField[currState].effecter_state);
+ if (iter == stateSet->second.end())
+ {
+ log<level::ERR>(
+ "Invalid state field passed or field not "
+ "found for PLDM_SYSTEM_POWER_STATE",
+ entry("EFFECTER_ID=%d", effecterId),
+ entry("FIELD=%d",
+ stateField[currState].effecter_state),
+ entry("OBJECT_PATH=%s", objPath.c_str()));
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ auto dbusProp = "RequestedPowerTransition";
+ std::variant<std::string> value{
+ std::get<std::string>(iter->second)};
+ auto dbusInterface = "xyz.openbmc_project.State.Chassis";
+ try
+ {
+ dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
+ dbusInterface, value);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Error setting property",
+ entry("ERROR=%s", e.what()),
+ entry("PROPERTY=%s", dbusProp),
+ entry("INTERFACE=%s", dbusInterface),
+ entry("PATH=%s", objPath.c_str()));
+ return PLDM_ERROR;
+ }
+ return PLDM_SUCCESS;
}}};
int rc = PLDM_SUCCESS;