blob: cf59025ca731ec6ac22a5e8ccc7354310f5ef382 [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)),
Patrick Williams45a1ed72021-04-30 21:02:43 -050057 pohTimer(sdeventplus::Event::get_default(),
58 std::bind(&Chassis::pohCallback, this), std::chrono::hours{1},
William A. Kennington IIId998f822018-10-17 23:17:57 -070059 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 */
Patrick Williams45a1ed72021-04-30 21:02:43 -050080 using ChassisInherit::pohCounter;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050081
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 Geissler8b1f8622022-01-28 16:37:07 -060089 /** @brief Determine status of power into system */
90 void determineStatusOfPower();
91
Andrew Geissler58a18012018-01-19 19:36:05 -080092 /**
93 * @brief subscribe to the systemd signals
94 *
95 * This object needs to capture when it's systemd targets complete
96 * so it can keep it's state updated
97 *
98 **/
99 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -0600100
Matthew Barthbe6efab2022-03-01 13:21:45 -0600101 /** @brief Start the systemd unit requested
Andrew Geissler58a18012018-01-19 19:36:05 -0800102 *
Matthew Barthbe6efab2022-03-01 13:21:45 -0600103 * This function calls `StartUnit` on the systemd unit given.
Andrew Geissler58a18012018-01-19 19:36:05 -0800104 *
Matthew Barthbe6efab2022-03-01 13:21:45 -0600105 * @param[in] sysdUnit - Systemd unit
Andrew Geissler58a18012018-01-19 19:36:05 -0800106 */
Matthew Barthbe6efab2022-03-01 13:21:45 -0600107 void startUnit(const std::string& sysdUnit);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600108
Andrew Geissler58a18012018-01-19 19:36:05 -0800109 /**
110 * @brief Determine if target is active
111 *
112 * This function determines if the target is active and
113 * helps prevent misleading log recorded states.
114 *
115 * @param[in] target - Target string to check on
116 *
117 * @return boolean corresponding to state active
118 **/
119 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600120
Andrew Geissler58a18012018-01-19 19:36:05 -0800121 /** @brief Check if systemd state change is relevant to this object
122 *
123 * Instance specific interface to handle the detected systemd state
124 * change
125 *
126 * @param[in] msg - Data associated with subscribed signal
127 *
128 */
129 int sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600130
Andrew Geissler58a18012018-01-19 19:36:05 -0800131 /** @brief Persistent sdbusplus DBus connection. */
132 sdbusplus::bus::bus& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600133
Andrew Geissler58a18012018-01-19 19:36:05 -0800134 /** @brief Used to subscribe to dbus systemd signals **/
135 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500136
Andrew Geissler2cf2a262022-02-02 14:38:41 -0600137 /** @brief Watch for any changes to UPS properties **/
138 std::unique_ptr<sdbusplus::bus::match_t> uPowerPropChangeSignal;
139
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500140 /** @brief Used to Set value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500141 uint32_t pohCounter(uint32_t value) override;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500142
William A. Kennington IIId998f822018-10-17 23:17:57 -0700143 /** @brief Used by the timer to update the POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500144 void pohCallback();
William A. Kennington IIId998f822018-10-17 23:17:57 -0700145
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500146 /** @brief Used to restore POHCounter value from persisted file */
147 void restorePOHCounter();
148
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500149 /** @brief Serialize and persist requested POH counter.
150 *
151 * @param[in] dir - pathname of file where the serialized POH counter will
152 * be placed.
153 *
154 * @return fs::path - pathname of persisted requested POH counter.
155 */
156 fs::path
Matt Spinler81957842018-07-11 10:37:12 -0500157 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500158
Matt Spinler81957842018-07-11 10:37:12 -0500159 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500160 *
161 * @param[in] path - pathname of persisted POH counter file
162 * @param[in] retCounter - deserialized POH counter value
163 *
164 * @return bool - true if the deserialization was successful, false
165 * otherwise.
166 */
Matt Spinler81957842018-07-11 10:37:12 -0500167 bool deserializePOH(const fs::path& path, uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500168
Matt Spinler9eab9862018-07-11 14:13:52 -0500169 /** @brief Sets the LastStateChangeTime property and persists it. */
170 void setStateChangeTime();
171
172 /** @brief Serialize the last power state change time.
173 *
174 * Save the time the state changed and the state itself.
175 * The state needs to be saved as well so that during rediscovery
176 * on reboots there's a way to know not to update the time again.
177 */
178 void serializeStateChangeTime();
179
180 /** @brief Deserialize the last power state change time.
181 *
182 * @param[out] time - Deserialized time
183 * @param[out] state - Deserialized power state
184 *
185 * @return bool - true if successful, false otherwise.
186 */
187 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
188
189 /** @brief Restores the power state change time.
190 *
191 * The time is loaded into the LastStateChangeTime D-Bus property.
192 * On the very first start after this code has been applied but
193 * before the state has changed, the LastStateChangeTime value
194 * will be zero.
195 */
196 void restoreChassisStateChangeTime();
197
William A. Kennington IIId998f822018-10-17 23:17:57 -0700198 /** @brief Timer used for tracking power on hours */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500199 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer;
Ben Tyner2c36e5a2021-07-12 14:56:49 -0500200
201 /** @brief Function to check for a standby voltage regulator fault
202 *
203 * Determine if a standby voltage regulator fault was detected and
204 * return true or false accordingly.
205 *
206 * @return true if fault detected, else false
207 */
208 bool standbyVoltageRegulatorFault();
Andrew Geissler2cf2a262022-02-02 14:38:41 -0600209
210 /** @brief Process UPS property changes
211 *
212 * Instance specific interface to monitor for changes to the UPS
213 * properties which may impact CurrentPowerStatus
214 *
215 * @param[in] msg - Data associated with subscribed signal
216 *
217 */
218 void uPowerChangeEvent(sdbusplus::message::message& msg);
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600219};
220
221} // namespace manager
222} // namespace state
223} // namespace phosphor