1 /**
2  * Copyright © 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "power_state.hpp"
19 
20 #include <sdbusplus/bus.hpp>
21 #include <sdbusplus/bus/match.hpp>
22 #include <sdeventplus/event.hpp>
23 
24 namespace sensor::monitor
25 {
26 
27 using InterfaceName = std::string;
28 using PropertyName = std::string;
29 using ErrorName = std::string;
30 using ObjectPath = std::string;
31 using InterfaceKey = std::tuple<ObjectPath, InterfaceName>;
32 
33 /**
34  * @class ThresholdAlarmLogger
35  *
36  * This class watches the threshold interfaces
37  *    openbmc_project.Sensor.Threshold.Warning
38  *    openbmc_project.Sensor.Threshold.Critical
39  *    openbmc_project.Sensor.Threshold.PerformanceLoss
40  *
41  * and creates event logs when their high and low alarm
42  * properties set and clear.  The error names of the
43  * event logs are based on the sensor type and look like:
44  *
45  * xyz.openbmc_project.Sensor.Threshold.Error.TemperatureWarningHigh
46  * xyz.openbmc_project.Sensor.Threshold.Error.TemperatureWarningHighClear
47  *
48  * Event logs are only created when the power is on.
49  */
50 class ThresholdAlarmLogger
51 {
52   public:
53     ThresholdAlarmLogger() = delete;
54     ~ThresholdAlarmLogger() = default;
55     ThresholdAlarmLogger(const ThresholdAlarmLogger&) = default;
56     ThresholdAlarmLogger& operator=(const ThresholdAlarmLogger&) = default;
57     ThresholdAlarmLogger(ThresholdAlarmLogger&&) = default;
58     ThresholdAlarmLogger& operator=(ThresholdAlarmLogger&&) = default;
59 
60     /**
61      * @brief Constructor
62      *
63      * Looks for existing active threshold alarms.
64      *
65      * @param[in] bus - The sdbusplus bus object
66      * @param[in] event - The sdeventplus event object
67      * @param[in] powerState - The PowerState object
68      */
69     ThresholdAlarmLogger(sdbusplus::bus_t& bus, sdeventplus::Event& event,
70                          std::shared_ptr<phosphor::fan::PowerState> powerState);
71 
72   private:
73     /**
74      * @brief The propertiesChanged handler for all of the thresholds
75      *        interfaces.
76      *
77      * Creates event logs for high/low alarm sets and clears.
78      *
79      * @param[in] msg - The signal message payload.
80      */
81     void propertiesChanged(sdbusplus::message_t& msg);
82 
83     /**
84      * @brief The interfacesRemoved removed handler for the threshold
85      *        interfaces.
86      *
87      * Removes that threshold from the alarms map
88      *
89      * @param[in] msg - The signal message payload.
90      */
91     void interfacesRemoved(sdbusplus::message_t& msg);
92 
93     /**
94      * @brief Checks for active alarms on the path and threshold interface
95      *        passed in and creates event logs if necessary.
96      *
97      * @param[in] interface - The threshold interface
98      * @param[in] sensorPath - The sensor D-Bus path
99      * @param[in] service - The D-Bus service that owns the interface
100      */
101     void checkThresholds(const std::string& interface,
102                          const std::string& sensorPath,
103                          const std::string& service);
104 
105     /**
106      * @brief Checks for all active alarms on all existing
107      *        threshold interfaces and creates event logs
108      *        if necessary.
109      */
110     void checkThresholds();
111 
112     /**
113      * @brief Creates an event log for the alarm set/clear
114      *
115      * @param[in] sensorPath - The sensor object path
116      * @param[in] interface - The threshold interface
117      * @param[in] alarmProperty - The alarm property name
118      * @param[in] alarmValue - The alarm value
119      */
120     void createEventLog(const std::string& sensorPath,
121                         const std::string& interface,
122                         const std::string& alarmProperty, bool alarmValue);
123 
124     /**
125      * @brief Returns the type of the sensor using the path segment
126      *        that precedes the sensor name.
127      *
128      * /xyz/openbmc_project/sensors/voltage/vout -> type == voltage
129      *
130      * @param[in] sensorPath - The sensor object path name
131      *
132      * @return std::string The type segment
133      */
134     std::string getSensorType(std::string sensorPath);
135 
136     /**
137      * @brief Allows for skipping event logs based on the sensor type.
138      *
139      * Specifically for the 'utilization' type because its provider
140      * doesn't support configurable thresholds yet.
141      *
142      * @param[in] type - The sensor type, like 'temperature'.
143      * @return bool - If it can be skipped or not.
144      */
145     bool skipSensorType(const std::string& type);
146 
147     /**
148      * @brief Returns the inventory path to use for a FRU callout
149      *        for the alarm exceeded errors.
150      *
151      * It finds the path by looking for 'inventory' or 'chassis'
152      * association objects on the sensor that point to a FRU.
153      *
154      * @param[in] std::string - The sensor object path
155      * @return std::string - The inventory path for the FRU callout.
156      *                       May be empty if none found.
157      */
158     std::string getCallout(const std::string& sensorPath);
159 
160     /**
161      * @brief The power state changed handler.
162      *
163      * Checks alarms when power is turned on.
164      *
165      * @param[in] powerStateOn - If the power is now on or off.
166      */
167     void powerStateChanged(bool powerStateOn);
168 
169     /**
170      * @brief The sdbusplus bus object
171      */
172     sdbusplus::bus_t& bus;
173 
174     /**
175      * @brief The sdeventplus Event object
176      */
177     sdeventplus::Event& event;
178 
179     /**
180      * @brief The PowerState object to track power state changes.
181      */
182     std::shared_ptr<phosphor::fan::PowerState> _powerState;
183 
184     /**
185      * @brief The Warning interface match object
186      */
187     sdbusplus::bus::match_t warningMatch;
188 
189     /**
190      * @brief The Critical interface match object
191      */
192     sdbusplus::bus::match_t criticalMatch;
193 
194     /**
195      * @brief The PerformanceLoss interface match object
196      */
197     sdbusplus::bus::match_t perfLossMatch;
198 
199     /**
200      * @brief The InterfacesRemoved match object
201      */
202     sdbusplus::bus::match_t ifacesRemovedMatch;
203 
204     /**
205      * @brief The current alarm values
206      */
207     std::map<InterfaceKey, std::map<PropertyName, bool>> alarms;
208 };
209 
210 } // namespace sensor::monitor
211