platform-mc: Added EventManager
Added eventManager to handle sensor event class(00h) which is defined in
table 11 of DSP0248 v1.3.0. In this commit, the eventManager supports to
receive event asynchronously. The commit will also log the Ipmitool SEL
log and Redfish log for PLDM sensor event messages.
Change-Id: I1b337ccae454067841ffbbd8754631216a995542
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Signed-off-by: Gilbert Chen <gilbertc@nvidia.com>
diff --git a/common/types.hpp b/common/types.hpp
index a1c1c51..e3b10ee 100644
--- a/common/types.hpp
+++ b/common/types.hpp
@@ -52,6 +52,12 @@
constexpr uint8_t BmcMctpEid = 8;
#define PLDM_PLATFORM_GETPDR_MAX_RECORD_BYTES 1024
+/* default the max event message buffer size BMC supported to 4K bytes */
+#define PLDM_PLATFORM_EVENT_MSG_MAX_BUFFER_SIZE 4096
+/* DSP0248 section16.9 EventMessageBufferSize Command, the default message
+ * buffer size is 256 bytes
+ */
+#define PLDM_PLATFORM_DEFAULT_MESSAGE_BUFFER_SIZE 256
namespace dbus
{
diff --git a/common/utils.hpp b/common/utils.hpp
index 7df5f81..05dc4bd 100644
--- a/common/utils.hpp
+++ b/common/utils.hpp
@@ -37,6 +37,22 @@
namespace utils
{
+enum class Level
+{
+ WARNING,
+ CRITICAL,
+ PERFORMANCELOSS,
+ SOFTSHUTDOWN,
+ HARDSHUTDOWN,
+ ERROR
+};
+enum class Direction
+{
+ HIGH,
+ LOW,
+ ERROR
+};
+
const std::set<std::string_view> dbusValueTypeNames = {
"bool", "uint8_t", "int16_t", "uint16_t",
"int32_t", "uint32_t", "int64_t", "uint64_t",
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index d04bb1e..b8ac0f6 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -377,15 +377,20 @@
try
{
const auto& handlers = eventHandlers.at(eventClass);
+ bool oneFailedHandler = false;
for (const auto& handler : handlers)
{
auto rc =
handler(request, payloadLength, formatVersion, tid, offset);
if (rc != PLDM_SUCCESS)
{
- return CmdHandler::ccOnlyResponse(request, rc);
+ oneFailedHandler = true;
}
}
+ if (oneFailedHandler)
+ {
+ return CmdHandler::ccOnlyResponse(request, rc);
+ }
}
catch (const std::out_of_range& e)
{
diff --git a/meson.build b/meson.build
index 22de2d4..32684b3 100644
--- a/meson.build
+++ b/meson.build
@@ -246,6 +246,7 @@
'platform-mc/manager.cpp',
'platform-mc/sensor_manager.cpp',
'platform-mc/numeric_sensor.cpp',
+ 'platform-mc/event_manager.cpp',
'requester/mctp_endpoint_discovery.cpp',
implicit_include_directories: false,
dependencies: deps,
diff --git a/platform-mc/event_manager.cpp b/platform-mc/event_manager.cpp
new file mode 100644
index 0000000..1b9c6c3
--- /dev/null
+++ b/platform-mc/event_manager.cpp
@@ -0,0 +1,308 @@
+#include "event_manager.hpp"
+
+#include "libpldm/utils.h"
+
+#include "terminus_manager.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+
+#include <cerrno>
+#include <memory>
+
+PHOSPHOR_LOG2_USING;
+
+namespace pldm
+{
+namespace platform_mc
+{
+namespace fs = std::filesystem;
+
+int EventManager::handlePlatformEvent(
+ pldm_tid_t tid, uint16_t eventId, uint8_t eventClass,
+ const uint8_t* eventData, size_t eventDataSize)
+{
+ /* EventClass sensorEvent `Table 11 - PLDM Event Types` DSP0248 */
+ if (eventClass == PLDM_SENSOR_EVENT)
+ {
+ uint16_t sensorId = 0;
+ uint8_t sensorEventClassType = 0;
+ size_t eventClassDataOffset = 0;
+ auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
+ &sensorEventClassType,
+ &eventClassDataOffset);
+ if (rc)
+ {
+ lg2::error(
+ "Failed to decode sensor event data from terminus ID {TID}, event class {CLASS}, event ID {EVENTID} with return code {RC}.",
+ "TID", tid, "CLASS", eventClass, "EVENTID", eventId, "RC", rc);
+ return rc;
+ }
+ switch (sensorEventClassType)
+ {
+ case PLDM_NUMERIC_SENSOR_STATE:
+ {
+ const uint8_t* sensorData = eventData + eventClassDataOffset;
+ size_t sensorDataLength = eventDataSize - eventClassDataOffset;
+ return processNumericSensorEvent(tid, sensorId, sensorData,
+ sensorDataLength);
+ }
+ case PLDM_STATE_SENSOR_STATE:
+ case PLDM_SENSOR_OP_STATE:
+ default:
+ lg2::info(
+ "Unsupported class type {CLASSTYPE} for the sensor event from terminus ID {TID} sensorId {SID}",
+ "CLASSTYPE", sensorEventClassType, "TID", tid, "SID",
+ sensorId);
+ return PLDM_ERROR;
+ }
+ }
+
+ lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE", eventClass);
+
+ return PLDM_ERROR;
+}
+
+int EventManager::processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
+ const uint8_t* sensorData,
+ size_t sensorDataLength)
+{
+ uint8_t eventState = 0;
+ uint8_t previousEventState = 0;
+ uint8_t sensorDataSize = 0;
+ uint32_t presentReading;
+ auto rc = decode_numeric_sensor_data(
+ sensorData, sensorDataLength, &eventState, &previousEventState,
+ &sensorDataSize, &presentReading);
+ if (rc)
+ {
+ lg2::error(
+ "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ",
+ "TID", tid, "RC", rc);
+ return rc;
+ }
+
+ double value = static_cast<double>(presentReading);
+ lg2::error(
+ "processNumericSensorEvent tid {TID}, sensorID {SID} value {VAL} previousState {PSTATE} eventState {ESTATE}",
+ "TID", tid, "SID", sensorId, "VAL", value, "PSTATE", previousEventState,
+ "ESTATE", eventState);
+
+ if (!termini.contains(tid) || !termini[tid])
+ {
+ lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
+ tid);
+ return PLDM_ERROR;
+ }
+
+ auto& terminus = termini[tid];
+
+ auto sensor = terminus->getSensorObject(sensorId);
+ if (!sensor)
+ {
+ lg2::error(
+ "Terminus ID {TID} has no sensor object with sensor ID {SID}.",
+ "TID", tid, "SID", sensorId);
+ return PLDM_ERROR;
+ }
+
+ switch (previousEventState)
+ {
+ case PLDM_SENSOR_UNKNOWN:
+ case PLDM_SENSOR_NORMAL:
+ {
+ switch (eventState)
+ {
+ case PLDM_SENSOR_UPPERFATAL:
+ case PLDM_SENSOR_UPPERCRITICAL:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH,
+ value, true, true);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::HIGH, value, true, true);
+ }
+ case PLDM_SENSOR_UPPERWARNING:
+ {
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH, value, true, true);
+ }
+ case PLDM_SENSOR_NORMAL:
+ break;
+ case PLDM_SENSOR_LOWERWARNING:
+ {
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW, value, true, true);
+ }
+ case PLDM_SENSOR_LOWERCRITICAL:
+ case PLDM_SENSOR_LOWERFATAL:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW,
+ value, true, true);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::LOW, value, true, true);
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case PLDM_SENSOR_LOWERWARNING:
+ {
+ switch (eventState)
+ {
+ case PLDM_SENSOR_UPPERFATAL:
+ case PLDM_SENSOR_UPPERCRITICAL:
+ break;
+ case PLDM_SENSOR_UPPERWARNING:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW,
+ value, false, false);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH, value, true, true);
+ }
+ case PLDM_SENSOR_NORMAL:
+ {
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW, value, false, false);
+ }
+ case PLDM_SENSOR_LOWERWARNING:
+ break;
+ case PLDM_SENSOR_LOWERCRITICAL:
+ case PLDM_SENSOR_LOWERFATAL:
+ {
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::LOW, value, true, true);
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case PLDM_SENSOR_LOWERCRITICAL:
+ case PLDM_SENSOR_LOWERFATAL:
+ {
+ switch (eventState)
+ {
+ case PLDM_SENSOR_UPPERFATAL:
+ case PLDM_SENSOR_UPPERCRITICAL:
+ case PLDM_SENSOR_UPPERWARNING:
+ break;
+ case PLDM_SENSOR_NORMAL:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::LOW,
+ value, false, false);
+ sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW,
+ value, true, true);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW, value, false, false);
+ }
+ case PLDM_SENSOR_LOWERWARNING:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::LOW,
+ value, false, false);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW, value, true, true);
+ }
+ case PLDM_SENSOR_LOWERCRITICAL:
+ case PLDM_SENSOR_LOWERFATAL:
+ default:
+ break;
+ }
+ break;
+ }
+ case PLDM_SENSOR_UPPERFATAL:
+ case PLDM_SENSOR_UPPERCRITICAL:
+ {
+ switch (eventState)
+ {
+ case PLDM_SENSOR_UPPERFATAL:
+ case PLDM_SENSOR_UPPERCRITICAL:
+ break;
+ case PLDM_SENSOR_UPPERWARNING:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::HIGH,
+ value, false, false);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH, value, true, true);
+ }
+ case PLDM_SENSOR_NORMAL:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::HIGH,
+ value, false, false);
+ sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH,
+ value, true, true);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH, value, false, false);
+ }
+ case PLDM_SENSOR_LOWERWARNING:
+ case PLDM_SENSOR_LOWERCRITICAL:
+ case PLDM_SENSOR_LOWERFATAL:
+ default:
+ break;
+ }
+ break;
+ }
+ case PLDM_SENSOR_UPPERWARNING:
+ {
+ switch (eventState)
+ {
+ case PLDM_SENSOR_UPPERFATAL:
+ case PLDM_SENSOR_UPPERCRITICAL:
+ {
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::CRITICAL,
+ pldm::utils::Direction::HIGH, value, true, true);
+ }
+ case PLDM_SENSOR_UPPERWARNING:
+ break;
+ case PLDM_SENSOR_NORMAL:
+ {
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH, value, false, false);
+ }
+ case PLDM_SENSOR_LOWERWARNING:
+ {
+ sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
+ pldm::utils::Direction::HIGH,
+ value, false, false);
+ return sensor->triggerThresholdEvent(
+ pldm::utils::Level::WARNING,
+ pldm::utils::Direction::LOW, value, true, true);
+ }
+ case PLDM_SENSOR_LOWERCRITICAL:
+ case PLDM_SENSOR_LOWERFATAL:
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return PLDM_SUCCESS;
+}
+
+} // namespace platform_mc
+} // namespace pldm
diff --git a/platform-mc/event_manager.hpp b/platform-mc/event_manager.hpp
new file mode 100644
index 0000000..f40db44
--- /dev/null
+++ b/platform-mc/event_manager.hpp
@@ -0,0 +1,100 @@
+#pragma once
+
+#include "libpldm/platform.h"
+#include "libpldm/pldm.h"
+
+#include "common/types.hpp"
+#include "numeric_sensor.hpp"
+#include "pldmd/dbus_impl_requester.hpp"
+#include "requester/handler.hpp"
+#include "terminus.hpp"
+#include "terminus_manager.hpp"
+
+namespace pldm
+{
+namespace platform_mc
+{
+
+/**
+ * @brief EventManager
+ *
+ * This class manages PLDM events from terminus. The function includes providing
+ * the API for process event data and using phosphor-logging API to log the
+ * event.
+ *
+ */
+class EventManager
+{
+ public:
+ EventManager() = delete;
+ EventManager(const EventManager&) = delete;
+ EventManager(EventManager&&) = delete;
+ EventManager& operator=(const EventManager&) = delete;
+ EventManager& operator=(EventManager&&) = delete;
+ virtual ~EventManager() = default;
+
+ explicit EventManager(TerminusManager& terminusManager,
+ TerminiMapper& termini) :
+ terminusManager(terminusManager), termini(termini) {};
+
+ /** @brief Handle platform event
+ *
+ * @param[in] tid - tid where the event is from
+ * @param[in] eventId - event Id
+ * @param[in] eventClass - event class
+ * @param[in] eventData - event data
+ * @param[in] eventDataSize - size of event data
+ * @return PLDM completion code
+ */
+ int handlePlatformEvent(pldm_tid_t tid, uint16_t eventId,
+ uint8_t eventClass, const uint8_t* eventData,
+ size_t eventDataSize);
+
+ /** @brief Set available state of terminus for pldm request.
+ *
+ * @param[in] tid - terminus ID
+ * @param[in] state - Terminus available state for PLDM request messages
+ */
+ void updateAvailableState(pldm_tid_t tid, Availability state)
+ {
+ availableState[tid] = state;
+ };
+
+ /** @brief Get available state of terminus for pldm request.
+ *
+ * @param[in] tid - terminus ID
+ */
+ bool getAvailableState(pldm_tid_t tid)
+ {
+ if (!availableState.contains(tid))
+ {
+ return false;
+ }
+ return availableState[tid];
+ };
+
+ protected:
+ /** @brief Helper method to process the PLDM Numeric sensor event class
+ *
+ * @param[in] tid - tid where the event is from
+ * @param[in] sensorId - Sensor ID which is the source of event
+ * @param[in] sensorData - Numeric sensor event data
+ * @param[in] sensorDataLength - event data length
+ *
+ * @return PLDM completion code
+ */
+ int processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
+ const uint8_t* sensorData,
+ size_t sensorDataLength);
+
+ /** @brief Reference of terminusManager */
+ TerminusManager& terminusManager;
+
+ /** @brief List of discovered termini */
+ TerminiMapper& termini;
+
+ /** @brief Available state for pldm request of terminus */
+ std::unordered_map<pldm_tid_t, Availability> availableState;
+};
+} // namespace platform_mc
+} // namespace pldm
diff --git a/platform-mc/manager.hpp b/platform-mc/manager.hpp
index efbd1cb..a4fd466 100644
--- a/platform-mc/manager.hpp
+++ b/platform-mc/manager.hpp
@@ -4,6 +4,7 @@
#include "common/instance_id.hpp"
#include "common/types.hpp"
+#include "event_manager.hpp"
#include "platform_manager.hpp"
#include "requester/handler.hpp"
#include "requester/mctp_endpoint_discovery.hpp"
@@ -36,7 +37,8 @@
terminusManager(event, handler, instanceIdDb, termini, this,
pldm::BmcMctpEid),
platformManager(terminusManager, termini),
- sensorManager(event, terminusManager, termini)
+ sensorManager(event, terminusManager, termini, this),
+ eventManager(terminusManager, termini)
{}
/** @brief Helper function to do the actions before discovering terminus
@@ -88,6 +90,7 @@
if (termini.contains(tid))
{
sensorManager.updateAvailableState(tid, state);
+ eventManager.updateAvailableState(tid, state);
}
}
@@ -98,6 +101,28 @@
sensorManager.stopPolling(tid);
}
+ /** @brief Sensor event handler funtion
+ *
+ * @param[in] request - Event message
+ * @param[in] payloadLength - Event message payload size
+ * @param[in] tid - Terminus ID
+ * @param[in] eventDataOffset - Event data offset
+ *
+ * @return PLDM error code: PLDM_SUCCESS when there is no error in handling
+ * the event
+ */
+ int handleSensorEvent(const pldm_msg* request, size_t payloadLength,
+ uint8_t /* formatVersion */, uint8_t tid,
+ size_t eventDataOffset)
+ {
+ auto eventData = reinterpret_cast<const uint8_t*>(request->payload) +
+ eventDataOffset;
+ auto eventDataSize = payloadLength - eventDataOffset;
+ eventManager.handlePlatformEvent(tid, 0x00, PLDM_SENSOR_EVENT,
+ eventData, eventDataSize);
+ return PLDM_SUCCESS;
+ }
+
private:
/** @brief List of discovered termini */
TerminiMapper termini{};
@@ -110,6 +135,9 @@
/** @brief Store platform manager handler */
SensorManager sensorManager;
+
+ /** @brief Store event manager handler */
+ EventManager eventManager;
};
} // namespace platform_mc
} // namespace pldm
diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp
index af6efad..6b387dd 100644
--- a/platform-mc/numeric_sensor.cpp
+++ b/platform-mc/numeric_sensor.cpp
@@ -750,5 +750,127 @@
}
}
}
+
+int NumericSensor::triggerThresholdEvent(
+ pldm::utils::Level eventType, pldm::utils::Direction direction,
+ double rawValue, bool newAlarm, bool assert)
+{
+ if (!valueIntf)
+ {
+ lg2::error(
+ "Failed to update thresholds sensor {NAME} D-Bus interfaces don't exist.",
+ "NAME", sensorName);
+ return PLDM_ERROR;
+ }
+
+ auto value = unitModifier(conversionFormula(rawValue));
+ lg2::error(
+ "triggerThresholdEvent eventType {TID}, direction {SID} value {VAL} newAlarm {PSTATE} assert {ESTATE}",
+ "TID", eventType, "SID", direction, "VAL", value, "PSTATE", newAlarm,
+ "ESTATE", assert);
+
+ switch (eventType)
+ {
+ case pldm::utils::Level::WARNING:
+ {
+ if (!thresholdWarningIntf)
+ {
+ lg2::error(
+ "Error:Trigger sensor warning event for non warning threshold sensors {NAME}",
+ "NAME", sensorName);
+ return PLDM_ERROR;
+ }
+ if (direction == pldm::utils::Direction::HIGH &&
+ !std::isnan(thresholdWarningIntf->warningHigh()))
+ {
+ auto alarm = thresholdWarningIntf->warningAlarmHigh();
+ if (alarm == newAlarm)
+ {
+ return PLDM_SUCCESS;
+ }
+ thresholdWarningIntf->warningAlarmHigh(newAlarm);
+ if (assert)
+ {
+ thresholdWarningIntf->warningHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdWarningIntf->warningHighAlarmDeasserted(value);
+ }
+ }
+ else if (direction == pldm::utils::Direction::LOW &&
+ !std::isnan(thresholdWarningIntf->warningLow()))
+ {
+ auto alarm = thresholdWarningIntf->warningAlarmLow();
+ if (alarm == newAlarm)
+ {
+ return PLDM_SUCCESS;
+ }
+ thresholdWarningIntf->warningAlarmLow(newAlarm);
+ if (assert)
+ {
+ thresholdWarningIntf->warningLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdWarningIntf->warningLowAlarmDeasserted(value);
+ }
+ }
+ break;
+ }
+ case pldm::utils::Level::CRITICAL:
+ {
+ if (!thresholdCriticalIntf)
+ {
+ lg2::error(
+ "Error:Trigger sensor Critical event for non warning threshold sensors {NAME}",
+ "NAME", sensorName);
+ return PLDM_ERROR;
+ }
+ if (direction == pldm::utils::Direction::HIGH &&
+ !std::isnan(thresholdCriticalIntf->criticalHigh()))
+ {
+ auto alarm = thresholdCriticalIntf->criticalAlarmHigh();
+ if (alarm == newAlarm)
+ {
+ return PLDM_SUCCESS;
+ }
+ thresholdCriticalIntf->criticalAlarmHigh(newAlarm);
+ if (assert)
+ {
+ thresholdCriticalIntf->criticalHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalHighAlarmDeasserted(value);
+ }
+ }
+ else if (direction == pldm::utils::Direction::LOW &&
+ !std::isnan(thresholdCriticalIntf->criticalLow()))
+ {
+ auto alarm = thresholdCriticalIntf->criticalAlarmLow();
+ if (alarm == newAlarm)
+ {
+ return PLDM_SUCCESS;
+ }
+ thresholdCriticalIntf->criticalAlarmLow(newAlarm);
+ if (assert)
+ {
+ thresholdCriticalIntf->criticalLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalLowAlarmDeasserted(value);
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return PLDM_SUCCESS;
+}
} // namespace platform_mc
} // namespace pldm
diff --git a/platform-mc/numeric_sensor.hpp b/platform-mc/numeric_sensor.hpp
index 7b2fc6a..92c709f 100644
--- a/platform-mc/numeric_sensor.hpp
+++ b/platform-mc/numeric_sensor.hpp
@@ -4,6 +4,7 @@
#include "libpldm/pldm.h"
#include "common/types.hpp"
+#include "common/utils.hpp"
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
@@ -166,6 +167,20 @@
}
};
+ /** @brief Check if value is over threshold.
+ *
+ * @param[in] eventType - event level in pldm::utils::Level
+ * @param[in] direction - direction type in pldm::utils::Direction
+ * @param[in] rawValue - sensor raw value
+ * @param[in] newAlarm - trigger alarm true/false
+ * @param[in] assert - event type asserted/deasserted
+ *
+ * @return PLDM completion code
+ */
+ int triggerThresholdEvent(pldm::utils::Level eventType,
+ pldm::utils::Direction direction, double rawValue,
+ bool newAlarm, bool assert);
+
/** @brief Terminus ID which the sensor belongs to */
pldm_tid_t tid;
diff --git a/platform-mc/platform_manager.cpp b/platform-mc/platform_manager.cpp
index 35526fb..51a6b06 100644
--- a/platform-mc/platform_manager.cpp
+++ b/platform-mc/platform_manager.cpp
@@ -37,6 +37,29 @@
terminus->parseTerminusPDRs();
}
+ uint16_t terminusMaxBufferSize = terminus->maxBufferSize;
+ if (!terminus->doesSupportCommand(PLDM_PLATFORM,
+ PLDM_EVENT_MESSAGE_BUFFER_SIZE))
+ {
+ terminusMaxBufferSize = PLDM_PLATFORM_DEFAULT_MESSAGE_BUFFER_SIZE;
+ }
+ else
+ {
+ /* Get maxBufferSize use PLDM command eventMessageBufferSize */
+ auto rc = co_await eventMessageBufferSize(
+ tid, terminus->maxBufferSize, terminusMaxBufferSize);
+ if (rc != PLDM_SUCCESS)
+ {
+ lg2::error(
+ "Failed to get message buffer size for terminus with TID: {TID}, error: {ERROR}",
+ "TID", tid, "ERROR", rc);
+ terminusMaxBufferSize =
+ PLDM_PLATFORM_DEFAULT_MESSAGE_BUFFER_SIZE;
+ }
+ }
+ terminus->maxBufferSize =
+ std::min(terminus->maxBufferSize, terminusMaxBufferSize);
+
auto rc = co_await configEventReceiver(tid);
if (rc)
{
@@ -369,6 +392,57 @@
co_return completionCode;
}
+exec::task<int> PlatformManager::eventMessageBufferSize(
+ pldm_tid_t tid, uint16_t receiverMaxBufferSize,
+ uint16_t& terminusBufferSize)
+{
+ Request request(
+ sizeof(pldm_msg_hdr) + PLDM_EVENT_MESSAGE_BUFFER_SIZE_REQ_BYTES);
+ auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+ auto rc = encode_event_message_buffer_size_req(0, receiverMaxBufferSize,
+ requestMsg);
+ if (rc)
+ {
+ lg2::error(
+ "Failed to encode request GetPDRRepositoryInfo for terminus ID {TID}, error {RC} ",
+ "TID", tid, "RC", rc);
+ co_return rc;
+ }
+
+ const pldm_msg* responseMsg = nullptr;
+ size_t responseLen = 0;
+ rc = co_await terminusManager.sendRecvPldmMsg(tid, request, &responseMsg,
+ &responseLen);
+ if (rc)
+ {
+ lg2::error(
+ "Failed to send EventMessageBufferSize message for terminus {TID}, error {RC}",
+ "TID", tid, "RC", rc);
+ co_return rc;
+ }
+
+ uint8_t completionCode;
+ rc = decode_event_message_buffer_size_resp(
+ responseMsg, responseLen, &completionCode, &terminusBufferSize);
+ if (rc)
+ {
+ lg2::error(
+ "Failed to decode response EventMessageBufferSize for terminus ID {TID}, error {RC} ",
+ "TID", tid, "RC", rc);
+ co_return rc;
+ }
+
+ if (completionCode != PLDM_SUCCESS)
+ {
+ lg2::error(
+ "Error : EventMessageBufferSize for terminus ID {TID}, complete code {CC}.",
+ "TID", tid, "CC", completionCode);
+ co_return completionCode;
+ }
+
+ co_return completionCode;
+}
+
exec::task<int> PlatformManager::setEventReceiver(
pldm_tid_t tid, pldm_event_message_global_enable eventMessageGlobalEnable,
pldm_transport_protocol_type protocolType, uint16_t heartbeatTimer)
diff --git a/platform-mc/platform_manager.hpp b/platform-mc/platform_manager.hpp
index 641f16a..549a4e7 100644
--- a/platform-mc/platform_manager.hpp
+++ b/platform-mc/platform_manager.hpp
@@ -111,6 +111,16 @@
pldm_event_message_global_enable eventMessageGlobalEnable,
pldm_transport_protocol_type protocolType, uint16_t heartbeatTimer);
+ /** @brief send eventMessageBufferSize
+ * @param[in] tid - Destination TID
+ * @param[in] receiverMaxBufferSize
+ * @param[out] terminusBufferSize
+ * @return coroutine return_value - PLDM completion code
+ */
+ exec::task<int> eventMessageBufferSize(pldm_tid_t tid,
+ uint16_t receiverMaxBufferSize,
+ uint16_t& terminusBufferSize);
+
/** @brief send eventMessageSupported
* @param[in] tid - Destination TID
* @param[in] formatVersion - version of the event format
diff --git a/platform-mc/sensor_manager.cpp b/platform-mc/sensor_manager.cpp
index fcfd0a6..74e3043 100644
--- a/platform-mc/sensor_manager.cpp
+++ b/platform-mc/sensor_manager.cpp
@@ -1,5 +1,6 @@
#include "sensor_manager.hpp"
+#include "manager.hpp"
#include "terminus_manager.hpp"
#include <phosphor-logging/lg2.hpp>
@@ -13,9 +14,9 @@
SensorManager::SensorManager(sdeventplus::Event& event,
TerminusManager& terminusManager,
- TerminiMapper& termini) :
+ TerminiMapper& termini, Manager* manager) :
event(event), terminusManager(terminusManager), termini(termini),
- pollingTime(SENSOR_POLLING_TIME)
+ pollingTime(SENSOR_POLLING_TIME), manager(manager)
{}
void SensorManager::startPolling(pldm_tid_t tid)
diff --git a/platform-mc/sensor_manager.hpp b/platform-mc/sensor_manager.hpp
index 1c7c788..29172bb 100644
--- a/platform-mc/sensor_manager.hpp
+++ b/platform-mc/sensor_manager.hpp
@@ -38,7 +38,7 @@
explicit SensorManager(sdeventplus::Event& event,
TerminusManager& terminusManager,
- TerminiMapper& termini);
+ TerminiMapper& termini, Manager* manager);
/** @brief starting sensor polling task
*/
@@ -111,6 +111,9 @@
/** @brief round robin sensor list */
std::map<pldm_tid_t, std::queue<std::shared_ptr<NumericSensor>>>
roundRobinSensors;
+
+ /** @brief pointer to Manager */
+ Manager* manager;
};
} // namespace platform_mc
} // namespace pldm
diff --git a/platform-mc/terminus.cpp b/platform-mc/terminus.cpp
index c8cd91a..b5a1e8c 100644
--- a/platform-mc/terminus.cpp
+++ b/platform-mc/terminus.cpp
@@ -14,8 +14,8 @@
{
Terminus::Terminus(pldm_tid_t tid, uint64_t supportedTypes) :
- initialized(false), synchronyConfigurationSupported(0), tid(tid),
- supportedTypes(supportedTypes)
+ initialized(false), maxBufferSize(PLDM_PLATFORM_EVENT_MSG_MAX_BUFFER_SIZE),
+ synchronyConfigurationSupported(0), tid(tid), supportedTypes(supportedTypes)
{}
bool Terminus::doesSupportType(uint8_t type)
@@ -537,5 +537,36 @@
}
}
+std::shared_ptr<NumericSensor> Terminus::getSensorObject(SensorId id)
+{
+ if (terminusName.empty())
+ {
+ lg2::error(
+ "Terminus ID {TID}: DOES NOT have terminus name. No numeric sensor object.",
+ "TID", tid);
+ return nullptr;
+ }
+ if (!numericSensors.size())
+ {
+ lg2::error("Terminus ID {TID} name {NAME}: DOES NOT have sensor.",
+ "TID", tid, "NAME", terminusName);
+ return nullptr;
+ }
+
+ for (auto& sensor : numericSensors)
+ {
+ if (!sensor)
+ {
+ continue;
+ }
+
+ if (sensor->sensorId == id)
+ {
+ return sensor;
+ }
+ }
+
+ return nullptr;
+}
} // namespace platform_mc
} // namespace pldm
diff --git a/platform-mc/terminus.hpp b/platform-mc/terminus.hpp
index 26a412b..dd766c6 100644
--- a/platform-mc/terminus.hpp
+++ b/platform-mc/terminus.hpp
@@ -133,6 +133,9 @@
/** @brief A flag to indicate if terminus has been initialized */
bool initialized = false;
+ /** @brief maximum message buffer size the terminus can send and receive */
+ uint16_t maxBufferSize;
+
/** @brief This value indicates the event messaging styles supported by the
* terminus
*/
@@ -148,6 +151,14 @@
*/
std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id);
+ /** @brief Get Numeric Sensor Object by sensorID
+ *
+ * @param[in] id - sensor ID
+ *
+ * @return sensor object
+ */
+ std::shared_ptr<NumericSensor> getSensorObject(SensorId id);
+
private:
/** @brief Find the Terminus Name from the Entity Auxiliary name list
* The Entity Auxiliary name list is entityAuxiliaryNamesTbl.
diff --git a/platform-mc/test/event_manager_test.cpp b/platform-mc/test/event_manager_test.cpp
new file mode 100644
index 0000000..01abf42
--- /dev/null
+++ b/platform-mc/test/event_manager_test.cpp
@@ -0,0 +1,390 @@
+#include "libpldm/base.h"
+#include "libpldm/entity.h"
+#include "libpldm/platform.h"
+
+#include "common/instance_id.hpp"
+#include "common/types.hpp"
+#include "mock_event_manager.hpp"
+#include "mock_terminus_manager.hpp"
+#include "platform-mc/platform_manager.hpp"
+#include "platform-mc/terminus_manager.hpp"
+#include "test/test_instance_id.hpp"
+
+#include <gtest/gtest.h>
+
+using ::testing::_;
+using ::testing::Return;
+
+class EventManagerTest : public testing::Test
+{
+ protected:
+ EventManagerTest() :
+ bus(pldm::utils::DBusHandler::getBus()),
+ event(sdeventplus::Event::get_default()), instanceIdDb(),
+ reqHandler(pldmTransport, event, instanceIdDb, false,
+ std::chrono::seconds(1), 2, std::chrono::milliseconds(100)),
+ terminusManager(event, reqHandler, instanceIdDb, termini, nullptr),
+ eventManager(terminusManager, termini),
+ platformManager(terminusManager, termini)
+ {}
+
+ PldmTransport* pldmTransport = nullptr;
+ sdbusplus::bus::bus& bus;
+ sdeventplus::Event event;
+ TestInstanceIdDb instanceIdDb;
+ pldm::requester::Handler<pldm::requester::Request> reqHandler;
+ pldm::platform_mc::MockTerminusManager terminusManager;
+ pldm::platform_mc::MockEventManager eventManager;
+ pldm::platform_mc::PlatformManager platformManager;
+ pldm::platform_mc::TerminiMapper termini{};
+};
+
+TEST_F(EventManagerTest, processNumericSensorEventTest)
+{
+#define SENSOR_READING 50
+#define WARNING_HIGH 45
+ pldm_tid_t tid = 1;
+ termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
+ tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM);
+ std::vector<uint8_t> pdr1{
+ 0x1,
+ 0x0,
+ 0x0,
+ 0x0, // record handle
+ 0x1, // PDRHeaderVersion
+ PLDM_NUMERIC_SENSOR_PDR, // PDRType
+ 0x0,
+ 0x0, // recordChangeNumber
+ PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
+ 0, // dataLength
+ 0,
+ 0, // PLDMTerminusHandle
+ 0x1,
+ 0x0, // sensorID=1
+ PLDM_ENTITY_POWER_SUPPLY,
+ 0, // entityType=Power Supply(120)
+ 1,
+ 0, // entityInstanceNumber
+ 1,
+ 0, // containerID=1
+ PLDM_NO_INIT, // sensorInit
+ false, // sensorAuxiliaryNamesPDR
+ PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C
+ 0, // unitModifier = 0
+ 0, // rateUnit
+ 0, // baseOEMUnitHandle
+ 0, // auxUnit
+ 0, // auxUnitModifier
+ 0, // auxRateUnit
+ 0, // rel
+ 0, // auxOEMUnitHandle
+ true, // isLinear
+ PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize
+ 0,
+ 0,
+ 0x80,
+ 0x3f, // resolution=1.0
+ 0,
+ 0,
+ 0,
+ 0, // offset=0
+ 0,
+ 0, // accuracy
+ 0, // plusTolerance
+ 0, // minusTolerance
+ 2, // hysteresis = 2
+ 0x1b, // supportedThresholds
+ 0, // thresholdAndHysteresisVolatility
+ 0,
+ 0,
+ 0x80,
+ 0x3f, // stateTransistionInterval=1.0
+ 0,
+ 0,
+ 0x80,
+ 0x3f, // updateInverval=1.0
+ 255, // maxReadable
+ 0, // minReadable
+ PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
+ 0x18, // rangeFieldsupport
+ 0, // nominalValue
+ 0, // normalMax
+ 0, // normalMin
+ WARNING_HIGH, // warningHigh
+ 20, // warningLow
+ 60, // criticalHigh
+ 10, // criticalLow
+ 0, // fatalHigh
+ 0 // fatalLow
+ };
+
+ std::vector<uint8_t> pdr2{
+ 0x1, 0x0, 0x0,
+ 0x0, // record handle
+ 0x1, // PDRHeaderVersion
+ PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
+ 0x1,
+ 0x0, // recordChangeNumber
+ 0x11,
+ 0, // dataLength
+ /* Entity Auxiliary Names PDR Data*/
+ 3,
+ 0x80, // entityType system software
+ 0x1,
+ 0x0, // Entity instance number =1
+ 0,
+ 0, // Overal system
+ 0, // shared Name Count one name only
+ 01, // nameStringCount
+ 0x65, 0x6e, 0x00,
+ 0x00, // Language Tag "en"
+ 0x53, 0x00, 0x30, 0x00,
+ 0x00 // Entity Name "S0"
+ };
+
+ // add dummy numeric sensor
+ termini[tid]->pdrs.emplace_back(pdr1);
+ termini[tid]->pdrs.emplace_back(pdr2);
+ termini[tid]->parseTerminusPDRs();
+ EXPECT_EQ(1, termini[tid]->numericSensors.size());
+
+ uint8_t platformEventStatus = 0;
+
+ std::vector<uint8_t> eventData{
+ 0x1,
+ 0x0, // sensor id
+ PLDM_NUMERIC_SENSOR_STATE,
+ PLDM_SENSOR_UPPERWARNING,
+ PLDM_SENSOR_NORMAL,
+ PLDM_SENSOR_DATA_SIZE_UINT8,
+ SENSOR_READING};
+ auto rc = eventManager.handlePlatformEvent(
+ tid, 0x00, PLDM_SENSOR_EVENT, eventData.data(), eventData.size());
+ EXPECT_EQ(PLDM_SUCCESS, rc);
+ EXPECT_EQ(PLDM_EVENT_NO_LOGGING, platformEventStatus);
+}
+
+TEST_F(EventManagerTest, SetEventReceiverTest)
+{
+ // Add terminus
+ auto mappedTid = terminusManager.mapTid(pldm::MctpInfo(10, "", "", 1));
+ auto tid = mappedTid.value();
+ termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
+ tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM);
+ auto terminus = termini[tid];
+
+ /* Set supported command by terminus */
+ auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
+ std::vector<uint8_t> pldmCmds(size);
+ uint8_t type = PLDM_PLATFORM;
+ uint8_t cmd = PLDM_GET_PDR_REPOSITORY_INFO;
+ auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ cmd = PLDM_GET_PDR;
+ idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ cmd = PLDM_EVENT_MESSAGE_SUPPORTED;
+ idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ cmd = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
+ idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ cmd = PLDM_SET_EVENT_RECEIVER;
+ idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ termini[tid]->setSupportedCommands(pldmCmds);
+
+ EXPECT_EQ(true, termini[tid]->doesSupportCommand(PLDM_PLATFORM,
+ PLDM_SET_EVENT_RECEIVER));
+ EXPECT_EQ(true, termini[tid]->doesSupportCommand(
+ PLDM_PLATFORM, PLDM_EVENT_MESSAGE_BUFFER_SIZE));
+ EXPECT_EQ(true, termini[tid]->doesSupportCommand(
+ PLDM_PLATFORM, PLDM_EVENT_MESSAGE_SUPPORTED));
+ EXPECT_EQ(true,
+ termini[tid]->doesSupportCommand(PLDM_PLATFORM, PLDM_GET_PDR));
+ EXPECT_EQ(true, termini[tid]->doesSupportCommand(
+ PLDM_PLATFORM, PLDM_GET_PDR_REPOSITORY_INFO));
+
+ // queue getPDRRepositoryInfo response
+ const size_t getPDRRepositoryInfoLen =
+ PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
+ getPDRRepositoryInfoResp{
+ 0x0, 0x02, 0x50, PLDM_SUCCESS,
+ 0x0, // repositoryState
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // updateTime
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // OEMUpdateTime
+ 2, 0x0, 0x0, 0x0, // recordCount
+ 0x0, 0x1, 0x0, 0x0, // repositorySize
+ 59, 0x0, 0x0, 0x0, // largestRecordSize
+ 0x0 // dataTransferHandleTimeout
+ };
+ auto rc = terminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()),
+ sizeof(getPDRRepositoryInfoResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ // queue getPDR responses
+ const size_t getPdrRespLen = 81;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
+ 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x1, 0x0, 0x0, 0x0, // nextRecordHandle
+ 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
+ 0x5, // transferFlag
+ 69, 0x0, // responseCount
+ // numeric Sensor PDR
+ 0x0, 0x0, 0x0,
+ 0x0, // record handle
+ 0x1, // PDRHeaderVersion
+ PLDM_NUMERIC_SENSOR_PDR, // PDRType
+ 0x0,
+ 0x0, // recordChangeNumber
+ PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+ PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
+ PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
+ 0, // dataLength
+ 0,
+ 0, // PLDMTerminusHandle
+ 0x1,
+ 0x0, // sensorID=1
+ 120,
+ 0, // entityType=Power Supply(120)
+ 1,
+ 0, // entityInstanceNumber
+ 0x1,
+ 0x0, // containerID=1
+ PLDM_NO_INIT, // sensorInit
+ false, // sensorAuxiliaryNamesPDR
+ PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C
+ 1, // unitModifier = 1
+ 0, // rateUnit
+ 0, // baseOEMUnitHandle
+ 0, // auxUnit
+ 0, // auxUnitModifier
+ 0, // auxRateUnit
+ 0, // rel
+ 0, // auxOEMUnitHandle
+ true, // isLinear
+ PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize
+ 0, 0, 0xc0,
+ 0x3f, // resolution=1.5
+ 0, 0, 0x80,
+ 0x3f, // offset=1.0
+ 0,
+ 0, // accuracy
+ 0, // plusTolerance
+ 0, // minusTolerance
+ 2, // hysteresis
+ 0, // supportedThresholds
+ 0, // thresholdAndHysteresisVolatility
+ 0, 0, 0x80,
+ 0x3f, // stateTransistionInterval=1.0
+ 0, 0, 0x80,
+ 0x3f, // updateInverval=1.0
+ 255, // maxReadable
+ 0, // minReadable
+ PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
+ 0, // rangeFieldsupport
+ 0, // nominalValue
+ 0, // normalMax
+ 0, // normalMin
+ 0, // warningHigh
+ 0, // warningLow
+ 0, // criticalHigh
+ 0, // criticalLow
+ 0, // fatalHigh
+ 0 // fatalLow
+ };
+ rc = terminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ const size_t getPdrAuxNameRespLen = 39;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrAuxNameRespLen>
+ getPdrAuxNameResp{
+ 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0,
+ 0x0, // nextRecordHandle
+ 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
+ 0x5, // transferFlag
+ 0x1b, 0x0, // responseCount
+ // Common PDR Header
+ 0x1, 0x0, 0x0,
+ 0x0, // record handle
+ 0x1, // PDRHeaderVersion
+ PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
+ 0x1,
+ 0x0, // recordChangeNumber
+ 0x11,
+ 0, // dataLength
+ /* Entity Auxiliary Names PDR Data*/
+ 3,
+ 0x80, // entityType system software
+ 0x1,
+ 0x0, // Entity instance number =1
+ 0,
+ 0, // Overal system
+ 0, // shared Name Count one name only
+ 01, // nameStringCount
+ 0x65, 0x6e, 0x00,
+ 0x00, // Language Tag "en"
+ 0x53, 0x00, 0x30, 0x00,
+ 0x00 // Entity Name "S0"
+ };
+ rc = terminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(getPdrAuxNameResp.data()),
+ sizeof(getPdrAuxNameResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ // queue eventMessageBufferSize response(bufferSize=32)
+ const size_t eventMessageBufferSizeRespLen = 3;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + eventMessageBufferSizeRespLen>
+ eventMessageBufferSizeResp{0x0, 0x02, 0x0d, PLDM_SUCCESS, 32, 0};
+ rc = terminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(eventMessageBufferSizeResp.data()),
+ sizeof(eventMessageBufferSizeResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ // queue eventMessageSupported response
+ const size_t eventMessageSupportedLen = 7;
+ PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + eventMessageSupportedLen>
+ eventMessageSupportedResp{0x0, 0x02, 0x0c, PLDM_SUCCESS,
+ 0x0, // synchronyConfiguration
+ 0x06, // synchronyConfigurationSupported
+ 3, // numberEventClassReturned
+ 0x0, 0x5, 0xfa};
+ rc = terminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(eventMessageSupportedResp.data()),
+ sizeof(eventMessageSupportedResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ // queue SetEventReceiver response
+ const size_t SetEventReceiverLen = 1;
+ PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + SetEventReceiverLen>
+ SetEventReceiverResp{0x0, 0x02, 0x04, PLDM_SUCCESS};
+ rc = terminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(SetEventReceiverResp.data()),
+ sizeof(SetEventReceiverResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ // should finish immediately
+ stdexec::sync_wait(platformManager.initTerminus());
+ EXPECT_EQ(true, terminus->initialized);
+ EXPECT_EQ(32, terminus->maxBufferSize);
+ EXPECT_EQ(0x06, terminus->synchronyConfigurationSupported.byte);
+ EXPECT_EQ(2, terminus->pdrs.size());
+ EXPECT_EQ(1, terminus->numericSensors.size());
+}
+
+TEST_F(EventManagerTest, updateAvailableState)
+{
+ pldm_tid_t tid = 1;
+ eventManager.updateAvailableState(tid, true);
+ EXPECT_EQ(true, eventManager.getAvailableState(tid));
+ eventManager.updateAvailableState(tid, false);
+ EXPECT_EQ(false, eventManager.getAvailableState(tid));
+ eventManager.updateAvailableState(2, false);
+ EXPECT_EQ(false, eventManager.getAvailableState(tid));
+}
diff --git a/platform-mc/test/meson.build b/platform-mc/test/meson.build
index ab7b20a..0e8bc87 100644
--- a/platform-mc/test/meson.build
+++ b/platform-mc/test/meson.build
@@ -6,6 +6,7 @@
'../manager.cpp',
'../sensor_manager.cpp',
'../numeric_sensor.cpp',
+ '../event_manager.cpp',
'../../requester/mctp_endpoint_discovery.cpp',
],
include_directories: ['../../requester', '../../pldmd'],
@@ -17,6 +18,7 @@
'platform_manager_test',
'sensor_manager_test',
'numeric_sensor_test',
+ 'event_manager_test',
]
foreach t : tests
diff --git a/platform-mc/test/mock_event_manager.hpp b/platform-mc/test/mock_event_manager.hpp
new file mode 100644
index 0000000..116e7f1
--- /dev/null
+++ b/platform-mc/test/mock_event_manager.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "platform-mc/event_manager.hpp"
+
+#include <gmock/gmock.h>
+
+namespace pldm
+{
+namespace platform_mc
+{
+
+class MockEventManager : public EventManager
+{
+ public:
+ MockEventManager(TerminusManager& terminusManager, TerminiMapper& termini) :
+ EventManager(terminusManager, termini) {};
+};
+
+} // namespace platform_mc
+} // namespace pldm
diff --git a/platform-mc/test/mock_sensor_manager.hpp b/platform-mc/test/mock_sensor_manager.hpp
index a52e4ea..fcb8102 100644
--- a/platform-mc/test/mock_sensor_manager.hpp
+++ b/platform-mc/test/mock_sensor_manager.hpp
@@ -13,9 +13,9 @@
{
public:
MockSensorManager(sdeventplus::Event& event,
- TerminusManager& terminusManager,
- TerminiMapper& termini) :
- SensorManager(event, terminusManager, termini) {};
+ TerminusManager& terminusManager, TerminiMapper& termini,
+ Manager* manager) :
+ SensorManager(event, terminusManager, termini, manager) {};
MOCK_METHOD(void, doSensorPolling, (pldm_tid_t tid), (override));
};
diff --git a/platform-mc/test/sensor_manager_test.cpp b/platform-mc/test/sensor_manager_test.cpp
index 59a120b..4ec9f5b 100644
--- a/platform-mc/test/sensor_manager_test.cpp
+++ b/platform-mc/test/sensor_manager_test.cpp
@@ -19,7 +19,7 @@
reqHandler(pldmTransport, event, instanceIdDb, false),
terminusManager(event, reqHandler, instanceIdDb, termini, nullptr,
pldm::BmcMctpEid),
- sensorManager(event, terminusManager, termini)
+ sensorManager(event, terminusManager, termini, nullptr)
{}
void runEventLoopForSeconds(uint64_t sec)
diff --git a/pldmd/pldmd.cpp b/pldmd/pldmd.cpp
index 46c216a..5aae40d 100644
--- a/pldmd/pldmd.cpp
+++ b/pldmd/pldmd.cpp
@@ -270,10 +270,24 @@
// FRU table is built lazily when a FRU command or Get PDR command is
// handled. To enable building FRU table, the FRU handler is passed to the
// Platform handler.
+
+ std::unique_ptr<platform_mc::Manager> platformManager =
+ std::make_unique<platform_mc::Manager>(event, reqHandler, instanceIdDb);
+
+ pldm::responder::platform::EventMap addOnEventHandlers{
+ {PLDM_SENSOR_EVENT,
+ {[&platformManager](const pldm_msg* request, size_t payloadLength,
+ uint8_t formatVersion, uint8_t tid,
+ size_t eventDataOffset) {
+ return platformManager->handleSensorEvent(
+ request, payloadLength, formatVersion, tid, eventDataOffset);
+ }}}};
+
auto platformHandler = std::make_unique<platform::Handler>(
&dbusHandler, hostEID, &instanceIdDb, PDR_JSONS_DIR, pdrRepo.get(),
hostPDRHandler.get(), dbusToPLDMEventHandler.get(), fruHandler.get(),
- platformConfigHandler.get(), &reqHandler, event, true);
+ platformConfigHandler.get(), &reqHandler, event, true,
+ addOnEventHandlers);
auto biosHandler = std::make_unique<bios::Handler>(
pldmTransport.getEventSource(), hostEID, &instanceIdDb, &reqHandler,
@@ -302,8 +316,6 @@
std::unique_ptr<fw_update::Manager> fwManager =
std::make_unique<fw_update::Manager>(event, reqHandler, instanceIdDb);
- std::unique_ptr<platform_mc::Manager> platformManager =
- std::make_unique<platform_mc::Manager>(event, reqHandler, instanceIdDb);
std::unique_ptr<MctpDiscovery> mctpDiscoveryHandler =
std::make_unique<MctpDiscovery>(
bus, std::initializer_list<MctpDiscoveryHandlerIntf*>{