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: Unable to send RAW command (channel=0x0 netfn=0x0 lun=0x0
cmd=0x8 rsp=0x80): Unknown (0x80)
Signed-off-by: jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
Signed-off-by: srikanta mondal <srikantax.mondal@intel.com>
Change-Id: I6faa0b5162ba02bbe0e8a3acaba092888ed48acc
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 46a4707..28cb756 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -34,37 +34,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;
+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_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;
+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 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 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 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;
@@ -74,6 +70,16 @@
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
@@ -179,12 +185,6 @@
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;
@@ -254,15 +254,15 @@
}
}
- 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"]) ==
@@ -276,9 +276,9 @@
// 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));
@@ -297,10 +297,10 @@
// 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");
@@ -360,19 +360,18 @@
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
@@ -383,13 +382,33 @@
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())
{
- // cookie == 0
- if (memcmp(&(reqptr->data[COOKIE_OFFSET]), &zeroCookie,
- SIZE_COOKIE) == 0)
+ 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)
+ {
+ // 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;
@@ -400,59 +419,106 @@
}
// 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());
@@ -475,17 +541,17 @@
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()
@@ -1576,7 +1642,7 @@
* @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;
@@ -1593,9 +1659,9 @@
{
log<level::ERR>("Error in BootMode Set");
report<InternalFailure>();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::ccUnspecifiedError;
}
- return IPMI_CC_OK;
+ return ipmi::ccSuccess;
}
ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
@@ -1613,19 +1679,18 @@
IpmiValue bootOption = ipmiDefault;
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;
@@ -1684,9 +1749,8 @@
}
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;
}
@@ -1699,14 +1763,14 @@
}
}
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);
@@ -1738,30 +1802,50 @@
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;
/* 000101
* Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
* This is the only parameter used by petitboot.
*/
- if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS)
+ if (parameterSelector ==
+ static_cast<uint7_t>(BootOptionParameter::bootFlags))
{
- IpmiValue bootOption = ((reqptr->data[1] & 0x3C) >> 2);
+ 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;
@@ -1771,10 +1855,6 @@
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);
@@ -1800,15 +1880,18 @@
"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.
@@ -1822,10 +1905,11 @@
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.
@@ -1840,48 +1924,79 @@
(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;
- }
- }
- else if (reqptr->parameter ==
- (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS)
- {
-
- int ret = setHostNetworkData(reqptr);
- if (ret < 0)
- {
log<level::ERR>(
- "setHostNetworkData failed for set_sys_boot_options");
- rc = IPMI_CC_UNSPECIFIED_ERROR;
+ "ipmiChassisSetSysBootOptions: Error in setting Boot "
+ "flag parameters");
+ return ipmi::responseUnspecifiedError();
}
}
- else if (reqptr->parameter ==
- static_cast<uint8_t>(BootOptionParameter::BOOT_INFO))
+ else if (parameterSelector ==
+ static_cast<uint7_t>(BootOptionParameter::bootInfo))
{
- // Handle parameter #4 and return command completed normally
- // (IPMI_CC_OK). There is no implementation in OpenBMC for this
+ uint8_t writeMak;
+ uint5_t bootInitiatorAckData;
+ uint3_t rsvd;
+
+ if (data.unpack(writeMak, bootInitiatorAckData, rsvd) != 0 ||
+ !data.fullyUnpacked())
+ {
+ return ipmi::responseReqDataLenInvalid();
+ }
+ 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
@@ -2043,9 +2158,11 @@
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 dcaf06c..93de2c0 100644
--- a/chassishandler.hpp
+++ b/chassishandler.hpp
@@ -46,15 +46,15 @@
};
enum class BootOptionParameter : size_t
{
- BOOT_INFO = 0x4,
- BOOT_FLAGS = 0x5,
- OPAL_NETWORK_SETTINGS = 0x61
+ bootInfo = 0x4,
+ bootFlags = 0x5,
+ opalNetworkSettings = 0x61
};
enum class BootOptionResponseSize : size_t
{
- BOOT_FLAGS = 5,
- OPAL_NETWORK_SETTINGS = 50
+ bootFlags = 5,
+ opalNetworkSettings = 50
};
enum class ChassisIDState : uint8_t