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/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)