xref: /openbmc/phosphor-modbus/rtu/port/base_port.cpp (revision 7f9d41ddfad8c74d51fa1cf4a591b7f085254396)
1 #include "base_port.hpp"
2 
3 #include "common/entity_manager_interface.hpp"
4 
5 #include <fcntl.h>
6 
7 #include <phosphor-logging/lg2.hpp>
8 #include <xyz/openbmc_project/Configuration/USBPort/client.hpp>
9 
10 #include <filesystem>
11 #include <format>
12 #include <optional>
13 #include <regex>
14 
15 namespace phosphor::modbus::rtu::port
16 {
17 
18 PHOSPHOR_LOG2_USING;
19 
BasePort(sdbusplus::async::context & ctx,const config::Config & config,const std::string & devicePath)20 BasePort::BasePort(sdbusplus::async::context& ctx, const config::Config& config,
21                    const std::string& devicePath) :
22     name(config.name), mutex(config.name)
23 {
24     fd = open(devicePath.c_str(), O_RDWR | O_NOCTTY);
25     if (fd == -1)
26     {
27         throw("Failed to open serial port " + devicePath +
28               " with error: " + strerror(errno));
29     }
30 
31     modbus =
32         std::make_unique<ModbusIntf>(ctx, fd, config.baudRate, config.rtsDelay);
33     if (!modbus)
34     {
35         throw std::runtime_error("Failed to create Modbus interface");
36     }
37 
38     info("Serial port {NAME} created successfully", "NAME", config.name);
39 }
40 
readHoldingRegisters(uint8_t deviceAddress,uint16_t registerOffset,uint32_t baudRate,Parity parity,std::vector<uint16_t> & registers)41 auto BasePort::readHoldingRegisters(
42     uint8_t deviceAddress, uint16_t registerOffset, uint32_t baudRate,
43     Parity parity, std::vector<uint16_t>& registers)
44     -> sdbusplus::async::task<bool>
45 {
46     sdbusplus::async::lock_guard lg{mutex};
47     co_await lg.lock();
48 
49     if (!modbus->setProperties(baudRate, parity))
50     {
51         error("Failed to set serial port properties");
52         co_return false;
53     }
54 
55     debug(
56         "Reading holding registers from device {ADDRESS} {PORT} at offset {OFFSET}",
57         "ADDRESS", deviceAddress, "PORT", name, "OFFSET", registerOffset);
58 
59     auto ret = co_await modbus->readHoldingRegisters(deviceAddress,
60                                                      registerOffset, registers);
61     if (!ret)
62     {
63         error(
64             "Failed to read holding registers from device {ADDRESS} {PORT} at offset "
65             "{OFFSET}",
66             "ADDRESS", deviceAddress, "PORT", name, "OFFSET", registerOffset);
67     }
68 
69     co_return ret;
70 }
71 
72 } // namespace phosphor::modbus::rtu::port
73