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