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