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 cancel the tach error
73      * method for that group so these untrusted sensors won't
74      * cause errors.
75      *
76      * Note this means groups should be designed such that
77      * in the same call to this function a sensor shouldn't
78      * make one group change to trusted and another to untrusted.
79      *
80      * @param[in] sensor - the sensor to check
81      *
82      * @return bool - if sensor is trusted in all groups or not
83      */
84     bool checkTrust(const monitor::TachSensor& sensor)
85     {
86         auto trusted = true;
87 
88         for (auto& group : groups)
89         {
90             if (group->inGroup(sensor))
91             {
92                 bool trust, changed;
93                 std::tie(trust, changed) = group->checkTrust(sensor);
94 
95                 if (!trust)
96                 {
97                     trusted = false;
98 
99                     if (changed)
100                     {
101                         group->cancelMonitoring();
102                     }
103                 }
104                 else
105                 {
106                     if (changed)
107                     {
108                         group->startMonitoring();
109                     }
110                 }
111             }
112         }
113 
114         return trusted;
115     }
116 
117     /**
118      * Registers a sensor with any trust groups that are interested
119      *
120      * @param[in] sensor - the sensor to register
121      */
122     void registerSensor(std::shared_ptr<monitor::TachSensor>& sensor)
123     {
124         std::for_each(groups.begin(), groups.end(), [&sensor](auto& group) {
125             group->registerSensor(sensor);
126         });
127     }
128 
129   private:
130     /**
131      * The list of sensor trust groups
132      */
133     std::vector<std::unique_ptr<Group>> groups;
134 };
135 
136 } // namespace trust
137 } // namespace fan
138 } // namespace phosphor
139