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