1cad9ecf6SJagpal Singh Gill #include "device_manager.hpp"
2cad9ecf6SJagpal Singh Gill
3e92aba45SJagpal Singh Gill #include "device/device_factory.hpp"
4cad9ecf6SJagpal Singh Gill #include "port/port_factory.hpp"
5cad9ecf6SJagpal Singh Gill
6cad9ecf6SJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
7cad9ecf6SJagpal Singh Gill #include <sdbusplus/async.hpp>
8cad9ecf6SJagpal Singh Gill #include <sdbusplus/server/manager.hpp>
9cad9ecf6SJagpal Singh Gill #include <xyz/openbmc_project/Configuration/ModbusRTUDetect/client.hpp>
10cad9ecf6SJagpal Singh Gill
11cad9ecf6SJagpal Singh Gill PHOSPHOR_LOG2_USING;
12cad9ecf6SJagpal Singh Gill
13cad9ecf6SJagpal Singh Gill namespace phosphor::modbus::rtu
14cad9ecf6SJagpal Singh Gill {
15cad9ecf6SJagpal Singh Gill
16cad9ecf6SJagpal Singh Gill using ModbusRTUDetectIntf =
17cad9ecf6SJagpal Singh Gill sdbusplus::client::xyz::openbmc_project::configuration::ModbusRTUDetect<>;
18e92aba45SJagpal Singh Gill using DeviceFactoryIntf = phosphor::modbus::rtu::device::DeviceFactory;
19cad9ecf6SJagpal Singh Gill
getInterfaces()20cad9ecf6SJagpal Singh Gill static entity_manager::interface_list_t getInterfaces()
21cad9ecf6SJagpal Singh Gill {
22cad9ecf6SJagpal Singh Gill entity_manager::interface_list_t interfaces;
23cad9ecf6SJagpal Singh Gill
24cad9ecf6SJagpal Singh Gill auto portInterfaces = PortIntf::PortFactory::getInterfaces();
25cad9ecf6SJagpal Singh Gill interfaces.insert(interfaces.end(), portInterfaces.begin(),
26cad9ecf6SJagpal Singh Gill portInterfaces.end());
27e92aba45SJagpal Singh Gill
28cad9ecf6SJagpal Singh Gill interfaces.emplace_back(ModbusRTUDetectIntf::interface);
29cad9ecf6SJagpal Singh Gill
30e92aba45SJagpal Singh Gill auto deviceInterfaces = DeviceFactoryIntf::getInterfaces();
31e92aba45SJagpal Singh Gill interfaces.insert(interfaces.end(), deviceInterfaces.begin(),
32e92aba45SJagpal Singh Gill deviceInterfaces.end());
33e92aba45SJagpal Singh Gill
34cad9ecf6SJagpal Singh Gill return interfaces;
35cad9ecf6SJagpal Singh Gill }
36cad9ecf6SJagpal Singh Gill
DeviceManager(sdbusplus::async::context & ctx)37cad9ecf6SJagpal Singh Gill DeviceManager::DeviceManager(sdbusplus::async::context& ctx) :
38cad9ecf6SJagpal Singh Gill ctx(ctx),
39cad9ecf6SJagpal Singh Gill entityManager(ctx, getInterfaces(),
40cad9ecf6SJagpal Singh Gill std::bind_front(&DeviceManager::processConfigAdded, this),
41*7184805aSJagpal Singh Gill std::bind_front(&DeviceManager::processConfigRemoved, this)),
42*7184805aSJagpal Singh Gill events(ctx)
43cad9ecf6SJagpal Singh Gill {
44cad9ecf6SJagpal Singh Gill ctx.spawn(entityManager.handleInventoryGet());
45cad9ecf6SJagpal Singh Gill info("DeviceManager created successfully");
46cad9ecf6SJagpal Singh Gill }
47cad9ecf6SJagpal Singh Gill
processConfigAdded(const sdbusplus::message::object_path & objectPath,const std::string & interfaceName)48cad9ecf6SJagpal Singh Gill auto DeviceManager::processConfigAdded(
49cad9ecf6SJagpal Singh Gill const sdbusplus::message::object_path& objectPath,
50cad9ecf6SJagpal Singh Gill const std::string& interfaceName) -> sdbusplus::async::task<>
51cad9ecf6SJagpal Singh Gill {
52cad9ecf6SJagpal Singh Gill debug("Config added for {PATH} with {INTF}", "PATH", objectPath, "INTF",
53cad9ecf6SJagpal Singh Gill interfaceName);
54cad9ecf6SJagpal Singh Gill if (interfaceName == ModbusRTUDetectIntf::interface && ports.size() == 0)
55cad9ecf6SJagpal Singh Gill {
56cad9ecf6SJagpal Singh Gill warning(
57cad9ecf6SJagpal Singh Gill "Skip processing ModbusRTUDetectIntf::interface as no serial ports detected yet");
58cad9ecf6SJagpal Singh Gill co_return;
59cad9ecf6SJagpal Singh Gill }
60cad9ecf6SJagpal Singh Gill
61cad9ecf6SJagpal Singh Gill auto portInterfaces = PortIntf::PortFactory::getInterfaces();
62cad9ecf6SJagpal Singh Gill if (std::find(portInterfaces.begin(), portInterfaces.end(),
63cad9ecf6SJagpal Singh Gill interfaceName) != portInterfaces.end())
64cad9ecf6SJagpal Singh Gill {
65e92aba45SJagpal Singh Gill co_return co_await processPortAdded(objectPath, interfaceName);
66e92aba45SJagpal Singh Gill }
67e92aba45SJagpal Singh Gill
68e92aba45SJagpal Singh Gill if (interfaceName == ModbusRTUDetectIntf::interface)
69e92aba45SJagpal Singh Gill {
70e92aba45SJagpal Singh Gill co_return co_await processInventoryAdded(objectPath);
71e92aba45SJagpal Singh Gill }
72e92aba45SJagpal Singh Gill
73e92aba45SJagpal Singh Gill auto deviceInterfaces = DeviceFactoryIntf::getInterfaces();
74e92aba45SJagpal Singh Gill if (std::find(deviceInterfaces.begin(), deviceInterfaces.end(),
75e92aba45SJagpal Singh Gill interfaceName) != deviceInterfaces.end())
76e92aba45SJagpal Singh Gill {
77e92aba45SJagpal Singh Gill co_return co_await processDeviceAdded(objectPath, interfaceName);
78e92aba45SJagpal Singh Gill }
79e92aba45SJagpal Singh Gill }
80e92aba45SJagpal Singh Gill
processPortAdded(const sdbusplus::message::object_path & objectPath,const std::string & interfaceName)81e92aba45SJagpal Singh Gill auto DeviceManager::processPortAdded(
82e92aba45SJagpal Singh Gill const sdbusplus::message::object_path& objectPath,
83e92aba45SJagpal Singh Gill const std::string& interfaceName) -> sdbusplus::async::task<>
84e92aba45SJagpal Singh Gill {
85cad9ecf6SJagpal Singh Gill auto config = co_await PortIntf::PortFactory::getConfig(
86cad9ecf6SJagpal Singh Gill ctx, objectPath, interfaceName);
87cad9ecf6SJagpal Singh Gill if (!config)
88cad9ecf6SJagpal Singh Gill {
89cad9ecf6SJagpal Singh Gill error("Failed to get Port config for {PATH}", "PATH", objectPath);
90cad9ecf6SJagpal Singh Gill co_return;
91cad9ecf6SJagpal Singh Gill }
92cad9ecf6SJagpal Singh Gill
93cad9ecf6SJagpal Singh Gill try
94cad9ecf6SJagpal Singh Gill {
95cad9ecf6SJagpal Singh Gill ports[config->name] = PortIntf::PortFactory::create(ctx, *config);
96cad9ecf6SJagpal Singh Gill }
97cad9ecf6SJagpal Singh Gill catch (const std::exception& e)
98cad9ecf6SJagpal Singh Gill {
99cad9ecf6SJagpal Singh Gill error("Failed to create Port for {PATH} with {ERROR}", "PATH",
100cad9ecf6SJagpal Singh Gill objectPath, "ERROR", e);
101cad9ecf6SJagpal Singh Gill co_return;
102cad9ecf6SJagpal Singh Gill }
103cad9ecf6SJagpal Singh Gill }
104e92aba45SJagpal Singh Gill
processInventoryAdded(const sdbusplus::message::object_path & objectPath)105e92aba45SJagpal Singh Gill auto DeviceManager::processInventoryAdded(
106e92aba45SJagpal Singh Gill const sdbusplus::message::object_path& objectPath)
107e92aba45SJagpal Singh Gill -> sdbusplus::async::task<>
108cad9ecf6SJagpal Singh Gill {
109cad9ecf6SJagpal Singh Gill auto res = co_await InventoryIntf::config::getConfig(ctx, objectPath);
110cad9ecf6SJagpal Singh Gill if (!res)
111cad9ecf6SJagpal Singh Gill {
112cad9ecf6SJagpal Singh Gill error("Failed to get Inventory Device config for {PATH}", "PATH",
113cad9ecf6SJagpal Singh Gill objectPath);
114cad9ecf6SJagpal Singh Gill co_return;
115cad9ecf6SJagpal Singh Gill }
116cad9ecf6SJagpal Singh Gill auto config = res.value();
117cad9ecf6SJagpal Singh Gill try
118cad9ecf6SJagpal Singh Gill {
119cad9ecf6SJagpal Singh Gill auto inventoryDevice =
120cad9ecf6SJagpal Singh Gill std::make_unique<InventoryIntf::Device>(ctx, config, ports);
121cad9ecf6SJagpal Singh Gill ctx.spawn(inventoryDevice->probePorts());
122cad9ecf6SJagpal Singh Gill inventoryDevices[config.name] = std::move(inventoryDevice);
123cad9ecf6SJagpal Singh Gill }
124cad9ecf6SJagpal Singh Gill catch (const std::exception& e)
125cad9ecf6SJagpal Singh Gill {
126cad9ecf6SJagpal Singh Gill error("Failed to create Inventory Device for {PATH} with {ERROR}",
127cad9ecf6SJagpal Singh Gill "PATH", objectPath, "ERROR", e);
128cad9ecf6SJagpal Singh Gill co_return;
129cad9ecf6SJagpal Singh Gill }
130cad9ecf6SJagpal Singh Gill }
131e92aba45SJagpal Singh Gill
processDeviceAdded(const sdbusplus::message::object_path & objectPath,const std::string & interfaceName)132e92aba45SJagpal Singh Gill auto DeviceManager::processDeviceAdded(
133e92aba45SJagpal Singh Gill const sdbusplus::message::object_path& objectPath,
134e92aba45SJagpal Singh Gill const std::string& interfaceName) -> sdbusplus::async::task<>
135e92aba45SJagpal Singh Gill {
136e92aba45SJagpal Singh Gill auto res =
137e92aba45SJagpal Singh Gill co_await DeviceFactoryIntf::getConfig(ctx, objectPath, interfaceName);
138e92aba45SJagpal Singh Gill if (!res)
139e92aba45SJagpal Singh Gill {
140e92aba45SJagpal Singh Gill error("Failed to get Device config for {PATH}", "PATH", objectPath);
141e92aba45SJagpal Singh Gill co_return;
142e92aba45SJagpal Singh Gill }
143e92aba45SJagpal Singh Gill auto config = res.value();
144e92aba45SJagpal Singh Gill
145e92aba45SJagpal Singh Gill try
146e92aba45SJagpal Singh Gill {
147e92aba45SJagpal Singh Gill auto serialPort = ports.find(config.portName);
148e92aba45SJagpal Singh Gill if (serialPort == ports.end())
149e92aba45SJagpal Singh Gill {
150e92aba45SJagpal Singh Gill error("Failed to get Inventory Device config for {PATH}", "PATH",
151e92aba45SJagpal Singh Gill objectPath);
152e92aba45SJagpal Singh Gill co_return;
153e92aba45SJagpal Singh Gill }
154e92aba45SJagpal Singh Gill
155*7184805aSJagpal Singh Gill auto device = DeviceFactoryIntf::create(ctx, config,
156*7184805aSJagpal Singh Gill *(serialPort->second), events);
157e92aba45SJagpal Singh Gill ctx.spawn(device->readSensorRegisters());
158e92aba45SJagpal Singh Gill devices[config.name] = std::move(device);
159e92aba45SJagpal Singh Gill }
160e92aba45SJagpal Singh Gill catch (const std::exception& e)
161e92aba45SJagpal Singh Gill {
162e92aba45SJagpal Singh Gill error("Failed to create Device for {PATH} with {ERROR}", "PATH",
163e92aba45SJagpal Singh Gill objectPath, "ERROR", e);
164e92aba45SJagpal Singh Gill co_return;
165e92aba45SJagpal Singh Gill }
166cad9ecf6SJagpal Singh Gill }
167cad9ecf6SJagpal Singh Gill
processConfigRemoved(const sdbusplus::message::object_path &,const std::string &)168cad9ecf6SJagpal Singh Gill auto DeviceManager::processConfigRemoved(
169cad9ecf6SJagpal Singh Gill const sdbusplus::message::object_path& /*unused*/,
170cad9ecf6SJagpal Singh Gill const std::string& /*unused*/) -> sdbusplus::async::task<>
171cad9ecf6SJagpal Singh Gill {
172cad9ecf6SJagpal Singh Gill // TODO: Implement this
173cad9ecf6SJagpal Singh Gill co_return;
174cad9ecf6SJagpal Singh Gill }
175cad9ecf6SJagpal Singh Gill
176cad9ecf6SJagpal Singh Gill } // namespace phosphor::modbus::rtu
177cad9ecf6SJagpal Singh Gill
main()178cad9ecf6SJagpal Singh Gill auto main() -> int
179cad9ecf6SJagpal Singh Gill {
180cad9ecf6SJagpal Singh Gill constexpr auto path = "/xyz/openbmc_project";
181cad9ecf6SJagpal Singh Gill constexpr auto serviceName = "xyz.openbmc_project.ModbusRTU";
182cad9ecf6SJagpal Singh Gill sdbusplus::async::context ctx;
183cad9ecf6SJagpal Singh Gill sdbusplus::server::manager_t manager{ctx, path};
184cad9ecf6SJagpal Singh Gill
185cad9ecf6SJagpal Singh Gill info("Creating Modbus device manager at {PATH}", "PATH", path);
186cad9ecf6SJagpal Singh Gill phosphor::modbus::rtu::DeviceManager deviceManager{ctx};
187cad9ecf6SJagpal Singh Gill
188cad9ecf6SJagpal Singh Gill ctx.request_name(serviceName);
189cad9ecf6SJagpal Singh Gill
190cad9ecf6SJagpal Singh Gill ctx.run();
191cad9ecf6SJagpal Singh Gill return 0;
192cad9ecf6SJagpal Singh Gill }
193