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