xref: /openbmc/phosphor-modbus/rtu/device_manager.cpp (revision cad9ecf69472f03f9ece64eff5d2d94bc51bcf90)
1*cad9ecf6SJagpal Singh Gill #include "device_manager.hpp"
2*cad9ecf6SJagpal Singh Gill 
3*cad9ecf6SJagpal Singh Gill #include "port/port_factory.hpp"
4*cad9ecf6SJagpal Singh Gill 
5*cad9ecf6SJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
6*cad9ecf6SJagpal Singh Gill #include <sdbusplus/async.hpp>
7*cad9ecf6SJagpal Singh Gill #include <sdbusplus/server/manager.hpp>
8*cad9ecf6SJagpal Singh Gill #include <xyz/openbmc_project/Configuration/ModbusRTUDetect/client.hpp>
9*cad9ecf6SJagpal Singh Gill 
10*cad9ecf6SJagpal Singh Gill PHOSPHOR_LOG2_USING;
11*cad9ecf6SJagpal Singh Gill 
12*cad9ecf6SJagpal Singh Gill namespace phosphor::modbus::rtu
13*cad9ecf6SJagpal Singh Gill {
14*cad9ecf6SJagpal Singh Gill 
15*cad9ecf6SJagpal Singh Gill using ModbusRTUDetectIntf =
16*cad9ecf6SJagpal Singh Gill     sdbusplus::client::xyz::openbmc_project::configuration::ModbusRTUDetect<>;
17*cad9ecf6SJagpal Singh Gill 
18*cad9ecf6SJagpal Singh Gill static entity_manager::interface_list_t getInterfaces()
19*cad9ecf6SJagpal Singh Gill {
20*cad9ecf6SJagpal Singh Gill     entity_manager::interface_list_t interfaces;
21*cad9ecf6SJagpal Singh Gill 
22*cad9ecf6SJagpal Singh Gill     auto portInterfaces = PortIntf::PortFactory::getInterfaces();
23*cad9ecf6SJagpal Singh Gill     interfaces.insert(interfaces.end(), portInterfaces.begin(),
24*cad9ecf6SJagpal Singh Gill                       portInterfaces.end());
25*cad9ecf6SJagpal Singh Gill     interfaces.emplace_back(ModbusRTUDetectIntf::interface);
26*cad9ecf6SJagpal Singh Gill 
27*cad9ecf6SJagpal Singh Gill     return interfaces;
28*cad9ecf6SJagpal Singh Gill }
29*cad9ecf6SJagpal Singh Gill 
30*cad9ecf6SJagpal Singh Gill DeviceManager::DeviceManager(sdbusplus::async::context& ctx) :
31*cad9ecf6SJagpal Singh Gill     ctx(ctx),
32*cad9ecf6SJagpal Singh Gill     entityManager(ctx, getInterfaces(),
33*cad9ecf6SJagpal Singh Gill                   std::bind_front(&DeviceManager::processConfigAdded, this),
34*cad9ecf6SJagpal Singh Gill                   std::bind_front(&DeviceManager::processConfigRemoved, this))
35*cad9ecf6SJagpal Singh Gill {
36*cad9ecf6SJagpal Singh Gill     ctx.spawn(entityManager.handleInventoryGet());
37*cad9ecf6SJagpal Singh Gill     info("DeviceManager created successfully");
38*cad9ecf6SJagpal Singh Gill }
39*cad9ecf6SJagpal Singh Gill 
40*cad9ecf6SJagpal Singh Gill auto DeviceManager::processConfigAdded(
41*cad9ecf6SJagpal Singh Gill     const sdbusplus::message::object_path& objectPath,
42*cad9ecf6SJagpal Singh Gill     const std::string& interfaceName) -> sdbusplus::async::task<>
43*cad9ecf6SJagpal Singh Gill {
44*cad9ecf6SJagpal Singh Gill     debug("Config added for {PATH} with {INTF}", "PATH", objectPath, "INTF",
45*cad9ecf6SJagpal Singh Gill           interfaceName);
46*cad9ecf6SJagpal Singh Gill     if (interfaceName == ModbusRTUDetectIntf::interface && ports.size() == 0)
47*cad9ecf6SJagpal Singh Gill     {
48*cad9ecf6SJagpal Singh Gill         warning(
49*cad9ecf6SJagpal Singh Gill             "Skip processing ModbusRTUDetectIntf::interface as no serial ports detected yet");
50*cad9ecf6SJagpal Singh Gill         co_return;
51*cad9ecf6SJagpal Singh Gill     }
52*cad9ecf6SJagpal Singh Gill 
53*cad9ecf6SJagpal Singh Gill     auto portInterfaces = PortIntf::PortFactory::getInterfaces();
54*cad9ecf6SJagpal Singh Gill     if (std::find(portInterfaces.begin(), portInterfaces.end(),
55*cad9ecf6SJagpal Singh Gill                   interfaceName) != portInterfaces.end())
56*cad9ecf6SJagpal Singh Gill     {
57*cad9ecf6SJagpal Singh Gill         auto config = co_await PortIntf::PortFactory::getConfig(
58*cad9ecf6SJagpal Singh Gill             ctx, objectPath, interfaceName);
59*cad9ecf6SJagpal Singh Gill         if (!config)
60*cad9ecf6SJagpal Singh Gill         {
61*cad9ecf6SJagpal Singh Gill             error("Failed to get Port config for {PATH}", "PATH", objectPath);
62*cad9ecf6SJagpal Singh Gill             co_return;
63*cad9ecf6SJagpal Singh Gill         }
64*cad9ecf6SJagpal Singh Gill 
65*cad9ecf6SJagpal Singh Gill         try
66*cad9ecf6SJagpal Singh Gill         {
67*cad9ecf6SJagpal Singh Gill             ports[config->name] = PortIntf::PortFactory::create(ctx, *config);
68*cad9ecf6SJagpal Singh Gill         }
69*cad9ecf6SJagpal Singh Gill         catch (const std::exception& e)
70*cad9ecf6SJagpal Singh Gill         {
71*cad9ecf6SJagpal Singh Gill             error("Failed to create Port for {PATH} with {ERROR}", "PATH",
72*cad9ecf6SJagpal Singh Gill                   objectPath, "ERROR", e);
73*cad9ecf6SJagpal Singh Gill             co_return;
74*cad9ecf6SJagpal Singh Gill         }
75*cad9ecf6SJagpal Singh Gill     }
76*cad9ecf6SJagpal Singh Gill     else if (interfaceName == ModbusRTUDetectIntf::interface)
77*cad9ecf6SJagpal Singh Gill     {
78*cad9ecf6SJagpal Singh Gill         auto res = co_await InventoryIntf::config::getConfig(ctx, objectPath);
79*cad9ecf6SJagpal Singh Gill         if (!res)
80*cad9ecf6SJagpal Singh Gill         {
81*cad9ecf6SJagpal Singh Gill             error("Failed to get Inventory Device config for {PATH}", "PATH",
82*cad9ecf6SJagpal Singh Gill                   objectPath);
83*cad9ecf6SJagpal Singh Gill             co_return;
84*cad9ecf6SJagpal Singh Gill         }
85*cad9ecf6SJagpal Singh Gill         auto config = res.value();
86*cad9ecf6SJagpal Singh Gill         try
87*cad9ecf6SJagpal Singh Gill         {
88*cad9ecf6SJagpal Singh Gill             auto inventoryDevice =
89*cad9ecf6SJagpal Singh Gill                 std::make_unique<InventoryIntf::Device>(ctx, config, ports);
90*cad9ecf6SJagpal Singh Gill             ctx.spawn(inventoryDevice->probePorts());
91*cad9ecf6SJagpal Singh Gill             inventoryDevices[config.name] = std::move(inventoryDevice);
92*cad9ecf6SJagpal Singh Gill         }
93*cad9ecf6SJagpal Singh Gill         catch (const std::exception& e)
94*cad9ecf6SJagpal Singh Gill         {
95*cad9ecf6SJagpal Singh Gill             error("Failed to create Inventory Device for {PATH} with {ERROR}",
96*cad9ecf6SJagpal Singh Gill                   "PATH", objectPath, "ERROR", e);
97*cad9ecf6SJagpal Singh Gill             co_return;
98*cad9ecf6SJagpal Singh Gill         }
99*cad9ecf6SJagpal Singh Gill     }
100*cad9ecf6SJagpal Singh Gill }
101*cad9ecf6SJagpal Singh Gill 
102*cad9ecf6SJagpal Singh Gill auto DeviceManager::processConfigRemoved(
103*cad9ecf6SJagpal Singh Gill     const sdbusplus::message::object_path& /*unused*/,
104*cad9ecf6SJagpal Singh Gill     const std::string& /*unused*/) -> sdbusplus::async::task<>
105*cad9ecf6SJagpal Singh Gill {
106*cad9ecf6SJagpal Singh Gill     // TODO: Implement this
107*cad9ecf6SJagpal Singh Gill     co_return;
108*cad9ecf6SJagpal Singh Gill }
109*cad9ecf6SJagpal Singh Gill 
110*cad9ecf6SJagpal Singh Gill } // namespace phosphor::modbus::rtu
111*cad9ecf6SJagpal Singh Gill 
112*cad9ecf6SJagpal Singh Gill auto main() -> int
113*cad9ecf6SJagpal Singh Gill {
114*cad9ecf6SJagpal Singh Gill     constexpr auto path = "/xyz/openbmc_project";
115*cad9ecf6SJagpal Singh Gill     constexpr auto serviceName = "xyz.openbmc_project.ModbusRTU";
116*cad9ecf6SJagpal Singh Gill     sdbusplus::async::context ctx;
117*cad9ecf6SJagpal Singh Gill     sdbusplus::server::manager_t manager{ctx, path};
118*cad9ecf6SJagpal Singh Gill 
119*cad9ecf6SJagpal Singh Gill     info("Creating Modbus device manager at {PATH}", "PATH", path);
120*cad9ecf6SJagpal Singh Gill     phosphor::modbus::rtu::DeviceManager deviceManager{ctx};
121*cad9ecf6SJagpal Singh Gill 
122*cad9ecf6SJagpal Singh Gill     ctx.request_name(serviceName);
123*cad9ecf6SJagpal Singh Gill 
124*cad9ecf6SJagpal Singh Gill     ctx.run();
125*cad9ecf6SJagpal Singh Gill     return 0;
126*cad9ecf6SJagpal Singh Gill }
127