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