1 #pragma once 2 3 #include <chrono> 4 #include <functional> 5 #include <experimental/filesystem> 6 #include <cereal/cereal.hpp> 7 #include <sdbusplus/bus.hpp> 8 #include <sdeventplus/clock.hpp> 9 #include <sdeventplus/event.hpp> 10 #include <sdeventplus/utility/timer.hpp> 11 #include "xyz/openbmc_project/State/Chassis/server.hpp" 12 #include "xyz/openbmc_project/State/PowerOnHours/server.hpp" 13 #include "config.h" 14 15 namespace phosphor 16 { 17 namespace state 18 { 19 namespace manager 20 { 21 22 using ChassisInherit = sdbusplus::server::object::object< 23 sdbusplus::xyz::openbmc_project::State::server::Chassis, 24 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>; 25 namespace sdbusRule = sdbusplus::bus::match::rules; 26 namespace fs = std::experimental::filesystem; 27 28 /** @class Chassis 29 * @brief OpenBMC chassis state management implementation. 30 * @details A concrete implementation for xyz.openbmc_project.State.Chassis 31 * DBus API. 32 */ 33 class Chassis : public ChassisInherit 34 { 35 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 43 * @param[in] objPath - The Dbus object path 44 */ 45 Chassis(sdbusplus::bus::bus& bus, const char* objPath) : 46 ChassisInherit(bus, objPath, true), bus(bus), 47 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, 53 std::placeholders::_1)), 54 pOHTimer(sdeventplus::Event::get_default(), 55 std::bind(&Chassis::pOHCallback, this), std::chrono::hours{1}, 56 std::chrono::minutes{1}) 57 { 58 subscribeToSystemdSignals(); 59 60 restoreChassisStateChangeTime(); 61 62 determineInitialState(); 63 64 restorePOHCounter(); // restore POHCounter from persisted file 65 66 // We deferred this until we could get our property correct 67 this->emit_object_added(); 68 } 69 70 /** @brief Set value of RequestedPowerTransition */ 71 Transition requestedPowerTransition(Transition value) override; 72 73 /** @brief Set value of CurrentPowerState */ 74 PowerState currentPowerState(PowerState value) override; 75 76 /** @brief Get value of POHCounter */ 77 using ChassisInherit::pOHCounter; 78 79 /** @brief Increment POHCounter if Chassis Power state is ON */ 80 void startPOHCounter(); 81 82 private: 83 /** @brief Determine initial chassis state and set internally */ 84 void determineInitialState(); 85 86 /** 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(); 94 95 /** @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); 103 104 /** 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); 115 116 /** @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); 125 126 /** @brief Persistent sdbusplus DBus connection. */ 127 sdbusplus::bus::bus& bus; 128 129 /** @brief Used to subscribe to dbus systemd signals **/ 130 sdbusplus::bus::match_t systemdSignals; 131 132 /** @brief Used to Set value of POHCounter */ 133 uint32_t pOHCounter(uint32_t value) override; 134 135 /** @brief Used by the timer to update the POHCounter */ 136 void pOHCallback(); 137 138 /** @brief Used to restore POHCounter value from persisted file */ 139 void restorePOHCounter(); 140 141 /** @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 149 serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH)); 150 151 /** @brief Deserialize a persisted requested POH counter. 152 * 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 */ 159 bool deserializePOH(const fs::path& path, uint32_t& retCounter); 160 161 /** @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 190 /** @brief Timer used for tracking power on hours */ 191 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pOHTimer; 192 }; 193 194 } // namespace manager 195 } // namespace state 196 } // namespace phosphor 197