xref: /openbmc/phosphor-fan-presence/monitor/trust_manager.hpp (revision fcb0dbcb144020606780da9dd2e2be517ef7cf6d)
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 
7177fe986SMatthew Barth #include <memory>
8177fe986SMatthew Barth #include <vector>
9177fe986SMatthew 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      */
Manager(const std::vector<monitor::CreateGroupFunction> & functions)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      */
active() const58136e23ddSMatt 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
72*fcb0dbcbSMatthew Barth      * just changed to false, it will cancel the tach error
73*fcb0dbcbSMatthew Barth      * method for that group so these untrusted sensors won't
74*fcb0dbcbSMatthew Barth      * cause errors.
75136e23ddSMatt Spinler      *
76136e23ddSMatt Spinler      * Note this means groups should be designed such that
77136e23ddSMatt Spinler      * in the same call to this function a sensor shouldn't
78136e23ddSMatt Spinler      * make one group change to trusted and another to untrusted.
79136e23ddSMatt Spinler      *
80136e23ddSMatt Spinler      * @param[in] sensor - the sensor to check
81136e23ddSMatt Spinler      *
82136e23ddSMatt Spinler      * @return bool - if sensor is trusted in all groups or not
83136e23ddSMatt Spinler      */
checkTrust(const monitor::TachSensor & sensor)84177fe986SMatthew Barth     bool checkTrust(const monitor::TachSensor& sensor)
85136e23ddSMatt Spinler     {
86136e23ddSMatt Spinler         auto trusted = true;
87136e23ddSMatt Spinler 
88136e23ddSMatt Spinler         for (auto& group : groups)
89136e23ddSMatt Spinler         {
90136e23ddSMatt Spinler             if (group->inGroup(sensor))
91136e23ddSMatt Spinler             {
92136e23ddSMatt Spinler                 bool trust, changed;
93136e23ddSMatt Spinler                 std::tie(trust, changed) = group->checkTrust(sensor);
94136e23ddSMatt Spinler 
95136e23ddSMatt Spinler                 if (!trust)
96136e23ddSMatt Spinler                 {
97136e23ddSMatt Spinler                     trusted = false;
98136e23ddSMatt Spinler 
99136e23ddSMatt Spinler                     if (changed)
100136e23ddSMatt Spinler                     {
101*fcb0dbcbSMatthew Barth                         group->cancelMonitoring();
102136e23ddSMatt Spinler                     }
103136e23ddSMatt Spinler                 }
104136e23ddSMatt Spinler                 else
105136e23ddSMatt Spinler                 {
106136e23ddSMatt Spinler                     if (changed)
107136e23ddSMatt Spinler                     {
108*fcb0dbcbSMatthew Barth                         group->startMonitoring();
109136e23ddSMatt Spinler                     }
110136e23ddSMatt Spinler                 }
111136e23ddSMatt Spinler             }
112136e23ddSMatt Spinler         }
113136e23ddSMatt Spinler 
114136e23ddSMatt Spinler         return trusted;
115136e23ddSMatt Spinler     }
116136e23ddSMatt Spinler 
117136e23ddSMatt Spinler     /**
118136e23ddSMatt Spinler      * Registers a sensor with any trust groups that are interested
119136e23ddSMatt Spinler      *
120136e23ddSMatt Spinler      * @param[in] sensor - the sensor to register
121136e23ddSMatt Spinler      */
registerSensor(std::shared_ptr<monitor::TachSensor> & sensor)122177fe986SMatthew Barth     void registerSensor(std::shared_ptr<monitor::TachSensor>& sensor)
123136e23ddSMatt Spinler     {
124177fe986SMatthew Barth         std::for_each(groups.begin(), groups.end(), [&sensor](auto& group) {
125136e23ddSMatt Spinler             group->registerSensor(sensor);
126136e23ddSMatt Spinler         });
127136e23ddSMatt Spinler     }
128136e23ddSMatt Spinler 
129136e23ddSMatt Spinler   private:
130136e23ddSMatt Spinler     /**
131136e23ddSMatt Spinler      * The list of sensor trust groups
132136e23ddSMatt Spinler      */
133136e23ddSMatt Spinler     std::vector<std::unique_ptr<Group>> groups;
134136e23ddSMatt Spinler };
135136e23ddSMatt Spinler 
136177fe986SMatthew Barth } // namespace trust
137177fe986SMatthew Barth } // namespace fan
138177fe986SMatthew Barth } // namespace phosphor
139