blob: bfd1b372f8660916c14bda4376f99dbd06ca1c41 [file] [log] [blame]
Shawn McCarneyc69a2752019-10-30 17:37:30 -05001/**
2 * Copyright © 2019 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
Shawn McCarneyc69a2752019-10-30 17:37:30 -050018#include "id_map.hpp"
Bob Kingb1ab1cf2020-05-18 18:26:26 +080019#include "pmbus_utils.hpp"
Bob King73eacee2020-10-23 13:58:02 +080020#include "services.hpp"
Shawn McCarneyc69a2752019-10-30 17:37:30 -050021
22#include <cstddef> // for size_t
Shawn McCarney0fd07d72020-03-06 17:16:24 -060023#include <optional>
Shawn McCarneyc69a2752019-10-30 17:37:30 -050024#include <stdexcept>
25#include <string>
Bob Kingb1ab1cf2020-05-18 18:26:26 +080026#include <vector>
Shawn McCarneyc69a2752019-10-30 17:37:30 -050027
Shawn McCarneyea7385b2019-11-07 12:19:32 -060028namespace phosphor::power::regulators
Shawn McCarneyc69a2752019-10-30 17:37:30 -050029{
30
Shawn McCarney494ef032019-11-07 15:56:50 -060031// Forward declarations to avoid circular dependencies
32class Device;
33class Rule;
34
Shawn McCarneyc69a2752019-10-30 17:37:30 -050035/**
36 * @class ActionEnvironment
37 *
38 * The current environment when executing actions.
39 *
40 * The ActionEnvironment contains the following information:
41 * - current device ID
42 * - current volts value (if any)
43 * - mapping from device and rule IDs to the corresponding objects
44 * - rule call stack depth (to detect infinite recursion)
Bob Kingb1ab1cf2020-05-18 18:26:26 +080045 * - sensor readings
Shawn McCarneyc69a2752019-10-30 17:37:30 -050046 */
47class ActionEnvironment
48{
49 public:
50 // Specify which compiler-generated methods we want
51 ActionEnvironment() = delete;
52 ActionEnvironment(const ActionEnvironment&) = delete;
53 ActionEnvironment(ActionEnvironment&&) = delete;
54 ActionEnvironment& operator=(const ActionEnvironment&) = delete;
55 ActionEnvironment& operator=(ActionEnvironment&&) = delete;
56 ~ActionEnvironment() = default;
57
58 /**
59 * Maximum rule call stack depth. Used to detect infinite recursion.
60 */
61 static constexpr size_t maxRuleDepth{30};
62
63 /**
64 * Constructor.
65 *
66 * @param idMap mapping from IDs to the associated Device/Rule objects
67 * @param deviceID current device ID
Bob King73eacee2020-10-23 13:58:02 +080068 * @param services system services like error logging and the journal
Shawn McCarneyc69a2752019-10-30 17:37:30 -050069 */
Bob King73eacee2020-10-23 13:58:02 +080070 explicit ActionEnvironment(const IDMap& idMap, const std::string& deviceID,
71 Services& services) :
Shawn McCarneyc69a2752019-10-30 17:37:30 -050072 idMap{idMap},
Bob King73eacee2020-10-23 13:58:02 +080073 deviceID{deviceID}, services{services}
Shawn McCarneyc69a2752019-10-30 17:37:30 -050074 {
75 }
76
77 /**
Bob Kingb1ab1cf2020-05-18 18:26:26 +080078 * Adds the specified sensor reading to this action environment.
79 *
80 * @param reading sensor reading from a regulator rail
81 */
82 void addSensorReading(const pmbus_utils::SensorReading& reading)
83 {
84 sensorReadings.emplace_back(reading);
85 }
86
87 /**
Shawn McCarneyc69a2752019-10-30 17:37:30 -050088 * Decrements the rule call stack depth by one.
89 *
90 * Should be used when a call to a rule returns. Does nothing if depth is
91 * already 0.
92 */
93 void decrementRuleDepth()
94 {
95 if (ruleDepth > 0)
96 {
97 --ruleDepth;
98 }
99 }
100
101 /**
102 * Returns the device with the current device ID.
103 *
104 * Throws invalid_argument if no device is found with current ID.
105 *
106 * @return device with current device ID
107 */
108 Device& getDevice() const
109 {
110 return idMap.getDevice(deviceID);
111 }
112
113 /**
114 * Returns the current device ID.
115 *
116 * @return current device ID
117 */
118 const std::string& getDeviceID() const
119 {
120 return deviceID;
121 }
122
123 /**
124 * Returns the rule with the specified ID.
125 *
126 * Throws invalid_argument if no rule is found with specified ID.
127 *
128 * @param id rule ID
129 * @return rule with specified ID
130 */
131 Rule& getRule(const std::string& id) const
132 {
133 return idMap.getRule(id);
134 }
135
136 /**
137 * Returns the current rule call stack depth.
138 *
139 * The depth is 0 if no rules have been called.
140 *
141 * @return rule call stack depth
142 */
143 size_t getRuleDepth() const
144 {
145 return ruleDepth;
146 }
147
148 /**
Bob Kingb1ab1cf2020-05-18 18:26:26 +0800149 * Returns the sensor readings stored in this action environment.
150 *
151 * @return sensor readings
152 */
153 const std::vector<pmbus_utils::SensorReading>& getSensorReadings() const
154 {
155 return sensorReadings;
156 }
157
158 /**
Bob King73eacee2020-10-23 13:58:02 +0800159 * Returns the services in this action environment.
160 *
161 * @return system services
162 */
163 Services& getServices() const
164 {
165 return services;
166 }
167
168 /**
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600169 * Returns the current volts value, if set.
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500170 *
171 * @return current volts value
172 */
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600173 std::optional<double> getVolts() const
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500174 {
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500175 return volts;
176 }
177
178 /**
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500179 * Increments the rule call stack depth by one.
180 *
181 * Should be used when a rule is called.
182 *
183 * Throws runtime_error if the new depth exceeds maxRuleDepth. This
184 * indicates that infinite recursion has probably occurred (rule A -> rule B
185 * -> rule A).
Shawn McCarney2134ca62019-11-11 13:06:18 -0600186 *
187 * @param ruleID ID of the rule that is being called
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500188 */
Shawn McCarney2134ca62019-11-11 13:06:18 -0600189 void incrementRuleDepth(const std::string& ruleID)
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500190 {
191 if (ruleDepth >= maxRuleDepth)
192 {
Shawn McCarney2134ca62019-11-11 13:06:18 -0600193 throw std::runtime_error("Maximum rule depth exceeded by rule " +
194 ruleID + '.');
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500195 }
196 ++ruleDepth;
197 }
198
199 /**
200 * Sets the current device ID.
201 *
202 * @param id device ID
203 */
204 void setDeviceID(const std::string& id)
205 {
206 deviceID = id;
207 }
208
209 /**
210 * Sets the current volts value.
211 *
212 * @param volts new volts value.
213 */
214 void setVolts(double volts)
215 {
216 this->volts = volts;
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500217 }
218
219 private:
220 /**
221 * Mapping from string IDs to the associated Device and Rule objects.
222 */
Shawn McCarney494ef032019-11-07 15:56:50 -0600223 const IDMap& idMap;
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500224
225 /**
226 * Current device ID.
227 */
228 std::string deviceID{};
229
230 /**
Bob King73eacee2020-10-23 13:58:02 +0800231 * System services like error logging and the journal.
232 */
233 Services& services;
234
235 /**
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500236 * Current volts value (if set).
237 */
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600238 std::optional<double> volts{};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500239
240 /**
241 * Rule call stack depth.
242 */
243 size_t ruleDepth{0};
Bob Kingb1ab1cf2020-05-18 18:26:26 +0800244
245 /**
246 * Sensor readings for a single regulator rail.
247 */
248 std::vector<pmbus_utils::SensorReading> sensorReadings{};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500249};
250
Shawn McCarneyea7385b2019-11-07 12:19:32 -0600251} // namespace phosphor::power::regulators