summaryrefslogtreecommitdiffstats
path: root/ipmid-new.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ipmid-new.cpp')
-rw-r--r--ipmid-new.cpp125
1 files changed, 124 insertions, 1 deletions
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index fb57666..a9aff36 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -125,6 +125,16 @@ static std::unordered_map<unsigned int, /* key is NetFn/Cmd */
HandlerTuple>
handlerMap;
+/* special map for decoding Group registered commands (NetFn 2Ch) */
+static std::unordered_map<unsigned int, /* key is Group/Cmd (NetFn is 2Ch) */
+ HandlerTuple>
+ groupHandlerMap;
+
+/* special map for decoding OEM registered commands (NetFn 2Eh) */
+static std::unordered_map<unsigned int, /* key is Iana/Cmd (NetFn is 2Eh) */
+ HandlerTuple>
+ oemHandlerMap;
+
namespace impl
{
/* common function to register all standard IPMI handlers */
@@ -152,6 +162,42 @@ bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
return false;
}
+/* common function to register all Group IPMI handlers */
+bool registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
+ HandlerBase::ptr handler)
+{
+ // create key and value for this handler
+ unsigned int netFnCmd = makeCmdKey(group, cmd);
+ HandlerTuple item(prio, priv, handler);
+
+ // consult the handler map and look for a match
+ auto& mapCmd = groupHandlerMap[netFnCmd];
+ if (!std::get<HandlerBase::ptr>(mapCmd) || std::get<int>(mapCmd) <= prio)
+ {
+ mapCmd = item;
+ return true;
+ }
+ return false;
+}
+
+/* common function to register all OEM IPMI handlers */
+bool registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
+ HandlerBase::ptr handler)
+{
+ // create key and value for this handler
+ unsigned int netFnCmd = makeCmdKey(iana, cmd);
+ HandlerTuple item(prio, priv, handler);
+
+ // consult the handler map and look for a match
+ auto& mapCmd = oemHandlerMap[netFnCmd];
+ if (!std::get<HandlerBase::ptr>(mapCmd) || std::get<int>(mapCmd) <= prio)
+ {
+ mapCmd = item;
+ return true;
+ }
+ return false;
+}
+
} // namespace impl
message::Response::ptr executeIpmiCommandCommon(
@@ -187,10 +233,56 @@ message::Response::ptr executeIpmiCommandCommon(
return errorResponse(request, ccInvalidCommand);
}
+message::Response::ptr executeIpmiGroupCommand(message::Request::ptr request)
+{
+ // look up the group for this request
+ Group group;
+ if (0 != request->unpack(group))
+ {
+ return errorResponse(request, ccReqDataLenInvalid);
+ }
+ // The handler will need to unpack group as well; we just need it for lookup
+ request->payload.reset();
+ message::Response::ptr response =
+ executeIpmiCommandCommon(groupHandlerMap, group, request);
+ // if the handler should add the group; executeIpmiCommandCommon does not
+ if (response->cc != ccSuccess && response->payload.size() == 0)
+ {
+ response->pack(group);
+ }
+ return response;
+}
+
+message::Response::ptr executeIpmiOemCommand(message::Request::ptr request)
+{
+ // look up the iana for this request
+ Iana iana;
+ if (0 != request->unpack(iana))
+ {
+ return errorResponse(request, ccReqDataLenInvalid);
+ }
+ request->payload.reset();
+ message::Response::ptr response =
+ executeIpmiCommandCommon(oemHandlerMap, iana, request);
+ // if the handler should add the iana; executeIpmiCommandCommon does not
+ if (response->cc != ccSuccess && response->payload.size() == 0)
+ {
+ response->pack(iana);
+ }
+ return response;
+}
+
message::Response::ptr executeIpmiCommand(message::Request::ptr request)
{
NetFn netFn = request->ctx->netFn;
- // TODO: handler OEM and group OEM commands here
+ if (netFnGroup == netFn)
+ {
+ return executeIpmiGroupCommand(request);
+ }
+ else if (netFnOem == netFn)
+ {
+ return executeIpmiOemCommand(request);
+ }
return executeIpmiCommandCommon(handlerMap, netFn, request);
}
@@ -365,6 +457,37 @@ void ipmi_register_callback(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
ipmi::impl::registerHandler(ipmi::prioOpenBmcBase, netFn, cmd, realPriv, h);
}
+namespace oem
+{
+
+class LegacyRouter : public oem::Router
+{
+ public:
+ virtual ~LegacyRouter()
+ {
+ }
+
+ /// Enable message routing to begin.
+ void activate() override
+ {
+ }
+
+ void registerHandler(Number oen, ipmi_cmd_t cmd, Handler handler) override
+ {
+ auto h = ipmi::makeLegacyHandler(std::forward<Handler>(handler));
+ ipmi::impl::registerOemHandler(ipmi::prioOpenBmcBase, oen, cmd,
+ ipmi::Privilege::Admin, h);
+ }
+};
+static LegacyRouter legacyRouter;
+
+Router* mutableRouter()
+{
+ return &legacyRouter;
+}
+
+} // namespace oem
+
/* legacy alternative to executionEntry */
void handleLegacyIpmiCommand(sdbusplus::message::message& m)
{
OpenPOWER on IntegriCloud