From e9a94a46c1de9a28b836519688ae8945b981e933 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 20 Apr 2018 16:20:28 +0200 Subject: Add FIC input Combines neatly with welle-io welle-cli webserver --- src/etianalyse.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/etianalyse.hpp | 8 +++-- src/etisnoop.cpp | 61 +++++++++++++++++++++++++----------- 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 quit; struct eti_analyse_config_t { FILE* etifd = nullptr; + FILE* ficfd = nullptr; bool ignore_error = false; std::map streams_to_decode; std::list > 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 \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; + } } -- cgit v1.2.3