blob: 4780e0f0dbb39ad0d2ed580283b146313469cc2d [file] [log] [blame]
Andrew Geisslera90a31a2016-12-13 16:16:28 -06001#pragma once
2
William A. Kennington IIId998f822018-10-17 23:17:57 -07003#include <chrono>
Patrick Williams8f8ba392017-05-05 15:47:39 -05004#include <functional>
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -05005#include <experimental/filesystem>
6#include <cereal/cereal.hpp>
Andrew Geisslera90a31a2016-12-13 16:16:28 -06007#include <sdbusplus/bus.hpp>
William A. Kennington IIId998f822018-10-17 23:17:57 -07008#include <sdeventplus/clock.hpp>
9#include <sdeventplus/event.hpp>
10#include <sdeventplus/utility/timer.hpp>
Andrew Geisslera90a31a2016-12-13 16:16:28 -060011#include "xyz/openbmc_project/State/Chassis/server.hpp"
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050012#include "xyz/openbmc_project/State/PowerOnHours/server.hpp"
13#include "config.h"
Andrew Geisslera90a31a2016-12-13 16:16:28 -060014
15namespace phosphor
16{
17namespace state
18{
19namespace manager
20{
21
Patrick Williams8f8ba392017-05-05 15:47:39 -050022using ChassisInherit = sdbusplus::server::object::object<
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050023 sdbusplus::xyz::openbmc_project::State::server::Chassis,
24 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
Patrick Williams8f8ba392017-05-05 15:47:39 -050025namespace sdbusRule = sdbusplus::bus::match::rules;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050026namespace fs = std::experimental::filesystem;
Patrick Williams8f8ba392017-05-05 15:47:39 -050027
Andrew Geisslera90a31a2016-12-13 16:16:28 -060028/** @class Chassis
29 * @brief OpenBMC chassis state management implementation.
30 * @details A concrete implementation for xyz.openbmc_project.State.Chassis
31 * DBus API.
32 */
Patrick Williams8f8ba392017-05-05 15:47:39 -050033class Chassis : public ChassisInherit
Andrew Geisslera90a31a2016-12-13 16:16:28 -060034{
Andrew Geissler58a18012018-01-19 19:36:05 -080035 public:
36 /** @brief Constructs Chassis State Manager
37 *
38 * @note This constructor passes 'true' to the base class in order to
39 * defer dbus object registration until we can run
40 * determineInitialState() and set our properties
41 *
42 * @param[in] bus - The Dbus bus object
43 * @param[in] instance - The instance of this object
44 * @param[in] objPath - The Dbus object path
45 */
46 Chassis(sdbusplus::bus::bus& bus, const char* busName,
47 const char* objPath) :
48 ChassisInherit(bus, objPath, true),
49 bus(bus),
50 systemdSignals(
51 bus,
52 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
53 sdbusRule::path("/org/freedesktop/systemd1") +
54 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
55 std::bind(std::mem_fn(&Chassis::sysStateChange), this,
William A. Kennington IIId998f822018-10-17 23:17:57 -070056 std::placeholders::_1)),
57 pOHTimer(sdeventplus::Event::get_default(),
58 std::bind(&Chassis::pOHCallback, this), std::chrono::hours{1},
59 std::chrono::minutes{1})
Andrew Geissler58a18012018-01-19 19:36:05 -080060 {
61 subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060062
Matt Spinler9eab9862018-07-11 14:13:52 -050063 restoreChassisStateChangeTime();
64
Andrew Geissler58a18012018-01-19 19:36:05 -080065 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060066
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050067 restorePOHCounter(); // restore POHCounter from persisted file
68
Andrew Geissler58a18012018-01-19 19:36:05 -080069 // We deferred this until we could get our property correct
70 this->emit_object_added();
71 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060072
Andrew Geissler58a18012018-01-19 19:36:05 -080073 /** @brief Set value of RequestedPowerTransition */
74 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060075
Andrew Geissler58a18012018-01-19 19:36:05 -080076 /** @brief Set value of CurrentPowerState */
77 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060078
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050079 /** @brief Get value of POHCounter */
80 using ChassisInherit::pOHCounter;
81
82 /** @brief Increment POHCounter if Chassis Power state is ON */
83 void startPOHCounter();
84
Andrew Geissler58a18012018-01-19 19:36:05 -080085 private:
86 /** @brief Determine initial chassis state and set internally */
87 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060088
Andrew Geissler58a18012018-01-19 19:36:05 -080089 /**
90 * @brief subscribe to the systemd signals
91 *
92 * This object needs to capture when it's systemd targets complete
93 * so it can keep it's state updated
94 *
95 **/
96 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060097
Andrew Geissler58a18012018-01-19 19:36:05 -080098 /** @brief Execute the transition request
99 *
100 * This function calls the appropriate systemd target for the input
101 * transition.
102 *
103 * @param[in] tranReq - Transition requested
104 */
105 void executeTransition(Transition tranReq);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600106
Andrew Geissler58a18012018-01-19 19:36:05 -0800107 /**
108 * @brief Determine if target is active
109 *
110 * This function determines if the target is active and
111 * helps prevent misleading log recorded states.
112 *
113 * @param[in] target - Target string to check on
114 *
115 * @return boolean corresponding to state active
116 **/
117 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600118
Andrew Geissler58a18012018-01-19 19:36:05 -0800119 /** @brief Check if systemd state change is relevant to this object
120 *
121 * Instance specific interface to handle the detected systemd state
122 * change
123 *
124 * @param[in] msg - Data associated with subscribed signal
125 *
126 */
127 int sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600128
Andrew Geissler58a18012018-01-19 19:36:05 -0800129 /** @brief Persistent sdbusplus DBus connection. */
130 sdbusplus::bus::bus& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600131
Andrew Geissler58a18012018-01-19 19:36:05 -0800132 /** @brief Used to subscribe to dbus systemd signals **/
133 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500134
135 /** @brief Used to Set value of POHCounter */
136 uint32_t pOHCounter(uint32_t value) override;
137
William A. Kennington IIId998f822018-10-17 23:17:57 -0700138 /** @brief Used by the timer to update the POHCounter */
139 void pOHCallback();
140
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500141 /** @brief Used to restore POHCounter value from persisted file */
142 void restorePOHCounter();
143
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500144 /** @brief Serialize and persist requested POH counter.
145 *
146 * @param[in] dir - pathname of file where the serialized POH counter will
147 * be placed.
148 *
149 * @return fs::path - pathname of persisted requested POH counter.
150 */
151 fs::path
Matt Spinler81957842018-07-11 10:37:12 -0500152 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500153
Matt Spinler81957842018-07-11 10:37:12 -0500154 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500155 *
156 * @param[in] path - pathname of persisted POH counter file
157 * @param[in] retCounter - deserialized POH counter value
158 *
159 * @return bool - true if the deserialization was successful, false
160 * otherwise.
161 */
Matt Spinler81957842018-07-11 10:37:12 -0500162 bool deserializePOH(const fs::path& path, uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500163
Matt Spinler9eab9862018-07-11 14:13:52 -0500164 /** @brief Sets the LastStateChangeTime property and persists it. */
165 void setStateChangeTime();
166
167 /** @brief Serialize the last power state change time.
168 *
169 * Save the time the state changed and the state itself.
170 * The state needs to be saved as well so that during rediscovery
171 * on reboots there's a way to know not to update the time again.
172 */
173 void serializeStateChangeTime();
174
175 /** @brief Deserialize the last power state change time.
176 *
177 * @param[out] time - Deserialized time
178 * @param[out] state - Deserialized power state
179 *
180 * @return bool - true if successful, false otherwise.
181 */
182 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
183
184 /** @brief Restores the power state change time.
185 *
186 * The time is loaded into the LastStateChangeTime D-Bus property.
187 * On the very first start after this code has been applied but
188 * before the state has changed, the LastStateChangeTime value
189 * will be zero.
190 */
191 void restoreChassisStateChangeTime();
192
William A. Kennington IIId998f822018-10-17 23:17:57 -0700193 /** @brief Timer used for tracking power on hours */
194 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pOHTimer;
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600195};
196
197} // namespace manager
198} // namespace state
199} // namespace phosphor