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

wirenboard / wb-mqtt-opcua / 75

02 Mar 2026 04:58AM UTC coverage: 57.527% (-0.4%) from 57.942%
75

push

github

web-flow
Add option to prevent groups update (#34)

168 of 285 branches covered (58.95%)

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

321 of 558 relevant lines covered (57.53%)

1.44 hits per line

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

0.0
/src/main.cpp
1
#include <getopt.h>
2

3
#include <wblib/signal_handling.h>
4
#include <wblib/wbmqtt.h>
5

6
#include "OPCUAServer.h"
7
#include "log.h"
8

9
#include "config_parser.h"
10
#include "opcua_exception.h"
11

12
#define LOG(logger) ::logger.Log() << "[main] "
13

14
#define STR(x) #x
15
#define XSTR(x) STR(x)
16

17
using namespace std;
18
using namespace WBMQTT;
19

20
const auto APP_NAME = "wb-mqtt-opcua";
21
const auto CONFIG_FULL_FILE_PATH = "/etc/wb-mqtt-opcua.conf";
22
const auto CONFIG_JSON_SCHEMA_FULL_FILE_PATH = "/usr/share/wb-mqtt-confed/schemas/wb-mqtt-opcua.schema.json";
23

24
const auto DRIVER_STOP_TIMEOUT_S = chrono::seconds(10);
25

26
//! Maximun time to start application. Exceded timeout will case application termination.
27
const auto DRIVER_INIT_TIMEOUT_S = chrono::seconds(60);
28

29
const auto EXIT_NOTCONFIGURED = 6; // Error in config file; do not auto-restart by systemd, treat as failure
30
const auto EXIT_NOTRUNNING = 7;    // Config is empty; do not auto-restart by systemd, do not treat as failure
31

32
namespace
33
{
34
    void PrintStartupInfo()
×
35
    {
36
        std::string commit(XSTR(WBMQTT_COMMIT));
×
37
        cout << APP_NAME << " " << XSTR(WBMQTT_VERSION);
×
38
        if (!commit.empty()) {
×
39
            cout << " git " << commit;
×
40
        }
41
        cout << endl;
×
42
    }
43

44
    void PrintUsage()
×
45
    {
46
        PrintStartupInfo();
×
47
        cout << "Usage:" << endl
×
48
             << " " << APP_NAME << " [options]" << endl
×
49
             << "Options:" << endl
×
50
             << "  -d  level     enable debuging output:" << endl
×
51
             << "                  1 - " << APP_NAME << " only;" << endl
×
52
             << "                  2 - MQTT only;" << endl
×
53
             << "                  3 - both;" << endl
×
54
             << "                  negative values - silent mode (-1, -2, -3))" << endl
×
55
             << "  -c  config    config file (default " << CONFIG_FULL_FILE_PATH << ")" << endl
×
56
             << "  -g  config    update config file with information about active MQTT publications" << endl
×
57
             << "  -p  port      MQTT broker port (default: 1883)" << endl
×
58
             << "  -h  IP        MQTT broker IP (default: localhost)" << endl
×
59
             << "  -u  user      MQTT user (optional)" << endl
×
60
             << "  -P  password  MQTT user password (optional)" << endl
×
61
             << "  -T  prefix    MQTT topic prefix (optional)" << endl;
×
62
    }
63

64
    void ParseCommadLine(int argc, char* argv[], WBMQTT::TMosquittoMqttConfig& mqttConfig, string& configFile)
×
65
    {
66
        int debugLevel = 0;
×
67
        int c;
68

69
        while ((c = getopt(argc, argv, "d:c:g:p:h:T:u:P:")) != -1) {
×
70
            switch (c) {
×
71
                case 'd':
×
72
                    debugLevel = stoi(optarg);
×
73
                    break;
×
74
                case 'c':
×
75
                    configFile = optarg;
×
76
                    break;
×
77
                case 'g':
×
78
                    try {
79
                        UpdateConfig(optarg, CONFIG_JSON_SCHEMA_FULL_FILE_PATH);
×
80
                    } catch (const exception& e) {
×
81
                        std::cerr << "FATAL: " << e.what();
×
82
                        exit(1);
×
83
                    }
84
                    exit(0);
×
85
                case 'p':
×
86
                    mqttConfig.Port = stoi(optarg);
×
87
                    break;
×
88
                case 'h':
×
89
                    mqttConfig.Host = optarg;
×
90
                    break;
×
91
                case 'T':
×
92
                    mqttConfig.Prefix = optarg;
×
93
                    break;
×
94
                case 'u':
×
95
                    mqttConfig.User = optarg;
×
96
                    break;
×
97
                case 'P':
×
98
                    mqttConfig.Password = optarg;
×
99
                    break;
×
100
                default:
×
101
                    PrintUsage();
×
102
                    exit(2);
×
103
            }
104
        }
105

106
        switch (debugLevel) {
×
107
            case 0:
×
108
                break;
×
109
            case -1:
×
110
                ::Info.SetEnabled(false);
×
111
                break;
×
112
            case -2:
×
113
                WBMQTT::Info.SetEnabled(false);
×
114
                break;
×
115
            case -3:
×
116
                WBMQTT::Info.SetEnabled(false);
×
117
                ::Info.SetEnabled(false);
×
118
                break;
×
119
            case 1:
×
120
                ::Debug.SetEnabled(true);
×
121
                break;
×
122
            case 2:
×
123
                WBMQTT::Debug.SetEnabled(true);
×
124
                break;
×
125
            case 3:
×
126
                WBMQTT::Debug.SetEnabled(true);
×
127
                ::Debug.SetEnabled(true);
×
128
                break;
×
129
            default:
×
130
                cout << "Invalid -d parameter value " << debugLevel << endl;
×
131
                PrintUsage();
×
132
                exit(2);
×
133
        }
134
    }
135
}
136

137
int main(int argc, char* argv[])
×
138
{
139
    TConfig config;
×
140
    string configFile(CONFIG_FULL_FILE_PATH);
×
141

142
    TPromise<void> initialized;
×
143
    SignalHandling::Handle({SIGINT, SIGTERM});
×
144
    SignalHandling::OnSignals({SIGINT, SIGTERM}, [&] { SignalHandling::Stop(); });
×
145
    SetThreadName(APP_NAME);
×
146

147
    ParseCommadLine(argc, argv, config.Mqtt, configFile);
×
148

149
    PrintStartupInfo();
×
150

151
    SignalHandling::SetWaitFor(DRIVER_INIT_TIMEOUT_S, initialized.GetFuture(), [&] {
×
152
        LOG(Error) << "Driver takes too long to initialize. Exiting.";
×
153
        exit(1);
×
154
    });
×
155

156
    SignalHandling::SetOnTimeout(DRIVER_STOP_TIMEOUT_S, [&] {
×
157
        LOG(Error) << "Driver takes too long to stop. Exiting.";
×
158
        exit(1);
×
159
    });
×
160

161
    try {
162
        LoadConfig(config, configFile, CONFIG_JSON_SCHEMA_FULL_FILE_PATH);
×
163
        if (config.Debug) {
×
164
            ::Debug.SetEnabled(true);
×
165
        }
166

167
        if (config.Mqtt.Id.empty())
×
168
            config.Mqtt.Id = APP_NAME;
×
169

170
        SignalHandling::Start();
×
171

172
        auto mqtt = NewMosquittoMqttClient(config.Mqtt);
×
173
        auto backend = NewDriverBackend(mqtt);
×
174
        auto driver = NewDriver(TDriverArgs{}.SetId(APP_NAME).SetBackend(backend));
×
175

176
        driver->StartLoop();
×
177
        driver->WaitForReady();
×
178

NEW
179
        auto OpcuaServer(OPCUA::MakeServer(config.OpcUa, driver));
×
180

181
        initialized.Complete();
×
182
        SignalHandling::Wait();
×
183
    } catch (const TEmptyConfigException&) {
×
184
        LOG(Error) << "All groups are disabled, stopping service gracefully";
×
185
        return EXIT_NOTRUNNING;
×
186
    } catch (const TConfigException& e) {
×
187
        LOG(Error) << "FATAL: " << e.what();
×
188
        return EXIT_NOTCONFIGURED;
×
189
    } catch (const exception& e) {
×
190
        LOG(Error) << "FATAL: " << e.what();
×
191
        return EXIT_FAILURE;
×
192
    }
193

194
    return EXIT_SUCCESS;
×
195
}
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