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