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

wirenboard / wb-mqtt-serial / 2

29 Dec 2025 12:28PM UTC coverage: 76.817% (+4.0%) from 72.836%
2

Pull #1045

github

54aa0c
pgasheev
up changelog
Pull Request #1045: Fix firmware version in WB-M1W2 template

6873 of 9161 branches covered (75.02%)

12966 of 16879 relevant lines covered (76.82%)

1651.61 hits per line

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

0.0
/src/rpc/rpc_port_setup_serial_client_task.cpp
1
#include "rpc_port_setup_serial_client_task.h"
2
#include "modbus_common.h"
3
#include "port/serial_port.h"
4
#include "rpc_helpers.h"
5
#include "serial_exc.h"
6
#include "wb_registers.h"
7

8
namespace
9
{
10
    TRPCPortSetupRequestItem ParseRPCPortSetupItemRequest(const Json::Value& request)
×
11
    {
12
        TRPCPortSetupRequestItem res;
×
13

14
        res.SlaveId = request["slave_id"].asUInt();
×
15

16
        if (request.isMember("sn")) {
×
17
            res.Sn = request["sn"].asUInt();
×
18
        }
19

20
        res.SerialPortSettings = ParseRPCSerialPortSettings(request);
×
21

22
        if (!request.isMember("cfg")) {
×
23
            return res;
×
24
        }
25

26
        const std::vector<std::string> regNames = {WbRegisters::BAUD_RATE_REGISTER_NAME,
27
                                                   WbRegisters::PARITY_REGISTER_NAME,
28
                                                   WbRegisters::STOP_BITS_REGISTER_NAME,
29
                                                   WbRegisters::SLAVE_ID_REGISTER_NAME};
×
30
        for (auto& regName: regNames) {
×
31
            if (request["cfg"].isMember(regName)) {
×
32
                auto regConfig = WbRegisters::GetRegisterConfig(regName);
×
33
                if (regConfig) {
×
34
                    PDeviceSetupItemConfig setup_item_config(
35
                        std::make_shared<TDeviceSetupItemConfig>(regName,
36
                                                                 regConfig,
37
                                                                 request["cfg"][regName].asString()));
×
38
                    res.Regs.insert(std::make_shared<TDeviceSetupItem>(setup_item_config, nullptr));
×
39
                }
40
            }
41
        }
42

43
        return res;
×
44
    }
45

46
    PRPCPortSetupRequest ParseRPCPortSetupRequest(const Json::Value& requestJson)
×
47
    {
48
        auto RPCRequest = std::make_shared<TRPCPortSetupRequest>();
×
49

50
        try {
51
            for (auto& request: requestJson["items"]) {
×
52
                RPCRequest->Items.push_back(ParseRPCPortSetupItemRequest(request));
×
53
            }
54

55
            WBMQTT::JSON::Get(requestJson, "total_timeout", RPCRequest->TotalTimeout);
×
56
        } catch (const std::runtime_error& e) {
×
57
            throw TRPCException(e.what(), TRPCResultCode::RPC_WRONG_PARAM_VALUE);
×
58
        }
59

60
        return RPCRequest;
×
61
    }
62
}
63

64
TRPCPortSetupSerialClientTask::TRPCPortSetupSerialClientTask(const Json::Value& request,
×
65
                                                             WBMQTT::TMqttRpcServer::TResultCallback onResult,
66
                                                             WBMQTT::TMqttRpcServer::TErrorCallback onError)
×
67
    : Request(ParseRPCPortSetupRequest(request))
×
68
{
69
    Request->OnResult = onResult;
×
70
    Request->OnError = onError;
×
71
    ExpireTime = std::chrono::steady_clock::now() + Request->TotalTimeout;
×
72
}
73

74
ISerialClientTask::TRunResult TRPCPortSetupSerialClientTask::Run(PFeaturePort port,
×
75
                                                                 TSerialClientDeviceAccessHandler& lastAccessedDevice,
76
                                                                 const std::list<PSerialDevice>& polledDevices)
77
{
78
    if (std::chrono::steady_clock::now() > ExpireTime) {
×
79
        if (Request->OnError) {
×
80
            Request->OnError(WBMQTT::E_RPC_REQUEST_TIMEOUT, "RPC request timeout");
×
81
        }
82
        return ISerialClientTask::TRunResult::OK;
×
83
    }
84

85
    try {
86
        if (!port->IsOpen()) {
×
87
            port->Open();
×
88
        }
89
        port->SkipNoise();
×
90
        std::unique_ptr<Modbus::IModbusTraits> baseTraits;
×
91
        if (port->IsModbusTcp()) {
×
92
            baseTraits = std::make_unique<Modbus::TModbusTCPTraits>();
×
93
        } else {
94
            baseTraits = std::make_unique<Modbus::TModbusRTUTraits>();
×
95
        }
96
        ModbusExt::TModbusTraits fastModbusTraits(std::move(baseTraits));
×
97
        Modbus::TModbusRTUTraits rtuTraits(false);
×
98
        auto frameTimeout =
99
            std::chrono::ceil<std::chrono::milliseconds>(port->GetSendTimeBytes(Modbus::STANDARD_FRAME_TIMEOUT_BYTES));
×
100
        for (auto item: Request->Items) {
×
101
            TSerialPortSettingsGuard settingsGuard(port, item.SerialPortSettings);
×
102
            port->SleepSinceLastInteraction(frameTimeout);
×
103
            lastAccessedDevice.PrepareToAccess(*port, nullptr);
×
104

105
            if (item.Sn) {
×
106
                fastModbusTraits.SetSn(item.Sn.value());
×
107
            }
108
            Modbus::TRegisterCache cache;
×
109
            Modbus::WriteSetupRegisters(item.Sn ? static_cast<Modbus::IModbusTraits&>(fastModbusTraits)
×
110
                                                : static_cast<Modbus::IModbusTraits&>(rtuTraits),
×
111
                                        *port,
×
112
                                        item.SlaveId,
113
                                        item.Regs,
114
                                        cache,
115
                                        std::chrono::microseconds(0),
×
116
                                        std::chrono::milliseconds(1),
×
117
                                        frameTimeout,
118
                                        false);
119
        }
120

121
        if (Request->OnResult) {
×
122
            Request->OnResult(Json::Value(Json::objectValue));
×
123
        }
124
    } catch (const std::exception& error) {
×
125
        if (Request->OnError) {
×
126
            Request->OnError(WBMQTT::E_RPC_SERVER_ERROR, std::string("Port IO error: ") + error.what());
×
127
        }
128
    }
129
    return ISerialClientTask::TRunResult::OK;
×
130
}
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