xref: /openbmc/phosphor-modbus/rtu/port/usb_port.cpp (revision b62e3dfe5505fdb8c2ab96156b62e3bfb878b7a6)
17f9d41ddSJagpal Singh Gill #include "usb_port.hpp"
27f9d41ddSJagpal Singh Gill 
37f9d41ddSJagpal Singh Gill #include "common/entity_manager_interface.hpp"
47f9d41ddSJagpal Singh Gill #include "port_factory.hpp"
57f9d41ddSJagpal Singh Gill 
67f9d41ddSJagpal Singh Gill #include <fcntl.h>
77f9d41ddSJagpal Singh Gill 
87f9d41ddSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
97f9d41ddSJagpal Singh Gill #include <xyz/openbmc_project/Configuration/USBPort/client.hpp>
107f9d41ddSJagpal Singh Gill 
117f9d41ddSJagpal Singh Gill #include <filesystem>
127f9d41ddSJagpal Singh Gill #include <format>
137f9d41ddSJagpal Singh Gill #include <optional>
147f9d41ddSJagpal Singh Gill #include <regex>
157f9d41ddSJagpal Singh Gill 
167f9d41ddSJagpal Singh Gill namespace phosphor::modbus::rtu::port
177f9d41ddSJagpal Singh Gill {
187f9d41ddSJagpal Singh Gill 
197f9d41ddSJagpal Singh Gill PHOSPHOR_LOG2_USING;
207f9d41ddSJagpal Singh Gill 
217f9d41ddSJagpal Singh Gill using USBPortConfigIntf =
227f9d41ddSJagpal Singh Gill     sdbusplus::client::xyz::openbmc_project::configuration::USBPort<>;
237f9d41ddSJagpal Singh Gill 
247f9d41ddSJagpal Singh Gill namespace config
257f9d41ddSJagpal Singh Gill {
267f9d41ddSJagpal Singh Gill 
277f9d41ddSJagpal Singh Gill struct USBPortConfig : public PortFactoryConfig
287f9d41ddSJagpal Singh Gill {
297f9d41ddSJagpal Singh Gill     std::string address = "unknown";
307f9d41ddSJagpal Singh Gill     uint16_t port = 0;
317f9d41ddSJagpal Singh Gill     uint16_t interface = 0;
32*b62e3dfeSJagpal Singh Gill 
33*b62e3dfeSJagpal Singh Gill     virtual ~USBPortConfig() = default;
347f9d41ddSJagpal Singh Gill };
357f9d41ddSJagpal Singh Gill 
367f9d41ddSJagpal Singh Gill } // namespace config
377f9d41ddSJagpal Singh Gill 
getDevicePath(const config::PortFactoryConfig & inConfig)38*b62e3dfeSJagpal Singh Gill static auto getDevicePath(const config::PortFactoryConfig& inConfig)
39*b62e3dfeSJagpal Singh Gill     -> std::string
407f9d41ddSJagpal Singh Gill {
417f9d41ddSJagpal Singh Gill     namespace fs = std::filesystem;
427f9d41ddSJagpal Singh Gill     auto config = static_cast<const config::USBPortConfig&>(inConfig);
43*b62e3dfeSJagpal Singh Gill 
447f9d41ddSJagpal Singh Gill     std::regex pattern(
457f9d41ddSJagpal Singh Gill         std::format("platform-{}\\.usb-usb.*{}-port{}", config.address,
467f9d41ddSJagpal Singh Gill                     config.interface, config.port));
477f9d41ddSJagpal Singh Gill     fs::path searchDir = "/dev/serial/by-path/";
487f9d41ddSJagpal Singh Gill 
497f9d41ddSJagpal Singh Gill     for (const auto& entry : fs::recursive_directory_iterator(searchDir))
507f9d41ddSJagpal Singh Gill     {
517f9d41ddSJagpal Singh Gill         if (entry.is_symlink())
527f9d41ddSJagpal Singh Gill         {
537f9d41ddSJagpal Singh Gill             auto filePath = entry.path();
547f9d41ddSJagpal Singh Gill             if (std::regex_search(filePath.filename().string(), pattern))
557f9d41ddSJagpal Singh Gill             {
567f9d41ddSJagpal Singh Gill                 return ("/dev/" +
577f9d41ddSJagpal Singh Gill                         fs::read_symlink(filePath).filename().string());
587f9d41ddSJagpal Singh Gill             }
597f9d41ddSJagpal Singh Gill         }
607f9d41ddSJagpal Singh Gill     }
617f9d41ddSJagpal Singh Gill 
627f9d41ddSJagpal Singh Gill     throw std::runtime_error("Failed to get device path");
637f9d41ddSJagpal Singh Gill }
647f9d41ddSJagpal Singh Gill 
USBPort(sdbusplus::async::context & ctx,const config::PortFactoryConfig & config)657f9d41ddSJagpal Singh Gill USBPort::USBPort(sdbusplus::async::context& ctx,
66*b62e3dfeSJagpal Singh Gill                  const config::PortFactoryConfig& config) :
677f9d41ddSJagpal Singh Gill     BasePort(ctx, config, getDevicePath(config))
687f9d41ddSJagpal Singh Gill {
697f9d41ddSJagpal Singh Gill     info("USB port {NAME} created successfully", "NAME", config.name);
707f9d41ddSJagpal Singh Gill }
717f9d41ddSJagpal Singh Gill 
getConfig(sdbusplus::async::context & ctx,const sdbusplus::message::object_path & objectPath)727f9d41ddSJagpal Singh Gill auto USBPort::getConfig(sdbusplus::async::context& ctx,
737f9d41ddSJagpal Singh Gill                         const sdbusplus::message::object_path& objectPath)
74*b62e3dfeSJagpal Singh Gill     -> sdbusplus::async::task<std::unique_ptr<config::PortFactoryConfig>>
757f9d41ddSJagpal Singh Gill {
76*b62e3dfeSJagpal Singh Gill     auto config = std::make_unique<config::USBPortConfig>();
77*b62e3dfeSJagpal Singh Gill     if (!config)
78*b62e3dfeSJagpal Singh Gill     {
79*b62e3dfeSJagpal Singh Gill         co_return std::nullptr_t();
80*b62e3dfeSJagpal Singh Gill     }
817f9d41ddSJagpal Singh Gill 
827f9d41ddSJagpal Singh Gill     auto properties =
837f9d41ddSJagpal Singh Gill         co_await USBPortConfigIntf(ctx)
847f9d41ddSJagpal Singh Gill             .service(entity_manager::EntityManagerInterface::serviceName)
857f9d41ddSJagpal Singh Gill             .path(objectPath.str)
867f9d41ddSJagpal Singh Gill             .properties();
877f9d41ddSJagpal Singh Gill 
88*b62e3dfeSJagpal Singh Gill     auto res = updateBaseConfig(*config, properties);
897f9d41ddSJagpal Singh Gill     if (!res)
907f9d41ddSJagpal Singh Gill     {
91*b62e3dfeSJagpal Singh Gill         co_return std::nullptr_t();
927f9d41ddSJagpal Singh Gill     }
937f9d41ddSJagpal Singh Gill 
94*b62e3dfeSJagpal Singh Gill     config->address = properties.device_address;
95*b62e3dfeSJagpal Singh Gill     config->port = properties.port;
96*b62e3dfeSJagpal Singh Gill     config->interface = properties.device_interface;
97*b62e3dfeSJagpal Singh Gill     config->portType = config::PortType::usb;
987f9d41ddSJagpal Singh Gill 
997f9d41ddSJagpal Singh Gill     debug(
1007f9d41ddSJagpal Singh Gill         "USB port config: {NAME} {PORT_TYPE} {PORT_MODE} {ADDRESS} {PORT} {INTERFACE} {BAUD_RATE} {RTS_DELAY}",
101*b62e3dfeSJagpal Singh Gill         "NAME", config->name, "PORT_TYPE", config->portType, "PORT_MODE",
102*b62e3dfeSJagpal Singh Gill         config->portMode, "ADDRESS", config->address, "PORT", config->port,
103*b62e3dfeSJagpal Singh Gill         "INTERFACE", config->interface, "BAUD_RATE", config->baudRate,
104*b62e3dfeSJagpal Singh Gill         "RTS_DELAY", config->rtsDelay);
105*b62e3dfeSJagpal Singh Gill 
1067f9d41ddSJagpal Singh Gill     co_return config;
1077f9d41ddSJagpal Singh Gill }
1087f9d41ddSJagpal Singh Gill 
1097f9d41ddSJagpal Singh Gill } // namespace phosphor::modbus::rtu::port
110