mirror of
https://github.com/merbanan/rtl_433.git
synced 2026-04-22 18:46:58 -04:00
Allow multiple input files, positional args are input files
This commit is contained in:
committed by
Christian W. Zuckschwerdt
parent
dfc1d79479
commit
4c80e60c97
@@ -55,9 +55,11 @@ Usage: = General options =
|
||||
[-r <filename>] Read data from input file instead of a receiver
|
||||
[-w <filename>] Save data stream to output file (a '-' dumps samples to stdout)
|
||||
[-W <filename>] Save data stream to output file, overwrite existing file
|
||||
= Data output options =
|
||||
[-F] kv|json|csv|syslog|null Produce decoded output in given format. Not yet supported by all drivers.
|
||||
Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout.
|
||||
Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514
|
||||
[-K] FILE|PATH|<tag> Add an expanded token or fixed tag to every output line.
|
||||
[-C] native|si|customary Convert units in decoded output.
|
||||
[-T] Specify number of seconds to run
|
||||
[-U] Print timestamps in UTC (this may also be accomplished by invocation with TZ environment variable set).
|
||||
|
||||
@@ -302,6 +302,9 @@ data_t *data_prepend(data_t *first, const char *key, const char *pretty_key, ...
|
||||
data_t *result = vdata_make(NULL, key, pretty_key, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!result)
|
||||
return first;
|
||||
|
||||
data_t *prev = result;
|
||||
while (prev && prev->next)
|
||||
prev = prev->next;
|
||||
|
||||
140
src/rtl_433.c
140
src/rtl_433.c
@@ -38,6 +38,7 @@
|
||||
|
||||
#define MAX_DATA_OUTPUTS 32
|
||||
#define MAX_DUMP_OUTPUTS 8
|
||||
#define MAX_IN_FILES 100
|
||||
|
||||
#ifdef GIT_VERSION
|
||||
#define STR_VALUE(arg) #arg
|
||||
@@ -61,6 +62,8 @@ struct app_cfg {
|
||||
int ppm_error;
|
||||
uint32_t out_block_size;
|
||||
char const *test_data;
|
||||
unsigned in_files;
|
||||
char const *in_file[MAX_IN_FILES];
|
||||
char const *in_filename;
|
||||
int do_exit;
|
||||
int do_exit_async;
|
||||
@@ -175,9 +178,11 @@ static void usage(r_device *devices, unsigned num_devices, int exit_code)
|
||||
"\t[-r <filename>] Read data from input file instead of a receiver\n"
|
||||
"\t[-w <filename>] Save data stream to output file (a '-' dumps samples to stdout)\n"
|
||||
"\t[-W <filename>] Save data stream to output file, overwrite existing file\n"
|
||||
"\t= Data output options =\n"
|
||||
"\t[-F] kv|json|csv|syslog|null Produce decoded output in given format. Not yet supported by all drivers.\n"
|
||||
"\t\t Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout.\n"
|
||||
"\t\t Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514\n"
|
||||
"\t[-K] FILE|PATH|<tag> Add an expanded token or fixed tag to every output line.\n"
|
||||
"\t[-C] native|si|customary Convert units in decoded output.\n"
|
||||
"\t[-T] Specify number of seconds to run\n"
|
||||
"\t[-U] Print timestamps in UTC (this may also be accomplished by invocation with TZ environment variable set).\n"
|
||||
@@ -940,6 +945,15 @@ static void add_dumper(char const *spec, file_info_t *dumper, int overwrite)
|
||||
}
|
||||
}
|
||||
|
||||
static void add_infile(char const *in_file)
|
||||
{
|
||||
if (cfg.in_files >= MAX_IN_FILES) {
|
||||
fprintf(stderr, "Max input files reached, ignoring \"%s\"!\n", in_file);
|
||||
return;
|
||||
}
|
||||
cfg.in_file[cfg.in_files++] = in_file;
|
||||
}
|
||||
|
||||
/// string to bool with default
|
||||
int atobv(char *arg, int def)
|
||||
{
|
||||
@@ -1146,7 +1160,7 @@ static void parse_conf_option(struct app_cfg *cfg, int opt, char *arg)
|
||||
if (!arg)
|
||||
help_read();
|
||||
|
||||
cfg->in_filename = arg;
|
||||
add_infile(arg);
|
||||
// TODO: check_read_file_info()
|
||||
break;
|
||||
case 'w':
|
||||
@@ -1350,6 +1364,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
parse_conf_args(&cfg, argc, argv);
|
||||
|
||||
// add all remaining positional arguments as input files
|
||||
while (argc > optind) {
|
||||
add_infile(argv[optind++]);
|
||||
}
|
||||
|
||||
if (demod->am_analyze) {
|
||||
demod->am_analyze->level_limit = &demod->level_limit;
|
||||
demod->am_analyze->frequency = &cfg.center_frequency;
|
||||
@@ -1357,12 +1376,6 @@ int main(int argc, char **argv) {
|
||||
demod->am_analyze->sample_size = &demod->sample_size;
|
||||
}
|
||||
|
||||
if (argc <= optind - 1) {
|
||||
usage(NULL, 0, 1);
|
||||
} else {
|
||||
out_filename = argv[optind]; // deprecated
|
||||
}
|
||||
|
||||
if (cfg.last_output_handler < 1) {
|
||||
add_kv_output(NULL);
|
||||
}
|
||||
@@ -1409,7 +1422,7 @@ int main(int argc, char **argv) {
|
||||
exit(!r);
|
||||
}
|
||||
|
||||
if (!cfg.in_filename) {
|
||||
if (!cfg.in_files) {
|
||||
r = sdr_open(&cfg.dev, &demod->sample_size, cfg.dev_query, !cfg.quiet_mode);
|
||||
if (r < 0) {
|
||||
exit(1);
|
||||
@@ -1442,8 +1455,7 @@ int main(int argc, char **argv) {
|
||||
add_dumper(out_filename, demod->dumper, 0); // deprecated
|
||||
}
|
||||
|
||||
if (cfg.in_filename) {
|
||||
parse_file_info(cfg.in_filename, &demod->load_info);
|
||||
if (cfg.in_files) {
|
||||
unsigned char *test_mode_buf = malloc(DEFAULT_BUF_LENGTH * sizeof(unsigned char));
|
||||
float *test_mode_float_buf = malloc(DEFAULT_BUF_LENGTH / sizeof(int16_t) * sizeof(float));
|
||||
if (!test_mode_buf || !test_mode_float_buf)
|
||||
@@ -1451,62 +1463,70 @@ int main(int argc, char **argv) {
|
||||
fprintf(stderr, "Couldn't allocate read buffers!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (strcmp(demod->load_info.path, "-") == 0) { /* read samples from stdin */
|
||||
in_file = stdin;
|
||||
cfg.in_filename = "<stdin>";
|
||||
} else {
|
||||
in_file = fopen(demod->load_info.path, "rb");
|
||||
if (!in_file) {
|
||||
fprintf(stderr, "Opening file: %s failed!\n", cfg.in_filename);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Test mode active. Reading samples from file: %s\n", cfg.in_filename); // Essential information (not quiet)
|
||||
if (demod->load_info.format == CU8_IQ
|
||||
|| demod->load_info.format == S16_AM
|
||||
|| demod->load_info.format == S16_FM) {
|
||||
demod->sample_size = sizeof(uint8_t); // CU8, AM, FM
|
||||
} else {
|
||||
demod->sample_size = sizeof(int16_t); // CF32, CS16
|
||||
}
|
||||
if (!cfg.quiet_mode) {
|
||||
fprintf(stderr, "Input format: %s\n", file_info_string(&demod->load_info));
|
||||
}
|
||||
sample_file_pos = 0.0;
|
||||
|
||||
int n_blocks = 0;
|
||||
unsigned long n_read;
|
||||
do {
|
||||
if (demod->load_info.format == CF32_IQ) {
|
||||
n_read = fread(test_mode_float_buf, sizeof(float), DEFAULT_BUF_LENGTH / 2, in_file);
|
||||
// clamp float to [-1,1] and scale to Q0.15
|
||||
for(unsigned long n = 0; n < n_read; n++) {
|
||||
int s_tmp = test_mode_float_buf[n] * INT16_MAX;
|
||||
if (s_tmp < -INT16_MAX)
|
||||
s_tmp = -INT16_MAX;
|
||||
else if (s_tmp > INT16_MAX)
|
||||
s_tmp = INT16_MAX;
|
||||
test_mode_buf[n] = (int16_t)s_tmp;
|
||||
}
|
||||
for (i = 0; i < cfg.in_files; ++i) {
|
||||
cfg.in_filename = cfg.in_file[i];
|
||||
|
||||
parse_file_info(cfg.in_filename, &demod->load_info);
|
||||
if (strcmp(demod->load_info.path, "-") == 0) { /* read samples from stdin */
|
||||
in_file = stdin;
|
||||
cfg.in_filename = "<stdin>";
|
||||
} else {
|
||||
n_read = fread(test_mode_buf, 1, DEFAULT_BUF_LENGTH, in_file);
|
||||
in_file = fopen(demod->load_info.path, "rb");
|
||||
if (!in_file) {
|
||||
fprintf(stderr, "Opening file: %s failed!\n", cfg.in_filename);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (n_read == 0) break; // sdr_callback() will Segmentation Fault with len=0
|
||||
sdr_callback(test_mode_buf, n_read, demod);
|
||||
n_blocks++;
|
||||
sample_file_pos = (float)n_blocks * n_read / cfg.samp_rate / 2 / demod->sample_size;
|
||||
} while (n_read != 0);
|
||||
fprintf(stderr, "Test mode active. Reading samples from file: %s\n", cfg.in_filename); // Essential information (not quiet)
|
||||
if (demod->load_info.format == CU8_IQ
|
||||
|| demod->load_info.format == S16_AM
|
||||
|| demod->load_info.format == S16_FM) {
|
||||
demod->sample_size = sizeof(uint8_t); // CU8, AM, FM
|
||||
} else {
|
||||
demod->sample_size = sizeof(int16_t); // CF32, CS16
|
||||
}
|
||||
if (!cfg.quiet_mode) {
|
||||
fprintf(stderr, "Input format: %s\n", file_info_string(&demod->load_info));
|
||||
}
|
||||
sample_file_pos = 0.0;
|
||||
|
||||
// Call a last time with cleared samples to ensure EOP detection
|
||||
memset(test_mode_buf, 128, DEFAULT_BUF_LENGTH); // 128 is 0 in unsigned data
|
||||
sdr_callback(test_mode_buf, DEFAULT_BUF_LENGTH, demod);
|
||||
int n_blocks = 0;
|
||||
unsigned long n_read;
|
||||
do {
|
||||
if (demod->load_info.format == CF32_IQ) {
|
||||
n_read = fread(test_mode_float_buf, sizeof(float), DEFAULT_BUF_LENGTH / 2, in_file);
|
||||
// clamp float to [-1,1] and scale to Q0.15
|
||||
for(unsigned long n = 0; n < n_read; n++) {
|
||||
int s_tmp = test_mode_float_buf[n] * INT16_MAX;
|
||||
if (s_tmp < -INT16_MAX)
|
||||
s_tmp = -INT16_MAX;
|
||||
else if (s_tmp > INT16_MAX)
|
||||
s_tmp = INT16_MAX;
|
||||
test_mode_buf[n] = (int16_t)s_tmp;
|
||||
}
|
||||
} else {
|
||||
n_read = fread(test_mode_buf, 1, DEFAULT_BUF_LENGTH, in_file);
|
||||
}
|
||||
if (n_read == 0) break; // sdr_callback() will Segmentation Fault with len=0
|
||||
sdr_callback(test_mode_buf, n_read, demod);
|
||||
n_blocks++;
|
||||
sample_file_pos = (float)n_blocks * n_read / cfg.samp_rate / 2 / demod->sample_size;
|
||||
} while (n_read != 0);
|
||||
|
||||
// Call a last time with cleared samples to ensure EOP detection
|
||||
memset(test_mode_buf, 128, DEFAULT_BUF_LENGTH); // 128 is 0 in unsigned data
|
||||
sdr_callback(test_mode_buf, DEFAULT_BUF_LENGTH, demod);
|
||||
|
||||
//Always classify a signal at the end of the file
|
||||
if (demod->am_analyze)
|
||||
am_analyze_classify(demod->am_analyze);
|
||||
if (!cfg.quiet_mode) {
|
||||
fprintf(stderr, "Test mode file issued %d packets\n", n_blocks);
|
||||
}
|
||||
|
||||
//Always classify a signal at the end of the file
|
||||
if (demod->am_analyze)
|
||||
am_analyze_classify(demod->am_analyze);
|
||||
if (!cfg.quiet_mode) {
|
||||
fprintf(stderr, "Test mode file issued %d packets\n", n_blocks);
|
||||
}
|
||||
|
||||
free(test_mode_buf);
|
||||
free(test_mode_float_buf);
|
||||
exit(0);
|
||||
|
||||
Reference in New Issue
Block a user