diff options
Diffstat (limited to 'chassishandler.cpp')
-rw-r--r-- | chassishandler.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/chassishandler.cpp b/chassishandler.cpp index 6002e7a..bfc079d 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -775,6 +775,10 @@ std::map<DbusValue, IpmiValue> dbusToIpmi = { {RestorePolicy::Policy::Restore, 0x01}, {RestorePolicy::Policy::AlwaysOn, 0x02}}; +static constexpr uint8_t noChange = 0x03; +static constexpr uint8_t allSupport = 0x01 | 0x02 | 0x04; +static constexpr uint8_t policyBitMask = 0x07; +static constexpr uint8_t setPolicyReqLen = 1; } // namespace power_policy //---------------------------------------------------------------------- @@ -1616,6 +1620,88 @@ ipmi_ret_t ipmiGetPOHCounter(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return rc; } +ipmi_ret_t ipmi_chassis_set_power_restore_policy( + ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, + ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) +{ + auto* reqptr = reinterpret_cast<uint8_t*>(request); + auto* resptr = reinterpret_cast<uint8_t*>(response); + uint8_t reqPolicy = 0; + + power_policy::DbusValue value = + power_policy::RestorePolicy::Policy::AlwaysOff; + + if (*data_len != power_policy::setPolicyReqLen) + { + phosphor::logging::log<level::ERR>("Unsupported request length", + entry("LEN=0x%x", *data_len)); + *data_len = 0; + return IPMI_CC_REQ_DATA_LEN_INVALID; + } + + reqPolicy = *reqptr & power_policy::policyBitMask; + if (reqPolicy > power_policy::noChange) + { + phosphor::logging::log<level::ERR>("Reserved request parameter", + entry("REQ=0x%x", reqPolicy)); + *data_len = 0; + return IPMI_CC_PARM_NOT_SUPPORTED; + } + + if (reqPolicy == power_policy::noChange) + { + // just return the supported policy + *resptr = power_policy::allSupport; + *data_len = power_policy::setPolicyReqLen; + return IPMI_CC_OK; + } + + for (auto const& it : power_policy::dbusToIpmi) + { + if (it.second == reqPolicy) + { + value = it.first; + break; + } + } + + try + { + const settings::Path& powerRestoreSetting = + chassis::internal::cache::objects.map + .at(chassis::internal::powerRestoreIntf) + .front(); + sdbusplus::message::variant<std::string> property = + convertForMessage(value); + + auto method = chassis::internal::dbus.new_method_call( + chassis::internal::cache::objects + .service(powerRestoreSetting, + chassis::internal::powerRestoreIntf) + .c_str(), + powerRestoreSetting.c_str(), ipmi::PROP_INTF, "Set"); + + method.append(chassis::internal::powerRestoreIntf, "PowerRestorePolicy", + property); + auto reply = chassis::internal::dbus.call(method); + if (reply.is_method_error()) + { + phosphor::logging::log<level::ERR>("Unspecified Error"); + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + } + catch (InternalFailure& e) + { + report<InternalFailure>(); + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + + *data_len = power_policy::setPolicyReqLen; + return IPMI_CC_OK; +} + void register_netfn_chassis_functions() { createIdentifyTimer(); @@ -1652,4 +1738,9 @@ void register_netfn_chassis_functions() // <Get POH Counter> ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_POH_COUNTER, NULL, ipmiGetPOHCounter, PRIVILEGE_USER); + + // <Set Power Restore Policy> + ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_RESTORE_POLICY, NULL, + ipmi_chassis_set_power_restore_policy, + PRIVILEGE_OPERATOR); } |