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