summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch821
1 files changed, 821 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch
new file mode 100644
index 000000000..f6a9e9f35
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch
@@ -0,0 +1,821 @@
+From 8133e8bd818f986a9c5d373b3c56683560103214 Mon Sep 17 00:00:00 2001
+From: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+Date: Thu, 3 Sep 2020 19:53:10 +0000
+Subject: [PATCH] chassishandler: SetSystemBootOptions to new API
+
+Rewrite ipmiChassisSetSysBootOptions to use newly introduced IPMI
+provider API
+
+Tested:
+verified using IPMI chassis bootparam command and raw commands
+Command: ipmitool chassis bootparam set bootflag force_disk
+Response: Set Boot Device to force_disk
+Command: ipmitool chassis bootparam set bootflag force_pxe
+Response: Set Boot Device to force_pxe
+Command: ipmitool chassis bootdev pxe options=persistent
+Response: Set Boot Device to pxe
+Command: ipmitool chassis bootparam set bootflag force_bios
+Response: Set Boot Device to force_bios
+Command: ipmitool chassis bootparam set bootflag force_safe
+Response: Set Chassis Boot Parameter 5 failed: Invalid data field in
+ request
+
+Command: ipmitool raw 0 8 0x5 0 0 0 0 0 //setBootOptions param 5
+Response: //Success
+Command: ipmitool raw 0 8 0x4 0 0 //setBootOptions param 4
+Response: //Success
+Command: ipmitool raw 0 8 0x61 0x21 0x70 0x62 0x21 0x00 0x01
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0x01 0x01 0x04 0 0 0 0 1 1 1 1 //setBootOptions param 61
+Response: //Success
+Command: ipmitool raw 0 8 0 0 //setBootOptions param 0
+Response: //Success
+
+Signed-off-by: srikanta mondal <srikantax.mondal@intel.com>
+Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+
+%% original patch: 0071-chassishandler-SetSystemBootOptions-to-new-API.patch
+---
+ chassishandler.cpp | 465 +++++++++++++++++++++++++++++----------------
+ chassishandler.hpp | 15 +-
+ 2 files changed, 305 insertions(+), 175 deletions(-)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index f5e7375..ca7cd2c 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -35,37 +35,33 @@
+ #include <xyz/openbmc_project/State/Host/server.hpp>
+ #include <xyz/openbmc_project/State/PowerOnHours/server.hpp>
+
+-// Defines
+-#define SET_PARM_VERSION 0x01
+-#define SET_PARM_BOOT_FLAGS_PERMANENT 0x40
+-#define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME 0x80
+-#define SET_PARM_BOOT_FLAGS_VALID_PERMANENT 0xC0
+-
+ 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
+- // option parametrs
+-constexpr size_t SIZE_PREFIX = 7;
+-constexpr size_t MAX_PREFIX_VALUE = 32;
+-constexpr size_t SIZE_COOKIE = 4;
+-constexpr size_t SIZE_VERSION = 2;
++static constexpr uint8_t setParmVersion = 0x01;
++static constexpr uint8_t setParmBootFlagsPermanent = 0x40;
++static constexpr uint8_t setParmBootFlagsValidOneTime = 0x80;
++static constexpr uint8_t setParmBootFlagsValidPermanent = 0xC0;
++
++constexpr size_t SIZE_BOOT_OPTION = static_cast<size_t>(
++ BootOptionResponseSize::opalNetworkSettings); // Maximum size of the boot
++ // option parameters
++constexpr size_t sizeVersion = 2;
+ constexpr size_t DEFAULT_IDENTIFY_TIME_OUT = 15;
+
+ // PetiBoot-Specific
+-static constexpr uint8_t net_conf_initial_bytes[] = {0x80, 0x21, 0x70, 0x62,
+- 0x21, 0x00, 0x01, 0x06};
+-
+-static constexpr size_t COOKIE_OFFSET = 1;
+-static constexpr size_t VERSION_OFFSET = 5;
+-static constexpr size_t ADDR_SIZE_OFFSET = 8;
+-static constexpr size_t MAC_OFFSET = 9;
+-static constexpr size_t ADDRTYPE_OFFSET = 16;
+-static constexpr size_t IPADDR_OFFSET = 17;
++static constexpr uint8_t netConfInitialBytes[] = {0x80, 0x21, 0x70, 0x62,
++ 0x21, 0x00, 0x01, 0x06};
++static constexpr uint8_t oemParmStart = 96;
++static constexpr uint8_t oemParmEnd = 127;
++
++static constexpr size_t cookieOffset = 1;
++static constexpr size_t versionOffset = 5;
++static constexpr size_t addrSizeOffset = 8;
++static constexpr size_t macOffset = 9;
++static constexpr size_t addrTypeOffset = 16;
++static constexpr size_t ipAddrOffset = 17;
+
+ static constexpr uint4_t RESERVED = 0;
+ static constexpr uint8_t CHANNEL_NOT_SUPPORTED = 0;
+@@ -75,6 +71,16 @@ static constexpr size_t chassisIdentifyReqLength = 2;
+ static constexpr size_t identifyIntervalPos = 0;
+ static constexpr size_t forceIdentifyPos = 1;
+
++namespace ipmi
++{
++constexpr Cc ccParmNotSupported = 0x80;
++
++static inline auto responseParmNotSupported()
++{
++ return response(ccParmNotSupported);
++}
++} // namespace ipmi
++
+ void register_netfn_chassis_functions() __attribute__((constructor));
+
+ // Host settings in dbus
+@@ -180,12 +186,6 @@ struct get_sys_boot_options_response_t
+ uint8_t data[SIZE_BOOT_OPTION];
+ } __attribute__((packed));
+
+-struct set_sys_boot_options_t
+-{
+- uint8_t parameter;
+- uint8_t data[SIZE_BOOT_OPTION];
+-} __attribute__((packed));
+-
+ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
+ {
+ ipmi::PropertyMap properties;
+@@ -255,15 +255,15 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
+ }
+ }
+
+- sscanf(
+- MACAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
+- (respptr->data + MAC_OFFSET), (respptr->data + MAC_OFFSET + 1),
+- (respptr->data + MAC_OFFSET + 2), (respptr->data + MAC_OFFSET + 3),
+- (respptr->data + MAC_OFFSET + 4), (respptr->data + MAC_OFFSET + 5));
++ sscanf(MACAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
++ (respptr->data + macOffset), (respptr->data + macOffset + 1),
++ (respptr->data + macOffset + 2), (respptr->data + macOffset + 3),
++ (respptr->data + macOffset + 4),
++ (respptr->data + macOffset + 5));
+
+- respptr->data[MAC_OFFSET + 6] = 0x00;
++ respptr->data[macOffset + 6] = 0x00;
+
+- std::memcpy(respptr->data + ADDRTYPE_OFFSET, &isStatic,
++ std::memcpy(respptr->data + addrTypeOffset, &isStatic,
+ sizeof(isStatic));
+
+ uint8_t addressFamily = (std::get<std::string>(properties["Type"]) ==
+@@ -277,9 +277,9 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
+
+ // ipaddress and gateway would be in IPv4 format
+ inet_pton(addressFamily, ipAddress.c_str(),
+- (respptr->data + IPADDR_OFFSET));
++ (respptr->data + ipAddrOffset));
+
+- uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
++ uint8_t prefixOffset = ipAddrOffset + addrSize;
+
+ std::memcpy(respptr->data + prefixOffset, &prefix, sizeof(prefix));
+
+@@ -298,10 +298,10 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
+
+ // PetiBoot-Specific
+ // If success then copy the first 9 bytes to the data
+- std::memcpy(respptr->data, net_conf_initial_bytes,
+- sizeof(net_conf_initial_bytes));
++ std::memcpy(respptr->data, netConfInitialBytes,
++ sizeof(netConfInitialBytes));
+
+- std::memcpy(respptr->data + ADDR_SIZE_OFFSET, &addrSize, sizeof(addrSize));
++ std::memcpy(respptr->data + addrSizeOffset, &addrSize, sizeof(addrSize));
+
+ #ifdef _IPMI_DEBUG_
+ std::printf("\n===Printing the IPMI Formatted Data========\n");
+@@ -361,19 +361,18 @@ std::string getAddrStr(uint8_t family, uint8_t* data, uint8_t offset,
+ return ipAddr;
+ }
+
+-int setHostNetworkData(set_sys_boot_options_t* reqptr)
++ipmi::Cc setHostNetworkData(ipmi::message::Payload& data)
+ {
+ using namespace std::string_literals;
+- std::string host_network_config;
+- char mac[]{"00:00:00:00:00:00"};
++ std::string hostNetworkConfig;
++ std::string mac("00:00:00:00:00:00");
+ std::string ipAddress, gateway;
+- char addrOrigin{0};
++ std::string addrOrigin{0};
+ uint8_t addrSize{0};
+ std::string addressOrigin =
+ "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
+ std::string addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
+ uint8_t prefix{0};
+- uint32_t zeroCookie = 0;
+ uint8_t family = AF_INET;
+
+ // cookie starts from second byte
+@@ -384,13 +383,33 @@ int setHostNetworkData(set_sys_boot_options_t* reqptr)
+ do
+ {
+ // cookie == 0x21 0x70 0x62 0x21
+- if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
+- (net_conf_initial_bytes + COOKIE_OFFSET),
+- SIZE_COOKIE) != 0)
++ data.trailingOk = true;
++ auto msgLen = data.size();
++ std::vector<uint8_t> msgPayloadBytes(msgLen);
++ if (data.unpack(msgPayloadBytes) != 0 || !data.fullyUnpacked())
++ {
++ log<level::ERR>(
++ "Error in unpacking message of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++
++ uint8_t* msgPayloadStartingPos = msgPayloadBytes.data();
++ constexpr size_t cookieSize = 4;
++ if (msgLen < cookieOffset + cookieSize)
++ {
++ log<level::ERR>(
++ "Error in cookie getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ if (std::equal(msgPayloadStartingPos + cookieOffset,
++ msgPayloadStartingPos + cookieOffset + cookieSize,
++ (netConfInitialBytes + cookieOffset)) != 0)
+ {
+- // cookie == 0
+- if (memcmp(&(reqptr->data[COOKIE_OFFSET]), &zeroCookie,
+- SIZE_COOKIE) == 0)
++ // all cookie == 0
++ if (std::all_of(msgPayloadStartingPos + cookieOffset,
++ msgPayloadStartingPos + cookieOffset +
++ cookieSize,
++ [](int i) { return i == 0; }) == true)
+ {
+ // need to zero out the network settings.
+ break;
+@@ -401,59 +420,106 @@ int setHostNetworkData(set_sys_boot_options_t* reqptr)
+ }
+
+ // vesion == 0x00 0x01
+- if (memcmp(&(reqptr->data[VERSION_OFFSET]),
+- (net_conf_initial_bytes + VERSION_OFFSET),
+- SIZE_VERSION) != 0)
++ if (msgLen < versionOffset + sizeVersion)
++ {
++ log<level::ERR>(
++ "Error in version getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ if (std::equal(msgPayloadStartingPos + versionOffset,
++ msgPayloadStartingPos + versionOffset + sizeVersion,
++ (netConfInitialBytes + versionOffset)) != 0)
+ {
+-
+ log<level::ERR>("Invalid Version");
+ elog<InternalFailure>();
+ }
+
+- std::snprintf(
+- mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
+- reqptr->data[MAC_OFFSET], reqptr->data[MAC_OFFSET + 1],
+- reqptr->data[MAC_OFFSET + 2], reqptr->data[MAC_OFFSET + 3],
+- reqptr->data[MAC_OFFSET + 4], reqptr->data[MAC_OFFSET + 5]);
++ if (msgLen < macOffset + 6)
++ {
++ log<level::ERR>(
++ "Error in mac address getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ std::stringstream result;
++ std::copy((msgPayloadStartingPos + macOffset),
++ (msgPayloadStartingPos + macOffset + 5),
++ std::ostream_iterator<int>(result, ":"));
++ mac = result.str();
+
+- std::memcpy(&addrOrigin, &(reqptr->data[ADDRTYPE_OFFSET]),
+- sizeof(decltype(addrOrigin)));
++ if (msgLen < addrTypeOffset + sizeof(decltype(addrOrigin)))
++ {
++ log<level::ERR>(
++ "Error in original address getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ std::copy(msgPayloadStartingPos + addrTypeOffset,
++ msgPayloadStartingPos + addrTypeOffset +
++ sizeof(decltype(addrOrigin)),
++ std::ostream_iterator<int>(result, ""));
++ addrOrigin = result.str();
+
+- if (addrOrigin)
++ if (!addrOrigin.empty())
+ {
+ addressOrigin =
+ "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
+ }
+
++ if (msgLen < addrSizeOffset + sizeof(decltype(addrSize)))
++ {
++ log<level::ERR>(
++ "Error in address size getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
+ // Get the address size
+- std::memcpy(&addrSize, &reqptr->data[ADDR_SIZE_OFFSET],
+- sizeof(addrSize));
++ std::copy(msgPayloadStartingPos + addrSizeOffset,
++ (msgPayloadStartingPos + addrSizeOffset +
++ sizeof(decltype(addrSize))),
++ &addrSize);
+
+- uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
+-
+- std::memcpy(&prefix, &(reqptr->data[prefixOffset]),
+- sizeof(decltype(prefix)));
++ uint8_t prefixOffset = ipAddrOffset + addrSize;
++ if (msgLen < prefixOffset + sizeof(decltype(prefix)))
++ {
++ log<level::ERR>(
++ "Error in prefix getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ std::copy(msgPayloadStartingPos + prefixOffset,
++ (msgPayloadStartingPos + prefixOffset +
++ sizeof(decltype(prefix))),
++ &prefix);
+
+ uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
+-
+ if (addrSize != ipmi::network::IPV4_ADDRESS_SIZE_BYTE)
+ {
+ addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
+ family = AF_INET6;
+ }
+
+- ipAddress =
+- getAddrStr(family, reqptr->data, IPADDR_OFFSET, addrSize);
++ if (msgLen < ipAddrOffset + addrSize)
++ {
++ log<level::ERR>(
++ "Error in IP address getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ ipAddress = getAddrStr(family, msgPayloadStartingPos, ipAddrOffset,
++ addrSize);
+
+- gateway = getAddrStr(family, reqptr->data, gatewayOffset, addrSize);
++ if (msgLen < gatewayOffset + addrSize)
++ {
++ log<level::ERR>(
++ "Error in gateway address getting of setHostNetworkData");
++ return ipmi::ccReqDataLenInvalid;
++ }
++ gateway = getAddrStr(family, msgPayloadStartingPos, gatewayOffset,
++ addrSize);
+
+ } while (0);
+
+ // Cookie == 0 or it is a valid cookie
+- host_network_config += "ipaddress="s + ipAddress + ",prefix="s +
+- std::to_string(prefix) + ",gateway="s + gateway +
+- ",mac="s + mac + ",addressOrigin="s +
+- addressOrigin;
++ hostNetworkConfig += "ipaddress="s + ipAddress + ",prefix="s +
++ std::to_string(prefix) + ",gateway="s + gateway +
++ ",mac="s + mac + ",addressOrigin="s +
++ addressOrigin;
+
+ sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+@@ -476,17 +542,17 @@ int setHostNetworkData(set_sys_boot_options_t* reqptr)
+ ipmi::setDbusProperty(bus, macObjectInfo.second, macObjectInfo.first,
+ MAC_INTERFACE, "MACAddress", std::string(mac));
+
+- log<level::DEBUG>(
+- "Network configuration changed",
+- entry("NETWORKCONFIG=%s", host_network_config.c_str()));
++ log<level::DEBUG>("Network configuration changed",
++ entry("NETWORKCONFIG=%s", hostNetworkConfig.c_str()));
+ }
+- catch (InternalFailure& e)
++ catch (sdbusplus::exception_t& e)
+ {
+ commit<InternalFailure>();
+- return -1;
++ log<level::ERR>("Error in ipmiChassisSetSysBootOptions call");
++ return ipmi::ccUnspecifiedError;
+ }
+
+- return 0;
++ return ipmi::ccSuccess;
+ }
+
+ uint32_t getPOHCounter()
+@@ -1444,7 +1510,7 @@ std::map<Mode::Modes, IpmiValue> modeDbusToIpmi = {
+ * @param[in] source - boot source value
+ * @return On failure return IPMI error.
+ */
+-static ipmi_ret_t setBootSource(const Source::Sources& source)
++static ipmi::Cc setBootSource(const Source::Sources& source)
+ {
+ using namespace chassis::internal;
+ using namespace chassis::internal::cache;
+@@ -1461,16 +1527,16 @@ static ipmi_ret_t setBootSource(const Source::Sources& source)
+ {
+ log<level::ERR>("Error in BootSource Set");
+ report<InternalFailure>();
+- return IPMI_CC_UNSPECIFIED_ERROR;
++ return ipmi::ccUnspecifiedError;
+ }
+- return IPMI_CC_OK;
++ return ipmi::ccSuccess;
+ }
+
+ /** @brief Set the property value for boot mode
+ * @param[in] mode - boot mode value
+ * @return On failure return IPMI error.
+ */
+-static ipmi_ret_t setBootMode(const Mode::Modes& mode)
++static ipmi::Cc setBootMode(const Mode::Modes& mode)
+ {
+ using namespace chassis::internal;
+ using namespace chassis::internal::cache;
+@@ -1487,9 +1553,9 @@ static ipmi_ret_t setBootMode(const Mode::Modes& mode)
+ {
+ log<level::ERR>("Error in BootMode Set");
+ report<InternalFailure>();
+- return IPMI_CC_UNSPECIFIED_ERROR;
++ return ipmi::ccUnspecifiedError;
+ }
+- return IPMI_CC_OK;
++ return ipmi::ccSuccess;
+ }
+
+ static constexpr uint8_t setComplete = 0x0;
+@@ -1511,29 +1577,28 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ IpmiValue bootOption = ipmiDefault;
+
+ if (reqptr->parameter ==
+- static_cast<uint8_t>(BootOptionParameter::SET_IN_PROGRESS))
++ static_cast<uint8_t>(BootOptionParameter::setInProgress))
+ {
+- *data_len =
+- static_cast<uint8_t>(BootOptionResponseSize::SET_IN_PROGRESS);
+- resp->version = SET_PARM_VERSION;
+- resp->parm = static_cast<uint8_t>(BootOptionParameter::SET_IN_PROGRESS);
++ *data_len = static_cast<uint8_t>(BootOptionResponseSize::setInProgress);
++ resp->version = setParmVersion;
++ resp->parm = static_cast<uint8_t>(BootOptionParameter::setInProgress);
+ resp->data[0] = transferStatus;
+ return IPMI_CC_OK;
+ }
+
+ std::memset(resp, 0, sizeof(*resp));
+- resp->version = SET_PARM_VERSION;
++ resp->version = setParmVersion;
+ resp->parm = 5;
+- resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
++ resp->data[0] = setParmBootFlagsValidOneTime;
+ /*
+ * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+ * This is the only parameter used by petitboot.
+ */
+ if (reqptr->parameter ==
+- static_cast<uint8_t>(BootOptionParameter::BOOT_FLAGS))
++ static_cast<uint8_t>(BootOptionParameter::bootFlags))
+ {
+
+- *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
++ *data_len = static_cast<uint8_t>(BootOptionResponseSize::bootFlags);
+ using namespace chassis::internal;
+ using namespace chassis::internal::cache;
+
+@@ -1592,9 +1657,8 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ }
+ resp->data[1] = (bootOption << 2);
+
+- resp->data[0] = oneTimeEnabled
+- ? SET_PARM_BOOT_FLAGS_VALID_ONE_TIME
+- : SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
++ resp->data[0] = oneTimeEnabled ? setParmBootFlagsValidOneTime
++ : setParmBootFlagsValidPermanent;
+
+ rc = IPMI_CC_OK;
+ }
+@@ -1607,14 +1671,14 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ }
+ }
+ else if (reqptr->parameter ==
+- static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS))
++ static_cast<uint8_t>(BootOptionParameter::opalNetworkSettings))
+ {
+
+ *data_len =
+- static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
++ static_cast<uint8_t>(BootOptionResponseSize::opalNetworkSettings);
+
+ resp->parm =
+- static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
++ static_cast<uint8_t>(BootOptionParameter::opalNetworkSettings);
+
+ int ret = getHostNetworkData(resp);
+
+@@ -1646,32 +1710,37 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ return rc;
+ }
+
+-ipmi_ret_t ipmi_chassis_set_sys_boot_options(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<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,
++ uint7_t parameterSelector,
++ bool parameterIsValid,
++ ipmi::message::Payload& data)
+ {
+ using namespace boot_options;
+- ipmi_ret_t rc = IPMI_CC_OK;
+- set_sys_boot_options_t* reqptr = (set_sys_boot_options_t*)request;
+-
+- std::printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",
+- reqptr->parameter);
+-
+- // This IPMI command does not have any resposne data
+- *data_len = 0;
++ ipmi::Cc rc;
+
+- if (reqptr->parameter ==
+- static_cast<uint8_t>(BootOptionParameter::SET_IN_PROGRESS))
++ if (parameterSelector ==
++ static_cast<uint7_t>(BootOptionParameter::setInProgress))
+ {
++ uint2_t setStatus;
++ uint6_t rsvd;
++
++ if (data.unpack(rsvd, setStatus) != 0 || !data.fullyUnpacked())
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ if (rsvd || setStatus != static_cast<uint2_t>(setComplete))
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
+ if ((transferStatus == setInProgress) &&
+- (reqptr->data[0] != setComplete))
++ (static_cast<uint8_t>(setStatus) != setComplete))
+ {
+- return IPMI_CC_FAIL_SET_IN_PROGRESS;
++ constexpr ipmi::Cc ccFailSetInProgress = 0x81;
++ return ipmi::response(ccFailSetInProgress);
+ }
+- transferStatus = reqptr->data[0];
+- return IPMI_CC_OK;
++ transferStatus = static_cast<uint8_t>(setStatus);
++
++ return ipmi::responseSuccess();
+ }
+
+ /* 000101
+@@ -1679,9 +1748,37 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ * This is the only parameter used by petitboot.
+ */
+
+- if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS)
+- {
+- IpmiValue bootOption = ((reqptr->data[1] & 0x3C) >> 2);
++ if (parameterSelector ==
++ static_cast<uint7_t>(BootOptionParameter::bootFlags))
++ {
++ uint5_t rsvd;
++ bool validFlag;
++ bool permanent;
++ bool biosBootType;
++ bool lockOutResetButton;
++ bool screenBlank;
++ uint4_t bootDeviceSelector;
++ bool lockKeyboard;
++ bool cmosClear;
++ uint8_t data3;
++ uint4_t biosInfo;
++ uint4_t rsvd1;
++ uint5_t deviceInstance;
++ uint3_t rsvd2;
++
++ if (data.unpack(rsvd, biosBootType, permanent, validFlag,
++ lockOutResetButton, screenBlank, bootDeviceSelector,
++ lockKeyboard, cmosClear, data3, biosInfo, rsvd1,
++ deviceInstance, rsvd2) != 0 ||
++ !data.fullyUnpacked())
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ if (rsvd || rsvd1 || rsvd2)
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
++
+ using namespace chassis::internal;
+ using namespace chassis::internal::cache;
+ auto oneTimeEnabled = false;
+@@ -1691,10 +1788,6 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ try
+ {
+- bool permanent =
+- (reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
+- SET_PARM_BOOT_FLAGS_PERMANENT;
+-
+ settings::Objects& objects = getObjects();
+
+ auto bootSetting = settings::boot::setting(objects, bootSourceIntf);
+@@ -1720,15 +1813,19 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ "Enabled", !permanent);
+ }
+
+- auto modeItr = modeIpmiToDbus.find(bootOption);
+- auto sourceItr = sourceIpmiToDbus.find(bootOption);
++ auto modeItr =
++ modeIpmiToDbus.find(static_cast<uint8_t>(bootDeviceSelector));
++ auto sourceItr =
++ sourceIpmiToDbus.find(static_cast<uint8_t>(bootDeviceSelector));
+ if (sourceIpmiToDbus.end() != sourceItr)
+ {
+ rc = setBootSource(sourceItr->second);
+- if (rc != IPMI_CC_OK)
++
++ if (rc != ipmi::ccSuccess)
+ {
+- *data_len = 0;
+- return rc;
++ log<level::ERR>("ipmiChassisSetSysBootOptions: Error in "
++ "setting boot source");
++ return ipmi::responseUnspecifiedError();
+ }
+ // If a set boot device is mapping to a boot source, then reset
+ // the boot mode D-Bus property to default.
+@@ -1742,10 +1839,11 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ if (modeIpmiToDbus.end() != modeItr)
+ {
+ rc = setBootMode(modeItr->second);
+- if (rc != IPMI_CC_OK)
++ if (rc != ipmi::ccSuccess)
+ {
+- *data_len = 0;
+- return rc;
++ log<level::ERR>("ipmiChassisSetSysBootOptions: Error in "
++ "setting boot mode");
++ return ipmi::responseUnspecifiedError();
+ }
+ // If a set boot device is mapping to a boot mode, then reset
+ // the boot source D-Bus property to default.
+@@ -1760,48 +1858,79 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ (sourceIpmiToDbus.end() == sourceItr))
+ {
+ // return error if boot option is not supported
+- *data_len = 0;
+- return IPMI_CC_INVALID_FIELD_REQUEST;
++ log<level::ERR>(
++ "ipmiChassisSetSysBootOptions: Boot option not supported");
++ return ipmi::responseInvalidFieldRequest();
+ }
+ }
+- catch (InternalFailure& e)
++ catch (sdbusplus::exception_t& e)
+ {
+ objectsPtr.reset();
+ report<InternalFailure>();
+- *data_len = 0;
+- return IPMI_CC_UNSPECIFIED_ERROR;
++ log<level::ERR>(
++ "ipmiChassisSetSysBootOptions: Error in setting Boot "
++ "flag parameters");
++ return ipmi::responseUnspecifiedError();
+ }
+ }
+- else if (reqptr->parameter ==
+- (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS)
++ else if (parameterSelector ==
++ static_cast<uint7_t>(BootOptionParameter::bootInfo))
+ {
++ uint8_t writeMak;
++ uint5_t bootInitiatorAckData;
++ uint3_t rsvd;
+
+- int ret = setHostNetworkData(reqptr);
+- if (ret < 0)
++ if (data.unpack(writeMak, bootInitiatorAckData, rsvd) != 0 ||
++ !data.fullyUnpacked())
+ {
+- log<level::ERR>(
+- "setHostNetworkData failed for set_sys_boot_options");
+- rc = IPMI_CC_UNSPECIFIED_ERROR;
++ return ipmi::responseReqDataLenInvalid();
+ }
+- }
+- else if (reqptr->parameter ==
+- static_cast<uint8_t>(BootOptionParameter::BOOT_INFO))
+- {
+- // Handle parameter #4 and return command completed normally
+- // (IPMI_CC_OK). There is no implementation in OpenBMC for this
++ if (rsvd)
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
++ // (ccSuccess). There is no implementation in OpenBMC for this
+ // parameter. This is added to support the ipmitool command `chassis
+ // bootdev` which sends set on parameter #4, before setting the boot
+ // flags.
+- rc = IPMI_CC_OK;
++ log<level::INFO>("ipmiChassisSetSysBootOptions: bootInfo parameter set "
++ "successfully");
++ data.trailingOk = true;
++ return ipmi::responseSuccess();
+ }
+ else
+ {
+- log<level::ERR>("Unsupported parameter",
+- entry("PARAM=0x%x", reqptr->parameter));
+- rc = IPMI_CC_PARM_NOT_SUPPORTED;
++ if ((parameterSelector >= static_cast<uint7_t>(oemParmStart)) &&
++ (parameterSelector <= static_cast<uint7_t>(oemParmEnd)))
++ {
++ if (parameterSelector ==
++ static_cast<uint7_t>(BootOptionParameter::opalNetworkSettings))
++ {
++ ipmi::Cc ret = setHostNetworkData(data);
++ if (ret != ipmi::ccSuccess)
++ {
++ log<level::ERR>("ipmiChassisSetSysBootOptions: Error in "
++ "setHostNetworkData");
++ data.trailingOk = true;
++ return ipmi::response(ret);
++ }
++ data.trailingOk = true;
++ return ipmi::responseSuccess();
++ }
++ else
++ {
++ log<level::ERR>(
++ "ipmiChassisSetSysBootOptions: Unsupported parameters",
++ entry("PARAM=0x%x",
++ static_cast<uint8_t>(parameterSelector)));
++ data.trailingOk = true;
++ return ipmi::responseParmNotSupported();
++ }
++ }
++ data.trailingOk = true;
++ return ipmi::responseParmNotSupported();
+ }
+-
+- return rc;
++ return ipmi::responseSuccess();
+ }
+
+ /** @brief implements Get POH counter command
+@@ -1963,9 +2092,11 @@ void register_netfn_chassis_functions()
+ ipmi::Privilege::Operator, ipmiChassisIdentify);
+
+ // <Set System Boot Options>
+- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
+- ipmi_chassis_set_sys_boot_options,
+- PRIVILEGE_OPERATOR);
++ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
++ ipmi::chassis::cmdSetSystemBootOptions,
++ ipmi::Privilege::Operator,
++ ipmiChassisSetSysBootOptions);
++
+ // <Get POH Counter>
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
+ ipmi::chassis::cmdGetPohCounter,
+diff --git a/chassishandler.hpp b/chassishandler.hpp
+index 353a929..479563a 100644
+--- a/chassishandler.hpp
++++ b/chassishandler.hpp
+@@ -25,7 +25,6 @@ enum ipmi_chassis_return_codes
+ {
+ IPMI_OK = 0x0,
+ IPMI_CC_PARM_NOT_SUPPORTED = 0x80,
+- IPMI_CC_FAIL_SET_IN_PROGRESS = 0x81,
+ };
+
+ // Generic completion codes,
+@@ -47,17 +46,17 @@ enum ipmi_chassis_control_cmds : uint8_t
+ };
+ enum class BootOptionParameter : size_t
+ {
+- SET_IN_PROGRESS = 0x0,
+- BOOT_INFO = 0x4,
+- BOOT_FLAGS = 0x5,
+- OPAL_NETWORK_SETTINGS = 0x61
++ setInProgress = 0x0,
++ bootInfo = 0x4,
++ bootFlags = 0x5,
++ opalNetworkSettings = 0x61
+ };
+
+ enum class BootOptionResponseSize : size_t
+ {
+- SET_IN_PROGRESS = 3,
+- BOOT_FLAGS = 5,
+- OPAL_NETWORK_SETTINGS = 50
++ setInProgress = 3,
++ bootFlags = 5,
++ opalNetworkSettings = 50
+ };
+
+ enum class ChassisIDState : uint8_t
+--
+2.17.1
+