1 #pragma once
2 
3 #include <memory>
4 #include <vector>
5 #include "tach_sensor.hpp"
6 #include "trust_group.hpp"
7 #include "types.hpp"
8 
9 namespace phosphor
10 {
11 namespace fan
12 {
13 namespace trust
14 {
15 
16 /**
17  * @class Manager
18  *
19  * The sensor trust manager class.  It can be asked if a tach sensor's
20  * reading can be trusted or not, based on the trust groups the sensor
21  * is in.
22  *
23  * When it finds a group's trust status changing, it will either stop or
24  * start the tach error timers for the group's sensors accordingly.
25  *
26  * See the trust::Group documentation for more details on sensor trust.
27  */
28 class Manager
29 {
30     public:
31 
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(
86                 const monitor::TachSensor& sensor)
87         {
88             auto trusted = true;
89 
90             for (auto& group : groups)
91             {
92                 if (group->inGroup(sensor))
93                 {
94                     bool trust, changed;
95                     std::tie(trust, changed) = group->checkTrust(sensor);
96 
97                     if (!trust)
98                     {
99                         trusted = false;
100 
101                         if (changed)
102                         {
103                             group->stopTimers();
104                         }
105                     }
106                     else
107                     {
108                         if (changed)
109                         {
110                             group->startTimers();
111                         }
112                     }
113                 }
114             }
115 
116             return trusted;
117         }
118 
119         /**
120          * Registers a sensor with any trust groups that are interested
121          *
122          * @param[in] sensor - the sensor to register
123          */
124         void registerSensor(
125                 std::shared_ptr<monitor::TachSensor>& sensor)
126         {
127             std::for_each(
128                     groups.begin(),
129                     groups.end(),
130                     [&sensor](auto& group)
131                     {
132                         group->registerSensor(sensor);
133                     });
134         }
135 
136     private:
137 
138         /**
139          * The list of sensor trust groups
140          */
141         std::vector<std::unique_ptr<Group>> groups;
142 };
143 
144 }
145 }
146 }
147