1 #pragma once
2 
3 #include "xyz/openbmc_project/State/BMC/server.hpp"
4 
5 #include <linux/watchdog.h>
6 
7 #include <sdbusplus/bus.hpp>
8 
9 namespace phosphor
10 {
11 namespace state
12 {
13 namespace manager
14 {
15 
16 using BMCInherit = sdbusplus::server::object_t<
17     sdbusplus::xyz::openbmc_project::State::server::BMC>;
18 namespace sdbusRule = sdbusplus::bus::match::rules;
19 
20 /** @class BMC
21  *  @brief OpenBMC BMC state management implementation.
22  *  @details A concrete implementation for xyz.openbmc_project.State.BMC
23  *  DBus API.
24  */
25 class BMC : public BMCInherit
26 {
27   public:
28     /** @brief Constructs BMC State Manager
29      *
30      * @param[in] bus       - The Dbus bus object
31      * @param[in] busName   - The Dbus name to own
32      * @param[in] objPath   - The Dbus object path
33      */
34     BMC(sdbusplus::bus_t& bus, const char* objPath) :
35         BMCInherit(bus, objPath, BMCInherit::action::defer_emit), bus(bus),
36         stateSignal(std::make_unique<decltype(stateSignal)::element_type>(
37             bus,
38             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
39                 sdbusRule::path("/org/freedesktop/systemd1") +
40                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
41             [this](sdbusplus::message_t& m) { bmcStateChange(m); }))
42     {
43         subscribeToSystemdSignals();
44         discoverInitialState();
45         discoverLastRebootCause();
46         this->emit_object_added();
47     };
48 
49     /** @brief Set value of BMCTransition **/
50     Transition requestedBMCTransition(Transition value) override;
51 
52     /** @brief Set value of CurrentBMCState **/
53     BMCState currentBMCState(BMCState value) override;
54 
55     /** @brief Returns the last time the BMC was rebooted
56      *
57      *  @details Uses uptime information to determine when
58      *           the BMC was last rebooted.
59      *
60      *  @return uint64_t - Epoch time, in milliseconds, of the
61      *                     last reboot.
62      */
63     uint64_t lastRebootTime() const override;
64 
65     /** @brief Set value of LastRebootCause **/
66     RebootCause lastRebootCause(RebootCause value) override;
67 
68   private:
69     /**
70      * @brief Retrieve input systemd unit state
71      **/
72     std::string getUnitState(const std::string& unitToCheck);
73     /**
74      * @brief discover the state of the bmc
75      **/
76     void discoverInitialState();
77 
78     /**
79      * @brief subscribe to the systemd signals
80      **/
81     void subscribeToSystemdSignals();
82 
83     /** @brief Execute the transition request
84      *
85      *  @param[in] tranReq   - Transition requested
86      */
87     void executeTransition(Transition tranReq);
88 
89     /** @brief Callback function on bmc state change
90      *
91      * Check if the state is relevant to the BMC and if so, update
92      * corresponding BMC object's state
93      *
94      * @param[in]  msg       - Data associated with subscribed signal
95      *
96      */
97     int bmcStateChange(sdbusplus::message_t& msg);
98 
99     /** @brief Persistent sdbusplus DBus bus connection. **/
100     sdbusplus::bus_t& bus;
101 
102     /** @brief Used to subscribe to dbus system state changes **/
103     std::unique_ptr<sdbusplus::bus::match_t> stateSignal;
104 
105     /**
106      * @brief discover the last reboot cause of the bmc
107      **/
108     void discoverLastRebootCause();
109 };
110 
111 } // namespace manager
112 } // namespace state
113 } // namespace phosphor
114