blob: d1943dc883ec65bd5daceb81ca90fd06572ee75b [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
Andrew Geissler58a18012018-01-19 19:36:05 -080043 * @param[in] objPath - The Dbus object path
44 */
Andrew Geissler769a62f2019-12-06 13:36:08 -060045 Chassis(sdbusplus::bus::bus& bus, const char* objPath) :
46 ChassisInherit(bus, objPath, true), bus(bus),
Andrew Geissler58a18012018-01-19 19:36:05 -080047 systemdSignals(
48 bus,
49 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
50 sdbusRule::path("/org/freedesktop/systemd1") +
51 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
52 std::bind(std::mem_fn(&Chassis::sysStateChange), this,
William A. Kennington IIId998f822018-10-17 23:17:57 -070053 std::placeholders::_1)),
54 pOHTimer(sdeventplus::Event::get_default(),
55 std::bind(&Chassis::pOHCallback, this), std::chrono::hours{1},
56 std::chrono::minutes{1})
Andrew Geissler58a18012018-01-19 19:36:05 -080057 {
58 subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060059
Matt Spinler9eab9862018-07-11 14:13:52 -050060 restoreChassisStateChangeTime();
61
Andrew Geissler58a18012018-01-19 19:36:05 -080062 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060063
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050064 restorePOHCounter(); // restore POHCounter from persisted file
65
Andrew Geissler58a18012018-01-19 19:36:05 -080066 // We deferred this until we could get our property correct
67 this->emit_object_added();
68 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060069
Andrew Geissler58a18012018-01-19 19:36:05 -080070 /** @brief Set value of RequestedPowerTransition */
71 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060072
Andrew Geissler58a18012018-01-19 19:36:05 -080073 /** @brief Set value of CurrentPowerState */
74 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060075
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050076 /** @brief Get value of POHCounter */
77 using ChassisInherit::pOHCounter;
78
79 /** @brief Increment POHCounter if Chassis Power state is ON */
80 void startPOHCounter();
81
Andrew Geissler58a18012018-01-19 19:36:05 -080082 private:
83 /** @brief Determine initial chassis state and set internally */
84 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060085
Andrew Geissler58a18012018-01-19 19:36:05 -080086 /**
87 * @brief subscribe to the systemd signals
88 *
89 * This object needs to capture when it's systemd targets complete
90 * so it can keep it's state updated
91 *
92 **/
93 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060094
Andrew Geissler58a18012018-01-19 19:36:05 -080095 /** @brief Execute the transition request
96 *
97 * This function calls the appropriate systemd target for the input
98 * transition.
99 *
100 * @param[in] tranReq - Transition requested
101 */
102 void executeTransition(Transition tranReq);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600103
Andrew Geissler58a18012018-01-19 19:36:05 -0800104 /**
105 * @brief Determine if target is active
106 *
107 * This function determines if the target is active and
108 * helps prevent misleading log recorded states.
109 *
110 * @param[in] target - Target string to check on
111 *
112 * @return boolean corresponding to state active
113 **/
114 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600115
Andrew Geissler58a18012018-01-19 19:36:05 -0800116 /** @brief Check if systemd state change is relevant to this object
117 *
118 * Instance specific interface to handle the detected systemd state
119 * change
120 *
121 * @param[in] msg - Data associated with subscribed signal
122 *
123 */
124 int sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600125
Andrew Geissler58a18012018-01-19 19:36:05 -0800126 /** @brief Persistent sdbusplus DBus connection. */
127 sdbusplus::bus::bus& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600128
Andrew Geissler58a18012018-01-19 19:36:05 -0800129 /** @brief Used to subscribe to dbus systemd signals **/
130 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500131
132 /** @brief Used to Set value of POHCounter */
133 uint32_t pOHCounter(uint32_t value) override;
134
William A. Kennington IIId998f822018-10-17 23:17:57 -0700135 /** @brief Used by the timer to update the POHCounter */
136 void pOHCallback();
137
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500138 /** @brief Used to restore POHCounter value from persisted file */
139 void restorePOHCounter();
140
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500141 /** @brief Serialize and persist requested POH counter.
142 *
143 * @param[in] dir - pathname of file where the serialized POH counter will
144 * be placed.
145 *
146 * @return fs::path - pathname of persisted requested POH counter.
147 */
148 fs::path
Matt Spinler81957842018-07-11 10:37:12 -0500149 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500150
Matt Spinler81957842018-07-11 10:37:12 -0500151 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500152 *
153 * @param[in] path - pathname of persisted POH counter file
154 * @param[in] retCounter - deserialized POH counter value
155 *
156 * @return bool - true if the deserialization was successful, false
157 * otherwise.
158 */
Matt Spinler81957842018-07-11 10:37:12 -0500159 bool deserializePOH(const fs::path& path, uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500160
Matt Spinler9eab9862018-07-11 14:13:52 -0500161 /** @brief Sets the LastStateChangeTime property and persists it. */
162 void setStateChangeTime();
163
164 /** @brief Serialize the last power state change time.
165 *
166 * Save the time the state changed and the state itself.
167 * The state needs to be saved as well so that during rediscovery
168 * on reboots there's a way to know not to update the time again.
169 */
170 void serializeStateChangeTime();
171
172 /** @brief Deserialize the last power state change time.
173 *
174 * @param[out] time - Deserialized time
175 * @param[out] state - Deserialized power state
176 *
177 * @return bool - true if successful, false otherwise.
178 */
179 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
180
181 /** @brief Restores the power state change time.
182 *
183 * The time is loaded into the LastStateChangeTime D-Bus property.
184 * On the very first start after this code has been applied but
185 * before the state has changed, the LastStateChangeTime value
186 * will be zero.
187 */
188 void restoreChassisStateChangeTime();
189
William A. Kennington IIId998f822018-10-17 23:17:57 -0700190 /** @brief Timer used for tracking power on hours */
191 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pOHTimer;
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600192};
193
194} // namespace manager
195} // namespace state
196} // namespace phosphor