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