aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2018-04-20 16:20:28 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-04-20 16:20:28 +0200
commite9a94a46c1de9a28b836519688ae8945b981e933 (patch)
tree25a7d275546157e682fc6dc145a786f52e87cf73
parenta0f10ed8a0b03f5f035e6da0c99b3b541aea23be (diff)
downloadetisnoop-e9a94a46c1de9a28b836519688ae8945b981e933.tar.gz
etisnoop-e9a94a46c1de9a28b836519688ae8945b981e933.tar.bz2
etisnoop-e9a94a46c1de9a28b836519688ae8945b981e933.zip
Add FIC input
Combines neatly with welle-io welle-cli webserver
-rw-r--r--src/etianalyse.cpp90
-rw-r--r--src/etianalyse.hpp8
-rw-r--r--src/etisnoop.cpp61
3 files changed, 139 insertions, 20 deletions
diff --git a/src/etianalyse.cpp b/src/etianalyse.cpp
index efb614a..4a99e5e 100644
--- a/src/etianalyse.cpp
+++ b/src/etianalyse.cpp
@@ -91,6 +91,15 @@ static void print_fig_result(const fig_result_t& fig_result, const display_setti
}
}
+void ETI_Analyser::analyse()
+{
+ if (config.etifd != nullptr) {
+ return eti_analyse();
+ }
+ else if (config.ficfd != nullptr) {
+ return fic_analyse();
+ }
+}
void ETI_Analyser::eti_analyse()
{
@@ -427,6 +436,7 @@ void ETI_Analyser::eti_analyse()
printvalue("FIG Length", 1, "FIC length in bytes", to_string(ficl*4));
printvalue("FIC", 1);
fib = p + 12 + 4*nst;
+
for (int i = 0; i < ficl*4/32; i++) {
printsequencestart(2);
printvalue("FIB", 3, "", to_string(i));
@@ -444,7 +454,8 @@ void ETI_Analyser::eti_analyse()
if (crccorrect)
printvalue("CRC", 3, "", "OK");
else {
- printvalue("CRC", 3, "", strprintf("Mismatch: %02x", i, crc));
+ printvalue("CRC", 3, "",
+ strprintf("Mismatch: %04x %04x", crc, figcrc));
}
printvalue("FIGs", 3);
@@ -640,6 +651,83 @@ void ETI_Analyser::eti_analyse()
figs_cleardb();
}
+void ETI_Analyser::fic_analyse()
+{
+ if (config.analyse_fig_rates) {
+ rate_display_header(config.analyse_fig_rates_per_second);
+ }
+
+ FILE *stat_fd = nullptr;
+ if (not config.statistics_filename.empty()) {
+ stat_fd = fopen(config.statistics_filename.c_str(), "w");
+ if (stat_fd == nullptr) {
+ fprintf(stderr, "Could not open statistics file: %s\n",
+ strerror(errno));
+ return;
+ }
+ }
+
+ bool running = true;
+ int i = 0;
+ while (running) {
+ FIGalyser figs;
+ uint8_t fib[32];
+ if (fread(fib, 32, 1, config.ficfd) == 0) {
+ break;
+ }
+
+ printsequencestart(2);
+ printvalue("FIB", 3, "", to_string(i));
+ figs.set_fib(i);
+ rate_new_fib(i);
+
+ const uint16_t figcrc = fib[30]*256 + fib[31];
+ uint16_t crc = 0xffff;
+ for (int j = 0; j < 30; j++) {
+ crc = update_crc_ccitt(crc, fib[j]);
+ }
+ crc =~ crc;
+ const bool crccorrect = (crc == figcrc);
+ if (crccorrect)
+ printvalue("CRC", 3, "", "OK");
+ else {
+ printvalue("CRC", 3, "",
+ strprintf("Mismatch: %04x %04x", crc, figcrc));
+ }
+
+ printvalue("FIGs", 3);
+
+ uint8_t *fig = fib;
+ bool endmarker = false;
+ int figcount = 0;
+ while (!endmarker) {
+ uint8_t figtype, figlen;
+ figtype = (fig[0] & 0xE0) >> 5;
+ if (figtype != 7) {
+ figlen = fig[0] & 0x1F;
+
+ printsequencestart(4);
+ decodeFIG(config, figs, fig+1, figlen, figtype, 5, crccorrect);
+ fig += figlen + 1;
+ figcount += figlen + 1;
+ if (figcount >= 29)
+ endmarker = true;
+ }
+ else {
+ endmarker = true;
+ }
+ }
+
+ if (quit.load()) running = false;
+
+ if (config.analyse_fic_carousel) {
+ figs.analyse(1);
+ }
+
+ i = (i+1) % 3;
+ }
+}
+
void ETI_Analyser::decodeFIG(
const eti_analyse_config_t &config,
FIGalyser &figs,
diff --git a/src/etianalyse.hpp b/src/etianalyse.hpp
index 8024063..692ec34 100644
--- a/src/etianalyse.hpp
+++ b/src/etianalyse.hpp
@@ -1,6 +1,6 @@
/*
Copyright (C) 2014 CSP Innovazione nelle ICT s.c.a r.l. (http://www.csp.it/)
- Copyright (C) 2017 Matthias P. Braendli (http://www.opendigitalradio.org)
+ Copyright (C) 2018 Matthias P. Braendli (http://www.opendigitalradio.org)
Copyright (C) 2015 Data Path
This program is free software: you can redistribute it and/or modify
@@ -46,6 +46,7 @@ extern std::atomic<bool> quit;
struct eti_analyse_config_t {
FILE* etifd = nullptr;
+ FILE* ficfd = nullptr;
bool ignore_error = false;
std::map<int, StreamSnoop> streams_to_decode;
std::list<std::pair<int, int> > figs_to_display;
@@ -67,9 +68,12 @@ class ETI_Analyser {
ensemble(),
wm_decoder() {}
- void eti_analyse(void);
+ void analyse(void);
private:
+ void eti_analyse(void);
+ void fic_analyse(void);
+
void decodeFIG(
const eti_analyse_config_t &config,
FIGalyser &figs,
diff --git a/src/etisnoop.cpp b/src/etisnoop.cpp
index 7aedef7..fa07ea2 100644
--- a/src/etisnoop.cpp
+++ b/src/etisnoop.cpp
@@ -72,7 +72,7 @@ const struct option longopts[] = {
{"help", no_argument, 0, 'h'},
{"ignore-error", no_argument, 0, 'e'},
{"input", required_argument, 0, 'i'},
- {"input-file", no_argument, 0, 'i'},
+ {"input-fic", required_argument, 0, 'I'},
{"num-frames", required_argument, 0, 'n'},
{"statistics", required_argument, 0, 's'},
{"verbose", no_argument, 0, 'v'},
@@ -85,10 +85,14 @@ void usage(void)
"The ETISnoop analyser decodes a RAW ETI file and prints out\n"
"its contents in YAML for easier analysis.\n"
"\n"
+ "It can also read a FIC dump from file.\n"
+ "\n"
" http://www.opendigitalradio.org\n"
"\n"
- "Usage: etisnoop [options] [-i filename]\n"
+ "Usage: etisnoop [options] [(-i|-I) filename]\n"
"\n"
+ " -i the file contains RAW ETI\n"
+ " -I the file contains FIC\n"
" -v increase verbosity (can be given more than once)\n"
" -d N decode subchannel N into .msc file and if DAB+, decode to .wav file\n"
" -s <filename.yaml>\n"
@@ -121,11 +125,13 @@ int main(int argc, char *argv[])
int index;
int ch = 0;
string file_name("-");
+ bool file_contains_eti = false;
+ bool file_contains_fic = false;
eti_analyse_config_t config;
while(ch != -1) {
- ch = getopt_long(argc, argv, "d:efF:hi:n:rRs:vw", longopts, &index);
+ ch = getopt_long(argc, argv, "d:efF:hi:I:n:rRs:vw", longopts, &index);
switch (ch) {
case 'd':
{
@@ -163,6 +169,11 @@ int main(int argc, char *argv[])
break;
case 'i':
file_name = optarg;
+ file_contains_eti = true;
+ break;
+ case 'I':
+ file_name = optarg;
+ file_contains_fic = true;
break;
case 'n':
config.num_frames_to_decode = std::atoi(optarg);
@@ -195,23 +206,39 @@ int main(int argc, char *argv[])
}
}
- FILE* etifd;
- if (file_name == "-") {
- fprintf(stderr, "Analysing stdin\n");
- etifd = stdin;
+ if (file_contains_eti and file_contains_fic) {
+ fprintf(stderr, "-i and -I are mutually exclusive\n");
+ return 1;
}
- else {
- etifd = fopen(file_name.c_str(), "r");
- if (etifd == NULL) {
- perror("File open failed");
- return 1;
+ else if (file_contains_eti or file_contains_fic) {
+ FILE* fd;
+ if (file_name == "-") {
+ fprintf(stderr, "Analysing stdin\n");
+ fd = stdin;
+ }
+ else {
+ fd = fopen(file_name.c_str(), "r");
+ if (fd == NULL) {
+ perror("File open failed");
+ return 1;
+ }
}
- }
- config.etifd = etifd;
- ETI_Analyser eti_analyser(config);
- eti_analyser.eti_analyse();
- fclose(etifd);
+ if (file_contains_eti) {
+ config.etifd = fd;
+ }
+ else {
+ config.ficfd = fd;
+ }
+
+ ETI_Analyser eti_analyser(config);
+ eti_analyser.analyse();
+ fclose(fd);
+ }
+ else {
+ fprintf(stderr, "Must specify either -i or -I\n");
+ return 1;
+ }
}