blob: 6d2fbd647a91033e00e321a3b0b84da0f3df89b3 [file] [log] [blame]
#include "device_manager.hpp"
#include "port/port_factory.hpp"
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/async.hpp>
#include <sdbusplus/server/manager.hpp>
#include <xyz/openbmc_project/Configuration/ModbusRTUDetect/client.hpp>
PHOSPHOR_LOG2_USING;
namespace phosphor::modbus::rtu
{
using ModbusRTUDetectIntf =
sdbusplus::client::xyz::openbmc_project::configuration::ModbusRTUDetect<>;
static entity_manager::interface_list_t getInterfaces()
{
entity_manager::interface_list_t interfaces;
auto portInterfaces = PortIntf::PortFactory::getInterfaces();
interfaces.insert(interfaces.end(), portInterfaces.begin(),
portInterfaces.end());
interfaces.emplace_back(ModbusRTUDetectIntf::interface);
return interfaces;
}
DeviceManager::DeviceManager(sdbusplus::async::context& ctx) :
ctx(ctx),
entityManager(ctx, getInterfaces(),
std::bind_front(&DeviceManager::processConfigAdded, this),
std::bind_front(&DeviceManager::processConfigRemoved, this))
{
ctx.spawn(entityManager.handleInventoryGet());
info("DeviceManager created successfully");
}
auto DeviceManager::processConfigAdded(
const sdbusplus::message::object_path& objectPath,
const std::string& interfaceName) -> sdbusplus::async::task<>
{
debug("Config added for {PATH} with {INTF}", "PATH", objectPath, "INTF",
interfaceName);
if (interfaceName == ModbusRTUDetectIntf::interface && ports.size() == 0)
{
warning(
"Skip processing ModbusRTUDetectIntf::interface as no serial ports detected yet");
co_return;
}
auto portInterfaces = PortIntf::PortFactory::getInterfaces();
if (std::find(portInterfaces.begin(), portInterfaces.end(),
interfaceName) != portInterfaces.end())
{
auto config = co_await PortIntf::PortFactory::getConfig(
ctx, objectPath, interfaceName);
if (!config)
{
error("Failed to get Port config for {PATH}", "PATH", objectPath);
co_return;
}
try
{
ports[config->name] = PortIntf::PortFactory::create(ctx, *config);
}
catch (const std::exception& e)
{
error("Failed to create Port for {PATH} with {ERROR}", "PATH",
objectPath, "ERROR", e);
co_return;
}
}
else if (interfaceName == ModbusRTUDetectIntf::interface)
{
auto res = co_await InventoryIntf::config::getConfig(ctx, objectPath);
if (!res)
{
error("Failed to get Inventory Device config for {PATH}", "PATH",
objectPath);
co_return;
}
auto config = res.value();
try
{
auto inventoryDevice =
std::make_unique<InventoryIntf::Device>(ctx, config, ports);
ctx.spawn(inventoryDevice->probePorts());
inventoryDevices[config.name] = std::move(inventoryDevice);
}
catch (const std::exception& e)
{
error("Failed to create Inventory Device for {PATH} with {ERROR}",
"PATH", objectPath, "ERROR", e);
co_return;
}
}
}
auto DeviceManager::processConfigRemoved(
const sdbusplus::message::object_path& /*unused*/,
const std::string& /*unused*/) -> sdbusplus::async::task<>
{
// TODO: Implement this
co_return;
}
} // namespace phosphor::modbus::rtu
auto main() -> int
{
constexpr auto path = "/xyz/openbmc_project";
constexpr auto serviceName = "xyz.openbmc_project.ModbusRTU";
sdbusplus::async::context ctx;
sdbusplus::server::manager_t manager{ctx, path};
info("Creating Modbus device manager at {PATH}", "PATH", path);
phosphor::modbus::rtu::DeviceManager deviceManager{ctx};
ctx.request_name(serviceName);
ctx.run();
return 0;
}