| #pragma once | 
 |  | 
 | #include <sdbusplus/bus.hpp> | 
 | #include <sdeventplus/event.hpp> | 
 | #include <tuple> | 
 | #include <vector> | 
 | #include "tach_sensor.hpp" | 
 | #include "trust_manager.hpp" | 
 | #include "types.hpp" | 
 |  | 
 | namespace phosphor | 
 | { | 
 | namespace fan | 
 | { | 
 | namespace monitor | 
 | { | 
 |  | 
 | /** | 
 |  * @class InvalidSensorError | 
 |  * | 
 |  * An exception type for sensors that don't exist or | 
 |  * are otherwise inaccessible. | 
 |  */ | 
 | class InvalidSensorError : public std::exception {}; | 
 |  | 
 | /** | 
 |  * @class Fan | 
 |  * | 
 |  * Represents a fan, which can contain 1 or more sensors which | 
 |  * loosely correspond to rotors.  See below. | 
 |  * | 
 |  * There is a sensor when hwmon exposes one, which means there is a | 
 |  * speed value to be read.  Sometimes there is a sensor per rotor, | 
 |  * and other times multiple rotors just use 1 sensor total where | 
 |  * the sensor reports the slowest speed of all of the rotors. | 
 |  * | 
 |  * A rotor's speed is set by writing the Target value of a sensor. | 
 |  * Sometimes each sensor in a fan supports having a Target, and other | 
 |  * times not all of them do.  A TachSensor object knows if it supports | 
 |  * the Target property. | 
 |  * | 
 |  * The strategy for monitoring fan speeds is as follows: | 
 |  * | 
 |  * Every time a Target (new speed written) or Input (actual speed read) | 
 |  * sensor changes, check if the input value is within some range of the target | 
 |  * value.  If it isn't, start a timer at the end of which the sensor will be | 
 |  * set to not functional.  If enough sensors in the fan are now nonfunctional, | 
 |  * set the whole fan to nonfunctional in the inventory. | 
 |  * | 
 |  * When sensor inputs come back within a specified range of the target, | 
 |  * stop its timer if running, make the sensor functional again if it wasn't, | 
 |  * and if enough sensors in the fan are now functional set the whole fan | 
 |  * back to functional in the inventory. | 
 |  */ | 
 | class Fan | 
 | { | 
 |     using Property = std::string; | 
 |     using Value = sdbusplus::message::variant<bool>; | 
 |     using PropertyMap = std::map<Property, Value>; | 
 |  | 
 |     using Interface = std::string; | 
 |     using InterfaceMap = std::map<Interface, PropertyMap>; | 
 |  | 
 |     using Object = sdbusplus::message::object_path; | 
 |     using ObjectMap = std::map<Object, InterfaceMap>; | 
 |  | 
 |     public: | 
 |  | 
 |         Fan() = delete; | 
 |         Fan(const Fan&) = delete; | 
 |         Fan(Fan&&) = default; | 
 |         Fan& operator=(const Fan&) = delete; | 
 |         Fan& operator=(Fan&&) = default; | 
 |         ~Fan() = default; | 
 |  | 
 |         /** | 
 |          * @brief Constructor | 
 |          * | 
 |          * @param mode - mode of fan monitor | 
 |          * @param bus - the dbus object | 
 |          * @param event - event loop reference | 
 |          * @param trust - the tach trust manager | 
 |          * @param def - the fan definition structure | 
 |          */ | 
 |         Fan(Mode mode, | 
 |             sdbusplus::bus::bus& bus, | 
 |             const sdeventplus::Event& event, | 
 |             std::unique_ptr<trust::Manager>& trust, | 
 |             const FanDefinition& def); | 
 |  | 
 |         /** | 
 |          * @brief Callback function for when an input sensor changes | 
 |          * | 
 |          * Starts a timer, where if it expires then the sensor | 
 |          * was out of range for too long and can be considered not functional. | 
 |          */ | 
 |         void tachChanged(TachSensor& sensor); | 
 |  | 
 |         /** | 
 |          * @brief Calls tachChanged(sensor) on each sensor | 
 |          */ | 
 |         void tachChanged(); | 
 |  | 
 |         /** | 
 |          * @brief The callback function for the timer | 
 |          * | 
 |          * Sets the sensor to not functional. | 
 |          * If enough sensors are now not functional, | 
 |          * updates the functional status of the whole | 
 |          * fan in the inventory. | 
 |          * | 
 |          * @param[in] sensor - the sensor whose timer expired | 
 |          */ | 
 |         void timerExpired(TachSensor& sensor); | 
 |  | 
 |         /** | 
 |          * @brief Get the name of the fan | 
 |          * | 
 |          * @return - The fan name | 
 |          */ | 
 |         inline const std::string& getName() const | 
 |         { | 
 |             return _name; | 
 |         } | 
 |  | 
 |         /** | 
 |          * @brief Finds the target speed of this fan | 
 |          * | 
 |          * Finds the target speed from the list of sensors that make up this | 
 |          * fan. At least one sensor should contain a target speed value. | 
 |          * | 
 |          * @return - The target speed found from the list of sensors on the fan | 
 |          */ | 
 |         uint64_t findTargetSpeed(); | 
 |  | 
 |     private: | 
 |  | 
 |         /** | 
 |          * @brief Returns true if the sensor input is not within | 
 |          * some deviation of the target. | 
 |          * | 
 |          * @param[in] sensor - the sensor to check | 
 |          */ | 
 |         bool outOfRange(const TachSensor& sensor); | 
 |  | 
 |         /** | 
 |          * @brief Returns true if too many sensors are nonfunctional | 
 |          *        as defined by _numSensorFailsForNonFunc | 
 |          */ | 
 |         bool tooManySensorsNonfunctional(); | 
 |  | 
 |         /** | 
 |          * @brief Updates the Functional property in the inventory | 
 |          *        for the fan based on the value passed in. | 
 |          * | 
 |          * @param[in] functional - If the Functional property should | 
 |          *                         be set to true or false. | 
 |          */ | 
 |         void updateInventory(bool functional); | 
 |  | 
 |         /** | 
 |          * @brief the dbus object | 
 |          */ | 
 |         sdbusplus::bus::bus& _bus; | 
 |  | 
 |         /** | 
 |          * @brief The inventory name of the fan | 
 |          */ | 
 |         const std::string _name; | 
 |  | 
 |         /** | 
 |          * @brief The percentage that the input speed must be below | 
 |          *        the target speed to be considered an error. | 
 |          *        Between 0 and 100. | 
 |          */ | 
 |         const size_t _deviation; | 
 |  | 
 |         /** | 
 |          * The number of sensors that must be nonfunctional at the | 
 |          * same time in order for the fan to be set to nonfunctional | 
 |          * in the inventory. | 
 |          */ | 
 |         const size_t _numSensorFailsForNonFunc; | 
 |  | 
 |         /** | 
 |          * @brief The current functional state of the fan | 
 |          */ | 
 |         bool _functional = true; | 
 |  | 
 |         /** | 
 |          * The sensor objects for the fan | 
 |          */ | 
 |         std::vector<std::shared_ptr<TachSensor>> _sensors; | 
 |  | 
 |         /** | 
 |          * The tach trust manager object | 
 |          */ | 
 |         std::unique_ptr<trust::Manager>& _trustManager; | 
 | }; | 
 |  | 
 | } | 
 | } | 
 | } |