1 #pragma once 2 3 #include <sdbusplus/bus.hpp> 4 #include <sdeventplus/event.hpp> 5 #include <tuple> 6 #include <vector> 7 #include "tach_sensor.hpp" 8 #include "trust_manager.hpp" 9 #include "types.hpp" 10 11 namespace phosphor 12 { 13 namespace fan 14 { 15 namespace monitor 16 { 17 18 /** 19 * @class InvalidSensorError 20 * 21 * An exception type for sensors that don't exist or 22 * are otherwise inaccessible. 23 */ 24 class InvalidSensorError : public std::exception {}; 25 26 /** 27 * @class Fan 28 * 29 * Represents a fan, which can contain 1 or more sensors which 30 * loosely correspond to rotors. See below. 31 * 32 * There is a sensor when hwmon exposes one, which means there is a 33 * speed value to be read. Sometimes there is a sensor per rotor, 34 * and other times multiple rotors just use 1 sensor total where 35 * the sensor reports the slowest speed of all of the rotors. 36 * 37 * A rotor's speed is set by writing the Target value of a sensor. 38 * Sometimes each sensor in a fan supports having a Target, and other 39 * times not all of them do. A TachSensor object knows if it supports 40 * the Target property. 41 * 42 * The strategy for monitoring fan speeds is as follows: 43 * 44 * Every time a Target (new speed written) or Input (actual speed read) 45 * sensor changes, check if the input value is within some range of the target 46 * value. If it isn't, start a timer at the end of which the sensor will be 47 * set to not functional. If enough sensors in the fan are now nonfunctional, 48 * set the whole fan to nonfunctional in the inventory. 49 * 50 * When sensor inputs come back within a specified range of the target, 51 * stop its timer if running, make the sensor functional again if it wasn't, 52 * and if enough sensors in the fan are now functional set the whole fan 53 * back to functional in the inventory. 54 */ 55 class Fan 56 { 57 using Property = std::string; 58 using Value = std::variant<bool>; 59 using PropertyMap = std::map<Property, Value>; 60 61 using Interface = std::string; 62 using InterfaceMap = std::map<Interface, PropertyMap>; 63 64 using Object = sdbusplus::message::object_path; 65 using ObjectMap = std::map<Object, InterfaceMap>; 66 67 public: 68 69 Fan() = delete; 70 Fan(const Fan&) = delete; 71 Fan(Fan&&) = default; 72 Fan& operator=(const Fan&) = delete; 73 Fan& operator=(Fan&&) = default; 74 ~Fan() = default; 75 76 /** 77 * @brief Constructor 78 * 79 * @param mode - mode of fan monitor 80 * @param bus - the dbus object 81 * @param event - event loop reference 82 * @param trust - the tach trust manager 83 * @param def - the fan definition structure 84 */ 85 Fan(Mode mode, 86 sdbusplus::bus::bus& bus, 87 const sdeventplus::Event& event, 88 std::unique_ptr<trust::Manager>& trust, 89 const FanDefinition& def); 90 91 /** 92 * @brief Callback function for when an input sensor changes 93 * 94 * Starts a timer, where if it expires then the sensor 95 * was out of range for too long and can be considered not functional. 96 */ 97 void tachChanged(TachSensor& sensor); 98 99 /** 100 * @brief Calls tachChanged(sensor) on each sensor 101 */ 102 void tachChanged(); 103 104 /** 105 * @brief The callback function for the timer 106 * 107 * Sets the sensor to not functional. 108 * If enough sensors are now not functional, 109 * updates the functional status of the whole 110 * fan in the inventory. 111 * 112 * @param[in] sensor - the sensor whose timer expired 113 */ 114 void timerExpired(TachSensor& sensor); 115 116 /** 117 * @brief Get the name of the fan 118 * 119 * @return - The fan name 120 */ 121 inline const std::string& getName() const 122 { 123 return _name; 124 } 125 126 /** 127 * @brief Finds the target speed of this fan 128 * 129 * Finds the target speed from the list of sensors that make up this 130 * fan. At least one sensor should contain a target speed value. 131 * 132 * @return - The target speed found from the list of sensors on the fan 133 */ 134 uint64_t findTargetSpeed(); 135 136 private: 137 138 /** 139 * @brief Returns true if the sensor input is not within 140 * some deviation of the target. 141 * 142 * @param[in] sensor - the sensor to check 143 */ 144 bool outOfRange(const TachSensor& sensor); 145 146 /** 147 * @brief Returns true if too many sensors are nonfunctional 148 * as defined by _numSensorFailsForNonFunc 149 */ 150 bool tooManySensorsNonfunctional(); 151 152 /** 153 * @brief Updates the Functional property in the inventory 154 * for the fan based on the value passed in. 155 * 156 * @param[in] functional - If the Functional property should 157 * be set to true or false. 158 */ 159 void updateInventory(bool functional); 160 161 /** 162 * @brief the dbus object 163 */ 164 sdbusplus::bus::bus& _bus; 165 166 /** 167 * @brief The inventory name of the fan 168 */ 169 const std::string _name; 170 171 /** 172 * @brief The percentage that the input speed must be below 173 * the target speed to be considered an error. 174 * Between 0 and 100. 175 */ 176 const size_t _deviation; 177 178 /** 179 * The number of sensors that must be nonfunctional at the 180 * same time in order for the fan to be set to nonfunctional 181 * in the inventory. 182 */ 183 const size_t _numSensorFailsForNonFunc; 184 185 /** 186 * @brief The current functional state of the fan 187 */ 188 bool _functional = true; 189 190 /** 191 * The sensor objects for the fan 192 */ 193 std::vector<std::shared_ptr<TachSensor>> _sensors; 194 195 /** 196 * The tach trust manager object 197 */ 198 std::unique_ptr<trust::Manager>& _trustManager; 199 }; 200 201 } 202 } 203 } 204