1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  * Copyright (C) 2021-2022 YADRO.
4  */
5 
6 #pragma once
7 
8 #include <boost/asio/io_context.hpp>
9 #include <boost/asio/steady_timer.hpp>
10 #include <boost/container/flat_map.hpp>
11 #include <nlohmann/json.hpp>
12 #include <sdbusplus/asio/object_server.hpp>
13 
14 #include <filesystem>
15 #include <string_view>
16 
17 namespace power_control
18 {
19 
20 /**
21  * @brief Persistent State Manager
22  *
23  * This manager supposed to store runtime parameters that supposed to be
24  * persistent over BMC reboot. It provides simple Get/Set interface and handle
25  * default values, hardcoded in getDefault() method.
26  * @note: currently only string parameters supported
27  */
28 using dbusPropertiesList =
29     boost::container::flat_map<std::string,
30                                std::variant<std::string, uint64_t>>;
31 /**
32  * @brief The class contains functions to invoke power restore policy.
33  *
34  * This class only exists to unite all PowerRestore-related code. It supposed
35  * to run only once on application startup.
36  */
37 class PowerRestoreController
38 {
39   public:
40     PowerRestoreController(boost::asio::io_context& io) :
41         policyInvoked(false), powerRestoreDelay(-1), powerRestoreTimer(io),
42         timerFired(false)
43     {}
44     /**
45      * @brief Power Restore entry point.
46      *
47      * Call this to start Power Restore algorithm.
48      */
49     void run();
50     /**
51      * @brief Initialize configuration parameters.
52      *
53      * Parse list of properties, received from dbus, to set Power Restore
54      * algorithm configuration.
55      * @param props - map of property names and values
56      */
57     void setProperties(const dbusPropertiesList& props);
58 
59   private:
60     bool policyInvoked;
61     std::string powerRestorePolicy;
62     int powerRestoreDelay;
63     std::list<sdbusplus::bus::match_t> matches;
64     boost::asio::steady_timer powerRestoreTimer;
65     bool timerFired;
66 #ifdef USE_ACBOOT
67     std::string acBoot;
68 #endif // USE_ACBOOT
69 
70     /**
71      * @brief Check if all required algorithms parameters are set
72      *
73      * Call this after set any of Power Restore algorithm parameters. Once all
74      * parameters are set this will run invoke() function.
75      */
76     void invokeIfReady();
77     /**
78      * @brief Actually perform power restore actions.
79      *
80      * Take Power Restore actions according to Policy and other parameters.
81      */
82     void invoke();
83     /**
84      * @brief Check if power was dropped.
85      *
86      * Read last saved power state to determine if host power was enabled before
87      * last BMC reboot.
88      */
89     bool wasPowerDropped();
90 };
91 
92 class PersistentState
93 {
94   public:
95     /**
96      * List of all supported parameters
97      */
98     enum class Params
99     {
100         PowerState,
101     };
102 
103     /**
104      * @brief Persistent storage initialization
105      *
106      * Class constructor automatically load last state from JSON file
107      */
108     PersistentState();
109     /**
110      * @brief Persistent storage cleanup
111      *
112      * Class destructor automatically save state to JSON file
113      */
114     ~PersistentState();
115     /**
116      * @brief Get parameter value from the storage
117      *
118      * Get the parameter from cached storage. Default value returned, if
119      * parameter was not set before.
120      * @param parameter - parameter to get
121      * @return parameter value
122      */
123     const std::string get(Params parameter);
124     /**
125      * @brief Store parameter value
126      *
127      * Set the parameter value in cached storage and dump it to disk.
128      * @param parameter - parameter to set
129      * @param value - parameter value to assign
130      */
131     void set(Params parameter, const std::string& value);
132 
133   private:
134     nlohmann::json stateData;
135     const std::filesystem::path powerControlDir = "/var/lib/power-control";
136     const std::string_view stateFile = "state.json";
137     const int indentationSize = 2;
138 
139     /**
140      * @brief Covert parameter ID to name
141      *
142      * Get the name corresponding to the given parameter.
143      * String name only used by the manager internal to generate human-readable
144      * JSON.
145      * @param parameter - parameter to convert
146      * @return parameter name
147      */
148     const std::string getName(const Params parameter);
149     /**
150      * @brief Get default parameter value
151      *
152      * Get the default value, associated with given parameter.
153      * @param parameter - parameter to get
154      * @return parameter default value
155      */
156     const std::string getDefault(const Params parameter);
157     /**
158      * @brief Save cache to file on disk
159      */
160     void saveState();
161 };
162 
163 } // namespace power_control
164