summaryrefslogtreecommitdiffstats
path: root/chassishandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chassishandler.cpp')
-rw-r--r--chassishandler.cpp964
1 files changed, 537 insertions, 427 deletions
diff --git a/chassishandler.cpp b/chassishandler.cpp
index f8a93b0..6e1341c 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -2,8 +2,6 @@
#include "chassishandler.hpp"
-#include "settings.hpp"
-
#include <arpa/inet.h>
#include <endian.h>
#include <limits.h>
@@ -26,6 +24,7 @@
#include <sdbusplus/message/types.hpp>
#include <sdbusplus/server/object.hpp>
#include <sdbusplus/timer.hpp>
+#include <settings.hpp>
#include <sstream>
#include <string>
#include <xyz/openbmc_project/Common/error.hpp>
@@ -44,6 +43,8 @@
std::unique_ptr<phosphor::Timer> identifyTimer
__attribute__((init_priority(101)));
+static ChassisIDState chassisIDState = ChassisIDState::reserved;
+
constexpr size_t SIZE_MAC = 18;
constexpr size_t SIZE_BOOT_OPTION = (uint8_t)
BootOptionResponseSize::OPAL_NETWORK_SETTINGS; // Maximum size of the boot
@@ -100,33 +101,14 @@ const static constexpr char chassisSMDevAddrProp[] = "SMDeviceAddress";
const static constexpr char chassisBridgeDevAddrProp[] = "BridgeDeviceAddress";
static constexpr uint8_t chassisCapFlagMask = 0x0f;
static constexpr uint8_t chassisCapAddrMask = 0xfe;
-
-typedef struct
-{
- uint8_t cap_flags;
- uint8_t fru_info_dev_addr;
- uint8_t sdr_dev_addr;
- uint8_t sel_dev_addr;
- uint8_t system_management_dev_addr;
- uint8_t bridge_dev_addr;
-} __attribute__((packed)) ipmi_chassis_cap_t;
-
-typedef struct
-{
- uint8_t cur_power_state;
- uint8_t last_power_event;
- uint8_t misc_power_state;
- uint8_t front_panel_button_cap_status;
-} __attribute__((packed)) ipmi_get_chassis_status_t;
-
-/**
- * @struct Get POH counter command response data
- */
-struct GetPOHCountResponse
-{
- uint8_t minPerCount; ///< Minutes per count
- uint8_t counterReading[4]; ///< Counter reading
-} __attribute__((packed));
+static constexpr const char* powerButtonIntf =
+ "xyz.openbmc_project.Chassis.Buttons.Power";
+static constexpr const char* powerButtonPath =
+ "/xyz/openbmc_project/Chassis/Buttons/Power0";
+static constexpr const char* resetButtonIntf =
+ "xyz.openbmc_project.Chassis.Buttons.Reset";
+static constexpr const char* resetButtonPath =
+ "/xyz/openbmc_project/Chassis/Buttons/Reset0";
// Phosphor Host State manager
namespace State = sdbusplus::xyz::openbmc_project::State::server;
@@ -136,7 +118,6 @@ namespace fs = std::filesystem;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using namespace sdbusplus::xyz::openbmc_project::Control::Boot::server;
-namespace variant_ns = sdbusplus::message::variant_ns;
namespace chassis
{
@@ -152,8 +133,18 @@ sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
namespace cache
{
-settings::Objects objects(dbus,
- {bootModeIntf, bootSourceIntf, powerRestoreIntf});
+std::unique_ptr<settings::Objects> objectsPtr = nullptr;
+
+settings::Objects& getObjects()
+{
+ if (objectsPtr == nullptr)
+ {
+ objectsPtr = std::make_unique<settings::Objects>(
+ dbus, std::vector<std::string>{bootModeIntf, bootSourceIntf,
+ powerRestoreIntf});
+ }
+ return *objectsPtr;
+}
} // namespace cache
} // namespace internal
@@ -216,19 +207,19 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
macObjectInfo.first, MAC_INTERFACE,
"MACAddress");
- auto ipAddress = variant_ns::get<std::string>(properties["Address"]);
+ auto ipAddress = std::get<std::string>(properties["Address"]);
- auto gateway = variant_ns::get<std::string>(properties["Gateway"]);
+ auto gateway = std::get<std::string>(properties["Gateway"]);
- auto prefix = variant_ns::get<uint8_t>(properties["PrefixLength"]);
+ auto prefix = std::get<uint8_t>(properties["PrefixLength"]);
uint8_t isStatic =
- (variant_ns::get<std::string>(properties["Origin"]) ==
+ (std::get<std::string>(properties["Origin"]) ==
"xyz.openbmc_project.Network.IP.AddressOrigin.Static")
? 1
: 0;
- auto MACAddress = variant_ns::get<std::string>(variant);
+ auto MACAddress = std::get<std::string>(variant);
// it is expected here that we should get the valid data
// but we may also get the default values.
@@ -266,11 +257,10 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
std::memcpy(respptr->data + ADDRTYPE_OFFSET, &isStatic,
sizeof(isStatic));
- uint8_t addressFamily =
- (variant_ns::get<std::string>(properties["Type"]) ==
- "xyz.openbmc_project.Network.IP.Protocol.IPv4")
- ? AF_INET
- : AF_INET6;
+ uint8_t addressFamily = (std::get<std::string>(properties["Type"]) ==
+ "xyz.openbmc_project.Network.IP.Protocol.IPv4")
+ ? AF_INET
+ : AF_INET6;
addrSize = (addressFamily == AF_INET)
? ipmi::network::IPV4_ADDRESS_SIZE_BYTE
@@ -504,39 +494,29 @@ uint32_t getPOHCounter()
ipmi::getDbusProperty(bus, service, chassisStateObj.first,
chassisPOHStateIntf, pOHCounterProperty);
- return variant_ns::get<uint32_t>(propValue);
-}
-
-ipmi_ret_t ipmi_chassis_wildcard(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)
-{
- // Status code.
- ipmi_ret_t rc = IPMI_CC_INVALID;
- *data_len = 0;
- return rc;
+ return std::get<uint32_t>(propValue);
}
-ipmi_ret_t ipmi_get_chassis_cap(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)
+/** @brief Implements the get chassis capabilities command
+ *
+ * @returns IPMI completion code plus response data
+ * chassisCapFlags - chassis capability flag
+ * chassisFRUInfoDevAddr - chassis FRU info Device Address
+ * chassisSDRDevAddr - chassis SDR device address
+ * chassisSELDevAddr - chassis SEL device address
+ * chassisSMDevAddr - chassis system management device address
+ * chassisBridgeDevAddr - chassis bridge device address
+ */
+ipmi::RspType<uint8_t, // chassis capabilities flag
+ uint8_t, // chassis FRU info Device Address
+ uint8_t, // chassis SDR device address
+ uint8_t, // chassis SEL device address
+ uint8_t, // chassis system management device address
+ uint8_t // chassis bridge device address
+ >
+ ipmiGetChassisCap()
{
- // sd_bus error
- ipmi_ret_t rc = IPMI_CC_OK;
-
- ipmi_chassis_cap_t chassis_cap{};
-
- if (*data_len != 0)
- {
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
-
- *data_len = sizeof(ipmi_chassis_cap_t);
-
+ ipmi::PropertyMap properties;
try
{
sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
@@ -555,120 +535,135 @@ ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
// interfaces).
// [0] -1b = Chassis provides intrusion (physical security) sensor.
// set to default value 0x0.
- ipmi::Value variant = ipmi::getDbusProperty(
- bus, chassisCapObject.second, chassisCapObject.first,
- chassisCapIntf, chassisCapFlagsProp);
- chassis_cap.cap_flags = variant_ns::get<uint8_t>(variant);
-
- variant = ipmi::getDbusProperty(bus, chassisCapObject.second,
- chassisCapObject.first, chassisCapIntf,
- chassisFRUDevAddrProp);
- // Chassis FRU info Device Address.
- chassis_cap.fru_info_dev_addr = variant_ns::get<uint8_t>(variant);
-
- variant = ipmi::getDbusProperty(bus, chassisCapObject.second,
- chassisCapObject.first, chassisCapIntf,
- chassisSDRDevAddrProp);
- // Chassis SDR Device Address.
- chassis_cap.sdr_dev_addr = variant_ns::get<uint8_t>(variant);
-
- variant = ipmi::getDbusProperty(bus, chassisCapObject.second,
- chassisCapObject.first, chassisCapIntf,
- chassisSELDevAddrProp);
- // Chassis SEL Device Address.
- chassis_cap.sel_dev_addr = variant_ns::get<uint8_t>(variant);
-
- variant = ipmi::getDbusProperty(bus, chassisCapObject.second,
- chassisCapObject.first, chassisCapIntf,
- chassisSMDevAddrProp);
- // Chassis System Management Device Address.
- chassis_cap.system_management_dev_addr =
- variant_ns::get<uint8_t>(variant);
-
- variant = ipmi::getDbusProperty(bus, chassisCapObject.second,
- chassisCapObject.first, chassisCapIntf,
- chassisBridgeDevAddrProp);
- // Chassis Bridge Device Address.
- chassis_cap.bridge_dev_addr = variant_ns::get<uint8_t>(variant);
- uint8_t* respP = reinterpret_cast<uint8_t*>(response);
- uint8_t* chassisP = reinterpret_cast<uint8_t*>(&chassis_cap);
- std::copy(chassisP, chassisP + *data_len, respP);
+
+ properties =
+ ipmi::getAllDbusProperties(bus, chassisCapObject.second,
+ chassisCapObject.first, chassisCapIntf);
}
catch (std::exception& e)
{
- log<level::ERR>(e.what());
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- *data_len = 0;
- return rc;
+ log<level::ERR>("Failed to fetch Chassis Capability properties",
+ entry("ERROR=%s", e.what()));
+ return ipmi::responseUnspecifiedError();
}
- return rc;
+ uint8_t* chassisCapFlags =
+ std::get_if<uint8_t>(&properties[chassisCapFlagsProp]);
+ if (chassisCapFlags == nullptr)
+ {
+ log<level::ERR>("Error to get chassis capability flags");
+ return ipmi::responseUnspecifiedError();
+ }
+ uint8_t* chassisFRUInfoDevAddr =
+ std::get_if<uint8_t>(&properties[chassisFRUDevAddrProp]);
+ if (chassisFRUInfoDevAddr == nullptr)
+ {
+ log<level::ERR>("Error to get chassis FRU info device address");
+ return ipmi::responseUnspecifiedError();
+ }
+ uint8_t* chassisSDRDevAddr =
+ std::get_if<uint8_t>(&properties[chassisSDRDevAddrProp]);
+ if (chassisSDRDevAddr == nullptr)
+ {
+ log<level::ERR>("Error to get chassis SDR device address");
+ return ipmi::responseUnspecifiedError();
+ }
+ uint8_t* chassisSELDevAddr =
+ std::get_if<uint8_t>(&properties[chassisSELDevAddrProp]);
+ if (chassisSELDevAddr == nullptr)
+ {
+ log<level::ERR>("Error to get chassis SEL device address");
+ return ipmi::responseUnspecifiedError();
+ }
+ uint8_t* chassisSMDevAddr =
+ std::get_if<uint8_t>(&properties[chassisSMDevAddrProp]);
+ if (chassisSMDevAddr == nullptr)
+ {
+ log<level::ERR>("Error to get chassis SM device address");
+ return ipmi::responseUnspecifiedError();
+ }
+ uint8_t* chassisBridgeDevAddr =
+ std::get_if<uint8_t>(&properties[chassisBridgeDevAddrProp]);
+ if (chassisBridgeDevAddr == nullptr)
+ {
+ log<level::ERR>("Error to get chassis bridge device address");
+ return ipmi::responseUnspecifiedError();
+ }
+
+ return ipmi::responseSuccess(*chassisCapFlags, *chassisFRUInfoDevAddr,
+ *chassisSDRDevAddr, *chassisSELDevAddr,
+ *chassisSMDevAddr, *chassisBridgeDevAddr);
}
-ipmi_ret_t ipmi_set_chassis_cap(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)
-{
- ipmi_ret_t rc = IPMI_CC_OK;
+/** @brief implements set chassis capalibities command
+ * @param intrusion - chassis intrusion
+ * @param fpLockout - frontpannel lockout
+ * @param reserved1 - skip one bit
+ * @param fruDeviceAddr - chassis FRU info Device Address
+ * @param sdrDeviceAddr - chassis SDR device address
+ * @param selDeviceAddr - chassis SEL device address
+ * @param smDeviceAddr - chassis system management device address
+ * @param bridgeDeviceAddr - chassis bridge device address
+ *
+ * @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiSetChassisCap(bool intrusion, bool fpLockout,
+ uint6_t reserved1,
- if (*data_len != sizeof(ipmi_chassis_cap_t))
- {
- log<level::ERR>("Unsupported request length",
- entry("LEN=0x%x", *data_len));
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
+ uint8_t fruDeviceAddr,
- ipmi_chassis_cap_t* chassisCap = static_cast<ipmi_chassis_cap_t*>(request);
+ uint8_t sdrDeviceAddr,
- *data_len = 0;
+ uint8_t selDeviceAddr,
+
+ uint8_t smDeviceAddr,
+
+ uint8_t bridgeDeviceAddr)
+{
// check input data
- if (0 != (chassisCap->cap_flags & ~chassisCapFlagMask))
+ if (reserved1 != 0)
{
- log<level::ERR>("Unsupported request parameter(CAP Flags)",
- entry("REQ=0x%x", chassisCap->cap_flags));
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ log<level::ERR>("Unsupported request parameter");
+ return ipmi::responseInvalidFieldRequest();
}
- if (0 != (chassisCap->fru_info_dev_addr & ~chassisCapAddrMask))
+ if ((fruDeviceAddr & ~chassisCapAddrMask) != 0)
{
log<level::ERR>("Unsupported request parameter(FRU Addr)",
- entry("REQ=0x%x", chassisCap->fru_info_dev_addr));
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ entry("REQ=0x%x", fruDeviceAddr));
+ return ipmi::responseInvalidFieldRequest();
}
-
- if (0 != (chassisCap->sdr_dev_addr & ~chassisCapAddrMask))
+ if ((sdrDeviceAddr & ~chassisCapAddrMask) != 0)
{
log<level::ERR>("Unsupported request parameter(SDR Addr)",
- entry("REQ=0x%x", chassisCap->sdr_dev_addr));
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ entry("REQ=0x%x", sdrDeviceAddr));
+ return ipmi::responseInvalidFieldRequest();
}
- if (0 != (chassisCap->sel_dev_addr & ~chassisCapAddrMask))
+ if ((selDeviceAddr & ~chassisCapAddrMask) != 0)
{
log<level::ERR>("Unsupported request parameter(SEL Addr)",
- entry("REQ=0x%x", chassisCap->sel_dev_addr));
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ entry("REQ=0x%x", selDeviceAddr));
+ return ipmi::responseInvalidFieldRequest();
}
- if (0 != (chassisCap->system_management_dev_addr & ~chassisCapAddrMask))
+ if ((smDeviceAddr & ~chassisCapAddrMask) != 0)
{
- log<level::ERR>(
- "Unsupported request parameter(SM Addr)",
- entry("REQ=0x%x", chassisCap->system_management_dev_addr));
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ log<level::ERR>("Unsupported request parameter(SM Addr)",
+ entry("REQ=0x%x", smDeviceAddr));
+ return ipmi::responseInvalidFieldRequest();
}
- if (0 != (chassisCap->bridge_dev_addr & ~chassisCapAddrMask))
+ if ((bridgeDeviceAddr & ~chassisCapAddrMask) != 0)
{
log<level::ERR>("Unsupported request parameter(Bridge Addr)",
- entry("REQ=0x%x", chassisCap->bridge_dev_addr));
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ entry("REQ=0x%x", bridgeDeviceAddr));
+ return ipmi::responseInvalidFieldRequest();
}
+ uint8_t capFlags = (static_cast<uint8_t>(intrusion)) |
+ ((static_cast<uint8_t>(fpLockout)) << 1);
try
{
sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
@@ -677,39 +672,34 @@ ipmi_ret_t ipmi_set_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi::setDbusProperty(bus, chassisCapObject.second,
chassisCapObject.first, chassisCapIntf,
- chassisCapFlagsProp, chassisCap->cap_flags);
+ chassisCapFlagsProp, capFlags);
ipmi::setDbusProperty(bus, chassisCapObject.second,
chassisCapObject.first, chassisCapIntf,
- chassisFRUDevAddrProp,
- chassisCap->fru_info_dev_addr);
+ chassisFRUDevAddrProp, fruDeviceAddr);
ipmi::setDbusProperty(bus, chassisCapObject.second,
chassisCapObject.first, chassisCapIntf,
- chassisSDRDevAddrProp, chassisCap->sdr_dev_addr);
+ chassisSDRDevAddrProp, sdrDeviceAddr);
ipmi::setDbusProperty(bus, chassisCapObject.second,
chassisCapObject.first, chassisCapIntf,
- chassisSELDevAddrProp, chassisCap->sel_dev_addr);
+ chassisSELDevAddrProp, selDeviceAddr);
ipmi::setDbusProperty(bus, chassisCapObject.second,
chassisCapObject.first, chassisCapIntf,
- chassisSMDevAddrProp,
- chassisCap->system_management_dev_addr);
+ chassisSMDevAddrProp, smDeviceAddr);
ipmi::setDbusProperty(bus, chassisCapObject.second,
chassisCapObject.first, chassisCapIntf,
- chassisBridgeDevAddrProp,
- chassisCap->bridge_dev_addr);
+ chassisBridgeDevAddrProp, bridgeDeviceAddr);
}
catch (std::exception& e)
{
log<level::ERR>(e.what());
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- return rc;
+ return ipmi::responseUnspecifiedError();
}
-
- return rc;
+ return ipmi::responseSuccess();
}
//------------------------------------------
@@ -770,6 +760,38 @@ int initiate_state_transition(State::Host::Transition transition)
return rc;
}
+//------------------------------------------
+// Set Enabled property to inform NMI source
+// handling to trigger a NMI_OUT BSOD.
+//------------------------------------------
+int setNmiProperty(const bool value)
+{
+ constexpr const char* nmiSourceObjPath =
+ "/xyz/openbmc_project/Chassis/Control/NMISource";
+ constexpr const char* nmiSourceIntf =
+ "xyz.openbmc_project.Chassis.Control.NMISource";
+ std::string bmcSourceSignal = "xyz.openbmc_project.Chassis.Control."
+ "NMISource.BMCSourceSignal.ChassisCmd";
+ std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+
+ try
+ {
+ auto service = ipmi::getService(*busp, nmiSourceIntf, nmiSourceObjPath);
+ ipmi::setDbusProperty(*busp, service, nmiSourceObjPath, nmiSourceIntf,
+ "BMCSource", bmcSourceSignal);
+ ipmi::setDbusProperty(*busp, service, nmiSourceObjPath, nmiSourceIntf,
+ "Enabled", value);
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>("Failed to trigger NMI_OUT",
+ entry("EXCEPTION=%s", e.what()));
+ return -1;
+ }
+
+ return 0;
+}
+
namespace power_policy
{
@@ -777,175 +799,264 @@ using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
using IpmiValue = uint8_t;
using DbusValue = RestorePolicy::Policy;
-std::map<DbusValue, IpmiValue> dbusToIpmi = {
+const std::map<DbusValue, IpmiValue> dbusToIpmi = {
{RestorePolicy::Policy::AlwaysOff, 0x00},
{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;
+
+/* helper function for Get Chassis Status Command
+ */
+std::optional<uint2_t> getPowerRestorePolicy()
+{
+ uint2_t restorePolicy = 0;
+ using namespace chassis::internal;
+
+ settings::Objects& objects = cache::getObjects();
+
+ try
+ {
+ const auto& powerRestoreSetting =
+ objects.map.at(powerRestoreIntf).front();
+ ipmi::Value result = ipmi::getDbusProperty(
+ *getSdBus(),
+ objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
+ powerRestoreSetting.c_str(), powerRestoreIntf,
+ "PowerRestorePolicy");
+ auto powerRestore = RestorePolicy::convertPolicyFromString(
+ std::get<std::string>(result));
+ restorePolicy = dbusToIpmi.at(powerRestore);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>(
+ "Failed to fetch pgood property", entry("ERROR=%s", e.what()),
+ entry("PATH=%s", objects.map.at(powerRestoreIntf).front().c_str()),
+ entry("INTERFACE=%s", powerRestoreIntf));
+ cache::objectsPtr.reset();
+ return std::nullopt;
+ }
+ return std::make_optional(restorePolicy);
+}
+
+/*
+ * getPowerStatus
+ * helper function for Get Chassis Status Command
+ * return - optional value for pgood (no value on error)
+ */
+std::optional<bool> getPowerStatus()
+{
+ bool powerGood = false;
+ std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+ try
+ {
+ constexpr const char* chassisStatePath =
+ "/xyz/openbmc_project/state/chassis0";
+ constexpr const char* chassisStateIntf =
+ "xyz.openbmc_project.State.Chassis";
+ auto service =
+ ipmi::getService(*busp, chassisStateIntf, chassisStatePath);
+
+ ipmi::Value powerState =
+ ipmi::getDbusProperty(*busp, service, chassisStatePath,
+ chassisStateIntf, "CurrentPowerState");
+ powerGood = std::get<std::string>(powerState) ==
+ "xyz.openbmc_project.State.Chassis.PowerState.On";
+ }
+ catch (const std::exception& e)
+ {
+ try
+ {
+ // FIXME: some legacy modules use the older path; try that next
+ constexpr const char* legacyPwrCtrlObj =
+ "/org/openbmc/control/power0";
+ constexpr const char* legacyPwrCtrlIntf =
+ "org.openbmc.control.Power";
+ auto service =
+ ipmi::getService(*busp, legacyPwrCtrlIntf, legacyPwrCtrlObj);
+
+ ipmi::Value variant = ipmi::getDbusProperty(
+ *busp, service, legacyPwrCtrlObj, legacyPwrCtrlIntf, "pgood");
+ powerGood = static_cast<bool>(std::get<int>(variant));
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Failed to fetch pgood property",
+ entry("ERROR=%s", e.what()));
+ return std::nullopt;
+ }
+ }
+ return std::make_optional(powerGood);
+}
+
+/*
+ * getACFailStatus
+ * helper function for Get Chassis Status Command
+ * return - bool value for ACFail (false on error)
+ */
+bool getACFailStatus()
+{
+ constexpr const char* powerControlObj =
+ "/xyz/openbmc_project/Chassis/Control/Power0";
+ constexpr const char* powerControlIntf =
+ "xyz.openbmc_project.Chassis.Control.Power";
+ bool acFail = false;
+ std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
+ try
+ {
+ auto service =
+ ipmi::getService(*bus, powerControlIntf, powerControlObj);
+
+ ipmi::Value variant = ipmi::getDbusProperty(
+ *bus, service, powerControlObj, powerControlIntf, "PFail");
+ acFail = std::get<bool>(variant);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Failed to fetch PFail property",
+ entry("ERROR=%s", e.what()),
+ entry("PATH=%s", powerControlObj),
+ entry("INTERFACE=%s", powerControlIntf));
+ }
+ return acFail;
+}
} // namespace power_policy
+static std::optional<bool> getButtonEnabled(const std::string& buttonPath,
+ const std::string& buttonIntf)
+{
+ std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+ bool buttonDisabled = false;
+ try
+ {
+ auto service = ipmi::getService(*busp, buttonIntf, buttonPath);
+ ipmi::Value enabled = ipmi::getDbusProperty(*busp, service, buttonPath,
+ buttonIntf, "Enabled");
+ buttonDisabled = !std::get<bool>(enabled);
+ }
+ catch (sdbusplus::exception::SdBusError& e)
+ {
+ log<level::ERR>("Fail to get button Enabled property",
+ entry("PATH=%s", buttonPath.c_str()),
+ entry("ERROR=%s", e.what()));
+ return std::nullopt;
+ }
+ return std::make_optional(buttonDisabled);
+}
+
//----------------------------------------------------------------------
// Get Chassis Status commands
//----------------------------------------------------------------------
-ipmi_ret_t ipmi_get_chassis_status(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)
+ipmi::RspType<bool, // Power is on
+ bool, // Power overload
+ bool, // Interlock
+ bool, // power fault
+ bool, // power control fault
+ uint2_t, // power restore policy
+ bool, // reserved
+
+ bool, // AC failed
+ bool, // last power down caused by a Power overload
+ bool, // last power down caused by a power interlock
+ bool, // last power down caused by power fault
+ bool, // last ‘Power is on’ state was entered via IPMI command
+ uint3_t, // reserved
+
+ bool, // Chassis intrusion active
+ bool, // Front Panel Lockout active
+ bool, // Drive Fault
+ bool, // Cooling/fan fault detected
+ uint2_t, // Chassis Identify State
+ bool, // Chassis Identify command and state info supported
+ bool, // reserved
+
+ bool, // Power off button disabled
+ bool, // Reset button disabled
+ bool, // Diagnostic Interrupt button disabled
+ bool, // Standby (sleep) button disabled
+ bool, // Power off button disable allowed
+ bool, // Reset button disable allowed
+ bool, // Diagnostic Interrupt button disable allowed
+ bool // Standby (sleep) button disable allowed
+ >
+ ipmiGetChassisStatus()
{
- const char* objname = "/org/openbmc/control/power0";
- const char* intf = "org.openbmc.control.Power";
-
- sd_bus* bus = NULL;
- sd_bus_message* reply = NULL;
- int r = 0;
- int pgood = 0;
- char* busname = NULL;
- ipmi_ret_t rc = IPMI_CC_OK;
- ipmi_get_chassis_status_t chassis_status{};
-
- uint8_t s = 0;
-
using namespace chassis::internal;
- using namespace chassis::internal::cache;
- using namespace power_policy;
-
- const auto& powerRestoreSetting = objects.map.at(powerRestoreIntf).front();
- auto method = dbus.new_method_call(
- objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
- powerRestoreSetting.c_str(), ipmi::PROP_INTF, "Get");
- method.append(powerRestoreIntf, "PowerRestorePolicy");
- auto resp = dbus.call(method);
- if (resp.is_method_error())
+ std::optional<uint2_t> restorePolicy =
+ power_policy::getPowerRestorePolicy();
+ std::optional<bool> powerGood = power_policy::getPowerStatus();
+ if (!restorePolicy || !powerGood)
{
- log<level::ERR>("Error in PowerRestorePolicy Get");
- report<InternalFailure>();
- *data_len = 0;
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- sdbusplus::message::variant<std::string> result;
- resp.read(result);
- auto powerRestore = RestorePolicy::convertPolicyFromString(
- variant_ns::get<std::string>(result));
-
- *data_len = 4;
-
- bus = ipmid_get_sd_bus_connection();
-
- r = mapper_get_service(bus, objname, &busname);
- if (r < 0)
- {
- log<level::ERR>("Failed to get bus name", entry("ERRNO=0x%X", -r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto finish;
- }
-
- r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply,
- "i");
- if (r < 0)
- {
- log<level::ERR>("Failed to call sd_bus_get_property",
- entry("PROPERTY=%s", "pgood"), entry("ERRNO=0x%X", -r),
- entry("BUS=%s", busname), entry("PATH=%s", objname),
- entry("INTERFACE=%s", intf));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto finish;
- }
-
- r = sd_bus_message_read(reply, "i", &pgood);
- if (r < 0)
- {
- log<level::ERR>("Failed to read sensor:", entry("ERRNO=0x%X", -r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto finish;
- }
-
- s = dbusToIpmi.at(powerRestore);
-
- // Current Power State
- // [7] reserved
- // [6..5] power restore policy
- // 00b = chassis stays powered off after AC/mains returns
- // 01b = after AC returns, power is restored to the state that was
- // in effect when AC/mains was lost.
- // 10b = chassis always powers up after AC/mains returns
- // 11b = unknow
- // Set to 00b, by observing the hardware behavior.
- // Do we need to define a dbus property to identify the restore
- // policy?
-
- // [4] power control fault
- // 1b = controller attempted to turn system power on or off, but
- // system did not enter desired state.
- // Set to 0b, since We don't support it..
-
- // [3] power fault
- // 1b = fault detected in main power subsystem.
- // set to 0b. for we don't support it.
-
- // [2] 1b = interlock (chassis is presently shut down because a chassis
- // panel interlock switch is active). (IPMI 1.5)
- // set to 0b, for we don't support it.
-
- // [1] power overload
- // 1b = system shutdown because of power overload condition.
- // set to 0b, for we don't support it.
-
- // [0] power is on
- // 1b = system power is on
- // 0b = system power is off(soft-off S4/S5, or mechanical off)
-
- chassis_status.cur_power_state = ((s & 0x3) << 5) | (pgood & 0x1);
-
- // Last Power Event
- // [7..5] – reserved
- // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
- // [3] – 1b = last power down caused by power fault
- // [2] – 1b = last power down caused by a power interlock being activated
- // [1] – 1b = last power down caused by a Power overload
- // [0] – 1b = AC failed
- // set to 0x0, for we don't support these fields.
-
- chassis_status.last_power_event = 0;
-
- // Misc. Chassis State
- // [7] – reserved
- // [6] – 1b = Chassis Identify command and state info supported (Optional)
- // 0b = Chassis Identify command support unspecified via this command.
- // (The Get Command Support command , if implemented, would still
- // indicate support for the Chassis Identify command)
- // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved
- // (return
- // as 00b) otherwise. Returns the present chassis identify state.
- // Refer to the Chassis Identify command for more info.
- // 00b = chassis identify state = Off
- // 01b = chassis identify state = Temporary(timed) On
- // 10b = chassis identify state = Indefinite On
- // 11b = reserved
- // [3] – 1b = Cooling/fan fault detected
- // [2] – 1b = Drive Fault
- // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
- // push-buttons disabled.)
- // [0] – 1b = Chassis Intrusion active
- // set to 0, for we don't support them.
- chassis_status.misc_power_state = 0;
// Front Panel Button Capabilities and disable/enable status(Optional)
- // set to 0, for we don't support them.
- chassis_status.front_panel_button_cap_status = 0;
-
- // Pack the actual response
- std::memcpy(response, &chassis_status, *data_len);
+ std::optional<bool> powerButtonReading =
+ getButtonEnabled(powerButtonPath, powerButtonIntf);
+ // allow disable if the interface is present
+ bool powerButtonDisableAllow = static_cast<bool>(powerButtonReading);
+ // default return the button is enabled (not disabled)
+ bool powerButtonDisabled = false;
+ if (powerButtonDisableAllow)
+ {
+ // return the real value of the button status, if present
+ powerButtonDisabled = *powerButtonReading;
+ }
-finish:
- free(busname);
- reply = sd_bus_message_unref(reply);
+ std::optional<bool> resetButtonReading =
+ getButtonEnabled(resetButtonPath, resetButtonIntf);
+ // allow disable if the interface is present
+ bool resetButtonDisableAllow = static_cast<bool>(resetButtonReading);
+ // default return the button is enabled (not disabled)
+ bool resetButtonDisabled = false;
+ if (resetButtonDisableAllow)
+ {
+ // return the real value of the button status, if present
+ resetButtonDisabled = *resetButtonReading;
+ }
- return rc;
+ bool powerDownAcFailed = power_policy::getACFailStatus();
+
+ // This response has a lot of hard-coded, unsupported fields
+ // They are set to false or 0
+ constexpr bool powerOverload = false;
+ constexpr bool chassisInterlock = false;
+ constexpr bool powerFault = false;
+ constexpr bool powerControlFault = false;
+ constexpr bool powerDownOverload = false;
+ constexpr bool powerDownInterlock = false;
+ constexpr bool powerDownPowerFault = false;
+ constexpr bool powerStatusIPMI = false;
+ constexpr bool chassisIntrusionActive = false;
+ constexpr bool frontPanelLockoutActive = false;
+ constexpr bool driveFault = false;
+ constexpr bool coolingFanFault = false;
+ // chassisIdentifySupport set because this command is implemented
+ constexpr bool chassisIdentifySupport = true;
+ uint2_t chassisIdentifyState = static_cast<uint2_t>(chassisIDState);
+ constexpr bool diagButtonDisabled = false;
+ constexpr bool sleepButtonDisabled = false;
+ constexpr bool diagButtonDisableAllow = false;
+ constexpr bool sleepButtonDisableAllow = false;
+
+ return ipmi::responseSuccess(
+ *powerGood, powerOverload, chassisInterlock, powerFault,
+ powerControlFault, *restorePolicy,
+ false, // reserved
+
+ powerDownAcFailed, powerDownOverload, powerDownInterlock,
+ powerDownPowerFault, powerStatusIPMI,
+ uint3_t(0), // reserved
+
+ chassisIntrusionActive, frontPanelLockoutActive, driveFault,
+ coolingFanFault, chassisIdentifyState, chassisIdentifySupport,
+ false, // reserved
+
+ powerButtonDisabled, resetButtonDisabled, diagButtonDisabled,
+ sleepButtonDisabled, powerButtonDisableAllow, resetButtonDisableAllow,
+ diagButtonDisableAllow, sleepButtonDisableAllow);
}
//-------------------------------------------------------------
@@ -1018,25 +1129,16 @@ void indicate_no_softoff_needed()
std::ofstream(path.c_str());
}
-//----------------------------------------------------------------------
-// Chassis Control commands
-//----------------------------------------------------------------------
-ipmi_ret_t ipmi_chassis_control(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)
+/** @brief Implementation of chassis control command
+ *
+ * @param - chassisControl command byte
+ *
+ * @return Success or InvalidFieldRequest.
+ */
+ipmi::RspType<> ipmiChassisControl(uint8_t chassisControl)
{
- // Error from power off.
int rc = 0;
-
- // No response for this command.
- *data_len = 0;
-
- // Catch the actual operaton by peeking into request buffer
- uint8_t chassis_ctrl_cmd = *(uint8_t*)request;
-
- switch (chassis_ctrl_cmd)
+ switch (chassisControl)
{
case CMD_POWER_ON:
rc = initiate_state_transition(State::Host::Transition::On);
@@ -1096,15 +1198,20 @@ ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
rc = initiate_state_transition(State::Host::Transition::Off);
break;
+ case CMD_PULSE_DIAGNOSTIC_INTR:
+ rc = setNmiProperty(true);
+ break;
+
default:
{
log<level::ERR>("Invalid Chassis Control command",
- entry("CMD=0x%X", chassis_ctrl_cmd));
- rc = -1;
+ entry("CMD=0x%X", chassisControl));
+ return ipmi::responseInvalidFieldRequest();
}
}
- return ((rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
+ return ((rc < 0) ? ipmi::responseUnspecifiedError()
+ : ipmi::responseSuccess());
}
/** @brief Return D-Bus connection string to enclosure identify LED object
@@ -1159,7 +1266,7 @@ void enclosureIdentifyLed(bool flag)
dbus.new_method_call(connection.c_str(), identify_led_object_name,
"org.freedesktop.DBus.Properties", "Set");
led.append("xyz.openbmc_project.Led.Group", "Asserted",
- sdbusplus::message::variant<bool>(flag));
+ std::variant<bool>(flag));
auto ledReply = dbus.call(led);
if (ledReply.is_method_error())
{
@@ -1175,6 +1282,7 @@ void enclosureIdentifyLedOff()
{
try
{
+ chassisIDState = ChassisIDState::off;
enclosureIdentifyLed(false);
}
catch (const InternalFailure& e)
@@ -1207,6 +1315,7 @@ ipmi::RspType<> ipmiChassisIdentify(std::optional<uint8_t> interval,
identifyTimer->stop();
try
{
+ chassisIDState = ChassisIDState::temporaryOn;
enclosureIdentifyLed(true);
}
catch (const InternalFailure& e)
@@ -1217,6 +1326,7 @@ ipmi::RspType<> ipmiChassisIdentify(std::optional<uint8_t> interval,
if (forceIdentify)
{
+ chassisIDState = ChassisIDState::indefiniteOn;
return ipmi::responseSuccess();
}
// start the timer
@@ -1243,10 +1353,13 @@ std::map<IpmiValue, Source::Sources> sourceIpmiToDbus = {
{0x01, Source::Sources::Network},
{0x02, Source::Sources::Disk},
{0x05, Source::Sources::ExternalMedia},
+ {0x0f, Source::Sources::RemovableMedia},
{ipmiDefault, Source::Sources::Default}};
std::map<IpmiValue, Mode::Modes> modeIpmiToDbus = {
+#ifdef ENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT
{0x03, Mode::Modes::Safe},
+#endif // ENABLE_BOOT_SAFE_MODE_SUPPORT
{0x06, Mode::Modes::Setup},
{ipmiDefault, Mode::Modes::Regular}};
@@ -1254,10 +1367,13 @@ std::map<Source::Sources, IpmiValue> sourceDbusToIpmi = {
{Source::Sources::Network, 0x01},
{Source::Sources::Disk, 0x02},
{Source::Sources::ExternalMedia, 0x05},
+ {Source::Sources::RemovableMedia, 0x0f},
{Source::Sources::Default, ipmiDefault}};
std::map<Mode::Modes, IpmiValue> modeDbusToIpmi = {
+#ifdef ENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT
{Mode::Modes::Safe, 0x03},
+#endif // ENABLE_BOOT_SAFE_MODE_SUPPORT
{Mode::Modes::Setup, 0x06},
{Mode::Modes::Regular, ipmiDefault}};
@@ -1271,8 +1387,8 @@ static ipmi_ret_t setBootSource(const Source::Sources& source)
{
using namespace chassis::internal;
using namespace chassis::internal::cache;
- sdbusplus::message::variant<std::string> property =
- convertForMessage(source);
+ std::variant<std::string> property = convertForMessage(source);
+ settings::Objects& objects = getObjects();
auto bootSetting = settings::boot::setting(objects, bootSourceIntf);
const auto& bootSourceSetting = std::get<settings::Path>(bootSetting);
auto method = dbus.new_method_call(
@@ -1297,7 +1413,8 @@ static ipmi_ret_t setBootMode(const Mode::Modes& mode)
{
using namespace chassis::internal;
using namespace chassis::internal::cache;
- sdbusplus::message::variant<std::string> property = convertForMessage(mode);
+ std::variant<std::string> property = convertForMessage(mode);
+ settings::Objects& objects = getObjects();
auto bootSetting = settings::boot::setting(objects, bootModeIntf);
const auto& bootModeSetting = std::get<settings::Path>(bootSetting);
auto method = dbus.new_method_call(
@@ -1347,6 +1464,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
try
{
+ settings::Objects& objects = getObjects();
auto bootSetting = settings::boot::setting(objects, bootSourceIntf);
const auto& bootSourceSetting =
std::get<settings::Path>(bootSetting);
@@ -1364,10 +1482,10 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
*data_len = 0;
return IPMI_CC_UNSPECIFIED_ERROR;
}
- sdbusplus::message::variant<std::string> result;
+ std::variant<std::string> result;
reply.read(result);
- auto bootSource = Source::convertSourcesFromString(
- variant_ns::get<std::string>(result));
+ auto bootSource =
+ Source::convertSourcesFromString(std::get<std::string>(result));
bootSetting = settings::boot::setting(objects, bootModeIntf);
const auto& bootModeSetting = std::get<settings::Path>(bootSetting);
@@ -1384,8 +1502,8 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return IPMI_CC_UNSPECIFIED_ERROR;
}
reply.read(result);
- auto bootMode = Mode::convertModesFromString(
- variant_ns::get<std::string>(result));
+ auto bootMode =
+ Mode::convertModesFromString(std::get<std::string>(result));
bootOption = sourceDbusToIpmi.at(bootSource);
if ((Mode::Modes::Regular == bootMode) &&
@@ -1407,6 +1525,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
}
catch (InternalFailure& e)
{
+ cache::objectsPtr.reset();
report<InternalFailure>();
*data_len = 0;
return IPMI_CC_UNSPECIFIED_ERROR;
@@ -1489,6 +1608,8 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
(reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
SET_PARM_BOOT_FLAGS_PERMANENT;
+ settings::Objects& objects = getObjects();
+
auto bootSetting = settings::boot::setting(objects, bootSourceIntf);
oneTimeEnabled =
@@ -1548,9 +1669,17 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
setBootSource(Source::Sources::Default);
}
}
+ if ((modeIpmiToDbus.end() == modeItr) &&
+ (sourceIpmiToDbus.end() == sourceItr))
+ {
+ // return error if boot option is not supported
+ *data_len = 0;
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
}
catch (InternalFailure& e)
{
+ objectsPtr.reset();
report<InternalFailure>();
*data_len = 0;
return IPMI_CC_UNSPECIFIED_ERROR;
@@ -1588,74 +1717,57 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
-ipmi_ret_t ipmiGetPOHCounter(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)
+/** @brief implements Get POH counter command
+ * @parameter
+ * - none
+ * @returns IPMI completion code plus response data
+ * - minPerCount - Minutes per count
+ * - counterReading - counter reading
+ */
+ipmi::RspType<uint8_t, // Minutes per count
+ uint32_t // Counter reading
+ >
+ ipmiGetPOHCounter()
{
// sd_bus error
- ipmi_ret_t rc = IPMI_CC_OK;
-
- auto resptr = reinterpret_cast<GetPOHCountResponse*>(response);
-
try
{
- auto pohCounter = getPOHCounter();
- resptr->counterReading[0] = pohCounter;
- resptr->counterReading[1] = pohCounter >> 8;
- resptr->counterReading[2] = pohCounter >> 16;
- resptr->counterReading[3] = pohCounter >> 24;
+ return ipmi::responseSuccess(static_cast<uint8_t>(poh::minutesPerCount),
+ getPOHCounter());
}
catch (std::exception& e)
{
log<level::ERR>(e.what());
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
-
- resptr->minPerCount = poh::minutesPerCount;
- *data_len = sizeof(GetPOHCountResponse);
-
- 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)
+ipmi::RspType<uint3_t, // policy support
+ uint5_t // reserved
+ >
+ ipmiChassisSetPowerRestorePolicy(boost::asio::yield_context yield,
+ uint3_t policy, uint5_t reserved)
{
- 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)
+ if (reserved || (policy > power_policy::noChange))
{
- phosphor::logging::log<level::ERR>("Unsupported request length",
- entry("LEN=0x%x", *data_len));
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
+ phosphor::logging::log<level::ERR>(
+ "Reserved request parameter",
+ entry("REQ=0x%x", static_cast<int>(policy)));
+ return ipmi::responseInvalidFieldRequest();
}
- if (*reqptr > power_policy::noChange)
- {
- phosphor::logging::log<level::ERR>("Reserved request parameter",
- entry("REQ=0x%x", *reqptr));
- *data_len = 0;
- return IPMI_CC_PARM_OUT_OF_RANGE;
- }
-
- reqPolicy = *reqptr & power_policy::policyBitMask;
- if (reqPolicy == power_policy::noChange)
+ if (policy == power_policy::noChange)
{
// just return the supported policy
- *resptr = power_policy::allSupport;
- *data_len = power_policy::setPolicyReqLen;
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(power_policy::allSupport, reserved);
}
for (auto const& it : power_policy::dbusToIpmi)
{
- if (it.second == reqPolicy)
+ if (it.second == policy)
{
value = it.first;
break;
@@ -1664,57 +1776,51 @@ ipmi_ret_t ipmi_chassis_set_power_restore_policy(
try
{
+ settings::Objects& objects = chassis::internal::cache::getObjects();
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
+ objects.map.at(chassis::internal::powerRestoreIntf).front();
+ std::variant<std::string> property = convertForMessage(value);
+
+ auto sdbusp = getSdBus();
+ boost::system::error_code ec;
+ sdbusp->yield_method_call<void>(
+ yield, ec,
+ 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())
+ powerRestoreSetting, ipmi::PROP_INTF, "Set",
+ chassis::internal::powerRestoreIntf, "PowerRestorePolicy",
+ property);
+ if (ec)
{
phosphor::logging::log<level::ERR>("Unspecified Error");
- *data_len = 0;
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
}
catch (InternalFailure& e)
{
+ chassis::internal::cache::objectsPtr.reset();
report<InternalFailure>();
- *data_len = 0;
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- *resptr = power_policy::allSupport;
- *data_len = power_policy::setPolicyReqLen;
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(power_policy::allSupport, reserved);
}
void register_netfn_chassis_functions()
{
createIdentifyTimer();
- // <Wildcard Command>
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL,
- ipmi_chassis_wildcard, PRIVILEGE_USER);
-
// Get Chassis Capabilities
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL,
- ipmi_get_chassis_cap, PRIVILEGE_USER);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdGetChassisCapabilities,
+ ipmi::Privilege::User, ipmiGetChassisCap);
// Set Chassis Capabilities
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_CHASSIS_CAP, NULL,
- ipmi_set_chassis_cap, PRIVILEGE_USER);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdSetChassisCapabilities,
+ ipmi::Privilege::User, ipmiSetChassisCap);
// <Get System Boot Options>
ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
@@ -1722,12 +1828,14 @@ void register_netfn_chassis_functions()
PRIVILEGE_OPERATOR);
// <Get Chassis Status>
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL,
- ipmi_get_chassis_status, PRIVILEGE_USER);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdGetChassisStatus,
+ ipmi::Privilege::User, ipmiGetChassisStatus);
// <Chassis Control>
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL,
- ipmi_chassis_control, PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdChassisControl,
+ ipmi::Privilege::Operator, ipmiChassisControl);
// <Chassis Identify>
ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
@@ -1739,11 +1847,13 @@ void register_netfn_chassis_functions()
ipmi_chassis_set_sys_boot_options,
PRIVILEGE_OPERATOR);
// <Get POH Counter>
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_POH_COUNTER, NULL,
- ipmiGetPOHCounter, PRIVILEGE_USER);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdGetPohCounter,
+ ipmi::Privilege::User, ipmiGetPOHCounter);
// <Set Power Restore Policy>
- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_RESTORE_POLICY, NULL,
- ipmi_chassis_set_power_restore_policy,
- PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdSetPowerRestorePolicy,
+ ipmi::Privilege::Operator,
+ ipmiChassisSetPowerRestorePolicy);
}
OpenPOWER on IntegriCloud