smbioshandler:move bmc region complete,Write& Lock
Rewrite "MDR_COMPLETE, WRITE & LOCK" cmds to new IPMI provider API.
Tested:
verified using ipmitool smbioshandler commands.
a. bmc region update complete
Command: ipmitool raw 0x3E 0x21 0xff 0xff
Output: Unable to send RAW command (channel=0x0 netfn=0x3e lun=0x0
cmd=0x21 rsp=0xc9): Parameter out of range
Command: ipmitool raw 0x3E 0x21 0xff 0x0
Output: Unable to send RAW command (channel=0x0 netfn=0x3e lun=0x0
cmd=0x21 rsp=0xd5): Command not supported in present state
b. bmc region write
Command: ipmitool raw 0x3E 0X24 0x01 0x2 0x03 0x00 0x01 04 0x01 0x01
Output: Unable to send RAW command (channel=0x0 netfn=0x3e lun=0x0
cmd=0x24 rsp=0xd5): Command not supported in present state
c. bmc region lock, before and after the changes.
Command: ipmitool raw 0x3E 0X25 0x00 0x01 0x01 0xff 0xff
Output: f3
Signed-off-by: jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
Change-Id: I05c572c2fe4bd38091301944e85d9246bcf1faa5
diff --git a/include/smbioshandler.hpp b/include/smbioshandler.hpp
index 4e403ca..40e081f 100644
--- a/include/smbioshandler.hpp
+++ b/include/smbioshandler.hpp
@@ -60,12 +60,6 @@
MDRState State;
} __attribute__((packed));
-struct RegionCompleteRequest
-{
- uint8_t sessionId;
- uint8_t regionId;
-} __attribute__((packed));
-
struct RegionReadRequest
{
uint8_t regionId;
@@ -80,21 +74,4 @@
uint8_t data[msgPayloadSize];
} __attribute__((packed));
-struct RegionWriteRequest
-{
- uint8_t sessionId;
- uint8_t regionId;
- uint8_t length;
- uint16_t offset;
- uint8_t data[msgPayloadSize];
-} __attribute__((packed));
-
-struct RegionLockRequest
-{
- uint8_t sessionId;
- uint8_t regionId;
- uint8_t lockPolicy;
- uint16_t msTimeout;
-} __attribute__((packed));
-
constexpr size_t maxMDRId = 5;
diff --git a/src/smbioshandler.cpp b/src/smbioshandler.cpp
index 9eebf7f..0c288b1 100644
--- a/src/smbioshandler.cpp
+++ b/src/smbioshandler.cpp
@@ -34,6 +34,7 @@
constexpr const char* DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
constexpr const char* MDRV1_PATH = "/xyz/openbmc_project/Smbios/MDR_V1";
constexpr const char* MDRV1_INTERFACE = "xyz.openbmc_project.Smbios.MDR_V1";
+static constexpr const uint8_t ccOemSetInProcess = 0x81;
static void register_netfn_smbios_functions() __attribute__((constructor));
@@ -125,63 +126,62 @@
return 0;
}
-ipmi_ret_t cmd_region_complete(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 bmc region update Complete command
+ * @param sessionId - session Lock Handle
+ * @param regionId - data Region
+ *
+ * @returns IPMI completion code
+ */
+ipmi::RspType<> bmcRegionUpdateComplete(uint8_t sessionId, uint8_t regionId)
{
- auto requestData = reinterpret_cast<const RegionCompleteRequest*>(request);
- uint8_t status;
+ std::variant<uint8_t, uint16_t> value;
- sdbusplus::message::variant<uint8_t, uint16_t> value;
-
- if (*data_len != sizeof(RegionCompleteRequest))
- {
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
-
- uint8_t regionId = requestData->regionId - 1;
- *data_len = 0;
-
- if (regionId >= maxMDRId)
+ if ((regionId >= maxMDRId) || (regionId == 0))
{
phosphor::logging::log<level::ERR>("Invalid region");
- return IPMI_CC_PARM_OUT_OF_RANGE;
+ return ipmi::responseParmOutOfRange();
}
std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
- if (set_regionId(regionId, service) < 0)
+ uint8_t regionIdLocal = regionId - 1;
+
+ if (regionIdLocal == 0)
+ {
+ phosphor::logging::log<level::ERR>("Invalid region");
+ return ipmi::responseParmOutOfRange();
+ }
+ if (set_regionId(regionIdLocal, service) < 0)
{
phosphor::logging::log<level::ERR>("Error setting regionId");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
{
phosphor::logging::log<level::ERR>("Error getting lockPolicy");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
if (regionLockUnlocked == std::get<uint8_t>(value))
{
- return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+ return ipmi::responseCommandNotAvailable();
}
if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
{
phosphor::logging::log<level::ERR>("Error getting sessionId");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- if (requestData->sessionId != std::get<uint8_t>(value))
+ if (sessionId != std::get<uint8_t>(value))
{
- return IPMI_CC_OEM_SET_IN_PROCESS;
+ return ipmi::response(ccOemSetInProcess);
}
auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
MDRV1_INTERFACE, "RegionComplete");
- method.append(regionId);
+ method.append(regionIdLocal);
auto reply = bus->call(method);
if (reply.is_method_error())
@@ -190,16 +190,19 @@
"Error set region complete",
phosphor::logging::entry("SERVICE=%s", service.c_str()),
phosphor::logging::entry("PATH=%s", MDRV1_PATH));
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
+ uint8_t status = 0;
reply.read(status);
if (status != 0)
+ {
phosphor::logging::log<level::ERR>(
"Error set region complete, unexpected error");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
+ }
- return IPMI_CC_OK;
+ return ipmi::responseSuccess();
}
ipmi_ret_t cmd_region_read(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
@@ -290,71 +293,64 @@
return IPMI_CC_OK;
}
-ipmi_ret_t cmd_region_write(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 bmc region write command
+ * @parameter
+ * - sessionId - session Lock Handle
+ * - regionId - data Region
+ * - length - data Length
+ * - offset - data Offset
+ * - data - data to be written
+ *
+ * @returns IPMI completion code plus response data
+ * - writeData - contains data Region, valid Data,
+ * lock Status, max Region Length, region Used (in bytes)
+ */
+ipmi::RspType<std::vector<uint8_t>>
+ bmcRegionWrite(uint8_t sessionId, uint8_t regionId, uint8_t length,
+ uint16_t offset, std::vector<uint8_t> data)
{
- auto requestData = reinterpret_cast<const RegionWriteRequest*>(request);
- uint8_t regionId = requestData->regionId - 1;
- std::string res;
- std::vector<uint8_t> writeData;
- uint16_t index;
- uint8_t tmp[255];
+ std::variant<uint8_t, uint16_t> value;
- size_t minInputLen = &requestData->data[0] - &requestData->sessionId + 1;
- if (*data_len < minInputLen)
- { // this command need at least 6 bytes input
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
-
- sdbusplus::message::variant<uint8_t, uint16_t> value;
-
- *data_len = 0;
-
- if (regionId >= maxMDRId)
+ if ((regionId >= maxMDRId) || (regionId == 0))
{
phosphor::logging::log<level::ERR>("Invalid region");
- return IPMI_CC_PARM_OUT_OF_RANGE;
+ return ipmi::responseParmOutOfRange();
}
std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
- if (set_regionId(regionId, service) < 0)
+ uint8_t regionIdLocal = regionId - 1;
+
+ if (set_regionId(regionIdLocal, service) < 0)
{
phosphor::logging::log<level::ERR>("Error setting regionId");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
{
phosphor::logging::log<level::ERR>("Error getting lockPolicy");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
if (regionLockUnlocked == std::get<uint8_t>(value))
{
- return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+ return ipmi::responseCommandNotAvailable();
}
if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
{
phosphor::logging::log<level::ERR>("Error getting sessionId");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- if (requestData->sessionId != std::get<uint8_t>(value))
+ if (sessionId != std::get<uint8_t>(value))
{
- return IPMI_CC_OEM_SET_IN_PROCESS;
+ return ipmi::response(ccOemSetInProcess);
}
- std::copy(&(requestData->length), &(requestData->data[requestData->length]),
- tmp);
- writeData.push_back(regionId);
- for (index = 0; index < minInputLen + requestData->length - 2; index++)
- {
- writeData.push_back(tmp[index]);
- }
-
+ std::vector<uint8_t> writeData;
+ std::copy(data.begin(), data.begin() + length,
+ writeData.data() + sizeof(regionIdLocal) + sizeof(length));
auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
MDRV1_INTERFACE, "RegionWrite");
@@ -367,67 +363,68 @@
"Error write region data",
phosphor::logging::entry("SERVICE=%s", service.c_str()),
phosphor::logging::entry("PATH=%s", MDRV1_PATH));
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
+ std::string res;
reply.read(res);
if (res == "NoData")
{
- return IPMI_CC_PARM_OUT_OF_RANGE;
+ return ipmi::responseParmOutOfRange();
}
else if (res != "Success")
{
phosphor::logging::log<level::ERR>(
"Error write region data, unexpected error");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(writeData);
}
-ipmi_ret_t cmd_region_lock(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 bmc region lock command
+ * @parameter
+ * - sessionId - session Lock Handle
+ * - regionId - data Region
+ * - lockPolicy - Lock Type
+ * - msTimeout - timeout. Number of milliseconds allowed before lock is
+ * released
+ *
+ * @returns IPMI completion code plus response data
+ * - lockResponse - session Lock Handle
+ */
+ipmi::RspType<uint8_t> // lockResponse
+ bmcRegionLock(uint8_t sessionId, uint8_t regionId, uint8_t lockPolicy,
+ uint16_t msTimeout)
{
- auto requestData = reinterpret_cast<const RegionLockRequest*>(request);
- uint8_t regionId = requestData->regionId - 1;
- sdbusplus::message::variant<uint8_t, uint16_t> value;
- auto res = reinterpret_cast<uint8_t*>(response);
- uint8_t lockResponse;
+ std::variant<uint8_t, uint16_t> value;
- if (*data_len != sizeof(RegionLockRequest))
- {
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
-
- *data_len = 0;
-
- if (regionId >= maxMDRId)
+ if ((regionId >= maxMDRId) || (regionId == 0))
{
phosphor::logging::log<level::ERR>("Invalid region");
- return IPMI_CC_PARM_OUT_OF_RANGE;
+ return ipmi::responseParmOutOfRange();
}
std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
- if (set_regionId(regionId, service) < 0)
+ uint8_t regionIdLocal = regionId - 1;
+ if (set_regionId(regionIdLocal, service) < 0)
{
phosphor::logging::log<level::ERR>("Error setting regionId");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
{
phosphor::logging::log<level::ERR>("Error getting lockPolicy");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- if (requestData->lockPolicy == regionLockUnlocked)
+ if (lockPolicy == regionLockUnlocked)
{
if (regionLockUnlocked == std::get<uint8_t>(value))
{
- return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
+ return ipmi::responseCommandNotAvailable();
}
}
if (regionLockUnlocked != std::get<uint8_t>(value))
@@ -435,21 +432,20 @@
if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
{
phosphor::logging::log<level::ERR>("Error getting sessionId");
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
- if (requestData->sessionId != std::get<uint8_t>(value))
+ if (sessionId != std::get<uint8_t>(value))
{
- if (requestData->lockPolicy != regionLockStrict)
+ if (lockPolicy != regionLockStrict)
{
- return IPMI_CC_OEM_SET_IN_PROCESS;
+ return ipmi::response(ccOemSetInProcess);
}
}
}
auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
MDRV1_INTERFACE, "RegionLock");
- method.append(requestData->sessionId, regionId, requestData->lockPolicy,
- requestData->msTimeout);
+ method.append(sessionId, regionIdLocal, lockPolicy, msTimeout);
auto reply = bus->call(method);
if (reply.is_method_error())
@@ -458,13 +454,12 @@
"Error lock region ",
phosphor::logging::entry("SERVICE=%s", service.c_str()),
phosphor::logging::entry("PATH=%s", MDRV1_PATH));
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
+ uint8_t lockResponse = 0;
reply.read(lockResponse);
- *data_len = sizeof(lockResponse);
- *res = lockResponse;
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(lockResponse);
}
static void register_netfn_smbios_functions(void)
@@ -476,9 +471,9 @@
cmd_region_status, PRIVILEGE_OPERATOR);
// <Update Complete Status Command>
- ipmi_register_callback(NETFUN_INTEL_APP_OEM,
- IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_COMPLETE, NULL,
- cmd_region_complete, PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
+ IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_COMPLETE,
+ ipmi::Privilege::Operator, bmcRegionUpdateComplete);
// <Read MDR Command>
ipmi_register_callback(NETFUN_INTEL_APP_OEM,
@@ -486,12 +481,12 @@
cmd_region_read, PRIVILEGE_OPERATOR);
// <Write MDR Command>
- ipmi_register_callback(NETFUN_INTEL_APP_OEM,
- IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_WRITE, NULL,
- cmd_region_write, PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
+ IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_WRITE,
+ ipmi::Privilege::Operator, bmcRegionWrite);
// <Lock MDR Command>
- ipmi_register_callback(NETFUN_INTEL_APP_OEM,
- IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_LOCK, NULL,
- cmd_region_lock, PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
+ IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_LOCK,
+ ipmi::Privilege::Operator, bmcRegionLock);
}