1a90a31a9SAndrew Geissler #pragma once
2a90a31a9SAndrew Geissler 
38f8ba39fSPatrick Williams #include <functional>
4*cb781fe1SNagaraju Goruganti #include <experimental/filesystem>
5*cb781fe1SNagaraju Goruganti #include <cereal/cereal.hpp>
6a90a31a9SAndrew Geissler #include <sdbusplus/bus.hpp>
7a90a31a9SAndrew Geissler #include "xyz/openbmc_project/State/Chassis/server.hpp"
8*cb781fe1SNagaraju Goruganti #include "xyz/openbmc_project/State/PowerOnHours/server.hpp"
9*cb781fe1SNagaraju Goruganti #include "config.h"
10*cb781fe1SNagaraju Goruganti #include "timer.hpp"
11a90a31a9SAndrew Geissler 
12a90a31a9SAndrew Geissler namespace phosphor
13a90a31a9SAndrew Geissler {
14a90a31a9SAndrew Geissler namespace state
15a90a31a9SAndrew Geissler {
16a90a31a9SAndrew Geissler namespace manager
17a90a31a9SAndrew Geissler {
18*cb781fe1SNagaraju Goruganti namespace POH
19*cb781fe1SNagaraju Goruganti {
20*cb781fe1SNagaraju Goruganti 
21*cb781fe1SNagaraju Goruganti using namespace std::chrono_literals;
22*cb781fe1SNagaraju Goruganti constexpr auto hour = 3600s; // seconds Per Hour
23*cb781fe1SNagaraju Goruganti 
24*cb781fe1SNagaraju Goruganti } // namespace  POH
25a90a31a9SAndrew Geissler 
268f8ba39fSPatrick Williams using ChassisInherit = sdbusplus::server::object::object<
27*cb781fe1SNagaraju Goruganti     sdbusplus::xyz::openbmc_project::State::server::Chassis,
28*cb781fe1SNagaraju Goruganti     sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
298f8ba39fSPatrick Williams namespace sdbusRule = sdbusplus::bus::match::rules;
30*cb781fe1SNagaraju Goruganti namespace fs = std::experimental::filesystem;
318f8ba39fSPatrick Williams 
32a90a31a9SAndrew Geissler /** @class Chassis
33a90a31a9SAndrew Geissler  *  @brief OpenBMC chassis state management implementation.
34a90a31a9SAndrew Geissler  *  @details A concrete implementation for xyz.openbmc_project.State.Chassis
35a90a31a9SAndrew Geissler  *  DBus API.
36a90a31a9SAndrew Geissler  */
378f8ba39fSPatrick Williams class Chassis : public ChassisInherit
38a90a31a9SAndrew Geissler {
39a90a31a9SAndrew Geissler   public:
40a90a31a9SAndrew Geissler     /** @brief Constructs Chassis State Manager
41a90a31a9SAndrew Geissler      *
42dff50ed6SAndrew Geissler      * @note This constructor passes 'true' to the base class in order to
43dff50ed6SAndrew Geissler      *       defer dbus object registration until we can run
44dff50ed6SAndrew Geissler      *       determineInitialState() and set our properties
45dff50ed6SAndrew Geissler      *
46a90a31a9SAndrew Geissler      * @param[in] bus       - The Dbus bus object
47dff50ed6SAndrew Geissler      * @param[in] instance  - The instance of this object
48a90a31a9SAndrew Geissler      * @param[in] objPath   - The Dbus object path
49a90a31a9SAndrew Geissler      */
5058a18013SAndrew Geissler     Chassis(sdbusplus::bus::bus& bus, const char* busName,
51a90a31a9SAndrew Geissler             const char* objPath) :
528f8ba39fSPatrick Williams         ChassisInherit(bus, objPath, true),
532ec3a7e9SAndrew Geissler         bus(bus),
5458a18013SAndrew Geissler         systemdSignals(
5558a18013SAndrew Geissler             bus,
5658a18013SAndrew Geissler             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
578f8ba39fSPatrick Williams                 sdbusRule::path("/org/freedesktop/systemd1") +
5858a18013SAndrew Geissler                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
5958a18013SAndrew Geissler             std::bind(std::mem_fn(&Chassis::sysStateChange), this,
6058a18013SAndrew Geissler                       std::placeholders::_1))
61dff50ed6SAndrew Geissler     {
620029a5d2SAndrew Geissler         subscribeToSystemdSignals();
630029a5d2SAndrew Geissler 
64dff50ed6SAndrew Geissler         determineInitialState();
65dff50ed6SAndrew Geissler 
66*cb781fe1SNagaraju Goruganti         restorePOHCounter(); // restore POHCounter from persisted file
67*cb781fe1SNagaraju Goruganti 
68dff50ed6SAndrew Geissler         // We deferred this until we could get our property correct
69dff50ed6SAndrew Geissler         this->emit_object_added();
70dff50ed6SAndrew Geissler     }
71dff50ed6SAndrew Geissler 
72a90a31a9SAndrew Geissler     /** @brief Set value of RequestedPowerTransition */
73a90a31a9SAndrew Geissler     Transition requestedPowerTransition(Transition value) override;
74a90a31a9SAndrew Geissler 
75a90a31a9SAndrew Geissler     /** @brief Set value of CurrentPowerState */
76a90a31a9SAndrew Geissler     PowerState currentPowerState(PowerState value) override;
77a90a31a9SAndrew Geissler 
78*cb781fe1SNagaraju Goruganti     /** @brief Get value of POHCounter */
79*cb781fe1SNagaraju Goruganti     using ChassisInherit::pOHCounter;
80*cb781fe1SNagaraju Goruganti 
81*cb781fe1SNagaraju Goruganti     /** @brief Increment POHCounter if Chassis Power state is ON */
82*cb781fe1SNagaraju Goruganti     void startPOHCounter();
83*cb781fe1SNagaraju Goruganti 
84a90a31a9SAndrew Geissler   private:
850029a5d2SAndrew Geissler     /** @brief Determine initial chassis state and set internally */
860029a5d2SAndrew Geissler     void determineInitialState();
870029a5d2SAndrew Geissler 
880029a5d2SAndrew Geissler     /**
890029a5d2SAndrew Geissler      * @brief subscribe to the systemd signals
900029a5d2SAndrew Geissler      *
910029a5d2SAndrew Geissler      * This object needs to capture when it's systemd targets complete
920029a5d2SAndrew Geissler      * so it can keep it's state updated
930029a5d2SAndrew Geissler      *
940029a5d2SAndrew Geissler      **/
950029a5d2SAndrew Geissler     void subscribeToSystemdSignals();
960029a5d2SAndrew Geissler 
97ce80f24cSAndrew Geissler     /** @brief Execute the transition request
98ce80f24cSAndrew Geissler      *
99ce80f24cSAndrew Geissler      * This function calls the appropriate systemd target for the input
100ce80f24cSAndrew Geissler      * transition.
101ce80f24cSAndrew Geissler      *
102ce80f24cSAndrew Geissler      * @param[in] tranReq    - Transition requested
103ce80f24cSAndrew Geissler      */
104ce80f24cSAndrew Geissler     void executeTransition(Transition tranReq);
105ce80f24cSAndrew Geissler 
106697474c5SJosh D. King     /**
107697474c5SJosh D. King      * @brief Determine if target is active
108697474c5SJosh D. King      *
109697474c5SJosh D. King      * This function determines if the target is active and
110697474c5SJosh D. King      * helps prevent misleading log recorded states.
111697474c5SJosh D. King      *
112697474c5SJosh D. King      * @param[in] target - Target string to check on
113697474c5SJosh D. King      *
114697474c5SJosh D. King      * @return boolean corresponding to state active
115697474c5SJosh D. King      **/
116697474c5SJosh D. King     bool stateActive(const std::string& target);
117697474c5SJosh D. King 
1180029a5d2SAndrew Geissler     /** @brief Check if systemd state change is relevant to this object
1192ec3a7e9SAndrew Geissler      *
1200029a5d2SAndrew Geissler      * Instance specific interface to handle the detected systemd state
1210029a5d2SAndrew Geissler      * change
1222ec3a7e9SAndrew Geissler      *
1232ec3a7e9SAndrew Geissler      * @param[in]  msg       - Data associated with subscribed signal
1242ec3a7e9SAndrew Geissler      *
1252ec3a7e9SAndrew Geissler      */
1268f8ba39fSPatrick Williams     int sysStateChange(sdbusplus::message::message& msg);
1272ec3a7e9SAndrew Geissler 
128a90a31a9SAndrew Geissler     /** @brief Persistent sdbusplus DBus connection. */
129a90a31a9SAndrew Geissler     sdbusplus::bus::bus& bus;
1302ec3a7e9SAndrew Geissler 
1310029a5d2SAndrew Geissler     /** @brief Used to subscribe to dbus systemd signals **/
1328f8ba39fSPatrick Williams     sdbusplus::bus::match_t systemdSignals;
133*cb781fe1SNagaraju Goruganti 
134*cb781fe1SNagaraju Goruganti     /** @brief Used to Set value of POHCounter */
135*cb781fe1SNagaraju Goruganti     uint32_t pOHCounter(uint32_t value) override;
136*cb781fe1SNagaraju Goruganti 
137*cb781fe1SNagaraju Goruganti     /** @brief Used to restore POHCounter value from persisted file */
138*cb781fe1SNagaraju Goruganti     void restorePOHCounter();
139*cb781fe1SNagaraju Goruganti 
140*cb781fe1SNagaraju Goruganti     /** @brief Function required by Cereal to perform serialization.
141*cb781fe1SNagaraju Goruganti      *
142*cb781fe1SNagaraju Goruganti      *  @tparam Archive - Cereal archive type (json in our case).
143*cb781fe1SNagaraju Goruganti      *  @param[in] archive - reference to Cereal archive.
144*cb781fe1SNagaraju Goruganti      *  @param[in] version - Class version that enables handling
145*cb781fe1SNagaraju Goruganti      *                       a serialized data across code levels
146*cb781fe1SNagaraju Goruganti      */
147*cb781fe1SNagaraju Goruganti     template <class Archive>
148*cb781fe1SNagaraju Goruganti     inline void save(Archive& archive, const std::uint32_t version) const
149*cb781fe1SNagaraju Goruganti     {
150*cb781fe1SNagaraju Goruganti         archive(pOHCounter());
151*cb781fe1SNagaraju Goruganti     }
152*cb781fe1SNagaraju Goruganti 
153*cb781fe1SNagaraju Goruganti     /** @brief Function required by Cereal to perform deserialization.
154*cb781fe1SNagaraju Goruganti      *
155*cb781fe1SNagaraju Goruganti      *  @tparam Archive - Cereal archive type (json in our case).
156*cb781fe1SNagaraju Goruganti      *  @param[in] archive - reference to Cereal archive.
157*cb781fe1SNagaraju Goruganti      *  @param[in] version - Class version that enables handling
158*cb781fe1SNagaraju Goruganti      *                       a serialized data across code levels
159*cb781fe1SNagaraju Goruganti      */
160*cb781fe1SNagaraju Goruganti     template <class Archive>
161*cb781fe1SNagaraju Goruganti     inline void load(Archive& archive, const std::uint32_t version)
162*cb781fe1SNagaraju Goruganti     {
163*cb781fe1SNagaraju Goruganti         uint32_t value;
164*cb781fe1SNagaraju Goruganti         archive(value);
165*cb781fe1SNagaraju Goruganti         pOHCounter(value);
166*cb781fe1SNagaraju Goruganti     }
167*cb781fe1SNagaraju Goruganti 
168*cb781fe1SNagaraju Goruganti     /** @brief Serialize and persist requested POH counter.
169*cb781fe1SNagaraju Goruganti      *
170*cb781fe1SNagaraju Goruganti      *  @param[in] dir - pathname of file where the serialized POH counter will
171*cb781fe1SNagaraju Goruganti      *                   be placed.
172*cb781fe1SNagaraju Goruganti      *
173*cb781fe1SNagaraju Goruganti      *  @return fs::path - pathname of persisted requested POH counter.
174*cb781fe1SNagaraju Goruganti      */
175*cb781fe1SNagaraju Goruganti     fs::path
176*cb781fe1SNagaraju Goruganti         serialize(const fs::path& dir = fs::path(POH_COUNTER_PERSIST_PATH));
177*cb781fe1SNagaraju Goruganti 
178*cb781fe1SNagaraju Goruganti     /** @brief Deserialze a persisted requested POH counter.
179*cb781fe1SNagaraju Goruganti      *
180*cb781fe1SNagaraju Goruganti      *  @param[in] path - pathname of persisted POH counter file
181*cb781fe1SNagaraju Goruganti      *  @param[in] retCounter - deserialized POH counter value
182*cb781fe1SNagaraju Goruganti      *
183*cb781fe1SNagaraju Goruganti      *  @return bool - true if the deserialization was successful, false
184*cb781fe1SNagaraju Goruganti      *                 otherwise.
185*cb781fe1SNagaraju Goruganti      */
186*cb781fe1SNagaraju Goruganti     bool deserialize(const fs::path& path, uint32_t& retCounter);
187*cb781fe1SNagaraju Goruganti 
188*cb781fe1SNagaraju Goruganti     /** @brief Timer */
189*cb781fe1SNagaraju Goruganti     std::unique_ptr<phosphor::state::manager::Timer> timer;
190a90a31a9SAndrew Geissler };
191a90a31a9SAndrew Geissler 
192a90a31a9SAndrew Geissler } // namespace manager
193a90a31a9SAndrew Geissler } // namespace state
194a90a31a9SAndrew Geissler } // namespace phosphor
195