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

wirenboard / wb-mqtt-smartweb / 2

31 Jul 2026 10:01AM UTC coverage: 33.897% (-0.4%) from 34.328%
2

Pull #40

github

476708
ekateluv
Lower coverage threshold to 33
Pull Request #40: Use exported vars instead of MAKEFLAGS for coverage options

307 of 744 branches covered (41.26%)

501 of 1478 relevant lines covered (33.9%)

20.03 hits per line

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

0.0
/src/main.cpp
1
#include <wblib/log.h>
2
#include <wblib/signal_handling.h>
3
#include <wblib/wbmqtt.h>
4

5
#include <getopt.h>
6

7
#include "CanPort.h"
8
#include "MqttToSmartWebGateway.h"
9
#include "SmartWebToMqttGateway.h"
10
#include "config_parser.h"
11
#include "exceptions.h"
12
#include "log.h"
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-smartweb";
21
const auto LIBWBMQTT_DB_FULL_FILE_PATH = "/var/lib/wb-mqtt-smartweb/libwbmqtt.db";
22
const auto CONFIG_FULL_FILE_PATH = "/etc/wb-mqtt-smartweb.conf";
23
const auto BUILT_IN_DEVICE_CLASSES_PATH = "/usr/share/wb-mqtt-smartweb/classes";
24
const auto CONFIG_JSON_SCHEMA_FULL_FILE_PATH = "/usr/share/wb-mqtt-confed/schemas/wb-mqtt-smartweb.schema.json";
25
const auto CLASS_JSON_SCHEMA_FULL_FILE_PATH = "/usr/share/wb-mqtt-confed/schemas/wb-mqtt-smartweb-class.schema.json";
26

27
const auto DRIVER_STOP_TIMEOUT_S = chrono::seconds(10);
28

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

32
#define LOG(logger) ::logger.Log() << "[main] "
33

34
namespace
35
{
36
    void PrintUsage();
37

38
    void ApplyDebugParam(int debugLevel)
×
39
    {
40
        switch (debugLevel) {
×
41
            case 0:
×
42
                break;
×
43
            case -1:
×
44
                ErrorMqttToSw.SetEnabled(false);
×
45
                WarnMqttToSw.SetEnabled(false);
×
46
                InfoMqttToSw.SetEnabled(false);
×
47
                DebugMqttToSw.SetEnabled(false);
×
48
                break;
×
49
            case -2:
×
50
                ErrorSwToMqtt.SetEnabled(false);
×
51
                WarnSwToMqtt.SetEnabled(false);
×
52
                InfoSwToMqtt.SetEnabled(false);
×
53
                DebugSwToMqtt.SetEnabled(false);
×
54
                break;
×
55
            case -3:
×
56
                WBMQTT::Info.SetEnabled(false);
×
57
                break;
×
58
            case -4:
×
59
                ErrorMqttToSw.SetEnabled(false);
×
60
                WarnMqttToSw.SetEnabled(false);
×
61
                InfoMqttToSw.SetEnabled(false);
×
62
                DebugMqttToSw.SetEnabled(false);
×
63
                ErrorSwToMqtt.SetEnabled(false);
×
64
                WarnSwToMqtt.SetEnabled(false);
×
65
                InfoSwToMqtt.SetEnabled(false);
×
66
                DebugSwToMqtt.SetEnabled(false);
×
67
                WBMQTT::Info.SetEnabled(false);
×
68
                break;
×
69
            case 1:
×
70
                DebugMqttToSw.SetEnabled(true);
×
71
                break;
×
72
            case 2:
×
73
                DebugSwToMqtt.SetEnabled(true);
×
74
                break;
×
75
            case 3:
×
76
                WBMQTT::Debug.SetEnabled(true);
×
77
                break;
×
78
            case 4:
×
79
                DebugMqttToSw.SetEnabled(true);
×
80
                DebugSwToMqtt.SetEnabled(true);
×
81
                WBMQTT::Debug.SetEnabled(true);
×
82
                break;
×
83
            default:
×
84
                cout << "Invalid -d parameter value " << debugLevel << endl;
×
85
                PrintUsage();
×
86
                exit(2); // EXIT_INVALIDARGUMENT
×
87
        }
88
    }
×
89

90
    void PrintStartupInfo()
×
91
    {
92
        std::string commit(XSTR(WBMQTT_COMMIT));
×
93
        cout << APP_NAME << " " << XSTR(WBMQTT_VERSION);
×
94
        if (!commit.empty()) {
×
95
            cout << " git " << commit;
×
96
        }
97
        cout << endl;
×
98
    }
×
99

100
    void PrintUsage()
×
101
    {
102
        PrintStartupInfo();
×
103
        cout << "Usage:" << endl
×
104
             << " " << APP_NAME << " [options]" << endl
×
105
             << "Options:" << endl
×
106
             << "  -d      level      enable debuging output:" << endl
×
107
             << "                       1 - MQTT to SmartWeb only;" << endl
×
108
             << "                       2 - SmartWeb to MQTT only;" << endl
×
109
             << "                       3 - MQTT only;" << endl
×
110
             << "                       4 - all;" << endl
×
111
             << "                       negative values - silent mode (-1, -2, -3, -4))" << endl
×
112
             << "  -c      config     config file (default " << CONFIG_FULL_FILE_PATH << ")" << endl
×
113
             << "  -i      interface  CAN interface (default: can0)" << endl
×
114
             << "  -p      port       MQTT broker port (default: 1883)" << endl
×
115
             << "  -h, -H  IP         MQTT broker IP (default: localhost)" << endl
×
116
             << "  -u      user       MQTT user (optional)" << endl
×
117
             << "  -P      password   MQTT user password (optional)" << endl
×
118
             << "  -T      prefix     MQTT topic prefix (optional)" << endl;
×
119
    }
×
120

121
    void ParseCommadLine(int argc, char* argv[], TMosquittoMqttConfig& mqttConfig, string& configFile, string& ifname)
×
122
    {
123
        int c;
124

125
        while ((c = getopt(argc, argv, "d:c:g:p:h:H:T:u:P:")) != -1) {
×
126
            switch (c) {
×
127
                case 'd':
×
128
                    ApplyDebugParam(stoi(optarg));
×
129
                    break;
×
130
                case 'c':
×
131
                    configFile = optarg;
×
132
                    break;
×
133
                case 'p':
×
134
                    mqttConfig.Port = stoi(optarg);
×
135
                    break;
×
136
                case 'h':
×
137
                case 'H':
138
                    mqttConfig.Host = optarg;
×
139
                    break;
×
140
                case 'T':
×
141
                    mqttConfig.Prefix = optarg;
×
142
                    break;
×
143
                case 'u':
×
144
                    mqttConfig.User = optarg;
×
145
                    break;
×
146
                case 'P':
×
147
                    mqttConfig.Password = optarg;
×
148
                    break;
×
149
                case 'i':
×
150
                    ifname = optarg;
×
151
                    break;
×
152
                default:
×
153
                    PrintUsage();
×
154
                    exit(2); // EXIT_INVALIDARGUMENT
×
155
            }
156
        }
157
    }
×
158
}
159

160
int main(int argc, char* argv[])
×
161
{
162
    string configFile(CONFIG_FULL_FILE_PATH);
×
163
    TConfig config;
×
164

165
    TPromise<void> initialized;
×
166
    SignalHandling::Handle({SIGINT, SIGTERM});
×
167
    SignalHandling::OnSignals({SIGINT, SIGTERM}, [&] { SignalHandling::Stop(); });
×
168
    SetThreadName(APP_NAME);
×
169
    ParseCommadLine(argc, argv, config.Mqtt, configFile, config.InterfaceName);
×
170

171
    PrintStartupInfo();
×
172

173
    SignalHandling::SetWaitFor(DRIVER_INIT_TIMEOUT_S, initialized.GetFuture(), [&] {
×
174
        LOG(WBMQTT::Error) << "Driver takes too long to initialize. Exiting.";
×
175
        exit(1);
×
176
    });
177

178
    SignalHandling::SetOnTimeout(DRIVER_STOP_TIMEOUT_S, [&] {
×
179
        LOG(WBMQTT::Error) << "Driver takes too long to stop. Exiting.";
×
180
        exit(1);
×
181
    });
182

183
    try {
184
        LoadConfig(config,
×
185
                   configFile,
186
                   configFile + ".d/classes",
×
187
                   BUILT_IN_DEVICE_CLASSES_PATH,
188
                   CONFIG_JSON_SCHEMA_FULL_FILE_PATH,
189
                   CLASS_JSON_SCHEMA_FULL_FILE_PATH);
190
        if (config.Debug) {
×
191
            ::Debug.SetEnabled(true);
×
192
        }
193
        if (config.Mqtt.Id.empty())
×
194
            config.Mqtt.Id = APP_NAME;
×
195
    } catch (const exception& e) {
×
196
        LOG(WBMQTT::Error) << "FATAL: " << e.what();
×
197
        return 6; // EXIT_NOTCONFIGURED
×
198
    }
×
199

200
    try {
201
        auto mqtt = NewMosquittoMqttClient(config.Mqtt);
×
202
        auto backend = NewDriverBackend(mqtt);
×
203
        auto driver = NewDriver(TDriverArgs{}
×
204
                                    .SetId(APP_NAME)
×
205
                                    .SetBackend(backend)
×
206
                                    .SetUseStorage(true)
×
207
                                    .SetReownUnknownDevices(true)
×
208
                                    .SetStoragePath(LIBWBMQTT_DB_FULL_FILE_PATH));
×
209

210
        driver->StartLoop();
×
211
        driver->WaitForReady();
×
212

213
        auto port = CAN::MakePort(config.InterfaceName);
×
214

215
        {
216
            TSmartWebToMqttGateway smartWebToMqttGateway(config.SmartWebToMqtt, port, driver);
×
217
            std::vector<std::shared_ptr<TMqttToSmartWebGateway>> mqttToSmartWebGateways;
×
218
            for (const auto& controller: config.Controllers) {
×
219
                mqttToSmartWebGateways.push_back(std::make_shared<TMqttToSmartWebGateway>(controller, port, driver));
×
220
            }
221

222
            initialized.Complete();
×
223
            SignalHandling::Start();
×
224
            SignalHandling::Wait();
×
225
        }
×
226
        driver->StopLoop();
×
227
        driver->Close();
×
228
    } catch (const TInterfaceNotFoundError& e) {
×
229
        LOG(WBMQTT::Error) << "FATAL: " << e.what();
×
230
        return 6; // EXIT_NOTCONFIGURED
×
231
    } catch (const exception& e) {
×
232
        LOG(WBMQTT::Error) << "FATAL: " << e.what();
×
233
        return 1;
×
234
    }
×
235

236
    return 0;
×
237
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc