| #include "LeakDetectionManager.hpp" |
| |
| #include "LeakGPIODetector.hpp" |
| |
| #include <phosphor-logging/lg2.hpp> |
| #include <sdbusplus/async.hpp> |
| #include <sdbusplus/message/native_types.hpp> |
| #include <sdbusplus/server/manager.hpp> |
| |
| #include <exception> |
| #include <functional> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| PHOSPHOR_LOG2_USING; |
| |
| namespace leak |
| { |
| |
| DetectionManager::DetectionManager(sdbusplus::async::context& ctx) : |
| ctx(ctx), leakEvents(ctx), |
| entityManager( |
| ctx, {GPIODetectorConfigIntf::interface}, |
| std::bind_front(&DetectionManager::processInventoryAdded, this), |
| std::bind_front(&DetectionManager::processInventoryRemoved, this)) |
| { |
| ctx.spawn(entityManager.handleInventoryGet()); |
| } |
| |
| auto DetectionManager::processInventoryAdded( |
| const sdbusplus::message::object_path& objectPath, |
| const std::string& /*unused*/) -> void |
| { |
| ctx.spawn(processConfigAddedAsync(objectPath)); |
| } |
| |
| auto DetectionManager::processInventoryRemoved( |
| const sdbusplus::message::object_path& objectPath, |
| const std::string& /*unused*/) -> void |
| { |
| if (!detectors.contains(objectPath.str)) |
| { |
| return; |
| } |
| debug("Removed detector {DETECTOR}", "DETECTOR", objectPath); |
| detectors.erase(objectPath.str); |
| } |
| |
| auto DetectionManager::processConfigAddedAsync( |
| sdbusplus::message::object_path objectPath) -> sdbusplus::async::task<> |
| { |
| auto res = co_await getDetectorConfig(objectPath); |
| if (!res) |
| { |
| co_return; |
| } |
| auto config = res.value(); |
| |
| if (detectors.contains(objectPath.str)) |
| { |
| warning("Detector {DETECTOR} already exist", "DETECTOR", config.name); |
| co_return; |
| } |
| |
| try |
| { |
| detectors[objectPath.str] = |
| std::make_unique<GPIODetector>(ctx, leakEvents, config); |
| } |
| catch (std::exception& e) |
| { |
| error("Failed to create detector {DETECTOR}: {ERROR}", "DETECTOR", |
| config.name, "ERROR", e.what()); |
| } |
| |
| co_return; |
| } |
| |
| auto DetectionManager::getDetectorConfig( |
| sdbusplus::message::object_path objectPath) |
| -> sdbusplus::async::task<std::optional<config::DetectorConfig>> |
| { |
| config::DetectorConfig config = {}; |
| |
| auto properties = |
| co_await GPIODetectorConfigIntf(ctx) |
| .service(entity_manager::EntityManagerInterface::serviceName) |
| .path(objectPath.str) |
| .properties(); |
| |
| config.name = properties.name; |
| |
| for (const auto& [key, value] : config::validDetectorTypes) |
| { |
| if (properties.type == key) |
| { |
| config.type = value; |
| break; |
| } |
| } |
| |
| config.pinName = properties.pin_name; |
| |
| for (const auto& [key, value] : config::validPinPolarity) |
| { |
| if (properties.polarity == key) |
| { |
| config.polarity = value; |
| break; |
| } |
| } |
| if (config.polarity == config::PinPolarity::unknown) |
| { |
| error("Invalid polarity {POLARITY} for {NAME}", "POLARITY", |
| properties.polarity, "NAME", config.name); |
| co_return std::nullopt; |
| } |
| |
| for (const auto& [key, value] : config::validDetectorLevel) |
| { |
| if (properties.level == key) |
| { |
| config.level = value; |
| break; |
| } |
| } |
| if (config.level == config::DetectorLevel::unknown) |
| { |
| error("Invalid level {LEVEL} for {NAME}", "LEVEL", properties.level, |
| "NAME", config.name); |
| co_return std::nullopt; |
| } |
| |
| debug("Detector config: {NAME} {PIN_NAME} {POLARITY} {LEVEL}", "NAME", |
| config.name, "PIN_NAME", config.pinName, "POLARITY", config.polarity, |
| "LEVEL", config.level); |
| |
| co_return config; |
| } |
| |
| } // namespace leak |
| |
| int main() |
| { |
| constexpr auto path = leak::DetectorIntf::namespace_path::value; |
| constexpr auto serviceName = "xyz.openbmc_project.leakdetector"; |
| sdbusplus::async::context ctx; |
| sdbusplus::server::manager_t manager{ctx, path}; |
| |
| info("Creating leak detection manager at {PATH}", "PATH", path); |
| leak::DetectionManager leakDetectionManager{ctx}; |
| |
| ctx.request_name(serviceName); |
| |
| ctx.run(); |
| return 0; |
| } |