Refactoring command line option handling

* Use own function to define and parse command line options

 * Command line options can be defined by config file also

 * --limesdr allows to auto-set required SDR option for LimeSDR
pull/1/head
Andreas Eversberg 5 years ago
parent 6ba1b8acab
commit 3b81007210
  1. 1
      .gitignore
  2. 1
      configure.ac
  3. 14
      docs/sdr.html
  4. 1
      src/Makefile.am
  5. 1
      src/amps/Makefile.am
  6. 277
      src/amps/amps_tacs_main.c
  7. 1
      src/anetz/Makefile.am
  8. 125
      src/anetz/main.c
  9. 2
      src/bnetz/Makefile.am
  10. 122
      src/bnetz/dialer.c
  11. 112
      src/bnetz/main.c
  12. 1
      src/cnetz/Makefile.am
  13. 356
      src/cnetz/main.c
  14. 1
      src/jolly/Makefile.am
  15. 122
      src/jolly/main.c
  16. 1
      src/jtacs/Makefile.am
  17. 1
      src/libdebug/debug.c
  18. 45
      src/libdebug/debug.h
  19. 206
      src/libmobile/main_mobile.c
  20. 6
      src/libmobile/main_mobile.h
  21. 7
      src/liboptions/Makefile.am
  22. 221
      src/liboptions/options.c
  23. 6
      src/liboptions/options.h
  24. 1
      src/libsdr/sdr.c
  25. 110
      src/libsdr/sdr_config.c
  26. 5
      src/libsdr/sdr_config.h
  27. 1
      src/nmt/Makefile.am
  28. 262
      src/nmt/main.c
  29. 1
      src/r2000/Makefile.am
  30. 317
      src/r2000/main.c
  31. 1
      src/radio/Makefile.am
  32. 277
      src/radio/main.c
  33. 1
      src/tacs/Makefile.am
  34. 2
      src/test/Makefile.am
  35. 2
      src/test/test_dms.c
  36. 1
      src/tv/Makefile.am
  37. 251
      src/tv/main.c

1
.gitignore vendored

@ -20,6 +20,7 @@ compile
.libs
.dirstamp
m4
src/liboptions/liboptions.a
src/libdebug/libdebug.a
src/libmobile/libmobile.a
src/libdisplay/libdisplay.a

@ -49,6 +49,7 @@ AS_IF([test "x$with_imagemagick" == "xyes"],[AC_MSG_NOTICE( Compiling with Image
AS_IF([test "x$with_alsa" != "xyes" -a "x$with_sdr" != "xyes"],[AC_MSG_FAILURE( Without sound nor SDR support this project does not make sense. Please support sound card for analog transceivers or better SDR!" )],[])
AC_OUTPUT(
src/liboptions/Makefile
src/libdebug/Makefile
src/libmobile/Makefile
src/libdisplay/Makefile

@ -67,7 +67,7 @@ LimeSDR
</p>
<p>
If you have this device, you need to install the SoapySDR, then the LimeSuit and finally run configure with Osmocom Analog, compile and install.
If you have this device, you need to install the SoapySDR, then the LimeSuite and finally run configure with Osmocom Analog, compile and install.
Run Osmocom Analog with --help again, and you should see a bunch of option for SDR.
In case of B-Netz, I use the following parameters:
</p>
@ -75,14 +75,21 @@ In case of B-Netz, I use the following parameters:
<pre>
# bnetz --sdr-soapy \
--sdr-tx-gain 50 \
--sdr-rx-antenna LNAL \
--sdr-rx-gain 30 \
--sdr-tx-gain 30 \
--sdr-samplerate 5000000 \
-s 100000 \
-k 17
</pre>
<p>
Be sure to select the right RX antenna input.
The frequencies we use require the low frequency filter network, so I suggest to connect your antenna to RX_1_L and select "--sdr-rx-antenna LNAL".
Different versions of LimeSuite have different default antenna inputs, so be sure to set your RX antenna.
</p>
<p>
In order to change from analog sound card to SDR, you need <b>--sdr-soapy</b> option.
In my setup I use antennas directly connected to the SDR.
@ -170,7 +177,8 @@ Because C-Netz uses only odd channel numbers for 10 KHz spacing, we use channel
<pre>
# cnetz --sdr-soapy \
--sdr-rx-gain 50 \
--sdr-rx-antenna LNAL \
--sdr-rx-gain 30 \
--sdr-tx-gain 30 \
--sdr-samplerate 5000000 \
-s 100000 \

@ -1,6 +1,7 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = \
liboptions \
libdebug \
libmobile \
libdisplay \

@ -26,6 +26,7 @@ amps_SOURCES = \
amps_LDADD = \
$(COMMON_LA) \
libamps.a \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libmobile/libmobile.a \
$(top_builddir)/src/libdisplay/libdisplay.a \

@ -19,13 +19,14 @@
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "../libsample/sample.h"
#include "../libmobile/main_mobile.h"
#include "../libdebug/debug.h"
#include "../libmobile/call.h"
#include "../liboptions/options.h"
#include "amps.h"
#include "dsp.h"
#include "frame.h"
@ -103,152 +104,132 @@ void print_help(const char *arg0)
main_mobile_print_hotkeys();
}
static int handle_options(int argc, char **argv)
static void add_options(void)
{
main_mobile_add_options();
option_add('T', "channel-type", 1);
option_add('F', "flip-polarity", 1);
option_add('P', "ms-power", 1);
option_add('D', "dtx", 1);
option_add('S', "sysinfo", 1);
option_add('O', "tolerant", 0);
}
static int handle_options(int short_option, int argi, char **argv)
{
const char *p;
int skip_args = 0;
int rc;
static struct option long_options_special[] = {
{"channel-type", 1, 0, 'T'},
{"flip-polarity", 1, 0, 'F'},
{"ms-power", 1, 0, 'P'},
{"dtx", 1, 0, 'D'},
{"sysinfo", 1, 0, 'S'},
{"tolerant", 0, 0, 'O'},
{0, 0, 0, 0}
};
main_mobile_set_options("T:F:P:D:S:O", long_options_special);
while (1) {
int option_index = 0, c;
c = getopt_long(argc, argv, optstring, long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'T':
if (!strcmp(optarg, "list")) {
amps_channel_list();
exit(0);
}
rc = amps_channel_by_short_name(optarg);
if (rc < 0) {
fprintf(stderr, "Error, channel type '%s' unknown. Please use '-t list' to get a list. I suggest to use the default.\n", optarg);
exit(0);
}
OPT_ARRAY(num_chan_type, chan_type, rc)
skip_args += 2;
break;
case 'F':
if (!strcasecmp(optarg, "no"))
flip_polarity = "no";
else if (!strcasecmp(optarg, "yes"))
flip_polarity = "yes";
else {
fprintf(stderr, "Given polarity '%s' is illegal, see help!\n", optarg);
exit(0);
}
skip_args += 2;
break;
case 'P':
ms_power = atoi(optarg);
if (ms_power > 7)
ms_power = 7;
if (ms_power < 0)
ms_power = 0;
skip_args += 2;
break;
case 'D':
dtx = atoi(optarg);
if (dtx > 3)
dtx = 3;
if (dtx < 0)
dtx = 0;
skip_args += 2;
break;
case 'S':
p = strchr(optarg, '=');
if (!p) {
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, see help!\n", optarg);
exit(0);
}
p++;
if (!strncasecmp(optarg, "sid=", p - optarg)
|| !strncasecmp(optarg, "aid=", p - optarg)) {
if (!strcasecmp(p, "list")) {
list_stations();
exit(0);
}
sid = atoi(p);
if (sid > 32767)
sid = 32767;
if (sid < 0)
sid = 0;
} else
if (!strncasecmp(optarg, "dcc=", p - optarg)) {
dcc = atoi(p);
if (dcc > 3)
dcc = 3;
if (dcc < 0)
dcc = 0;
} else
if (!strncasecmp(optarg, "scc=", p - optarg)) {
scc = atoi(p);
if (scc > 2)
scc = 2;
if (scc < 0)
scc = 0;
} else
if (!strncasecmp(optarg, "regincr=", p - optarg)) {
regincr = atoi(p);
} else
if (!strncasecmp(optarg, "pureg=", p - optarg)) {
pureg = atoi(p) & 1;
} else
if (!strncasecmp(optarg, "pdreg=", p - optarg)) {
pdreg = atoi(p) & 1;
} else
if (!strncasecmp(optarg, "locaid=", p - optarg)) {
locaid = atoi(p);
if (locaid > 4095)
locaid = 4095;
} else
if (!strncasecmp(optarg, "regh=", p - optarg)) {
regh = atoi(p) & 1;
} else
if (!strncasecmp(optarg, "regr=", p - optarg)) {
regr = atoi(p) & 1;
} else
if (!strncasecmp(optarg, "bis=", p - optarg)) {
bis = atoi(p) & 1;
} else {
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
exit(0);
switch (short_option) {
case 'T':
if (!strcmp(argv[argi], "list")) {
amps_channel_list();
return 0;
}
rc = amps_channel_by_short_name(argv[argi]);
if (rc < 0) {
fprintf(stderr, "Error, channel type '%s' unknown. Please use '-t list' to get a list. I suggest to use the default.\n", argv[argi]);
return -EINVAL;
}
OPT_ARRAY(num_chan_type, chan_type, rc)
break;
case 'F':
if (!strcasecmp(argv[argi], "no"))
flip_polarity = "no";
else if (!strcasecmp(argv[argi], "yes"))
flip_polarity = "yes";
else {
fprintf(stderr, "Given polarity '%s' is illegal, use '-h' for help!\n", argv[argi]);
return -EINVAL;
}
break;
case 'P':
ms_power = atoi(argv[argi]);
if (ms_power > 7)
ms_power = 7;
if (ms_power < 0)
ms_power = 0;
break;
case 'D':
dtx = atoi(argv[argi]);
if (dtx > 3)
dtx = 3;
if (dtx < 0)
dtx = 0;
break;
case 'S':
p = strchr(argv[argi], '=');
if (!p) {
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, use '-h' for help!\n", argv[argi]);
return -EINVAL;
}
p++;
if (!strncasecmp(argv[argi], "sid=", p - argv[argi])
|| !strncasecmp(argv[argi], "aid=", p - argv[argi])) {
if (!strcasecmp(p, "list")) {
list_stations();
return 0;
}
skip_args += 2;
break;
case 'O':
tolerant = 1;
skip_args += 1;
break;
default:
main_mobile_opt_switch(c, argv[0], &skip_args);
sid = atoi(p);
if (sid > 32767)
sid = 32767;
if (sid < 0)
sid = 0;
} else
if (!strncasecmp(argv[argi], "dcc=", p - argv[argi])) {
dcc = atoi(p);
if (dcc > 3)
dcc = 3;
if (dcc < 0)
dcc = 0;
} else
if (!strncasecmp(argv[argi], "scc=", p - argv[argi])) {
scc = atoi(p);
if (scc > 2)
scc = 2;
if (scc < 0)
scc = 0;
} else
if (!strncasecmp(argv[argi], "regincr=", p - argv[argi])) {
regincr = atoi(p);
} else
if (!strncasecmp(argv[argi], "pureg=", p - argv[argi])) {
pureg = atoi(p) & 1;
} else
if (!strncasecmp(argv[argi], "pdreg=", p - argv[argi])) {
pdreg = atoi(p) & 1;
} else
if (!strncasecmp(argv[argi], "locaid=", p - argv[argi])) {
locaid = atoi(p);
if (locaid > 4095)
locaid = 4095;
} else
if (!strncasecmp(argv[argi], "regh=", p - argv[argi])) {
regh = atoi(p) & 1;
} else
if (!strncasecmp(argv[argi], "regr=", p - argv[argi])) {
regr = atoi(p) & 1;
} else
if (!strncasecmp(argv[argi], "bis=", p - argv[argi])) {
bis = atoi(p) & 1;
} else {
fprintf(stderr, "Given sysinfo parameter '%s' unknown, use '-h' for help!\n", argv[argi]);
return -EINVAL;
}
break;
case 'O':
tolerant = 1;
break;
default:
return main_mobile_handle_options(short_option, argi, argv);
}
free(long_options);
return skip_args;
return 1;
}
int main_amps_tacs(int argc, char *argv[])
{
int rc;
int skip_args;
int rc, argi;
const char *station_id = "";
int polarity;
int i;
@ -258,12 +239,24 @@ int main_amps_tacs(int argc, char *argv[])
main_mobile_init();
skip_args = handle_options(argc, argv);
argc -= skip_args;
argv += skip_args;
/* handle options / config file */
add_options();
if (!tacs) {
rc = options_config_file("~/.osmocom/analog/amps.conf", handle_options);
} else if (!jtacs) {
rc = options_config_file("~/.osmocom/analog/tacs.conf", handle_options);
} else {
rc = options_config_file("~/.osmocom/analog/jtacs.conf", handle_options);
}
if (rc < 0)
return 0;
argi = options_command_line(argc, argv, handle_options);
if (argi <= 0)
return argi;
if (argc > 1) {
station_id = argv[1];
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 10) {
printf("Given station ID '%s' does not have 10 digits\n", station_id);
return 0;
@ -272,7 +265,7 @@ int main_amps_tacs(int argc, char *argv[])
if (!num_kanal) {
printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", (!tacs) ? 334 : 323);
print_help(argv[-skip_args]);
print_help(argv[0]);
return 0;
}
if (use_sdr) {
@ -380,7 +373,7 @@ int main_amps_tacs(int argc, char *argv[])
else if (use_sdr)
polarity = 1; /* SDR is always positive */
else {
fprintf(stderr, "You must define, if the the TX deviation polarity has to be flipped. (-F yes | no) See help.\n");
fprintf(stderr, "You must define, if the the TX deviation polarity has to be flipped. (-F yes | no) use '-h' for help.\n");
exit(0);
}

@ -18,6 +18,7 @@ anetz_SOURCES = \
anetz_LDADD = \
$(COMMON_LA) \
libgermanton.a \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libmobile/libmobile.a \
$(top_builddir)/src/libdisplay/libdisplay.a \

@ -19,15 +19,16 @@
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include "../libsample/sample.h"
#include "../libmobile/main_mobile.h"
#include "../libdebug/debug.h"
#include "../libtimer/timer.h"
#include "../libmobile/call.h"
#include "../liboptions/options.h"
#include "freiton.h"
#include "besetztton.h"
#include "anetz.h"
@ -69,79 +70,60 @@ void print_help(const char *arg0)
main_mobile_print_hotkeys();
}
static int handle_options(int argc, char **argv)
static void add_options(void)
{
main_mobile_add_options();
option_add('O', "operator", 1);
option_add('G', "geo", 1);
option_add('V', "page-gain", 1);
option_add('P', "page-sequence", 1);
option_add('S', "squelch", 1);
}
static int handle_options(int short_option, int argi, char **argv)
{
int skip_args = 0;
char *p;
double gain_db;
static struct option long_options_special[] = {
{"operator", 1, 0, 'O'},
{"geo", 1, 0, 'G'},
{"page-gain", 1, 0, 'V'},
{"page-sequence", 1, 0, 'P'},
{"squelch", 1, 0, 'S'},
{0, 0, 0, 0}
};
main_mobile_set_options("O:G:V:P:S:", long_options_special);
while (1) {
int option_index = 0, c;
c = getopt_long(argc, argv, optstring, long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'O':
strncpy(operator, optarg, sizeof(operator) - 1);
operator[sizeof(operator) - 1] = '\0';
skip_args += 2;
break;
case 'G':
if (!strcasecmp(optarg, "list")) {
station_list();
exit(0);
}
if ((p = strchr(optarg, ','))) {
get_station_by_coordinates(atof(optarg), atof(p + 1));
exit(0);
}
fprintf(stderr, "Invalid geo parameter\n");
exit(0);
break;
case 'V':
gain_db = atof(optarg);
page_gain = pow(10, gain_db / 20.0);
skip_args += 2;
break;
case 'P':
page_sequence = atoi(optarg);
skip_args += 2;
break;
case 'S':
if (!strcasecmp(optarg, "auto"))
squelch_db = 0.0;
else
squelch_db = atof(optarg);
skip_args += 2;
break;
default:
main_mobile_opt_switch(c, argv[0], &skip_args);
switch (short_option) {
case 'O':
strncpy(operator, argv[argi], sizeof(operator) - 1);
operator[sizeof(operator) - 1] = '\0';
break;
case 'G':
if (!strcasecmp(argv[argi], "list")) {
station_list();
return 0;
}
if ((p = strchr(argv[argi], ','))) {
get_station_by_coordinates(atof(argv[argi]), atof(p + 1));
return 0;
}
fprintf(stderr, "Invalid geo parameter\n");
return -EINVAL;
case 'V':
gain_db = atof(argv[argi]);
page_gain = pow(10, gain_db / 20.0);
break;
case 'P':
page_sequence = atoi(argv[argi]);
break;
case 'S':
if (!strcasecmp(argv[argi], "auto"))
squelch_db = 0.0;
else
squelch_db = atof(argv[argi]);
break;
default:
return main_mobile_handle_options(short_option, argi, argv);
}
free(long_options);
return skip_args;
return 1;
}
int main(int argc, char *argv[])
{
int rc;
int skip_args;
int rc, argi;
const char *station_id = "";
int i;
@ -154,12 +136,17 @@ int main(int argc, char *argv[])
main_mobile_init();
skip_args = handle_options(argc, argv);
argc -= skip_args;
argv += skip_args;
/* handle options / config file */
add_options();
rc = options_config_file("~/.osmocom/analog/anetz.conf", handle_options);
if (rc < 0)
return 0;
argi = options_command_line(argc, argv, handle_options);
if (argi <= 0)
return argi;
if (argc > 1) {
station_id = argv[1];
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 5 && strlen(station_id) != 7) {
printf("Given station ID '%s' does not have 7 or (the last) 5 digits\n", station_id);
return 0;
@ -170,7 +157,7 @@ int main(int argc, char *argv[])
if (!num_kanal) {
printf("No channel (\"Kanal\") is specified, I suggest channel 30.\n\n");
print_help(argv[-skip_args]);
print_help(argv[0]);
return 0;
}
if (use_sdr) {

@ -15,6 +15,7 @@ bnetz_SOURCES = \
bnetz_LDADD = \
$(COMMON_LA) \
../anetz/libgermanton.a \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libmobile/libmobile.a \
$(top_builddir)/src/libdisplay/libdisplay.a \
@ -36,6 +37,7 @@ bnetz_dialer_SOURCES = \
dialer.c
bnetz_dialer_LDADD = \
$(COMMON_LA) \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libfsk/libfsk.a \
$(top_builddir)/src/libfm/libfm.a \

@ -19,10 +19,10 @@
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "../libsample/sample.h"
#include "../libfsk/fsk.h"
#include "../libwave/wave.h"
@ -30,6 +30,7 @@
#ifdef HAVE_ALSA
#include "../libsound/sound.h"
#endif
#include "../liboptions/options.h"
#include "telegramm.h"
#define MAX_PAUSE 0.5 /* pause before and after dialing sequence */
@ -92,7 +93,6 @@ static void print_help(const char *arg0)
printf(" -a --audio-device hw:<card>,<device>\n");
printf(" Sound card and device number (default = '%s')\n", audiodev);
#endif
printf(" Don't set it for SDR!\n");
printf(" -s --samplerate <rate>\n");
printf(" Sample rate of sound device (default = '%d')\n", samplerate);
printf(" -w --write-tx-wave <file>\n");
@ -106,70 +106,50 @@ static void print_help(const char *arg0)
printf(" Indicate to base station that we are a pay phone. ('Muenztelefon')\n");
}
static int handle_options(int argc, char **argv)
static void add_options(void)
{
const char *optstring;
int skip_args = 0;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"station-id", 1, 0, 'i'},
{"audio-device", 1, 0, 'a'},
{"samplerate", 1, 0, 's'},
{"write-tx-wave", 1, 0, 'w'},
{"gebuehrenimpuls", 0, 0, 'g'},
{"metering", 0, 0, OPT_METERING},
{"muenztelefon", 0, 0, 'm'},
{"coin-box", 0, 0, OPT_COIN_BOX},
{0, 0, 0, 0},
};
optstring = "hi:a:s:w:gm";
while (1) {
int option_index = 0, c;
c = getopt_long(argc, argv, optstring, long_options, &option_index);
if (c == -1)
break;
option_add('h', "help", 0);
option_add('i', "station-id", 1);
option_add('a', "audio-device", 1);
option_add('s', "samplerate", 1);
option_add('w', "write-tx-wave", 1);
option_add('g', "gebuehrenimpuls", 0);
option_add(OPT_METERING, "metering", 0);
option_add('m', "muenztelefon", 0);
option_add(OPT_COIN_BOX, "coin-box", 0);
}
switch (c) {
case 'h':
print_help(argv[0]);
exit(0);
case 'i':
station_id = strdup(optarg);
skip_args += 2;
break;
case 'a':
audiodev = strdup(optarg);
skip_args += 2;
break;
case 's':
samplerate = atoi(optarg);
skip_args += 2;
break;
case 'w':
write_tx_wave = strdup(optarg);
skip_args += 2;
break;
case 'g':
case OPT_METERING:
start_digit = 'S';
skip_args += 1;
break;
case 'm':
case OPT_COIN_BOX:
start_digit = 'M';
skip_args += 1;
break;
default:
break;
}
static int handle_options(int short_option, int __attribute__((unused)) argi, char **argv)
{
switch (short_option) {
case 'h':
print_help(argv[0]);
return 0;
case 'i':
station_id = strdup(argv[argi]);
break;
case 'a':
audiodev = strdup(argv[argi]);
break;
case 's':
samplerate = atoi(argv[argi]);
break;
case 'w':
write_tx_wave = strdup(argv[argi]);
break;
case 'g':
case OPT_METERING:
start_digit = 'S';
break;
case 'm':
case OPT_COIN_BOX:
start_digit = 'M';
break;
default:
return -EINVAL;
}
return skip_args;
return 1;
}
@ -301,10 +281,8 @@ static void process_signal(void)
int main(int argc, char *argv[])
{
const char *arg0 = argv[0];
int skip_args;
int i;
int rc;
int rc, argi;
/* init */
bnetz_init_telegramm();
@ -313,13 +291,15 @@ int main(int argc, char *argv[])
/* latency of send buffer in samples */
latspl = samplerate * latency / 1000;
skip_args = handle_options(argc, argv);
argc -= skip_args;
argv += skip_args;
/* handle options / config file */
add_options();
argi = options_command_line(argc, argv, handle_options);
if (argi <= 0)
return argi;
if (argc <= 1) {
if (argi >= argc) {
printf("No phone number given!\n\n");
print_help(arg0);
print_help(argv[0]);
goto exit;
}
@ -336,7 +316,7 @@ int main(int argc, char *argv[])
}
/* check for valid phone number */
dialing = argv[1];
dialing = argv[argi];
if (strlen(dialing) < 4) {
printf("Given phone number '%s' has too few digits! (less than minimum of 4 digits)\n", dialing);
goto exit;

@ -19,9 +19,9 @@
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include "../libsample/sample.h"
#include "../libdebug/debug.h"
@ -29,6 +29,7 @@
#include "../libmobile/main_mobile.h"
#include "../anetz/freiton.h"
#include "../anetz/besetztton.h"
#include "../liboptions/options.h"
#include "bnetz.h"
#include "dsp.h"
#include "stations.h"
@ -79,70 +80,54 @@ void print_help(const char *arg0)
main_mobile_print_hotkeys();
}
static int handle_options(int argc, char **argv)
static void add_options(void)
{
main_mobile_add_options();
option_add('G', "gfs", 1);
option_add('M', "gebuehrenimpuls", 1);
option_add('P', "paging", 1);
option_add('S', "squelch", 1);
}
static int handle_options(int short_option, int argi, char **argv)
{
int skip_args = 0;
char *p;
static struct option long_options_special[] = {
{"gfs", 1, 0, 'G'},
{"gebuehrenimpuls", 1, 0, 'M'},
{"paging", 1, 0, 'P'},
{"squelch", 1, 0, 'S'},
{0, 0, 0, 0},
};
main_mobile_set_options("G:M:P:S:", long_options_special);
while (1) {
int option_index = 0, c;
c = getopt_long(argc, argv, optstring, long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'G':
if (!strcasecmp(optarg, "list")) {
station_list();
exit(0);
}
if ((p = strchr(optarg, ','))) {
gfs = get_station_by_coordinates(atof(optarg), atof(p + 1));
if (gfs == 0)
exit(0);
} else
gfs = atoi(optarg);
skip_args += 2;
break;
case 'M':
metering = atoi(optarg);
skip_args += 2;
break;
case 'P':
paging = strdup(optarg);
skip_args += 2;
break;
case 'S':
if (!strcasecmp(optarg, "auto"))
squelch_db = 0.0;
else
squelch_db = atof(optarg);
skip_args += 2;
break;
default:
main_mobile_opt_switch(c, argv[0], &skip_args);
switch (short_option) {
case 'G':
if (!strcasecmp(argv[argi], "list")) {
station_list();
return 0;
}
if ((p = strchr(argv[argi], ','))) {
gfs = get_station_by_coordinates(atof(argv[argi]), atof(p + 1));
if (gfs == 0)
return -EINVAL;
} else
gfs = atoi(argv[argi]);
break;
case 'M':
metering = atoi(argv[argi]);
break;
case 'P':
paging = strdup(argv[argi]);
break;
case 'S':
if (!strcasecmp(argv[argi], "auto"))
squelch_db = 0.0;
else
squelch_db = atof(argv[argi]);
break;
default:
return main_mobile_handle_options(short_option, argi, argv);
}
return skip_args;
return 1;
}
int main(int argc, char *argv[])
{
int rc;
int skip_args;
int rc, argi;
const char *station_id = "";
int i;
@ -153,12 +138,17 @@ int main(int argc, char *argv[])
main_mobile_init();
skip_args = handle_options(argc, argv);
argc -= skip_args;
argv += skip_args;
/* handle options / config file */
add_options();
rc = options_config_file("~/.osmocom/analog/bnetz.conf", handle_options);
if (rc < 0)
return 0;
argi = options_command_line(argc, argv, handle_options);
if (argi <= 0)
return argi;
if (argc > 1) {
station_id = argv[1];
if (argi < argc) {
station_id = argv[argi];
if (strlen(station_id) != 5) {
printf("Given station ID '%s' does not have 5 digits\n", station_id);
return 0;
@ -167,7 +157,7 @@ int main(int argc, char *argv[])
if (!num_kanal) {
printf("No channel (\"Kanal\") is specified, I suggest channel 1 (sound card) or 17 (SDR).\n\n");
print_help(argv[-skip_args]);
print_help(argv[0]);
return 0;
}
if (use_sdr) {

@ -17,6 +17,7 @@ cnetz_SOURCES = \
cnetz_LDADD = \
$(COMMON_LA) \
../anetz/libgermanton.a \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libmobile/libmobile.a \
$(top_builddir)/src/libdisplay/libdisplay.a \

@ -19,15 +19,16 @@
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "../libsample/sample.h"
#include "../libmobile/main_mobile.h"
#include "../libdebug/debug.h"
#include "../libmobile/call.h"
#include "../anetz/freiton.h"
#include "../anetz/besetztton.h"
#include "../liboptions/options.h"
#include "cnetz.h"
#include "database.h"
#include "sysinfo.h"
@ -216,198 +217,174 @@ static int atoi_limit(const char *p, int l1, int l2)
#define OPT_WARTESCHLANGE 256
static int handle_options(int argc, char **argv)
static void add_options(void)
{
main_mobile_add_options();
option_add('T', "channel-type", 1);
option_add('M', "measure-speed", 0);
option_add('C', "clock-speed", 1);
option_add('F', "flip-polarity", 1);
option_add('P', "ms-power", 1);
option_add('A', "authentication", 0);
option_add('Q', "queue", 1);
option_add(OPT_WARTESCHLANGE, "warteschlange", 1);
option_add('G', "gebuehren", 1);
option_add('S', "sysinfo", 1);
option_add('D', "demod", 1);
}
static int handle_options(int short_option, int argi, char **argv)
{
int skip_args = 0;
int rc;
const char *p;
static struct option long_options_special[] = {
{"channel-type", 1, 0, 'T'},
{"measure-speed", 0, 0, 'M'},
{"clock-speed", 1, 0, 'C'},
{"flip-polarity", 1, 0, 'F'},
{"ms-power", 1, 0, 'P'},
{"authentication", 0, 0, 'A'},
{"queue", 1, 0, 'Q'},
{"warteschlange", 1, 0, OPT_WARTESCHLANGE},
{"gebuehren", 1, 0, 'G'},
{"sysinfo", 1, 0, 'S'},
{"demod", 1, 0, 'D'},
{0, 0, 0, 0}
};
main_mobile_set_options("T:MC:F:P:AQ:G:S:D:", long_options_special);
while (1) {
int option_index = 0, c;
c = getopt_long(argc, argv, optstring, long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'T':
if (!strcmp(optarg, "list")) {
cnetz_channel_list();
exit(0);
}
rc = cnetz_channel_by_short_name(optarg);
if (rc < 0) {
fprintf(stderr, "Error, channel type '%s' unknown. Please use '-t list' to get a list. I suggest to use the default.\n", optarg);
exit(0);
}
OPT_ARRAY(num_chan_type, chan_type, rc)
skip_args += 2;
break;
case 'M':
measure_speed = 1;
skip_args++;
break;
case 'C':
p = strchr(optarg, ',');
if (!p) {
fprintf(stderr, "Illegal clock speed, use two values, seperated by comma and no spaces!\n");
exit(0);
}
clock_speed[0] = strtold(optarg, NULL);
clock_speed[1] = strtold(p + 1, NULL);
set_clock_speed = 1;
skip_args += 2;
break;
case 'F':
if (!strcasecmp(optarg, "no"))
flip_polarity = "no";
else if (!strcasecmp(optarg, "yes"))
flip_polarity = "yes";
else if (!strcasecmp(optarg, "auto"))
flip_polarity = "auto";
else {
fprintf(stderr, "Given polarity '%s' is illegal, see help!\n", optarg);
exit(0);
}
skip_args += 2;
break;
case 'P':
ms_power = atoi_limit(optarg, 0, 3);
skip_args += 2;
break;
case 'A':
auth = 1;
skip_args += 1;
break;
case 'Q':
case OPT_WARTESCHLANGE:
warteschlange = atoi_limit(optarg, 0, 1);;
skip_args += 2;
break;
case 'G':
metering = atoi(optarg);
skip_args += 2;
break;
case 'S':
p = strchr(optarg, '=');
if (!p) {
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, see help!\n", optarg);
exit(0);
}
p++;
if (!strncasecmp(optarg, "fuz-nat=", p - optarg)) {
fuz_nat = atoi_limit(p, 0, 7);
} else
if (!strncasecmp(optarg, "fuz-fuvst=", p - optarg)) {
fuz_fuvst = atoi_limit(p, 0, 32);
} else
if (!strncasecmp(optarg, "fuz-rest=", p - optarg)) {
fuz_rest = atoi_limit(p, 0, 255);
} else
if (!strncasecmp(optarg, "kennung-fufst=", p - optarg)) {
kennung_fufst = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(optarg, "ws-kennung=", p - optarg)) {
ws_kennung = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(optarg, "fuvst-sperren=", p - optarg)) {
fuvst_sperren = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(optarg, "grenz-einbuchen=", p - optarg)) {
grenz_einbuchen = atoi_limit(p, 0, 7);
} else
if (!strncasecmp(optarg, "grenz-umschalten=", p - optarg)) {
grenz_umschalten = atoi_limit(p, 0, 15);
} else
if (!strncasecmp(optarg, "grenz-ausloesen=", p - optarg)) {
grenz_ausloesen = atoi_limit(p, 0, 15);
} else
if (!strncasecmp(optarg, "mittel-umschalten=", p - optarg)) {
mittel_umschalten = atoi_limit(p, 0, 5);
} else
if (!strncasecmp(optarg, "mittel-ausloesen=", p - optarg)) {
mittel_ausloesen = atoi_limit(p, 0, 5);
} else
if (!strncasecmp(optarg, "genauigkeit=", p - optarg)) {
genauigkeit = atoi_limit(p, 0, 1);
} else
if (!strncasecmp(optarg, "bewertung=", p - optarg)) {
bewertung = atoi_limit(p, 0, 1);
} else
if (!strncasecmp(optarg, "entfernung=", p - optarg)) {
entfernung = atoi_limit(p, 0, 15);
} else
if (!strncasecmp(optarg, "nachbar-prio=", p - optarg)) {
nachbar_prio = atoi_limit(p, 0, 1);
} else
if (!strncasecmp(optarg, "futln-sperre=", p - optarg)) {
char value[128], *v, *q;
strncpy(value, p, sizeof(value) - 1);
value[sizeof(value) - 1] = '\0';
v = value;
q = strchr(value, '-');
if (q)
*q++ = '\0';
if (strlen(v) > 5)
v += strlen(v) - 5;
futln_sperre_start = atoi(v) & 0xf;
if (q) {
if (strlen(q) > 5)
q += strlen(q) - 5;
futln_sperre_end = atoi(q) & 0xf;
}
} else
{
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
exit(0);
}
skip_args += 2;
break;
case 'D':
if (!strcasecmp(optarg, "auto"))
demod = FSK_DEMOD_AUTO;
else if (!strcasecmp(optarg, "slope"))
demod = FSK_DEMOD_SLOPE;
else if (!strcasecmp(optarg, "level"))
demod = FSK_DEMOD_LEVEL;
else {
fprintf(stderr, "Given demodulation type '%s' is illegal, see help!\n", optarg);
exit(0);
switch (short_option) {
case 'T':
if (!strcmp(argv[argi], "list")) {
cnetz_channel_list();
return 0;
}
rc = cnetz_channel_by_short_name(argv[argi]);
if (rc < 0) {
fprintf(stderr, "Error, channel type '%s' unknown. Please use '-t list' to get a list. I suggest to use the default.\n", argv[argi]);
return -EINVAL;
}
OPT_ARRAY(num_chan_type, chan_type, rc)
break;
case 'M':
measure_speed = 1;
break;
case 'C':
p = strchr(argv[argi], ',');
if (!p) {
fprintf(stderr, "Illegal clock speed, use two values, seperated by comma and no spaces!\n");
return -EINVAL;
}
clock_speed[0] = strtold(argv[argi], NULL);
clock_speed[1] = strtold(p + 1, NULL);
set_clock_speed = 1;
break;
case 'F':
if (!strcasecmp(argv[argi], "no"))
flip_polarity = "no";
else if (!strcasecmp(argv[argi], "yes"))
flip_polarity = "yes";
else if (!strcasecmp(argv[argi], "auto"))
flip_polarity = "auto";
else {
fprintf(stderr, "Given polarity '%s' is illegal, use '-h' for help!\n", argv[argi]);
return -EINVAL;
}
break;
case 'P':
ms_power = atoi_limit(argv[argi], 0, 3);
break;
case 'A':
auth = 1;
break;
case 'Q':
case OPT_WARTESCHLANGE:
warteschlange = atoi_limit(argv[argi], 0, 1);;
break;
case 'G':
metering = atoi(argv[argi]);
break;
case 'S':
p = strchr(argv[argi], '=');
if (!p) {
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, use '-h' for help!\n", argv[argi]);
return -EINVAL;
}
p++;
if (!strncasecmp(argv[argi], "fuz-nat=", p - argv[argi])) {
fuz_nat = atoi_limit(p, 0, 7);
} else
if (!strncasecmp(argv[argi], "fuz-fuvst=", p - argv[argi])) {
fuz_fuvst = atoi_limit(p, 0, 32);
} else
if (!strncasecmp(argv[argi], "fuz-rest=", p - argv[argi])) {
fuz_rest = atoi_limit(p, 0, 255);
} else
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
kennung_fufst = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(argv[argi], "ws-kennung=", p - argv[argi])) {
ws_kennung = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(argv[argi], "fuvst-sperren=", p - argv[argi])) {
fuvst_sperren = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(argv[argi], "grenz-einbuchen="