pldmd: implement a new handler registration scheme
Implement a PLDM request handler registration scheme that requires
handlers to be C++ objects rather than plain functions. This was needed
for a couple of reasons:
- Perform specific actions at the PLDM daemon startup (that's when the
handlers are loaded).
- Share data across PLDM request messages (for eg FRU/BIOS tables),
without having to resort to globals and statics.
Tested:
- existing unit tests still pass
- added tests for the new registration scheme
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Change-Id: I1cf1c0a6fccd15da54f08120e61a5f256df6bc36
diff --git a/handler.hpp b/handler.hpp
new file mode 100644
index 0000000..67ad471
--- /dev/null
+++ b/handler.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <functional>
+#include <map>
+
+#include "libpldm/base.h"
+
+namespace pldm
+{
+
+using Command = uint8_t;
+
+namespace responder
+{
+
+using Response = std::vector<uint8_t>;
+class CmdHandler;
+using HandlerFunc =
+ std::function<Response(const pldm_msg* request, size_t reqMsgLen)>;
+
+class CmdHandler
+{
+ public:
+ /** @brief Invoke a PLDM command handler
+ *
+ * @param[in] pldmCommand - PLDM command code
+ * @param[in] request - PLDM request message
+ * @param[in] reqMsgLen - PLDM request message size
+ * @return PLDM response message
+ */
+ Response handle(Command pldmCommand, const pldm_msg* request,
+ size_t reqMsgLen)
+ {
+ return handlers.at(pldmCommand)(request, reqMsgLen);
+ }
+
+ protected:
+ /** @brief map of PLDM command code to handler - to be populated by derived
+ * classes.
+ */
+ std::map<Command, HandlerFunc> handlers;
+};
+
+} // namespace responder
+} // namespace pldm
diff --git a/invoker.hpp b/invoker.hpp
new file mode 100644
index 0000000..c885ee8
--- /dev/null
+++ b/invoker.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "handler.hpp"
+
+#include <map>
+#include <memory>
+
+#include "libpldm/base.h"
+
+namespace pldm
+{
+
+using Type = uint8_t;
+
+namespace responder
+{
+
+class Invoker
+{
+ public:
+ /** @brief Register a handler for a PLDM Type
+ *
+ * @param[in] pldmType - PLDM type code
+ * @param[in] handler - PLDM Type handler
+ */
+ void registerHandler(Type pldmType, std::unique_ptr<CmdHandler> handler)
+ {
+ handlers.emplace(pldmType, std::move(handler));
+ }
+
+ /** @brief Invoke a PLDM command handler
+ *
+ * @param[in] pldmType - PLDM type code
+ * @param[in] pldmCommand - PLDM command code
+ * @param[in] request - PLDM request message
+ * @param[in] reqMsgLen - PLDM request message size
+ * @return PLDM response message
+ */
+ Response handle(Type pldmType, Command pldmCommand, const pldm_msg* request,
+ size_t reqMsgLen)
+ {
+ return handlers.at(pldmType)->handle(pldmCommand, request, reqMsgLen);
+ }
+
+ private:
+ std::map<Type, std::unique_ptr<CmdHandler>> handlers;
+};
+
+} // namespace responder
+} // namespace pldm
diff --git a/libpldmresponder/base.cpp b/libpldmresponder/base.cpp
index e94597a..b9f5ff1 100644
--- a/libpldmresponder/base.cpp
+++ b/libpldmresponder/base.cpp
@@ -1,7 +1,6 @@
#include "libpldm/base.h"
#include "base.hpp"
-#include "registration.hpp"
#include <array>
#include <cstring>
@@ -14,6 +13,9 @@
namespace pldm
{
+
+using Type = uint8_t;
+
namespace responder
{
@@ -36,19 +38,8 @@
namespace base
{
-void registerHandlers()
-{
- registerHandler(PLDM_BASE, PLDM_GET_PLDM_TYPES, std::move(getPLDMTypes));
- registerHandler(PLDM_BASE, PLDM_GET_PLDM_COMMANDS,
- std::move(getPLDMCommands));
- registerHandler(PLDM_BASE, PLDM_GET_PLDM_VERSION,
- std::move(getPLDMVersion));
- registerHandler(PLDM_BASE, PLDM_GET_TID, std::move(getTID));
-}
-
-} // namespace base
-
-Response getPLDMTypes(const pldm_msg* request, size_t /*payloadLength*/)
+Response Handler::getPLDMTypes(const pldm_msg* request,
+ size_t /*payloadLength*/)
{
// DSP0240 has this as a bitfield8[N], where N = 0 to 7
std::array<bitfield8_t, 8> types{};
@@ -68,7 +59,7 @@
return response;
}
-Response getPLDMCommands(const pldm_msg* request, size_t payloadLength)
+Response Handler::getPLDMCommands(const pldm_msg* request, size_t payloadLength)
{
ver32_t version{};
Type type;
@@ -109,7 +100,7 @@
return response;
}
-Response getPLDMVersion(const pldm_msg* request, size_t payloadLength)
+Response Handler::getPLDMVersion(const pldm_msg* request, size_t payloadLength)
{
uint32_t transferHandle;
Type type;
@@ -147,7 +138,7 @@
return response;
}
-Response getTID(const pldm_msg* request, size_t /*payloadLength*/)
+Response Handler::getTID(const pldm_msg* request, size_t /*payloadLength*/)
{
// assigned 1 to the bmc as the PLDM terminus
uint8_t tid = 1;
@@ -160,5 +151,6 @@
return response;
}
+} // namespace base
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/base.hpp b/libpldmresponder/base.hpp
index a6e5abd..519bff2 100644
--- a/libpldmresponder/base.hpp
+++ b/libpldmresponder/base.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "handler.hpp"
+
#include <stdint.h>
#include <vector>
@@ -8,51 +10,67 @@
namespace pldm
{
-
-using Type = uint8_t;
-
-using Response = std::vector<uint8_t>;
-
namespace responder
{
-
namespace base
{
-/** @brief Register handlers for command from the base spec
- */
-void registerHandlers();
+
+class Handler : public CmdHandler
+{
+ public:
+ Handler()
+ {
+ handlers.emplace(PLDM_GET_PLDM_TYPES,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->getPLDMTypes(request, payloadLength);
+ });
+ handlers.emplace(PLDM_GET_PLDM_COMMANDS, [this](const pldm_msg* request,
+ size_t payloadLength) {
+ return this->getPLDMCommands(request, payloadLength);
+ });
+ handlers.emplace(PLDM_GET_PLDM_VERSION, [this](const pldm_msg* request,
+ size_t payloadLength) {
+ return this->getPLDMVersion(request, payloadLength);
+ });
+ handlers.emplace(PLDM_GET_TID,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->getTID(request, payloadLength);
+ });
+ }
+
+ /** @brief Handler for getPLDMTypes
+ *
+ * @param[in] request - Request message payload
+ * @param[in] payload_length - Request message payload length
+ * @param[return] Response - PLDM Response message
+ */
+ Response getPLDMTypes(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for getPLDMCommands
+ *
+ * @param[in] request - Request message payload
+ * @param[in] payload_length - Request message payload length
+ * @param[return] Response - PLDM Response message
+ */
+ Response getPLDMCommands(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for getPLDMCommands
+ *
+ * @param[in] request - Request message payload
+ * @param[in] payload_length - Request message payload length
+ * @param[return] Response - PLDM Response message
+ */
+ Response getPLDMVersion(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for getTID
+ *
+ * @param[in] request - Request message payload
+ * @param[in] payload_length - Request message payload length
+ * @param[return] Response - PLDM Response message
+ */
+ Response getTID(const pldm_msg* request, size_t payloadLength);
+};
+
} // namespace base
-
-/** @brief Handler for getPLDMTypes
- *
- * @param[in] request - Request message payload
- * @param[in] payload_length - Request message payload length
- * @param[return] Response - PLDM Response message
- */
-Response getPLDMTypes(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Handler for getPLDMCommands
- *
- * @param[in] request - Request message payload
- * @param[in] payload_length - Request message payload length
- * @param[return] Response - PLDM Response message
- */
-Response getPLDMCommands(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Handler for getPLDMCommands
- *
- * @param[in] request - Request message payload
- * @param[in] payload_length - Request message payload length
- * @param[return] Response - PLDM Response message
- */
-Response getPLDMVersion(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Handler for getTID
- *
- * @param[in] request - Request message payload
- * @param[in] payload_length - Request message payload length
- * @param[return] Response - PLDM Response message
- */
-Response getTID(const pldm_msg* request, size_t payloadLength);
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index 1c48f1a..c3a1c53 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -1,7 +1,6 @@
#include "bios.hpp"
#include "libpldmresponder/utils.hpp"
-#include "registration.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
#include <array>
@@ -72,7 +71,10 @@
} // namespace utils
-Response getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
+namespace bios
+{
+
+Response Handler::getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
{
uint8_t seconds = 0;
uint8_t minutes = 0;
@@ -117,7 +119,8 @@
std::chrono::microseconds(timeUsec))
.count();
- utils::epochToBCDTime(timeSec, seconds, minutes, hours, day, month, year);
+ pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
+ day, month, year);
encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS, seconds,
minutes, hours, day, month, year, responsePtr);
@@ -163,7 +166,8 @@
});
Table stringTable;
- stringTable.reserve(utils::getTableTotalsize(sizeWithoutPad));
+ stringTable.reserve(
+ pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
stringTable.resize(sizeWithoutPad);
auto tablePtr = stringTable.data();
@@ -177,7 +181,7 @@
sizeWithoutPad -= entry_length;
}
- utils::padAndChecksum(stringTable);
+ pldm::responder::utils::padAndChecksum(stringTable);
BIOSStringTable.store(stringTable);
response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
stringTable.size(),
@@ -647,7 +651,7 @@
response.size(), responsePtr);
return response;
}
- utils::padAndChecksum(attributeTable);
+ pldm::responder::utils::padAndChecksum(attributeTable);
BIOSAttributeTable.store(attributeTable);
response.resize(sizeof(pldm_msg_hdr) +
PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
@@ -751,7 +755,7 @@
response.size(), responsePtr);
return response;
}
- utils::padAndChecksum(attributeValueTable);
+ pldm::responder::utils::padAndChecksum(attributeValueTable);
BIOSAttributeValueTable.store(attributeValueTable);
response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
@@ -764,7 +768,7 @@
return response;
}
-Response getBIOSTable(const pldm_msg* request, size_t payloadLength)
+Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
{
fs::create_directory(BIOS_TABLES_DIR);
auto response = internal::buildBIOSTables(request, payloadLength,
@@ -773,15 +777,6 @@
return response;
}
-namespace bios
-{
-
-void registerHandlers()
-{
- registerHandler(PLDM_BIOS, PLDM_GET_DATE_TIME, std::move(getDateTime));
- registerHandler(PLDM_BIOS, PLDM_GET_BIOS_TABLE, std::move(getBIOSTable));
-}
-
namespace internal
{
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index 412e07a..e9abed2 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -4,6 +4,7 @@
#include "bios_parser.hpp"
#include "bios_table.hpp"
+#include "handler.hpp"
#include <stdint.h>
@@ -17,7 +18,6 @@
namespace pldm
{
-using Response = std::vector<uint8_t>;
using AttributeHandle = uint16_t;
using StringHandle = uint16_t;
using PossibleValuesByHandle = std::vector<StringHandle>;
@@ -25,18 +25,15 @@
namespace responder
{
+namespace bios
+{
+
using AttrTableEntryHandler =
std::function<void(const struct pldm_bios_attr_table_entry*)>;
void traverseBIOSAttrTable(const bios::Table& BIOSAttrTable,
AttrTableEntryHandler handler);
-namespace bios
-{
-/** @brief Register handlers for command from the platform spec
- */
-void registerHandlers();
-
namespace internal
{
@@ -49,25 +46,41 @@
*/
Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
const char* biosJsonDir, const char* biosTablePath);
-} // end namespace internal
+} // namespace internal
+
+class Handler : public CmdHandler
+{
+ public:
+ Handler()
+ {
+ handlers.emplace(PLDM_GET_DATE_TIME,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->getDateTime(request, payloadLength);
+ });
+ handlers.emplace(PLDM_GET_BIOS_TABLE,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->getBIOSTable(request, payloadLength);
+ });
+ }
+
+ /** @brief Handler for GetDateTime
+ *
+ * @param[in] request - Request message payload
+ * @param[return] Response - PLDM Response message
+ */
+ Response getDateTime(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for GetBIOSTable
+ *
+ * @param[in] request - Request message
+ * @param[in] payload_length - Request message payload length
+ * @param[return] Response - PLDM Response message
+ */
+ Response getBIOSTable(const pldm_msg* request, size_t payloadLength);
+};
} // namespace bios
-/** @brief Handler for GetDateTime
- *
- * @param[in] request - Request message payload
- * @param[return] Response - PLDM Response message
- */
-Response getDateTime(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Handler for GetBIOSTable
- *
- * @param[in] request - Request message
- * @param[in] payload_length - Request message payload length
- * @param[return] Response - PLDM Response message
- */
-Response getBIOSTable(const pldm_msg* request, size_t payloadLength);
-
namespace utils
{
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 770ef8c..8ad31d4 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -14,7 +14,6 @@
'effecters.cpp',
'utils.cpp',
'platform.cpp',
- '../registration.cpp'
]
if get_option('oem-ibm').enabled()
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 538c49c..50237cf 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -1,30 +1,17 @@
#include "platform.hpp"
-#include "registration.hpp"
-
namespace pldm
{
-
namespace responder
{
-
namespace platform
{
-void registerHandlers()
-{
- registerHandler(PLDM_PLATFORM, PLDM_GET_PDR, std::move(getPDR));
- registerHandler(PLDM_PLATFORM, PLDM_SET_STATE_EFFECTER_STATES,
- std::move(setStateEffecterStates));
-}
-
-} // namespace platform
-
using namespace phosphor::logging;
using namespace pldm::responder::effecter::dbus_mapping;
-Response getPDR(const pldm_msg* request, size_t payloadLength)
+Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
{
Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
@@ -92,7 +79,8 @@
return response;
}
-Response setStateEffecterStates(const pldm_msg* request, size_t payloadLength)
+Response Handler::setStateEffecterStates(const pldm_msg* request,
+ size_t payloadLength)
{
Response response(
sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
@@ -129,5 +117,6 @@
return response;
}
+} // namespace platform
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index ec168f4..be48950 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -2,6 +2,7 @@
#include "config.h"
+#include "handler.hpp"
#include "libpldmresponder/pdr.hpp"
#include "libpldmresponder/utils.hpp"
@@ -14,254 +15,269 @@
namespace pldm
{
-
-using Response = std::vector<uint8_t>;
-
namespace responder
{
-
namespace platform
{
-/** @brief Register handlers for commands from the platform spec
- */
-void registerHandlers();
-
-} // namespace platform
-
-/** @brief Handler for GetPDR
- *
- * @param[in] request - Request message payload
- * @param[in] payloadLength - Request payload length
- * @param[out] Response - Response message written here
- */
-Response getPDR(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Handler for setStateEffecterStates
- *
- * @param[in] request - Request message
- * @param[in] payloadLength - Request payload length
- * @return Response - PLDM Response message
- */
-Response setStateEffecterStates(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Function to set the effecter requested by pldm requester
- * @param[in] dBusIntf - The interface object
- * @param[in] effecterId - Effecter ID sent by the requester to act on
- * @param[in] stateField - The state field data for each of the states, equal
- * to composite effecter count in number
- * @return - Success or failure in setting the states. Returns failure in terms
- * of PLDM completion codes if atleast one state fails to be set
- */
-template <class DBusInterface>
-int setStateEffecterStatesHandler(
- const DBusInterface& dBusIntf, effecter::Id effecterId,
- const std::vector<set_effecter_state_field>& stateField)
+class Handler : public CmdHandler
{
- using namespace std::string_literals;
- using DBusProperty = std::variant<std::string, bool>;
- using StateSetId = uint16_t;
- using StateSetNum = uint8_t;
- using PropertyMap =
- std::map<StateSetId, std::map<StateSetNum, DBusProperty>>;
- static const PropertyMap stateNumToDbusProp = {
- {PLDM_BOOT_PROGRESS_STATE,
- {{PLDM_BOOT_NOT_ACTIVE,
- "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
- "Standby"s},
- {PLDM_BOOT_COMPLETED,
- "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
- "BootComplete"s}}},
- {PLDM_SYSTEM_POWER_STATE,
- {{PLDM_OFF_SOFT_GRACEFUL,
- "xyz.openbmc_project.State.Chassis.Transition.Off"s}}}};
- using namespace phosphor::logging;
- using namespace pldm::responder::pdr;
- using namespace pldm::responder::effecter::dbus_mapping;
-
- state_effecter_possible_states* states = nullptr;
- pldm_state_effecter_pdr* pdr = nullptr;
- uint8_t compEffecterCnt = stateField.size();
- uint32_t recordHndl{};
- Repo& pdrRepo = get(PDR_JSONS_DIR);
- pdr::Entry pdrEntry{};
-
- while (!pdr)
+ public:
+ Handler()
{
- pdrEntry = pdrRepo.at(recordHndl);
- pldm_pdr_hdr* header = reinterpret_cast<pldm_pdr_hdr*>(pdrEntry.data());
- if (header->type != PLDM_STATE_EFFECTER_PDR)
- {
- recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
- if (recordHndl)
- {
- continue;
- }
- return PLDM_PLATFORM_INVALID_EFFECTER_ID;
- }
- pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data());
- recordHndl = pdr->hdr.record_handle;
- if (pdr->effecter_id == effecterId)
- {
- states = reinterpret_cast<state_effecter_possible_states*>(
- pdr->possible_states);
- if (compEffecterCnt > pdr->composite_effecter_count)
- {
- log<level::ERR>("The requester sent wrong composite effecter "
- "count for the effecter",
- entry("EFFECTER_ID=%d", effecterId),
- entry("COMP_EFF_CNT=%d", compEffecterCnt));
- return PLDM_ERROR_INVALID_DATA;
- }
- break;
- }
- recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
- if (!recordHndl)
- {
- return PLDM_PLATFORM_INVALID_EFFECTER_ID;
- }
- pdr = nullptr;
+ handlers.emplace(PLDM_GET_PDR,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->getPDR(request, payloadLength);
+ });
+ handlers.emplace(PLDM_SET_STATE_EFFECTER_STATES,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->setStateEffecterStates(request,
+ payloadLength);
+ });
}
- std::map<StateSetId, std::function<int(const std::string& objPath,
- const uint8_t currState)>>
- effecterToDbusEntries = {
- {PLDM_BOOT_PROGRESS_STATE,
- [&](const std::string& objPath, const uint8_t currState) {
- auto stateSet =
- stateNumToDbusProp.find(PLDM_BOOT_PROGRESS_STATE);
- if (stateSet == stateNumToDbusProp.end())
- {
- log<level::ERR>("Couldn't find D-Bus mapping for "
- "PLDM_BOOT_PROGRESS_STATE",
- entry("EFFECTER_ID=%d", effecterId));
- return PLDM_ERROR;
- }
- auto iter = stateSet->second.find(
- stateField[currState].effecter_state);
- if (iter == stateSet->second.end())
- {
- log<level::ERR>(
- "Invalid state field passed or field not "
- "found for PLDM_BOOT_PROGRESS_STATE",
- entry("EFFECTER_ID=%d", effecterId),
- entry("FIELD=%d",
- stateField[currState].effecter_state),
- entry("OBJECT_PATH=%s", objPath.c_str()));
- return PLDM_ERROR_INVALID_DATA;
- }
- auto dbusProp = "OperatingSystemState";
- std::variant<std::string> value{
- std::get<std::string>(iter->second)};
- auto dbusInterface =
- "xyz.openbmc_project.State.OperatingSystem.Status";
- try
- {
- dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
- dbusInterface, value);
- }
- catch (const std::exception& e)
- {
- log<level::ERR>("Error setting property",
- entry("ERROR=%s", e.what()),
- entry("PROPERTY=%s", dbusProp),
- entry("INTERFACE=%s", dbusInterface),
- entry("PATH=%s", objPath.c_str()));
- return PLDM_ERROR;
- }
- return PLDM_SUCCESS;
- }},
- {PLDM_SYSTEM_POWER_STATE,
- [&](const std::string& objPath, const uint8_t currState) {
- auto stateSet =
- stateNumToDbusProp.find(PLDM_SYSTEM_POWER_STATE);
- if (stateSet == stateNumToDbusProp.end())
- {
- log<level::ERR>("Couldn't find D-Bus mapping for "
- "PLDM_SYSTEM_POWER_STATE",
- entry("EFFECTER_ID=%d", effecterId));
- return PLDM_ERROR;
- }
- auto iter = stateSet->second.find(
- stateField[currState].effecter_state);
- if (iter == stateSet->second.end())
- {
- log<level::ERR>(
- "Invalid state field passed or field not "
- "found for PLDM_SYSTEM_POWER_STATE",
- entry("EFFECTER_ID=%d", effecterId),
- entry("FIELD=%d",
- stateField[currState].effecter_state),
- entry("OBJECT_PATH=%s", objPath.c_str()));
- return PLDM_ERROR_INVALID_DATA;
- }
- auto dbusProp = "RequestedPowerTransition";
- std::variant<std::string> value{
- std::get<std::string>(iter->second)};
- auto dbusInterface = "xyz.openbmc_project.State.Chassis";
- try
- {
- dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
- dbusInterface, value);
- }
- catch (const std::exception& e)
- {
- log<level::ERR>("Error setting property",
- entry("ERROR=%s", e.what()),
- entry("PROPERTY=%s", dbusProp),
- entry("INTERFACE=%s", dbusInterface),
- entry("PATH=%s", objPath.c_str()));
- return PLDM_ERROR;
- }
- return PLDM_SUCCESS;
- }}};
+ /** @brief Handler for GetPDR
+ *
+ * @param[in] request - Request message payload
+ * @param[in] payloadLength - Request payload length
+ * @param[out] Response - Response message written here
+ */
+ Response getPDR(const pldm_msg* request, size_t payloadLength);
- int rc = PLDM_SUCCESS;
- auto paths = get(effecterId);
- for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
+ /** @brief Handler for setStateEffecterStates
+ *
+ * @param[in] request - Request message
+ * @param[in] payloadLength - Request payload length
+ * @return Response - PLDM Response message
+ */
+ Response setStateEffecterStates(const pldm_msg* request,
+ size_t payloadLength);
+
+ /** @brief Function to set the effecter requested by pldm requester
+ * @param[in] dBusIntf - The interface object
+ * @param[in] effecterId - Effecter ID sent by the requester to act on
+ * @param[in] stateField - The state field data for each of the states,
+ * equal to composite effecter count in number
+ * @return - Success or failure in setting the states. Returns failure in
+ * terms of PLDM completion codes if atleast one state fails to be set
+ */
+ template <class DBusInterface>
+ int setStateEffecterStatesHandler(
+ const DBusInterface& dBusIntf, effecter::Id effecterId,
+ const std::vector<set_effecter_state_field>& stateField)
{
- std::vector<StateSetNum> allowed{};
- // computation is based on table 79 from DSP0248 v1.1.1
- uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
- uint8_t bit =
- stateField[currState].effecter_state - (8 * bitfieldIndex);
- if (states->possible_states_size < bitfieldIndex ||
- !(states->states[bitfieldIndex].byte & (1 << bit)))
+ using namespace std::string_literals;
+ using DBusProperty = std::variant<std::string, bool>;
+ using StateSetId = uint16_t;
+ using StateSetNum = uint8_t;
+ using PropertyMap =
+ std::map<StateSetId, std::map<StateSetNum, DBusProperty>>;
+ static const PropertyMap stateNumToDbusProp = {
+ {PLDM_BOOT_PROGRESS_STATE,
+ {{PLDM_BOOT_NOT_ACTIVE,
+ "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
+ "Standby"s},
+ {PLDM_BOOT_COMPLETED,
+ "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
+ "BootComplete"s}}},
+ {PLDM_SYSTEM_POWER_STATE,
+ {{PLDM_OFF_SOFT_GRACEFUL,
+ "xyz.openbmc_project.State.Chassis.Transition.Off"s}}}};
+ using namespace phosphor::logging;
+ using namespace pldm::responder::pdr;
+ using namespace pldm::responder::effecter::dbus_mapping;
+
+ state_effecter_possible_states* states = nullptr;
+ pldm_state_effecter_pdr* pdr = nullptr;
+ uint8_t compEffecterCnt = stateField.size();
+ uint32_t recordHndl{};
+ Repo& pdrRepo = get(PDR_JSONS_DIR);
+ pdr::Entry pdrEntry{};
+
+ while (!pdr)
{
- log<level::ERR>(
- "Invalid state set value", entry("EFFECTER_ID=%d", effecterId),
- entry("VALUE=%d", stateField[currState].effecter_state),
- entry("COMPOSITE_EFFECTER_ID=%d", currState),
- entry("DBUS_PATH=%c", paths[currState].c_str()));
- rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
- break;
- }
- auto iter = effecterToDbusEntries.find(states->state_set_id);
- if (iter == effecterToDbusEntries.end())
- {
- uint16_t setId = states->state_set_id;
- log<level::ERR>(
- "Did not find the state set for the state effecter pdr ",
- entry("STATE=%d", setId), entry("EFFECTER_ID=%d", effecterId));
- rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
- break;
- }
- if (stateField[currState].set_request == PLDM_REQUEST_SET)
- {
- rc = iter->second(paths[currState], currState);
- if (rc != PLDM_SUCCESS)
+ pdrEntry = pdrRepo.at(recordHndl);
+ pldm_pdr_hdr* header =
+ reinterpret_cast<pldm_pdr_hdr*>(pdrEntry.data());
+ if (header->type != PLDM_STATE_EFFECTER_PDR)
{
+ recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
+ if (recordHndl)
+ {
+ continue;
+ }
+ return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+ }
+ pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data());
+ recordHndl = pdr->hdr.record_handle;
+ if (pdr->effecter_id == effecterId)
+ {
+ states = reinterpret_cast<state_effecter_possible_states*>(
+ pdr->possible_states);
+ if (compEffecterCnt > pdr->composite_effecter_count)
+ {
+ log<level::ERR>(
+ "The requester sent wrong composite effecter "
+ "count for the effecter",
+ entry("EFFECTER_ID=%d", effecterId),
+ entry("COMP_EFF_CNT=%d", compEffecterCnt));
+ return PLDM_ERROR_INVALID_DATA;
+ }
break;
}
+ recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
+ if (!recordHndl)
+ {
+ return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+ }
+ pdr = nullptr;
}
- uint8_t* nextState =
- reinterpret_cast<uint8_t*>(states) +
- sizeof(state_effecter_possible_states) - sizeof(states->states) +
- (states->possible_states_size * sizeof(states->states));
- states = reinterpret_cast<state_effecter_possible_states*>(nextState);
- }
- return rc;
-}
+ std::map<StateSetId, std::function<int(const std::string& objPath,
+ const uint8_t currState)>>
+ effecterToDbusEntries = {
+ {PLDM_BOOT_PROGRESS_STATE,
+ [&](const std::string& objPath, const uint8_t currState) {
+ auto stateSet =
+ stateNumToDbusProp.find(PLDM_BOOT_PROGRESS_STATE);
+ if (stateSet == stateNumToDbusProp.end())
+ {
+ log<level::ERR>("Couldn't find D-Bus mapping for "
+ "PLDM_BOOT_PROGRESS_STATE",
+ entry("EFFECTER_ID=%d", effecterId));
+ return PLDM_ERROR;
+ }
+ auto iter = stateSet->second.find(
+ stateField[currState].effecter_state);
+ if (iter == stateSet->second.end())
+ {
+ log<level::ERR>(
+ "Invalid state field passed or field not "
+ "found for PLDM_BOOT_PROGRESS_STATE",
+ entry("EFFECTER_ID=%d", effecterId),
+ entry("FIELD=%d",
+ stateField[currState].effecter_state),
+ entry("OBJECT_PATH=%s", objPath.c_str()));
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ auto dbusProp = "OperatingSystemState";
+ std::variant<std::string> value{
+ std::get<std::string>(iter->second)};
+ auto dbusInterface =
+ "xyz.openbmc_project.State.OperatingSystem.Status";
+ try
+ {
+ dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
+ dbusInterface, value);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Error setting property",
+ entry("ERROR=%s", e.what()),
+ entry("PROPERTY=%s", dbusProp),
+ entry("INTERFACE=%s", dbusInterface),
+ entry("PATH=%s", objPath.c_str()));
+ return PLDM_ERROR;
+ }
+ return PLDM_SUCCESS;
+ }},
+ {PLDM_SYSTEM_POWER_STATE,
+ [&](const std::string& objPath, const uint8_t currState) {
+ auto stateSet =
+ stateNumToDbusProp.find(PLDM_SYSTEM_POWER_STATE);
+ if (stateSet == stateNumToDbusProp.end())
+ {
+ log<level::ERR>("Couldn't find D-Bus mapping for "
+ "PLDM_SYSTEM_POWER_STATE",
+ entry("EFFECTER_ID=%d", effecterId));
+ return PLDM_ERROR;
+ }
+ auto iter = stateSet->second.find(
+ stateField[currState].effecter_state);
+ if (iter == stateSet->second.end())
+ {
+ log<level::ERR>(
+ "Invalid state field passed or field not "
+ "found for PLDM_SYSTEM_POWER_STATE",
+ entry("EFFECTER_ID=%d", effecterId),
+ entry("FIELD=%d",
+ stateField[currState].effecter_state),
+ entry("OBJECT_PATH=%s", objPath.c_str()));
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ auto dbusProp = "RequestedPowerTransition";
+ std::variant<std::string> value{
+ std::get<std::string>(iter->second)};
+ auto dbusInterface = "xyz.openbmc_project.State.Chassis";
+ try
+ {
+ dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
+ dbusInterface, value);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Error setting property",
+ entry("ERROR=%s", e.what()),
+ entry("PROPERTY=%s", dbusProp),
+ entry("INTERFACE=%s", dbusInterface),
+ entry("PATH=%s", objPath.c_str()));
+ return PLDM_ERROR;
+ }
+ return PLDM_SUCCESS;
+ }}};
+
+ int rc = PLDM_SUCCESS;
+ auto paths = get(effecterId);
+ for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
+ {
+ std::vector<StateSetNum> allowed{};
+ // computation is based on table 79 from DSP0248 v1.1.1
+ uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
+ uint8_t bit =
+ stateField[currState].effecter_state - (8 * bitfieldIndex);
+ if (states->possible_states_size < bitfieldIndex ||
+ !(states->states[bitfieldIndex].byte & (1 << bit)))
+ {
+ log<level::ERR>(
+ "Invalid state set value",
+ entry("EFFECTER_ID=%d", effecterId),
+ entry("VALUE=%d", stateField[currState].effecter_state),
+ entry("COMPOSITE_EFFECTER_ID=%d", currState),
+ entry("DBUS_PATH=%c", paths[currState].c_str()));
+ rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
+ break;
+ }
+ auto iter = effecterToDbusEntries.find(states->state_set_id);
+ if (iter == effecterToDbusEntries.end())
+ {
+ uint16_t setId = states->state_set_id;
+ log<level::ERR>(
+ "Did not find the state set for the state effecter pdr ",
+ entry("STATE=%d", setId),
+ entry("EFFECTER_ID=%d", effecterId));
+ rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
+ break;
+ }
+ if (stateField[currState].set_request == PLDM_REQUEST_SET)
+ {
+ rc = iter->second(paths[currState], currState);
+ if (rc != PLDM_SUCCESS)
+ {
+ break;
+ }
+ }
+ uint8_t* nextState =
+ reinterpret_cast<uint8_t*>(states) +
+ sizeof(state_effecter_possible_states) -
+ sizeof(states->states) +
+ (states->possible_states_size * sizeof(states->states));
+ states =
+ reinterpret_cast<state_effecter_possible_states*>(nextState);
+ }
+ return rc;
+ }
+};
+
+} // namespace platform
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io.cpp b/oem/ibm/libpldmresponder/file_io.cpp
index 05051b6..963a6b6 100644
--- a/oem/ibm/libpldmresponder/file_io.cpp
+++ b/oem/ibm/libpldmresponder/file_io.cpp
@@ -5,7 +5,6 @@
#include "file_io_by_type.hpp"
#include "file_table.hpp"
#include "libpldmresponder/utils.hpp"
-#include "registration.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
#include <fcntl.h>
@@ -31,28 +30,6 @@
namespace responder
{
-namespace oem_ibm
-{
-
-void registerHandlers()
-{
- registerHandler(PLDM_OEM, PLDM_GET_FILE_TABLE, std::move(getFileTable));
- registerHandler(PLDM_OEM, PLDM_READ_FILE_INTO_MEMORY,
- std::move(readFileIntoMemory));
- registerHandler(PLDM_OEM, PLDM_WRITE_FILE_FROM_MEMORY,
- std::move(writeFileFromMemory));
- registerHandler(PLDM_OEM, PLDM_READ_FILE, std::move(readFile));
- registerHandler(PLDM_OEM, PLDM_WRITE_FILE, std::move(writeFile));
- registerHandler(PLDM_OEM, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
- std::move(writeFileByTypeFromMemory));
- registerHandler(PLDM_OEM, PLDM_READ_FILE_BY_TYPE_INTO_MEMORY,
- std::move(readFileByTypeIntoMemory));
- registerHandler(PLDM_OEM, PLDM_READ_FILE_BY_TYPE,
- std::move(readFileByType));
-}
-
-} // namespace oem_ibm
-
namespace fs = std::filesystem;
using namespace phosphor::logging;
@@ -173,7 +150,11 @@
} // namespace dma
-Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength)
+namespace oem_ibm
+{
+
+Response Handler::readFileIntoMemory(const pldm_msg* request,
+ size_t payloadLength)
{
uint32_t fileHandle = 0;
uint32_t offset = 0;
@@ -254,7 +235,8 @@
request->hdr.instance_id);
}
-Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength)
+Response Handler::writeFileFromMemory(const pldm_msg* request,
+ size_t payloadLength)
{
uint32_t fileHandle = 0;
uint32_t offset = 0;
@@ -330,7 +312,7 @@
request->hdr.instance_id);
}
-Response getFileTable(const pldm_msg* request, size_t payloadLength)
+Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
{
uint32_t transferHandle = 0;
uint8_t transferFlag = 0;
@@ -385,7 +367,7 @@
return response;
}
-Response readFile(const pldm_msg* request, size_t payloadLength)
+Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
{
uint32_t fileHandle = 0;
uint32_t offset = 0;
@@ -465,7 +447,7 @@
return response;
}
-Response writeFile(const pldm_msg* request, size_t payloadLength)
+Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
{
uint32_t fileHandle = 0;
uint32_t offset = 0;
@@ -601,20 +583,21 @@
return response;
}
-Response writeFileByTypeFromMemory(const pldm_msg* request,
- size_t payloadLength)
+Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
+ size_t payloadLength)
{
return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
payloadLength);
}
-Response readFileByTypeIntoMemory(const pldm_msg* request, size_t payloadLength)
+Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
+ size_t payloadLength)
{
return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
payloadLength);
}
-Response readFileByType(const pldm_msg* request, size_t payloadLength)
+Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
{
Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
@@ -661,5 +644,6 @@
return response;
}
+} // namespace oem_ibm
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io.hpp b/oem/ibm/libpldmresponder/file_io.hpp
index 07a13aa..231222c 100644
--- a/oem/ibm/libpldmresponder/file_io.hpp
+++ b/oem/ibm/libpldmresponder/file_io.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "handler.hpp"
+
#include <stdint.h>
#include <unistd.h>
@@ -11,19 +13,8 @@
namespace pldm
{
-
namespace responder
{
-
-namespace oem_ibm
-{
-/** @brief Register handlers for command from the platform spec
- */
-void registerHandlers();
-} // namespace oem_ibm
-
-using Response = std::vector<uint8_t>;
-
namespace dma
{
@@ -121,79 +112,128 @@
} // namespace dma
-/** @brief Handler for readFileIntoMemory command
- *
- * @param[in] request - pointer to PLDM request payload
- * @param[in] payloadLength - length of the message
- *
- * @return PLDM response message
- */
-Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength);
+namespace oem_ibm
+{
-/** @brief Handler for writeFileIntoMemory command
- *
- * @param[in] request - pointer to PLDM request payload
- * @param[in] payloadLength - length of the message
- *
- * @return PLDM response message
- */
-Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength);
+class Handler : public CmdHandler
+{
+ public:
+ Handler()
+ {
+ handlers.emplace(PLDM_READ_FILE_INTO_MEMORY,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->readFileIntoMemory(request,
+ payloadLength);
+ });
+ handlers.emplace(PLDM_WRITE_FILE_FROM_MEMORY,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->writeFileFromMemory(request,
+ payloadLength);
+ });
+ handlers.emplace(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->writeFileByTypeFromMemory(
+ request, payloadLength);
+ });
+ handlers.emplace(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->readFileByTypeIntoMemory(
+ request, payloadLength);
+ });
+ handlers.emplace(PLDM_READ_FILE_BY_TYPE, [this](const pldm_msg* request,
+ size_t payloadLength) {
+ return this->readFileByType(request, payloadLength);
+ });
+ handlers.emplace(PLDM_GET_FILE_TABLE,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->getFileTable(request, payloadLength);
+ });
+ handlers.emplace(PLDM_READ_FILE,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->readFile(request, payloadLength);
+ });
+ handlers.emplace(PLDM_WRITE_FILE,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->writeFile(request, payloadLength);
+ });
+ }
-/** @brief Handler for writeFileByTypeFromMemory command
- *
- * @param[in] request - pointer to PLDM request payload
- * @param[in] payloadLength - length of the message
- *
- * @return PLDM response message
- */
+ /** @brief Handler for readFileIntoMemory command
+ *
+ * @param[in] request - pointer to PLDM request payload
+ * @param[in] payloadLength - length of the message
+ *
+ * @return PLDM response message
+ */
+ Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength);
-Response writeFileByTypeFromMemory(const pldm_msg* request,
- size_t payloadLength);
+ /** @brief Handler for writeFileIntoMemory command
+ *
+ * @param[in] request - pointer to PLDM request payload
+ * @param[in] payloadLength - length of the message
+ *
+ * @return PLDM response message
+ */
+ Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength);
-/** @brief Handler for readFileByTypeIntoMemory command
- *
- * @param[in] request - pointer to PLDM request payload
- * @param[in] payloadLength - length of the message
- *
- * @return PLDM response message
- */
-Response readFileByTypeIntoMemory(const pldm_msg* request,
- size_t payloadLength);
+ /** @brief Handler for writeFileByTypeFromMemory command
+ *
+ * @param[in] request - pointer to PLDM request payload
+ * @param[in] payloadLength - length of the message
+ *
+ * @return PLDM response message
+ */
-/** @brief Handler for readFileByType command
- *
- * @param[in] request - pointer to PLDM request payload
- * @param[in] payloadLength - length of the message
- *
- * @return PLDM response message
- */
-Response readFileByType(const pldm_msg* request, size_t payloadLength);
+ Response writeFileByTypeFromMemory(const pldm_msg* request,
+ size_t payloadLength);
-/** @brief Handler for GetFileTable command
- *
- * @param[in] request - pointer to PLDM request payload
- * @param[in] payloadLength - length of the message payload
- *
- * @return PLDM response message
- */
-Response getFileTable(const pldm_msg* request, size_t payloadLength);
+ /** @brief Handler for readFileByTypeIntoMemory command
+ *
+ * @param[in] request - pointer to PLDM request payload
+ * @param[in] payloadLength - length of the message
+ *
+ * @return PLDM response message
+ */
+ Response readFileByTypeIntoMemory(const pldm_msg* request,
+ size_t payloadLength);
-/** @brief Handler for readFile command
- *
- * @param[in] request - PLDM request msg
- * @param[in] payloadLength - length of the message payload
- *
- * @return PLDM response message
- */
-Response readFile(const pldm_msg* request, size_t payloadLength);
+ /** @brief Handler for readFileByType command
+ *
+ * @param[in] request - pointer to PLDM request payload
+ * @param[in] payloadLength - length of the message
+ *
+ * @return PLDM response message
+ */
+ Response readFileByType(const pldm_msg* request, size_t payloadLength);
-/** @brief Handler for writeFile command
- *
- * @param[in] request - PLDM request msg
- * @param[in] payloadLength - length of the message payload
- *
- * @return PLDM response message
- */
-Response writeFile(const pldm_msg* request, size_t payloadLength);
+ /** @brief Handler for GetFileTable command
+ *
+ * @param[in] request - pointer to PLDM request payload
+ * @param[in] payloadLength - length of the message payload
+ *
+ * @return PLDM response message
+ */
+ Response getFileTable(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for readFile command
+ *
+ * @param[in] request - PLDM request msg
+ * @param[in] payloadLength - length of the message payload
+ *
+ * @return PLDM response message
+ */
+ Response readFile(const pldm_msg* request, size_t payloadLength);
+
+ /** @brief Handler for writeFile command
+ *
+ * @param[in] request - PLDM request msg
+ * @param[in] payloadLength - length of the message payload
+ *
+ * @return PLDM response message
+ */
+ Response writeFile(const pldm_msg* request, size_t payloadLength);
+};
+
+} // namespace oem_ibm
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/test/libpldmresponder_fileio_test.cpp b/oem/ibm/test/libpldmresponder_fileio_test.cpp
index 3894ff3..e62e8e1 100644
--- a/oem/ibm/test/libpldmresponder_fileio_test.cpp
+++ b/oem/ibm/test/libpldmresponder_fileio_test.cpp
@@ -20,6 +20,7 @@
namespace fs = std::filesystem;
using Json = nlohmann::json;
using namespace pldm::filetable;
+using namespace pldm::responder;
class TestFileTable : public testing::Test
{
@@ -213,7 +214,8 @@
&address, sizeof(address));
// Pass invalid payload length
- auto response = readFileIntoMemory(request, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileIntoMemory(request, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
}
@@ -242,7 +244,8 @@
// Initialise the file table with 2 valid file handles 0 & 1.
auto& table = buildFileTable(fileTableConfig.c_str());
- auto response = readFileIntoMemory(request, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
// Clear the file table contents.
@@ -272,7 +275,8 @@
using namespace pldm::filetable;
auto& table = buildFileTable(fileTableConfig.c_str());
- auto response = readFileIntoMemory(request, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
// Clear the file table contents.
@@ -302,7 +306,8 @@
using namespace pldm::filetable;
auto& table = buildFileTable(fileTableConfig.c_str());
- auto response = readFileIntoMemory(request, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH);
// Clear the file table contents.
@@ -335,7 +340,8 @@
using namespace pldm::filetable;
auto& table = buildFileTable(fileTableConfig.c_str());
- auto response = readFileIntoMemory(request, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH);
// Clear the file table contents.
@@ -362,12 +368,13 @@
&address, sizeof(address));
// Pass invalid payload length
- auto response = writeFileFromMemory(request, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.writeFileFromMemory(request, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
// The length field is not a multiple of DMA minsize
- response = writeFileFromMemory(request, requestPayloadLength);
+ response = handler.writeFileFromMemory(request, requestPayloadLength);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_WRITE_LENGTH);
}
@@ -396,7 +403,8 @@
// Initialise the file table with 2 valid file handles 0 & 1.
auto& table = buildFileTable(fileTableConfig.c_str());
- auto response = writeFileFromMemory(request, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.writeFileFromMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
// Clear the file table contents.
@@ -427,7 +435,8 @@
// Initialise the file table with 2 valid file handles 0 & 1.
auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str());
- auto response = writeFileFromMemory(request, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.writeFileFromMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
// Clear the file table contents.
@@ -495,7 +504,8 @@
request->operation_flag = opFlag;
request->table_type = type;
- auto response = getFileTable(requestMsgPtr, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
size_t offsetSize = sizeof(responsePtr->payload[0]);
@@ -517,7 +527,8 @@
auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
// Pass invalid command payload length
- auto response = getFileTable(request, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.getFileTable(request, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
}
@@ -538,7 +549,8 @@
request->operation_flag = opFlag;
request->table_type = type;
- auto response = getFileTable(requestMsgPtr, requestPayloadLength);
+ oem_ibm::Handler handler;
+ auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
}
@@ -565,21 +577,22 @@
auto& table = buildFileTable(fileTableConfig.c_str());
// Invalid payload length
- auto response = readFile(requestMsgPtr, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.readFile(requestMsgPtr, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
// Data out of range. File size is 1024, offset = 1024 is invalid.
request->offset = 1024;
- response = readFile(requestMsgPtr, payload_length);
+ response = handler.readFile(requestMsgPtr, payload_length);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
// Invalid file handle
request->file_handle = 2;
- response = readFile(requestMsgPtr, payload_length);
+ response = handler.readFile(requestMsgPtr, payload_length);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -614,7 +627,8 @@
std::vector<char> buffer(length);
stream.read(buffer.data(), length);
- auto responseMsg = readFile(requestMsgPtr, payload_length);
+ oem_ibm::Handler handler;
+ auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
auto response = reinterpret_cast<pldm_read_file_resp*>(
responseMsg.data() + sizeof(pldm_msg_hdr));
ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
@@ -630,7 +644,7 @@
buffer.resize(fileSize - request->offset);
stream.read(buffer.data(), (fileSize - request->offset));
- responseMsg = readFile(requestMsgPtr, payload_length);
+ responseMsg = handler.readFile(requestMsgPtr, payload_length);
response = reinterpret_cast<pldm_read_file_resp*>(responseMsg.data() +
sizeof(pldm_msg_hdr));
ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
@@ -663,21 +677,22 @@
request->length = length;
// Invalid payload length
- auto response = writeFile(requestMsgPtr, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.writeFile(requestMsgPtr, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
// Data out of range. File size is 1024, offset = 1024 is invalid.
request->offset = 1024;
- response = writeFile(requestMsgPtr, payload_length);
+ response = handler.writeFile(requestMsgPtr, payload_length);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
// Invalid file handle
request->file_handle = 2;
- response = writeFile(requestMsgPtr, payload_length);
+ response = handler.writeFile(requestMsgPtr, payload_length);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -709,7 +724,8 @@
request->length = length;
memcpy(request->file_data, fileData.data(), fileData.size());
- auto responseMsg = writeFile(requestMsgPtr, payload_length);
+ oem_ibm::Handler handler;
+ auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
auto response = reinterpret_cast<pldm_read_file_resp*>(
responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -741,7 +757,8 @@
request->length = 17;
request->address = 0;
- auto response = writeFileByTypeFromMemory(req, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.writeFileByTypeFromMemory(req, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
struct pldm_read_write_file_by_type_memory_resp* resp =
@@ -749,7 +766,7 @@
responsePtr->payload);
ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
- response = writeFileByTypeFromMemory(req, requestPayloadLength);
+ response = handler.writeFileByTypeFromMemory(req, requestPayloadLength);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
@@ -792,23 +809,24 @@
request->length = 17;
request->address = 0;
- auto response = readFileByTypeIntoMemory(req, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileByTypeIntoMemory(req, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
struct pldm_read_write_file_by_type_memory_resp* resp =
reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
responsePtr->payload);
ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
- response =
- readFileByTypeIntoMemory(req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
+ response = handler.readFileByTypeIntoMemory(
+ req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
responsePtr->payload);
ASSERT_EQ(PLDM_INVALID_WRITE_LENGTH, resp->completion_code);
request->length = 16;
- response =
- readFileByTypeIntoMemory(req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
+ response = handler.readFileByTypeIntoMemory(
+ req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
responsePtr->payload);
@@ -829,14 +847,15 @@
request->offset = 0;
request->length = 13;
- auto response = readFileByType(req, 0);
+ oem_ibm::Handler handler;
+ auto response = handler.readFileByType(req, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
struct pldm_read_write_file_by_type_resp* resp =
reinterpret_cast<struct pldm_read_write_file_by_type_resp*>(
responsePtr->payload);
ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
- response = readFileByType(req, payloadLength);
+ response = handler.readFileByType(req, payloadLength);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
resp = reinterpret_cast<struct pldm_read_write_file_by_type_resp*>(
responsePtr->payload);
diff --git a/pldmd.cpp b/pldmd.cpp
index 39bee54..1b37726 100644
--- a/pldmd.cpp
+++ b/pldmd.cpp
@@ -1,9 +1,9 @@
#include "dbus_impl_requester.hpp"
+#include "invoker.hpp"
#include "libpldmresponder/base.hpp"
#include "libpldmresponder/bios.hpp"
#include "libpldmresponder/platform.hpp"
#include "libpldmresponder/utils.hpp"
-#include "registration.hpp"
#include <err.h>
#include <getopt.h>
@@ -23,6 +23,7 @@
#include <sdeventplus/event.hpp>
#include <sdeventplus/source/io.hpp>
#include <sstream>
+#include <stdexcept>
#include <string>
#include <vector>
@@ -36,13 +37,14 @@
constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1;
+using namespace pldm::responder;
using namespace phosphor::logging;
using namespace pldm;
using namespace sdeventplus;
using namespace sdeventplus::source;
static Response processRxMsg(const std::vector<uint8_t>& requestMsg,
- dbus_api::Requester& requester)
+ Invoker& invoker, dbus_api::Requester& requester)
{
Response response;
@@ -60,9 +62,12 @@
auto request = reinterpret_cast<const pldm_msg*>(hdr);
size_t requestLen = requestMsg.size() - sizeof(struct pldm_msg_hdr) -
sizeof(eid) - sizeof(type);
- response = pldm::responder::invokeHandler(
- hdrFields.pldm_type, hdrFields.command, request, requestLen);
- if (response.empty())
+ try
+ {
+ response = invoker.handle(hdrFields.pldm_type, hdrFields.command,
+ request, requestLen);
+ }
+ catch (const std::out_of_range& e)
{
uint8_t completion_code = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
response.resize(sizeof(pldm_msg_hdr));
@@ -140,12 +145,14 @@
break;
}
- pldm::responder::base::registerHandlers();
- pldm::responder::bios::registerHandlers();
- pldm::responder::platform::registerHandlers();
+ Invoker invoker{};
+ invoker.registerHandler(PLDM_BASE, std::make_unique<base::Handler>());
+ invoker.registerHandler(PLDM_BIOS, std::make_unique<bios::Handler>());
+ invoker.registerHandler(PLDM_PLATFORM,
+ std::make_unique<platform::Handler>());
#ifdef OEM_IBM
- pldm::responder::oem_ibm::registerHandlers();
+ invoker.registerHandler(PLDM_OEM, std::make_unique<oem_ibm::Handler>());
#endif
/* Create local socket. */
@@ -188,8 +195,8 @@
auto bus = sdbusplus::bus::new_default();
dbus_api::Requester dbusImplReq(bus, "/xyz/openbmc_project/pldm");
- auto callback = [verbose, &dbusImplReq](IO& /*io*/, int fd,
- uint32_t revents) {
+ auto callback = [verbose, &invoker, &dbusImplReq](IO& /*io*/, int fd,
+ uint32_t revents) {
if (!(revents & EPOLLIN))
{
return;
@@ -240,7 +247,8 @@
else
{
// process message and send response
- auto response = processRxMsg(requestMsg, dbusImplReq);
+ auto response =
+ processRxMsg(requestMsg, invoker, dbusImplReq);
if (!response.empty())
{
if (verbose)
diff --git a/registration.cpp b/registration.cpp
deleted file mode 100644
index 7fb7957..0000000
--- a/registration.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "registration.hpp"
-
-#include <map>
-#include <phosphor-logging/log.hpp>
-
-using namespace phosphor::logging;
-
-namespace pldm
-{
-
-namespace responder
-{
-
-namespace internal
-{
-using Command = uint8_t;
-using CommandHandler = std::map<Command, Handler>;
-using Type = uint8_t;
-std::map<Type, CommandHandler> typeHandlers;
-} // namespace internal
-
-void registerHandler(uint8_t pldmType, uint8_t pldmCommand, Handler&& handler)
-{
- using namespace internal;
- CommandHandler& ch = typeHandlers[pldmType];
- ch.emplace(pldmCommand, std::move(handler));
-}
-
-Response invokeHandler(uint8_t pldmType, uint8_t pldmCommand,
- const pldm_msg* request, size_t payloadLength)
-{
- using namespace internal;
- Response response;
- if (!(typeHandlers.end() == typeHandlers.find(pldmType)))
- {
- if (!((typeHandlers.at(pldmType)).end() ==
- (typeHandlers.at(pldmType)).find(pldmCommand)))
- {
- response = typeHandlers.at(pldmType).at(pldmCommand)(request,
- payloadLength);
- if (response.empty())
- {
- log<level::ERR>("Encountered invalid response");
- }
- }
- else
- {
- log<level::ERR>("Unsupported PLDM command",
- entry("TYPE=0x%02x", pldmType),
- entry("COMMAND=0x%02x", pldmCommand));
- }
- }
- else
- {
- log<level::ERR>("Unsupported PLDM TYPE",
- entry("TYPE=0x%02x", pldmType));
- }
-
- return response;
-}
-
-} // namespace responder
-} // namespace pldm
diff --git a/registration.hpp b/registration.hpp
deleted file mode 100644
index 0bd496f..0000000
--- a/registration.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include <functional>
-#include <map>
-
-#include "libpldm/base.h"
-
-namespace pldm
-{
-
-using Response = std::vector<uint8_t>;
-
-namespace responder
-{
-
-using Handler =
- std::function<Response(const pldm_msg* request, size_t payloadLength)>;
-
-/** @brief Register a handler for input PLDM command
- *
- * @param[in] pldmType - PLDM type code
- * @param[in] pldmCommand - PLDM command code
- * @param[in] handler - PLDM command handler
- */
-void registerHandler(uint8_t pldmType, uint8_t pldmCommand, Handler&& handler);
-
-/** @brief Invoke a handler for input PLDM command
- *
- * @param[in] pldmType - PLDM type code
- * @param[in] pldmCommand - PLDM command code
- * @param[in] request - PLDM request message
- * @param[in] payloadLength - PLDM request message length
- * @return PLDM Response message
- */
-Response invokeHandler(uint8_t pldmType, uint8_t pldmCommand,
- const pldm_msg* request, size_t payloadLength);
-
-} // namespace responder
-} // namespace pldm
diff --git a/test/libpldmresponder_base_test.cpp b/test/libpldmresponder_base_test.cpp
index bbd986a..885ef24 100644
--- a/test/libpldmresponder_base_test.cpp
+++ b/test/libpldmresponder_base_test.cpp
@@ -16,7 +16,8 @@
auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
// payload length will be 0 in this case
size_t requestPayloadLength = 0;
- auto response = getPLDMTypes(request, requestPayloadLength);
+ base::Handler handler;
+ auto response = handler.getPLDMTypes(request, requestPayloadLength);
// Only base type supported at the moment
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
uint8_t* payload_ptr = responsePtr->payload;
@@ -33,7 +34,8 @@
requestPayload{};
auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
- auto response = getPLDMCommands(request, requestPayloadLength);
+ base::Handler handler;
+ auto response = handler.getPLDMCommands(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
uint8_t* payload_ptr = responsePtr->payload;
ASSERT_EQ(payload_ptr[0], 0);
@@ -49,7 +51,8 @@
request->payload[0] = 0xFF;
size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
- auto response = getPLDMCommands(request, requestPayloadLength);
+ base::Handler handler;
+ auto response = handler.getPLDMCommands(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
uint8_t* payload_ptr = responsePtr->payload;
ASSERT_EQ(payload_ptr[0], PLDM_ERROR_INVALID_PLDM_TYPE);
@@ -72,7 +75,8 @@
ASSERT_EQ(0, rc);
- auto response = getPLDMVersion(request, requestPayloadLength);
+ base::Handler handler;
+ auto response = handler.getPLDMVersion(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], 0);
@@ -101,7 +105,8 @@
ASSERT_EQ(0, rc);
- auto response = getPLDMVersion(request, requestPayloadLength - 1);
+ base::Handler handler;
+ auto response = handler.getPLDMVersion(request, requestPayloadLength - 1);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -113,7 +118,7 @@
ASSERT_EQ(0, rc);
- response = getPLDMVersion(request, requestPayloadLength);
+ response = handler.getPLDMVersion(request, requestPayloadLength);
responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
@@ -125,7 +130,8 @@
auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
size_t requestPayloadLength = 0;
- auto response = getTID(request, requestPayloadLength);
+ base::Handler handler;
+ auto response = handler.getTID(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
uint8_t* payload = responsePtr->payload;
diff --git a/test/libpldmresponder_bios_test.cpp b/test/libpldmresponder_bios_test.cpp
index 7271567..1271dda 100644
--- a/test/libpldmresponder_bios_test.cpp
+++ b/test/libpldmresponder_bios_test.cpp
@@ -177,7 +177,7 @@
table.insert(table.end(), padSize, 0);
table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
- pldm::responder::traverseBIOSAttrTable(
+ pldm::responder::bios::traverseBIOSAttrTable(
table, [&](const struct pldm_bios_attr_table_entry* entry) {
int rc;
switch (entry->attr_type)
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
index 6b89b2e..88a6eb4 100644
--- a/test/libpldmresponder_platform_test.cpp
+++ b/test/libpldmresponder_platform_test.cpp
@@ -25,7 +25,8 @@
using namespace pdr;
Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
ASSERT_EQ(pdrRepo.empty(), false);
- auto response = getPDR(request, requestPayloadLength);
+ platform::Handler handler;
+ auto response = handler.getPDR(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -59,7 +60,8 @@
using namespace pdr;
Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
ASSERT_EQ(pdrRepo.empty(), false);
- auto response = getPDR(request, requestPayloadLength);
+ platform::Handler handler;
+ auto response = handler.getPDR(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -86,7 +88,8 @@
using namespace pdr;
Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
ASSERT_EQ(pdrRepo.empty(), false);
- auto response = getPDR(request, requestPayloadLength);
+ platform::Handler handler;
+ auto response = handler.getPDR(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE);
@@ -105,7 +108,8 @@
using namespace pdr;
Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
ASSERT_EQ(pdrRepo.empty(), false);
- auto response = getPDR(request, requestPayloadLength);
+ platform::Handler handler;
+ auto response = handler.getPDR(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -129,7 +133,8 @@
using namespace pdr;
Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
ASSERT_EQ(pdrRepo.empty(), false);
- auto response = getPDR(request, requestPayloadLength);
+ platform::Handler handler;
+ auto response = handler.getPDR(request, requestPayloadLength);
// Let's try to find a PDR of type stateEffecter (= 11) and entity type =
// 100
@@ -141,7 +146,8 @@
start = request->payload;
recordHandle = reinterpret_cast<uint32_t*>(start);
*recordHandle = handle;
- auto response = getPDR(request, requestPayloadLength);
+ platform::Handler handler;
+ auto response = handler.getPDR(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -218,8 +224,9 @@
EXPECT_CALL(handlerObj, setDbusProperty(objPath, bootProgressProp,
bootProgressInf, value))
.Times(2);
- auto rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
- stateField);
+ platform::Handler handler;
+ auto rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(
+ handlerObj, 0x1, stateField);
ASSERT_EQ(rc, 0);
}
@@ -236,23 +243,24 @@
stateField.push_back({PLDM_REQUEST_SET, 4});
MockdBusHandler handlerObj;
- auto rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
- stateField);
+ platform::Handler handler;
+ auto rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(
+ handlerObj, 0x1, stateField);
ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
- rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x9,
- stateField);
+ rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x9,
+ stateField);
ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID);
stateField.push_back({PLDM_REQUEST_SET, 4});
- rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
- stateField);
+ rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
+ stateField);
ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
std::vector<set_effecter_state_field> newStateField;
newStateField.push_back({PLDM_REQUEST_SET, 1});
- rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x2,
- newStateField);
+ rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x2,
+ newStateField);
ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
}
diff --git a/test/meson.build b/test/meson.build
index ee509db..4019cde 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -29,6 +29,7 @@
'libpldm_fru_test',
'libpldm_utils_test',
'pldmd_instanceid_test',
+ 'pldmd_registration_test',
]
if get_option('oem-ibm').enabled()
diff --git a/test/pldmd_registration_test.cpp b/test/pldmd_registration_test.cpp
new file mode 100644
index 0000000..d51efdd
--- /dev/null
+++ b/test/pldmd_registration_test.cpp
@@ -0,0 +1,49 @@
+#include "invoker.hpp"
+
+#include <stdexcept>
+
+#include "libpldm/base.h"
+
+#include <gtest/gtest.h>
+
+using namespace pldm;
+using namespace pldm::responder;
+constexpr Command testCmd = 0xFF;
+constexpr Type testType = 0xFF;
+
+class TestHandler : public CmdHandler
+{
+ public:
+ TestHandler()
+ {
+ handlers.emplace(testCmd,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->handle(request, payloadLength);
+ });
+ }
+
+ Response handle(const pldm_msg* /*request*/, size_t /*payloadLength*/)
+ {
+ return {100, 200};
+ }
+};
+
+TEST(Registration, testSuccess)
+{
+ Invoker invoker{};
+ invoker.registerHandler(testType, std::make_unique<TestHandler>());
+ auto result = invoker.handle(testType, testCmd, nullptr, 0);
+ ASSERT_EQ(result[0], 100);
+ ASSERT_EQ(result[1], 200);
+}
+
+TEST(Registration, testFailure)
+{
+ Invoker invoker{};
+ ASSERT_THROW(invoker.handle(testType, testCmd, nullptr, 0),
+ std::out_of_range);
+ invoker.registerHandler(testType, std::make_unique<TestHandler>());
+ uint8_t badCmd = 0xFE;
+ ASSERT_THROW(invoker.handle(testType, badCmd, nullptr, 0),
+ std::out_of_range);
+}