xref: /openbmc/phosphor-fan-presence/monitor/trust_manager.hpp (revision 177fe986c14f5feecb97ef1aec435d2780b6e473)
1136e23ddSMatt Spinler #pragma once
2136e23ddSMatt Spinler 
3136e23ddSMatt Spinler #include "tach_sensor.hpp"
4136e23ddSMatt Spinler #include "trust_group.hpp"
5136e23ddSMatt Spinler #include "types.hpp"
6136e23ddSMatt Spinler 
7*177fe986SMatthew Barth #include <memory>
8*177fe986SMatthew Barth #include <vector>
9*177fe986SMatthew Barth 
10136e23ddSMatt Spinler namespace phosphor
11136e23ddSMatt Spinler {
12136e23ddSMatt Spinler namespace fan
13136e23ddSMatt Spinler {
14136e23ddSMatt Spinler namespace trust
15136e23ddSMatt Spinler {
16136e23ddSMatt Spinler 
17136e23ddSMatt Spinler /**
18136e23ddSMatt Spinler  * @class Manager
19136e23ddSMatt Spinler  *
20136e23ddSMatt Spinler  * The sensor trust manager class.  It can be asked if a tach sensor's
21136e23ddSMatt Spinler  * reading can be trusted or not, based on the trust groups the sensor
22136e23ddSMatt Spinler  * is in.
23136e23ddSMatt Spinler  *
24136e23ddSMatt Spinler  * When it finds a group's trust status changing, it will either stop or
25136e23ddSMatt Spinler  * start the tach error timers for the group's sensors accordingly.
26136e23ddSMatt Spinler  *
27136e23ddSMatt Spinler  * See the trust::Group documentation for more details on sensor trust.
28136e23ddSMatt Spinler  */
29136e23ddSMatt Spinler class Manager
30136e23ddSMatt Spinler {
31136e23ddSMatt Spinler   public:
32136e23ddSMatt Spinler     Manager() = delete;
33136e23ddSMatt Spinler     Manager(const Manager&) = delete;
34136e23ddSMatt Spinler     Manager& operator=(const Manager&) = delete;
35136e23ddSMatt Spinler     Manager(Manager&&) = default;
36136e23ddSMatt Spinler     Manager& operator=(Manager&&) = default;
37136e23ddSMatt Spinler     ~Manager() = default;
38136e23ddSMatt Spinler 
39136e23ddSMatt Spinler     /**
40136e23ddSMatt Spinler      * Constructor
41136e23ddSMatt Spinler      *
42136e23ddSMatt Spinler      * @param[in] functions - trust group creation function vector
43136e23ddSMatt Spinler      */
44136e23ddSMatt Spinler     explicit Manager(const std::vector<monitor::CreateGroupFunction>& functions)
45136e23ddSMatt Spinler     {
46136e23ddSMatt Spinler         for (auto& create : functions)
47136e23ddSMatt Spinler         {
48136e23ddSMatt Spinler             groups.emplace_back(create());
49136e23ddSMatt Spinler         }
50136e23ddSMatt Spinler     }
51136e23ddSMatt Spinler 
52136e23ddSMatt Spinler     /**
53136e23ddSMatt Spinler      * Says if trust groups have been created and
54136e23ddSMatt Spinler      * need to be checked.
55136e23ddSMatt Spinler      *
56136e23ddSMatt Spinler      * @return bool - If there are any trust groups
57136e23ddSMatt Spinler      */
58136e23ddSMatt Spinler     inline bool active() const
59136e23ddSMatt Spinler     {
60136e23ddSMatt Spinler         return !groups.empty();
61136e23ddSMatt Spinler     }
62136e23ddSMatt Spinler 
63136e23ddSMatt Spinler     /**
64136e23ddSMatt Spinler      * Checks if a sensor value can be trusted
65136e23ddSMatt Spinler      *
66136e23ddSMatt Spinler      * Checks if the sensor is trusted in each group
67136e23ddSMatt Spinler      * it belongs to.  Only considered trusted if it is
68136e23ddSMatt Spinler      * trusted in all groups it belongs to.
69136e23ddSMatt Spinler      *
70136e23ddSMatt Spinler      * While checking group trust, the code will also check
71136e23ddSMatt Spinler      * if the trust status has just changed.  If the status
72136e23ddSMatt Spinler      * just changed to false, it will stop the tach error
73136e23ddSMatt Spinler      * timers for that group so these untrusted sensors won't
74136e23ddSMatt Spinler      * cause errors.  If changed to true, it will start those timers
75136e23ddSMatt Spinler      * back up again.
76136e23ddSMatt Spinler      *
77136e23ddSMatt Spinler      * Note this means groups should be designed such that
78136e23ddSMatt Spinler      * in the same call to this function a sensor shouldn't
79136e23ddSMatt Spinler      * make one group change to trusted and another to untrusted.
80136e23ddSMatt Spinler      *
81136e23ddSMatt Spinler      * @param[in] sensor - the sensor to check
82136e23ddSMatt Spinler      *
83136e23ddSMatt Spinler      * @return bool - if sensor is trusted in all groups or not
84136e23ddSMatt Spinler      */
85*177fe986SMatthew Barth     bool checkTrust(const monitor::TachSensor& sensor)
86136e23ddSMatt Spinler     {
87136e23ddSMatt Spinler         auto trusted = true;
88136e23ddSMatt Spinler 
89136e23ddSMatt Spinler         for (auto& group : groups)
90136e23ddSMatt Spinler         {
91136e23ddSMatt Spinler             if (group->inGroup(sensor))
92136e23ddSMatt Spinler             {
93136e23ddSMatt Spinler                 bool trust, changed;
94136e23ddSMatt Spinler                 std::tie(trust, changed) = group->checkTrust(sensor);
95136e23ddSMatt Spinler 
96136e23ddSMatt Spinler                 if (!trust)
97136e23ddSMatt Spinler                 {
98136e23ddSMatt Spinler                     trusted = false;
99136e23ddSMatt Spinler 
100136e23ddSMatt Spinler                     if (changed)
101136e23ddSMatt Spinler                     {
102136e23ddSMatt Spinler                         group->stopTimers();
103136e23ddSMatt Spinler                     }
104136e23ddSMatt Spinler                 }
105136e23ddSMatt Spinler                 else
106136e23ddSMatt Spinler                 {
107136e23ddSMatt Spinler                     if (changed)
108136e23ddSMatt Spinler                     {
109136e23ddSMatt Spinler                         group->startTimers();
110136e23ddSMatt Spinler                     }
111136e23ddSMatt Spinler                 }
112136e23ddSMatt Spinler             }
113136e23ddSMatt Spinler         }
114136e23ddSMatt Spinler 
115136e23ddSMatt Spinler         return trusted;
116136e23ddSMatt Spinler     }
117136e23ddSMatt Spinler 
118136e23ddSMatt Spinler     /**
119136e23ddSMatt Spinler      * Registers a sensor with any trust groups that are interested
120136e23ddSMatt Spinler      *
121136e23ddSMatt Spinler      * @param[in] sensor - the sensor to register
122136e23ddSMatt Spinler      */
123*177fe986SMatthew Barth     void registerSensor(std::shared_ptr<monitor::TachSensor>& sensor)
124136e23ddSMatt Spinler     {
125*177fe986SMatthew Barth         std::for_each(groups.begin(), groups.end(), [&sensor](auto& group) {
126136e23ddSMatt Spinler             group->registerSensor(sensor);
127136e23ddSMatt Spinler         });
128136e23ddSMatt Spinler     }
129136e23ddSMatt Spinler 
130136e23ddSMatt Spinler   private:
131136e23ddSMatt Spinler     /**
132136e23ddSMatt Spinler      * The list of sensor trust groups
133136e23ddSMatt Spinler      */
134136e23ddSMatt Spinler     std::vector<std::unique_ptr<Group>> groups;
135136e23ddSMatt Spinler };
136136e23ddSMatt Spinler 
137*177fe986SMatthew Barth } // namespace trust
138*177fe986SMatthew Barth } // namespace fan
139*177fe986SMatthew Barth } // namespace phosphor
140