xref: /openbmc/phosphor-modbus/rtu/port/usb_port.cpp (revision 7f9d41ddfad8c74d51fa1cf4a591b7f085254396)
1*7f9d41ddSJagpal Singh Gill #include "usb_port.hpp"
2*7f9d41ddSJagpal Singh Gill 
3*7f9d41ddSJagpal Singh Gill #include "common/entity_manager_interface.hpp"
4*7f9d41ddSJagpal Singh Gill #include "port_factory.hpp"
5*7f9d41ddSJagpal Singh Gill 
6*7f9d41ddSJagpal Singh Gill #include <fcntl.h>
7*7f9d41ddSJagpal Singh Gill 
8*7f9d41ddSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
9*7f9d41ddSJagpal Singh Gill #include <xyz/openbmc_project/Configuration/USBPort/client.hpp>
10*7f9d41ddSJagpal Singh Gill 
11*7f9d41ddSJagpal Singh Gill #include <filesystem>
12*7f9d41ddSJagpal Singh Gill #include <format>
13*7f9d41ddSJagpal Singh Gill #include <optional>
14*7f9d41ddSJagpal Singh Gill #include <regex>
15*7f9d41ddSJagpal Singh Gill 
16*7f9d41ddSJagpal Singh Gill namespace phosphor::modbus::rtu::port
17*7f9d41ddSJagpal Singh Gill {
18*7f9d41ddSJagpal Singh Gill 
19*7f9d41ddSJagpal Singh Gill PHOSPHOR_LOG2_USING;
20*7f9d41ddSJagpal Singh Gill 
21*7f9d41ddSJagpal Singh Gill using USBPortConfigIntf =
22*7f9d41ddSJagpal Singh Gill     sdbusplus::client::xyz::openbmc_project::configuration::USBPort<>;
23*7f9d41ddSJagpal Singh Gill 
24*7f9d41ddSJagpal Singh Gill namespace config
25*7f9d41ddSJagpal Singh Gill {
26*7f9d41ddSJagpal Singh Gill 
27*7f9d41ddSJagpal Singh Gill struct USBPortConfig : public PortFactoryConfig
28*7f9d41ddSJagpal Singh Gill {
29*7f9d41ddSJagpal Singh Gill     std::string address = "unknown";
30*7f9d41ddSJagpal Singh Gill     uint16_t port = 0;
31*7f9d41ddSJagpal Singh Gill     uint16_t interface = 0;
32*7f9d41ddSJagpal Singh Gill };
33*7f9d41ddSJagpal Singh Gill 
34*7f9d41ddSJagpal Singh Gill } // namespace config
35*7f9d41ddSJagpal Singh Gill 
36*7f9d41ddSJagpal Singh Gill static auto getDevicePath(const config::Config& inConfig) -> std::string
37*7f9d41ddSJagpal Singh Gill {
38*7f9d41ddSJagpal Singh Gill     namespace fs = std::filesystem;
39*7f9d41ddSJagpal Singh Gill     auto config = static_cast<const config::USBPortConfig&>(inConfig);
40*7f9d41ddSJagpal Singh Gill     std::regex pattern(
41*7f9d41ddSJagpal Singh Gill         std::format("platform-{}\\.usb-usb.*{}-port{}", config.address,
42*7f9d41ddSJagpal Singh Gill                     config.interface, config.port));
43*7f9d41ddSJagpal Singh Gill     fs::path searchDir = "/dev/serial/by-path/";
44*7f9d41ddSJagpal Singh Gill 
45*7f9d41ddSJagpal Singh Gill     for (const auto& entry : fs::recursive_directory_iterator(searchDir))
46*7f9d41ddSJagpal Singh Gill     {
47*7f9d41ddSJagpal Singh Gill         if (entry.is_symlink())
48*7f9d41ddSJagpal Singh Gill         {
49*7f9d41ddSJagpal Singh Gill             auto filePath = entry.path();
50*7f9d41ddSJagpal Singh Gill             if (std::regex_search(filePath.filename().string(), pattern))
51*7f9d41ddSJagpal Singh Gill             {
52*7f9d41ddSJagpal Singh Gill                 return ("/dev/" +
53*7f9d41ddSJagpal Singh Gill                         fs::read_symlink(filePath).filename().string());
54*7f9d41ddSJagpal Singh Gill             }
55*7f9d41ddSJagpal Singh Gill         }
56*7f9d41ddSJagpal Singh Gill     }
57*7f9d41ddSJagpal Singh Gill 
58*7f9d41ddSJagpal Singh Gill     throw std::runtime_error("Failed to get device path");
59*7f9d41ddSJagpal Singh Gill }
60*7f9d41ddSJagpal Singh Gill 
61*7f9d41ddSJagpal Singh Gill USBPort::USBPort(sdbusplus::async::context& ctx,
62*7f9d41ddSJagpal Singh Gill                  config::PortFactoryConfig& config) :
63*7f9d41ddSJagpal Singh Gill     BasePort(ctx, config, getDevicePath(config))
64*7f9d41ddSJagpal Singh Gill {
65*7f9d41ddSJagpal Singh Gill     info("USB port {NAME} created successfully", "NAME", config.name);
66*7f9d41ddSJagpal Singh Gill }
67*7f9d41ddSJagpal Singh Gill 
68*7f9d41ddSJagpal Singh Gill auto USBPort::getConfig(sdbusplus::async::context& ctx,
69*7f9d41ddSJagpal Singh Gill                         const sdbusplus::message::object_path& objectPath)
70*7f9d41ddSJagpal Singh Gill     -> sdbusplus::async::task<std::optional<config::PortFactoryConfig>>
71*7f9d41ddSJagpal Singh Gill {
72*7f9d41ddSJagpal Singh Gill     config::USBPortConfig config = {};
73*7f9d41ddSJagpal Singh Gill 
74*7f9d41ddSJagpal Singh Gill     auto properties =
75*7f9d41ddSJagpal Singh Gill         co_await USBPortConfigIntf(ctx)
76*7f9d41ddSJagpal Singh Gill             .service(entity_manager::EntityManagerInterface::serviceName)
77*7f9d41ddSJagpal Singh Gill             .path(objectPath.str)
78*7f9d41ddSJagpal Singh Gill             .properties();
79*7f9d41ddSJagpal Singh Gill 
80*7f9d41ddSJagpal Singh Gill     auto res = updateBaseConfig(config, properties);
81*7f9d41ddSJagpal Singh Gill     if (!res)
82*7f9d41ddSJagpal Singh Gill     {
83*7f9d41ddSJagpal Singh Gill         co_return std::nullopt;
84*7f9d41ddSJagpal Singh Gill     }
85*7f9d41ddSJagpal Singh Gill 
86*7f9d41ddSJagpal Singh Gill     config.address = properties.device_address;
87*7f9d41ddSJagpal Singh Gill     config.port = properties.port;
88*7f9d41ddSJagpal Singh Gill     config.interface = properties.device_interface;
89*7f9d41ddSJagpal Singh Gill 
90*7f9d41ddSJagpal Singh Gill     debug(
91*7f9d41ddSJagpal Singh Gill         "USB port config: {NAME} {PORT_TYPE} {PORT_MODE} {ADDRESS} {PORT} {INTERFACE} {BAUD_RATE} {RTS_DELAY}",
92*7f9d41ddSJagpal Singh Gill         "NAME", config.name, "PORT_TYPE", config.portType, "PORT_MODE",
93*7f9d41ddSJagpal Singh Gill         config.portMode, "ADDRESS", config.address, "PORT", config.port,
94*7f9d41ddSJagpal Singh Gill         "INTERFACE", config.interface, "BAUD_RATE", config.baudRate,
95*7f9d41ddSJagpal Singh Gill         "RTS_DELAY", config.rtsDelay);
96*7f9d41ddSJagpal Singh Gill     co_return config;
97*7f9d41ddSJagpal Singh Gill }
98*7f9d41ddSJagpal Singh Gill 
99*7f9d41ddSJagpal Singh Gill } // namespace phosphor::modbus::rtu::port
100