xref: /openbmc/phosphor-modbus/rtu/port/base_port.hpp (revision b62e3dfe5505fdb8c2ab96156b62e3bfb878b7a6)
17f9d41ddSJagpal Singh Gill #pragma once
27f9d41ddSJagpal Singh Gill 
37f9d41ddSJagpal Singh Gill #include "modbus/modbus.hpp"
47f9d41ddSJagpal Singh Gill 
57f9d41ddSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
67f9d41ddSJagpal Singh Gill #include <sdbusplus/async.hpp>
77f9d41ddSJagpal Singh Gill #include <xyz/openbmc_project/Configuration/USBPort/client.hpp>
87f9d41ddSJagpal Singh Gill 
97f9d41ddSJagpal Singh Gill #include <concepts>
107f9d41ddSJagpal Singh Gill 
117f9d41ddSJagpal Singh Gill namespace phosphor::modbus::rtu::port
127f9d41ddSJagpal Singh Gill {
137f9d41ddSJagpal Singh Gill 
147f9d41ddSJagpal Singh Gill using ModbusIntf = phosphor::modbus::rtu::Modbus;
157f9d41ddSJagpal Singh Gill 
167f9d41ddSJagpal Singh Gill namespace config
177f9d41ddSJagpal Singh Gill {
187f9d41ddSJagpal Singh Gill 
197f9d41ddSJagpal Singh Gill enum class PortMode
207f9d41ddSJagpal Singh Gill {
217f9d41ddSJagpal Singh Gill     rs232,
227f9d41ddSJagpal Singh Gill     rs485,
237f9d41ddSJagpal Singh Gill     unknown
247f9d41ddSJagpal Singh Gill };
257f9d41ddSJagpal Singh Gill 
267f9d41ddSJagpal Singh Gill static constexpr std::array<std::pair<std::string_view, PortMode>, 2>
277f9d41ddSJagpal Singh Gill     validPortModes = {{{"RS232", PortMode::rs232}, {"RS485", PortMode::rs485}}};
287f9d41ddSJagpal Singh Gill 
297f9d41ddSJagpal Singh Gill struct Config
307f9d41ddSJagpal Singh Gill {
317f9d41ddSJagpal Singh Gill     std::string name = "unknown";
327f9d41ddSJagpal Singh Gill     PortMode portMode = PortMode::unknown;
337f9d41ddSJagpal Singh Gill     uint32_t baudRate = 0;
347f9d41ddSJagpal Singh Gill     uint16_t rtsDelay = 0;
35*b62e3dfeSJagpal Singh Gill 
36*b62e3dfeSJagpal Singh Gill     virtual ~Config() = default;
377f9d41ddSJagpal Singh Gill };
387f9d41ddSJagpal Singh Gill 
397f9d41ddSJagpal Singh Gill template <typename T>
407f9d41ddSJagpal Singh Gill concept HasPropertiesMembers = requires(T properties) {
417f9d41ddSJagpal Singh Gill                                    {
427f9d41ddSJagpal Singh Gill                                        properties.name
437f9d41ddSJagpal Singh Gill                                    } -> std::same_as<std::string&>;
447f9d41ddSJagpal Singh Gill                                    {
457f9d41ddSJagpal Singh Gill                                        properties.mode
467f9d41ddSJagpal Singh Gill                                    } -> std::same_as<std::string&>;
477f9d41ddSJagpal Singh Gill                                    {
487f9d41ddSJagpal Singh Gill                                        properties.baud_rate
497f9d41ddSJagpal Singh Gill                                    } -> std::same_as<uint64_t&>;
507f9d41ddSJagpal Singh Gill                                    {
517f9d41ddSJagpal Singh Gill                                        properties.rts_delay
527f9d41ddSJagpal Singh Gill                                    } -> std::same_as<uint64_t&>;
537f9d41ddSJagpal Singh Gill                                };
547f9d41ddSJagpal Singh Gill 
557f9d41ddSJagpal Singh Gill template <typename T>
567f9d41ddSJagpal Singh Gill concept HasConfigMembers = requires(T config) {
577f9d41ddSJagpal Singh Gill                                { config.name } -> std::same_as<std::string&>;
587f9d41ddSJagpal Singh Gill                                { config.portMode } -> std::same_as<PortMode&>;
597f9d41ddSJagpal Singh Gill                                { config.baudRate } -> std::same_as<uint32_t&>;
607f9d41ddSJagpal Singh Gill                                { config.rtsDelay } -> std::same_as<uint16_t&>;
617f9d41ddSJagpal Singh Gill                            };
627f9d41ddSJagpal Singh Gill 
637f9d41ddSJagpal Singh Gill template <HasConfigMembers BaseConfig, HasPropertiesMembers BaseProperties>
updateBaseConfig(BaseConfig & config,const BaseProperties & properties)647f9d41ddSJagpal Singh Gill auto updateBaseConfig(BaseConfig& config, const BaseProperties& properties)
657f9d41ddSJagpal Singh Gill     -> bool
667f9d41ddSJagpal Singh Gill {
677f9d41ddSJagpal Singh Gill     PHOSPHOR_LOG2_USING;
687f9d41ddSJagpal Singh Gill 
697f9d41ddSJagpal Singh Gill     config.name = properties.name;
707f9d41ddSJagpal Singh Gill     config.baudRate = static_cast<uint32_t>(properties.baud_rate);
717f9d41ddSJagpal Singh Gill     config.rtsDelay = static_cast<uint16_t>(properties.rts_delay);
727f9d41ddSJagpal Singh Gill 
737f9d41ddSJagpal Singh Gill     for (const auto& [modeStr, portMode] : config::validPortModes)
747f9d41ddSJagpal Singh Gill     {
757f9d41ddSJagpal Singh Gill         if (modeStr == properties.mode)
767f9d41ddSJagpal Singh Gill         {
777f9d41ddSJagpal Singh Gill             config.portMode = portMode;
787f9d41ddSJagpal Singh Gill             break;
797f9d41ddSJagpal Singh Gill         }
807f9d41ddSJagpal Singh Gill     }
817f9d41ddSJagpal Singh Gill     if (config.portMode == PortMode::unknown)
827f9d41ddSJagpal Singh Gill     {
837f9d41ddSJagpal Singh Gill         error("Invalid port mode {PORT_MODE} for {NAME}", "PORT_MODE",
847f9d41ddSJagpal Singh Gill               properties.mode, "NAME", properties.name);
857f9d41ddSJagpal Singh Gill         return false;
867f9d41ddSJagpal Singh Gill     }
877f9d41ddSJagpal Singh Gill 
887f9d41ddSJagpal Singh Gill     debug("Base Port config: {NAME} {PORT_MODE} {BAUD_RATE} {RTS_DELAY}",
897f9d41ddSJagpal Singh Gill           "NAME", config.name, "PORT_MODE", config.portMode, "BAUD_RATE",
907f9d41ddSJagpal Singh Gill           config.baudRate, "RTS_DELAY", config.rtsDelay);
917f9d41ddSJagpal Singh Gill 
927f9d41ddSJagpal Singh Gill     return true;
937f9d41ddSJagpal Singh Gill }
947f9d41ddSJagpal Singh Gill 
957f9d41ddSJagpal Singh Gill } // namespace config
967f9d41ddSJagpal Singh Gill 
977f9d41ddSJagpal Singh Gill class BasePort
987f9d41ddSJagpal Singh Gill {
997f9d41ddSJagpal Singh Gill   public:
1007f9d41ddSJagpal Singh Gill     explicit BasePort(sdbusplus::async::context& ctx,
1017f9d41ddSJagpal Singh Gill                       const config::Config& config,
1027f9d41ddSJagpal Singh Gill                       const std::string& devicePath);
1037f9d41ddSJagpal Singh Gill 
1047f9d41ddSJagpal Singh Gill     auto readHoldingRegisters(uint8_t deviceAddress, uint16_t registerOffset,
1057f9d41ddSJagpal Singh Gill                               uint32_t baudRate, Parity parity,
1067f9d41ddSJagpal Singh Gill                               std::vector<uint16_t>& registers)
1077f9d41ddSJagpal Singh Gill         -> sdbusplus::async::task<bool>;
1087f9d41ddSJagpal Singh Gill 
1097f9d41ddSJagpal Singh Gill   private:
1107f9d41ddSJagpal Singh Gill     std::string name;
1117f9d41ddSJagpal Singh Gill     int fd = -1;
1127f9d41ddSJagpal Singh Gill     std::unique_ptr<ModbusIntf> modbus;
1137f9d41ddSJagpal Singh Gill     sdbusplus::async::mutex mutex;
1147f9d41ddSJagpal Singh Gill };
1157f9d41ddSJagpal Singh Gill 
1167f9d41ddSJagpal Singh Gill } // namespace phosphor::modbus::rtu::port
117