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 #ifndef SDBUSPP_NEW_CAMELCASE 19 #define pohCounter pOHCounter 20 #endif 21 22 namespace phosphor 23 { 24 namespace state 25 { 26 namespace manager 27 { 28 29 using ChassisInherit = sdbusplus::server::object::object< 30 sdbusplus::xyz::openbmc_project::State::server::Chassis, 31 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>; 32 namespace sdbusRule = sdbusplus::bus::match::rules; 33 namespace fs = std::experimental::filesystem; 34 35 /** @class Chassis 36 * @brief OpenBMC chassis state management implementation. 37 * @details A concrete implementation for xyz.openbmc_project.State.Chassis 38 * DBus API. 39 */ 40 class Chassis : public ChassisInherit 41 { 42 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 50 * @param[in] objPath - The Dbus object path 51 */ 52 Chassis(sdbusplus::bus::bus& bus, const char* objPath) : 53 ChassisInherit(bus, objPath, true), bus(bus), 54 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, 60 std::placeholders::_1)), 61 pohTimer(sdeventplus::Event::get_default(), 62 std::bind(&Chassis::pohCallback, this), std::chrono::hours{1}, 63 std::chrono::minutes{1}) 64 { 65 subscribeToSystemdSignals(); 66 67 restoreChassisStateChangeTime(); 68 69 determineInitialState(); 70 71 restorePOHCounter(); // restore POHCounter from persisted file 72 73 // We deferred this until we could get our property correct 74 this->emit_object_added(); 75 } 76 77 /** @brief Set value of RequestedPowerTransition */ 78 Transition requestedPowerTransition(Transition value) override; 79 80 /** @brief Set value of CurrentPowerState */ 81 PowerState currentPowerState(PowerState value) override; 82 83 /** @brief Get value of POHCounter */ 84 using ChassisInherit::pohCounter; 85 86 /** @brief Increment POHCounter if Chassis Power state is ON */ 87 void startPOHCounter(); 88 89 private: 90 /** @brief Determine initial chassis state and set internally */ 91 void determineInitialState(); 92 93 /** 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(); 101 102 /** @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); 110 111 /** 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); 122 123 /** @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); 132 133 /** @brief Persistent sdbusplus DBus connection. */ 134 sdbusplus::bus::bus& bus; 135 136 /** @brief Used to subscribe to dbus systemd signals **/ 137 sdbusplus::bus::match_t systemdSignals; 138 139 /** @brief Used to Set value of POHCounter */ 140 uint32_t pohCounter(uint32_t value) override; 141 142 /** @brief Used by the timer to update the POHCounter */ 143 void pohCallback(); 144 145 /** @brief Used to restore POHCounter value from persisted file */ 146 void restorePOHCounter(); 147 148 /** @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 156 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH)); 157 158 /** @brief Deserialize a persisted requested POH counter. 159 * 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 */ 166 bool deserializePOH(const fs::path& path, uint32_t& retCounter); 167 168 /** @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 197 /** @brief Timer used for tracking power on hours */ 198 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer; 199 }; 200 201 } // namespace manager 202 } // namespace state 203 } // namespace phosphor 204