1bdd9cb71SJosh D. King #pragma once 2bdd9cb71SJosh D. King 3928bbf15SAndrew Geissler #include "utils.hpp" 4bdd9cb71SJosh D. King #include "xyz/openbmc_project/State/BMC/server.hpp" 5bdd9cb71SJosh D. King 62bfb1efcSTim Lee #include <linux/watchdog.h> 7564eb4faSWilly Tu #include <sys/sysinfo.h> 82bfb1efcSTim Lee 9e426b589SAndrew Geissler #include <sdbusplus/bus.hpp> 10e426b589SAndrew Geissler 11564eb4faSWilly Tu #include <cassert> 12564eb4faSWilly Tu #include <chrono> 13564eb4faSWilly Tu 14bdd9cb71SJosh D. King namespace phosphor 15bdd9cb71SJosh D. King { 16bdd9cb71SJosh D. King namespace state 17bdd9cb71SJosh D. King { 18bdd9cb71SJosh D. King namespace manager 19bdd9cb71SJosh D. King { 20bdd9cb71SJosh D. King 21f053e6feSPatrick Williams using BMCInherit = sdbusplus::server::object_t< 227e969cb9SPatrick Williams sdbusplus::server::xyz::openbmc_project::state::BMC>; 23d32f8181SPatrick Williams namespace sdbusRule = sdbusplus::bus::match::rules; 24d32f8181SPatrick Williams 25bdd9cb71SJosh D. King /** @class BMC 26bdd9cb71SJosh D. King * @brief OpenBMC BMC state management implementation. 27bdd9cb71SJosh D. King * @details A concrete implementation for xyz.openbmc_project.State.BMC 28bdd9cb71SJosh D. King * DBus API. 29bdd9cb71SJosh D. King */ 30d32f8181SPatrick Williams class BMC : public BMCInherit 31bdd9cb71SJosh D. King { 32bdd9cb71SJosh D. King public: 33bdd9cb71SJosh D. King /** @brief Constructs BMC State Manager 34bdd9cb71SJosh D. King * 35bdd9cb71SJosh D. King * @param[in] bus - The Dbus bus object 36bdd9cb71SJosh D. King * @param[in] busName - The Dbus name to own 37bdd9cb71SJosh D. King * @param[in] objPath - The Dbus object path 38bdd9cb71SJosh D. King */ BMC(sdbusplus::bus_t & bus,const char * objPath)39f053e6feSPatrick Williams BMC(sdbusplus::bus_t& bus, const char* objPath) : 4076070747SPatrick Williams BMCInherit(bus, objPath, BMCInherit::action::defer_emit), bus(bus), 4158a18013SAndrew Geissler stateSignal(std::make_unique<decltype(stateSignal)::element_type>( 42d613b816SJosh D. King bus, 4358a18013SAndrew Geissler sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 44d32f8181SPatrick Williams sdbusRule::path("/org/freedesktop/systemd1") + 4558a18013SAndrew Geissler sdbusRule::interface("org.freedesktop.systemd1.Manager"), 46bd1eebd9SWilly Tu [this](sdbusplus::message_t& m) { bmcStateChange(m); })), 47bd1eebd9SWilly Tu 48bd1eebd9SWilly Tu timeSyncSignal(std::make_unique<decltype(timeSyncSignal)::element_type>( 49bd1eebd9SWilly Tu bus, 50bd1eebd9SWilly Tu sdbusRule::propertiesChanged( 51bd1eebd9SWilly Tu "/org/freedesktop/systemd1/unit/time_2dsync_2etarget", 52bd1eebd9SWilly Tu "org.freedesktop.systemd1.Unit"), __anonbe750f0c0202(sdbusplus::message_t& m) 53bd1eebd9SWilly Tu [this](sdbusplus::message_t& m) { 54bd1eebd9SWilly Tu std::string interface; 55bd1eebd9SWilly Tu std::unordered_map<std::string, std::variant<std::string>> 56bd1eebd9SWilly Tu propertyChanged; 57bd1eebd9SWilly Tu m.read(interface, propertyChanged); 58bd1eebd9SWilly Tu 59bd1eebd9SWilly Tu for (const auto& [key, value] : propertyChanged) 60bd1eebd9SWilly Tu { 61bd1eebd9SWilly Tu if (key == "ActiveState" && 62bd1eebd9SWilly Tu std::holds_alternative<std::string>(value) && 63bd1eebd9SWilly Tu std::get<std::string>(value) == "active") 64bd1eebd9SWilly Tu { 65bd1eebd9SWilly Tu updateLastRebootTime(); 66bd1eebd9SWilly Tu timeSyncSignal.reset(); 67bd1eebd9SWilly Tu } 68bd1eebd9SWilly Tu } 69bd1eebd9SWilly Tu })) 706db3822dSJosh D. King { 71928bbf15SAndrew Geissler utils::subscribeToSystemdSignals(bus); 72d3e58474SJosh D. King discoverInitialState(); 732bfb1efcSTim Lee discoverLastRebootCause(); 74bd1eebd9SWilly Tu updateLastRebootTime(); 75564eb4faSWilly Tu 76d3e58474SJosh D. King this->emit_object_added(); 776db3822dSJosh D. King }; 786db3822dSJosh D. King 796db3822dSJosh D. King /** @brief Set value of BMCTransition **/ 806db3822dSJosh D. King Transition requestedBMCTransition(Transition value) override; 816db3822dSJosh D. King 82d613b816SJosh D. King /** @brief Set value of CurrentBMCState **/ 83d613b816SJosh D. King BMCState currentBMCState(BMCState value) override; 846db3822dSJosh D. King 85e6710b7eSMatt Spinler /** @brief Returns the last time the BMC was rebooted 86e6710b7eSMatt Spinler * 87e6710b7eSMatt Spinler * @details Uses uptime information to determine when 88e6710b7eSMatt Spinler * the BMC was last rebooted. 89e6710b7eSMatt Spinler * 90e6710b7eSMatt Spinler * @return uint64_t - Epoch time, in milliseconds, of the 91e6710b7eSMatt Spinler * last reboot. 92e6710b7eSMatt Spinler */ 93e6710b7eSMatt Spinler uint64_t lastRebootTime() const override; 94e6710b7eSMatt Spinler 952bfb1efcSTim Lee /** @brief Set value of LastRebootCause **/ 962bfb1efcSTim Lee RebootCause lastRebootCause(RebootCause value) override; 972bfb1efcSTim Lee 986db3822dSJosh D. King private: 996db3822dSJosh D. King /** 1002774c788SAndrew Geissler * @brief Retrieve input systemd unit state 1012774c788SAndrew Geissler **/ 1022774c788SAndrew Geissler std::string getUnitState(const std::string& unitToCheck); 1032774c788SAndrew Geissler /** 104d3e58474SJosh D. King * @brief discover the state of the bmc 105d3e58474SJosh D. King **/ 106d3e58474SJosh D. King void discoverInitialState(); 107d3e58474SJosh D. King 1085162a7b7SJosh D. King /** @brief Execute the transition request 1095162a7b7SJosh D. King * 1105162a7b7SJosh D. King * @param[in] tranReq - Transition requested 1115162a7b7SJosh D. King */ 1125162a7b7SJosh D. King void executeTransition(Transition tranReq); 1135162a7b7SJosh D. King 114d613b816SJosh D. King /** @brief Callback function on bmc state change 115d613b816SJosh D. King * 116d613b816SJosh D. King * Check if the state is relevant to the BMC and if so, update 117d613b816SJosh D. King * corresponding BMC object's state 118d613b816SJosh D. King * 119d613b816SJosh D. King * @param[in] msg - Data associated with subscribed signal 120d613b816SJosh D. King * 121d613b816SJosh D. King */ 122f053e6feSPatrick Williams int bmcStateChange(sdbusplus::message_t& msg); 123d613b816SJosh D. King 1246db3822dSJosh D. King /** @brief Persistent sdbusplus DBus bus connection. **/ 125f053e6feSPatrick Williams sdbusplus::bus_t& bus; 1266db3822dSJosh D. King 127d613b816SJosh D. King /** @brief Used to subscribe to dbus system state changes **/ 128d32f8181SPatrick Williams std::unique_ptr<sdbusplus::bus::match_t> stateSignal; 1292bfb1efcSTim Lee 130bd1eebd9SWilly Tu /** @brief Used to subscribe to timesync **/ 131bd1eebd9SWilly Tu std::unique_ptr<sdbusplus::bus::match_t> timeSyncSignal; 132bd1eebd9SWilly Tu 1332bfb1efcSTim Lee /** 1342bfb1efcSTim Lee * @brief discover the last reboot cause of the bmc 1352bfb1efcSTim Lee **/ 1362bfb1efcSTim Lee void discoverLastRebootCause(); 137564eb4faSWilly Tu 138564eb4faSWilly Tu /** 139bd1eebd9SWilly Tu * @brief update the last reboot time of the bmc 140bd1eebd9SWilly Tu **/ 141bd1eebd9SWilly Tu void updateLastRebootTime(); 142bd1eebd9SWilly Tu 143bd1eebd9SWilly Tu /** 144*3ff5a360SManojkiran Eda * @brief the lastRebootTime calculated at startup. 145564eb4faSWilly Tu **/ 146564eb4faSWilly Tu uint64_t rebootTime; 147bdd9cb71SJosh D. King }; 148bdd9cb71SJosh D. King 149bdd9cb71SJosh D. King } // namespace manager 150bdd9cb71SJosh D. King } // namespace state 151bdd9cb71SJosh D. King } // namespace phosphor 152