blob: a1fcb0467e9e898a6f6f96f3f9cd37e1ff0e91ee [file] [log] [blame]
Andrew Geisslera90a31a2016-12-13 16:16:28 -06001#pragma once
2
Patrick Williams8f8ba392017-05-05 15:47:39 -05003#include <functional>
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -05004#include <experimental/filesystem>
5#include <cereal/cereal.hpp>
Andrew Geisslera90a31a2016-12-13 16:16:28 -06006#include <sdbusplus/bus.hpp>
7#include "xyz/openbmc_project/State/Chassis/server.hpp"
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -05008#include "xyz/openbmc_project/State/PowerOnHours/server.hpp"
9#include "config.h"
10#include "timer.hpp"
Andrew Geisslera90a31a2016-12-13 16:16:28 -060011
12namespace phosphor
13{
14namespace state
15{
16namespace manager
17{
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050018namespace POH
19{
20
21using namespace std::chrono_literals;
22constexpr auto hour = 3600s; // seconds Per Hour
23
24} // namespace POH
Andrew Geisslera90a31a2016-12-13 16:16:28 -060025
Patrick Williams8f8ba392017-05-05 15:47:39 -050026using ChassisInherit = sdbusplus::server::object::object<
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050027 sdbusplus::xyz::openbmc_project::State::server::Chassis,
28 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
Patrick Williams8f8ba392017-05-05 15:47:39 -050029namespace sdbusRule = sdbusplus::bus::match::rules;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050030namespace fs = std::experimental::filesystem;
Patrick Williams8f8ba392017-05-05 15:47:39 -050031
Andrew Geisslera90a31a2016-12-13 16:16:28 -060032/** @class Chassis
33 * @brief OpenBMC chassis state management implementation.
34 * @details A concrete implementation for xyz.openbmc_project.State.Chassis
35 * DBus API.
36 */
Patrick Williams8f8ba392017-05-05 15:47:39 -050037class Chassis : public ChassisInherit
Andrew Geisslera90a31a2016-12-13 16:16:28 -060038{
Andrew Geissler58a18012018-01-19 19:36:05 -080039 public:
40 /** @brief Constructs Chassis State Manager
41 *
42 * @note This constructor passes 'true' to the base class in order to
43 * defer dbus object registration until we can run
44 * determineInitialState() and set our properties
45 *
46 * @param[in] bus - The Dbus bus object
47 * @param[in] instance - The instance of this object
48 * @param[in] objPath - The Dbus object path
49 */
50 Chassis(sdbusplus::bus::bus& bus, const char* busName,
51 const char* objPath) :
52 ChassisInherit(bus, objPath, true),
53 bus(bus),
54 systemdSignals(
55 bus,
56 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
57 sdbusRule::path("/org/freedesktop/systemd1") +
58 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
59 std::bind(std::mem_fn(&Chassis::sysStateChange), this,
60 std::placeholders::_1))
61 {
62 subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060063
Andrew Geissler58a18012018-01-19 19:36:05 -080064 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060065
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050066 restorePOHCounter(); // restore POHCounter from persisted file
67
Andrew Geissler58a18012018-01-19 19:36:05 -080068 // We deferred this until we could get our property correct
69 this->emit_object_added();
70 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060071
Andrew Geissler58a18012018-01-19 19:36:05 -080072 /** @brief Set value of RequestedPowerTransition */
73 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060074
Andrew Geissler58a18012018-01-19 19:36:05 -080075 /** @brief Set value of CurrentPowerState */
76 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060077
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050078 /** @brief Get value of POHCounter */
79 using ChassisInherit::pOHCounter;
80
81 /** @brief Increment POHCounter if Chassis Power state is ON */
82 void startPOHCounter();
83
Andrew Geissler58a18012018-01-19 19:36:05 -080084 private:
85 /** @brief Determine initial chassis state and set internally */
86 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060087
Andrew Geissler58a18012018-01-19 19:36:05 -080088 /**
89 * @brief subscribe to the systemd signals
90 *
91 * This object needs to capture when it's systemd targets complete
92 * so it can keep it's state updated
93 *
94 **/
95 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060096
Andrew Geissler58a18012018-01-19 19:36:05 -080097 /** @brief Execute the transition request
98 *
99 * This function calls the appropriate systemd target for the input
100 * transition.
101 *
102 * @param[in] tranReq - Transition requested
103 */
104 void executeTransition(Transition tranReq);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600105
Andrew Geissler58a18012018-01-19 19:36:05 -0800106 /**
107 * @brief Determine if target is active
108 *
109 * This function determines if the target is active and
110 * helps prevent misleading log recorded states.
111 *
112 * @param[in] target - Target string to check on
113 *
114 * @return boolean corresponding to state active
115 **/
116 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600117
Andrew Geissler58a18012018-01-19 19:36:05 -0800118 /** @brief Check if systemd state change is relevant to this object
119 *
120 * Instance specific interface to handle the detected systemd state
121 * change
122 *
123 * @param[in] msg - Data associated with subscribed signal
124 *
125 */
126 int sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600127
Andrew Geissler58a18012018-01-19 19:36:05 -0800128 /** @brief Persistent sdbusplus DBus connection. */
129 sdbusplus::bus::bus& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600130
Andrew Geissler58a18012018-01-19 19:36:05 -0800131 /** @brief Used to subscribe to dbus systemd signals **/
132 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500133
134 /** @brief Used to Set value of POHCounter */
135 uint32_t pOHCounter(uint32_t value) override;
136
137 /** @brief Used to restore POHCounter value from persisted file */
138 void restorePOHCounter();
139
140 /** @brief Function required by Cereal to perform serialization.
141 *
142 * @tparam Archive - Cereal archive type (json in our case).
143 * @param[in] archive - reference to Cereal archive.
144 * @param[in] version - Class version that enables handling
145 * a serialized data across code levels
146 */
147 template <class Archive>
148 inline void save(Archive& archive, const std::uint32_t version) const
149 {
150 archive(pOHCounter());
151 }
152
153 /** @brief Function required by Cereal to perform deserialization.
154 *
155 * @tparam Archive - Cereal archive type (json in our case).
156 * @param[in] archive - reference to Cereal archive.
157 * @param[in] version - Class version that enables handling
158 * a serialized data across code levels
159 */
160 template <class Archive>
161 inline void load(Archive& archive, const std::uint32_t version)
162 {
163 uint32_t value;
164 archive(value);
165 pOHCounter(value);
166 }
167
168 /** @brief Serialize and persist requested POH counter.
169 *
170 * @param[in] dir - pathname of file where the serialized POH counter will
171 * be placed.
172 *
173 * @return fs::path - pathname of persisted requested POH counter.
174 */
175 fs::path
176 serialize(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
177
178 /** @brief Deserialze a persisted requested POH counter.
179 *
180 * @param[in] path - pathname of persisted POH counter file
181 * @param[in] retCounter - deserialized POH counter value
182 *
183 * @return bool - true if the deserialization was successful, false
184 * otherwise.
185 */
186 bool deserialize(const fs::path& path, uint32_t& retCounter);
187
188 /** @brief Timer */
189 std::unique_ptr<phosphor::state::manager::Timer> timer;
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600190};
191
192} // namespace manager
193} // namespace state
194} // namespace phosphor