1a90a31a9SAndrew Geissler #pragma once
2a90a31a9SAndrew Geissler 
3d998f82bSWilliam A. Kennington III #include <chrono>
48f8ba39fSPatrick Williams #include <functional>
5cb781fe1SNagaraju Goruganti #include <experimental/filesystem>
6cb781fe1SNagaraju Goruganti #include <cereal/cereal.hpp>
7a90a31a9SAndrew Geissler #include <sdbusplus/bus.hpp>
8d998f82bSWilliam A. Kennington III #include <sdeventplus/clock.hpp>
9d998f82bSWilliam A. Kennington III #include <sdeventplus/event.hpp>
10d998f82bSWilliam A. Kennington III #include <sdeventplus/utility/timer.hpp>
11a90a31a9SAndrew Geissler #include "xyz/openbmc_project/State/Chassis/server.hpp"
12cb781fe1SNagaraju Goruganti #include "xyz/openbmc_project/State/PowerOnHours/server.hpp"
13cb781fe1SNagaraju Goruganti #include "config.h"
14a90a31a9SAndrew Geissler 
15a90a31a9SAndrew Geissler namespace phosphor
16a90a31a9SAndrew Geissler {
17a90a31a9SAndrew Geissler namespace state
18a90a31a9SAndrew Geissler {
19a90a31a9SAndrew Geissler namespace manager
20a90a31a9SAndrew Geissler {
21a90a31a9SAndrew Geissler 
228f8ba39fSPatrick Williams using ChassisInherit = sdbusplus::server::object::object<
23cb781fe1SNagaraju Goruganti     sdbusplus::xyz::openbmc_project::State::server::Chassis,
24cb781fe1SNagaraju Goruganti     sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
258f8ba39fSPatrick Williams namespace sdbusRule = sdbusplus::bus::match::rules;
26cb781fe1SNagaraju Goruganti namespace fs = std::experimental::filesystem;
278f8ba39fSPatrick Williams 
28a90a31a9SAndrew Geissler /** @class Chassis
29a90a31a9SAndrew Geissler  *  @brief OpenBMC chassis state management implementation.
30a90a31a9SAndrew Geissler  *  @details A concrete implementation for xyz.openbmc_project.State.Chassis
31a90a31a9SAndrew Geissler  *  DBus API.
32a90a31a9SAndrew Geissler  */
338f8ba39fSPatrick Williams class Chassis : public ChassisInherit
34a90a31a9SAndrew Geissler {
35a90a31a9SAndrew Geissler   public:
36a90a31a9SAndrew Geissler     /** @brief Constructs Chassis State Manager
37a90a31a9SAndrew Geissler      *
38dff50ed6SAndrew Geissler      * @note This constructor passes 'true' to the base class in order to
39dff50ed6SAndrew Geissler      *       defer dbus object registration until we can run
40dff50ed6SAndrew Geissler      *       determineInitialState() and set our properties
41dff50ed6SAndrew Geissler      *
42a90a31a9SAndrew Geissler      * @param[in] bus       - The Dbus bus object
43a90a31a9SAndrew Geissler      * @param[in] objPath   - The Dbus object path
44a90a31a9SAndrew Geissler      */
45*769a62f1SAndrew Geissler     Chassis(sdbusplus::bus::bus& bus, const char* objPath) :
46*769a62f1SAndrew Geissler         ChassisInherit(bus, objPath, true), bus(bus),
4758a18013SAndrew Geissler         systemdSignals(
4858a18013SAndrew Geissler             bus,
4958a18013SAndrew Geissler             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
508f8ba39fSPatrick Williams                 sdbusRule::path("/org/freedesktop/systemd1") +
5158a18013SAndrew Geissler                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
5258a18013SAndrew Geissler             std::bind(std::mem_fn(&Chassis::sysStateChange), this,
53d998f82bSWilliam A. Kennington III                       std::placeholders::_1)),
54d998f82bSWilliam A. Kennington III         pOHTimer(sdeventplus::Event::get_default(),
55d998f82bSWilliam A. Kennington III                  std::bind(&Chassis::pOHCallback, this), std::chrono::hours{1},
56d998f82bSWilliam A. Kennington III                  std::chrono::minutes{1})
57dff50ed6SAndrew Geissler     {
580029a5d2SAndrew Geissler         subscribeToSystemdSignals();
590029a5d2SAndrew Geissler 
609eab9861SMatt Spinler         restoreChassisStateChangeTime();
619eab9861SMatt Spinler 
62dff50ed6SAndrew Geissler         determineInitialState();
63dff50ed6SAndrew Geissler 
64cb781fe1SNagaraju Goruganti         restorePOHCounter(); // restore POHCounter from persisted file
65cb781fe1SNagaraju Goruganti 
66dff50ed6SAndrew Geissler         // We deferred this until we could get our property correct
67dff50ed6SAndrew Geissler         this->emit_object_added();
68dff50ed6SAndrew Geissler     }
69dff50ed6SAndrew Geissler 
70a90a31a9SAndrew Geissler     /** @brief Set value of RequestedPowerTransition */
71a90a31a9SAndrew Geissler     Transition requestedPowerTransition(Transition value) override;
72a90a31a9SAndrew Geissler 
73a90a31a9SAndrew Geissler     /** @brief Set value of CurrentPowerState */
74a90a31a9SAndrew Geissler     PowerState currentPowerState(PowerState value) override;
75a90a31a9SAndrew Geissler 
76cb781fe1SNagaraju Goruganti     /** @brief Get value of POHCounter */
77cb781fe1SNagaraju Goruganti     using ChassisInherit::pOHCounter;
78cb781fe1SNagaraju Goruganti 
79cb781fe1SNagaraju Goruganti     /** @brief Increment POHCounter if Chassis Power state is ON */
80cb781fe1SNagaraju Goruganti     void startPOHCounter();
81cb781fe1SNagaraju Goruganti 
82a90a31a9SAndrew Geissler   private:
830029a5d2SAndrew Geissler     /** @brief Determine initial chassis state and set internally */
840029a5d2SAndrew Geissler     void determineInitialState();
850029a5d2SAndrew Geissler 
860029a5d2SAndrew Geissler     /**
870029a5d2SAndrew Geissler      * @brief subscribe to the systemd signals
880029a5d2SAndrew Geissler      *
890029a5d2SAndrew Geissler      * This object needs to capture when it's systemd targets complete
900029a5d2SAndrew Geissler      * so it can keep it's state updated
910029a5d2SAndrew Geissler      *
920029a5d2SAndrew Geissler      **/
930029a5d2SAndrew Geissler     void subscribeToSystemdSignals();
940029a5d2SAndrew Geissler 
95ce80f24cSAndrew Geissler     /** @brief Execute the transition request
96ce80f24cSAndrew Geissler      *
97ce80f24cSAndrew Geissler      * This function calls the appropriate systemd target for the input
98ce80f24cSAndrew Geissler      * transition.
99ce80f24cSAndrew Geissler      *
100ce80f24cSAndrew Geissler      * @param[in] tranReq    - Transition requested
101ce80f24cSAndrew Geissler      */
102ce80f24cSAndrew Geissler     void executeTransition(Transition tranReq);
103ce80f24cSAndrew Geissler 
104697474c5SJosh D. King     /**
105697474c5SJosh D. King      * @brief Determine if target is active
106697474c5SJosh D. King      *
107697474c5SJosh D. King      * This function determines if the target is active and
108697474c5SJosh D. King      * helps prevent misleading log recorded states.
109697474c5SJosh D. King      *
110697474c5SJosh D. King      * @param[in] target - Target string to check on
111697474c5SJosh D. King      *
112697474c5SJosh D. King      * @return boolean corresponding to state active
113697474c5SJosh D. King      **/
114697474c5SJosh D. King     bool stateActive(const std::string& target);
115697474c5SJosh D. King 
1160029a5d2SAndrew Geissler     /** @brief Check if systemd state change is relevant to this object
1172ec3a7e9SAndrew Geissler      *
1180029a5d2SAndrew Geissler      * Instance specific interface to handle the detected systemd state
1190029a5d2SAndrew Geissler      * change
1202ec3a7e9SAndrew Geissler      *
1212ec3a7e9SAndrew Geissler      * @param[in]  msg       - Data associated with subscribed signal
1222ec3a7e9SAndrew Geissler      *
1232ec3a7e9SAndrew Geissler      */
1248f8ba39fSPatrick Williams     int sysStateChange(sdbusplus::message::message& msg);
1252ec3a7e9SAndrew Geissler 
126a90a31a9SAndrew Geissler     /** @brief Persistent sdbusplus DBus connection. */
127a90a31a9SAndrew Geissler     sdbusplus::bus::bus& bus;
1282ec3a7e9SAndrew Geissler 
1290029a5d2SAndrew Geissler     /** @brief Used to subscribe to dbus systemd signals **/
1308f8ba39fSPatrick Williams     sdbusplus::bus::match_t systemdSignals;
131cb781fe1SNagaraju Goruganti 
132cb781fe1SNagaraju Goruganti     /** @brief Used to Set value of POHCounter */
133cb781fe1SNagaraju Goruganti     uint32_t pOHCounter(uint32_t value) override;
134cb781fe1SNagaraju Goruganti 
135d998f82bSWilliam A. Kennington III     /** @brief Used by the timer to update the POHCounter */
136d998f82bSWilliam A. Kennington III     void pOHCallback();
137d998f82bSWilliam A. Kennington III 
138cb781fe1SNagaraju Goruganti     /** @brief Used to restore POHCounter value from persisted file */
139cb781fe1SNagaraju Goruganti     void restorePOHCounter();
140cb781fe1SNagaraju Goruganti 
141cb781fe1SNagaraju Goruganti     /** @brief Serialize and persist requested POH counter.
142cb781fe1SNagaraju Goruganti      *
143cb781fe1SNagaraju Goruganti      *  @param[in] dir - pathname of file where the serialized POH counter will
144cb781fe1SNagaraju Goruganti      *                   be placed.
145cb781fe1SNagaraju Goruganti      *
146cb781fe1SNagaraju Goruganti      *  @return fs::path - pathname of persisted requested POH counter.
147cb781fe1SNagaraju Goruganti      */
148cb781fe1SNagaraju Goruganti     fs::path
14981957841SMatt Spinler         serializePOH(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
150cb781fe1SNagaraju Goruganti 
15181957841SMatt Spinler     /** @brief Deserialize a persisted requested POH counter.
152cb781fe1SNagaraju Goruganti      *
153cb781fe1SNagaraju Goruganti      *  @param[in] path - pathname of persisted POH counter file
154cb781fe1SNagaraju Goruganti      *  @param[in] retCounter - deserialized POH counter value
155cb781fe1SNagaraju Goruganti      *
156cb781fe1SNagaraju Goruganti      *  @return bool - true if the deserialization was successful, false
157cb781fe1SNagaraju Goruganti      *                 otherwise.
158cb781fe1SNagaraju Goruganti      */
15981957841SMatt Spinler     bool deserializePOH(const fs::path& path, uint32_t& retCounter);
160cb781fe1SNagaraju Goruganti 
1619eab9861SMatt Spinler     /** @brief Sets the LastStateChangeTime property and persists it. */
1629eab9861SMatt Spinler     void setStateChangeTime();
1639eab9861SMatt Spinler 
1649eab9861SMatt Spinler     /** @brief Serialize the last power state change time.
1659eab9861SMatt Spinler      *
1669eab9861SMatt Spinler      *  Save the time the state changed and the state itself.
1679eab9861SMatt Spinler      *  The state needs to be saved as well so that during rediscovery
1689eab9861SMatt Spinler      *  on reboots there's a way to know not to update the time again.
1699eab9861SMatt Spinler      */
1709eab9861SMatt Spinler     void serializeStateChangeTime();
1719eab9861SMatt Spinler 
1729eab9861SMatt Spinler     /** @brief Deserialize the last power state change time.
1739eab9861SMatt Spinler      *
1749eab9861SMatt Spinler      *  @param[out] time - Deserialized time
1759eab9861SMatt Spinler      *  @param[out] state - Deserialized power state
1769eab9861SMatt Spinler      *
1779eab9861SMatt Spinler      *  @return bool - true if successful, false otherwise.
1789eab9861SMatt Spinler      */
1799eab9861SMatt Spinler     bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
1809eab9861SMatt Spinler 
1819eab9861SMatt Spinler     /** @brief Restores the power state change time.
1829eab9861SMatt Spinler      *
1839eab9861SMatt Spinler      *  The time is loaded into the LastStateChangeTime D-Bus property.
1849eab9861SMatt Spinler      *  On the very first start after this code has been applied but
1859eab9861SMatt Spinler      *  before the state has changed, the LastStateChangeTime value
1869eab9861SMatt Spinler      *  will be zero.
1879eab9861SMatt Spinler      */
1889eab9861SMatt Spinler     void restoreChassisStateChangeTime();
1899eab9861SMatt Spinler 
190d998f82bSWilliam A. Kennington III     /** @brief Timer used for tracking power on hours */
191d998f82bSWilliam A. Kennington III     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pOHTimer;
192a90a31a9SAndrew Geissler };
193a90a31a9SAndrew Geissler 
194a90a31a9SAndrew Geissler } // namespace manager
195a90a31a9SAndrew Geissler } // namespace state
196a90a31a9SAndrew Geissler } // namespace phosphor
197