blob: 77f226a7f6f3545c60f26388e79520f7b35b1f8e [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;
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070032
33 virtual ~USBPortConfig() = default;
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070034};
35
36} // namespace config
37
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070038static auto getDevicePath(const config::PortFactoryConfig& inConfig)
39 -> std::string
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070040{
41 namespace fs = std::filesystem;
42 auto config = static_cast<const config::USBPortConfig&>(inConfig);
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070043
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070044 std::regex pattern(
45 std::format("platform-{}\\.usb-usb.*{}-port{}", config.address,
46 config.interface, config.port));
47 fs::path searchDir = "/dev/serial/by-path/";
48
49 for (const auto& entry : fs::recursive_directory_iterator(searchDir))
50 {
51 if (entry.is_symlink())
52 {
53 auto filePath = entry.path();
54 if (std::regex_search(filePath.filename().string(), pattern))
55 {
56 return ("/dev/" +
57 fs::read_symlink(filePath).filename().string());
58 }
59 }
60 }
61
62 throw std::runtime_error("Failed to get device path");
63}
64
65USBPort::USBPort(sdbusplus::async::context& ctx,
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070066 const config::PortFactoryConfig& config) :
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070067 BasePort(ctx, config, getDevicePath(config))
68{
69 info("USB port {NAME} created successfully", "NAME", config.name);
70}
71
72auto USBPort::getConfig(sdbusplus::async::context& ctx,
73 const sdbusplus::message::object_path& objectPath)
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070074 -> sdbusplus::async::task<std::unique_ptr<config::PortFactoryConfig>>
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070075{
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070076 auto config = std::make_unique<config::USBPortConfig>();
77 if (!config)
78 {
79 co_return std::nullptr_t();
80 }
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070081
82 auto properties =
83 co_await USBPortConfigIntf(ctx)
84 .service(entity_manager::EntityManagerInterface::serviceName)
85 .path(objectPath.str)
86 .properties();
87
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070088 auto res = updateBaseConfig(*config, properties);
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070089 if (!res)
90 {
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070091 co_return std::nullptr_t();
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070092 }
93
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -070094 config->address = properties.device_address;
95 config->port = properties.port;
96 config->interface = properties.device_interface;
97 config->portType = config::PortType::usb;
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -070098
99 debug(
100 "USB port config: {NAME} {PORT_TYPE} {PORT_MODE} {ADDRESS} {PORT} {INTERFACE} {BAUD_RATE} {RTS_DELAY}",
Jagpal Singh Gillb62e3df2025-10-22 18:10:40 -0700101 "NAME", config->name, "PORT_TYPE", config->portType, "PORT_MODE",
102 config->portMode, "ADDRESS", config->address, "PORT", config->port,
103 "INTERFACE", config->interface, "BAUD_RATE", config->baudRate,
104 "RTS_DELAY", config->rtsDelay);
105
Jagpal Singh Gill7f9d41d2025-10-16 09:42:18 -0700106 co_return config;
107}
108
109} // namespace phosphor::modbus::rtu::port