blob: 5348f5f4214ab8ecbb9e8b1276f46c2a6cf47f64 [file] [log] [blame]
Jagpal Singh Gill15dde862024-10-16 09:42:54 -07001#include "LeakDetectionManager.hpp"
2
3#include "LeakGPIODetector.hpp"
4
5#include <phosphor-logging/lg2.hpp>
6#include <sdbusplus/async.hpp>
7#include <sdbusplus/message/native_types.hpp>
8#include <sdbusplus/server/manager.hpp>
9
10#include <exception>
11#include <functional>
12#include <memory>
13#include <optional>
14#include <string>
15
16PHOSPHOR_LOG2_USING;
17
18namespace leak
19{
20
21DetectionManager::DetectionManager(sdbusplus::async::context& ctx) :
22 ctx(ctx), leakEvents(ctx),
23 entityManager(
24 ctx, {GPIODetectorConfigIntf::interface},
25 std::bind_front(&DetectionManager::processInventoryAdded, this),
26 std::bind_front(&DetectionManager::processInventoryRemoved, this))
27{
28 ctx.spawn(entityManager.handleInventoryGet());
29}
30
31auto DetectionManager::processInventoryAdded(
32 const sdbusplus::message::object_path& objectPath,
33 const std::string& /*unused*/) -> void
34{
35 ctx.spawn(processConfigAddedAsync(objectPath));
36}
37
38auto DetectionManager::processInventoryRemoved(
39 const sdbusplus::message::object_path& objectPath,
40 const std::string& /*unused*/) -> void
41{
42 if (!detectors.contains(objectPath.str))
43 {
44 return;
45 }
46 debug("Removed detector {DETECTOR}", "DETECTOR", objectPath);
47 detectors.erase(objectPath.str);
48}
49
50auto DetectionManager::processConfigAddedAsync(
51 sdbusplus::message::object_path objectPath) -> sdbusplus::async::task<>
52{
53 auto res = co_await getDetectorConfig(objectPath);
54 if (!res)
55 {
56 co_return;
57 }
58 auto config = res.value();
59
60 if (detectors.contains(objectPath.str))
61 {
62 warning("Detector {DETECTOR} already exist", "DETECTOR", config.name);
63 co_return;
64 }
65
66 try
67 {
68 detectors[objectPath.str] =
69 std::make_unique<GPIODetector>(ctx, leakEvents, config);
70 }
71 catch (std::exception& e)
72 {
73 error("Failed to create detector {DETECTOR}: {ERROR}", "DETECTOR",
74 config.name, "ERROR", e.what());
75 }
76
77 co_return;
78}
79
80auto DetectionManager::getDetectorConfig(
81 sdbusplus::message::object_path objectPath)
82 -> sdbusplus::async::task<std::optional<config::DetectorConfig>>
83{
84 config::DetectorConfig config = {};
85
86 auto properties =
87 co_await GPIODetectorConfigIntf(ctx)
88 .service(entity_manager::EntityManagerInterface::serviceName)
89 .path(objectPath.str)
90 .properties();
91
92 config.name = properties.name;
93
94 for (const auto& [key, value] : config::validDetectorTypes)
95 {
96 if (properties.type == key)
97 {
98 config.type = value;
99 break;
100 }
101 }
102
103 config.pinName = properties.pin_name;
104
105 for (const auto& [key, value] : config::validPinPolarity)
106 {
107 if (properties.polarity == key)
108 {
109 config.polarity = value;
110 break;
111 }
112 }
113 if (config.polarity == config::PinPolarity::unknown)
114 {
115 error("Invalid polarity {POLARITY} for {NAME}", "POLARITY",
116 properties.polarity, "NAME", config.name);
117 co_return std::nullopt;
118 }
119
120 for (const auto& [key, value] : config::validDetectorLevel)
121 {
122 if (properties.level == key)
123 {
124 config.level = value;
125 break;
126 }
127 }
128 if (config.level == config::DetectorLevel::unknown)
129 {
130 error("Invalid level {LEVEL} for {NAME}", "LEVEL", properties.level,
131 "NAME", config.name);
132 co_return std::nullopt;
133 }
134
135 debug("Detector config: {NAME} {PIN_NAME} {POLARITY} {LEVEL}", "NAME",
136 config.name, "PIN_NAME", config.pinName, "POLARITY", config.polarity,
137 "LEVEL", config.level);
138
139 co_return config;
140}
141
142} // namespace leak
143
144int main()
145{
146 constexpr auto path = leak::DetectorIntf::namespace_path::value;
147 constexpr auto serviceName = "xyz.openbmc_project.leakdetector";
148 sdbusplus::async::context ctx;
149 sdbusplus::server::manager_t manager{ctx, path};
150
151 info("Creating leak detection manager at {PATH}", "PATH", path);
152 leak::DetectionManager leakDetectionManager{ctx};
153
154 ctx.request_name(serviceName);
155
156 ctx.run();
157 return 0;
158}