xref: /openbmc/phosphor-fan-presence/monitor/trust_manager.hpp (revision 136e23dd27dbff225fd7b68cb624e4b612cf790f)
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