blob: 6d2fbd647a91033e00e321a3b0b84da0f3df89b3 [file] [log] [blame]
Jagpal Singh Gillcad9ecf2025-10-22 19:53:16 -07001#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
10PHOSPHOR_LOG2_USING;
11
12namespace phosphor::modbus::rtu
13{
14
15using ModbusRTUDetectIntf =
16 sdbusplus::client::xyz::openbmc_project::configuration::ModbusRTUDetect<>;
17
18static 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
30DeviceManager::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
40auto 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
102auto 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
112auto 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}