#include "config.h" #include "utils.hpp" #include #include #include #include #include namespace phosphor { namespace state { namespace manager { namespace utils { PHOSPHOR_LOG2_USING; constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"; std::string getService(sdbusplus::bus_t& bus, std::string path, std::string interface) { auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject"); mapper.append(path, std::vector({interface})); std::vector>> mapperResponse; try { auto mapperResponseMsg = bus.call(mapper); mapperResponseMsg.read(mapperResponse); if (mapperResponse.empty()) { error( "Error no matching service with path {PATH} and interface {INTERFACE}", "PATH", path, "INTERFACE", interface); throw std::runtime_error("Error no matching service"); } } catch (const sdbusplus::exception_t& e) { error("Error in mapper call with path {PATH}, interface " "{INTERFACE}, and exception {ERROR}", "PATH", path, "INTERFACE", interface, "ERROR", e); throw; } return mapperResponse.begin()->first; } std::string getProperty(sdbusplus::bus_t& bus, const std::string& path, const std::string& interface, const std::string& propertyName) { std::variant property; std::string service = getService(bus, path, interface); auto method = bus.new_method_call(service.c_str(), path.c_str(), PROPERTY_INTERFACE, "Get"); method.append(interface, propertyName); try { auto reply = bus.call(method); reply.read(property); } catch (const sdbusplus::exception_t& e) { error("Error in property Get, error {ERROR}, property {PROPERTY}", "ERROR", e, "PROPERTY", propertyName); throw; } if (std::get(property).empty()) { error("Error reading property response for {PROPERTY}", "PROPERTY", propertyName); throw std::runtime_error("Error reading property response"); } return std::get(property); } void setProperty(sdbusplus::bus_t& bus, const std::string& path, const std::string& interface, const std::string& property, const std::string& value) { std::variant variantValue = value; std::string service = getService(bus, path, interface); auto method = bus.new_method_call(service.c_str(), path.c_str(), PROPERTY_INTERFACE, "Set"); method.append(interface, property, variantValue); bus.call_noreply(method); return; } int getGpioValue(const std::string& gpioName) { int gpioval = -1; gpiod_line* line = gpiod_line_find(gpioName.c_str()); if (nullptr != line) { // take ownership of gpio if (0 != gpiod_line_request_input(line, "state-manager")) { error("Failed request for {GPIO_NAME} GPIO", "GPIO_NAME", gpioName); } else { // get gpio value gpioval = gpiod_line_get_value(line); // release ownership of gpio gpiod_line_close_chip(line); } } return gpioval; } void createError( sdbusplus::bus_t& bus, const std::string& errorMsg, sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level errLevel, std::map additionalData) { try { // Always add the _PID on for some extra logging debug additionalData.emplace("_PID", std::to_string(getpid())); auto method = bus.new_method_call( "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging", "xyz.openbmc_project.Logging.Create", "Create"); method.append(errorMsg, errLevel, additionalData); auto resp = bus.call(method); } catch (const sdbusplus::exception_t& e) { error("sdbusplus D-Bus call exception, error {ERROR} trying to create " "an error with {ERROR_MSG}", "ERROR", e, "ERROR_MSG", errorMsg); throw std::runtime_error( "Error in invoking D-Bus logging create interface"); } catch (const std::exception& e) { error("D-bus call exception: {ERROR}", "ERROR", e); throw e; } } void createBmcDump(sdbusplus::bus_t& bus) { auto method = bus.new_method_call( "xyz.openbmc_project.Dump.Manager", "/xyz/openbmc_project/dump/bmc", "xyz.openbmc_project.Dump.Create", "CreateDump"); method.append( std::vector< std::pair>>()); try { bus.call_noreply(method); } catch (const sdbusplus::exception_t& e) { error("Failed to create BMC dump, exception:{ERROR}", "ERROR", e); // just continue, this is error path anyway so we're just collecting // what we can } } bool checkACLoss(size_t& chassisId) { std::string chassisLostPowerFileFmt = fmt::sprintf(CHASSIS_LOST_POWER_FILE, chassisId); std::filesystem::path chassisPowerLossFile{chassisLostPowerFileFmt}; if (std::filesystem::exists(chassisPowerLossFile)) { return true; } return false; } } // namespace utils } // namespace manager } // namespace state } // namespace phosphor