diff options
Diffstat (limited to 'chassishandler.cpp')
-rw-r--r-- | chassishandler.cpp | 964 |
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); } |