summaryrefslogtreecommitdiffstats
path: root/monitor/trust_manager.hpp
blob: d78e6476fab8bceecbbe66b0ac95e46d00007eeb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#pragma once

#include <memory>
#include <vector>
#include "tach_sensor.hpp"
#include "trust_group.hpp"
#include "types.hpp"

namespace phosphor
{
namespace fan
{
namespace trust
{

/**
 * @class Manager
 *
 * The sensor trust manager class.  It can be asked if a tach sensor's
 * reading can be trusted or not, based on the trust groups the sensor
 * is in.
 *
 * When it finds a group's trust status changing, it will either stop or
 * start the tach error timers for the group's sensors accordingly.
 *
 * See the trust::Group documentation for more details on sensor trust.
 */
class Manager
{
    public:

        Manager() = delete;
        Manager(const Manager&) = delete;
        Manager& operator=(const Manager&) = delete;
        Manager(Manager&&) = default;
        Manager& operator=(Manager&&) = default;
        ~Manager() = default;

        /**
         * Constructor
         *
         * @param[in] functions - trust group creation function vector
         */
        explicit Manager(const std::vector<monitor::CreateGroupFunction>& functions)
        {
            for (auto& create : functions)
            {
                groups.emplace_back(create());
            }
        }

        /**
         * Says if trust groups have been created and
         * need to be checked.
         *
         * @return bool - If there are any trust groups
         */
        inline bool active() const
        {
            return !groups.empty();
        }

        /**
         * Checks if a sensor value can be trusted
         *
         * Checks if the sensor is trusted in each group
         * it belongs to.  Only considered trusted if it is
         * trusted in all groups it belongs to.
         *
         * While checking group trust, the code will also check
         * if the trust status has just changed.  If the status
         * just changed to false, it will stop the tach error
         * timers for that group so these untrusted sensors won't
         * cause errors.  If changed to true, it will start those timers
         * back up again.
         *
         * Note this means groups should be designed such that
         * in the same call to this function a sensor shouldn't
         * make one group change to trusted and another to untrusted.
         *
         * @param[in] sensor - the sensor to check
         *
         * @return bool - if sensor is trusted in all groups or not
         */
        bool checkTrust(
                const monitor::TachSensor& sensor)
        {
            auto trusted = true;

            for (auto& group : groups)
            {
                if (group->inGroup(sensor))
                {
                    bool trust, changed;
                    std::tie(trust, changed) = group->checkTrust(sensor);

                    if (!trust)
                    {
                        trusted = false;

                        if (changed)
                        {
                            group->stopTimers();
                        }
                    }
                    else
                    {
                        if (changed)
                        {
                            group->startTimers();
                        }
                    }
                }
            }

            return trusted;
        }

        /**
         * Registers a sensor with any trust groups that are interested
         *
         * @param[in] sensor - the sensor to register
         */
        void registerSensor(
                std::unique_ptr<monitor::TachSensor>& sensor)
        {
            std::for_each(
                    groups.begin(),
                    groups.end(),
                    [&sensor](auto& group)
                    {
                        group->registerSensor(sensor);
                    });
        }

    private:

        /**
         * The list of sensor trust groups
         */
        std::vector<std::unique_ptr<Group>> groups;
};

}
}
}
OpenPOWER on IntegriCloud