blob: 601e2a65fb3f8f844db66ae154ae2e5f73ae9bfe [file] [log] [blame]
Andrew Geisslera90a31a2016-12-13 16:16:28 -06001#pragma once
2
Andrew Geisslere426b582020-05-28 12:40:55 -05003#include "config.h"
4
5#include "xyz/openbmc_project/State/Chassis/server.hpp"
6#include "xyz/openbmc_project/State/PowerOnHours/server.hpp"
7
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -05008#include <cereal/cereal.hpp>
Andrew Geisslera90a31a2016-12-13 16:16:28 -06009#include <sdbusplus/bus.hpp>
William A. Kennington IIId998f822018-10-17 23:17:57 -070010#include <sdeventplus/clock.hpp>
11#include <sdeventplus/event.hpp>
12#include <sdeventplus/utility/timer.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050013
14#include <chrono>
15#include <experimental/filesystem>
16#include <functional>
Andrew Geisslera90a31a2016-12-13 16:16:28 -060017
18namespace phosphor
19{
20namespace state
21{
22namespace manager
23{
24
Patrick Williams8f8ba392017-05-05 15:47:39 -050025using ChassisInherit = sdbusplus::server::object::object<
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050026 sdbusplus::xyz::openbmc_project::State::server::Chassis,
27 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
Patrick Williams8f8ba392017-05-05 15:47:39 -050028namespace sdbusRule = sdbusplus::bus::match::rules;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050029namespace fs = std::experimental::filesystem;
Patrick Williams8f8ba392017-05-05 15:47:39 -050030
Andrew Geisslera90a31a2016-12-13 16:16:28 -060031/** @class Chassis
32 * @brief OpenBMC chassis state management implementation.
33 * @details A concrete implementation for xyz.openbmc_project.State.Chassis
34 * DBus API.
35 */
Patrick Williams8f8ba392017-05-05 15:47:39 -050036class Chassis : public ChassisInherit
Andrew Geisslera90a31a2016-12-13 16:16:28 -060037{
Andrew Geissler58a18012018-01-19 19:36:05 -080038 public:
39 /** @brief Constructs Chassis State Manager
40 *
41 * @note This constructor passes 'true' to the base class in order to
42 * defer dbus object registration until we can run
43 * determineInitialState() and set our properties
44 *
45 * @param[in] bus - The Dbus bus object
Andrew Geissler58a18012018-01-19 19:36:05 -080046 * @param[in] objPath - The Dbus object path
47 */
Andrew Geissler769a62f2019-12-06 13:36:08 -060048 Chassis(sdbusplus::bus::bus& bus, const char* objPath) :
49 ChassisInherit(bus, objPath, true), bus(bus),
Andrew Geissler58a18012018-01-19 19:36:05 -080050 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