blob: 9a6b6479d0444b1aac077aa3f18e2d41e2400d3b [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
Matt Spinler9eab9862018-07-11 14:13:52 -050064 restoreChassisStateChangeTime();
65
Andrew Geissler58a18012018-01-19 19:36:05 -080066 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060067
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050068 restorePOHCounter(); // restore POHCounter from persisted file
69
Andrew Geissler58a18012018-01-19 19:36:05 -080070 // We deferred this until we could get our property correct
71 this->emit_object_added();
72 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060073
Andrew Geissler58a18012018-01-19 19:36:05 -080074 /** @brief Set value of RequestedPowerTransition */
75 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060076
Andrew Geissler58a18012018-01-19 19:36:05 -080077 /** @brief Set value of CurrentPowerState */
78 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060079
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050080 /** @brief Get value of POHCounter */
81 using ChassisInherit::pOHCounter;
82
83 /** @brief Increment POHCounter if Chassis Power state is ON */
84 void startPOHCounter();
85
Andrew Geissler58a18012018-01-19 19:36:05 -080086 private:
87 /** @brief Determine initial chassis state and set internally */
88 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060089
Andrew Geissler58a18012018-01-19 19:36:05 -080090 /**
91 * @brief subscribe to the systemd signals
92 *
93 * This object needs to capture when it's systemd targets complete
94 * so it can keep it's state updated
95 *
96 **/
97 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060098
Andrew Geissler58a18012018-01-19 19:36:05 -080099 /** @brief Execute the transition request
100 *
101 * This function calls the appropriate systemd target for the input
102 * transition.
103 *
104 * @param[in] tranReq - Transition requested
105 */
106 void executeTransition(Transition tranReq);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600107
Andrew Geissler58a18012018-01-19 19:36:05 -0800108 /**
109 * @brief Determine if target is active
110 *
111 * This function determines if the target is active and
112 * helps prevent misleading log recorded states.
113 *
114 * @param[in] target - Target string to check on
115 *
116 * @return boolean corresponding to state active
117 **/
118 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600119
Andrew Geissler58a18012018-01-19 19:36:05 -0800120 /** @brief Check if systemd state change is relevant to this object
121 *
122 * Instance specific interface to handle the detected systemd state
123 * change
124 *
125 * @param[in] msg - Data associated with subscribed signal
126 *
127 */
128 int sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600129
Andrew Geissler58a18012018-01-19 19:36:05 -0800130 /** @brief Persistent sdbusplus DBus connection. */
131 sdbusplus::bus::bus& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600132
Andrew Geissler58a18012018-01-19 19:36:05 -0800133 /** @brief Used to subscribe to dbus systemd signals **/
134 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500135
136 /** @brief Used to Set value of POHCounter */
137 uint32_t pOHCounter(uint32_t value) override;
138
139 /** @brief Used to restore POHCounter value from persisted file */
140 void restorePOHCounter();
141
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500142 /** @brief Serialize and persist requested POH counter.
143 *
144 * @param[in] dir - pathname of file where the serialized POH counter will
145 * be placed.
146 *
147 * @return fs::path - pathname of persisted requested POH counter.
148 */
149 fs::path
Matt Spinler81957842018-07-11 10:37:12 -0500150 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500151
Matt Spinler81957842018-07-11 10:37:12 -0500152 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500153 *
154 * @param[in] path - pathname of persisted POH counter file
155 * @param[in] retCounter - deserialized POH counter value
156 *
157 * @return bool - true if the deserialization was successful, false
158 * otherwise.
159 */
Matt Spinler81957842018-07-11 10:37:12 -0500160 bool deserializePOH(const fs::path& path, uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500161
Matt Spinler9eab9862018-07-11 14:13:52 -0500162 /** @brief Sets the LastStateChangeTime property and persists it. */
163 void setStateChangeTime();
164
165 /** @brief Serialize the last power state change time.
166 *
167 * Save the time the state changed and the state itself.
168 * The state needs to be saved as well so that during rediscovery
169 * on reboots there's a way to know not to update the time again.
170 */
171 void serializeStateChangeTime();
172
173 /** @brief Deserialize the last power state change time.
174 *
175 * @param[out] time - Deserialized time
176 * @param[out] state - Deserialized power state
177 *
178 * @return bool - true if successful, false otherwise.
179 */
180 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
181
182 /** @brief Restores the power state change time.
183 *
184 * The time is loaded into the LastStateChangeTime D-Bus property.
185 * On the very first start after this code has been applied but
186 * before the state has changed, the LastStateChangeTime value
187 * will be zero.
188 */
189 void restoreChassisStateChangeTime();
190
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500191 /** @brief Timer */
192 std::unique_ptr<phosphor::state::manager::Timer> timer;
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600193};
194
195} // namespace manager
196} // namespace state
197} // namespace phosphor