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:
Andreas Eversberg 2018-05-19 10:56:43 +02:00
parent e74b7442c6
commit 5df7f92647
10 changed files with 390 additions and 224 deletions

View File

@ -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" },

View File

@ -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);

View File

@ -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 */

View File

@ -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) \
{ \

7
liboptions/Makefile.am Normal file
View File

@ -0,0 +1,7 @@
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
noinst_LIBRARIES = liboptions.a
liboptions_a_SOURCES = \
options.c

221
liboptions/options.c Normal file
View File

@ -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;
}

6
liboptions/options.h Normal file
View File

@ -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);

View File

@ -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>

View File

@ -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)

View File

@ -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);