1*136e23ddSMatt Spinler #pragma once 2*136e23ddSMatt Spinler 3*136e23ddSMatt Spinler #include <memory> 4*136e23ddSMatt Spinler #include <vector> 5*136e23ddSMatt Spinler #include "tach_sensor.hpp" 6*136e23ddSMatt Spinler #include "trust_group.hpp" 7*136e23ddSMatt Spinler #include "types.hpp" 8*136e23ddSMatt Spinler 9*136e23ddSMatt Spinler namespace phosphor 10*136e23ddSMatt Spinler { 11*136e23ddSMatt Spinler namespace fan 12*136e23ddSMatt Spinler { 13*136e23ddSMatt Spinler namespace trust 14*136e23ddSMatt Spinler { 15*136e23ddSMatt Spinler 16*136e23ddSMatt Spinler /** 17*136e23ddSMatt Spinler * @class Manager 18*136e23ddSMatt Spinler * 19*136e23ddSMatt Spinler * The sensor trust manager class. It can be asked if a tach sensor's 20*136e23ddSMatt Spinler * reading can be trusted or not, based on the trust groups the sensor 21*136e23ddSMatt Spinler * is in. 22*136e23ddSMatt Spinler * 23*136e23ddSMatt Spinler * When it finds a group's trust status changing, it will either stop or 24*136e23ddSMatt Spinler * start the tach error timers for the group's sensors accordingly. 25*136e23ddSMatt Spinler * 26*136e23ddSMatt Spinler * See the trust::Group documentation for more details on sensor trust. 27*136e23ddSMatt Spinler */ 28*136e23ddSMatt Spinler class Manager 29*136e23ddSMatt Spinler { 30*136e23ddSMatt Spinler public: 31*136e23ddSMatt Spinler 32*136e23ddSMatt Spinler Manager() = delete; 33*136e23ddSMatt Spinler Manager(const Manager&) = delete; 34*136e23ddSMatt Spinler Manager& operator=(const Manager&) = delete; 35*136e23ddSMatt Spinler Manager(Manager&&) = default; 36*136e23ddSMatt Spinler Manager& operator=(Manager&&) = default; 37*136e23ddSMatt Spinler ~Manager() = default; 38*136e23ddSMatt Spinler 39*136e23ddSMatt Spinler /** 40*136e23ddSMatt Spinler * Constructor 41*136e23ddSMatt Spinler * 42*136e23ddSMatt Spinler * @param[in] functions - trust group creation function vector 43*136e23ddSMatt Spinler */ 44*136e23ddSMatt Spinler explicit Manager(const std::vector<monitor::CreateGroupFunction>& functions) 45*136e23ddSMatt Spinler { 46*136e23ddSMatt Spinler for (auto& create : functions) 47*136e23ddSMatt Spinler { 48*136e23ddSMatt Spinler groups.emplace_back(create()); 49*136e23ddSMatt Spinler } 50*136e23ddSMatt Spinler } 51*136e23ddSMatt Spinler 52*136e23ddSMatt Spinler /** 53*136e23ddSMatt Spinler * Says if trust groups have been created and 54*136e23ddSMatt Spinler * need to be checked. 55*136e23ddSMatt Spinler * 56*136e23ddSMatt Spinler * @return bool - If there are any trust groups 57*136e23ddSMatt Spinler */ 58*136e23ddSMatt Spinler inline bool active() const 59*136e23ddSMatt Spinler { 60*136e23ddSMatt Spinler return !groups.empty(); 61*136e23ddSMatt Spinler } 62*136e23ddSMatt Spinler 63*136e23ddSMatt Spinler /** 64*136e23ddSMatt Spinler * Checks if a sensor value can be trusted 65*136e23ddSMatt Spinler * 66*136e23ddSMatt Spinler * Checks if the sensor is trusted in each group 67*136e23ddSMatt Spinler * it belongs to. Only considered trusted if it is 68*136e23ddSMatt Spinler * trusted in all groups it belongs to. 69*136e23ddSMatt Spinler * 70*136e23ddSMatt Spinler * While checking group trust, the code will also check 71*136e23ddSMatt Spinler * if the trust status has just changed. If the status 72*136e23ddSMatt Spinler * just changed to false, it will stop the tach error 73*136e23ddSMatt Spinler * timers for that group so these untrusted sensors won't 74*136e23ddSMatt Spinler * cause errors. If changed to true, it will start those timers 75*136e23ddSMatt Spinler * back up again. 76*136e23ddSMatt Spinler * 77*136e23ddSMatt Spinler * Note this means groups should be designed such that 78*136e23ddSMatt Spinler * in the same call to this function a sensor shouldn't 79*136e23ddSMatt Spinler * make one group change to trusted and another to untrusted. 80*136e23ddSMatt Spinler * 81*136e23ddSMatt Spinler * @param[in] sensor - the sensor to check 82*136e23ddSMatt Spinler * 83*136e23ddSMatt Spinler * @return bool - if sensor is trusted in all groups or not 84*136e23ddSMatt Spinler */ 85*136e23ddSMatt Spinler bool checkTrust( 86*136e23ddSMatt Spinler const monitor::TachSensor& sensor) 87*136e23ddSMatt Spinler { 88*136e23ddSMatt Spinler auto trusted = true; 89*136e23ddSMatt Spinler 90*136e23ddSMatt Spinler for (auto& group : groups) 91*136e23ddSMatt Spinler { 92*136e23ddSMatt Spinler if (group->inGroup(sensor)) 93*136e23ddSMatt Spinler { 94*136e23ddSMatt Spinler bool trust, changed; 95*136e23ddSMatt Spinler std::tie(trust, changed) = group->checkTrust(sensor); 96*136e23ddSMatt Spinler 97*136e23ddSMatt Spinler if (!trust) 98*136e23ddSMatt Spinler { 99*136e23ddSMatt Spinler trusted = false; 100*136e23ddSMatt Spinler 101*136e23ddSMatt Spinler if (changed) 102*136e23ddSMatt Spinler { 103*136e23ddSMatt Spinler group->stopTimers(); 104*136e23ddSMatt Spinler } 105*136e23ddSMatt Spinler } 106*136e23ddSMatt Spinler else 107*136e23ddSMatt Spinler { 108*136e23ddSMatt Spinler if (changed) 109*136e23ddSMatt Spinler { 110*136e23ddSMatt Spinler group->startTimers(); 111*136e23ddSMatt Spinler } 112*136e23ddSMatt Spinler } 113*136e23ddSMatt Spinler } 114*136e23ddSMatt Spinler } 115*136e23ddSMatt Spinler 116*136e23ddSMatt Spinler return trusted; 117*136e23ddSMatt Spinler } 118*136e23ddSMatt Spinler 119*136e23ddSMatt Spinler /** 120*136e23ddSMatt Spinler * Registers a sensor with any trust groups that are interested 121*136e23ddSMatt Spinler * 122*136e23ddSMatt Spinler * @param[in] sensor - the sensor to register 123*136e23ddSMatt Spinler */ 124*136e23ddSMatt Spinler void registerSensor( 125*136e23ddSMatt Spinler std::unique_ptr<monitor::TachSensor>& sensor) 126*136e23ddSMatt Spinler { 127*136e23ddSMatt Spinler std::for_each( 128*136e23ddSMatt Spinler groups.begin(), 129*136e23ddSMatt Spinler groups.end(), 130*136e23ddSMatt Spinler [&sensor](auto& group) 131*136e23ddSMatt Spinler { 132*136e23ddSMatt Spinler group->registerSensor(sensor); 133*136e23ddSMatt Spinler }); 134*136e23ddSMatt Spinler } 135*136e23ddSMatt Spinler 136*136e23ddSMatt Spinler private: 137*136e23ddSMatt Spinler 138*136e23ddSMatt Spinler /** 139*136e23ddSMatt Spinler * The list of sensor trust groups 140*136e23ddSMatt Spinler */ 141*136e23ddSMatt Spinler std::vector<std::unique_ptr<Group>> groups; 142*136e23ddSMatt Spinler }; 143*136e23ddSMatt Spinler 144*136e23ddSMatt Spinler } 145*136e23ddSMatt Spinler } 146*136e23ddSMatt Spinler } 147