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