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