1 #pragma once 2 3 #include "config.h" 4 5 #include "xyz/openbmc_project/State/Chassis/server.hpp" 6 #include "xyz/openbmc_project/State/PowerOnHours/server.hpp" 7 8 #include <cereal/cereal.hpp> 9 #include <sdbusplus/bus.hpp> 10 #include <sdeventplus/clock.hpp> 11 #include <sdeventplus/event.hpp> 12 #include <sdeventplus/utility/timer.hpp> 13 14 #include <chrono> 15 #include <experimental/filesystem> 16 #include <functional> 17 18 namespace phosphor 19 { 20 namespace state 21 { 22 namespace manager 23 { 24 25 using ChassisInherit = sdbusplus::server::object::object< 26 sdbusplus::xyz::openbmc_project::State::server::Chassis, 27 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>; 28 namespace sdbusRule = sdbusplus::bus::match::rules; 29 namespace fs = std::experimental::filesystem; 30 31 /** @class Chassis 32 * @brief OpenBMC chassis state management implementation. 33 * @details A concrete implementation for xyz.openbmc_project.State.Chassis 34 * DBus API. 35 */ 36 class Chassis : public ChassisInherit 37 { 38 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 46 * @param[in] objPath - The Dbus object path 47 */ 48 Chassis(sdbusplus::bus::bus& bus, const char* objPath) : 49 ChassisInherit(bus, objPath, true), 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, 56 std::placeholders::_1)), 57 pohTimer(sdeventplus::Event::get_default(), 58 std::bind(&Chassis::pohCallback, this), std::chrono::hours{1}, 59 std::chrono::minutes{1}) 60 { 61 subscribeToSystemdSignals(); 62 63 restoreChassisStateChangeTime(); 64 65 determineInitialState(); 66 67 restorePOHCounter(); // restore POHCounter from persisted file 68 69 // We deferred this until we could get our property correct 70 this->emit_object_added(); 71 } 72 73 /** @brief Set value of RequestedPowerTransition */ 74 Transition requestedPowerTransition(Transition value) override; 75 76 /** @brief Set value of CurrentPowerState */ 77 PowerState currentPowerState(PowerState value) override; 78 79 /** @brief Get value of POHCounter */ 80 using ChassisInherit::pohCounter; 81 82 /** @brief Increment POHCounter if Chassis Power state is ON */ 83 void startPOHCounter(); 84 85 private: 86 /** @brief Determine initial chassis state and set internally */ 87 void determineInitialState(); 88 89 /** @brief Determine status of power into system */ 90 void determineStatusOfPower(); 91 92 /** 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(); 100 101 /** @brief Execute the transition request 102 * 103 * This function calls the appropriate systemd target for the input 104 * transition. 105 * 106 * @param[in] tranReq - Transition requested 107 */ 108 void executeTransition(Transition tranReq); 109 110 /** 111 * @brief Determine if target is active 112 * 113 * This function determines if the target is active and 114 * helps prevent misleading log recorded states. 115 * 116 * @param[in] target - Target string to check on 117 * 118 * @return boolean corresponding to state active 119 **/ 120 bool stateActive(const std::string& target); 121 122 /** @brief Check if systemd state change is relevant to this object 123 * 124 * Instance specific interface to handle the detected systemd state 125 * change 126 * 127 * @param[in] msg - Data associated with subscribed signal 128 * 129 */ 130 int sysStateChange(sdbusplus::message::message& msg); 131 132 /** @brief Persistent sdbusplus DBus connection. */ 133 sdbusplus::bus::bus& bus; 134 135 /** @brief Used to subscribe to dbus systemd signals **/ 136 sdbusplus::bus::match_t systemdSignals; 137 138 /** @brief Watch for any changes to UPS properties **/ 139 std::unique_ptr<sdbusplus::bus::match_t> uPowerPropChangeSignal; 140 141 /** @brief Used to Set value of POHCounter */ 142 uint32_t pohCounter(uint32_t value) override; 143 144 /** @brief Used by the timer to update the POHCounter */ 145 void pohCallback(); 146 147 /** @brief Used to restore POHCounter value from persisted file */ 148 void restorePOHCounter(); 149 150 /** @brief Serialize and persist requested POH counter. 151 * 152 * @param[in] dir - pathname of file where the serialized POH counter will 153 * be placed. 154 * 155 * @return fs::path - pathname of persisted requested POH counter. 156 */ 157 fs::path 158 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH)); 159 160 /** @brief Deserialize a persisted requested POH counter. 161 * 162 * @param[in] path - pathname of persisted POH counter file 163 * @param[in] retCounter - deserialized POH counter value 164 * 165 * @return bool - true if the deserialization was successful, false 166 * otherwise. 167 */ 168 bool deserializePOH(const fs::path& path, uint32_t& retCounter); 169 170 /** @brief Sets the LastStateChangeTime property and persists it. */ 171 void setStateChangeTime(); 172 173 /** @brief Serialize the last power state change time. 174 * 175 * Save the time the state changed and the state itself. 176 * The state needs to be saved as well so that during rediscovery 177 * on reboots there's a way to know not to update the time again. 178 */ 179 void serializeStateChangeTime(); 180 181 /** @brief Deserialize the last power state change time. 182 * 183 * @param[out] time - Deserialized time 184 * @param[out] state - Deserialized power state 185 * 186 * @return bool - true if successful, false otherwise. 187 */ 188 bool deserializeStateChangeTime(uint64_t& time, PowerState& state); 189 190 /** @brief Restores the power state change time. 191 * 192 * The time is loaded into the LastStateChangeTime D-Bus property. 193 * On the very first start after this code has been applied but 194 * before the state has changed, the LastStateChangeTime value 195 * will be zero. 196 */ 197 void restoreChassisStateChangeTime(); 198 199 /** @brief Timer used for tracking power on hours */ 200 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer; 201 202 /** @brief Function to check for a standby voltage regulator fault 203 * 204 * Determine if a standby voltage regulator fault was detected and 205 * return true or false accordingly. 206 * 207 * @return true if fault detected, else false 208 */ 209 bool standbyVoltageRegulatorFault(); 210 211 /** @brief Process UPS property changes 212 * 213 * Instance specific interface to monitor for changes to the UPS 214 * properties which may impact CurrentPowerStatus 215 * 216 * @param[in] msg - Data associated with subscribed signal 217 * 218 */ 219 void uPowerChangeEvent(sdbusplus::message::message& msg); 220 }; 221 222 } // namespace manager 223 } // namespace state 224 } // namespace phosphor 225