2018-04-01 06:53:37 +00:00
|
|
|
/*
|
2019-02-23 17:30:16 +00:00
|
|
|
Copyright (C) 2017-2019 Fredrik Öhrström
|
2018-04-01 06:53:37 +00:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2017-08-31 09:19:57 +00:00
|
|
|
|
|
|
|
#include"cmdline.h"
|
2019-05-04 11:07:37 +00:00
|
|
|
#include"config.h"
|
2018-03-16 10:48:04 +00:00
|
|
|
#include"meters.h"
|
2017-08-31 09:19:57 +00:00
|
|
|
#include"util.h"
|
|
|
|
|
2019-02-23 12:41:17 +00:00
|
|
|
#include<string>
|
|
|
|
|
2017-08-31 09:19:57 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2019-02-24 13:08:51 +00:00
|
|
|
unique_ptr<Configuration> parseCommandLine(int argc, char **argv) {
|
2017-08-31 09:19:57 +00:00
|
|
|
|
2019-02-24 13:08:51 +00:00
|
|
|
Configuration * c = new Configuration;
|
2018-02-28 21:14:16 +00:00
|
|
|
|
2017-08-31 09:19:57 +00:00
|
|
|
int i=1;
|
2019-03-04 11:34:19 +00:00
|
|
|
const char *filename = strrchr(argv[0], '/');
|
|
|
|
if (filename) {
|
|
|
|
filename++;
|
|
|
|
} else {
|
|
|
|
filename = argv[0];
|
|
|
|
}
|
2019-02-23 12:41:17 +00:00
|
|
|
if (!strcmp(filename, "wmbusmetersd")) {
|
|
|
|
c->daemon = true;
|
2019-02-24 08:58:31 +00:00
|
|
|
if (argc != 2) {
|
|
|
|
error("Usage error: wmbusmetersd must have a single argument to the pid file.\n");
|
2019-02-23 12:41:17 +00:00
|
|
|
}
|
2019-02-24 08:58:31 +00:00
|
|
|
c->pid_file = argv[1];
|
2019-02-24 13:08:51 +00:00
|
|
|
return unique_ptr<Configuration>(c);
|
2019-02-23 12:41:17 +00:00
|
|
|
}
|
2017-08-31 09:19:57 +00:00
|
|
|
if (argc < 2) {
|
|
|
|
c->need_help = true;
|
2019-02-24 13:08:51 +00:00
|
|
|
return unique_ptr<Configuration>(c);
|
2017-08-31 09:19:57 +00:00
|
|
|
}
|
|
|
|
while (argv[i] && argv[i][0] == '-') {
|
|
|
|
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
|
|
|
|
c->need_help = true;
|
2019-02-24 13:08:51 +00:00
|
|
|
return unique_ptr<Configuration>(c);
|
2017-08-31 09:19:57 +00:00
|
|
|
}
|
2018-02-28 21:14:16 +00:00
|
|
|
if (!strcmp(argv[i], "--silence")) {
|
|
|
|
c->silence = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2017-08-31 09:19:57 +00:00
|
|
|
if (!strcmp(argv[i], "--verbose")) {
|
|
|
|
c->verbose = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2019-04-15 19:17:15 +00:00
|
|
|
if (!strcmp(argv[i], "--version")) {
|
|
|
|
c->version = true;
|
|
|
|
return unique_ptr<Configuration>(c);
|
|
|
|
}
|
|
|
|
if (!strcmp(argv[i], "--license")) {
|
|
|
|
c->license = true;
|
|
|
|
return unique_ptr<Configuration>(c);
|
|
|
|
}
|
2018-02-28 21:14:16 +00:00
|
|
|
if (!strcmp(argv[i], "--debug")) {
|
|
|
|
c->debug = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-05 21:56:41 +00:00
|
|
|
LinkMode lm = isLinkMode(argv[i]);
|
|
|
|
if (lm != LinkMode::UNKNOWN) {
|
2018-11-01 16:17:23 +00:00
|
|
|
if (c->link_mode_set) {
|
|
|
|
error("You have already specified a link mode!\n");
|
|
|
|
}
|
2019-03-05 21:56:41 +00:00
|
|
|
c->link_mode = lm;
|
2018-11-01 16:17:23 +00:00
|
|
|
c->link_mode_set = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-03-05 10:29:25 +00:00
|
|
|
if (!strcmp(argv[i], "--logtelegrams")) {
|
|
|
|
c->logtelegrams = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2019-02-26 08:33:10 +00:00
|
|
|
if (!strncmp(argv[i], "--useconfig", 11)) {
|
|
|
|
if (strlen(argv[i]) == 11)
|
|
|
|
{
|
|
|
|
c->useconfig = true;
|
|
|
|
c->config_root = "";
|
|
|
|
return unique_ptr<Configuration>(c);
|
|
|
|
}
|
|
|
|
else if (strlen(argv[i]) > 12 && argv[i][11] == '=')
|
|
|
|
{
|
|
|
|
size_t len = strlen(argv[i]) - 12;
|
|
|
|
c->useconfig = true;
|
|
|
|
c->config_root = string(argv[i]+12, len);
|
2019-03-12 19:37:25 +00:00
|
|
|
if (c->config_root == "/") {
|
|
|
|
c->config_root = "";
|
|
|
|
}
|
2019-02-26 08:33:10 +00:00
|
|
|
return unique_ptr<Configuration>(c);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error("You must supply a directory to --useconfig=dir\n");
|
|
|
|
}
|
|
|
|
i++;
|
2019-02-23 12:41:17 +00:00
|
|
|
if (i > 1 || argc > 2) {
|
|
|
|
error("Usage error: --useconfig implies no other arguments on the command line.\n");
|
|
|
|
}
|
2019-02-26 08:33:10 +00:00
|
|
|
continue;
|
2019-02-23 12:41:17 +00:00
|
|
|
}
|
2019-02-23 17:30:16 +00:00
|
|
|
if (!strcmp(argv[i], "--reload")) {
|
|
|
|
c->reload = true;
|
|
|
|
if (i > 1 || argc > 2) {
|
|
|
|
error("Usage error: --reload implies no other arguments on the command line.\n");
|
|
|
|
}
|
2019-02-24 13:08:51 +00:00
|
|
|
return unique_ptr<Configuration>(c);
|
2019-02-23 17:30:16 +00:00
|
|
|
}
|
2019-02-26 21:19:16 +00:00
|
|
|
if (!strncmp(argv[i], "--format", 8)) {
|
|
|
|
if (strlen(argv[i]) == 8 ||
|
|
|
|
(strlen(argv[i]) == 13 &&
|
|
|
|
!strncmp(argv[i]+8, "=json", 5)))
|
2018-03-05 10:29:25 +00:00
|
|
|
{
|
|
|
|
c->json = true;
|
|
|
|
c->fields = false;
|
|
|
|
}
|
2019-02-26 21:19:16 +00:00
|
|
|
else if (strlen(argv[i]) == 15 &&
|
2018-03-05 10:29:25 +00:00
|
|
|
!strncmp(argv[i]+7, "=fields", 7))
|
|
|
|
{
|
|
|
|
c->json = false;
|
|
|
|
c->fields = true;
|
|
|
|
c->separator = ';';
|
|
|
|
} else {
|
2019-02-26 21:19:16 +00:00
|
|
|
error("Unknown output format: \"%s\"\n", argv[i]+8);
|
2018-03-05 10:29:25 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2019-05-04 20:39:45 +00:00
|
|
|
if (!strncmp(argv[i], "--addconversions=", 16)) {
|
2019-05-04 06:52:25 +00:00
|
|
|
if (strlen(argv[i]) > 16)
|
|
|
|
{
|
2019-05-04 11:07:37 +00:00
|
|
|
string s = string(argv[i]+16);
|
|
|
|
handleConversions(c, s);
|
2019-05-04 06:52:25 +00:00
|
|
|
} else {
|
|
|
|
error("You must supply conversion units.\n");
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-03-05 10:29:25 +00:00
|
|
|
if (!strncmp(argv[i], "--separator=", 12)) {
|
|
|
|
if (!c->fields) {
|
2019-02-26 21:19:16 +00:00
|
|
|
error("You must specify --format=fields before --separator=X\n");
|
2018-03-05 10:29:25 +00:00
|
|
|
}
|
|
|
|
if (strlen(argv[i]) != 13) {
|
|
|
|
error("You must supply a single character as the field separator.\n");
|
|
|
|
}
|
|
|
|
c->separator = argv[i][12];
|
2017-08-31 09:19:57 +00:00
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-03-05 12:42:56 +00:00
|
|
|
if (!strncmp(argv[i], "--meterfiles", 12)) {
|
2017-09-02 10:17:54 +00:00
|
|
|
c->meterfiles = true;
|
2018-03-05 12:42:56 +00:00
|
|
|
if (strlen(argv[i]) > 12 && argv[i][12] == '=') {
|
|
|
|
size_t len = strlen(argv[i])-13;
|
|
|
|
if (len > 0) {
|
2019-02-23 12:41:17 +00:00
|
|
|
c->meterfiles_dir = string(argv[i]+13, len);
|
2018-03-05 12:42:56 +00:00
|
|
|
} else {
|
|
|
|
c->meterfiles_dir = "/tmp";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
c->meterfiles_dir = "/tmp";
|
|
|
|
}
|
2019-01-27 23:03:25 +00:00
|
|
|
if (!checkIfDirExists(c->meterfiles_dir.c_str())) {
|
2019-02-23 12:57:05 +00:00
|
|
|
error("Cannot write meter files into dir \"%s\"\n", c->meterfiles_dir.c_str());
|
2018-03-05 14:12:58 +00:00
|
|
|
}
|
2017-09-02 10:17:54 +00:00
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2019-02-26 21:19:16 +00:00
|
|
|
if (!strncmp(argv[i], "--meterfilesaction", 18)) {
|
|
|
|
if (strlen(argv[i]) > 18 && argv[i][18] == '=') {
|
|
|
|
if (!strncmp(argv[i]+19, "overwrite", 9)) {
|
|
|
|
c->meterfiles_action = MeterFileType::Overwrite;
|
|
|
|
} else if (!strncmp(argv[i]+19, "append", 6)) {
|
|
|
|
c->meterfiles_action = MeterFileType::Append;
|
|
|
|
} else {
|
|
|
|
error("No such meter file action %s\n", argv[i]+19);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
error("Incorrect option %s\n", argv[i]);
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2019-02-24 14:20:55 +00:00
|
|
|
if (!strncmp(argv[i], "--logfile=", 10)) {
|
|
|
|
c->use_logfile = true;
|
|
|
|
if (strlen(argv[i]) > 10) {
|
|
|
|
size_t len = strlen(argv[i])-10;
|
|
|
|
if (len > 0) {
|
|
|
|
c->logfile = string(argv[i]+10, len);
|
|
|
|
} else {
|
|
|
|
error("Not a valid log file name.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-02 12:50:12 +00:00
|
|
|
if (!strncmp(argv[i], "--shell=", 8)) {
|
|
|
|
string cmd = string(argv[i]+8);
|
|
|
|
if (cmd == "") {
|
|
|
|
error("The shell command cannot be empty.\n");
|
|
|
|
}
|
|
|
|
c->shells.push_back(cmd);
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strncmp(argv[i], "--shellenvs", 11)) {
|
|
|
|
c->list_shell_envs = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2017-09-02 21:26:57 +00:00
|
|
|
if (!strcmp(argv[i], "--oneshot")) {
|
|
|
|
c->oneshot = true;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-03-05 14:12:58 +00:00
|
|
|
if (!strncmp(argv[i], "--exitafter=", 12) && strlen(argv[i]) > 12) {
|
|
|
|
c->exitafter = parseTime(argv[i]+12);
|
|
|
|
if (c->exitafter <= 0) {
|
|
|
|
error("Not a valid time to exit after. \"%s\"\n", argv[i]+12);
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2017-08-31 09:19:57 +00:00
|
|
|
if (!strcmp(argv[i], "--")) {
|
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
error("Unknown option \"%s\"\n", argv[i]);
|
|
|
|
}
|
2018-02-28 21:14:16 +00:00
|
|
|
|
2019-03-05 21:56:41 +00:00
|
|
|
char *extra = argv[i] ? strchr(argv[i], ':') : NULL ;
|
2019-02-25 21:03:20 +00:00
|
|
|
if (extra) {
|
|
|
|
*extra = 0;
|
|
|
|
extra++;
|
|
|
|
c->device_extra = extra;
|
|
|
|
}
|
2019-03-05 21:56:41 +00:00
|
|
|
if (argv[i]) {
|
|
|
|
c->device = argv[i];
|
|
|
|
}
|
2017-08-31 09:19:57 +00:00
|
|
|
i++;
|
2019-03-05 21:56:41 +00:00
|
|
|
if (c->device.length() == 0) {
|
|
|
|
error("You must supply the usb device to which the wmbus dongle is connected.\n");
|
|
|
|
}
|
2017-08-31 09:19:57 +00:00
|
|
|
|
2018-03-05 10:29:25 +00:00
|
|
|
if ((argc-i) % 4 != 0) {
|
|
|
|
error("For each meter you must supply a: name,type,id and key.\n");
|
2017-08-31 09:19:57 +00:00
|
|
|
}
|
2018-03-05 10:29:25 +00:00
|
|
|
int num_meters = (argc-i)/4;
|
2017-08-31 09:19:57 +00:00
|
|
|
|
|
|
|
for (int m=0; m<num_meters; ++m) {
|
2019-02-23 12:41:17 +00:00
|
|
|
string name = argv[m*4+i+0];
|
|
|
|
string type = argv[m*4+i+1];
|
|
|
|
string id = argv[m*4+i+2];
|
|
|
|
string key = argv[m*4+i+3];
|
2018-02-28 21:14:16 +00:00
|
|
|
|
2018-03-16 10:48:04 +00:00
|
|
|
MeterType mt = toMeterType(type);
|
|
|
|
|
2019-05-04 08:52:18 +00:00
|
|
|
if (mt == MeterType::UNKNOWN) error("Not a valid meter type \"%s\"\n", type.c_str());
|
2019-02-23 12:41:17 +00:00
|
|
|
if (!isValidId(id)) error("Not a valid meter id \"%s\"\n", id.c_str());
|
|
|
|
if (!isValidKey(key)) error("Not a valid meter key \"%s\"\n", key.c_str());
|
2019-02-23 21:06:50 +00:00
|
|
|
c->meters.push_back(MeterInfo(name, type, id, key));
|
2017-08-31 09:19:57 +00:00
|
|
|
}
|
|
|
|
|
2019-02-24 13:08:51 +00:00
|
|
|
return unique_ptr<Configuration>(c);
|
2017-08-31 09:19:57 +00:00
|
|
|
}
|