• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wirenboard / wb-mqtt-serial / 676

25 Jul 2025 11:44AM UTC coverage: 72.932%. Remained the same
676

push

github

web-flow
Revert "Merge branch 'feature/modbus-tcp-rpc'"

6463 of 9226 branches covered (70.05%)

0 of 5 new or added lines in 2 files covered. (0.0%)

26 existing lines in 1 file now uncovered.

12370 of 16961 relevant lines covered (72.93%)

373.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/rpc/rpc_port_load_modbus_serial_client_task.cpp
1
#include "rpc_port_load_modbus_serial_client_task.h"
2
#include "modbus_base.h"
3
#include "rpc_port_handler.h"
4
#include "serial_exc.h"
5
#include "serial_port.h"
6

7
template<> bool inline WBMQTT::JSON::Is<uint8_t>(const Json::Value& value)
×
8
{
9
    return value.isUInt();
×
10
}
11

12
template<> inline uint8_t WBMQTT::JSON::As<uint8_t>(const Json::Value& value)
×
13
{
14
    return value.asUInt() & 0xFF;
×
15
}
16

17
template<> bool inline WBMQTT::JSON::Is<uint16_t>(const Json::Value& value)
×
18
{
19
    return value.isUInt();
×
20
}
21

22
template<> inline uint16_t WBMQTT::JSON::As<uint16_t>(const Json::Value& value)
×
23
{
24
    return value.asUInt() & 0xFFFF;
×
25
}
26

27
template<> bool inline WBMQTT::JSON::Is<Modbus::EFunction>(const Json::Value& value)
×
28
{
29
    if (!value.isUInt()) {
×
30
        return false;
×
31
    }
32
    auto fun = value.asUInt();
×
33
    return Modbus::IsSupportedFunction(fun & 0xFF);
×
34
}
35

36
template<> inline Modbus::EFunction WBMQTT::JSON::As<Modbus::EFunction>(const Json::Value& value)
×
37
{
38
    return static_cast<Modbus::EFunction>(value.asUInt() & 0xFF);
×
39
}
40

41
TRPCPortLoadModbusRequest::TRPCPortLoadModbusRequest(TRPCDeviceParametersCache& parametersCache)
×
42
    : ParametersCache(parametersCache)
×
43
{}
44

45
PRPCPortLoadModbusRequest ParseRPCPortLoadModbusRequest(const Json::Value& request,
×
46
                                                        TRPCDeviceParametersCache& parametersCache)
47
{
48
    PRPCPortLoadModbusRequest RPCRequest = std::make_shared<TRPCPortLoadModbusRequest>(parametersCache);
×
49

50
    try {
51
        ParseRPCPortLoadRequest(request, *RPCRequest);
×
52
        WBMQTT::JSON::Get(request, "slave_id", RPCRequest->SlaveId);
×
53
        WBMQTT::JSON::Get(request, "address", RPCRequest->Address);
×
54
        WBMQTT::JSON::Get(request, "count", RPCRequest->Count);
×
55
        WBMQTT::JSON::Get(request, "write_address", RPCRequest->WriteAddress);
×
56
        WBMQTT::JSON::Get(request, "write_count", RPCRequest->WriteCount);
×
57
        WBMQTT::JSON::Get(request, "function", RPCRequest->Function);
×
58
    } catch (const std::runtime_error& e) {
×
59
        throw TRPCException(e.what(), TRPCResultCode::RPC_WRONG_PARAM_VALUE);
×
60
    }
61

UNCOV
62
    return RPCRequest;
×
63
}
64

UNCOV
65
void ExecRPCPortLoadModbusRequest(TPort& port, PRPCPortLoadModbusRequest rpcRequest)
×
66
{
67
    try {
68
        port.CheckPortOpen();
×
69
        port.SkipNoise();
×
UNCOV
70
        port.SleepSinceLastInteraction(rpcRequest->FrameTimeout);
×
71

NEW
72
        Modbus::TModbusRTUTraits traits;
×
73
        auto pdu = Modbus::MakePDU(rpcRequest->Function,
×
UNCOV
74
                                   rpcRequest->Address,
×
UNCOV
75
                                   rpcRequest->Count,
×
76
                                   rpcRequest->WriteAddress,
×
77
                                   rpcRequest->WriteCount,
×
78
                                   rpcRequest->Message);
×
UNCOV
79
        auto responsePduSize = Modbus::CalcResponsePDUSize(rpcRequest->Function, rpcRequest->Count);
×
80
        auto res = traits.Transaction(port,
NEW
81
                                      rpcRequest->SlaveId,
×
82
                                      pdu,
83
                                      responsePduSize,
NEW
84
                                      rpcRequest->ResponseTimeout,
×
NEW
85
                                      rpcRequest->FrameTimeout);
×
86
        auto response = Modbus::ExtractResponseData(rpcRequest->Function, res.Pdu);
×
87

88
        if (rpcRequest->OnResult) {
×
89
            Json::Value replyJSON;
×
90
            replyJSON["response"] = FormatResponse(response, rpcRequest->Format);
×
UNCOV
91
            rpcRequest->OnResult(replyJSON);
×
92
        }
93

UNCOV
94
        if (rpcRequest->Function == Modbus::EFunction::FN_WRITE_SINGLE_COIL ||
×
95
            rpcRequest->Function == Modbus::EFunction::FN_WRITE_SINGLE_REGISTER ||
×
96
            rpcRequest->Function == Modbus::EFunction::FN_WRITE_MULTIPLE_COILS ||
×
97
            rpcRequest->Function == Modbus::EFunction::FN_WRITE_MULTIPLE_REGISTERS ||
×
98
            rpcRequest->Function == Modbus::EFunction::FN_READ_WRITE_MULTIPLE_REGISTERS)
×
99
        {
100
            std::string id = rpcRequest->ParametersCache.GetId(port, std::to_string(rpcRequest->SlaveId));
×
101
            rpcRequest->ParametersCache.Remove(id);
×
102
        }
UNCOV
103
    } catch (const Modbus::TModbusExceptionError& error) {
×
UNCOV
104
        Json::Value replyJSON;
×
UNCOV
105
        replyJSON["exception"]["code"] = error.GetExceptionCode();
×
UNCOV
106
        replyJSON["exception"]["msg"] = error.what();
×
107
        rpcRequest->OnResult(replyJSON);
×
UNCOV
108
    } catch (const TResponseTimeoutException& error) {
×
UNCOV
109
        if (rpcRequest->OnError) {
×
110
            rpcRequest->OnError(WBMQTT::E_RPC_REQUEST_TIMEOUT, error.what());
×
111
        }
112
    }
113
}
114

115
TRPCPortLoadModbusSerialClientTask::TRPCPortLoadModbusSerialClientTask(const Json::Value& request,
×
116
                                                                       WBMQTT::TMqttRpcServer::TResultCallback onResult,
117
                                                                       WBMQTT::TMqttRpcServer::TErrorCallback onError,
118
                                                                       TRPCDeviceParametersCache& parametersCache)
×
UNCOV
119
    : Request(ParseRPCPortLoadModbusRequest(request, parametersCache))
×
120
{
UNCOV
121
    Request->OnResult = onResult;
×
UNCOV
122
    Request->OnError = onError;
×
123
    ExpireTime = std::chrono::steady_clock::now() + Request->TotalTimeout;
×
124
}
125

UNCOV
126
ISerialClientTask::TRunResult TRPCPortLoadModbusSerialClientTask::Run(
×
127
    PPort port,
128
    TSerialClientDeviceAccessHandler& lastAccessedDevice,
129
    const std::list<PSerialDevice>& polledDevices)
130
{
131
    if (std::chrono::steady_clock::now() > ExpireTime) {
×
132
        if (Request->OnError) {
×
UNCOV
133
            Request->OnError(WBMQTT::E_RPC_REQUEST_TIMEOUT, "RPC request timeout");
×
134
        }
135
        return ISerialClientTask::TRunResult::OK;
×
136
    }
137

138
    try {
139
        if (!port->IsOpen()) {
×
UNCOV
140
            port->Open();
×
141
        }
142
        lastAccessedDevice.PrepareToAccess(*port, nullptr);
×
UNCOV
143
        TSerialPortSettingsGuard settingsGuard(port, Request->SerialPortSettings);
×
UNCOV
144
        ExecRPCPortLoadModbusRequest(*port, Request);
×
UNCOV
145
    } catch (const std::exception& error) {
×
UNCOV
146
        if (Request->OnError) {
×
UNCOV
147
            Request->OnError(WBMQTT::E_RPC_SERVER_ERROR, std::string("Port IO error: ") + error.what());
×
148
        }
149
    }
UNCOV
150
    return ISerialClientTask::TRunResult::OK;
×
151
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc