xref: /openbmc/phosphor-power/phosphor-regulators/src/actions/action_environment.hpp (revision f54021972b91be5058b50e9046bb0dd5a3b22a80)
1c69a2750SShawn McCarney /**
2c69a2750SShawn McCarney  * Copyright © 2019 IBM Corporation
3c69a2750SShawn McCarney  *
4c69a2750SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
5c69a2750SShawn McCarney  * you may not use this file except in compliance with the License.
6c69a2750SShawn McCarney  * You may obtain a copy of the License at
7c69a2750SShawn McCarney  *
8c69a2750SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
9c69a2750SShawn McCarney  *
10c69a2750SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
11c69a2750SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
12c69a2750SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c69a2750SShawn McCarney  * See the License for the specific language governing permissions and
14c69a2750SShawn McCarney  * limitations under the License.
15c69a2750SShawn McCarney  */
16c69a2750SShawn McCarney #pragma once
17c69a2750SShawn McCarney 
18c69a2750SShawn McCarney #include "id_map.hpp"
19421128efSShawn McCarney #include "phase_fault.hpp"
2073eaceebSBob King #include "services.hpp"
21c69a2750SShawn McCarney 
22c69a2750SShawn McCarney #include <cstddef> // for size_t
23421128efSShawn McCarney #include <map>
240fd07d7dSShawn McCarney #include <optional>
25421128efSShawn McCarney #include <set>
26c69a2750SShawn McCarney #include <stdexcept>
27c69a2750SShawn McCarney #include <string>
28c69a2750SShawn McCarney 
29ea7385b8SShawn McCarney namespace phosphor::power::regulators
30c69a2750SShawn McCarney {
31c69a2750SShawn McCarney 
32494ef03aSShawn McCarney // Forward declarations to avoid circular dependencies
33494ef03aSShawn McCarney class Device;
34494ef03aSShawn McCarney class Rule;
35494ef03aSShawn McCarney 
36c69a2750SShawn McCarney /**
37c69a2750SShawn McCarney  * @class ActionEnvironment
38c69a2750SShawn McCarney  *
39c69a2750SShawn McCarney  * The current environment when executing actions.
40c69a2750SShawn McCarney  *
41c69a2750SShawn McCarney  * The ActionEnvironment contains the following information:
42c69a2750SShawn McCarney  *   - current device ID
43c69a2750SShawn McCarney  *   - current volts value (if any)
44c69a2750SShawn McCarney  *   - mapping from device and rule IDs to the corresponding objects
45c69a2750SShawn McCarney  *   - rule call stack depth (to detect infinite recursion)
46421128efSShawn McCarney  *   - reference to system services
47421128efSShawn McCarney  *   - faults detected by actions (if any)
48421128efSShawn McCarney  *   - additional error data captured by actions (if any)
49c69a2750SShawn McCarney  */
50c69a2750SShawn McCarney class ActionEnvironment
51c69a2750SShawn McCarney {
52c69a2750SShawn McCarney   public:
53c69a2750SShawn McCarney     // Specify which compiler-generated methods we want
54c69a2750SShawn McCarney     ActionEnvironment() = delete;
55c69a2750SShawn McCarney     ActionEnvironment(const ActionEnvironment&) = delete;
56c69a2750SShawn McCarney     ActionEnvironment(ActionEnvironment&&) = delete;
57c69a2750SShawn McCarney     ActionEnvironment& operator=(const ActionEnvironment&) = delete;
58c69a2750SShawn McCarney     ActionEnvironment& operator=(ActionEnvironment&&) = delete;
59c69a2750SShawn McCarney     ~ActionEnvironment() = default;
60c69a2750SShawn McCarney 
61c69a2750SShawn McCarney     /**
62c69a2750SShawn McCarney      * Maximum rule call stack depth.  Used to detect infinite recursion.
63c69a2750SShawn McCarney      */
64c69a2750SShawn McCarney     static constexpr size_t maxRuleDepth{30};
65c69a2750SShawn McCarney 
66c69a2750SShawn McCarney     /**
67c69a2750SShawn McCarney      * Constructor.
68c69a2750SShawn McCarney      *
69c69a2750SShawn McCarney      * @param idMap mapping from IDs to the associated Device/Rule objects
70c69a2750SShawn McCarney      * @param deviceID current device ID
7173eaceebSBob King      * @param services system services like error logging and the journal
72c69a2750SShawn McCarney      */
ActionEnvironment(const IDMap & idMap,const std::string & deviceID,Services & services)7373eaceebSBob King     explicit ActionEnvironment(const IDMap& idMap, const std::string& deviceID,
7473eaceebSBob King                                Services& services) :
75*f5402197SPatrick Williams         idMap{idMap}, deviceID{deviceID}, services{services}
760c9a33d6SAdriana Kobylak     {}
77c69a2750SShawn McCarney 
78c69a2750SShawn McCarney     /**
79421128efSShawn McCarney      * Adds the specified key/value pair to the map of additional error data
80421128efSShawn McCarney      * that has been captured.
81421128efSShawn McCarney      *
82421128efSShawn McCarney      * This data provides more information about an error and will be stored in
83421128efSShawn McCarney      * the error log.
84421128efSShawn McCarney      *
85421128efSShawn McCarney      * @param key key name
86421128efSShawn McCarney      * @param value value expressed as a string
87421128efSShawn McCarney      */
addAdditionalErrorData(const std::string & key,const std::string & value)88421128efSShawn McCarney     void addAdditionalErrorData(const std::string& key,
89421128efSShawn McCarney                                 const std::string& value)
90421128efSShawn McCarney     {
91421128efSShawn McCarney         additionalErrorData.emplace(key, value);
92421128efSShawn McCarney     }
93421128efSShawn McCarney 
94421128efSShawn McCarney     /**
95421128efSShawn McCarney      * Adds the specified phase fault to the set of faults that have been
96421128efSShawn McCarney      * detected.
97421128efSShawn McCarney      *
98421128efSShawn McCarney      * @param type phase fault type
99421128efSShawn McCarney      */
addPhaseFault(PhaseFaultType type)100421128efSShawn McCarney     void addPhaseFault(PhaseFaultType type)
101421128efSShawn McCarney     {
102421128efSShawn McCarney         phaseFaults.emplace(type);
103421128efSShawn McCarney     }
104421128efSShawn McCarney 
105421128efSShawn McCarney     /**
106c69a2750SShawn McCarney      * Decrements the rule call stack depth by one.
107c69a2750SShawn McCarney      *
108c69a2750SShawn McCarney      * Should be used when a call to a rule returns.  Does nothing if depth is
109c69a2750SShawn McCarney      * already 0.
110c69a2750SShawn McCarney      */
decrementRuleDepth()111c69a2750SShawn McCarney     void decrementRuleDepth()
112c69a2750SShawn McCarney     {
113c69a2750SShawn McCarney         if (ruleDepth > 0)
114c69a2750SShawn McCarney         {
115c69a2750SShawn McCarney             --ruleDepth;
116c69a2750SShawn McCarney         }
117c69a2750SShawn McCarney     }
118c69a2750SShawn McCarney 
119c69a2750SShawn McCarney     /**
120421128efSShawn McCarney      * Returns the additional error data that has been captured (if any).
121421128efSShawn McCarney      *
122421128efSShawn McCarney      * @return additional error data
123421128efSShawn McCarney      */
getAdditionalErrorData() const124421128efSShawn McCarney     const std::map<std::string, std::string>& getAdditionalErrorData() const
125421128efSShawn McCarney     {
126421128efSShawn McCarney         return additionalErrorData;
127421128efSShawn McCarney     }
128421128efSShawn McCarney 
129421128efSShawn McCarney     /**
130c69a2750SShawn McCarney      * Returns the device with the current device ID.
131c69a2750SShawn McCarney      *
132c69a2750SShawn McCarney      * Throws invalid_argument if no device is found with current ID.
133c69a2750SShawn McCarney      *
134c69a2750SShawn McCarney      * @return device with current device ID
135c69a2750SShawn McCarney      */
getDevice() const136c69a2750SShawn McCarney     Device& getDevice() const
137c69a2750SShawn McCarney     {
138c69a2750SShawn McCarney         return idMap.getDevice(deviceID);
139c69a2750SShawn McCarney     }
140c69a2750SShawn McCarney 
141c69a2750SShawn McCarney     /**
142c69a2750SShawn McCarney      * Returns the current device ID.
143c69a2750SShawn McCarney      *
144c69a2750SShawn McCarney      * @return current device ID
145c69a2750SShawn McCarney      */
getDeviceID() const146c69a2750SShawn McCarney     const std::string& getDeviceID() const
147c69a2750SShawn McCarney     {
148c69a2750SShawn McCarney         return deviceID;
149c69a2750SShawn McCarney     }
150c69a2750SShawn McCarney 
151c69a2750SShawn McCarney     /**
152421128efSShawn McCarney      * Returns the set of phase faults that have been detected (if any).
153421128efSShawn McCarney      *
154421128efSShawn McCarney      * @return phase faults detected
155421128efSShawn McCarney      */
getPhaseFaults() const156421128efSShawn McCarney     const std::set<PhaseFaultType>& getPhaseFaults() const
157421128efSShawn McCarney     {
158421128efSShawn McCarney         return phaseFaults;
159421128efSShawn McCarney     }
160421128efSShawn McCarney 
161421128efSShawn McCarney     /**
162c69a2750SShawn McCarney      * Returns the rule with the specified ID.
163c69a2750SShawn McCarney      *
164c69a2750SShawn McCarney      * Throws invalid_argument if no rule is found with specified ID.
165c69a2750SShawn McCarney      *
166c69a2750SShawn McCarney      * @param id rule ID
167c69a2750SShawn McCarney      * @return rule with specified ID
168c69a2750SShawn McCarney      */
getRule(const std::string & id) const169c69a2750SShawn McCarney     Rule& getRule(const std::string& id) const
170c69a2750SShawn McCarney     {
171c69a2750SShawn McCarney         return idMap.getRule(id);
172c69a2750SShawn McCarney     }
173c69a2750SShawn McCarney 
174c69a2750SShawn McCarney     /**
175c69a2750SShawn McCarney      * Returns the current rule call stack depth.
176c69a2750SShawn McCarney      *
177c69a2750SShawn McCarney      * The depth is 0 if no rules have been called.
178c69a2750SShawn McCarney      *
179c69a2750SShawn McCarney      * @return rule call stack depth
180c69a2750SShawn McCarney      */
getRuleDepth() const181c69a2750SShawn McCarney     size_t getRuleDepth() const
182c69a2750SShawn McCarney     {
183c69a2750SShawn McCarney         return ruleDepth;
184c69a2750SShawn McCarney     }
185c69a2750SShawn McCarney 
186c69a2750SShawn McCarney     /**
18773eaceebSBob King      * Returns the services in this action environment.
18873eaceebSBob King      *
18973eaceebSBob King      * @return system services
19073eaceebSBob King      */
getServices() const19173eaceebSBob King     Services& getServices() const
19273eaceebSBob King     {
19373eaceebSBob King         return services;
19473eaceebSBob King     }
19573eaceebSBob King 
19673eaceebSBob King     /**
1970fd07d7dSShawn McCarney      * Returns the current volts value, if set.
198c69a2750SShawn McCarney      *
199c69a2750SShawn McCarney      * @return current volts value
200c69a2750SShawn McCarney      */
getVolts() const2010fd07d7dSShawn McCarney     std::optional<double> getVolts() const
202c69a2750SShawn McCarney     {
203c69a2750SShawn McCarney         return volts;
204c69a2750SShawn McCarney     }
205c69a2750SShawn McCarney 
206c69a2750SShawn McCarney     /**
207c69a2750SShawn McCarney      * Increments the rule call stack depth by one.
208c69a2750SShawn McCarney      *
209c69a2750SShawn McCarney      * Should be used when a rule is called.
210c69a2750SShawn McCarney      *
211c69a2750SShawn McCarney      * Throws runtime_error if the new depth exceeds maxRuleDepth.  This
212c69a2750SShawn McCarney      * indicates that infinite recursion has probably occurred (rule A -> rule B
213c69a2750SShawn McCarney      * -> rule A).
2142134ca66SShawn McCarney      *
2152134ca66SShawn McCarney      * @param ruleID ID of the rule that is being called
216c69a2750SShawn McCarney      */
incrementRuleDepth(const std::string & ruleID)2172134ca66SShawn McCarney     void incrementRuleDepth(const std::string& ruleID)
218c69a2750SShawn McCarney     {
219c69a2750SShawn McCarney         if (ruleDepth >= maxRuleDepth)
220c69a2750SShawn McCarney         {
221*f5402197SPatrick Williams             throw std::runtime_error(
222*f5402197SPatrick Williams                 "Maximum rule depth exceeded by rule " + ruleID + '.');
223c69a2750SShawn McCarney         }
224c69a2750SShawn McCarney         ++ruleDepth;
225c69a2750SShawn McCarney     }
226c69a2750SShawn McCarney 
227c69a2750SShawn McCarney     /**
228c69a2750SShawn McCarney      * Sets the current device ID.
229c69a2750SShawn McCarney      *
230c69a2750SShawn McCarney      * @param id device ID
231c69a2750SShawn McCarney      */
setDeviceID(const std::string & id)232c69a2750SShawn McCarney     void setDeviceID(const std::string& id)
233c69a2750SShawn McCarney     {
234c69a2750SShawn McCarney         deviceID = id;
235c69a2750SShawn McCarney     }
236c69a2750SShawn McCarney 
237c69a2750SShawn McCarney     /**
238c69a2750SShawn McCarney      * Sets the current volts value.
239c69a2750SShawn McCarney      *
240c69a2750SShawn McCarney      * @param volts new volts value.
241c69a2750SShawn McCarney      */
setVolts(double volts)242c69a2750SShawn McCarney     void setVolts(double volts)
243c69a2750SShawn McCarney     {
244c69a2750SShawn McCarney         this->volts = volts;
245c69a2750SShawn McCarney     }
246c69a2750SShawn McCarney 
247c69a2750SShawn McCarney   private:
248c69a2750SShawn McCarney     /**
249c69a2750SShawn McCarney      * Mapping from string IDs to the associated Device and Rule objects.
250c69a2750SShawn McCarney      */
251494ef03aSShawn McCarney     const IDMap& idMap;
252c69a2750SShawn McCarney 
253c69a2750SShawn McCarney     /**
254c69a2750SShawn McCarney      * Current device ID.
255c69a2750SShawn McCarney      */
256c69a2750SShawn McCarney     std::string deviceID{};
257c69a2750SShawn McCarney 
258c69a2750SShawn McCarney     /**
25973eaceebSBob King      * System services like error logging and the journal.
26073eaceebSBob King      */
26173eaceebSBob King     Services& services;
26273eaceebSBob King 
26373eaceebSBob King     /**
264c69a2750SShawn McCarney      * Current volts value (if set).
265c69a2750SShawn McCarney      */
2660fd07d7dSShawn McCarney     std::optional<double> volts{};
267c69a2750SShawn McCarney 
268c69a2750SShawn McCarney     /**
269c69a2750SShawn McCarney      * Rule call stack depth.
270c69a2750SShawn McCarney      */
271c69a2750SShawn McCarney     size_t ruleDepth{0};
272421128efSShawn McCarney 
273421128efSShawn McCarney     /**
274421128efSShawn McCarney      * Redundant phase faults that have been detected.
275421128efSShawn McCarney      */
276421128efSShawn McCarney     std::set<PhaseFaultType> phaseFaults{};
277421128efSShawn McCarney 
278421128efSShawn McCarney     /**
279421128efSShawn McCarney      * Additional error data that has been captured.
280421128efSShawn McCarney      */
281421128efSShawn McCarney     std::map<std::string, std::string> additionalErrorData{};
282c69a2750SShawn McCarney };
283c69a2750SShawn McCarney 
284ea7385b8SShawn McCarney } // namespace phosphor::power::regulators
285