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