| #include "psm_handler.hpp" |
| |
| #include "log.hpp" |
| |
| #include <fmt/printf.h> |
| |
| #include <variant> |
| |
| namespace boot_time_monitor |
| { |
| namespace psm |
| { |
| |
| namespace btm = boot_time_monitor; |
| |
| using BasicVariantType = |
| std::variant<std::vector<std::string>, std::string, int64_t, uint64_t, |
| double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>; |
| |
| std::string inline translateHostStateName(std::string_view state) |
| { |
| std::size_t found = state.find_last_of('.'); |
| return std::string("HostState:") + std::string(state.substr(found + 1)); |
| } |
| |
| std::string inline translateOSStatus(std::string_view status) |
| { |
| std::size_t found = status.find_last_of('.'); |
| return std::string("OSStatus:") + std::string(status.substr(found + 1)); |
| } |
| |
| Handler::Handler(sdbusplus::bus::bus& bus, const btm::NodeConfig& nodeConfig, |
| const btm::psm::PSMConfig& psmConfig, |
| std::shared_ptr<btm::api::IBoottimeApi> api) : |
| mNodeConfig(nodeConfig), mApi(std::move(api)) |
| { |
| // Initialize mPreHostState |
| auto method = |
| bus.new_method_call(psmConfig.hostStateDbusService.c_str(), // Service |
| psmConfig.hostStateDbusObjPath.c_str(), // Path |
| "org.freedesktop.DBus.Properties", // Iface |
| "Get"); // Function |
| method.append("xyz.openbmc_project.State.Host", "CurrentHostState"); |
| BasicVariantType result; |
| try |
| { |
| bus.call(method).read(result); |
| mPreHostState = std::get<std::string>(result); |
| fmt::print("[{}] Get `CurrentHostState` success. value={}\n", |
| __FUNCTION__, mPreHostState); |
| } |
| catch (const sdbusplus::exception::SdBusError& e) |
| { |
| fmt::print(stderr, "[{}] Failed to get `CurrentHostState`. ERROR={}\n", |
| __FUNCTION__, e.what()); |
| fmt::print( |
| stderr, |
| "[{}] Initialized `mPreHostState` to empty string as default value\n", |
| __FUNCTION__); |
| } |
| |
| hostStateWatcher = std::make_unique<sdbusplus::bus::match::match>( |
| bus, |
| sdbusplus::bus::match::rules::propertiesChanged( |
| psmConfig.hostStateDbusObjPath, "xyz.openbmc_project.State.Host"), |
| [this](sdbusplus::message::message& message) { |
| std::string objectName; |
| boost::container::flat_map< |
| std::string, |
| std::variant<std::string, bool, int64_t, uint64_t, double>> |
| values; |
| message.read(objectName, values); |
| |
| auto findState = values.find("CurrentHostState"); |
| if (findState != values.end()) |
| { |
| const std::string curHostState = |
| std::get<std::string>(findState->second); |
| fmt::print( |
| stderr, |
| "[hostStateWatcher] CurrentHostState has changed from {} to {}\n", |
| mPreHostState, curHostState); |
| absl::Status status = mApi->SetNodeCheckpoint( |
| mNodeConfig, translateHostStateName(curHostState), 0, 0); |
| btm::log::LogIfError(status); |
| mPreHostState = curHostState; |
| } |
| }); |
| |
| // Initialize mPreOSState |
| method = |
| bus.new_method_call(psmConfig.osStateDbusService.c_str(), // Service |
| psmConfig.osStateDbusObjPath.c_str(), // Path |
| "org.freedesktop.DBus.Properties", // Iface |
| "Get"); // Function |
| method.append("xyz.openbmc_project.State.OperatingSystem.Status", |
| "OperatingSystemState"); |
| try |
| { |
| bus.call(method).read(result); |
| mPreOSState = std::get<std::string>(result); |
| fmt::print("[{}] Get `OperatingSystemState` success. value={}\n", |
| __FUNCTION__, mPreOSState); |
| } |
| catch (const sdbusplus::exception::SdBusError& e) |
| { |
| fmt::print(stderr, |
| "[{}] Failed to get `OperatingSystemState`. ERROR={}\n", |
| __FUNCTION__, e.what()); |
| fmt::print( |
| stderr, |
| "[{}] Initialized `mPreOSState` to empty string as default value\n", |
| __FUNCTION__); |
| } |
| |
| osStatusWatcher = std::make_unique<sdbusplus::bus::match::match>( |
| bus, |
| sdbusplus::bus::match::rules::propertiesChanged( |
| psmConfig.osStateDbusObjPath, |
| "xyz.openbmc_project.State.OperatingSystem.Status"), |
| [this](sdbusplus::message::message& message) { |
| std::string objectName; |
| boost::container::flat_map< |
| std::string, |
| std::variant<std::string, bool, int64_t, uint64_t, double>> |
| values; |
| message.read(objectName, values); |
| |
| auto findState = values.find("OperatingSystemState"); |
| if (findState != values.end()) |
| { |
| const std::string curOSStatus = |
| std::get<std::string>(findState->second); |
| |
| fmt::print( |
| stderr, |
| "[osStatusWatcher] curOSStatus has changed from {} to {}\n", |
| mPreOSState, curOSStatus); |
| absl::Status status = mApi->SetNodeCheckpoint( |
| mNodeConfig, translateOSStatus(curOSStatus), 0, 0); |
| btm::log::LogIfError(status); |
| mPreOSState = curOSStatus; |
| } |
| }); |
| } |
| } // namespace psm |
| } // namespace boot_time_monitor |