#pragma once #include "modbus/modbus.hpp" #include #include #include #include namespace phosphor::modbus::rtu::port { using ModbusIntf = phosphor::modbus::rtu::Modbus; namespace config { enum class PortMode { rs232, rs485, unknown }; static constexpr std::array, 2> validPortModes = {{{"RS232", PortMode::rs232}, {"RS485", PortMode::rs485}}}; struct Config { std::string name = "unknown"; PortMode portMode = PortMode::unknown; uint32_t baudRate = 0; uint16_t rtsDelay = 0; virtual ~Config() = default; }; template concept HasPropertiesMembers = requires(T properties) { { properties.name } -> std::same_as; { properties.mode } -> std::same_as; { properties.baud_rate } -> std::same_as; { properties.rts_delay } -> std::same_as; }; template concept HasConfigMembers = requires(T config) { { config.name } -> std::same_as; { config.portMode } -> std::same_as; { config.baudRate } -> std::same_as; { config.rtsDelay } -> std::same_as; }; template auto updateBaseConfig(BaseConfig& config, const BaseProperties& properties) -> bool { PHOSPHOR_LOG2_USING; config.name = properties.name; config.baudRate = static_cast(properties.baud_rate); config.rtsDelay = static_cast(properties.rts_delay); for (const auto& [modeStr, portMode] : config::validPortModes) { if (modeStr == properties.mode) { config.portMode = portMode; break; } } if (config.portMode == PortMode::unknown) { error("Invalid port mode {PORT_MODE} for {NAME}", "PORT_MODE", properties.mode, "NAME", properties.name); return false; } debug("Base Port config: {NAME} {PORT_MODE} {BAUD_RATE} {RTS_DELAY}", "NAME", config.name, "PORT_MODE", config.portMode, "BAUD_RATE", config.baudRate, "RTS_DELAY", config.rtsDelay); return true; } } // namespace config class BasePort { public: explicit BasePort(sdbusplus::async::context& ctx, const config::Config& config, const std::string& devicePath); auto readHoldingRegisters(uint8_t deviceAddress, uint16_t registerOffset, uint32_t baudRate, Parity parity, std::vector& registers) -> sdbusplus::async::task; private: std::string name; int fd = -1; std::unique_ptr modbus; sdbusplus::async::mutex mutex; }; } // namespace phosphor::modbus::rtu::port