xref: /openbmc/phosphor-modbus/rtu/port/base_port.hpp (revision 7f9d41ddfad8c74d51fa1cf4a591b7f085254396)
1*7f9d41ddSJagpal Singh Gill #pragma once
2*7f9d41ddSJagpal Singh Gill 
3*7f9d41ddSJagpal Singh Gill #include "modbus/modbus.hpp"
4*7f9d41ddSJagpal Singh Gill 
5*7f9d41ddSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
6*7f9d41ddSJagpal Singh Gill #include <sdbusplus/async.hpp>
7*7f9d41ddSJagpal Singh Gill #include <xyz/openbmc_project/Configuration/USBPort/client.hpp>
8*7f9d41ddSJagpal Singh Gill 
9*7f9d41ddSJagpal Singh Gill #include <concepts>
10*7f9d41ddSJagpal Singh Gill 
11*7f9d41ddSJagpal Singh Gill namespace phosphor::modbus::rtu::port
12*7f9d41ddSJagpal Singh Gill {
13*7f9d41ddSJagpal Singh Gill 
14*7f9d41ddSJagpal Singh Gill using ModbusIntf = phosphor::modbus::rtu::Modbus;
15*7f9d41ddSJagpal Singh Gill 
16*7f9d41ddSJagpal Singh Gill namespace config
17*7f9d41ddSJagpal Singh Gill {
18*7f9d41ddSJagpal Singh Gill 
19*7f9d41ddSJagpal Singh Gill enum class PortMode
20*7f9d41ddSJagpal Singh Gill {
21*7f9d41ddSJagpal Singh Gill     rs232,
22*7f9d41ddSJagpal Singh Gill     rs485,
23*7f9d41ddSJagpal Singh Gill     unknown
24*7f9d41ddSJagpal Singh Gill };
25*7f9d41ddSJagpal Singh Gill 
26*7f9d41ddSJagpal Singh Gill static constexpr std::array<std::pair<std::string_view, PortMode>, 2>
27*7f9d41ddSJagpal Singh Gill     validPortModes = {{{"RS232", PortMode::rs232}, {"RS485", PortMode::rs485}}};
28*7f9d41ddSJagpal Singh Gill 
29*7f9d41ddSJagpal Singh Gill struct Config
30*7f9d41ddSJagpal Singh Gill {
31*7f9d41ddSJagpal Singh Gill     std::string name = "unknown";
32*7f9d41ddSJagpal Singh Gill     PortMode portMode = PortMode::unknown;
33*7f9d41ddSJagpal Singh Gill     uint32_t baudRate = 0;
34*7f9d41ddSJagpal Singh Gill     uint16_t rtsDelay = 0;
35*7f9d41ddSJagpal Singh Gill };
36*7f9d41ddSJagpal Singh Gill 
37*7f9d41ddSJagpal Singh Gill template <typename T>
38*7f9d41ddSJagpal Singh Gill concept HasPropertiesMembers = requires(T properties) {
39*7f9d41ddSJagpal Singh Gill                                    {
40*7f9d41ddSJagpal Singh Gill                                        properties.name
41*7f9d41ddSJagpal Singh Gill                                    } -> std::same_as<std::string&>;
42*7f9d41ddSJagpal Singh Gill                                    {
43*7f9d41ddSJagpal Singh Gill                                        properties.mode
44*7f9d41ddSJagpal Singh Gill                                    } -> std::same_as<std::string&>;
45*7f9d41ddSJagpal Singh Gill                                    {
46*7f9d41ddSJagpal Singh Gill                                        properties.baud_rate
47*7f9d41ddSJagpal Singh Gill                                    } -> std::same_as<uint64_t&>;
48*7f9d41ddSJagpal Singh Gill                                    {
49*7f9d41ddSJagpal Singh Gill                                        properties.rts_delay
50*7f9d41ddSJagpal Singh Gill                                    } -> std::same_as<uint64_t&>;
51*7f9d41ddSJagpal Singh Gill                                };
52*7f9d41ddSJagpal Singh Gill 
53*7f9d41ddSJagpal Singh Gill template <typename T>
54*7f9d41ddSJagpal Singh Gill concept HasConfigMembers = requires(T config) {
55*7f9d41ddSJagpal Singh Gill                                { config.name } -> std::same_as<std::string&>;
56*7f9d41ddSJagpal Singh Gill                                { config.portMode } -> std::same_as<PortMode&>;
57*7f9d41ddSJagpal Singh Gill                                { config.baudRate } -> std::same_as<uint32_t&>;
58*7f9d41ddSJagpal Singh Gill                                { config.rtsDelay } -> std::same_as<uint16_t&>;
59*7f9d41ddSJagpal Singh Gill                            };
60*7f9d41ddSJagpal Singh Gill 
61*7f9d41ddSJagpal Singh Gill template <HasConfigMembers BaseConfig, HasPropertiesMembers BaseProperties>
62*7f9d41ddSJagpal Singh Gill auto updateBaseConfig(BaseConfig& config, const BaseProperties& properties)
63*7f9d41ddSJagpal Singh Gill     -> bool
64*7f9d41ddSJagpal Singh Gill {
65*7f9d41ddSJagpal Singh Gill     PHOSPHOR_LOG2_USING;
66*7f9d41ddSJagpal Singh Gill 
67*7f9d41ddSJagpal Singh Gill     config.name = properties.name;
68*7f9d41ddSJagpal Singh Gill     config.baudRate = static_cast<uint32_t>(properties.baud_rate);
69*7f9d41ddSJagpal Singh Gill     config.rtsDelay = static_cast<uint16_t>(properties.rts_delay);
70*7f9d41ddSJagpal Singh Gill 
71*7f9d41ddSJagpal Singh Gill     for (const auto& [modeStr, portMode] : config::validPortModes)
72*7f9d41ddSJagpal Singh Gill     {
73*7f9d41ddSJagpal Singh Gill         if (modeStr == properties.mode)
74*7f9d41ddSJagpal Singh Gill         {
75*7f9d41ddSJagpal Singh Gill             config.portMode = portMode;
76*7f9d41ddSJagpal Singh Gill             break;
77*7f9d41ddSJagpal Singh Gill         }
78*7f9d41ddSJagpal Singh Gill     }
79*7f9d41ddSJagpal Singh Gill     if (config.portMode == PortMode::unknown)
80*7f9d41ddSJagpal Singh Gill     {
81*7f9d41ddSJagpal Singh Gill         error("Invalid port mode {PORT_MODE} for {NAME}", "PORT_MODE",
82*7f9d41ddSJagpal Singh Gill               properties.mode, "NAME", properties.name);
83*7f9d41ddSJagpal Singh Gill         return false;
84*7f9d41ddSJagpal Singh Gill     }
85*7f9d41ddSJagpal Singh Gill 
86*7f9d41ddSJagpal Singh Gill     debug("Base Port config: {NAME} {PORT_MODE} {BAUD_RATE} {RTS_DELAY}",
87*7f9d41ddSJagpal Singh Gill           "NAME", config.name, "PORT_MODE", config.portMode, "BAUD_RATE",
88*7f9d41ddSJagpal Singh Gill           config.baudRate, "RTS_DELAY", config.rtsDelay);
89*7f9d41ddSJagpal Singh Gill 
90*7f9d41ddSJagpal Singh Gill     return true;
91*7f9d41ddSJagpal Singh Gill }
92*7f9d41ddSJagpal Singh Gill 
93*7f9d41ddSJagpal Singh Gill } // namespace config
94*7f9d41ddSJagpal Singh Gill 
95*7f9d41ddSJagpal Singh Gill class BasePort
96*7f9d41ddSJagpal Singh Gill {
97*7f9d41ddSJagpal Singh Gill   public:
98*7f9d41ddSJagpal Singh Gill     explicit BasePort(sdbusplus::async::context& ctx,
99*7f9d41ddSJagpal Singh Gill                       const config::Config& config,
100*7f9d41ddSJagpal Singh Gill                       const std::string& devicePath);
101*7f9d41ddSJagpal Singh Gill 
102*7f9d41ddSJagpal Singh Gill     auto readHoldingRegisters(uint8_t deviceAddress, uint16_t registerOffset,
103*7f9d41ddSJagpal Singh Gill                               uint32_t baudRate, Parity parity,
104*7f9d41ddSJagpal Singh Gill                               std::vector<uint16_t>& registers)
105*7f9d41ddSJagpal Singh Gill         -> sdbusplus::async::task<bool>;
106*7f9d41ddSJagpal Singh Gill 
107*7f9d41ddSJagpal Singh Gill   private:
108*7f9d41ddSJagpal Singh Gill     std::string name;
109*7f9d41ddSJagpal Singh Gill     int fd = -1;
110*7f9d41ddSJagpal Singh Gill     std::unique_ptr<ModbusIntf> modbus;
111*7f9d41ddSJagpal Singh Gill     sdbusplus::async::mutex mutex;
112*7f9d41ddSJagpal Singh Gill };
113*7f9d41ddSJagpal Singh Gill 
114*7f9d41ddSJagpal Singh Gill } // namespace phosphor::modbus::rtu::port
115