Add responder for Platform Event Message
Provide infrastructure to hook handler for each PLDM event type.
Change-Id: I67480bb923f5eca311b2b0e597a146e020a5baf7
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/libpldm/platform.h b/libpldm/platform.h
index 92b8b9d..5bb110c 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -30,6 +30,7 @@
/* Minimum length for PLDM PlatformEventMessage request */
#define PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES 3
#define PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES 6
+#define PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES 2
/* Minumum length of senson event data */
#define PLDM_SENSOR_EVENT_DATA_MIN_LENGTH 5
@@ -184,6 +185,17 @@
PLDM_SENSOR_DATA_SIZE_SINT32
};
+/** @brief PLDM PlatformEventMessage response status
+ */
+enum pldm_platform_event_status {
+ PLDM_EVENT_NO_LOGGING = 0x00,
+ PLDM_EVENT_LOGGING_DISABLED = 0x01,
+ PLDM_EVENT_LOG_FULL = 0x02,
+ PLDM_EVENT_ACCEPTED_FOR_LOGGING = 0x03,
+ PLDM_EVENT_LOGGED = 0x04,
+ PLDM_EVENT_LOGGING_REJECTED = 0x05
+};
+
/** @struct pldm_pdr_hdr
*
* Structure representing PLDM common PDR header
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 6aef73d..0a33d86 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -195,6 +195,89 @@
return response;
}
+Response Handler::platformEventMessage(const pldm_msg* request,
+ size_t payloadLength)
+{
+ uint8_t formatVersion{};
+ uint8_t tid{};
+ uint8_t eventClass{};
+ size_t offset{};
+
+ auto rc = decode_platform_event_message_req(
+ request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
+ if (rc != PLDM_SUCCESS)
+ {
+ return CmdHandler::ccOnlyResponse(request, rc);
+ }
+
+ try
+ {
+ const auto& handlers = eventHandlers.at(eventClass);
+ for (const auto& handler : handlers)
+ {
+ auto rc =
+ handler(request, payloadLength, formatVersion, tid, offset);
+ if (rc != PLDM_SUCCESS)
+ {
+ return CmdHandler::ccOnlyResponse(request, rc);
+ }
+ }
+ }
+ catch (const std::out_of_range& e)
+ {
+ return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
+ }
+
+ Response response(
+ sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
+ PLDM_EVENT_NO_LOGGING, responsePtr);
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ return response;
+}
+
+int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
+ uint8_t /*formatVersion*/, uint8_t /*tid*/,
+ size_t eventDataOffset)
+{
+ uint16_t sensorId{};
+ uint8_t eventClass{};
+ size_t eventClassDataOffset{};
+ auto eventData =
+ reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
+ auto eventDataSize = payloadLength - eventDataOffset;
+
+ auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
+ &eventClass, &eventClassDataOffset);
+ if (rc != PLDM_SUCCESS)
+ {
+ return rc;
+ }
+
+ if (eventClass == PLDM_STATE_SENSOR_STATE)
+ {
+ uint8_t sensorOffset{};
+ uint8_t eventState{};
+ uint8_t previousEventState{};
+
+ rc = decode_state_sensor_data(&eventClass, eventClassDataOffset,
+ &sensorOffset, &eventState,
+ &previousEventState);
+ }
+ else
+ {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ return PLDM_SUCCESS;
+}
+
} // namespace platform
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index 75a1ad3..a435dca 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -31,11 +31,21 @@
using DbusObjMaps =
std::map<EffecterId,
std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>>;
+using DbusPath = std::string;
+using EffecterObjs = std::vector<DbusPath>;
+using EventType = uint8_t;
+using EventHandler = std::function<int(
+ const pldm_msg* request, size_t payloadLength, uint8_t formatVersion,
+ uint8_t tid, size_t eventDataOffset)>;
+using EventHandlers = std::vector<EventHandler>;
+using EventMap = std::map<EventType, EventHandlers>;
class Handler : public CmdHandler
{
public:
- Handler(const std::string& dir, pldm_pdr* repo) : pdrRepo(repo)
+ Handler(const std::string& dir, pldm_pdr* repo,
+ const std::optional<EventMap>& addOnHandlersMap = std::nullopt) :
+ pdrRepo(repo)
{
generate(dir, pdrRepo);
@@ -48,6 +58,41 @@
return this->setStateEffecterStates(request,
payloadLength);
});
+ handlers.emplace(PLDM_PLATFORM_EVENT_MESSAGE,
+ [this](const pldm_msg* request, size_t payloadLength) {
+ return this->platformEventMessage(request,
+ payloadLength);
+ });
+
+ // Default handler for PLDM Events
+ eventHandlers[PLDM_SENSOR_EVENT].emplace_back(
+ [this](const pldm_msg* request, size_t payloadLength,
+ uint8_t formatVersion, uint8_t tid, size_t eventDataOffset) {
+ return this->sensorEvent(request, payloadLength, formatVersion,
+ tid, eventDataOffset);
+ });
+
+ // Additional OEM event handlers for PLDM events, append it to the
+ // standard handlers
+ if (addOnHandlersMap)
+ {
+ auto addOnHandlers = addOnHandlersMap.value();
+ for (EventMap::iterator iter = addOnHandlers.begin();
+ iter != addOnHandlers.end(); ++iter)
+ {
+ auto search = eventHandlers.find(iter->first);
+ if (search != eventHandlers.end())
+ {
+ search->second.insert(std::end(search->second),
+ std::begin(iter->second),
+ std::end(iter->second));
+ }
+ else
+ {
+ eventHandlers.emplace(iter->first, iter->second);
+ }
+ }
+ }
}
pdr_utils::Repo& getRepo()
@@ -97,6 +142,11 @@
*/
void generateStateEffecterRepo(const Json& json, Repo& repo);
+ /** @brief map of PLDM event type to EventHandlers
+ *
+ */
+ EventMap eventHandlers;
+
/** @brief Handler for GetPDR
*
* @param[in] request - Request message payload
@@ -114,6 +164,28 @@
Response setStateEffecterStates(const pldm_msg* request,
size_t payloadLength);
+ /** @brief Handler for PlatformEventMessage
+ *
+ * @param[in] request - Request message
+ * @param[in] payloadLength - Request payload length
+ * @return Response - PLDM Response message
+ */
+ Response platformEventMessage(const pldm_msg* request,
+ size_t payloadLength);
+
+ /** @brief Handler for event class Sensor event
+ *
+ * @param[in] request - Request message
+ * @param[in] payloadLength - Request payload length
+ * @param[in] formatVersion - Version of the event format
+ * @param[in] tid - Terminus ID of the event's originator
+ * @param[in] eventDataOffset - Offset of the event data in the request
+ * message
+ * @return PLDM completion code
+ */
+ int sensorEvent(const pldm_msg* request, size_t payloadLength,
+ uint8_t formatVersion, uint8_t tid, size_t eventDataOffset);
+
/** @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