diff --git a/platform-mc/manager.hpp b/platform-mc/manager.hpp index ae72ec5aa..1397f8a8c 100644 --- a/platform-mc/manager.hpp +++ b/platform-mc/manager.hpp @@ -38,11 +38,14 @@ class Manager : public pldm::MctpDiscoveryHandlerIntf explicit Manager(sdeventplus::Event& event, RequesterHandler& handler, pldm::InstanceIdDb& instanceIdDb, const bool verbose) : terminusManager(event, handler, instanceIdDb, termini, this, - pldm::BmcMctpEid), + pldm::BmcMctpEid, nullptr), platformManager(terminusManager, termini, this), sensorManager(event, terminusManager, termini, this), eventManager(terminusManager, termini, verbose) - {this->verbose = verbose;} + { + this->verbose = verbose; + terminusManager.setSensorManager(&sensorManager); + } /** @brief Helper function to do the actions before discovering terminus * @@ -106,7 +109,23 @@ class Manager : public pldm::MctpDiscoveryHandlerIntf */ void startSensorPolling(pldm_tid_t tid) { - sensorManager.startPolling(tid); + if (termini.contains(tid)) + { + for (auto& sensor : termini[tid]->numericSensors) + { + if (sensor) + { + sensor->isReady = true; + } + } + } + + else + { + lg2::error("terminii does not contain TID: {TID}.", "TID", tid); + } + + sensorManager.startPolling(tid); } /** @brief Helper function to set available state for pldm request (sensor diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp index d3c0ee69f..795c6af73 100644 --- a/platform-mc/numeric_sensor.cpp +++ b/platform-mc/numeric_sensor.cpp @@ -2,6 +2,7 @@ #include "common/utils.hpp" #include "requester/handler.hpp" +#include "sensor_manager.hpp" #include @@ -15,6 +16,27 @@ namespace pldm namespace platform_mc { +double SensorValue::value() const +{ + if (this->nSensor.sensorManager && !nSensor.updateTime && nSensor.isReady && !nSensor.pollPending) + { + nSensor.pollPending = true; + + lg2::info("Get reading for sensor Id: {ID}", "ID", nSensor.sensorId); + nSensor.scope.spawn( + [](SensorManager* manager, NumericSensor* sensor) -> exec::task { + auto sPtr = std::shared_ptr(sensor, [](auto) {}); + co_await manager->getSensorReading(sPtr); + sensor->pollPending = false; + co_return; + }(nSensor.sensorManager, const_cast(&nSensor)) + ); + } + + auto value = ValueIntf::value(); + return value; +} + inline bool NumericSensor::createInventoryPath( const std::string& associationPath, const std::string& sensorName, const uint16_t entityType, const uint16_t entityInstanceNum, @@ -163,7 +185,9 @@ void NumericSensor::setSensorUnit(uint8_t baseUnit) NumericSensor::NumericSensor( const pldm_tid_t tid, const bool sensorDisabled, std::shared_ptr pdr, std::string& sensorName, - std::string& associationPath) : tid(tid), sensorName(sensorName) + std::string& associationPath, SensorManager* sensorManager, + exec::async_scope& scoperef) : + tid(tid), sensorName(sensorName), sensorManager(sensorManager), scope(scoperef) { if (!pdr) { @@ -289,7 +313,7 @@ NumericSensor::NumericSensor( { try { - valueIntf = std::make_unique(bus, path.c_str()); + valueIntf = std::make_unique(bus, path.c_str(), *this); } catch (const sdbusplus::exception_t& e) { @@ -419,8 +443,9 @@ NumericSensor::NumericSensor( NumericSensor::NumericSensor( const pldm_tid_t tid, const bool sensorDisabled, std::shared_ptr pdr, - std::string& sensorName, std::string& associationPath) : - tid(tid), sensorName(sensorName) + std::string& sensorName, std::string& associationPath, SensorManager* sensorManager, + exec::async_scope& scoperef) : + tid(tid), sensorName(sensorName), sensorManager(sensorManager), scope(scoperef) { if (!pdr) { @@ -532,7 +557,7 @@ NumericSensor::NumericSensor( { try { - valueIntf = std::make_unique(bus, path.c_str()); + valueIntf = std::make_unique(bus, path.c_str(), *this); } catch (const sdbusplus::exception_t& e) { @@ -698,7 +723,7 @@ void NumericSensor::updateReading(bool available, bool functional, double value) double curValue = 0; if (!useMetricInterface) { - curValue = valueIntf->value(); + curValue = valueIntf->ValueIntf::value(); } else { diff --git a/platform-mc/numeric_sensor.hpp b/platform-mc/numeric_sensor.hpp index 37f46959d..1e6062873 100644 --- a/platform-mc/numeric_sensor.hpp +++ b/platform-mc/numeric_sensor.hpp @@ -49,6 +49,39 @@ using AssociationDefinitionsInft = sdbusplus::server::object_t< using EntityIntf = sdbusplus::server::object_t< sdbusplus::xyz::openbmc_project::Inventory::Source::PLDM::server::Entity>; +class NumericSensor; // Forward declaration +class SensorManager; // forward declaration + +/** @brief Custom implementation of the Value interface for numeric sensors. + * + * This class overrides the standard sdbusplus Value interface to provide + * specialized handling for property access, such as triggering hardware + * polls when the value is requested via D-Bus. + */ +class SensorValue : public ValueIntf { +public: + SensorValue(sdbusplus::bus_t& bus, const char* path, pldm::platform_mc::NumericSensor& nS) : + ValueIntf(bus, path, ValueIntf::action::emit_object_added), + nSensor(nS) + {} + + /** @brief Get the sensor reading property. + * + * This override triggers an asynchronous hardware poll to update the + * sensor reading when the D-Bus property is accessed (Read-on-Demand). + * + * @return The current sensor value stored in the D-Bus interface. + */ + double value() const override; + + double value(double val) override { + return ValueIntf::value(val); + } + +private: + pldm::platform_mc::NumericSensor& nSensor; +}; + /** * @brief NumericSensor * @@ -60,11 +93,13 @@ class NumericSensor public: NumericSensor(const pldm_tid_t tid, const bool sensorDisabled, std::shared_ptr pdr, - std::string& sensorName, std::string& associationPath); + std::string& sensorName, std::string& associationPath, + SensorManager* sensorManager, exec::__scope::async_scope& scope); NumericSensor(const pldm_tid_t tid, const bool sensorDisabled, std::shared_ptr pdr, - std::string& sensorName, std::string& associationPath); + std::string& sensorName, std::string& associationPath, + SensorManager* sensorManager, exec::__scope::async_scope& scope); ~NumericSensor() {}; @@ -247,6 +282,18 @@ class NumericSensor /** @brief Sensor Unit */ SensorUnit sensorUnit; + /** @brief Sensor Manager to read sensor reading */ + SensorManager* sensorManager; + + /** @brief Scope to manage the lifetime of asynchronous sensor reading tasks */ + exec::__scope::async_scope& scope; + + /** @brief Flag to enable Read-on-Demand only after initialization is complete */ + bool isReady{false}; + + /** @brief Flag to prevent multiple concurrent hardware polls for the same sensor */ + std::atomic pollPending{false}; + private: /** * @brief Check sensor reading if any threshold has been crossed and update @@ -275,7 +322,7 @@ class NumericSensor const uint16_t containerId); std::unique_ptr metricIntf = nullptr; - std::unique_ptr valueIntf = nullptr; + std::unique_ptr valueIntf = nullptr; std::unique_ptr thresholdWarningIntf = nullptr; std::unique_ptr thresholdCriticalIntf = nullptr; std::unique_ptr thresholdHardShutdownIntf = diff --git a/platform-mc/sensor_manager.hpp b/platform-mc/sensor_manager.hpp index 6ccd4ba5a..8da400f80 100644 --- a/platform-mc/sensor_manager.hpp +++ b/platform-mc/sensor_manager.hpp @@ -77,6 +77,13 @@ class SensorManager return availableState[tid]; }; + /** @brief Sending getSensorReading command for the sensor + * + * @param[in] sensor - the sensor to be updated + * @return coroutine return_value - PLDM completion code + */ + exec::task getSensorReading(std::shared_ptr sensor); + protected: /** @brief start a coroutine for polling all sensors. */ @@ -89,13 +96,6 @@ class SensorManager */ exec::task doSensorPollingTask(pldm_tid_t tid); - /** @brief Sending getSensorReading command for the sensor - * - * @param[in] sensor - the sensor to be updated - * @return coroutine return_value - PLDM completion code - */ - exec::task getSensorReading(std::shared_ptr sensor); - /** @brief Reference to to PLDM daemon's main event loop. */ sdeventplus::Event& event; diff --git a/platform-mc/terminus.cpp b/platform-mc/terminus.cpp index 64de0a3b3..ebb1181cf 100644 --- a/platform-mc/terminus.cpp +++ b/platform-mc/terminus.cpp @@ -2,6 +2,7 @@ #include "dbus_impl_fru.hpp" #include "terminus_manager.hpp" +#include "sensor_manager.hpp" #include @@ -16,11 +17,12 @@ namespace platform_mc Terminus::Terminus(pldm_tid_t tid, uint64_t supportedTypes, sdeventplus::Event& event, - TerminusManager& terminusManager) : + TerminusManager& terminusManager, + SensorManager* sensorManager) : initialized(false), maxBufferSize(PLDM_PLATFORM_EVENT_MSG_MAX_BUFFER_SIZE), synchronyConfigurationSupported(0), pollEvent(false), tid(tid), supportedTypes(supportedTypes), event(event), - terminusManager(terminusManager) + terminusManager(terminusManager), sensorManager(sensorManager) {} bool Terminus::doesSupportType(uint8_t type) @@ -703,7 +705,8 @@ void Terminus::addNumericSensor( try { auto sensor = std::make_shared( - tid, true, pdr, sensorName, inventoryPath); + tid, true, pdr, sensorName, inventoryPath, sensorManager, + terminusScope); lg2::info("Created NumericSensor {NAME}", "NAME", sensorName); numericSensors.emplace_back(sensor); } @@ -876,7 +879,8 @@ void Terminus::addCompactNumericSensor( try { auto sensor = std::make_shared( - tid, true, pdr, sensorName, inventoryPath); + tid, true, pdr, sensorName, inventoryPath, sensorManager, + terminusScope); lg2::info("Created Compact NumericSensor {NAME}", "NAME", sensorName); numericSensors.emplace_back(sensor); } diff --git a/platform-mc/terminus.hpp b/platform-mc/terminus.hpp index 4d17060b6..3c14cffa7 100644 --- a/platform-mc/terminus.hpp +++ b/platform-mc/terminus.hpp @@ -89,6 +89,8 @@ namespace pldm namespace platform_mc { +class SensorManager; //forward declaration + using ContainerID = uint16_t; using EntityInstanceNumber = uint16_t; using EntityName = std::string; @@ -142,7 +144,8 @@ class Terminus { public: Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes, - sdeventplus::Event& event, TerminusManager& terminusManager); + sdeventplus::Event& event, TerminusManager& terminusManager, + SensorManager* sensorManager); /** @brief Check if the terminus supports the PLDM type message * @@ -519,6 +522,9 @@ class Terminus /** @brief Reference to TerminusManager */ TerminusManager& terminusManager; + /** @brief Reference to SensorManager */ + SensorManager* sensorManager; + /** @brief Numeric Sensor PDR list */ std::vector> numericSensorPdrs{}; diff --git a/platform-mc/terminus_manager.cpp b/platform-mc/terminus_manager.cpp index 935cdd8f2..b84eead6a 100644 --- a/platform-mc/terminus_manager.cpp +++ b/platform-mc/terminus_manager.cpp @@ -360,7 +360,7 @@ exec::task TerminusManager::initMctpTerminus(const MctpInfo& mctpInfo) try { termini[tid] = - std::make_shared(tid, supportedTypes, event, *this); + std::make_shared(tid, supportedTypes, event, *this, sensorManager); } catch (const sdbusplus::exception_t& e) { diff --git a/platform-mc/terminus_manager.hpp b/platform-mc/terminus_manager.hpp index 250fe995c..d0edf6f7a 100644 --- a/platform-mc/terminus_manager.hpp +++ b/platform-mc/terminus_manager.hpp @@ -54,16 +54,24 @@ class TerminusManager explicit TerminusManager( sdeventplus::Event& event, RequesterHandler& handler, pldm::InstanceIdDb& instanceIdDb, TerminiMapper& termini, - Manager* manager, mctp_eid_t localEid) : + Manager* manager, mctp_eid_t localEid, SensorManager* sensorManager) : handler(handler), instanceIdDb(instanceIdDb), termini(termini), tidPool(tidPoolSize, false), manager(manager), localEid(localEid), - event(event) + event(event), sensorManager(sensorManager) { // DSP0240 v1.1.0 table-8, special value: 0,0xFF = reserved tidPool[0] = true; tidPool[PLDM_TID_RESERVED] = true; } + /** @brief Set the Sensor Manager pointer + * + * @param[in] manager - Pointer to the Sensor Manager + */ + void setSensorManager(SensorManager* manager) { + sensorManager = manager; + } + /** @brief start a coroutine to discover terminus * * @param[in] mctpInfos - list information of the MCTP endpoints @@ -321,6 +329,9 @@ class TerminusManager * work */ sdeventplus::Event& event; + + /** @brief A Sensor Manager instance **/ + SensorManager* sensorManager; }; } // namespace platform_mc } // namespace pldm