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, true), 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 discover the state of the bmc
74      **/
75     void discoverInitialState();
76 
77     /**
78      * @brief subscribe to the systemd signals
79      **/
80     void subscribeToSystemdSignals();
81 
82     /** @brief Execute the transition request
83      *
84      *  @param[in] tranReq   - Transition requested
85      */
86     void executeTransition(Transition tranReq);
87 
88     /** @brief Callback function on bmc state change
89      *
90      * Check if the state is relevant to the BMC and if so, update
91      * corresponding BMC object's state
92      *
93      * @param[in]  msg       - Data associated with subscribed signal
94      *
95      */
96     int bmcStateChange(sdbusplus::message::message& msg);
97 
98     /** @brief Persistent sdbusplus DBus bus connection. **/
99     sdbusplus::bus::bus& bus;
100 
101     /** @brief Used to subscribe to dbus system state changes **/
102     std::unique_ptr<sdbusplus::bus::match_t> stateSignal;
103 
104     /**
105      * @brief discover the last reboot cause of the bmc
106      **/
107     void discoverLastRebootCause();
108 };
109 
110 } // namespace manager
111 } // namespace state
112 } // namespace phosphor
113