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

wirenboard / wb-mqtt-serial / 7

26 Nov 2025 06:26AM UTC coverage: 76.773% (-0.1%) from 76.899%
7

push

github

u236
Merge remote-tracking branch 'origin/master' into wasm

6865 of 9158 branches covered (74.96%)

17 of 112 new or added lines in 10 files covered. (15.18%)

6 existing lines in 2 files now uncovered.

12957 of 16877 relevant lines covered (76.77%)

825.72 hits per line

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

0.0
/src/rpc/rpc_device_set_task.cpp
1
#include "rpc_device_set_task.h"
2
#include "config_merge_template.h"
3
#include "rpc_helpers.h"
4

5
#define LOG(logger) ::logger.Log() << "[RPC] "
6

7
namespace
8
{
9
    void ExecRPCRequest(PPort port, PRPCDeviceSetRequest rpcRequest)
×
10
    {
11
        if (!rpcRequest->OnResult) {
×
12
            return;
×
13
        }
14

15
        TDeviceSetupItems setupItems;
×
16
        rpcRequest->GetChannelsSetupItems(setupItems);
×
17
        rpcRequest->GetParametersSetupItems(setupItems);
×
18
        if (setupItems.empty()) {
×
NEW
19
            rpcRequest->OnResult(Json::Value(Json::objectValue));
×
20
        }
21

22
        std::string error;
×
23
        try {
24
            rpcRequest->Device->Prepare(*port, TDevicePrepareMode::WITHOUT_SETUP);
×
25
        } catch (const TSerialDeviceException& e) {
×
26
            error = std::string("Failed to prepare session: ") + e.what();
×
27
            LOG(Warn) << port->GetDescription() << " " << rpcRequest->Device->ToString() << ": " << error;
×
28
            throw TRPCException(error, TRPCResultCode::RPC_WRONG_PARAM_VALUE);
×
29
        }
30

31
        try {
32
            rpcRequest->Device->WriteSetupRegisters(*port, setupItems, true);
×
33
        } catch (const TSerialDeviceException& e) {
×
34
            error = e.what();
×
35
        }
36

37
        try {
38
            rpcRequest->Device->EndSession(*port);
×
39
        } catch (const TSerialDeviceException& e) {
×
40
            LOG(Warn) << port->GetDescription() << rpcRequest->Device->ToString()
×
41
                      << " unable to end session: " << e.what();
×
42
        }
43

44
        if (!error.empty()) {
×
45
            LOG(Warn) << port->GetDescription() << rpcRequest->Device->ToString() << ": " << error;
×
46
            throw TRPCException(error, TRPCResultCode::RPC_WRONG_PARAM_VALUE);
×
47
        }
48

NEW
49
        rpcRequest->OnResult(Json::Value(Json::objectValue));
×
50
    }
51
} // namespace
52

53
TRPCDeviceSetRequest::TRPCDeviceSetRequest(const TDeviceProtocolParams& protocolParams,
×
54
                                           PSerialDevice device,
55
                                           PDeviceTemplate deviceTemplate,
56
                                           bool deviceFromConfig)
×
57
    : TRPCDeviceRequest(protocolParams, device, deviceTemplate, deviceFromConfig)
×
58
{}
59

60
void TRPCDeviceSetRequest::ParseRequestItems(const Json::Value& items,
×
61
                                             std::unordered_map<std::string, std::string>& map)
62
{
63
    for (auto it = items.begin(); it != items.end(); ++it) {
×
64
        map[it.key().asString()] = (*it).asString();
×
65
    }
66
}
67

68
void TRPCDeviceSetRequest::GetChannelsSetupItems(TDeviceSetupItems& setupItems)
×
69
{
70
    for (auto item: DeviceTemplate->GetTemplate()["channels"]) {
×
71
        if (item["readonly"].asBool()) {
×
72
            continue;
×
73
        }
74
        auto id = item["name"].asString();
×
75
        if (Channels.count(id)) {
×
76
            setupItems.insert(CreateSetupItem(id, item, Channels[id]));
×
77
            Channels.erase(id);
×
78
        }
79
    }
80
    if (!Channels.empty()) {
×
81
        throw TRPCException("Channel \"" + Channels.begin()->first + "\" is read only or not found in \"" +
×
82
                                DeviceTemplate->Type + "\" device template",
×
83
                            TRPCResultCode::RPC_WRONG_PARAM_VALUE);
×
84
    }
85
}
86

87
void TRPCDeviceSetRequest::GetParametersSetupItems(TDeviceSetupItems& setupItems)
×
88
{
89
    auto params = DeviceTemplate->GetTemplate()["parameters"];
×
90
    for (auto it = params.begin(); it != params.end(); ++it) {
×
91
        auto item = *it;
×
92
        if (item["readonly"].asBool()) {
×
93
            continue;
×
94
        }
95
        auto id = params.isObject() ? it.key().asString() : item["id"].asString();
×
96
        if (Parameters.count(id)) {
×
97
            setupItems.insert(CreateSetupItem(id, item, Parameters[id]));
×
98
            Parameters.erase(id);
×
99
        }
100
    }
101
    if (!Parameters.empty()) {
×
102
        throw TRPCException("Parameter \"" + Parameters.begin()->first + "\" is read only or not found in \"" +
×
103
                                DeviceTemplate->Type + "\" device template",
×
104
                            TRPCResultCode::RPC_WRONG_PARAM_VALUE);
×
105
    }
106
}
107

108
PDeviceSetupItem TRPCDeviceSetRequest::CreateSetupItem(const std::string& id,
×
109
                                                       const Json::Value& data,
110
                                                       const std::string& value)
111
{
112
    auto config = LoadRegisterConfig(data,
113
                                     *ProtocolParams.protocol->GetRegTypes(),
×
114
                                     std::string(),
×
115
                                     *ProtocolParams.factory,
×
116
                                     ProtocolParams.factory->GetRegisterAddressFactory().GetBaseRegisterAddress(),
×
117
                                     0);
×
118
    auto itemConfig = std::make_shared<TDeviceSetupItemConfig>(id, config.RegisterConfig, value);
×
119
    return std::make_shared<TDeviceSetupItem>(itemConfig, Device);
×
120
}
121

122
PRPCDeviceSetRequest ParseRPCDeviceSetRequest(const Json::Value& request,
×
123
                                              const TDeviceProtocolParams& protocolParams,
124
                                              PSerialDevice device,
125
                                              PDeviceTemplate deviceTemplate,
126
                                              bool deviceFromConfig,
127
                                              WBMQTT::TMqttRpcServer::TResultCallback onResult,
128
                                              WBMQTT::TMqttRpcServer::TErrorCallback onError)
129
{
130
    auto res = std::make_shared<TRPCDeviceSetRequest>(protocolParams, device, deviceTemplate, deviceFromConfig);
×
131
    res->ParseSettings(request, onResult, onError);
×
132
    res->ParseRequestItems(request["channels"], res->Channels);
×
133
    res->ParseRequestItems(request["parameters"], res->Parameters);
×
134
    return res;
×
135
}
136

137
TRPCDeviceSetSerialClientTask::TRPCDeviceSetSerialClientTask(PRPCDeviceSetRequest request): Request(request)
×
138
{
139
    ExpireTime = std::chrono::steady_clock::now() + Request->TotalTimeout;
×
140
}
141

142
ISerialClientTask::TRunResult TRPCDeviceSetSerialClientTask::Run(PFeaturePort port,
×
143
                                                                 TSerialClientDeviceAccessHandler& lastAccessedDevice,
144
                                                                 const std::list<PSerialDevice>& polledDevices)
145
{
146
    if (std::chrono::steady_clock::now() > ExpireTime) {
×
147
        if (Request->OnError) {
×
148
            Request->OnError(WBMQTT::E_RPC_REQUEST_TIMEOUT, "RPC request timeout");
×
149
        }
150
        return ISerialClientTask::TRunResult::OK;
×
151
    }
152
    try {
153
        if (!port->IsOpen()) {
×
154
            port->Open();
×
155
        }
156
        lastAccessedDevice.PrepareToAccess(*port, nullptr);
×
157
        if (!Request->DeviceFromConfig) {
×
158
            TSerialPortSettingsGuard settingsGuard(port, Request->SerialPortSettings);
×
NEW
159
            ExecRPCRequest(port, Request);
×
160
        } else {
NEW
161
            ExecRPCRequest(port, Request);
×
162
        }
163
    } catch (const std::exception& error) {
×
164
        if (Request->OnError) {
×
165
            Request->OnError(WBMQTT::E_RPC_SERVER_ERROR, std::string("Port IO error: ") + error.what());
×
166
        }
167
    }
168
    return ISerialClientTask::TRunResult::OK;
×
169
}
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