blob: 7ffa67b523f9295c7be93ce7b0425c45ebf66f61 [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"),
Willy Tubd1eebd2023-10-05 12:14:20 -070046 [this](sdbusplus::message_t& m) { bmcStateChange(m); })),
47
48 timeSyncSignal(std::make_unique<decltype(timeSyncSignal)::element_type>(
49 bus,
50 sdbusRule::propertiesChanged(
51 "/org/freedesktop/systemd1/unit/time_2dsync_2etarget",
52 "org.freedesktop.systemd1.Unit"),
53 [this](sdbusplus::message_t& m) {
54 std::string interface;
55 std::unordered_map<std::string, std::variant<std::string>>
56 propertyChanged;
57 m.read(interface, propertyChanged);
58
59 for (const auto& [key, value] : propertyChanged)
60 {
61 if (key == "ActiveState" &&
62 std::holds_alternative<std::string>(value) &&
63 std::get<std::string>(value) == "active")
64 {
65 updateLastRebootTime();
66 timeSyncSignal.reset();
67 }
68 }
69 }))
Andrew Geissler58a18012018-01-19 19:36:05 -080070 {
Andrew Geissler928bbf12023-02-14 13:30:14 -060071 utils::subscribeToSystemdSignals(bus);
Andrew Geissler58a18012018-01-19 19:36:05 -080072 discoverInitialState();
Tim Lee2bfb1ef2021-03-17 09:50:35 +080073 discoverLastRebootCause();
Willy Tubd1eebd2023-10-05 12:14:20 -070074 updateLastRebootTime();
Willy Tu564eb4f2023-09-07 16:02:46 -070075
Andrew Geissler58a18012018-01-19 19:36:05 -080076 this->emit_object_added();
77 };
Josh D. King6db38222016-12-19 14:52:40 -060078
Andrew Geissler58a18012018-01-19 19:36:05 -080079 /** @brief Set value of BMCTransition **/
80 Transition requestedBMCTransition(Transition value) override;
Josh D. King6db38222016-12-19 14:52:40 -060081
Andrew Geissler58a18012018-01-19 19:36:05 -080082 /** @brief Set value of CurrentBMCState **/
83 BMCState currentBMCState(BMCState value) override;
Josh D. King6db38222016-12-19 14:52:40 -060084
Matt Spinlere6710b72018-07-12 16:05:55 -050085 /** @brief Returns the last time the BMC was rebooted
86 *
87 * @details Uses uptime information to determine when
88 * the BMC was last rebooted.
89 *
90 * @return uint64_t - Epoch time, in milliseconds, of the
91 * last reboot.
92 */
93 uint64_t lastRebootTime() const override;
94
Tim Lee2bfb1ef2021-03-17 09:50:35 +080095 /** @brief Set value of LastRebootCause **/
96 RebootCause lastRebootCause(RebootCause value) override;
97
Andrew Geissler58a18012018-01-19 19:36:05 -080098 private:
99 /**
Andrew Geissler2774c782022-02-17 16:57:14 -0600100 * @brief Retrieve input systemd unit state
101 **/
102 std::string getUnitState(const std::string& unitToCheck);
103 /**
Andrew Geissler58a18012018-01-19 19:36:05 -0800104 * @brief discover the state of the bmc
105 **/
106 void discoverInitialState();
Josh D. Kingd3e58472017-02-02 11:09:11 -0600107
Andrew Geissler58a18012018-01-19 19:36:05 -0800108 /** @brief Execute the transition request
109 *
110 * @param[in] tranReq - Transition requested
111 */
112 void executeTransition(Transition tranReq);
Josh D. King5162a7b2016-12-19 16:15:00 -0600113
Andrew Geissler58a18012018-01-19 19:36:05 -0800114 /** @brief Callback function on bmc state change
115 *
116 * Check if the state is relevant to the BMC and if so, update
117 * corresponding BMC object's state
118 *
119 * @param[in] msg - Data associated with subscribed signal
120 *
121 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500122 int bmcStateChange(sdbusplus::message_t& msg);
Josh D. Kingd613b812016-12-19 16:47:45 -0600123
Andrew Geissler58a18012018-01-19 19:36:05 -0800124 /** @brief Persistent sdbusplus DBus bus connection. **/
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500125 sdbusplus::bus_t& bus;
Josh D. King6db38222016-12-19 14:52:40 -0600126
Andrew Geissler58a18012018-01-19 19:36:05 -0800127 /** @brief Used to subscribe to dbus system state changes **/
128 std::unique_ptr<sdbusplus::bus::match_t> stateSignal;
Tim Lee2bfb1ef2021-03-17 09:50:35 +0800129
Willy Tubd1eebd2023-10-05 12:14:20 -0700130 /** @brief Used to subscribe to timesync **/
131 std::unique_ptr<sdbusplus::bus::match_t> timeSyncSignal;
132
Tim Lee2bfb1ef2021-03-17 09:50:35 +0800133 /**
134 * @brief discover the last reboot cause of the bmc
135 **/
136 void discoverLastRebootCause();
Willy Tu564eb4f2023-09-07 16:02:46 -0700137
138 /**
Willy Tubd1eebd2023-10-05 12:14:20 -0700139 * @brief update the last reboot time of the bmc
140 **/
141 void updateLastRebootTime();
142
143 /**
Willy Tu564eb4f2023-09-07 16:02:46 -0700144 * @brief the lastRebootTime calcuated at startup.
145 **/
146 uint64_t rebootTime;
Josh D. Kingbdd9cb72016-12-19 11:13:43 -0600147};
148
149} // namespace manager
150} // namespace state
151} // namespace phosphor