1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "canbusutil.h"
5#include "sigtermhandler.h"
6
7#include <QCommandLineParser>
8#include <QCoreApplication>
9#include <QTextStream>
10
11#include <signal.h>
12
13int main(int argc, char *argv[])
14{
15 QCoreApplication app(argc, argv);
16 QCoreApplication::setApplicationName(QStringLiteral("canbusutil"));
17 QCoreApplication::setApplicationVersion(QStringLiteral(QT_VERSION_STR));
18
19 std::unique_ptr<SigTermHandler> s(SigTermHandler::instance());
20 if (signal(SIGINT, handler: SigTermHandler::handle) == SIG_ERR)
21 return -1;
22 QObject::connect(sender: s.get(), signal: &SigTermHandler::sigTermSignal, context: &app, slot: &QCoreApplication::quit);
23
24 QTextStream output(stdout);
25 CanBusUtil util(output, app);
26
27 QCommandLineParser parser;
28 parser.setApplicationDescription(CanBusUtil::tr(
29 s: "Sends arbitrary CAN bus frames.\n"
30 "If the -l option is set, all received CAN bus frames are dumped."));
31 parser.addHelpOption();
32 parser.addVersionOption();
33
34 parser.addPositionalArgument(QStringLiteral("plugin"),
35 description: CanBusUtil::tr(s: "Plugin name to use. See --list-plugins."));
36
37 parser.addPositionalArgument(QStringLiteral("device"),
38 description: CanBusUtil::tr(s: "Device to use."));
39
40 parser.addPositionalArgument(QStringLiteral("data"),
41 description: CanBusUtil::tr(
42 s: "Data to send if -l is not specified. Format:\n"
43 "\t\t<id>#{payload} (CAN 2.0 data frames),\n"
44 "\t\t<id>#Rxx (CAN 2.0 RTR frames with xx bytes data length),\n"
45 "\t\t<id>##[flags]{payload} (CAN FD data frames),\n"
46 "where {payload} has 0..8 (0..64 CAN FD) ASCII hex-value pairs, "
47 "and flags is one optional ASCII hex char for CAN FD flags: "
48 "1 = Bitrate Switch, 2 = Error State Indicator\n"
49 "e.g. 1#1a2b3c\n"), QStringLiteral("[data]"));
50
51 const QCommandLineOption listeningOption({"l", "listen"},
52 CanBusUtil::tr(s: "Start listening CAN data on device."));
53 parser.addOption(commandLineOption: listeningOption);
54
55 const QCommandLineOption listOption({"L", "list-plugins"},
56 CanBusUtil::tr(s: "List all available plugins."));
57 parser.addOption(commandLineOption: listOption);
58
59 const QCommandLineOption showTimeStampOption({"t", "timestamp"},
60 CanBusUtil::tr(s: "Show timestamp for each received CAN bus frame."));
61 parser.addOption(commandLineOption: showTimeStampOption);
62
63 const QCommandLineOption showFlagsOption({"i", "info"},
64 CanBusUtil::tr(s: "Show flags bitrate switch, error indicator, and local echo"
65 " for each received CAN bus frame."));
66 parser.addOption(commandLineOption: showFlagsOption);
67
68 const QCommandLineOption listDevicesOption({"d", "devices"},
69 CanBusUtil::tr(s: "Show available CAN bus devices for the given plugin."));
70 parser.addOption(commandLineOption: listDevicesOption);
71
72 const QCommandLineOption canFdOption({"f", "can-fd"},
73 CanBusUtil::tr(s: "Enable CAN FD functionality when listening."));
74 parser.addOption(commandLineOption: canFdOption);
75
76 const QCommandLineOption loopbackOption({"c", "local-loopback"},
77 CanBusUtil::tr(s: "Transmits all sent frames to other local applications."));
78 parser.addOption(commandLineOption: loopbackOption);
79
80 const QCommandLineOption receiveOwnOption({"o", "receive-own"},
81 CanBusUtil::tr(s: "Receive each sent frame on successful transmission."));
82 parser.addOption(commandLineOption: receiveOwnOption);
83
84 const QCommandLineOption bitrateOption({"b", "bitrate"},
85 CanBusUtil::tr(s: "Set the CAN bus bitrate to the given value."),
86 QStringLiteral("bitrate"));
87 parser.addOption(commandLineOption: bitrateOption);
88
89 const QCommandLineOption dataBitrateOption({"a", "data-bitrate"},
90 CanBusUtil::tr(s: "Set the CAN FD data bitrate to the given value."),
91 QStringLiteral("bitrate"));
92 parser.addOption(commandLineOption: dataBitrateOption);
93
94 parser.process(app);
95
96 if (parser.isSet(option: listOption))
97 return util.printPlugins();
98
99 QString data;
100 const QStringList args = parser.positionalArguments();
101
102 if (parser.isSet(option: canFdOption))
103 util.setConfigurationParameter(key: QCanBusDevice::CanFdKey, value: true);
104 if (parser.isSet(option: loopbackOption))
105 util.setConfigurationParameter(key: QCanBusDevice::LoopbackKey, value: true);
106 if (parser.isSet(option: receiveOwnOption))
107 util.setConfigurationParameter(key: QCanBusDevice::ReceiveOwnKey, value: true);
108 if (!parser.value(option: bitrateOption).isEmpty()) {
109 util.setConfigurationParameter(key: QCanBusDevice::BitRateKey,
110 value: parser.value(option: bitrateOption).toInt());
111 }
112 if (!parser.value(option: dataBitrateOption).isEmpty()) {
113 util.setConfigurationParameter(key: QCanBusDevice::DataBitRateKey,
114 value: parser.value(option: dataBitrateOption).toInt());
115 }
116
117 if (parser.isSet(option: listeningOption)) {
118 util.setShowTimeStamp(parser.isSet(option: showTimeStampOption));
119 util.setShowFlags(parser.isSet(option: showFlagsOption));
120 } else if (args.size() == 3) {
121 data = args.at(i: 2);
122 } else if (args.size() == 1 && parser.isSet(option: listDevicesOption)) {
123 return util.printDevices(pluginName: args.at(i: 0));
124 }
125
126 if (args.size() < 2 || args.size() > 3) {
127 output << CanBusUtil::tr(s: "Invalid number of arguments (%1 given).").arg(a: args.size());
128 output << Qt::endl << Qt::endl << parser.helpText();
129 return 1;
130 }
131
132 if (!util.start(pluginName: args.at(i: 0), deviceName: args.at(i: 1), data))
133 return -1;
134
135 return app.exec();
136}
137

source code of qtserialbus/src/tools/canbusutil/main.cpp