diff options
Diffstat (limited to 'chassis_state_manager.cpp')
-rw-r--r-- | chassis_state_manager.cpp | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/chassis_state_manager.cpp b/chassis_state_manager.cpp index ece0b1c..d78a6f7 100644 --- a/chassis_state_manager.cpp +++ b/chassis_state_manager.cpp @@ -1,6 +1,15 @@ #include <sdbusplus/bus.hpp> #include <phosphor-logging/log.hpp> +#include <phosphor-logging/elog-errors.hpp> +#include "xyz/openbmc_project/Common/error.hpp" #include "chassis_state_manager.hpp" +#include <cereal/archives/json.hpp> +#include <fstream> +#include "config.h" +#include <experimental/filesystem> + +// Register class version with Cereal +CEREAL_CLASS_VERSION(phosphor::state::manager::Chassis, CLASS_VERSION); namespace phosphor { @@ -181,10 +190,127 @@ Chassis::Transition Chassis::requestedPowerTransition(Transition value) Chassis::PowerState Chassis::currentPowerState(PowerState value) { + PowerState chassisPowerState; log<level::INFO>("Change to Chassis Power State", entry("CHASSIS_CURRENT_POWER_STATE=%s", convertForMessage(value).c_str())); - return server::Chassis::currentPowerState(value); + + chassisPowerState = server::Chassis::currentPowerState(value); + if (chassisPowerState == PowerState::On) + { + timer->state(timer::ON); + } + else + { + timer->state(timer::OFF); + } + return chassisPowerState; +} + +uint32_t Chassis::pOHCounter(uint32_t value) +{ + if (value != pOHCounter()) + { + ChassisInherit::pOHCounter(value); + serialize(); + } + return pOHCounter(); +} + +void Chassis::restorePOHCounter() +{ + uint32_t counter; + if (!deserialize(POH_COUNTER_PERSIST_PATH, counter)) + { + // set to default value + pOHCounter(0); + } + else + { + pOHCounter(counter); + } +} + +fs::path Chassis::serialize(const fs::path& path) +{ + std::ofstream os(path.c_str(), std::ios::binary); + cereal::JSONOutputArchive oarchive(os); + oarchive(pOHCounter()); + return path; +} + +bool Chassis::deserialize(const fs::path& path, uint32_t& pOHCounter) +{ + try + { + if (fs::exists(path)) + { + std::ifstream is(path.c_str(), std::ios::in | std::ios::binary); + cereal::JSONInputArchive iarchive(is); + iarchive(pOHCounter); + return true; + } + return false; + } + catch (cereal::Exception& e) + { + log<level::ERR>(e.what()); + fs::remove(path); + return false; + } + catch (const fs::filesystem_error& e) + { + return false; + } + + return false; +} + +void Chassis::startPOHCounter() +{ + using namespace std::chrono_literals; + using namespace phosphor::logging; + using namespace sdbusplus::xyz::openbmc_project::Common::Error; + + auto dir = fs::path(POH_COUNTER_PERSIST_PATH).parent_path(); + fs::create_directories(dir); + + sd_event* event = nullptr; + auto r = sd_event_default(&event); + if (r < 0) + { + log<level::ERR>("Error creating a default sd_event handler"); + throw; + } + + phosphor::state::manager::EventPtr eventP{event}; + event = nullptr; + + auto callback = [&]() { + if (ChassisInherit::currentPowerState() == PowerState::On) + { + pOHCounter(pOHCounter() + 1); + } + }; + + try + { + timer = std::make_unique<phosphor::state::manager::Timer>( + eventP, callback, std::chrono::seconds(POH::hour), + phosphor::state::manager::timer::ON); + bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL); + r = sd_event_loop(eventP.get()); + if (r < 0) + { + log<level::ERR>("Error occurred during the sd_event_loop", + entry("RC=%d", r)); + elog<InternalFailure>(); + } + } + catch (InternalFailure& e) + { + phosphor::logging::commit<InternalFailure>(); + } } } // namespace manager |