blob: 9b13af404d151c565990658ef32227c171971884 [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
Patrick Williams45a1ed72021-04-30 21:02:43 -050018#ifndef SDBUSPP_NEW_CAMELCASE
19#define pohCounter pOHCounter
20#endif
21
Andrew Geisslera90a31a2016-12-13 16:16:28 -060022namespace phosphor
23{
24namespace state
25{
26namespace manager
27{
28
Patrick Williams8f8ba392017-05-05 15:47:39 -050029using ChassisInherit = sdbusplus::server::object::object<
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050030 sdbusplus::xyz::openbmc_project::State::server::Chassis,
31 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
Patrick Williams8f8ba392017-05-05 15:47:39 -050032namespace sdbusRule = sdbusplus::bus::match::rules;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050033namespace fs = std::experimental::filesystem;
Patrick Williams8f8ba392017-05-05 15:47:39 -050034
Andrew Geisslera90a31a2016-12-13 16:16:28 -060035/** @class Chassis
36 * @brief OpenBMC chassis state management implementation.
37 * @details A concrete implementation for xyz.openbmc_project.State.Chassis
38 * DBus API.
39 */
Patrick Williams8f8ba392017-05-05 15:47:39 -050040class Chassis : public ChassisInherit
Andrew Geisslera90a31a2016-12-13 16:16:28 -060041{
Andrew Geissler58a18012018-01-19 19:36:05 -080042 public:
43 /** @brief Constructs Chassis State Manager
44 *
45 * @note This constructor passes 'true' to the base class in order to
46 * defer dbus object registration until we can run
47 * determineInitialState() and set our properties
48 *
49 * @param[in] bus - The Dbus bus object
Andrew Geissler58a18012018-01-19 19:36:05 -080050 * @param[in] objPath - The Dbus object path
51 */
Andrew Geissler769a62f2019-12-06 13:36:08 -060052 Chassis(sdbusplus::bus::bus& bus, const char* objPath) :
53 ChassisInherit(bus, objPath, true), bus(bus),
Andrew Geissler58a18012018-01-19 19:36:05 -080054 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,
William A. Kennington IIId998f822018-10-17 23:17:57 -070060 std::placeholders::_1)),
Patrick Williams45a1ed72021-04-30 21:02:43 -050061 pohTimer(sdeventplus::Event::get_default(),
62 std::bind(&Chassis::pohCallback, this), std::chrono::hours{1},
William A. Kennington IIId998f822018-10-17 23:17:57 -070063 std::chrono::minutes{1})
Andrew Geissler58a18012018-01-19 19:36:05 -080064 {
65 subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060066
Matt Spinler9eab9862018-07-11 14:13:52 -050067 restoreChassisStateChangeTime();
68
Andrew Geissler58a18012018-01-19 19:36:05 -080069 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060070
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050071 restorePOHCounter(); // restore POHCounter from persisted file
72
Andrew Geissler58a18012018-01-19 19:36:05 -080073 // We deferred this until we could get our property correct
74 this->emit_object_added();
75 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060076
Andrew Geissler58a18012018-01-19 19:36:05 -080077 /** @brief Set value of RequestedPowerTransition */
78 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060079
Andrew Geissler58a18012018-01-19 19:36:05 -080080 /** @brief Set value of CurrentPowerState */
81 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060082
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050083 /** @brief Get value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -050084 using ChassisInherit::pohCounter;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050085
86 /** @brief Increment POHCounter if Chassis Power state is ON */
87 void startPOHCounter();
88
Andrew Geissler58a18012018-01-19 19:36:05 -080089 private:
90 /** @brief Determine initial chassis state and set internally */
91 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060092
Andrew Geissler58a18012018-01-19 19:36:05 -080093 /**
94 * @brief subscribe to the systemd signals
95 *
96 * This object needs to capture when it's systemd targets complete
97 * so it can keep it's state updated
98 *
99 **/
100 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -0600101
Andrew Geissler58a18012018-01-19 19:36:05 -0800102 /** @brief Execute the transition request
103 *
104 * This function calls the appropriate systemd target for the input
105 * transition.
106 *
107 * @param[in] tranReq - Transition requested
108 */
109 void executeTransition(Transition tranReq);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600110
Andrew Geissler58a18012018-01-19 19:36:05 -0800111 /**
112 * @brief Determine if target is active
113 *
114 * This function determines if the target is active and
115 * helps prevent misleading log recorded states.
116 *
117 * @param[in] target - Target string to check on
118 *
119 * @return boolean corresponding to state active
120 **/
121 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600122
Andrew Geissler58a18012018-01-19 19:36:05 -0800123 /** @brief Check if systemd state change is relevant to this object
124 *
125 * Instance specific interface to handle the detected systemd state
126 * change
127 *
128 * @param[in] msg - Data associated with subscribed signal
129 *
130 */
131 int sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600132
Andrew Geissler58a18012018-01-19 19:36:05 -0800133 /** @brief Persistent sdbusplus DBus connection. */
134 sdbusplus::bus::bus& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600135
Andrew Geissler58a18012018-01-19 19:36:05 -0800136 /** @brief Used to subscribe to dbus systemd signals **/
137 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500138
139 /** @brief Used to Set value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500140 uint32_t pohCounter(uint32_t value) override;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500141
William A. Kennington IIId998f822018-10-17 23:17:57 -0700142 /** @brief Used by the timer to update the POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500143 void pohCallback();
William A. Kennington IIId998f822018-10-17 23:17:57 -0700144
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500145 /** @brief Used to restore POHCounter value from persisted file */
146 void restorePOHCounter();
147
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500148 /** @brief Serialize and persist requested POH counter.
149 *
150 * @param[in] dir - pathname of file where the serialized POH counter will
151 * be placed.
152 *
153 * @return fs::path - pathname of persisted requested POH counter.
154 */
155 fs::path
Matt Spinler81957842018-07-11 10:37:12 -0500156 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500157
Matt Spinler81957842018-07-11 10:37:12 -0500158 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500159 *
160 * @param[in] path - pathname of persisted POH counter file
161 * @param[in] retCounter - deserialized POH counter value
162 *
163 * @return bool - true if the deserialization was successful, false
164 * otherwise.
165 */
Matt Spinler81957842018-07-11 10:37:12 -0500166 bool deserializePOH(const fs::path& path, uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500167
Matt Spinler9eab9862018-07-11 14:13:52 -0500168 /** @brief Sets the LastStateChangeTime property and persists it. */
169 void setStateChangeTime();
170
171 /** @brief Serialize the last power state change time.
172 *
173 * Save the time the state changed and the state itself.
174 * The state needs to be saved as well so that during rediscovery
175 * on reboots there's a way to know not to update the time again.
176 */
177 void serializeStateChangeTime();
178
179 /** @brief Deserialize the last power state change time.
180 *
181 * @param[out] time - Deserialized time
182 * @param[out] state - Deserialized power state
183 *
184 * @return bool - true if successful, false otherwise.
185 */
186 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
187
188 /** @brief Restores the power state change time.
189 *
190 * The time is loaded into the LastStateChangeTime D-Bus property.
191 * On the very first start after this code has been applied but
192 * before the state has changed, the LastStateChangeTime value
193 * will be zero.
194 */
195 void restoreChassisStateChangeTime();
196
William A. Kennington IIId998f822018-10-17 23:17:57 -0700197 /** @brief Timer used for tracking power on hours */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500198 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer;
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600199};
200
201} // namespace manager
202} // namespace state
203} // namespace phosphor