diff options
-rw-r--r-- | monitor/tach_sensor.cpp | 1 | ||||
-rw-r--r-- | monitor/tach_sensor.hpp | 1 | ||||
-rw-r--r-- | monitor/trust_group.hpp | 238 |
3 files changed, 239 insertions, 1 deletions
diff --git a/monitor/tach_sensor.cpp b/monitor/tach_sensor.cpp index 9a98e37..040e8f9 100644 --- a/monitor/tach_sensor.cpp +++ b/monitor/tach_sensor.cpp @@ -26,7 +26,6 @@ namespace fan namespace monitor { -constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; constexpr auto FAN_SENSOR_CONTROL_INTF = "xyz.openbmc_project.Control.FanSpeed"; constexpr auto FAN_SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value"; constexpr auto FAN_TARGET_PROPERTY = "Target"; diff --git a/monitor/tach_sensor.hpp b/monitor/tach_sensor.hpp index 60a55e3..9b10110 100644 --- a/monitor/tach_sensor.hpp +++ b/monitor/tach_sensor.hpp @@ -15,6 +15,7 @@ namespace monitor class Fan; +constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; /** * @class TachSensor diff --git a/monitor/trust_group.hpp b/monitor/trust_group.hpp new file mode 100644 index 0000000..af7b372 --- /dev/null +++ b/monitor/trust_group.hpp @@ -0,0 +1,238 @@ +#pragma once +#include <memory> +#include "tach_sensor.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace trust +{ + +/** + * @class Group + * + * An abstract sensor trust group base class. + * + * Supports the ability to know if a fan speed sensor value can + * be trusted or not, where if it isn't trusted then it shouldn't + * be used to determine if the fan is faulted or not. + * + * It's a group in that there can be multiple sensors in the group + * and the trust of all sensors depends on something about those sensors. + * For example, if all sensors in the group report a speed of zero, + * then no sensor in the group is trusted. All sensors in the group + * have the same trust value. + * + * Trust is calculated when checkTrust() is called after a group + * sensor's tach value changes. + * + * A derived class must override checkGroupTrust(). + */ +class Group +{ + public: + + Group() = delete; + virtual ~Group() = default; + Group(const Group&) = delete; + Group& operator=(const Group&) = delete; + Group(Group&&) = default; + Group& operator=(Group&&) = default; + + /** + * Constructor + * + * @param[in] names - the names of the sensors in the group + */ + explicit Group(const std::vector<std::string>& names) : + _names(names) + { + } + + /** + * Used to register a TachSensor object with the group. + * It's only added to the group if the sensor's name is + * in the group's list of names. + * + * @param[in] sensor - the TachSensor to register + */ + void registerSensor(std::unique_ptr<monitor::TachSensor>& sensor) + { + auto found = std::find_if( + _names.begin(), + _names.end(), + [&sensor](const auto& name) + { + return monitor::FAN_SENSOR_PATH + + name == sensor->name(); + }); + + if (found != _names.end()) + { + _sensors.push_back(sensor); + } + } + + /** + * Says if a sensor belongs to the group. + * + * After all sensors have registered, this can be + * used to say if a TachSensor is in the group. + * + * @param[in] sensor - the TachSensor object + */ + bool inGroup(const monitor::TachSensor& sensor) + { + return (std::find_if( + _sensors.begin(), + _sensors.end(), + [&sensor](const auto& s) + { + return sensor.name() == s.get()->name(); + }) != _sensors.end()); + } + + /** + * Stops the timers on all sensors in the group. + * + * Called when the group just changed to not trusted, + * so that its sensors' timers can't fire a callback + * that may cause them to be considered faulted. + */ + void stopTimers() + { + std::for_each( + _sensors.begin(), + _sensors.end(), + [](const auto& s) + { + s.get()->stopTimer(); + }); + } + + /** + * Starts the timers on all functional sensors in the group. + * + * Called when the group just changed to trusted. + */ + void startTimers() + { + std::for_each( + _sensors.begin(), + _sensors.end(), + [](const auto& s) + { + //If a sensor isn't functional, then its timer + //already expired so don't bother starting it again + if (s.get()->functional()) + { + s.get()->startTimer(); + } + }); + } + + /** + * Determines the trust for this group based on this + * sensor's latest status. + * + * Calls the derived class's checkGroupTrust function + * and updates the class with the results. + * + * If this is called with a sensor not in the group, + * it will be considered trusted. + * + * @param[in] sensor - TachSensor object + * + * @return tuple<bool, bool> - + * field 0 - the trust value + * field 1 - if that trust value changed since last call + * to checkTrust + */ + auto checkTrust(const monitor::TachSensor& sensor) + { + if (inGroup(sensor)) + { + auto trust = checkGroupTrust(); + + setTrust(trust); + + return std::tuple<bool, bool>(_trusted, _stateChange); + } + return std::tuple<bool, bool>(true, false); + } + + /** + * Says if all sensors in the group are currently trusted, + * as determined by the last call to checkTrust(). + * + * @return bool - if the group's sensors are trusted or not + */ + inline auto getTrust() const + { + return _trusted; + } + + /** + * Says if the trust value changed in the last call to + * checkTrust() + * + * @return bool - if the trust changed or not + */ + inline auto trustChanged() const + { + return _stateChange; + } + + protected: + + /** + * The sensor objects in the group. + * + * Added by registerSensor(). + */ + std::vector<std::reference_wrapper< + std::unique_ptr<monitor::TachSensor>>> _sensors; + + private: + + /** + * Checks if the group's sensors are trusted. + * + * The derived class must override this function + * to provide custom functionality. + * + * @return bool - if group is trusted or not + */ + virtual bool checkGroupTrust() = 0; + + /** + * Sets the trust value on the object. + * + * @param[in] trust - the new trust value + */ + inline void setTrust(bool trust) + { + _stateChange = (trust != _trusted); + _trusted = trust; + } + + /** + * The current trust state of the group + */ + bool _trusted = true; + + /** + * If the trust value changed in the last call to checkTrust + */ + bool _stateChange = false; + + /** + * The names of the sensors that should be added to this group + */ + const std::vector<std::string> _names; +}; + +} +} +} |