1 #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 16 namespace phosphor::modbus::rtu::port 17 { 18 19 PHOSPHOR_LOG2_USING; 20 21 using USBPortConfigIntf = 22 sdbusplus::client::xyz::openbmc_project::configuration::USBPort<>; 23 24 namespace config 25 { 26 27 struct 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 36 static 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 61 USBPort::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 68 auto 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 100