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