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
This commit is contained in:
parent
6ba1b8acab
commit
3b81007210
|
@ -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,85 +104,71 @@ 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) {
|
||||
switch (short_option) {
|
||||
case 'T':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
amps_channel_list();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
rc = amps_channel_by_short_name(optarg);
|
||||
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", optarg);
|
||||
exit(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)
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'F':
|
||||
if (!strcasecmp(optarg, "no"))
|
||||
if (!strcasecmp(argv[argi], "no"))
|
||||
flip_polarity = "no";
|
||||
else if (!strcasecmp(optarg, "yes"))
|
||||
else if (!strcasecmp(argv[argi], "yes"))
|
||||
flip_polarity = "yes";
|
||||
else {
|
||||
fprintf(stderr, "Given polarity '%s' is illegal, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given polarity '%s' is illegal, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'P':
|
||||
ms_power = atoi(optarg);
|
||||
ms_power = atoi(argv[argi]);
|
||||
if (ms_power > 7)
|
||||
ms_power = 7;
|
||||
if (ms_power < 0)
|
||||
ms_power = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'D':
|
||||
dtx = atoi(optarg);
|
||||
dtx = atoi(argv[argi]);
|
||||
if (dtx > 3)
|
||||
dtx = 3;
|
||||
if (dtx < 0)
|
||||
dtx = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'S':
|
||||
p = strchr(optarg, '=');
|
||||
p = strchr(argv[argi], '=');
|
||||
if (!p) {
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
p++;
|
||||
if (!strncasecmp(optarg, "sid=", p - optarg)
|
||||
|| !strncasecmp(optarg, "aid=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "sid=", p - argv[argi])
|
||||
|| !strncasecmp(argv[argi], "aid=", p - argv[argi])) {
|
||||
if (!strcasecmp(p, "list")) {
|
||||
list_stations();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
sid = atoi(p);
|
||||
if (sid > 32767)
|
||||
|
@ -189,66 +176,60 @@ static int handle_options(int argc, char **argv)
|
|||
if (sid < 0)
|
||||
sid = 0;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "dcc=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "dcc=", p - argv[argi])) {
|
||||
dcc = atoi(p);
|
||||
if (dcc > 3)
|
||||
dcc = 3;
|
||||
if (dcc < 0)
|
||||
dcc = 0;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "scc=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "scc=", p - argv[argi])) {
|
||||
scc = atoi(p);
|
||||
if (scc > 2)
|
||||
scc = 2;
|
||||
if (scc < 0)
|
||||
scc = 0;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "regincr=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "regincr=", p - argv[argi])) {
|
||||
regincr = atoi(p);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "pureg=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "pureg=", p - argv[argi])) {
|
||||
pureg = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "pdreg=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "pdreg=", p - argv[argi])) {
|
||||
pdreg = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "locaid=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "locaid=", p - argv[argi])) {
|
||||
locaid = atoi(p);
|
||||
if (locaid > 4095)
|
||||
locaid = 4095;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "regh=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "regh=", p - argv[argi])) {
|
||||
regh = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "regr=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "regr=", p - argv[argi])) {
|
||||
regr = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "bis=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "bis=", p - argv[argi])) {
|
||||
bis = atoi(p) & 1;
|
||||
} else {
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' unknown, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'O':
|
||||
tolerant = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
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) {
|
||||
switch (short_option) {
|
||||
case 'O':
|
||||
strncpy(operator, optarg, sizeof(operator) - 1);
|
||||
strncpy(operator, argv[argi], sizeof(operator) - 1);
|
||||
operator[sizeof(operator) - 1] = '\0';
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'G':
|
||||
if (!strcasecmp(optarg, "list")) {
|
||||
if (!strcasecmp(argv[argi], "list")) {
|
||||
station_list();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
if ((p = strchr(optarg, ','))) {
|
||||
get_station_by_coordinates(atof(optarg), atof(p + 1));
|
||||
exit(0);
|
||||
if ((p = strchr(argv[argi], ','))) {
|
||||
get_station_by_coordinates(atof(argv[argi]), atof(p + 1));
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "Invalid geo parameter\n");
|
||||
exit(0);
|
||||
break;
|
||||
return -EINVAL;
|
||||
case 'V':
|
||||
gain_db = atof(optarg);
|
||||
gain_db = atof(argv[argi]);
|
||||
page_gain = pow(10, gain_db / 20.0);
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'P':
|
||||
page_sequence = atoi(optarg);
|
||||
skip_args += 2;
|
||||
page_sequence = atoi(argv[argi]);
|
||||
break;
|
||||
case 'S':
|
||||
if (!strcasecmp(optarg, "auto"))
|
||||
if (!strcasecmp(argv[argi], "auto"))
|
||||
squelch_db = 0.0;
|
||||
else
|
||||
squelch_db = atof(optarg);
|
||||
skip_args += 2;
|
||||
squelch_db = atof(argv[argi]);
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
switch (c) {
|
||||
static int handle_options(int short_option, int __attribute__((unused)) argi, char **argv)
|
||||
{
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_help(argv[0]);
|
||||
exit(0);
|
||||
return 0;
|
||||
case 'i':
|
||||
station_id = strdup(optarg);
|
||||
skip_args += 2;
|
||||
station_id = strdup(argv[argi]);
|
||||
break;
|
||||
case 'a':
|
||||
audiodev = strdup(optarg);
|
||||
skip_args += 2;
|
||||
audiodev = strdup(argv[argi]);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
skip_args += 2;
|
||||
samplerate = atoi(argv[argi]);
|
||||
break;
|
||||
case 'w':
|
||||
write_tx_wave = strdup(optarg);
|
||||
skip_args += 2;
|
||||
write_tx_wave = strdup(argv[argi]);
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
switch (short_option) {
|
||||
case 'G':
|
||||
if (!strcasecmp(optarg, "list")) {
|
||||
if (!strcasecmp(argv[argi], "list")) {
|
||||
station_list();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
if ((p = strchr(optarg, ','))) {
|
||||
gfs = get_station_by_coordinates(atof(optarg), atof(p + 1));
|
||||
if ((p = strchr(argv[argi], ','))) {
|
||||
gfs = get_station_by_coordinates(atof(argv[argi]), atof(p + 1));
|
||||
if (gfs == 0)
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
} else
|
||||
gfs = atoi(optarg);
|
||||
skip_args += 2;
|
||||
gfs = atoi(argv[argi]);
|
||||
break;
|
||||
case 'M':
|
||||
metering = atoi(optarg);
|
||||
skip_args += 2;
|
||||
metering = atoi(argv[argi]);
|
||||
break;
|
||||
case 'P':
|
||||
paging = strdup(optarg);
|
||||
skip_args += 2;
|
||||
paging = strdup(argv[argi]);
|
||||
break;
|
||||
case 'S':
|
||||
if (!strcasecmp(optarg, "auto"))
|
||||
if (!strcasecmp(argv[argi], "auto"))
|
||||
squelch_db = 0.0;
|
||||
else
|
||||
squelch_db = atof(optarg);
|
||||
skip_args += 2;
|
||||
squelch_db = atof(argv[argi]);
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
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 \
|
||||
|
|
170
src/cnetz/main.c
170
src/cnetz/main.c
|
@ -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,149 +217,131 @@ 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) {
|
||||
switch (short_option) {
|
||||
case 'T':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
cnetz_channel_list();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
rc = cnetz_channel_by_short_name(optarg);
|
||||
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", optarg);
|
||||
exit(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)
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'M':
|
||||
measure_speed = 1;
|
||||
skip_args++;
|
||||
break;
|
||||
case 'C':
|
||||
p = strchr(optarg, ',');
|
||||
p = strchr(argv[argi], ',');
|
||||
if (!p) {
|
||||
fprintf(stderr, "Illegal clock speed, use two values, seperated by comma and no spaces!\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
clock_speed[0] = strtold(optarg, NULL);
|
||||
clock_speed[0] = strtold(argv[argi], NULL);
|
||||
clock_speed[1] = strtold(p + 1, NULL);
|
||||
set_clock_speed = 1;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'F':
|
||||
if (!strcasecmp(optarg, "no"))
|
||||
if (!strcasecmp(argv[argi], "no"))
|
||||
flip_polarity = "no";
|
||||
else if (!strcasecmp(optarg, "yes"))
|
||||
else if (!strcasecmp(argv[argi], "yes"))
|
||||
flip_polarity = "yes";
|
||||
else if (!strcasecmp(optarg, "auto"))
|
||||
else if (!strcasecmp(argv[argi], "auto"))
|
||||
flip_polarity = "auto";
|
||||
else {
|
||||
fprintf(stderr, "Given polarity '%s' is illegal, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given polarity '%s' is illegal, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'P':
|
||||
ms_power = atoi_limit(optarg, 0, 3);
|
||||
skip_args += 2;
|
||||
ms_power = atoi_limit(argv[argi], 0, 3);
|
||||
break;
|
||||
case 'A':
|
||||
auth = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
case 'Q':
|
||||
case OPT_WARTESCHLANGE:
|
||||
warteschlange = atoi_limit(optarg, 0, 1);;
|
||||
skip_args += 2;
|
||||
warteschlange = atoi_limit(argv[argi], 0, 1);;
|
||||
break;
|
||||
case 'G':
|
||||
metering = atoi(optarg);
|
||||
skip_args += 2;
|
||||
metering = atoi(argv[argi]);
|
||||
break;
|
||||
case 'S':
|
||||
p = strchr(optarg, '=');
|
||||
p = strchr(argv[argi], '=');
|
||||
if (!p) {
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
p++;
|
||||
if (!strncasecmp(optarg, "fuz-nat=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "fuz-nat=", p - argv[argi])) {
|
||||
fuz_nat = atoi_limit(p, 0, 7);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "fuz-fuvst=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "fuz-fuvst=", p - argv[argi])) {
|
||||
fuz_fuvst = atoi_limit(p, 0, 32);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "fuz-rest=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "fuz-rest=", p - argv[argi])) {
|
||||
fuz_rest = atoi_limit(p, 0, 255);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "kennung-fufst=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
|
||||
kennung_fufst = atoi_limit(p, 0, 3);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "ws-kennung=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "ws-kennung=", p - argv[argi])) {
|
||||
ws_kennung = atoi_limit(p, 0, 3);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "fuvst-sperren=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "fuvst-sperren=", p - argv[argi])) {
|
||||
fuvst_sperren = atoi_limit(p, 0, 3);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "grenz-einbuchen=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "grenz-einbuchen=", p - argv[argi])) {
|
||||
grenz_einbuchen = atoi_limit(p, 0, 7);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "grenz-umschalten=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "grenz-umschalten=", p - argv[argi])) {
|
||||
grenz_umschalten = atoi_limit(p, 0, 15);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "grenz-ausloesen=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "grenz-ausloesen=", p - argv[argi])) {
|
||||
grenz_ausloesen = atoi_limit(p, 0, 15);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "mittel-umschalten=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "mittel-umschalten=", p - argv[argi])) {
|
||||
mittel_umschalten = atoi_limit(p, 0, 5);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "mittel-ausloesen=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "mittel-ausloesen=", p - argv[argi])) {
|
||||
mittel_ausloesen = atoi_limit(p, 0, 5);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "genauigkeit=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "genauigkeit=", p - argv[argi])) {
|
||||
genauigkeit = atoi_limit(p, 0, 1);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "bewertung=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "bewertung=", p - argv[argi])) {
|
||||
bewertung = atoi_limit(p, 0, 1);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "entfernung=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "entfernung=", p - argv[argi])) {
|
||||
entfernung = atoi_limit(p, 0, 15);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "nachbar-prio=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "nachbar-prio=", p - argv[argi])) {
|
||||
nachbar_prio = atoi_limit(p, 0, 1);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "futln-sperre=", p - optarg)) {
|
||||
if (!strncasecmp(argv[argi], "futln-sperre=", p - argv[argi])) {
|
||||
char value[128], *v, *q;
|
||||
strncpy(value, p, sizeof(value) - 1);
|
||||
value[sizeof(value) - 1] = '\0';
|
||||
|
@ -376,38 +359,32 @@ static int handle_options(int argc, char **argv)
|
|||
}
|
||||
} else
|
||||
{
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' unknown, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'D':
|
||||
if (!strcasecmp(optarg, "auto"))
|
||||
if (!strcasecmp(argv[argi], "auto"))
|
||||
demod = FSK_DEMOD_AUTO;
|
||||
else if (!strcasecmp(optarg, "slope"))
|
||||
else if (!strcasecmp(argv[argi], "slope"))
|
||||
demod = FSK_DEMOD_SLOPE;
|
||||
else if (!strcasecmp(optarg, "level"))
|
||||
else if (!strcasecmp(argv[argi], "level"))
|
||||
demod = FSK_DEMOD_LEVEL;
|
||||
else {
|
||||
fprintf(stderr, "Given demodulation type '%s' is illegal, see help!\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Given demodulation type '%s' is illegal, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
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 mandatory = 0;
|
||||
int polarity;
|
||||
|
@ -422,12 +399,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/cnetz.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) != 7) {
|
||||
printf("Given station ID '%s' does not have 7 digits\n", station_id);
|
||||
return 0;
|
||||
|
@ -470,7 +452,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (mandatory) {
|
||||
print_help(argv[-skip_args]);
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ jollycom_SOURCES = \
|
|||
jollycom_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 \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* main
|
||||
/* JollyCom main
|
||||
*
|
||||
* (C) 2017 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
|
@ -19,11 +19,11 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include "../libmncc/mncc_sock.h"
|
||||
#include "../anetz/freiton.h"
|
||||
#include "../anetz/besetztton.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "jolly.h"
|
||||
#include "dsp.h"
|
||||
#include "voice.h"
|
||||
|
@ -70,32 +71,22 @@ void print_help(const char *arg0)
|
|||
main_mobile_print_hotkeys();
|
||||
}
|
||||
|
||||
static int handle_options(int argc, char **argv)
|
||||
static void add_options(void)
|
||||
{
|
||||
int skip_args = 0;
|
||||
main_mobile_add_options();
|
||||
option_add('F', "frequency", 1);
|
||||
option_add('S', "squelch", 1);
|
||||
option_add('N', "nbfm", 0);
|
||||
option_add('R', "repeater", 0);
|
||||
}
|
||||
|
||||
static struct option long_options_special[] = {
|
||||
{"frequency", 1, 0, 'F'},
|
||||
{"squelch", 1, 0, 'S'},
|
||||
{"nbfm", 0, 0, 'N'},
|
||||
{"repeater", 0, 0, 'R'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
main_mobile_set_options("F:S:NR", long_options_special);
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
char *string, *string_dl, *string_ul, *string_step;
|
||||
|
||||
c = getopt_long(argc, argv, optstring, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
switch (short_option) {
|
||||
case 'F':
|
||||
string = strdup(optarg);
|
||||
string = strdup(argv[argi]);
|
||||
string_dl = strsep(&string, ",");
|
||||
string_ul = strsep(&string, ",");
|
||||
string_step = strsep(&string, ",");
|
||||
|
@ -106,37 +97,29 @@ static int handle_options(int argc, char **argv)
|
|||
dl_freq = atof(string_dl);
|
||||
ul_freq = atof(string_ul);
|
||||
step = atof(string_step);
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'S':
|
||||
if (!strcasecmp(optarg, "auto"))
|
||||
if (!strcasecmp(argv[argi], "auto"))
|
||||
squelch_db = 0.0;
|
||||
else
|
||||
squelch_db = atof(optarg);
|
||||
skip_args += 2;
|
||||
squelch_db = atof(argv[argi]);
|
||||
break;
|
||||
case 'N':
|
||||
nbfm = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
case 'R':
|
||||
repeater = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
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 mandatory = 0;
|
||||
int i;
|
||||
|
@ -148,12 +131,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/jollycom.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) != 4) {
|
||||
printf("Given station ID '%s' does not have 4 digits\n", station_id);
|
||||
return 0;
|
||||
|
@ -178,7 +166,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (mandatory) {
|
||||
print_help(argv[-skip_args]);
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ jtacs_SOURCES = \
|
|||
jtacs_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
../amps/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 \
|
||||
|
|
|
@ -41,6 +41,7 @@ struct debug_cat {
|
|||
const char *name;
|
||||
const char *color;
|
||||
} debug_cat[] = {
|
||||
{ "options", "\033[1;37m" },
|
||||
{ "sender", "\033[1;33m" },
|
||||
{ "sound", "\033[0;35m" },
|
||||
{ "dsp", "\033[0;31m" },
|
||||
|
|
|
@ -4,28 +4,29 @@
|
|||
#define DEBUG_NOTICE 2 /* something unexpected happens */
|
||||
#define DEBUG_ERROR 3 /* there is an error with this software */
|
||||
|
||||
#define DSENDER 0
|
||||
#define DSOUND 1
|
||||
#define DDSP 2
|
||||
#define DANETZ 3
|
||||
#define DBNETZ 4
|
||||
#define DCNETZ 5
|
||||
#define DNMT 6
|
||||
#define DAMPS 7
|
||||
#define DR2000 8
|
||||
#define DJOLLY 9
|
||||
#define DFRAME 10
|
||||
#define DCALL 11
|
||||
#define DMNCC 12
|
||||
#define DDB 13
|
||||
#define DTRANS 14
|
||||
#define DDMS 15
|
||||
#define DSMS 16
|
||||
#define DSDR 17
|
||||
#define DUHD 18
|
||||
#define DSOAPY 19
|
||||
#define DWAVE 20
|
||||
#define DRADIO 21
|
||||
#define DOPTIONS 0
|
||||
#define DSENDER 1
|
||||
#define DSOUND 2
|
||||
#define DDSP 3
|
||||
#define DANETZ 4
|
||||
#define DBNETZ 5
|
||||
#define DCNETZ 6
|
||||
#define DNMT 7
|
||||
#define DAMPS 8
|
||||
#define DR2000 9
|
||||
#define DJOLLY 10
|
||||
#define DFRAME 11
|
||||
#define DCALL 12
|
||||
#define DMNCC 13
|
||||
#define DDB 14
|
||||
#define DTRANS 15
|
||||
#define DDMS 16
|
||||
#define DSMS 17
|
||||
#define DSDR 18
|
||||
#define DUHD 19
|
||||
#define DSOAPY 20
|
||||
#define DWAVE 21
|
||||
#define DRADIO 22
|
||||
|
||||
void get_win_size(int *w, int *h);
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
@ -28,7 +27,6 @@
|
|||
#include <math.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "main_mobile.h"
|
||||
#include "../libdebug/debug.h"
|
||||
|
@ -42,6 +40,7 @@
|
|||
#include "../libsdr/sdr.h"
|
||||
#include "../libsdr/sdr_config.h"
|
||||
#endif
|
||||
#include "../liboptions/options.h"
|
||||
|
||||
#define DEFAULT_LO_OFFSET -1000000.0
|
||||
|
||||
|
@ -153,6 +152,8 @@ void main_mobile_print_help(const char *arg0, const char *ext_usage)
|
|||
printf(" --read-tx-wave <file>\n");
|
||||
printf(" Replace transmitted audio by given wave file.\n");
|
||||
#ifdef HAVE_SDR
|
||||
printf(" --limesdr\n");
|
||||
printf(" Auto-select several required options for LimeSDR\n");
|
||||
sdr_config_print_help();
|
||||
#endif
|
||||
printf("\nNetwork specific options:\n");
|
||||
|
@ -178,214 +179,167 @@ void main_mobile_print_hotkeys(void)
|
|||
#define OPT_READ_TX_WAVE 1004
|
||||
#define OPT_CALL_SAMPLERATE 1005
|
||||
#define OPT_MNCC_NAME 1006
|
||||
#define OPT_LIMESDR 1100
|
||||
|
||||
static struct option main_mobile_long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"debug", 1, 0, 'v'},
|
||||
{"kanal", 1, 0, 'k'},
|
||||
{"channel", 1, 0, OPT_CHANNEL},
|
||||
{"audio-device", 1, 0, 'a'},
|
||||
{"samplerate", 1, 0, 's'},
|
||||
{"interval", 1, 0, 'i'},
|
||||
{"buffer", 1, 0, 'b'},
|
||||
{"pre-emphasis", 0, 0, 'p'},
|
||||
{"de-emphasis", 0, 0, 'd'},
|
||||
{"rx-gain", 1, 0, 'g'},
|
||||
{"echo-test", 0, 0, 'e'},
|
||||
{"mncc-cross", 0, 0, 'x'},
|
||||
{"mncc-sock", 0, 0, 'm'},
|
||||
{"mncc-name", 1, 0, OPT_MNCC_NAME},
|
||||
{"call-device", 1, 0, 'c'},
|
||||
{"call-samplerate", 1, 0, OPT_CALL_SAMPLERATE},
|
||||
{"tones", 0, 0, 't'},
|
||||
{"loopback", 1, 0, 'l'},
|
||||
{"realtime", 1, 0, 'r'},
|
||||
{"write-rx-wave", 1, 0, OPT_WRITE_RX_WAVE},
|
||||
{"write-tx-wave", 1, 0, OPT_WRITE_TX_WAVE},
|
||||
{"read-rx-wave", 1, 0, OPT_READ_RX_WAVE},
|
||||
{"read-tx-wave", 1, 0, OPT_READ_TX_WAVE},
|
||||
{0, 0, 0, 0}
|
||||
void main_mobile_add_options(void)
|
||||
{
|
||||
option_add('h', "help", 0);
|
||||
option_add('v', "debug", 1);
|
||||
option_add('k', "kanal", 1);
|
||||
option_add(OPT_CHANNEL, "channel", 1);
|
||||
option_add('a', "audio-device", 1);
|
||||
option_add('s', "samplerate", 1);
|
||||
option_add('i', "interval", 1);
|
||||
option_add('b', "buffer", 1);
|
||||
option_add('p', "pre-emphasis", 0);
|
||||
option_add('d', "de-emphasis", 0);
|
||||
option_add('g', "rx-gain", 1);
|
||||
option_add('e', "echo-test", 0);
|
||||
option_add('x', "mncc-cross", 0);
|
||||
option_add('m', "mncc-sock", 0);
|
||||
option_add(OPT_MNCC_NAME, "mncc-name", 1);
|
||||
option_add('c', "call-device", 1);
|
||||
option_add(OPT_CALL_SAMPLERATE, "call-samplerate", 1);
|
||||
option_add('t', "tones", 0);
|
||||
option_add('l', "loopback", 1);
|
||||
option_add('r', "realtime", 1);
|
||||
option_add(OPT_WRITE_RX_WAVE, "write-rx-wave", 1);
|
||||
option_add(OPT_WRITE_TX_WAVE, "write-tx-wave", 1);
|
||||
option_add(OPT_READ_RX_WAVE, "read-rx-wave", 1);
|
||||
option_add(OPT_READ_TX_WAVE, "read-tx-wave", 1);
|
||||
#ifdef HAVE_SDR
|
||||
option_add(OPT_LIMESDR, "limesdr", 0);
|
||||
sdr_config_add_options();
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char *main_mobile_optstring = "hv:k:a:s:i:b:pdg:exmc:t:l:r:";
|
||||
|
||||
struct option *long_options;
|
||||
char *optstring;
|
||||
|
||||
static void check_duplicate_option(int num, struct option *option)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (long_options[i].val == option->val) {
|
||||
fprintf(stderr, "Duplicate option %d. Please fix!\n", option->val);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main_mobile_set_options(const char *optstring_special, struct option *long_options_special)
|
||||
{
|
||||
int i = 0, j;
|
||||
|
||||
long_options = calloc(sizeof(*long_options), 256);
|
||||
for (j = 0; main_mobile_long_options[j].name; i++, j++) {
|
||||
check_duplicate_option(i, &main_mobile_long_options[j]);
|
||||
memcpy(&long_options[i], &main_mobile_long_options[j], sizeof(*long_options));
|
||||
}
|
||||
#ifdef HAVE_SDR
|
||||
for (j = 0; sdr_config_long_options[j].name; i++, j++) {
|
||||
check_duplicate_option(i, &sdr_config_long_options[j]);
|
||||
memcpy(&long_options[i], &sdr_config_long_options[j], sizeof(*long_options));
|
||||
}
|
||||
#endif
|
||||
for (; long_options_special->name; i++) {
|
||||
check_duplicate_option(i, long_options_special);
|
||||
memcpy(&long_options[i], long_options_special++, sizeof(*long_options));
|
||||
}
|
||||
|
||||
optstring = calloc(256, 2);
|
||||
strcpy(optstring, main_mobile_optstring);
|
||||
#ifdef HAVE_SDR
|
||||
strcat(optstring, sdr_config_optstring);
|
||||
#endif
|
||||
strcat(optstring, optstring_special);
|
||||
}
|
||||
|
||||
void print_help(const char *arg0);
|
||||
|
||||
void main_mobile_opt_switch(int c, char *arg0, int *skip_args)
|
||||
int main_mobile_handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
double gain_db;
|
||||
#ifdef HAVE_SDR
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
switch (c) {
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_help(arg0);
|
||||
exit(0);
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
case 'v':
|
||||
if (!strcasecmp(optarg, "list")) {
|
||||
if (!strcasecmp(argv[argi], "list")) {
|
||||
debug_list_cat();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
if (parse_debug_opt(optarg)) {
|
||||
rc = parse_debug_opt(argv[argi]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to parse debug option, please use -h for help.\n");
|
||||
exit(0);
|
||||
return rc;
|
||||
}
|
||||
*skip_args += 2;
|
||||
break;
|
||||
case 'k':
|
||||
case OPT_CHANNEL:
|
||||
OPT_ARRAY(num_kanal, kanal, atoi(optarg))
|
||||
*skip_args += 2;
|
||||
OPT_ARRAY(num_kanal, kanal, atoi(argv[argi]))
|
||||
break;
|
||||
case 'a':
|
||||
OPT_ARRAY(num_audiodev, audiodev, strdup(optarg))
|
||||
*skip_args += 2;
|
||||
OPT_ARRAY(num_audiodev, audiodev, strdup(argv[argi]))
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
samplerate = atoi(argv[argi]);
|
||||
break;
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
interval = atoi(argv[argi]);
|
||||
if (interval < 1)
|
||||
interval = 1;
|
||||
if (interval > 25)
|
||||
interval = 25;
|
||||
break;
|
||||
case 'b':
|
||||
latency = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
latency = atoi(argv[argi]);
|
||||
break;
|
||||
case 'p':
|
||||
if (!uses_emphasis) {
|
||||
no_emph:
|
||||
fprintf(stderr, "This network does not use emphasis, please do not enable pre- or de-emphasis! Disable emphasis on transceiver, if possible.\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
do_pre_emphasis = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case 'd':
|
||||
if (!uses_emphasis)
|
||||
goto no_emph;
|
||||
do_de_emphasis = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case 'g':
|
||||
gain_db = atof(optarg);
|
||||
gain_db = atof(argv[argi]);
|
||||
if (gain_db < 0.0) {
|
||||
fprintf(stderr, "Given gain is below 0. To reduce RX signal, use sound card's mixer (or resistor net)!\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
rx_gain = pow(10, gain_db / 20.0);
|
||||
*skip_args += 2;
|
||||
break;
|
||||
case 'e':
|
||||
echo_test = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case 'x':
|
||||
use_mncc_cross = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case 'm':
|
||||
use_mncc_sock = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case OPT_MNCC_NAME:
|
||||
mncc_name = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
mncc_name = strdup(argv[argi]);
|
||||
break;
|
||||
case 'c':
|
||||
call_audiodev = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
call_audiodev = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_CALL_SAMPLERATE:
|
||||
call_samplerate = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
call_samplerate = atoi(argv[argi]);
|
||||
break;
|
||||
case 't':
|
||||
send_patterns = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
send_patterns = atoi(argv[argi]);
|
||||
break;
|
||||
case 'l':
|
||||
loopback = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
loopback = atoi(argv[argi]);
|
||||
break;
|
||||
case 'r':
|
||||
rt_prio = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
rt_prio = atoi(argv[argi]);
|
||||
break;
|
||||
case OPT_WRITE_RX_WAVE:
|
||||
write_rx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
write_rx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_WRITE_TX_WAVE:
|
||||
write_tx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
write_tx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_READ_RX_WAVE:
|
||||
read_rx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
read_rx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_READ_TX_WAVE:
|
||||
read_tx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
read_tx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
#ifdef HAVE_SDR
|
||||
case OPT_LIMESDR:
|
||||
{
|
||||
char *argv_lime[] = { argv[0],
|
||||
"--sdr-soapy",
|
||||
"--sdr-rx-antenna", "LNAL",
|
||||
"--sdr-rx-gain", "30",
|
||||
"--sdr-tx-gain", "30",
|
||||
"--sdr-samplerate", "5000000",
|
||||
"--sdr-bandwidth", "15000000",
|
||||
"-s", "200000",
|
||||
};
|
||||
int argc_lime = sizeof(argv_lime) / sizeof (*argv_lime);
|
||||
return options_command_line(argc_lime, argv_lime, main_mobile_handle_options);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
#ifdef HAVE_SDR
|
||||
rc = sdr_config_opt_switch(c, skip_args);
|
||||
if (rc < 0)
|
||||
exit (0);
|
||||
|
||||
return sdr_config_handle_options(short_option, argi, argv);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* global variable to quit main loop */
|
||||
|
|
|
@ -22,10 +22,8 @@ extern const char *read_tx_wave;
|
|||
void main_mobile_init(void);
|
||||
void main_mobile_print_help(const char *arg0, const char *ext_usage);
|
||||
void main_mobile_print_hotkeys(void);
|
||||
extern struct option *long_options;
|
||||
extern char *optstring;
|
||||
void main_mobile_set_options(const char *optstring_special, struct option *long_options_special);
|
||||
void main_mobile_opt_switch(int c, char *arg0, int *skip_args);
|
||||
void main_mobile_add_options(void);
|
||||
int main_mobile_handle_options(int short_option, int argi, char **argv);
|
||||
|
||||
#define OPT_ARRAY(num_name, name, value) \
|
||||
{ \
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
||||
|
||||
noinst_LIBRARIES = liboptions.a
|
||||
|
||||
liboptions_a_SOURCES = \
|
||||
options.c
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
/* command line options and config file parsing
|
||||
*
|
||||
* (C) 2018 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "options.h"
|
||||
#include "../libdebug/debug.h"
|
||||
|
||||
typedef struct option {
|
||||
struct option *next;
|
||||
int short_option;
|
||||
const char *long_option;
|
||||
int parameter_count;
|
||||
} option_t;
|
||||
|
||||
static option_t *option_head = NULL;
|
||||
static option_t **option_tailp = &option_head;
|
||||
static int first_option = 1;
|
||||
|
||||
void option_add(int short_option, const char *long_option, int parameter_count)
|
||||
{
|
||||
option_t *option;
|
||||
|
||||
/* check if option already exists */
|
||||
for (option = option_head; option; option = option->next) {
|
||||
if (option->short_option == short_option
|
||||
|| !strcmp(option->long_option, long_option)) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Option '%s' added twice, please fix!\n", option->long_option);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
option = calloc(1, sizeof(*option));
|
||||
if (!option) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "No mem!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
option->short_option = short_option;
|
||||
option->long_option = long_option;
|
||||
option->parameter_count = parameter_count;
|
||||
*option_tailp = option;
|
||||
option_tailp = &(option->next);
|
||||
}
|
||||
|
||||
// FIXME: support more than one option */
|
||||
int options_config_file(const char *config_file, int (*handle_options)(int short_option, int argi, char *argv[]))
|
||||
{
|
||||
static const char *home;
|
||||
char config[256];
|
||||
FILE *fp;
|
||||
char buffer[256], opt[256], param[256], *p, *argv[1];
|
||||
int line;
|
||||
int rc = 1;
|
||||
int i;
|
||||
option_t *option;
|
||||
|
||||
/* open config file */
|
||||
home = getenv("HOME");
|
||||
if (home == NULL)
|
||||
return 1;
|
||||
sprintf(config, "%s/%s", home, config_file + 2);
|
||||
|
||||
fp = fopen(config, "r");
|
||||
if (!fp) {
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Config file '%s' seems not to exist, using command line options only.\n", config);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* parse config file */
|
||||
line = 0;
|
||||
while((fgets(buffer, sizeof(buffer), fp))) {
|
||||
line++;
|
||||
/* prevent buffer overflow */
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
/* cut away new-line and white spaces */
|
||||
while (buffer[0] && buffer[strlen(buffer) - 1] <= ' ')
|
||||
buffer[strlen(buffer) - 1] = '\0';
|
||||
p = buffer;
|
||||
/* remove white spaces in front of first keyword */
|
||||
while (*p > '\0' && *p <= ' ')
|
||||
p++;
|
||||
/* ignore '#' lines */
|
||||
if (*p == '#')
|
||||
continue;
|
||||
/* get option form line */
|
||||
i = 0;
|
||||
while (*p > ' ')
|
||||
opt[i++] = *p++;
|
||||
opt[i] = '\0';
|
||||
if (opt[0] == '\0')
|
||||
continue;
|
||||
/* skip white spaces behind option */
|
||||
while (*p > '\0' && *p <= ' ')
|
||||
p++;
|
||||
/* get param from line */
|
||||
i = 0;
|
||||
while (*p > ' ')
|
||||
param[i++] = *p++;
|
||||
param[i] = '\0';
|
||||
/* search option */
|
||||
for (option = option_head; option; option = option->next) {
|
||||
if (opt[0] == option->short_option && opt[1] == '\0') {
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Config file option '%s' ('%s'), parameter '%s'\n", opt, option->long_option, param);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(opt, option->long_option)) {
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Config file option '%s', parameter '%s'\n", opt, param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!option) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given option '%s' in config file '%s' at line %d is not a valid option, use '-h' for help!\n", opt, config_file, line);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (option->parameter_count && !param[0]) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given option '%s' in config file '%s' at line %d requires %d parameter(s), use '-h' for help!\n", opt, config_file, line, option->parameter_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
argv[0] = param;
|
||||
rc = handle_options(option->short_option, 0, argv);
|
||||
if (rc <= 0)
|
||||
goto done;
|
||||
first_option = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
/* close config file */
|
||||
fclose(fp);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int options_command_line(int argc, char *argv[], int (*handle_options)(int short_option, int argi, char *argv[]))
|
||||
{
|
||||
option_t *option;
|
||||
int argi, i;
|
||||
int rc;
|
||||
|
||||
for (argi = 1; argi < argc; argi++) {
|
||||
if (argv[argi][0] == '-') {
|
||||
if (argv[argi][1] != '-') {
|
||||
if (strlen(argv[argi]) != 2) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given command line option '%s' exceeds one character, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* -x */
|
||||
for (option = option_head; option; option = option->next) {
|
||||
if (argv[argi][1] == option->short_option) {
|
||||
if (option->parameter_count && argi + option->parameter_count < argc)
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Command line option '%s' ('--%s'), parameter '%s'\n", argv[argi], option->long_option, argv[argi + 1]);
|
||||
else
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Command line option '%s' ('--%s')\n", argv[argi], option->long_option);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* --xxxxxx */
|
||||
for (option = option_head; option; option = option->next) {
|
||||
if (!strcmp(argv[argi] + 2, option->long_option)) {
|
||||
if (option->parameter_count && argi + option->parameter_count < argc)
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Command line option '%s', parameter '%s'\n", argv[argi], argv[argi + 1]);
|
||||
else
|
||||
PDEBUG(DOPTIONS, DEBUG_INFO, "Command line option '%s'\n", argv[argi]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!option) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given command line option '%s' is not a valid option, use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (argi + option->parameter_count >= argc) {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given command line option '%s' requires %d parameter(s), use '-h' for help!\n", argv[argi], option->parameter_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = handle_options(option->short_option, argi + 1, argv);
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
first_option = 0;
|
||||
argi += option->parameter_count;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
/* no more options, so we check if there is an option after a non-option parameter */
|
||||
for (i = argi; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given command line option '%s' behind command line parameter '%s' not allowed! Please put all command line options before command line parameter(s).\n", argv[i], argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return argi;
|
||||
}
|
||||
|
||||
int option_is_first(void)
|
||||
{
|
||||
return first_option;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
void option_add(int short_option, const char *long_option, int parameter_count);
|
||||
int options_config_file(const char *config_file, int (*handle_options)(int short_option, int argi, char *argv[]));
|
||||
int options_command_line(int argc, char *argv[], int (*handle_options)(int short_option, int argi, char *argv[]));
|
||||
int option_is_first(void);
|
||||
|
|
@ -25,7 +25,6 @@ enum paging_signal;
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <getopt.h>
|
||||
#define __USE_GNU
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -23,8 +23,9 @@ enum paging_signal;
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "sdr.h"
|
||||
#include "sdr_config.h"
|
||||
|
||||
|
@ -122,43 +123,40 @@ void sdr_config_print_hotkeys(void)
|
|||
#define OPT_SDR_SWAP_LINKS 1517
|
||||
#define OPT_SDR_UHD_TX_TS 1518
|
||||
|
||||
struct option sdr_config_long_options[] = {
|
||||
{"sdr-uhd", 0, 0, OPT_SDR_UHD},
|
||||
{"sdr-soapy", 0, 0, OPT_SDR_SOAPY},
|
||||
{"sdr-channel", 1, 0, OPT_SDR_CHANNEL},
|
||||
{"sdr-device-args", 1, 0, OPT_SDR_DEVICE_ARGS},
|
||||
{"sdr-stream-args", 1, 0, OPT_SDR_STREAM_ARGS},
|
||||
{"sdr-tune-args", 1, 0, OPT_SDR_TUNE_ARGS},
|
||||
{"sdr-samplerate", 1, 0, OPT_SDR_SAMPLERATE},
|
||||
{"sdr-lo-offset", 1, 0, OPT_SDR_LO_OFFSET},
|
||||
{"sdr-bandwidth", 1, 0, OPT_SDR_BANDWIDTH},
|
||||
{"sdr-rx-antenna", 1, 0, OPT_SDR_RX_ANTENNA},
|
||||
{"sdr-tx-antenna", 1, 0, OPT_SDR_TX_ANTENNA},
|
||||
{"sdr-rx-gain", 1, 0, OPT_SDR_RX_GAIN},
|
||||
{"sdr-tx-gain", 1, 0, OPT_SDR_TX_GAIN},
|
||||
{"write-iq-rx-wave", 1, 0, OPT_WRITE_IQ_RX_WAVE},
|
||||
{"write-iq-tx-wave", 1, 0, OPT_WRITE_IQ_TX_WAVE},
|
||||
{"read-iq-rx-wave", 1, 0, OPT_READ_IQ_RX_WAVE},
|
||||
{"read-iq-tx-wave", 1, 0, OPT_READ_IQ_TX_WAVE},
|
||||
{"sdr-swap-links", 0, 0, OPT_SDR_SWAP_LINKS},
|
||||
{"sdr-uhd-tx-timestamps", 0, 0, OPT_SDR_UHD_TX_TS},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
const char *sdr_config_optstring = "";
|
||||
|
||||
int sdr_config_opt_switch(int c, int *skip_args)
|
||||
void sdr_config_add_options(void)
|
||||
{
|
||||
switch (c) {
|
||||
option_add(OPT_SDR_UHD, "sdr-uhd", 0);
|
||||
option_add(OPT_SDR_SOAPY, "sdr-soapy", 0);
|
||||
option_add(OPT_SDR_CHANNEL, "sdr-channel", 1);
|
||||
option_add(OPT_SDR_DEVICE_ARGS, "sdr-device-args", 1);
|
||||
option_add(OPT_SDR_STREAM_ARGS, "sdr-stream-args", 1);
|
||||
option_add(OPT_SDR_TUNE_ARGS, "sdr-tune-args", 1);
|
||||
option_add(OPT_SDR_SAMPLERATE, "sdr-samplerate", 1);
|
||||
option_add(OPT_SDR_LO_OFFSET, "sdr-lo-offset", 1);
|
||||
option_add(OPT_SDR_BANDWIDTH, "sdr-bandwidth", 1);
|
||||
option_add(OPT_SDR_RX_ANTENNA, "sdr-rx-antenna", 1);
|
||||
option_add(OPT_SDR_TX_ANTENNA, "sdr-tx-antenna", 1);
|
||||
option_add(OPT_SDR_RX_GAIN, "sdr-rx-gain", 1);
|
||||
option_add(OPT_SDR_TX_GAIN, "sdr-tx-gain", 1);
|
||||
option_add(OPT_WRITE_IQ_RX_WAVE, "write-iq-rx-wave", 1);
|
||||
option_add(OPT_WRITE_IQ_TX_WAVE, "write-iq-tx-wave", 1);
|
||||
option_add(OPT_READ_IQ_RX_WAVE, "read-iq-rx-wave", 1);
|
||||
option_add(OPT_READ_IQ_TX_WAVE, "read-iq-tx-wave", 1);
|
||||
option_add(OPT_SDR_SWAP_LINKS, "sdr-swap-links", 0);
|
||||
option_add(OPT_SDR_UHD_TX_TS, "sdr-uhd-tx-timestamps", 0);
|
||||
}
|
||||
|
||||
int sdr_config_handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
switch (short_option) {
|
||||
case OPT_SDR_UHD:
|
||||
#ifdef HAVE_UHD
|
||||
sdr_config->uhd = 1;
|
||||
use_sdr = 1;
|
||||
#else
|
||||
fprintf(stderr, "UHD SDR support not compiled in!\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
#endif
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case OPT_SDR_SOAPY:
|
||||
#ifdef HAVE_SOAPY
|
||||
|
@ -166,83 +164,65 @@ int sdr_config_opt_switch(int c, int *skip_args)
|
|||
use_sdr = 1;
|
||||
#else
|
||||
fprintf(stderr, "SoapySDR support not compiled in!\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
#endif
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case OPT_SDR_CHANNEL:
|
||||
sdr_config->channel = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->channel = atoi(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_DEVICE_ARGS:
|
||||
sdr_config->device_args = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->device_args = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_STREAM_ARGS:
|
||||
sdr_config->stream_args = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->stream_args = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_TUNE_ARGS:
|
||||
sdr_config->tune_args = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->tune_args = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_SAMPLERATE:
|
||||
sdr_config->samplerate = atoi(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->samplerate = atoi(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_LO_OFFSET:
|
||||
sdr_config->lo_offset = atof(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->lo_offset = atof(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_BANDWIDTH:
|
||||
sdr_config->bandwidth = atof(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->bandwidth = atof(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_RX_ANTENNA:
|
||||
sdr_config->rx_antenna = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->rx_antenna = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_TX_ANTENNA:
|
||||
sdr_config->tx_antenna = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->tx_antenna = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_RX_GAIN:
|
||||
sdr_config->rx_gain = atof(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->rx_gain = atof(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_TX_GAIN:
|
||||
sdr_config->tx_gain = atof(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->tx_gain = atof(argv[argi]);
|
||||
break;
|
||||
case OPT_WRITE_IQ_RX_WAVE:
|
||||
sdr_config->write_iq_rx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->write_iq_rx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_WRITE_IQ_TX_WAVE:
|
||||
sdr_config->write_iq_tx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->write_iq_tx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_READ_IQ_RX_WAVE:
|
||||
sdr_config->read_iq_rx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->read_iq_rx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_READ_IQ_TX_WAVE:
|
||||
sdr_config->read_iq_tx_wave = strdup(optarg);
|
||||
*skip_args += 2;
|
||||
sdr_config->read_iq_tx_wave = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_SDR_SWAP_LINKS:
|
||||
sdr_config->swap_links = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
case OPT_SDR_UHD_TX_TS:
|
||||
sdr_config->uhd_tx_timestamps = 1;
|
||||
*skip_args += 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sdr_configure(int samplerate)
|
||||
|
|
|
@ -26,8 +26,7 @@ extern sdr_config_t *sdr_config;
|
|||
void sdr_config_init(double lo_offset);
|
||||
void sdr_config_print_help(void);
|
||||
void sdr_config_print_hotkeys(void);
|
||||
extern struct option sdr_config_long_options[];
|
||||
extern const char *sdr_config_optstring;
|
||||
int sdr_config_opt_switch(int c, int *skip_args);
|
||||
void sdr_config_add_options(void);
|
||||
int sdr_config_handle_options(int short_option, int argi, char **argv);
|
||||
int sdr_configure(int samplerate);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ nmt_SOURCES = \
|
|||
nmt_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
libdmssms.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 \
|
||||
|
|
142
src/nmt/main.c
142
src/nmt/main.c
|
@ -19,16 +19,17 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../libmobile/main_mobile.h"
|
||||
#include "../libdebug/debug.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "nmt.h"
|
||||
#include "frame.h"
|
||||
#include "dsp.h"
|
||||
|
@ -97,92 +98,79 @@ 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('N', "nmt-system", 1);
|
||||
option_add('T', "channel-type", 1);
|
||||
option_add('P', "ms-power", 1);
|
||||
option_add('Y', "traffic-area", 1);
|
||||
option_add('A', "area-number", 1);
|
||||
option_add('C', "compandor", 1);
|
||||
option_add('0', "supervisory", 1);
|
||||
option_add('S', "smsc-number", 1);
|
||||
option_add('I', "caller-id", 1);
|
||||
}
|
||||
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
int rc;
|
||||
char *p;
|
||||
int super;
|
||||
int skip_args = 0;
|
||||
|
||||
static struct option long_options_special[] = {
|
||||
{"nmt-system", 1, 0, 'N'},
|
||||
{"channel-type", 1, 0, 'T'},
|
||||
{"ms-power", 1, 0, 'P'},
|
||||
{"traffic-area", 1, 0, 'Y'},
|
||||
{"area-number", 1, 0, 'A'},
|
||||
{"compandor", 1, 0, 'C'},
|
||||
{"supervisory", 1, 0, '0'},
|
||||
{"smsc-number", 1, 0, 'S'},
|
||||
{"caller-id", 1, 0, 'I'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
main_mobile_set_options("N:T:P:Y:A:C:0:S:I:", long_options_special);
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c, rc;
|
||||
static int first_option = 1;
|
||||
|
||||
c = getopt_long(argc, argv, optstring, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
switch (short_option) {
|
||||
case 'N':
|
||||
nmt_system = atoi(optarg);
|
||||
nmt_system = atoi(argv[argi]);
|
||||
if (nmt_system != 450 && nmt_system != 900) {
|
||||
fprintf(stderr, "Error, NMT system type '%s' unknown. Please use '-N 450' for NMT-450 or '-N 900' for NMT-900.\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Error, NMT system type '%s' unknown. Please use '-N 450' for NMT-450 or '-N 900' for NMT-900.\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (nmt_system == 900)
|
||||
ms_power = 0;
|
||||
if (!first_option) {
|
||||
if (!option_is_first()) {
|
||||
fprintf(stderr, "Please specify the NMT system (-N) as first command line option!\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'T':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
nmt_channel_list(nmt_system);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
rc = nmt_channel_by_short_name(nmt_system, optarg);
|
||||
rc = nmt_channel_by_short_name(nmt_system, 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", optarg);
|
||||
exit(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)
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'P':
|
||||
ms_power = atoi(optarg);
|
||||
ms_power = atoi(argv[argi]);
|
||||
if (ms_power > 3)
|
||||
ms_power = 3;
|
||||
if (ms_power < 0)
|
||||
ms_power = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'Y':
|
||||
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
nmt_country_list(nmt_system);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
/* digits */
|
||||
strncpy(country, optarg, sizeof(country) - 1);
|
||||
strncpy(country, argv[argi], sizeof(country) - 1);
|
||||
country[sizeof(country) - 1] = '\0';
|
||||
p = strchr(country, ',');
|
||||
if (!p) {
|
||||
fprintf(stderr, "Illegal traffic area '%s', see '-h' for help\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Illegal traffic area '%s', see '-h' for help\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
*p++ = '\0';
|
||||
rc = nmt_country_by_short_name(nmt_system, country);
|
||||
if (rc < 0) {
|
||||
error_ta:
|
||||
fprintf(stderr, "Invalid traffic area '%s', use '-Y list' for a list of valid areas\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Invalid traffic area '%s', use '-Y list' for a list of valid areas\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
traffic_area[0] = rc + '0';
|
||||
if (p[strlen(p) - 1] != '!') {
|
||||
|
@ -192,46 +180,36 @@ error_ta:
|
|||
}
|
||||
nmt_value2digits(atoi(p), traffic_area + 1, 1);
|
||||
traffic_area[2] = '\0';
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'A':
|
||||
area_no = optarg[0] - '0';
|
||||
area_no = argv[argi][0] - '0';
|
||||
if (area_no > 4) {
|
||||
fprintf(stderr, "Area number '%s' out of range, please use 1..4 or 0 for no area\n", optarg);
|
||||
exit(0);
|
||||
fprintf(stderr, "Area number '%s' out of range, please use 1..4 or 0 for no area\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'C':
|
||||
compandor = atoi(optarg);
|
||||
skip_args += 2;
|
||||
compandor = atoi(argv[argi]);
|
||||
break;
|
||||
case '0':
|
||||
super = atoi(optarg);
|
||||
super = atoi(argv[argi]);
|
||||
if (super < 0 || super > 4) {
|
||||
fprintf(stderr, "Given supervisory signal is wrong, use '-h' for help!\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
OPT_ARRAY(num_supervisory, supervisory, super)
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'S':
|
||||
smsc_number = strdup(optarg);
|
||||
skip_args += 2;
|
||||
smsc_number = strdup(argv[argi]);
|
||||
break;
|
||||
case 'I':
|
||||
send_callerid = atoi(optarg);
|
||||
skip_args += 2;
|
||||
send_callerid = atoi(argv[argi]);
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
first_option = 0;
|
||||
return main_mobile_handle_options(short_option, argi, argv);
|
||||
}
|
||||
|
||||
free(long_options);
|
||||
|
||||
return skip_args;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void myhandler(void)
|
||||
|
@ -280,8 +258,7 @@ int submit_sms(const char *sms)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int skip_args;
|
||||
int rc, argi;
|
||||
const char *station_id = "";
|
||||
int mandatory = 0;
|
||||
int i;
|
||||
|
@ -292,12 +269,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/nmt.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) != 7) {
|
||||
printf("Given station ID '%s' does not have 7 digits\n", station_id);
|
||||
return 0;
|
||||
|
@ -338,7 +320,7 @@ int main(int argc, char *argv[])
|
|||
num_audiodev = 1; /* use default */
|
||||
if (num_kanal != num_audiodev) {
|
||||
fprintf(stderr, "You need to specify as many sound devices as you have channels.\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (num_kanal == 1 && num_chan_type == 0) {
|
||||
num_chan_type = 1; /* use default */
|
||||
|
@ -347,14 +329,14 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
if (num_kanal != num_chan_type) {
|
||||
fprintf(stderr, "You need to specify as many channel types as you have channels.\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (num_kanal == 1 && num_supervisory == 0)
|
||||
num_supervisory = 1; /* use default */
|
||||
if (num_kanal != num_supervisory) {
|
||||
fprintf(stderr, "You need to specify as many supervisory signals as you have channels.\n");
|
||||
fprintf(stderr, "They shall be different at channels that are close to each other.\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (num_kanal) {
|
||||
uint8_t super[5] = { 0, 0, 0, 0, 0 };
|
||||
|
@ -378,7 +360,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (mandatory) {
|
||||
print_help(argv[-skip_args]);
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ radiocom2000_SOURCES = \
|
|||
main.c
|
||||
radiocom2000_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||
|
|
141
src/r2000/main.c
141
src/r2000/main.c
|
@ -19,16 +19,17 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../libmobile/main_mobile.h"
|
||||
#include "../libdebug/debug.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "r2000.h"
|
||||
#include "dsp.h"
|
||||
#include "frame.h"
|
||||
|
@ -102,77 +103,64 @@ void print_help(const char *arg0)
|
|||
#define OPT_TAXE 258
|
||||
#define OPT_DESTRUCTION 259
|
||||
|
||||
static int handle_options(int argc, char **argv)
|
||||
static void add_options(void)
|
||||
{
|
||||
int skip_args = 0;
|
||||
main_mobile_add_options();
|
||||
option_add('B', "band", 1);
|
||||
option_add(OPT_BANDE, "bande", 1);
|
||||
option_add('T', "channel-type", 1);
|
||||
option_add('R', "relais", 1);
|
||||
option_add(OPT_DEPORT, "deport", 1);
|
||||
option_add('I', "agi", 1);
|
||||
option_add('P', "sm-power", 1);
|
||||
option_add(OPT_TAXE, "taxe", 1);
|
||||
option_add('C', "crins", 1);
|
||||
option_add(OPT_DESTRUCTION, "destruction", 1);
|
||||
option_add('N', "nconv", 1);
|
||||
option_add('S', "recall", 1);
|
||||
}
|
||||
|
||||
static struct option long_options_special[] = {
|
||||
{"band", 1, 0, 'B'},
|
||||
{"bande", 1, 0, OPT_BANDE},
|
||||
{"channel-type", 1, 0, 'T'},
|
||||
{"relais", 1, 0, 'R'},
|
||||
{"deport", 1, 0, OPT_DEPORT},
|
||||
{"agi", 1, 0, 'I'},
|
||||
{"sm-power", 1, 0, 'P'},
|
||||
{"taxe", 1, 0, OPT_TAXE},
|
||||
{"crins", 1, 0, 'C'},
|
||||
{"destruction", 1, 0, OPT_DESTRUCTION},
|
||||
{"nconv", 1, 0, 'N'},
|
||||
{"recall", 1, 0, 'S'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
main_mobile_set_options("B:T:R:I:P:C:N:S", long_options_special);
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c, rc;
|
||||
|
||||
c = getopt_long(argc, argv, optstring, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
switch (short_option) {
|
||||
case 'B':
|
||||
case OPT_BANDE:
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
r2000_band_list();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
band = atoi(optarg);
|
||||
skip_args += 2;
|
||||
band = atoi(argv[argi]);
|
||||
break;
|
||||
case 'T':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
r2000_channel_list();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
rc = r2000_channel_by_short_name(optarg);
|
||||
rc = r2000_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", optarg);
|
||||
exit(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)
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'R':
|
||||
relais = atoi(optarg);
|
||||
relais = atoi(argv[argi]);
|
||||
if (relais > 511)
|
||||
relais = 511;
|
||||
if (relais < 1)
|
||||
relais = 1;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case OPT_DEPORT:
|
||||
deport = atoi(optarg);
|
||||
deport = atoi(argv[argi]);
|
||||
if (deport > 7)
|
||||
deport = 7;
|
||||
if (deport < 0)
|
||||
deport = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'I':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
int i;
|
||||
|
||||
printf("\nList of possible AGI (inscription permission) codes:\n\n");
|
||||
|
@ -180,34 +168,31 @@ static int handle_options(int argc, char **argv)
|
|||
printf("------------------------------------------------------------------------\n");
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("%d\t%s\n", i, param_agi(i));
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
agi = atoi(optarg);
|
||||
agi = atoi(argv[argi]);
|
||||
if (agi < 0 || agi > 7) {
|
||||
fprintf(stderr, "Error, given inscription permission (AGI) %d is invalid, use 'list' to get a list of values!\n", agi);
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'P':
|
||||
sm_power = atoi(optarg);
|
||||
sm_power = atoi(argv[argi]);
|
||||
if (sm_power > 1)
|
||||
sm_power = 1;
|
||||
if (sm_power < 0)
|
||||
sm_power = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case OPT_TAXE:
|
||||
taxe = atoi(optarg);
|
||||
taxe = atoi(argv[argi]);
|
||||
if (taxe > 1)
|
||||
taxe = 1;
|
||||
if (taxe < 0)
|
||||
taxe = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
#if 0
|
||||
case 'A':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
int i;
|
||||
|
||||
printf("\nList of possible AGA (call permission) codes:\n\n");
|
||||
|
@ -215,18 +200,17 @@ static int handle_options(int argc, char **argv)
|
|||
printf("------------------------------------------------------------------------\n");
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%d\t%s\n", i, param_aga(i));
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
aga = atoi(optarg);
|
||||
aga = atoi(argv[argi]);
|
||||
if (aga < 0 || aga > 3) {
|
||||
fprintf(stderr, "Error, given call permission (AGA) %d is invalid, use 'list' to get a list of values!\n", aga);
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
#endif
|
||||
case 'C':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
int i;
|
||||
|
||||
printf("\nList of possible CRINS (inscription response) codes:\n\n");
|
||||
|
@ -234,47 +218,39 @@ static int handle_options(int argc, char **argv)
|
|||
printf("------------------------------------------------------------------------\n");
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("%d\t%s\n", i, param_crins(i));
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
crins = atoi(optarg);
|
||||
crins = atoi(argv[argi]);
|
||||
if (crins < 0 || crins > 7) {
|
||||
fprintf(stderr, "Error, given inscription response (CRINS) %d is invalid, use 'list' to get a list of values!\n", crins);
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case OPT_DESTRUCTION:
|
||||
if (!strcmp(optarg, "YES")) {
|
||||
if (!strcmp(argv[argi], "YES")) {
|
||||
destruction = 2342;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'N':
|
||||
nconv = atoi(optarg);
|
||||
nconv = atoi(argv[argi]);
|
||||
if (nconv > 7)
|
||||
nconv = 7;
|
||||
if (nconv < 0)
|
||||
nconv = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'S':
|
||||
recall = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
default:
|
||||
main_mobile_opt_switch(c, argv[0], &skip_args);
|
||||
}
|
||||
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 mandatory = 0;
|
||||
int i;
|
||||
|
@ -284,12 +260,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/radiocom2000.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) != 9) {
|
||||
printf("Given station ID '%s' does not have 9 digits\n", station_id);
|
||||
return 0;
|
||||
|
@ -328,7 +309,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (mandatory) {
|
||||
print_help(argv[-skip_args]);
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ osmoradio_SOURCES = \
|
|||
main.c
|
||||
osmoradio_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libwave/libwave.a \
|
||||
$(top_builddir)/src/libsample/libsample.a \
|
||||
|
|
191
src/radio/main.c
191
src/radio/main.c
|
@ -1,4 +1,4 @@
|
|||
/* main function
|
||||
/* Radio main function
|
||||
*
|
||||
* (C) 2018 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
|
@ -24,8 +24,8 @@ enum paging_signal;
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
@ -34,6 +34,7 @@ enum paging_signal;
|
|||
#include "../libsdr/sdr_config.h"
|
||||
#include "../libsdr/sdr.h"
|
||||
#include "../libdisplay/display.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "radio.h"
|
||||
|
||||
#define DEFAULT_LO_OFFSET -1000000.0
|
||||
|
@ -137,170 +138,121 @@ void print_help(const char *arg0)
|
|||
printf(" -S --stereo\n");
|
||||
printf(" Enables stereo carrier for frequency modulated UHF broadcast.\n");
|
||||
printf(" It uses the 'Pilot-tone' system.\n");
|
||||
printf(" --limesdr\n");
|
||||
printf(" Auto-select several required options for LimeSDR\n");
|
||||
sdr_config_print_help();
|
||||
}
|
||||
|
||||
static struct option long_options_common[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"frequency", 1, 0, 'f'},
|
||||
{"samplerate", 1, 0, 's'},
|
||||
{"tx-wave-file", 1, 0, 'r'},
|
||||
{"rx-wave-file", 1, 0, 'w'},
|
||||
{"audio-device", 1, 0, 'a'},
|
||||
{"modulation", 1, 0, 'M'},
|
||||
{"rx", 0, 0, 'R'},
|
||||
{"tx", 0, 0, 'T'},
|
||||
{"bandwidth", 1, 0, 'B'},
|
||||
{"deviation", 1, 0, 'D'},
|
||||
{"modulation-index", 1, 0, 'I'},
|
||||
{"emphasis", 1, 0, 'E'},
|
||||
{"stereo", 0, 0, 'S'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
#define OPT_LIMESDR 1100
|
||||
|
||||
static const char *optstring_common = "hf:s:r:w:a:M:RTB:D:I:E:S";
|
||||
|
||||
struct option *long_options;
|
||||
char *optstring;
|
||||
|
||||
static void check_duplicate_option(int num, struct option *option)
|
||||
static void add_options(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (long_options[i].val == option->val) {
|
||||
fprintf(stderr, "Duplicate option %d. Please fix!\n", option->val);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
option_add('h', "help", 0);
|
||||
option_add('f', "frequency", 1);
|
||||
option_add('s', "samplerate", 1);
|
||||
option_add('r', "tx-wave-file", 1);
|
||||
option_add('w', "rx-wave-file", 1);
|
||||
option_add('a', "audio-device", 1);
|
||||
option_add('M', "modulation", 1);
|
||||
option_add('R', "rx", 0);
|
||||
option_add('T', "tx", 0);
|
||||
option_add('B', "bandwidth", 1);
|
||||
option_add('D', "deviation", 1);
|
||||
option_add('I', "modulation-index", 1);
|
||||
option_add('E', "emphasis", 1);
|
||||
option_add('S', "stereo", 0);
|
||||
option_add(OPT_LIMESDR, "limesdr", 0);
|
||||
sdr_config_add_options();
|
||||
}
|
||||
|
||||
void set_options_common(void)
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
int i = 0, j;
|
||||
|
||||
long_options = calloc(sizeof(*long_options), 256);
|
||||
for (j = 0; long_options_common[i].name; i++, j++) {
|
||||
check_duplicate_option(i, &long_options_common[j]);
|
||||
memcpy(&long_options[i], &long_options_common[j], sizeof(*long_options));
|
||||
}
|
||||
for (j = 0; sdr_config_long_options[j].name; i++, j++) {
|
||||
check_duplicate_option(i, &sdr_config_long_options[j]);
|
||||
memcpy(&long_options[i], &sdr_config_long_options[j], sizeof(*long_options));
|
||||
}
|
||||
|
||||
optstring = calloc(256, 2);
|
||||
strcpy(optstring, optstring_common);
|
||||
strcat(optstring, sdr_config_optstring);
|
||||
}
|
||||
|
||||
static int handle_options(int argc, char **argv)
|
||||
{
|
||||
int skip_args = 0;
|
||||
int rc;
|
||||
|
||||
set_options_common();
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
|
||||
c = getopt_long(argc, argv, optstring, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_help(argv[0]);
|
||||
exit(0);
|
||||
return 0;
|
||||
case 'f':
|
||||
frequency = atof(optarg);
|
||||
skip_args += 2;
|
||||
frequency = atof(argv[argi]);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atof(optarg);
|
||||
skip_args += 2;
|
||||
samplerate = atof(argv[argi]);
|
||||
break;
|
||||
case 'r':
|
||||
tx_wave_file = strdup(optarg);
|
||||
skip_args += 2;
|
||||
tx_wave_file = strdup(argv[argi]);
|
||||
break;
|
||||
case 'w':
|
||||
rx_wave_file = strdup(optarg);
|
||||
skip_args += 2;
|
||||
rx_wave_file = strdup(argv[argi]);
|
||||
break;
|
||||
case 'a':
|
||||
tx_audiodev = strdup(optarg);
|
||||
rx_audiodev = strdup(optarg);
|
||||
skip_args += 2;
|
||||
tx_audiodev = strdup(argv[argi]);
|
||||
rx_audiodev = strdup(argv[argi]);
|
||||
break;
|
||||
case 'M':
|
||||
if (!strcasecmp(optarg, "fm"))
|
||||
if (!strcasecmp(argv[argi], "fm"))
|
||||
modulation = MODULATION_FM;
|
||||
else
|
||||
if (!strcasecmp(optarg, "am"))
|
||||
if (!strcasecmp(argv[argi], "am"))
|
||||
modulation = MODULATION_AM_DSB;
|
||||
else
|
||||
if (!strcasecmp(optarg, "usb"))
|
||||
if (!strcasecmp(argv[argi], "usb"))
|
||||
modulation = MODULATION_AM_USB;
|
||||
else
|
||||
if (!strcasecmp(optarg, "lsb"))
|
||||
if (!strcasecmp(argv[argi], "lsb"))
|
||||
modulation = MODULATION_AM_LSB;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Invalid modulation option, see help!\n");
|
||||
exit(0);
|
||||
fprintf(stderr, "Invalid modulation option, use '-h' for help!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'R':
|
||||
rx = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
case 'T':
|
||||
tx = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
case 'B':
|
||||
bandwidth = atof(optarg);
|
||||
skip_args += 2;
|
||||
bandwidth = atof(argv[argi]);
|
||||
break;
|
||||
case 'D':
|
||||
deviation = atof(optarg);
|
||||
skip_args += 2;
|
||||
deviation = atof(argv[argi]);
|
||||
break;
|
||||
case 'I':
|
||||
modulation_index = atof(optarg);
|
||||
modulation_index = atof(argv[argi]);
|
||||
if (modulation_index < 0.0 || modulation_index > 1.0) {
|
||||
fprintf(stderr, "Invalid modulation index, see help!\n");
|
||||
exit(0);
|
||||
fprintf(stderr, "Invalid modulation index, use '-h' for help!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'E':
|
||||
time_constant_us = atof(optarg);
|
||||
skip_args += 2;
|
||||
time_constant_us = atof(argv[argi]);
|
||||
break;
|
||||
case 'S':
|
||||
stereo = 1;
|
||||
skip_args += 1;
|
||||
break;
|
||||
default:
|
||||
rc = sdr_config_opt_switch(c, &skip_args);
|
||||
if (rc < 0)
|
||||
exit(0);
|
||||
break;
|
||||
case OPT_LIMESDR:
|
||||
{
|
||||
char *argv_lime[] = { argv[0],
|
||||
"--sdr-soapy",
|
||||
"--sdr-rx-antenna", "LNAL",
|
||||
"--sdr-rx-gain", "50",
|
||||
"--sdr-tx-gain", "50",
|
||||
"--sdr-samplerate", "5000000",
|
||||
"--sdr-bandwidth", "15000000",
|
||||
};
|
||||
int argc_lime = sizeof(argv_lime) / sizeof (*argv_lime);
|
||||
return options_command_line(argc_lime, argv_lime, handle_options);
|
||||
}
|
||||
default:
|
||||
return sdr_config_handle_options(short_option, argi, argv);
|
||||
}
|
||||
|
||||
return skip_args;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int skip_args;
|
||||
int rc;
|
||||
const char *arg0 = argv[0];
|
||||
int rc, argi;
|
||||
radio_t radio;
|
||||
struct termios term, term_orig;
|
||||
int c;
|
||||
|
@ -310,13 +262,18 @@ int main(int argc, char *argv[])
|
|||
|
||||
sdr_config_init(DEFAULT_LO_OFFSET);
|
||||
|
||||
skip_args = handle_options(argc, argv);
|
||||
argc -= skip_args + 1;
|
||||
argv += skip_args + 1;
|
||||
/* handle options / config file */
|
||||
add_options();
|
||||
rc = options_config_file("~/.osmocom/analog/radio.conf", handle_options);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
|
||||
if (frequency == 0.0) {
|
||||
printf("No frequency given, I suggest to use 100000000 (100 MHz) and FM\n\n");
|
||||
print_help(arg0);
|
||||
print_help(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -324,12 +281,12 @@ int main(int argc, char *argv[])
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "Please select SDR, see help!\n");
|
||||
fprintf(stderr, "Please select SDR, use '-h' for help!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (modulation == MODULATION_NONE) {
|
||||
fprintf(stderr, "Please select modulation, see help!\n");
|
||||
fprintf(stderr, "Please select modulation, use '-h' for help!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -341,18 +298,18 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (stereo && modulation != MODULATION_FM) {
|
||||
fprintf(stderr, "Stereo works with FM only, see help!\n");
|
||||
fprintf(stderr, "Stereo works with FM only, use '-h' for help!\n");
|
||||
exit(0);
|
||||
}
|
||||
if (!rx && !tx) {
|
||||
fprintf(stderr, "You need to specify --rx (receiver) and/or --tx (transmitter), see help!\n");
|
||||
fprintf(stderr, "You need to specify --rx (receiver) and/or --tx (transmitter), use '-h' for help!\n");
|
||||
exit(0);
|
||||
}
|
||||
if (stereo && bandwidth != 15000.0) {
|
||||
fprintf(stderr, "Warning: Stereo works with bandwidth of 15 KHz only, using this bandwidth!\n");
|
||||
}
|
||||
if (stereo && time_constant_us != 75.0 && time_constant_us != 50.0) {
|
||||
fprintf(stderr, "Stereo works with time constant of 50 uS or 75 uS only, see help!\n");
|
||||
fprintf(stderr, "Stereo works with time constant of 50 uS or 75 uS only, use '-h' for help!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ tacs_SOURCES = \
|
|||
tacs_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
../amps/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 \
|
||||
|
|
|
@ -57,6 +57,7 @@ test_dms_LDADD = \
|
|||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||
$(top_builddir)/src/nmt/libdmssms.a \
|
||||
$(top_builddir)/src/libjitter/libjitter.a \
|
||||
|
@ -90,6 +91,7 @@ test_sms_LDADD = \
|
|||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||
$(top_builddir)/src/nmt/libdmssms.a \
|
||||
$(top_builddir)/src/libjitter/libjitter.a \
|
||||
|
|
|
@ -43,7 +43,7 @@ void dms_receive(nmt_t *nmt, const uint8_t *data, int length, int eight_bits)
|
|||
{
|
||||
printf("(getting %d digits from DMS layer)\n", length);
|
||||
|
||||
assert(!memcmp((const char *)data, check_sequence, length), "Expecting received data to macht");
|
||||
assert(!memcmp((const char *)data, check_sequence, length), "Expecting received data to match");
|
||||
|
||||
check_sequence += length;
|
||||
check_length = length;
|
||||
|
|
|
@ -14,6 +14,7 @@ osmotv_SOURCES = \
|
|||
main.c
|
||||
osmotv_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libimage/libimage.a \
|
||||
$(top_builddir)/src/libfm/libfm.a \
|
||||
|
|
193
src/tv/main.c
193
src/tv/main.c
|
@ -1,4 +1,4 @@
|
|||
/* main function
|
||||
/* JollyTV main function
|
||||
*
|
||||
* (C) 2017 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
|
@ -24,8 +24,8 @@ enum paging_signal;
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../libfilter/iir_filter.h"
|
||||
|
@ -37,6 +37,7 @@ enum paging_signal;
|
|||
#include "../libsdr/sdr_config.h"
|
||||
#include "../libsdr/sdr.h"
|
||||
#endif
|
||||
#include "../liboptions/options.h"
|
||||
#include "bas.h"
|
||||
#include "tv_modulate.h"
|
||||
#include "channels.h"
|
||||
|
@ -114,149 +115,104 @@ void print_help(const char *arg0)
|
|||
printf(" Give exactly 12 characters to display as Station ID.\n");
|
||||
printf(" (default = \"%s\")\n", station_id);
|
||||
#ifdef HAVE_SDR
|
||||
printf(" --limesdr\n");
|
||||
printf(" Auto-select several required options for LimeSDR\n");
|
||||
sdr_config_print_help();
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct option long_options_common[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"frequency", 1, 0, 'f'},
|
||||
{"channel", 1, 0, 'c'},
|
||||
{"samplerate", 1, 0, 'r'},
|
||||
{"wave-file", 1, 0, 'w'},
|
||||
{"fbas", 1, 0, 'F'},
|
||||
{"tone", 1, 0, 'T'},
|
||||
{"circle-radius", 1, 0, 'R'},
|
||||
{"color-bar", 1, 0, 'C'},
|
||||
{"grid-only", 1, 0, 'G'},
|
||||
{"station-id", 1, 0, 'I'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
#define OPT_LIMESDR 1100
|
||||
|
||||
static const char *optstring_common = "hf:c:r:w:F:T:R:C:G:I:";
|
||||
|
||||
struct option *long_options;
|
||||
char *optstring;
|
||||
|
||||
static void check_duplicate_option(int num, struct option *option)
|
||||
static void add_options(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (long_options[i].val == option->val) {
|
||||
fprintf(stderr, "Duplicate option %d. Please fix!\n", option->val);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_options_common(void)
|
||||
{
|
||||
int i = 0, j;
|
||||
|
||||
long_options = calloc(sizeof(*long_options), 256);
|
||||
for (j = 0; long_options_common[i].name; i++, j++) {
|
||||
check_duplicate_option(i, &long_options_common[j]);
|
||||
memcpy(&long_options[i], &long_options_common[j], sizeof(*long_options));
|
||||
}
|
||||
option_add('h', "help", 0);
|
||||
option_add('f', "frequency", 1);
|
||||
option_add('c', "channel", 1);
|
||||
option_add('r', "samplerate", 1);
|
||||
option_add('w', "wave-file", 1);
|
||||
option_add('F', "fbas", 1);
|
||||
option_add('T', "tone", 1);
|
||||
option_add('R', "circle-radius", 1);
|
||||
option_add('C', "color-bar", 1);
|
||||
option_add('G', "grid-only", 1);
|
||||
option_add('I', "station-id", 1);
|
||||
#ifdef HAVE_SDR
|
||||
for (j = 0; sdr_config_long_options[j].name; i++, j++) {
|
||||
check_duplicate_option(i, &sdr_config_long_options[j]);
|
||||
memcpy(&long_options[i], &sdr_config_long_options[j], sizeof(*long_options));
|
||||
}
|
||||
#endif
|
||||
|
||||
optstring = calloc(256, 2);
|
||||
strcpy(optstring, optstring_common);
|
||||
#ifdef HAVE_SDR
|
||||
strcat(optstring, sdr_config_optstring);
|
||||
option_add(OPT_LIMESDR, "limesdr", 0);
|
||||
sdr_config_add_options();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int handle_options(int argc, char **argv)
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
int skip_args = 0;
|
||||
#ifdef HAVE_SDR
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
set_options_common();
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
|
||||
c = getopt_long(argc, argv, optstring, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_help(argv[0]);
|
||||
exit(0);
|
||||
return 0;
|
||||
case 'f':
|
||||
frequency = atof(optarg);
|
||||
skip_args += 2;
|
||||
frequency = atof(argv[argi]);
|
||||
break;
|
||||
case 'c':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
if (!strcmp(argv[argi], "list")) {
|
||||
list_tv_channels();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
frequency = get_tv_video_frequency(atoi(optarg));
|
||||
frequency = get_tv_video_frequency(atoi(argv[argi]));
|
||||
if (frequency == 0.0) {
|
||||
fprintf(stderr, "Given channel number unknown, use \"-c list\" to get a list.\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'r':
|
||||
samplerate = atof(optarg);
|
||||
skip_args += 2;
|
||||
samplerate = atof(argv[argi]);
|
||||
break;
|
||||
case 'w':
|
||||
wave_file = strdup(optarg);
|
||||
skip_args += 2;
|
||||
wave_file = strdup(argv[argi]);
|
||||
break;
|
||||
case 'F':
|
||||
fbas = atoi(optarg);
|
||||
skip_args += 2;
|
||||
fbas = atoi(argv[argi]);
|
||||
break;
|
||||
case 'T':
|
||||
tone = atoi(optarg);
|
||||
skip_args += 2;
|
||||
tone = atoi(argv[argi]);
|
||||
break;
|
||||
case 'R':
|
||||
circle_radius = atof(optarg);
|
||||
skip_args += 2;
|
||||
circle_radius = atof(argv[argi]);
|
||||
break;
|
||||
case 'C':
|
||||
color_bar = atoi(optarg);
|
||||
skip_args += 2;
|
||||
color_bar = atoi(argv[argi]);
|
||||
break;
|
||||
case 'G':
|
||||
grid_only = atoi(optarg);
|
||||
skip_args += 2;
|
||||
grid_only = atoi(argv[argi]);
|
||||
break;
|
||||
case 'I':
|
||||
station_id = strdup(optarg);
|
||||
station_id = strdup(argv[argi]);
|
||||
if (strlen(station_id) != 12) {
|
||||
fprintf(stderr, "Given station ID must be exactly 12 charaters long. (Use spaces to fill it.)\n");
|
||||
exit(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
#ifdef HAVE_SDR
|
||||
case OPT_LIMESDR:
|
||||
{
|
||||
char *argv_lime[] = { argv[0],
|
||||
"--sdr-soapy",
|
||||
"--sdr-tx-gain", "50",
|
||||
"--sdr-lo-offset", "-3000000",
|
||||
"--sdr-bandwidth", "60000000",
|
||||
"-r", "13750000",
|
||||
};
|
||||
int argc_lime = sizeof(argv_lime) / sizeof (*argv_lime);
|
||||
return options_command_line(argc_lime, argv_lime, handle_options);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
#ifdef HAVE_SDR
|
||||
rc = sdr_config_opt_switch(c, &skip_args);
|
||||
if (rc < 0)
|
||||
exit(0);
|
||||
return sdr_config_handle_options(short_option, argi, argv);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return skip_args;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void tx_bas(sample_t *sample_bas, __attribute__((__unused__)) sample_t *sample_tone, __attribute__((__unused__)) uint8_t *power_tone, int samples)
|
||||
|
@ -448,9 +404,7 @@ error:
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int skip_args;
|
||||
int __attribute__((__unused__)) rc;
|
||||
const char *arg0 = argv[0];
|
||||
int __attribute__((__unused__)) rc, argi;
|
||||
|
||||
debuglevel = 0;
|
||||
|
||||
|
@ -458,12 +412,17 @@ int main(int argc, char *argv[])
|
|||
sdr_config_init(DEFAULT_LO_OFFSET);
|
||||
#endif
|
||||
|
||||
skip_args = handle_options(argc, argv);
|
||||
argc -= skip_args + 1;
|
||||
argv += skip_args + 1;
|
||||
/* handle options / config file */
|
||||
add_options();
|
||||
rc = options_config_file("~/.osmocom/analog/osmotv.conf", handle_options);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
|
||||
if (frequency == 0.0 && !wave_file) {
|
||||
print_help(arg0);
|
||||
print_help(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -475,22 +434,22 @@ int main(int argc, char *argv[])
|
|||
#endif
|
||||
}
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "Expecting command, see help!\n");
|
||||
if (argi >= argc) {
|
||||
fprintf(stderr, "Expecting command, use '-h' for help!\n");
|
||||
exit(0);
|
||||
} else if (!strcmp(argv[0], "tx-fubk")) {
|
||||
} else if (!strcmp(argv[argi], "tx-fubk")) {
|
||||
tx_test_picture(BAS_FUBK);
|
||||
} else if (!strcmp(argv[0], "tx-vcr")) {
|
||||
} else if (!strcmp(argv[argi], "tx-vcr")) {
|
||||
tx_test_picture(BAS_VCR);
|
||||
} else if (!strcmp(argv[0], "tx-img")) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Expecting image file, see help!\n");
|
||||
exit(0);
|
||||
} else if (!strcmp(argv[argi], "tx-img")) {
|
||||
if (argi + 1 >= argc) {
|
||||
fprintf(stderr, "Expecting image file, use '-h' for help!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tx_img(argv[1]);
|
||||
tx_img(argv[argi + 1]);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown command '%s', see help!\n", argv[0]);
|
||||
exit(0);
|
||||
fprintf(stderr, "Unknown command '%s', use '-h' for help!\n", argv[argi]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue