1a90a31a9SAndrew Geissler #pragma once 2a90a31a9SAndrew Geissler 3e426b589SAndrew Geissler #include "config.h" 4e426b589SAndrew Geissler 5e426b589SAndrew Geissler #include "xyz/openbmc_project/State/Chassis/server.hpp" 6e426b589SAndrew Geissler #include "xyz/openbmc_project/State/PowerOnHours/server.hpp" 7e426b589SAndrew Geissler 8cb781fe1SNagaraju Goruganti #include <cereal/cereal.hpp> 9a90a31a9SAndrew Geissler #include <sdbusplus/bus.hpp> 10d998f82bSWilliam A. Kennington III #include <sdeventplus/clock.hpp> 11d998f82bSWilliam A. Kennington III #include <sdeventplus/event.hpp> 12d998f82bSWilliam A. Kennington III #include <sdeventplus/utility/timer.hpp> 13e426b589SAndrew Geissler 14e426b589SAndrew Geissler #include <chrono> 15e426b589SAndrew Geissler #include <experimental/filesystem> 16e426b589SAndrew Geissler #include <functional> 17a90a31a9SAndrew Geissler 18a90a31a9SAndrew Geissler namespace phosphor 19a90a31a9SAndrew Geissler { 20a90a31a9SAndrew Geissler namespace state 21a90a31a9SAndrew Geissler { 22a90a31a9SAndrew Geissler namespace manager 23a90a31a9SAndrew Geissler { 24a90a31a9SAndrew Geissler 258f8ba39fSPatrick Williams using ChassisInherit = sdbusplus::server::object::object< 26cb781fe1SNagaraju Goruganti sdbusplus::xyz::openbmc_project::State::server::Chassis, 27cb781fe1SNagaraju Goruganti sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>; 288f8ba39fSPatrick Williams namespace sdbusRule = sdbusplus::bus::match::rules; 29cb781fe1SNagaraju Goruganti namespace fs = std::experimental::filesystem; 308f8ba39fSPatrick Williams 31a90a31a9SAndrew Geissler /** @class Chassis 32a90a31a9SAndrew Geissler * @brief OpenBMC chassis state management implementation. 33a90a31a9SAndrew Geissler * @details A concrete implementation for xyz.openbmc_project.State.Chassis 34a90a31a9SAndrew Geissler * DBus API. 35a90a31a9SAndrew Geissler */ 368f8ba39fSPatrick Williams class Chassis : public ChassisInherit 37a90a31a9SAndrew Geissler { 38a90a31a9SAndrew Geissler public: 39a90a31a9SAndrew Geissler /** @brief Constructs Chassis State Manager 40a90a31a9SAndrew Geissler * 41dff50ed6SAndrew Geissler * @note This constructor passes 'true' to the base class in order to 42dff50ed6SAndrew Geissler * defer dbus object registration until we can run 43dff50ed6SAndrew Geissler * determineInitialState() and set our properties 44dff50ed6SAndrew Geissler * 45a90a31a9SAndrew Geissler * @param[in] bus - The Dbus bus object 46a90a31a9SAndrew Geissler * @param[in] objPath - The Dbus object path 47*70f36d8eSPotin Lai * @param[in] id - Chassis id 48a90a31a9SAndrew Geissler */ 49*70f36d8eSPotin Lai Chassis(sdbusplus::bus::bus& bus, const char* objPath, size_t id) : 50769a62f1SAndrew Geissler ChassisInherit(bus, objPath, true), bus(bus), 5158a18013SAndrew Geissler systemdSignals( 5258a18013SAndrew Geissler bus, 5358a18013SAndrew Geissler sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 548f8ba39fSPatrick Williams sdbusRule::path("/org/freedesktop/systemd1") + 5558a18013SAndrew Geissler sdbusRule::interface("org.freedesktop.systemd1.Manager"), 5658a18013SAndrew Geissler std::bind(std::mem_fn(&Chassis::sysStateChange), this, 57d998f82bSWilliam A. Kennington III std::placeholders::_1)), 58*70f36d8eSPotin Lai id(id), pohTimer(sdeventplus::Event::get_default(), 59*70f36d8eSPotin Lai std::bind(&Chassis::pohCallback, this), 60*70f36d8eSPotin Lai std::chrono::hours{1}, std::chrono::minutes{1}) 61dff50ed6SAndrew Geissler { 620029a5d2SAndrew Geissler subscribeToSystemdSignals(); 630029a5d2SAndrew Geissler 64*70f36d8eSPotin Lai createSystemdTargetTable(); 65*70f36d8eSPotin Lai 669eab9861SMatt Spinler restoreChassisStateChangeTime(); 679eab9861SMatt Spinler 68dff50ed6SAndrew Geissler determineInitialState(); 69dff50ed6SAndrew Geissler 70cb781fe1SNagaraju Goruganti restorePOHCounter(); // restore POHCounter from persisted file 71cb781fe1SNagaraju Goruganti 72dff50ed6SAndrew Geissler // We deferred this until we could get our property correct 73dff50ed6SAndrew Geissler this->emit_object_added(); 74dff50ed6SAndrew Geissler } 75dff50ed6SAndrew Geissler 76a90a31a9SAndrew Geissler /** @brief Set value of RequestedPowerTransition */ 77a90a31a9SAndrew Geissler Transition requestedPowerTransition(Transition value) override; 78a90a31a9SAndrew Geissler 79a90a31a9SAndrew Geissler /** @brief Set value of CurrentPowerState */ 80a90a31a9SAndrew Geissler PowerState currentPowerState(PowerState value) override; 81a90a31a9SAndrew Geissler 82cb781fe1SNagaraju Goruganti /** @brief Get value of POHCounter */ 8345a1ed71SPatrick Williams using ChassisInherit::pohCounter; 84cb781fe1SNagaraju Goruganti 85cb781fe1SNagaraju Goruganti /** @brief Increment POHCounter if Chassis Power state is ON */ 86cb781fe1SNagaraju Goruganti void startPOHCounter(); 87cb781fe1SNagaraju Goruganti 88a90a31a9SAndrew Geissler private: 89*70f36d8eSPotin Lai /** @brief Create systemd target instance names and mapping table */ 90*70f36d8eSPotin Lai void createSystemdTargetTable(); 91*70f36d8eSPotin Lai 920029a5d2SAndrew Geissler /** @brief Determine initial chassis state and set internally */ 930029a5d2SAndrew Geissler void determineInitialState(); 940029a5d2SAndrew Geissler 958b1f8620SAndrew Geissler /** @brief Determine status of power into system */ 968b1f8620SAndrew Geissler void determineStatusOfPower(); 978b1f8620SAndrew Geissler 980029a5d2SAndrew Geissler /** 990029a5d2SAndrew Geissler * @brief subscribe to the systemd signals 1000029a5d2SAndrew Geissler * 1010029a5d2SAndrew Geissler * This object needs to capture when it's systemd targets complete 1020029a5d2SAndrew Geissler * so it can keep it's state updated 1030029a5d2SAndrew Geissler * 1040029a5d2SAndrew Geissler **/ 1050029a5d2SAndrew Geissler void subscribeToSystemdSignals(); 1060029a5d2SAndrew Geissler 107be6efabcSMatthew Barth /** @brief Start the systemd unit requested 108ce80f24cSAndrew Geissler * 109be6efabcSMatthew Barth * This function calls `StartUnit` on the systemd unit given. 110ce80f24cSAndrew Geissler * 111be6efabcSMatthew Barth * @param[in] sysdUnit - Systemd unit 112ce80f24cSAndrew Geissler */ 113be6efabcSMatthew Barth void startUnit(const std::string& sysdUnit); 114ce80f24cSAndrew Geissler 115697474c5SJosh D. King /** 116697474c5SJosh D. King * @brief Determine if target is active 117697474c5SJosh D. King * 118697474c5SJosh D. King * This function determines if the target is active and 119697474c5SJosh D. King * helps prevent misleading log recorded states. 120697474c5SJosh D. King * 121697474c5SJosh D. King * @param[in] target - Target string to check on 122697474c5SJosh D. King * 123697474c5SJosh D. King * @return boolean corresponding to state active 124697474c5SJosh D. King **/ 125697474c5SJosh D. King bool stateActive(const std::string& target); 126697474c5SJosh D. King 1270029a5d2SAndrew Geissler /** @brief Check if systemd state change is relevant to this object 1282ec3a7e9SAndrew Geissler * 1290029a5d2SAndrew Geissler * Instance specific interface to handle the detected systemd state 1300029a5d2SAndrew Geissler * change 1312ec3a7e9SAndrew Geissler * 1322ec3a7e9SAndrew Geissler * @param[in] msg - Data associated with subscribed signal 1332ec3a7e9SAndrew Geissler * 1342ec3a7e9SAndrew Geissler */ 1358f8ba39fSPatrick Williams int sysStateChange(sdbusplus::message::message& msg); 1362ec3a7e9SAndrew Geissler 137a90a31a9SAndrew Geissler /** @brief Persistent sdbusplus DBus connection. */ 138a90a31a9SAndrew Geissler sdbusplus::bus::bus& bus; 1392ec3a7e9SAndrew Geissler 1400029a5d2SAndrew Geissler /** @brief Used to subscribe to dbus systemd signals **/ 1418f8ba39fSPatrick Williams sdbusplus::bus::match_t systemdSignals; 142cb781fe1SNagaraju Goruganti 1432cf2a268SAndrew Geissler /** @brief Watch for any changes to UPS properties **/ 1442cf2a268SAndrew Geissler std::unique_ptr<sdbusplus::bus::match_t> uPowerPropChangeSignal; 1452cf2a268SAndrew Geissler 146*70f36d8eSPotin Lai /** @brief Chassis id. **/ 147*70f36d8eSPotin Lai const size_t id = 0; 148*70f36d8eSPotin Lai 149*70f36d8eSPotin Lai /** @brief Transition state to systemd target mapping table. **/ 150*70f36d8eSPotin Lai std::map<Transition, std::string> systemdTargetTable; 151*70f36d8eSPotin Lai 152cb781fe1SNagaraju Goruganti /** @brief Used to Set value of POHCounter */ 15345a1ed71SPatrick Williams uint32_t pohCounter(uint32_t value) override; 154cb781fe1SNagaraju Goruganti 155d998f82bSWilliam A. Kennington III /** @brief Used by the timer to update the POHCounter */ 15645a1ed71SPatrick Williams void pohCallback(); 157d998f82bSWilliam A. Kennington III 158cb781fe1SNagaraju Goruganti /** @brief Used to restore POHCounter value from persisted file */ 159cb781fe1SNagaraju Goruganti void restorePOHCounter(); 160cb781fe1SNagaraju Goruganti 161cb781fe1SNagaraju Goruganti /** @brief Serialize and persist requested POH counter. 162cb781fe1SNagaraju Goruganti * 163cb781fe1SNagaraju Goruganti * @param[in] dir - pathname of file where the serialized POH counter will 164cb781fe1SNagaraju Goruganti * be placed. 165cb781fe1SNagaraju Goruganti * 166cb781fe1SNagaraju Goruganti * @return fs::path - pathname of persisted requested POH counter. 167cb781fe1SNagaraju Goruganti */ 168cb781fe1SNagaraju Goruganti fs::path 16981957841SMatt Spinler serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH)); 170cb781fe1SNagaraju Goruganti 17181957841SMatt Spinler /** @brief Deserialize a persisted requested POH counter. 172cb781fe1SNagaraju Goruganti * 173cb781fe1SNagaraju Goruganti * @param[in] path - pathname of persisted POH counter file 174cb781fe1SNagaraju Goruganti * @param[in] retCounter - deserialized POH counter value 175cb781fe1SNagaraju Goruganti * 176cb781fe1SNagaraju Goruganti * @return bool - true if the deserialization was successful, false 177cb781fe1SNagaraju Goruganti * otherwise. 178cb781fe1SNagaraju Goruganti */ 17981957841SMatt Spinler bool deserializePOH(const fs::path& path, uint32_t& retCounter); 180cb781fe1SNagaraju Goruganti 1819eab9861SMatt Spinler /** @brief Sets the LastStateChangeTime property and persists it. */ 1829eab9861SMatt Spinler void setStateChangeTime(); 1839eab9861SMatt Spinler 1849eab9861SMatt Spinler /** @brief Serialize the last power state change time. 1859eab9861SMatt Spinler * 1869eab9861SMatt Spinler * Save the time the state changed and the state itself. 1879eab9861SMatt Spinler * The state needs to be saved as well so that during rediscovery 1889eab9861SMatt Spinler * on reboots there's a way to know not to update the time again. 1899eab9861SMatt Spinler */ 1909eab9861SMatt Spinler void serializeStateChangeTime(); 1919eab9861SMatt Spinler 1929eab9861SMatt Spinler /** @brief Deserialize the last power state change time. 1939eab9861SMatt Spinler * 1949eab9861SMatt Spinler * @param[out] time - Deserialized time 1959eab9861SMatt Spinler * @param[out] state - Deserialized power state 1969eab9861SMatt Spinler * 1979eab9861SMatt Spinler * @return bool - true if successful, false otherwise. 1989eab9861SMatt Spinler */ 1999eab9861SMatt Spinler bool deserializeStateChangeTime(uint64_t& time, PowerState& state); 2009eab9861SMatt Spinler 2019eab9861SMatt Spinler /** @brief Restores the power state change time. 2029eab9861SMatt Spinler * 2039eab9861SMatt Spinler * The time is loaded into the LastStateChangeTime D-Bus property. 2049eab9861SMatt Spinler * On the very first start after this code has been applied but 2059eab9861SMatt Spinler * before the state has changed, the LastStateChangeTime value 2069eab9861SMatt Spinler * will be zero. 2079eab9861SMatt Spinler */ 2089eab9861SMatt Spinler void restoreChassisStateChangeTime(); 2099eab9861SMatt Spinler 210d998f82bSWilliam A. Kennington III /** @brief Timer used for tracking power on hours */ 21145a1ed71SPatrick Williams sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer; 2122c36e5adSBen Tyner 2132c36e5adSBen Tyner /** @brief Function to check for a standby voltage regulator fault 2142c36e5adSBen Tyner * 2152c36e5adSBen Tyner * Determine if a standby voltage regulator fault was detected and 2162c36e5adSBen Tyner * return true or false accordingly. 2172c36e5adSBen Tyner * 2182c36e5adSBen Tyner * @return true if fault detected, else false 2192c36e5adSBen Tyner */ 2202c36e5adSBen Tyner bool standbyVoltageRegulatorFault(); 2212cf2a268SAndrew Geissler 2222cf2a268SAndrew Geissler /** @brief Process UPS property changes 2232cf2a268SAndrew Geissler * 2242cf2a268SAndrew Geissler * Instance specific interface to monitor for changes to the UPS 2252cf2a268SAndrew Geissler * properties which may impact CurrentPowerStatus 2262cf2a268SAndrew Geissler * 2272cf2a268SAndrew Geissler * @param[in] msg - Data associated with subscribed signal 2282cf2a268SAndrew Geissler * 2292cf2a268SAndrew Geissler */ 2302cf2a268SAndrew Geissler void uPowerChangeEvent(sdbusplus::message::message& msg); 231a90a31a9SAndrew Geissler }; 232a90a31a9SAndrew Geissler 233a90a31a9SAndrew Geissler } // namespace manager 234a90a31a9SAndrew Geissler } // namespace state 235a90a31a9SAndrew Geissler } // namespace phosphor 236