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