blob: d50d4f324c25525cc04558b5e55db118eaaa5ce9 [file] [log] [blame]
Josh D. Kingbdd9cb72016-12-19 11:13:43 -06001#pragma once
2
Andrew Geissler928bbf12023-02-14 13:30:14 -06003#include "utils.hpp"
Josh D. Kingbdd9cb72016-12-19 11:13:43 -06004#include "xyz/openbmc_project/State/BMC/server.hpp"
5
Tim Lee2bfb1ef2021-03-17 09:50:35 +08006#include <linux/watchdog.h>
Willy Tu564eb4f2023-09-07 16:02:46 -07007#include <sys/sysinfo.h>
Tim Lee2bfb1ef2021-03-17 09:50:35 +08008
Andrew Geisslere426b582020-05-28 12:40:55 -05009#include <sdbusplus/bus.hpp>
10
Willy Tu564eb4f2023-09-07 16:02:46 -070011#include <cassert>
12#include <chrono>
13
Josh D. Kingbdd9cb72016-12-19 11:13:43 -060014namespace phosphor
15{
16namespace state
17{
18namespace manager
19{
20
Patrick Williamsf053e6f2022-07-22 19:26:54 -050021using BMCInherit = sdbusplus::server::object_t<
Patrick Williams7e969cb2023-08-23 16:24:23 -050022 sdbusplus::server::xyz::openbmc_project::state::BMC>;
Patrick Williamsd32f8182017-05-05 15:55:24 -050023namespace sdbusRule = sdbusplus::bus::match::rules;
24
Josh D. Kingbdd9cb72016-12-19 11:13:43 -060025/** @class BMC
26 * @brief OpenBMC BMC state management implementation.
27 * @details A concrete implementation for xyz.openbmc_project.State.BMC
28 * DBus API.
29 */
Patrick Williamsd32f8182017-05-05 15:55:24 -050030class BMC : public BMCInherit
Josh D. Kingbdd9cb72016-12-19 11:13:43 -060031{
Andrew Geissler58a18012018-01-19 19:36:05 -080032 public:
33 /** @brief Constructs BMC State Manager
34 *
35 * @param[in] bus - The Dbus bus object
36 * @param[in] busName - The Dbus name to own
37 * @param[in] objPath - The Dbus object path
38 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -050039 BMC(sdbusplus::bus_t& bus, const char* objPath) :
Patrick Williams76070742022-04-05 15:20:12 -050040 BMCInherit(bus, objPath, BMCInherit::action::defer_emit), bus(bus),
Andrew Geissler58a18012018-01-19 19:36:05 -080041 stateSignal(std::make_unique<decltype(stateSignal)::element_type>(
42 bus,
43 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
44 sdbusRule::path("/org/freedesktop/systemd1") +
45 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
William A. Kennington IIIbd28f022022-11-22 17:11:49 -080046 [this](sdbusplus::message_t& m) { bmcStateChange(m); }))
Andrew Geissler58a18012018-01-19 19:36:05 -080047 {
Andrew Geissler928bbf12023-02-14 13:30:14 -060048 utils::subscribeToSystemdSignals(bus);
Andrew Geissler58a18012018-01-19 19:36:05 -080049 discoverInitialState();
Tim Lee2bfb1ef2021-03-17 09:50:35 +080050 discoverLastRebootCause();
Willy Tu564eb4f2023-09-07 16:02:46 -070051
52 using namespace std::chrono;
53 struct sysinfo info;
54
55 auto rc = sysinfo(&info);
56 assert(rc == 0);
57 // Since uptime is in seconds, also get the current time in seconds.
58 auto now = time_point_cast<seconds>(system_clock::now());
59 auto rebootTimeTs = now - seconds(info.uptime);
60 rebootTime =
61 duration_cast<milliseconds>(rebootTimeTs.time_since_epoch())
62 .count();
63
Andrew Geissler58a18012018-01-19 19:36:05 -080064 this->emit_object_added();
65 };
Josh D. King6db38222016-12-19 14:52:40 -060066
Andrew Geissler58a18012018-01-19 19:36:05 -080067 /** @brief Set value of BMCTransition **/
68 Transition requestedBMCTransition(Transition value) override;
Josh D. King6db38222016-12-19 14:52:40 -060069
Andrew Geissler58a18012018-01-19 19:36:05 -080070 /** @brief Set value of CurrentBMCState **/
71 BMCState currentBMCState(BMCState value) override;
Josh D. King6db38222016-12-19 14:52:40 -060072
Matt Spinlere6710b72018-07-12 16:05:55 -050073 /** @brief Returns the last time the BMC was rebooted
74 *
75 * @details Uses uptime information to determine when
76 * the BMC was last rebooted.
77 *
78 * @return uint64_t - Epoch time, in milliseconds, of the
79 * last reboot.
80 */
81 uint64_t lastRebootTime() const override;
82
Tim Lee2bfb1ef2021-03-17 09:50:35 +080083 /** @brief Set value of LastRebootCause **/
84 RebootCause lastRebootCause(RebootCause value) override;
85
Andrew Geissler58a18012018-01-19 19:36:05 -080086 private:
87 /**
Andrew Geissler2774c782022-02-17 16:57:14 -060088 * @brief Retrieve input systemd unit state
89 **/
90 std::string getUnitState(const std::string& unitToCheck);
91 /**
Andrew Geissler58a18012018-01-19 19:36:05 -080092 * @brief discover the state of the bmc
93 **/
94 void discoverInitialState();
Josh D. Kingd3e58472017-02-02 11:09:11 -060095
Andrew Geissler58a18012018-01-19 19:36:05 -080096 /** @brief Execute the transition request
97 *
98 * @param[in] tranReq - Transition requested
99 */
100 void executeTransition(Transition tranReq);
Josh D. King5162a7b2016-12-19 16:15:00 -0600101
Andrew Geissler58a18012018-01-19 19:36:05 -0800102 /** @brief Callback function on bmc state change
103 *
104 * Check if the state is relevant to the BMC and if so, update
105 * corresponding BMC object's state
106 *
107 * @param[in] msg - Data associated with subscribed signal
108 *
109 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500110 int bmcStateChange(sdbusplus::message_t& msg);
Josh D. Kingd613b812016-12-19 16:47:45 -0600111
Andrew Geissler58a18012018-01-19 19:36:05 -0800112 /** @brief Persistent sdbusplus DBus bus connection. **/
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500113 sdbusplus::bus_t& bus;
Josh D. King6db38222016-12-19 14:52:40 -0600114
Andrew Geissler58a18012018-01-19 19:36:05 -0800115 /** @brief Used to subscribe to dbus system state changes **/
116 std::unique_ptr<sdbusplus::bus::match_t> stateSignal;
Tim Lee2bfb1ef2021-03-17 09:50:35 +0800117
118 /**
119 * @brief discover the last reboot cause of the bmc
120 **/
121 void discoverLastRebootCause();
Willy Tu564eb4f2023-09-07 16:02:46 -0700122
123 /**
124 * @brief the lastRebootTime calcuated at startup.
125 **/
126 uint64_t rebootTime;
Josh D. Kingbdd9cb72016-12-19 11:13:43 -0600127};
128
129} // namespace manager
130} // namespace state
131} // namespace phosphor