diff options
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | src/etianalyse.cpp | 350 | ||||
| -rw-r--r-- | src/etiinput.cpp | 4 | ||||
| -rw-r--r-- | src/etisnoop.cpp | 11 | ||||
| -rw-r--r-- | src/faad_decoder.cpp | 14 | ||||
| -rw-r--r-- | src/fec/decode_rs.h | 12 | ||||
| -rw-r--r-- | src/fig0_0.cpp | 4 | ||||
| -rw-r--r-- | src/fig0_1.cpp | 26 | ||||
| -rw-r--r-- | src/fig0_10.cpp | 18 | ||||
| -rw-r--r-- | src/fig0_11.cpp | 43 | ||||
| -rw-r--r-- | src/fig0_13.cpp | 15 | ||||
| -rw-r--r-- | src/fig0_14.cpp | 5 | ||||
| -rw-r--r-- | src/fig0_16.cpp | 15 | ||||
| -rw-r--r-- | src/fig0_17.cpp | 19 | ||||
| -rw-r--r-- | src/fig0_18.cpp | 24 | ||||
| -rw-r--r-- | src/fig0_19.cpp | 18 | ||||
| -rw-r--r-- | src/fig0_2.cpp | 75 | ||||
| -rw-r--r-- | src/fig0_21.cpp | 78 | ||||
| -rw-r--r-- | src/fig0_22.cpp | 25 | ||||
| -rw-r--r-- | src/fig0_24.cpp | 23 | ||||
| -rw-r--r-- | src/fig0_25.cpp | 20 | ||||
| -rw-r--r-- | src/fig0_26.cpp | 8 | ||||
| -rw-r--r-- | src/fig0_27.cpp | 10 | ||||
| -rw-r--r-- | src/fig0_28.cpp | 5 | ||||
| -rw-r--r-- | src/fig0_3.cpp | 19 | ||||
| -rw-r--r-- | src/fig0_31.cpp | 18 | ||||
| -rw-r--r-- | src/fig0_5.cpp | 22 | ||||
| -rw-r--r-- | src/fig0_6.cpp | 50 | ||||
| -rw-r--r-- | src/fig0_8.cpp | 17 | ||||
| -rw-r--r-- | src/fig0_9.cpp | 29 | ||||
| -rw-r--r-- | src/fig1.cpp | 38 | ||||
| -rw-r--r-- | src/utils.cpp | 169 | ||||
| -rw-r--r-- | src/utils.hpp | 31 | ||||
| -rw-r--r-- | src/watermarkdecoder.hpp | 3 | ||||
| -rwxr-xr-x | yamlexample.py | 17 | 
36 files changed, 723 insertions, 520 deletions
@@ -1,8 +1,8 @@  ETISnoop analyser  ================= -The ETISnoop analyser decodes and prints out a RAW ETI file in a -form that makes analysis easier. +The ETISnoop analyser decodes a RAW ETI file and prints out +its contents in YAML for easier analysis.  It can show information about the signalling, details about the FIGs,  and extract a DAB+ subchannel into a file. @@ -24,7 +24,7 @@ Then do  About  ----- -This is a contribution by CSP.it, is now developed by opendigitalradio, +This is a contribution from CSP.it, now developed by Opendigitalradio,  and is published under the terms of the GNU GPL v3 or later.  See LICENCE for more information. diff --git a/configure.ac b/configure.ac index a028afc..52eba96 100644 --- a/configure.ac +++ b/configure.ac @@ -34,8 +34,6 @@ AC_SEARCH_LIBS([NeAACDecDecode], [faad], [], [    AC_MSG_ERROR([unable to find libfaad])  ]) -AC_CHECK_LIB([rt], [clock_gettime], [], [AC_MSG_ERROR([library rt is missing])]) -  AM_CONDITIONAL([IS_GIT_REPO], [test -d '.git'])  AC_CONFIG_FILES([Makefile]) diff --git a/src/etianalyse.cpp b/src/etianalyse.cpp index b027654..415e7a6 100644 --- a/src/etianalyse.cpp +++ b/src/etianalyse.cpp @@ -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 @@ -58,27 +58,34 @@ eti_analyse_config_t::is_fig_to_be_printed(int type, int extension) const              make_pair(type, extension)) != figs_to_display.end();  } +static +string replace_first(const string& source, const string& from, const string& to) +{ +    string s(source); +    size_t i = s.find(from); +    if (i != string::npos) { +        s.replace(i, from.length(), to); +    } +    return s; +} +  static void print_fig_result(const fig_result_t& fig_result, const display_settings_t& disp)  {      if (disp.print) {          for (const auto& msg : fig_result.msgs) {              std::string s;              for (int i = 0; i < msg.level; i++) { -                s += "    "; +                s += " ";              } -            s += msg.msg; +            s += replace_first(msg.msg, "=", ": ");              for (int i = 0; i < disp.indent; i++) { -                printf("\t"); +                printf(" ");              }              printf("%s\n", s.c_str());          }          if (not fig_result.errors.empty()) { -            printf("ERRORS:\n");              for (const auto& err : fig_result.errors) { -                for (int i = 0; i < disp.indent; i++) { -                    printf("\t"); -                } -                printf("%s\n", err.c_str()); +                fprintf(stderr, "ERRORS: %s\n" , err.c_str());              }          }      } @@ -96,7 +103,7 @@ void ETI_Analyser::eti_analyse()      uint8_t scid,tpl;      uint16_t sad[64],stl[64];      char sdesc[256]; -    uint32_t frame_nb = 0, frame_sec = 0, frame_ms = 0, frame_h, frame_m, frame_s; +    uint32_t frame_nb = 0, frame_sec = 0, frame_ms = 0;      static int last_fct = -1; @@ -105,20 +112,20 @@ void ETI_Analyser::eti_analyse()      int stream_type = ETI_STREAM_TYPE_NONE;      if (identify_eti_format(config.etifd, &stream_type) == -1) { -        printf("Could not identify stream type\n"); +        fprintf(stderr, "Could not identify stream type\n");          running = false;      }      else { -        printf("Identified ETI type "); +        fprintf(stderr, "Identified ETI type ");          if (stream_type == ETI_STREAM_TYPE_RAW) -            printf("RAW\n"); +            fprintf(stderr, "RAW\n");          else if (stream_type == ETI_STREAM_TYPE_STREAMED) -            printf("STREAMED\n"); +            fprintf(stderr, "STREAMED\n");          else if (stream_type == ETI_STREAM_TYPE_FRAMED) -            printf("FRAMED\n"); +            fprintf(stderr, "FRAMED\n");          else -            printf("?\n"); +            fprintf(stderr, "?\n");      }      if (config.analyse_fig_rates) { @@ -148,11 +155,12 @@ void ETI_Analyser::eti_analyse()          }          // Timestamp and Frame Number -        frame_h = (frame_sec / 3600); -        frame_m = (frame_sec - (frame_h * 3600)) / 60; -        frame_s = (frame_sec - (frame_h * 3600) - (frame_m * 60)); -        sprintf(sdesc, "%02d:%02d:%02d.%03d frame %d", frame_h, frame_m, frame_s, frame_ms, frame_nb); -        printbuf(sdesc, 0, NULL, 0); +        uint32_t frame_h = (frame_sec / 3600); +        uint32_t frame_m = (frame_sec - (frame_h * 3600)) / 60; +        uint32_t frame_s = (frame_sec - (frame_h * 3600) - (frame_m * 60)); +        printf("---\n"); +        printf("Frame: %d\n", frame_nb); +        printf("Time: %02d:%02d:%02d.%03d\n", frame_h, frame_m, frame_s, frame_ms);          frame_ms += 24; // + 24 ms          if (frame_ms >= 1000) {              frame_ms -= 1000; @@ -165,14 +173,12 @@ void ETI_Analyser::eti_analyse()          // SYNC - ERR          if (p[0] == 0xFF) { -            desc = "No error"; -            printbuf("ERR", 1, p, 1, desc); +            printbuf("ERR", 1, p, 1, "", "No Error");          }          else { -            desc = "Error"; -            printbuf("ERR", 1, p, 1, desc); +            printbuf("ERR", 1, p, 1, "", "Error");              if (!config.ignore_error) { -                printf("Aborting because of SYNC error\n"); +                fprintf(stderr, "Aborting because of SYNC error\n");                  break;              }          } @@ -186,10 +192,11 @@ void ETI_Analyser::eti_analyse()                  memcpy(prevsync, p+1, 3);              }              else { -                desc ="Wrong FSYNC"; +                desc = "Wrong FSYNC";                  memcpy(prevsync, "\x00\x00\x00", 3);              } -        } else if (memcmp(prevsync, "\x07\x3a\xb6", 3) == 0) { +        } +        else if (memcmp(prevsync, "\x07\x3a\xb6", 3) == 0) {              if (memcmp(p + 1, "\xf8\xc5\x49", 3) != 0) {                  desc = "Wrong FSYNC";                  memcpy(prevsync, "\x00\x00\x00", 3); @@ -197,7 +204,8 @@ void ETI_Analyser::eti_analyse()                  desc = "OK";                  memcpy(prevsync, p + 1, 3);              } -        } else if (memcmp(prevsync, "\xf8\xc5\x49", 3) == 0) { +        } +        else if (memcmp(prevsync, "\xf8\xc5\x49", 3) == 0) {              if (memcmp(p + 1, "\x07\x3a\xb6", 3) != 0) {                  desc = "Wrong FSYNC";                  memcpy(prevsync, "\x00\x00\x00", 3); @@ -206,20 +214,18 @@ void ETI_Analyser::eti_analyse()                  memcpy(prevsync, p + 1, 3);              }          } -        printbuf("Sync FSYNC", 1, p + 1, 3, desc); +        printbuf("FSYNC", 1, p + 1, 3, "", desc);          // LIDATA -        printbuf("LDATA", 0, NULL, 0); +        printbuf("LIDATA");          // LIDATA - FC -        printbuf("FC - Frame Characterization field", 1, p+4, 4); +        printbuf("FC", 1, p+4, 4, "Frame Characterization field");          // LIDATA - FC - FCT -        char fct_str[25]; -        sprintf(fct_str, "%d", p[4]);          int fct = p[4]; -        printbuf("FCT  - Frame Count", 2, p+4, 1, fct_str); +        printbuf("FCT", 2, p+4, 1, "Frame Count", to_string(fct));          if (last_fct != -1) {              if ((last_fct + 1) % 250 != fct) { -                printf("FCT not contiguous\n"); +                printbuf("Error: FCT not contiguous", 2);              }          }          last_fct = fct; @@ -228,23 +234,20 @@ void ETI_Analyser::eti_analyse()          {              stringstream ss; -            ss << (int)ficf;              if (ficf == 1) { -                ss << "- FIC Information are present"; +                ss << "FIC Information are present";              }              else { -                ss << "- FIC Information are not present"; +                ss << "FIC Information are not present";              } -            printbuf("FICF - Fast Information Channel Flag", 2, NULL, 0, ss.str()); +            printbuf("FICF", 2, nullptr, 0, ss.str(), to_string(ficf));          }          // LIDATA - FC - NST          nst = p[5] & 0x7F;          { -            stringstream ss; -            ss << (int)nst; -            printbuf("NST  - Number of streams", 2, NULL, 0, ss.str()); +            printbuf("NST", 2, nullptr, 0, "Number of streams", to_string(nst));          }          // LIDATA - FC - FP @@ -252,30 +255,27 @@ void ETI_Analyser::eti_analyse()          {              stringstream ss;              ss << (int)fp; -            printbuf("FP   - Frame Phase", 2, &fp, 1, ss.str()); +            printbuf("FP", 2, &fp, 1, "Frame Phase", to_string(fp));          }          // LIDATA - FC - MID          mid = (p[6] & 0x18) >> 3;          { -            stringstream ss; -            ss << "Mode "; +            string modestr;              if (mid != 0) { -                ss << (int)mid; +                modestr = to_string(mid);              }              else { -                ss << "4"; +                modestr = "4";              } -            printbuf("MID  - Mode Identity", 2, &mid, 1, ss.str()); +            printbuf("MID", 2, &mid, 1, "Mode Identity", modestr);              set_mode_identity(mid);          }          // LIDATA - FC - FL          fl = (p[6] & 0x07) * 256 + p[7];          { -            stringstream ss; -            ss << fl << " words"; -            printbuf("FL   - Frame Length", 2, NULL, 0, ss.str()); +            printbuf("FL", 2, nullptr, 0, "Frame Length in words", to_string(fl));          }          if (ficf == 0) { @@ -289,62 +289,96 @@ void ETI_Analyser::eti_analyse()          }          // STC -        printbuf("STC - Stream Characterisation", 1, NULL, 0); +        printvalue("STC", 1);          for (int i=0; i < nst; i++) { -            sprintf(sdesc, "Stream number %d", i); -            printbuf("STC  - Stream Characterisation", 2, p + 8 + 4*i, 4, sdesc); +            printsequencestart(2); +            printbuf("Stream Number", 3, p + 8 + 4*i, 4, "", to_string(i));              scid = (p[8 + 4*i] & 0xFC) >> 2; -            sprintf(sdesc, "%d", scid); -            printbuf("SCID - Sub-channel Identifier", 3, NULL, 0, sdesc); + +            printvalue("SCID", 3, "Sub-channel Identifier", to_string(scid));              sad[i] = (p[8+4*i] & 0x03) * 256 + p[9+4*i]; -            sprintf(sdesc, "%d", sad[i]); -            printbuf("SAD  - Sub-channel Start Address", 3, NULL, 0, sdesc); + +            printvalue("SAD", 3, "Sub-channel Start Address", to_string(sad[i]));              tpl = (p[10+4*i] & 0xFC) >> 2;              if ((tpl & 0x20) >> 5 == 1) {                  uint8_t opt, plevel;                  string plevelstr; +                string rate; +                int num_cu = 0;                  opt = (tpl & 0x1c) >> 2;                  plevel = (tpl & 0x03);                  if (opt == 0x00) { -                    if (plevel == 0) -                        plevelstr = "1-A, 1/4, 16 CUs"; -                    else if (plevel == 1) -                        plevelstr = "2-A, 3/8, 8 CUs"; -                    else if (plevel == 2) -                        plevelstr = "3-A, 1/2, 6 CUs"; -                    else if (plevel == 3) -                        plevelstr = "4-A, 3/4, 4 CUs"; +                    if (plevel == 0) { +                        plevelstr = "1-A"; +                        rate = "1/4"; +                        num_cu = 16; +                    } +                    else if (plevel == 1) { +                        plevelstr = "2-A"; +                        rate = "3/8"; +                        num_cu = 8; +                    } +                    else if (plevel == 2) { +                        plevelstr = "3-A"; +                        rate = "1/2"; +                        num_cu = 6; +                    } +                    else if (plevel == 3) { +                        plevelstr = "4-A"; +                        rate = "3/4"; +                        num_cu = 4; +                    }                  }                  else if (opt == 0x01) { -                    if (plevel == 0) -                        plevelstr = "1-B, 4/9, 27 CUs"; -                    else if (plevel == 1) -                        plevelstr = "2-B, 4/7, 21 CUs"; -                    else if (plevel == 2) -                        plevelstr = "3-B, 4/6, 18 CUs"; -                    else if (plevel == 3) -                        plevelstr = "4-B, 4/5, 15 CUs"; +                    if (plevel == 0) { +                        plevelstr = "1-B"; +                        rate = "4/9"; +                        num_cu = 27; +                    } +                    else if (plevel == 1) { +                        plevelstr = "2-B"; +                        rate = "4/7"; +                        num_cu = 21; +                    } +                    else if (plevel == 2) { +                        plevelstr = "3-B"; +                        rate = "4/6"; +                        num_cu = 18; +                    } +                    else if (plevel == 3) { +                        plevelstr = "4-B"; +                        rate = "4/5"; +                        num_cu = 15; +                    }                  }                  else { -                    stringstream ss; -                    ss << "Unknown option " << opt; -                    plevelstr = ss.str(); +                    plevelstr = "Unknown option " + to_string(opt); +                } +                printvalue("TPL", 3, "Sub-channel Type and Protection Level"); +                printvalue("EEP", 4, "Equal Error Protection", to_string(tpl)); +                printvalue("Level", 5, "", plevelstr); +                if (not rate.empty()) { +                    printvalue("Rate", 5, "", rate); +                } +                if (num_cu) { +                    printvalue("CUs", 5, "", to_string(num_cu));                  } -                sprintf(sdesc, "0x%02x - Equal Error Protection. %s", tpl, plevelstr.c_str());              }              else {                  uint8_t tsw, uepidx;                  tsw = (tpl & 0x08);                  uepidx = tpl & 0x07; -                sprintf(sdesc, "0x%02x - Unequal Error Protection. Table switch %d,  UEP index %d", tpl, tsw, uepidx); +                printvalue("TPL", 3, "Sub-channel Type and Protection Level"); +                printvalue("UEP", 4, "Unequal Error Protection", to_string(tpl)); +                printvalue("Table switch", 5, "", to_string(tsw)); +                printvalue("Index", 5, "", to_string(uepidx));              } -            printbuf("TPL  - Sub-channel Type and Protection Level", 3, NULL, 0, sdesc);              stl[i] = (p[10+4*i] & 0x03) * 256 + \                        p[11+4*i]; -            sprintf(sdesc, "%d => %d kbit/s", stl[i], stl[i]*8/3); -            printbuf("STL  - Sub-channel Stream Length", 3, NULL, 0, sdesc); +            printvalue("STL", 3, "Sub-channel Stream Length", to_string(stl[i])); +            printvalue("bitrate", 3, "kbit/s", to_string(stl[i]*8/3));              if (config.statistics and config.streams_to_decode.count(i) == 0) {                  config.streams_to_decode.emplace(std::piecewise_construct, @@ -361,31 +395,26 @@ void ETI_Analyser::eti_analyse()          }          // EOH -        printbuf("EOH - End Of Header", 1, p + 8 + 4*nst, 4); -        uint16_t mnsc = p[8 + 4*nst] * 256 + \ -                                  p[8 + 4*nst + 1]; -        { -            stringstream ss; -            ss << mnsc; -            printbuf("MNSC - Multiplex Network Signalling Channel", 2, p+8+4*nst, 2, ss.str()); -        } +        printbuf("EOH", 1, p + 8 + 4*nst, 4, "End Of Header"); +        uint16_t mnsc = p[8 + 4*nst] * 256 + p[8 + 4*nst + 1]; +        printbuf("MNSC", 2, p+8+4*nst, 2, "Multiplex Network Signalling Channel", strprintf("%04x", mnsc)); -        crch = p[8 + 4*nst + 2]*256 + \ -               p[8 + 4*nst + 3]; +        crch = p[8 + 4*nst + 2]*256 + p[8 + 4*nst + 3];          crc  = 0xffff; -        for (int i=4; i < 8 + 4*nst + 2; i++) +        for (int i=4; i < 8 + 4*nst + 2; i++) {              crc = update_crc_ccitt(crc, p[i]); +        }          crc =~ crc;          if (crc == crch) { -            sprintf(sdesc,"CRC OK"); +            sprintf(sdesc, "OK");          }          else { -            sprintf(sdesc,"CRC Mismatch: %02x",crc); +            sprintf(sdesc, "Mismatch: %02x",crc);          } -        printbuf("Header CRC", 2, p + 8 + 4*nst + 2, 2, sdesc); +        printbuf("Header CRC", 2, p + 8 + 4*nst + 2, 2, "", sdesc);          // MST - FIC          if (ficf == 1) { @@ -395,13 +424,12 @@ void ETI_Analyser::eti_analyse()              uint8_t ficdata[32*4];              memcpy(ficdata, p + 12 + 4*nst, ficl*4); -            sprintf(sdesc, "FIC Data (%d bytes)", ficl*4); -            //printbuf(sdesc, 1, ficdata, ficl*4); -            printbuf(sdesc, 1, NULL, 0); +            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++) { -                sprintf(sdesc, "FIB %d", i); -                printbuf(sdesc, 1, NULL, 0); +                printsequencestart(2); +                printvalue("FIB", 3, "", to_string(i));                  fig=fib;                  figs.set_fib(i);                  rate_new_fib(i); @@ -414,10 +442,12 @@ void ETI_Analyser::eti_analyse()                  crc =~ crc;                  const bool crccorrect = (crc == figcrc);                  if (crccorrect) -                    sprintf(sdesc, "FIB %d CRC OK", i); -                else -                    sprintf(sdesc, "FIB %d CRC Mismatch: %02x", i, crc); +                    printvalue("CRC", 3, "", "OK"); +                else { +                    printvalue("CRC", 3, "", strprintf("Mismatch: %02x", i, crc)); +                } +                printvalue("FIGs", 3);                  bool endmarker = false;                  int figcount = 0; @@ -426,9 +456,9 @@ void ETI_Analyser::eti_analyse()                      figtype = (fig[0] & 0xE0) >> 5;                      if (figtype != 7) {                          figlen = fig[0] & 0x1F; -                        sprintf(sdesc, "FIG %d [%d bytes]", figtype, figlen); -                        printbuf(sdesc, 3, fig+1, figlen); -                        decodeFIG(config, figs, fig+1, figlen, figtype, 4, crccorrect); + +                        printsequencestart(4); +                        decodeFIG(config, figs, fig+1, figlen, figtype, 5, crccorrect);                          fig += figlen + 1;                          figcount += figlen + 1;                          if (figcount >= 29) @@ -447,47 +477,46 @@ void ETI_Analyser::eti_analyse()              }          } +        printvalue("Stream Data", 1);          int offset = 0;          for (int i=0; i < nst; i++) {              uint8_t streamdata[684*8];              memcpy(streamdata, p + 12 + 4*nst + ficf*ficl*4 + offset, stl[i]*8);              offset += stl[i] * 8; -            if (config.streams_to_decode.count(i) > 0) { -                sprintf(sdesc, "id %d, len %d, selected for decoding", i, stl[i]*8); -            } -            else { -                sprintf(sdesc, "id %d, len %d, not selected for decoding", i, stl[i]*8); -            } -            if (get_verbosity() > 2) { -                printbuf("Stream Data", 1, streamdata, stl[i]*8, sdesc); -            } -            else { -                printbuf("Stream Data", 1, streamdata, 0, sdesc); +            printsequencestart(2); +            printvalue("Id", 3, "", to_string(i)); +            printvalue("Length", 3, "", to_string(stl[i]*8)); +            printvalue("Selected for decoding", 3, "", +                    (config.streams_to_decode.count(i) > 0 ? "true" : "false")); + +            if (get_verbosity() > 1) { +                printbuf("Data", 3, streamdata, stl[i]*8);              }              if (config.streams_to_decode.count(i) > 0) {                  config.streams_to_decode.at(i).push(streamdata, stl[i]*8);              } -          }          //* EOF (4 Bytes) +        printbuf("EOF", 1, p + 12 + 4*nst + ficf*ficl*4 + offset, 4); +          // CRC (2 Bytes)          crch = p[12 + 4*nst + ficf*ficl*4 + offset] * 256 + \                 p[12 + 4*nst + ficf*ficl*4 + offset + 1];          crc = 0xffff; -        for (int i = 12 + 4*nst; i < 12 + 4*nst + ficf*ficl*4 + offset; i++) +        for (int i = 12 + 4*nst; i < 12 + 4*nst + ficf*ficl*4 + offset; i++) {              crc = update_crc_ccitt(crc, p[i]); +        }          crc =~ crc;          if (crc == crch) -            sprintf(sdesc, "CRC OK"); +            sprintf(sdesc, "OK");          else -            sprintf(sdesc, "CRC Mismatch: %02x", crc); +            sprintf(sdesc, "Mismatch: %02x", crc); -        printbuf("EOF", 1, p + 12 + 4*nst + ficf*ficl*4 + offset, 4); -        printbuf("CRC", 2, p + 12 + 4*nst + ficf*ficl*4 + offset, 2, sdesc); +        printbuf("CRC", 2, p + 12 + 4*nst + ficf*ficl*4 + offset, 2, "", sdesc);          // RFU (2 Bytes)          printbuf("RFU", 2, p + 12 + 4*nst + ficf*ficl*4 + offset + 2, 2); @@ -499,12 +528,8 @@ void ETI_Analyser::eti_analyse()                          (uint32_t)(p[tist_ix+2]) << 8 |                          (uint32_t)(p[tist_ix+3]); -        sprintf(sdesc, "%f ms", (TIST & 0xFFFFFF) / 16384.0); -        printbuf("TIST - Time Stamp", 1, p + tist_ix, 4, sdesc); - -        if (get_verbosity()) { -            printf("-------------------------------------------------------------------------------------------------------------\n"); -        } +        sprintf(sdesc, "%f", (TIST & 0xFFFFFF) / 16384.0); +        printbuf("TIST", 1, p + tist_ix, 4, "Time Stamp (ms)", sdesc);          if (config.analyse_fig_rates and (fct % 250) == 0) {              rate_display_analysis(false, config.analyse_fig_rates_per_second); @@ -513,7 +538,7 @@ void ETI_Analyser::eti_analyse()          num_frames++;          if (config.num_frames_to_decode > 0 and                  num_frames >= config.num_frames_to_decode) { -            printf("Decoded %zu ETI frames\n", num_frames); +            fprintf(stderr, "Decoded %zu ETI frames\n", num_frames);              break;          } @@ -624,8 +649,6 @@ void ETI_Analyser::decodeFIG(          int indent,          bool fibcrccorrect)  { -    char desc[512]; -      switch (figtype) {          case 0:              { @@ -634,10 +657,16 @@ void ETI_Analyser::decodeFIG(                  const display_settings_t disp(config.is_fig_to_be_printed(figtype, fig0.ext()), indent); +                printvalue("FIG", disp, "", strprintf("0/%d", fig0.ext())); +                if (get_verbosity() > 0) { +                    printbuf("Data", disp, f, figlen); +                } +                  if (disp.print) { -                    sprintf(desc, "FIG %d/%d: C/N=%d OE=%d P/D=%d", -                            figtype, fig0.ext(), fig0.cn(), fig0.oe(), fig0.pd()); -                    printfig(desc, disp, f+1, figlen-1); +                    printvalue("Length", disp, "", to_string(figlen)); +                    printvalue("OE", disp, "", to_string(fig0.oe())); +                    printvalue("C/N", disp, "", to_string(fig0.cn())); +                    printvalue("P/D", disp, "", to_string(fig0.pd()));                  }                  figs.push_back(figtype, fig0.ext(), figlen); @@ -645,6 +674,7 @@ void ETI_Analyser::decodeFIG(                  auto fig_result = fig0_select(fig0, disp);                  fig_result.figtype = figtype;                  fig_result.figext = fig0.ext(); +                printvalue("Decoding", disp);                  print_fig_result(fig_result, disp+1);                  rate_announce_fig(figtype, fig0.ext(), fig_result.complete); @@ -657,10 +687,15 @@ void ETI_Analyser::decodeFIG(                  fig1.fibcrccorrect = fibcrccorrect;                  const display_settings_t disp(config.is_fig_to_be_printed(figtype, fig1.ext()), indent); + +                printvalue("FIG", disp, "", strprintf("1/%d", fig1.ext())); +                if (get_verbosity() > 0) { +                    printbuf("Data", disp, f, figlen); +                } +                  if (disp.print) { -                    sprintf(desc, "FIG %d/%d: OE=%d", -                            figtype, fig1.ext(), fig1.oe()); -                    printfig(desc, disp, f+1, figlen-1); +                    printvalue("Length", disp, "", to_string(figlen)); +                    printvalue("OE", disp, "", to_string(fig1.oe()));                  }                  figs.push_back(figtype, fig1.ext(), figlen); @@ -668,6 +703,7 @@ void ETI_Analyser::decodeFIG(                  auto fig_result = fig1_select(fig1, disp);                  fig_result.figtype = figtype;                  fig_result.figext = fig1.ext(); +                printvalue("Decoding", disp);                  print_fig_result(fig_result, disp+1);                  rate_announce_fig(figtype, fig1.ext(), fig_result.complete);              } @@ -682,12 +718,18 @@ void ETI_Analyser::decodeFIG(                  ext = f[0] & 0x07;                  const display_settings_t disp(config.is_fig_to_be_printed(figtype, ext), indent); -                if (disp.print) { -                    sprintf(desc, -                            "FIG %d/%d: Toggle flag=%d, Segment_index=%d, OE=%d", -                            figtype, ext, toggle_flag, segment_index, oe); -                    printfig(desc, disp, f+1, figlen-1); +                printvalue("FIG", disp, "", strprintf("2/%d", ext)); + +                if (get_verbosity() > 0) { +                    printbuf("Data", disp, f, figlen); +                } + +                if (disp.print) { +                    printvalue("Length", disp, "", to_string(figlen)); +                    printvalue("OE", disp, "", to_string(oe)); +                    printvalue("Toggle flag", disp, "", to_string(toggle_flag)); +                    printvalue("Segment index", disp, "", to_string(segment_index));                  }                  figs.push_back(figtype, ext, figlen); @@ -707,10 +749,18 @@ void ETI_Analyser::decodeFIG(                  const display_settings_t disp(config.is_fig_to_be_printed(figtype, ext), indent); -                sprintf(desc, -                        "FIG %d/%d: D1=%d, D2=%d, TCId=%d", -                        figtype, ext, d1, d2, tcid); -                printfig(desc, disp, f+1, figlen-1); +                printvalue("FIG", disp, "", strprintf("5/%d", ext)); + +                if (get_verbosity() > 0) { +                    printbuf("Data", disp, f, figlen); +                } + +                if (disp.print) { +                    printvalue("Length", disp, "", to_string(figlen)); +                    printvalue("D1", disp, "", to_string(d1)); +                    printvalue("D2", disp, "", to_string(d2)); +                    printvalue("TCId", disp, "", to_string(tcid)); +                }                  figs.push_back(figtype, ext, figlen); @@ -721,11 +771,13 @@ void ETI_Analyser::decodeFIG(          case 6:              {// Conditional access                  fprintf(stderr, "ERROR: ETI contains unsupported FIG 6\n"); +                printvalue("FIG", indent, "", "6 - unsupported");              }              break;          default:              {                  fprintf(stderr, "ERROR: ETI contains unknown FIG %d\n", figtype); +                printvalue("FIG", indent, "", strprintf("%d - unsupported", figtype));              }              break;      } diff --git a/src/etiinput.cpp b/src/etiinput.cpp index 8f47ec0..22e6cd6 100644 --- a/src/etiinput.cpp +++ b/src/etiinput.cpp @@ -180,7 +180,7 @@ int get_eti_frame(FILE* inputfile, int stream_type, void* buf)      }      if (frameSize > 6144) { // there might be a better limit -        printf("Wrong frame size %u in ETI file!\n", frameSize); +        fprintf(stderr, "Wrong frame size %u in ETI file!\n", frameSize);          return -1;      } @@ -188,7 +188,7 @@ int get_eti_frame(FILE* inputfile, int stream_type, void* buf)      if (read_bytes != frameSize) {          // A short read of a frame (i.e. reading an incomplete frame)          // is not tolerated. Input files must not contain incomplete frames -        printf("Incomplete frame in ETI file!\n"); +        fprintf(stderr, "Incomplete frame in ETI file!\n");          return -1;      } diff --git a/src/etisnoop.cpp b/src/etisnoop.cpp index 1547af3..7aedef7 100644 --- a/src/etisnoop.cpp +++ b/src/etisnoop.cpp @@ -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 @@ -82,8 +82,8 @@ void usage(void)  {      fprintf(stderr,              "Opendigitalradio ETISnoop analyser %s compiled at %s, %s\n\n" -            "The ETISnoop analyser decodes and prints out a RAW ETI file in a\n" -            "form that makes analysis easier.\n" +            "The ETISnoop analyser decodes a RAW ETI file and prints out\n" +            "its contents in YAML for easier analysis.\n"              "\n"              "  http://www.opendigitalradio.org\n"              "\n" @@ -94,7 +94,7 @@ void usage(void)              "   -s <filename.yaml>\n"              "           statistics mode: decode all subchannels and measure audio level, write statistics to file\n"              "   -n N    stop analysing after N ETI frames\n" -            "   -f      analyse FIC carousel\n" +            "   -f      analyse FIC carousel (no YAML output)\n"              "   -r      analyse FIG rates in FIGs per second\n"              "   -R      analyse FIG rates in frames per FIG\n"              "   -w      decode CRC-DABMUX and ODR-DabMux watermark.\n" @@ -198,7 +198,7 @@ int main(int argc, char *argv[])      FILE* etifd;      if (file_name == "-") { -        printf("Analysing stdin\n"); +        fprintf(stderr, "Analysing stdin\n");          etifd = stdin;      }      else { @@ -215,4 +215,3 @@ int main(int argc, char *argv[])      fclose(etifd);  } - diff --git a/src/faad_decoder.cpp b/src/faad_decoder.cpp index ced9921..280bf0d 100644 --- a/src/faad_decoder.cpp +++ b/src/faad_decoder.cpp @@ -109,7 +109,7 @@ bool FaadDecoder::decode(vector<vector<uint8_t> > aus)              int core_sr_index = m_dac_rate ? (m_sbr_flag ? 6 : 3) : (m_sbr_flag ? 8 : 5);   // 24/48/16/32 kHz              int core_ch_config = get_aac_channel_configuration();              if(core_ch_config == -1) { -                printf("Unrecognized mpeg surround config (ignored): %d\n", m_mpeg_surround_config); +                fprintf(stderr, "Unrecognized mpeg surround config (ignored): %d\n", m_mpeg_surround_config);                  return false;              } @@ -124,7 +124,7 @@ bool FaadDecoder::decode(vector<vector<uint8_t> > aus)              long int init_result = NeAACDecInit2(m_faad_handle.decoder, asc, sizeof(asc), &samplerate, &channels);              if(init_result != 0) {                  /* If some error initializing occured, skip the file */ -                printf("Error initializing decoder library: %s\n", NeAACDecGetErrorMessage(-init_result)); +                fprintf(stderr, "Error initializing decoder library: %s\n", NeAACDecGetErrorMessage(-init_result));                  NeAACDecClose(m_faad_handle.decoder);                  return false;              } @@ -140,15 +140,15 @@ bool FaadDecoder::decode(vector<vector<uint8_t> > aus)          size_t samples  = hInfo.samples;  #if 0 -        printf("bytes consumed %d\n", (int)(hInfo.bytesconsumed)); -        printf("samplerate = %d, samples = %zu, channels = %d," +        fprintf(stderr, "bytes consumed %d\n", (int)(hInfo.bytesconsumed)); +        fprintf(stderr, "samplerate = %d, samples = %zu, channels = %d,"                  " error = %d, sbr = %d\n", m_sample_rate, samples,                  m_channels, hInfo.error, hInfo.sbr); -        printf("header = %d\n", hInfo.header_type); +        fprintf(stderr, "header = %d\n", hInfo.header_type);  #endif          if (hInfo.error != 0) { -            printf("FAAD Warning: %s\n", +            fprintf(stderr, "FAAD Warning: %s\n",                      faacDecGetErrorMessage(hInfo.error));              return false;          } @@ -161,7 +161,7 @@ bool FaadDecoder::decode(vector<vector<uint8_t> > aus)          if (samples) {              if (m_channels != 1 and m_channels != 2) { -                printf("Cannot handle %d channels\n", m_channels); +                fprintf(stderr, "Cannot handle %d channels\n", m_channels);              }              m_stats.peak_level_left = 0; diff --git a/src/fec/decode_rs.h b/src/fec/decode_rs.h index c165cf3..03a800a 100644 --- a/src/fec/decode_rs.h +++ b/src/fec/decode_rs.h @@ -145,15 +145,15 @@        count++;      }      if (count != no_eras) { -      printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras); +      fprintf(stderr, "RS: count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);        count = -1;        goto finish;      }  #if DEBUG >= 2 -    printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); +    fprintf(stderr, "\n Erasure positions as determined by roots of Eras Loc Poly:\n");      for (i = 0; i < count; i++) -      printf("%d ", loc[i]); -    printf("\n"); +      fprintf(stderr, "%d ", loc[i]); +    fprintf(stderr, "\n");  #endif  #endif    } @@ -227,7 +227,7 @@        continue; /* Not a root */      /* store root (index-form) and error location number */  #if DEBUG>=2 -    printf("count %d root %d loc %d\n",count,i,k); +    fprintf(stderr, "count %d root %d loc %d\n",count,i,k);  #endif      root[count] = i;      loc[count] = k; @@ -279,7 +279,7 @@      }  #if DEBUG >= 1      if (den == 0) { -      printf("\n ERROR: denominator = 0\n"); +      fprintf(stderr, "\n ERROR: denominator = 0\n");        count = -1;        goto finish;      } diff --git a/src/fig0_0.cpp b/src/fig0_0.cpp index b643185..96724f1 100644 --- a/src/fig0_0.cpp +++ b/src/fig0_0.cpp @@ -42,11 +42,11 @@ fig_result_t fig0_0(fig0_common_t& fig0, const display_settings_t &disp)      }      const uint8_t cid  = (f[1] & 0xF0) >> 4; -    r.msgs.emplace_back(1, strprintf("Country ID=%d", cid)); +    r.msgs.emplace_back(strprintf("Country ID=%d", cid));      const uint16_t eref = (f[1] & 0x0F)*256 + \                             f[2]; -    r.msgs.emplace_back(1, strprintf("Ensemble reference=%d", eref)); +    r.msgs.emplace_back(strprintf("Ensemble reference=%d", eref));      const uint8_t ch = (f[3] & 0xC0) >> 6;      r.msgs.push_back(strprintf("Change flag=%d", ch)); diff --git a/src/fig0_1.cpp b/src/fig0_1.cpp index d878677..c812b46 100644 --- a/src/fig0_1.cpp +++ b/src/fig0_1.cpp @@ -71,6 +71,8 @@ fig_result_t fig0_1(fig0_common_t& fig0, const display_settings_t &disp)                  ensemble_database::subchannel_t::protection_type_t::UEP;          } +        r.msgs.emplace_back("-"); +          if (long_flag) {              int option = (f[i+2] >> 4) & 0x07;              int protection_level = (f[i+2] >> 2) & 0x03; @@ -78,22 +80,22 @@ fig_result_t fig0_1(fig0_common_t& fig0, const display_settings_t &disp)                                       f[i+3];              i += 4; -            r.msgs.push_back(strprintf("Subch 0x%x", subch_id)); -            r.msgs.push_back(strprintf("start_addr %d", start_addr)); -            r.msgs.emplace_back("long"); +            r.msgs.emplace_back(1, strprintf("Subch=0x%x", subch_id)); +            r.msgs.emplace_back(1, strprintf("start_addr=%d", start_addr)); +            r.msgs.emplace_back(1, "form=long");              if (option == 0x00) { -                r.msgs.push_back(strprintf("EEP %d-A", protection_level+1)); +                r.msgs.emplace_back(1, strprintf("EEP=%d-A", protection_level+1));              }              else if (option == 0x01) { -                r.msgs.push_back(strprintf("EEP %d-B", protection_level+1)); +                r.msgs.emplace_back(1, strprintf("EEP=%d-B", protection_level+1));              }              else { -                r.errors.push_back(strprintf("Invalid option %d protection %d", +                r.errors.emplace_back(strprintf("Invalid option %d protection %d",                              option, protection_level));              } -            r.msgs.push_back(strprintf("subch size %d", subchannel_size)); +            r.msgs.emplace_back(1, strprintf("subch size=%d", subchannel_size));              if (fig0.fibcrccorrect) {                  auto& subch = fig0.ensemble.get_subchannel(subch_id); @@ -113,13 +115,13 @@ fig_result_t fig0_1(fig0_common_t& fig0, const display_settings_t &disp)              int table_switch = (f[i+2] >> 6) & 0x01;              uint32_t table_index  = (f[i+2] & 0x3F); -            r.msgs.push_back(strprintf("Subch 0x%x", subch_id)); -            r.msgs.push_back(strprintf("start_addr %d", start_addr)); -            r.msgs.emplace_back("short"); +            r.msgs.emplace_back(1, strprintf("Subch=0x%x", subch_id)); +            r.msgs.emplace_back(1, strprintf("start_addr=%d", start_addr)); +            r.msgs.emplace_back(1, "form=short");              if (table_switch != 0) { -                r.errors.push_back(strprintf("Invalid table_switch %d", table_switch)); +                r.errors.emplace_back(strprintf("Invalid table_switch %d", table_switch));              } -            r.msgs.push_back(strprintf("table index %d", table_index)); +            r.msgs.emplace_back(1, strprintf("table index=%d", table_index));              if (fig0.fibcrccorrect) {                  auto& subch = fig0.ensemble.get_subchannel(subch_id); diff --git a/src/fig0_10.cpp b/src/fig0_10.cpp index b4af859..1b0158b 100644 --- a/src/fig0_10.cpp +++ b/src/fig0_10.cpp @@ -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 @@ -59,19 +59,19 @@ fig_result_t fig0_10(fig0_common_t& fig0, const display_settings_t &disp)          uint8_t seconds = f[5] >> 2;          uint16_t milliseconds = ((uint16_t)(f[5] & 0x3) << 8) | f[6]; -        r.msgs.emplace_back("long form"); +        r.msgs.emplace_back("form=long");          r.msgs.push_back(strprintf("MJD=0x%X %s", MJD, dateStr)); -        r.msgs.push_back(strprintf("LSI %u", LSI)); -        r.msgs.push_back(strprintf("ConfInd %u", ConfInd)); -        r.msgs.push_back(strprintf("UTC Time: %02d:%02d:%02d.%d", +        r.msgs.push_back(strprintf("LSI=%u", LSI)); +        r.msgs.push_back(strprintf("ConfInd=%u", ConfInd)); +        r.msgs.push_back(strprintf("UTC Time=%02d:%02d:%02d.%d",                      hours, minutes, seconds, milliseconds));      }      else { -        r.msgs.emplace_back("short form"); +        r.msgs.emplace_back("form=short");          r.msgs.push_back(strprintf("MJD=0x%X %s", MJD, dateStr)); -        r.msgs.push_back(strprintf("LSI %u", LSI)); -        r.msgs.push_back(strprintf("ConfInd %u", ConfInd)); -        r.msgs.push_back(strprintf("UTC Time: %02d:%02d", hours, minutes)); +        r.msgs.push_back(strprintf("LSI=%u", LSI)); +        r.msgs.push_back(strprintf("ConfInd=%u", ConfInd)); +        r.msgs.push_back(strprintf("UTC Time=%02d:%02d", hours, minutes));      }      r.complete = true; diff --git a/src/fig0_11.cpp b/src/fig0_11.cpp index f019fa3..196dd37 100644 --- a/src/fig0_11.cpp +++ b/src/fig0_11.cpp @@ -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 @@ -71,14 +71,15 @@ fig_result_t fig0_11(fig0_common_t& fig0, const display_settings_t &disp)          key = ((uint16_t)fig0.oe() << 12) | ((uint16_t)fig0.pd() << 11) | Region_Id;          i += 2; +        r.msgs.emplace_back("-");          if (GATy == 0) {              // TII list -            r.msgs.push_back(strprintf("GATy=%d", GATy)); -            r.msgs.emplace_back("Geographical area defined by a TII list"); -            r.msgs.push_back(strprintf("G/E flag=%d %s coverage area", +            r.msgs.emplace_back(1, strprintf("GATy=%d", GATy)); +            r.msgs.emplace_back(1, "Geographical area=defined by TII list"); +            r.msgs.emplace_back(1, strprintf("G/E flag=%d %s coverage area",                          GE_flag, GE_flag ? "Global" : "Ensemble")); -            r.msgs.push_back(strprintf("RegionId=0x%X", Region_Id)); -            r.msgs.push_back(strprintf("database key=0x%X", key)); +            r.msgs.emplace_back(1, strprintf("RegionId=0x%X", Region_Id)); +            r.msgs.emplace_back(1, strprintf("database key=0x%X", key));              if (i < fig0.figlen) {                  Rfu = f[i] >> 5; @@ -86,9 +87,9 @@ fig_result_t fig0_11(fig0_common_t& fig0, const display_settings_t &disp)                      r.errors.push_back(strprintf("Rfu=%d invalid value", Rfu));                  }                  Length_TII_list = f[i] & 0x1F; -                r.msgs.push_back(strprintf(", Length of TII list=%d", Length_TII_list)); +                r.msgs.emplace_back(1, strprintf("Length of TII list=%d", Length_TII_list));                  if (Length_TII_list == 0) { -                    r.msgs.emplace_back("CEI"); +                    r.msgs.emplace_back("CEI=true");                  }                  i++; @@ -158,27 +159,27 @@ fig_result_t fig0_11(fig0_common_t& fig0, const display_settings_t &disp)          }          else if (GATy == 1) {              // Coordinates -            r.msgs.push_back(strprintf("GATy=%d", GATy)); -            r.msgs.emplace_back("Geographical area defined as a spherical rectangle " +            r.msgs.emplace_back(1, strprintf("GATy=%d", GATy)); +            r.msgs.emplace_back(1, "Geographical area=defined as a spherical rectangle "                      "by the geographical co-ordinates of one corner and its latitude and "                      "longitude extents"); -            r.msgs.push_back(strprintf("G/E flag=%d %s coverage area", +            r.msgs.emplace_back(1, strprintf("G/E flag=%d %s coverage area",                      GE_flag, GE_flag ? "Global" : "Ensemble")); -            r.msgs.push_back(strprintf("RegionId=0x%X", Region_Id)); -            r.msgs.push_back(strprintf("database key=0x%X", key)); +            r.msgs.emplace_back(1, strprintf("RegionId=0x%X", Region_Id)); +            r.msgs.emplace_back(1, strprintf("database key=0x%X", key));              if (i < (fig0.figlen - 6)) {                  Latitude_coarse = ((int16_t)f[i] << 8) | ((uint16_t)f[i+1]);                  Longitude_coarse = ((int16_t)f[i+2] << 8) | ((uint16_t)f[i+3]);                  gps_pos.latitude = ((double)Latitude_coarse) * 90 / 32768;                  gps_pos.longitude = ((double)Latitude_coarse) * 180 / 32768; -                r.msgs.push_back(strprintf("Lat Lng coarse=0x%X 0x%X => %f, %f", +                r.msgs.emplace_back(1, strprintf("Lat Lng coarse=0x%X 0x%X => %f, %f",                          Latitude_coarse, Longitude_coarse, gps_pos.latitude, gps_pos.longitude));                  Extent_Latitude = ((uint16_t)f[i+4] << 4) | ((uint16_t)(f[i+5] >> 4));                  Extent_Longitude = ((uint16_t)(f[i+5] & 0x0F) << 8) | ((uint16_t)f[i+6]);                  gps_pos.latitude += ((double)Extent_Latitude) * 90 / 32768;                  gps_pos.longitude += ((double)Extent_Longitude) * 180 / 32768; -                r.msgs.push_back(strprintf("Extent Lat Lng=0x%X 0x%X => %f, %f", +                r.msgs.emplace_back(1, strprintf("Extent Lat Lng=0x%X 0x%X => %f, %f",                          Extent_Latitude, Extent_Longitude, gps_pos.latitude, gps_pos.longitude));              }              else { @@ -188,13 +189,13 @@ fig_result_t fig0_11(fig0_common_t& fig0, const display_settings_t &disp)          }          else {              // Rfu -            r.msgs.push_back(strprintf("GATy=%d", GATy)); -            r.msgs.emplace_back("reserved for future use of the geographical"); -            r.msgs.push_back(strprintf("G/E flag=%d %s coverage area", +            r.msgs.emplace_back(1, strprintf("GATy=%d", GATy)); +            r.msgs.emplace_back(1, "Geographical area=reserved for future use"); +            r.msgs.emplace_back(1, strprintf("G/E flag=%d %s coverage area",                          GE_flag, GE_flag ? "Global" : "Ensemble")); -            r.msgs.push_back(strprintf("RegionId=0x%X", Region_Id)); -            r.msgs.push_back(strprintf("database key=0x%X", key)); -            r.msgs.push_back(strprintf("stop Region definition iteration %d/%d", +            r.msgs.emplace_back(1, strprintf("RegionId=0x%X", Region_Id)); +            r.msgs.emplace_back(1, strprintf("database key=0x%X", key)); +            r.msgs.emplace_back(1, strprintf("stop Region definition iteration %d/%d",                       i, fig0.figlen));              // stop Region definition iteration              i = fig0.figlen; diff --git a/src/fig0_13.cpp b/src/fig0_13.cpp index ca8880f..f79e96a 100644 --- a/src/fig0_13.cpp +++ b/src/fig0_13.cpp @@ -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 @@ -108,20 +108,21 @@ fig_result_t fig0_13(fig0_common_t& fig0, const display_settings_t &disp)      complete |= fig0_13_is_complete(SId, SCIdS); -    r.msgs.push_back(strprintf("SId=0x%X", SId)); -    r.msgs.push_back(strprintf("SCIdS=%u", SCIdS)); -    r.msgs.push_back(strprintf("No=%u", No)); +    r.msgs.emplace_back(strprintf("SId=0x%X", SId)); +    r.msgs.emplace_back(strprintf("SCIdS=%u", SCIdS)); +    r.msgs.emplace_back("User applications:");      for (int numapp = 0; numapp < No; numapp++) {          uint16_t user_app_type = ((f[k] << 8) |                  (f[k+1] & 0xE0)) >> 5;          uint8_t  user_app_len  = f[k+1] & 0x1F;          k+=2; -        r.msgs.emplace_back(1, strprintf("User Application %d '%s'; length %u", +        r.msgs.emplace_back(1, "-"); +        r.msgs.emplace_back(2, strprintf("User Application=%d '%s'",                  user_app_type, -                get_fig_0_13_userapp(user_app_type).c_str(), -                user_app_len)); +                get_fig_0_13_userapp(user_app_type).c_str())); +        r.msgs.emplace_back(2, strprintf("length=%u", user_app_len));      }      r.complete = complete; diff --git a/src/fig0_14.cpp b/src/fig0_14.cpp index 65b5797..de32820 100644 --- a/src/fig0_14.cpp +++ b/src/fig0_14.cpp @@ -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 @@ -69,7 +69,8 @@ fig_result_t fig0_14(fig0_common_t& fig0, const display_settings_t &disp)          SubChId = f[i] >> 2;          r.complete |= fig0_14_is_complete(SubChId);          FEC_scheme = f[i] & 0x3; -        r.msgs.push_back(strprintf("SubChId=0x%X", SubChId)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SubChId=0x%X", SubChId));          r.msgs.emplace_back(1, strprintf("FEC scheme=%d %s",                  FEC_scheme, FEC_schemes_str[FEC_scheme]));          i++; diff --git a/src/fig0_16.cpp b/src/fig0_16.cpp index bff2a01..0f47533 100644 --- a/src/fig0_16.cpp +++ b/src/fig0_16.cpp @@ -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 @@ -72,8 +72,9 @@ fig_result_t fig0_16(fig0_common_t& fig0, const display_settings_t &disp)          Continuation_flag = (f[i+4] >> 1) & 0x01;          Update_flag = f[i+4] & 0x01; -        r.msgs.push_back(strprintf("SId=0x%X", SId)); -        r.msgs.push_back(strprintf("PNum=0x%X ", PNum) + pnum_to_str(PNum)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back(1, strprintf("PNum=0x%X ", PNum) + pnum_to_str(PNum));          if (Rfa != 0) {              r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa)); @@ -83,10 +84,10 @@ fig_result_t fig0_16(fig0_common_t& fig0, const display_settings_t &disp)              r.errors.push_back(strprintf(", Rfu=0x%X invalid value", Rfu));          } -        r.msgs.push_back(strprintf("Continuation flag=%d: the programme will %s", +        r.msgs.emplace_back(1, strprintf("Continuation flag=%d, the programme will %s",                  Continuation_flag,                  Continuation_flag ? "be interrupted but continued later" : "not be subject to a planned interruption")); -        r.msgs.push_back(strprintf("Update flag=%d %sre-direction", +        r.msgs.emplace_back(1, strprintf("Update flag=%d %sre-direction",                  Update_flag, Update_flag ? "" : "no "));          i += 5; @@ -94,10 +95,10 @@ fig_result_t fig0_16(fig0_common_t& fig0, const display_settings_t &disp)              // In the case of a re-direction, the New SId and New PNum shall be appended              if (i < (fig0.figlen - 1)) {                  New_SId = ((uint16_t)f[i] << 8) | ((uint16_t)f[i+1]); -                r.msgs.push_back(strprintf("New SId=0x%X", New_SId)); +                r.msgs.emplace_back(1, strprintf("New SId=0x%X", New_SId));                  if (i < (fig0.figlen - 3)) {                      New_PNum = ((uint16_t)f[i+2] << 8) | ((uint16_t)f[i+3]); -                    r.msgs.push_back(strprintf("New PNum=0x%X ", New_PNum) + pnum_to_str(New_PNum)); +                    r.msgs.emplace_back(1, strprintf("New PNum=0x%X ", New_PNum) + pnum_to_str(New_PNum));                  }                  else {                      r.errors.push_back("missing New PNum !"); diff --git a/src/fig0_17.cpp b/src/fig0_17.cpp index 8eb2ba9..247e79e 100644 --- a/src/fig0_17.cpp +++ b/src/fig0_17.cpp @@ -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 @@ -65,15 +65,16 @@ fig_result_t fig0_17(fig0_common_t& fig0, const display_settings_t &disp)          L_flag = ((f[i+2] >> 5) & 0x01);          CC_flag = ((f[i+2] >> 4) & 0x01);          Rfa = (f[i+2] & 0x0F); -        r.msgs.push_back(strprintf("SId=0x%X", SId)); -        r.msgs.push_back(strprintf( +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back(1, strprintf(                      "S/D=%d Programme Type codes and language (when present), %srepresent the current programme contents",                      SD_flag, SD_flag?"":"may not ")); -        r.msgs.push_back(strprintf("P/S=%d %s service component", +        r.msgs.emplace_back(1, strprintf("P/S=%d %s service component",                      PS_flag, PS_flag?"secondary":"primary")); -        r.msgs.push_back(strprintf("L flag=%d language field %s", +        r.msgs.emplace_back(1, strprintf("L flag=%d language field %s",                  L_flag, L_flag?"present":"absent")); -        r.msgs.push_back(strprintf("CC flag=%d complementary code and preceding Rfa and Rfu fields %s", +        r.msgs.emplace_back(1, strprintf("CC flag=%d complementary code and preceding Rfa and Rfu fields %s",                  CC_flag, CC_flag?"present":"absent"));          if (Rfa != 0) { @@ -84,7 +85,7 @@ fig_result_t fig0_17(fig0_common_t& fig0, const display_settings_t &disp)          if (L_flag != 0) {              if (i < fig0.figlen) {                  Language = f[i]; -                r.msgs.push_back(strprintf("Language=0x%X %s", Language, +                r.msgs.emplace_back(1, strprintf("Language=0x%X %s", Language,                          get_language_name(Language)));              }              else { @@ -103,7 +104,7 @@ fig_result_t fig0_17(fig0_common_t& fig0, const display_settings_t &disp)                  r.errors.push_back(strprintf("Rfu=%d invalid value", Rfu));              }              Int_code = f[i] & 0x1F; -            r.msgs.push_back(strprintf("Int code=0x%X %s", Int_code, +            r.msgs.emplace_back(1, strprintf("Int code=0x%X %s", Int_code,                          get_programme_type(get_international_table(), Int_code)));              i++;          } @@ -122,7 +123,7 @@ fig_result_t fig0_17(fig0_common_t& fig0, const display_settings_t &disp)                      r.errors.push_back(strprintf("Rfu=%d invalid value", Rfu));                  }                  Comp_code = f[i] & 0x1F; -                r.msgs.push_back(strprintf("Comp code=0x%X %s", Comp_code, +                r.msgs.emplace_back(1, strprintf("Comp code=0x%X %s", Comp_code,                              get_programme_type(get_international_table(), Comp_code)));                  i++;              } diff --git a/src/fig0_18.cpp b/src/fig0_18.cpp index cc82bec..ecbf7ba 100644 --- a/src/fig0_18.cpp +++ b/src/fig0_18.cpp @@ -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 @@ -65,34 +65,42 @@ fig_result_t fig0_18(fig0_common_t& fig0, const display_settings_t &disp)          Asu_flags = ((uint16_t)f[i+2] << 8) | (uint16_t)f[i+3];          Rfa = (f[i+4] >> 5);          Number_clusters = (f[i+4] & 0x1F); -        r.msgs.push_back(strprintf("SId=0x%X", SId)); -        r.msgs.push_back(strprintf("Asu flags=0x%04x", Asu_flags)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back(1, strprintf("Asu flags=0x%04x", Asu_flags));          if (Rfa != 0) {              r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa));          } -        r.msgs.push_back(strprintf("Number of clusters=%d", Number_clusters)); +        r.msgs.emplace_back(1, strprintf("Number of clusters=%d", Number_clusters));          key = ((uint32_t)fig0.oe() << 17) | ((uint32_t)fig0.pd() << 16) | (uint32_t)SId; -        r.msgs.push_back(strprintf("database key=0x%05x", key)); +        r.msgs.emplace_back(1, strprintf("database key=0x%05x", key));          // CEI Change Event Indication          if ((Number_clusters == 0) && (Asu_flags == 0)) { -            r.msgs.emplace_back("CEI"); +            r.msgs.emplace_back("CEI=true");          }          i += 5; +        std::stringstream clusters_ss;          for(j = 0; (j < Number_clusters) && (i < fig0.figlen); j++) {              // iterate over Cluster Id -            r.msgs.emplace_back(1, strprintf("Cluster Id=0x%X", f[i])); +            if (j > 0) { +                clusters_ss << ", "; +            } +            clusters_ss << strprintf("0x%X", f[i]);              i++;          } +        r.msgs.emplace_back(1, "Cluster Ids: [" + clusters_ss.str() + "]"); +          if (j < Number_clusters) {              r.errors.push_back("missing Cluster Id, fig length too short !");          } +        r.msgs.emplace_back(1, "Announcements:");          // decode announcement support types          for (j = 0; j < 16; j++) {              if (Asu_flags & (1 << j)) { -                r.msgs.emplace_back(1, strprintf("Announcement support=%s", get_announcement_type(j))); +                r.msgs.emplace_back(2, strprintf("- %s", get_announcement_type(j)));              }          }      } diff --git a/src/fig0_19.cpp b/src/fig0_19.cpp index 5fef324..0e6c25e 100644 --- a/src/fig0_19.cpp +++ b/src/fig0_19.cpp @@ -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 @@ -66,11 +66,12 @@ fig_result_t fig0_19(fig0_common_t& fig0, const display_settings_t &disp)          New_flag = (f[i+3] >> 7);          Region_flag = (f[i+3] >> 6) & 0x1;          SubChId = (f[i+3] & 0x3F); -        r.msgs.push_back(strprintf("Cluster Id=0x%02x", Cluster_Id)); -        r.msgs.push_back(strprintf("Asw flags=0x%04x", Asw_flags)); -        r.msgs.push_back(strprintf("New flag=%d %s", New_flag, (New_flag)?"new":"repeat")); -        r.msgs.push_back(strprintf("Region flag=%d last byte %s", Region_flag, (Region_flag)?"present":"absent")); -        r.msgs.push_back(strprintf("SubChId=%d", SubChId)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("Cluster Id=0x%02x", Cluster_Id)); +        r.msgs.emplace_back(1, strprintf("Asw flags=0x%04x", Asw_flags)); +        r.msgs.emplace_back(1, strprintf("New flag=%d %s", New_flag, (New_flag)?"new":"repeat")); +        r.msgs.emplace_back(1, strprintf("Region flag=%d last byte %s", Region_flag, (Region_flag)?"present":"absent")); +        r.msgs.emplace_back(1, strprintf("SubChId=%d", SubChId));          if (Region_flag) {              if (i < (fig0.figlen - 4)) {                  // read region lower part @@ -79,16 +80,17 @@ fig_result_t fig0_19(fig0_common_t& fig0, const display_settings_t &disp)                  if (Rfa != 0) {                      r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa));                  } -                r.msgs.push_back(strprintf("Region Lower Part=0x%02x", RegionId_LP)); +                r.msgs.emplace_back(1, strprintf("Region Lower Part=0x%02x", RegionId_LP));              }              else {                  r.errors.push_back("missing Region Lower Part, fig length too short !");              }          }          // decode announcement switching types +        r.msgs.emplace_back(1, strprintf("Announcement switching:"));          for(j = 0; j < 16; j++) {              if (Asw_flags & (1 << j)) { -                r.msgs.emplace_back(1, strprintf("Announcement switching=%s", get_announcement_type(j))); +                r.msgs.emplace_back(2, strprintf("- %s", get_announcement_type(j)));              }          }          i += (4 + Region_flag); diff --git a/src/fig0_2.cpp b/src/fig0_2.cpp index 48e9adf..eec0eb4 100644 --- a/src/fig0_2.cpp +++ b/src/fig0_2.cpp @@ -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 @@ -53,7 +53,6 @@ fig_result_t fig0_2(fig0_common_t& fig0, const display_settings_t &disp)      uint16_t sref, sid;      uint8_t cid, ecc, local, caid, ncomp, timd, ps, ca, subchid, scty;      int k = 1; -    std::string psdesc;      uint8_t* f = fig0.f;      fig_result_t r; @@ -86,20 +85,16 @@ fig_result_t fig0_2(fig0_common_t& fig0, const display_settings_t &disp)          caid  = (f[k] & 0x70) >> 4;          ncomp =  f[k] & 0x0F; -        if (fig0.pd() == 0) { -            r.msgs.push_back(strprintf("Service ID=0x%X (Country id=%d, Service reference=%d)", -                        sid, cid, sref)); -            r.msgs.emplace_back(1, strprintf("Number of components=%d", ncomp)); -            r.msgs.emplace_back(1, strprintf("Local flag=%d", local)); -            r.msgs.emplace_back(1, strprintf("CAID=%d", caid)); -        } -        else { -            r.msgs.push_back(strprintf("Service ID=0x%X (ECC=%d, Country id=%d, Service reference=%d)", -                        sid, ecc, cid, sref)); -            r.msgs.emplace_back(1, strprintf("Number of components=%d", ncomp)); -            r.msgs.emplace_back(1, strprintf("Local flag=%d", local)); -            r.msgs.emplace_back(1, strprintf("CAID=%d", caid)); +        r.msgs.emplace_back(0, "-"); +        r.msgs.emplace_back(1, strprintf("Service ID=0x%X", sid)); +        if (fig0.pd() != 0) { +            r.msgs.emplace_back(1, strprintf("ECC=%d", ecc));          } +        r.msgs.emplace_back(1, strprintf("Country id=%d", cid)); +        r.msgs.emplace_back(1, strprintf("Service reference=%d", sref)); +        r.msgs.emplace_back(1, strprintf("Number of components=%d", ncomp)); +        r.msgs.emplace_back(1, strprintf("Local flag=%d", local)); +        r.msgs.emplace_back(1, strprintf("CAID=%d", caid));          if (fig0.fibcrccorrect) {              auto& service = fig0.ensemble.get_or_create_service(sid); @@ -108,11 +103,13 @@ fig_result_t fig0_2(fig0_common_t& fig0, const display_settings_t &disp)          k++; +        r.msgs.emplace_back(1, "Components:");          for (int i = 0; i < ncomp; i++) {              uint8_t scomp[2];              memcpy(scomp, f+k, 2); -            r.msgs.emplace_back(1, strprintf("Component[%d]", i)); +            r.msgs.emplace_back(2, "-"); +            r.msgs.emplace_back(3, strprintf("ID=%d", i));              timd    = (scomp[0] & 0xC0) >> 6;              ps      = (scomp[1] & 0x02) >> 1; @@ -128,10 +125,10 @@ fig_result_t fig0_2(fig0_common_t& fig0, const display_settings_t &disp)                 */              if (ps == 0) { -                psdesc = "Secondary service"; +                r.msgs.emplace_back(3, "primary=true");              }              else { -                psdesc = "Primary service"; +                r.msgs.emplace_back(3, "primary=false");              }              if (fig0.fibcrccorrect) { @@ -144,45 +141,41 @@ fig_result_t fig0_2(fig0_common_t& fig0, const display_settings_t &disp)              if (timd == 0) {                  //MSC stream audio -                r.msgs.emplace_back(2, "Stream audio mode"); -                r.msgs.emplace_back(2, psdesc); +                r.msgs.emplace_back(3, "Mode=audio stream");                  if (scty == 0) -                    r.msgs.emplace_back(2, strprintf("MPEG Foreground sound (%d)", scty)); +                    r.msgs.emplace_back(3, strprintf("ASCTy=MPEG Foreground sound (%d)", scty));                  else if (scty == 1) -                    r.msgs.emplace_back(2, strprintf("MPEG Background sound (%d)", scty)); +                    r.msgs.emplace_back(3, strprintf("ASCTy=MPEG Background sound (%d)", scty));                  else if (scty == 2) -                    r.msgs.emplace_back(2, strprintf("Multi Channel sound (%d)", scty)); +                    r.msgs.emplace_back(3, strprintf("ASCTy=Multi Channel sound (%d)", scty));                  else if (scty == 63) -                    r.msgs.emplace_back(2, strprintf("AAC sound (%d)", scty)); +                    r.msgs.emplace_back(3, strprintf("ASCTy=AAC sound (%d)", scty));                  else -                    r.msgs.emplace_back(2, strprintf("Unknown ASCTy (%d)", scty)); +                    r.msgs.emplace_back(3, strprintf("ASCTy=Unknown ASCTy (%d)", scty)); -                r.msgs.emplace_back(2, strprintf("SubChannel ID=%02X", subchid)); -                r.msgs.emplace_back(2, strprintf("CA=%d", ca)); +                r.msgs.emplace_back(3, strprintf("SubChannel ID=%02X", subchid)); +                r.msgs.emplace_back(3, strprintf("CA=%d", ca));              }              else if (timd == 1) {                  // MSC stream data -                r.msgs.emplace_back(2, "Stream data mode"); -                r.msgs.emplace_back(2, psdesc); -                r.msgs.emplace_back(2, strprintf("DSCTy=%d %s", scty, get_dscty_type(scty))); -                r.msgs.emplace_back(2, strprintf("SubChannel ID=%02X", subchid)); -                r.msgs.emplace_back(2, strprintf("CA=%d", ca)); +                r.msgs.emplace_back(3, "Mode=data stream"); +                r.msgs.emplace_back(3, strprintf("DSCTy=%d %s", scty, get_dscty_type(scty))); +                r.msgs.emplace_back(3, strprintf("SubChannel ID=%02X", subchid)); +                r.msgs.emplace_back(3, strprintf("CA=%d", ca));              }              else if (timd == 2) {                  // FIDC -                r.msgs.emplace_back(2, "FIDC mode"); -                r.msgs.emplace_back(2, psdesc); -                r.msgs.emplace_back(2, strprintf("DSCTy=%d %s", scty, get_dscty_type(scty))); -                r.msgs.emplace_back(2, strprintf("Fast Information Data Channel ID=%02X", subchid)); -                r.msgs.emplace_back(2, strprintf("CA=%d", ca)); +                r.msgs.emplace_back(3, "Mode=FIDC"); +                r.msgs.emplace_back(3, strprintf("DSCTy=%d %s", scty, get_dscty_type(scty))); +                r.msgs.emplace_back(3, strprintf("Fast Information Data Channel ID=%02X", subchid)); +                r.msgs.emplace_back(3, strprintf("CA=%d", ca));              }              else if (timd == 3) {                  // MSC Packet mode -                r.msgs.emplace_back(2, "MSC Packet Mode"); -                r.msgs.emplace_back(2, psdesc); -                r.msgs.emplace_back(2, strprintf("SubChannel ID=%02X", subchid)); -                r.msgs.emplace_back(2, strprintf("CA=%d", ca)); +                r.msgs.emplace_back(3, "Mode=MSC Packet"); +                r.msgs.emplace_back(3, strprintf("SubChannel ID=%02X", subchid)); +                r.msgs.emplace_back(3, strprintf("CA=%d", ca));              }              k += 2; diff --git a/src/fig0_21.cpp b/src/fig0_21.cpp index 648e50c..71c8ce5 100644 --- a/src/fig0_21.cpp +++ b/src/fig0_21.cpp @@ -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 @@ -59,11 +59,13 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)          const uint16_t RegionId = (f[i] << 3) | (f[i+1] >> 5);          r.complete |= fig0_21_is_complete(RegionId);          const uint8_t Length_FI_list = f[i+1] & 0x1F; // in bytes -        r.msgs.push_back(strprintf("RegionId=0x%03x", RegionId)); -        r.msgs.push_back(strprintf("Len=%d Bytes", Length_FI_list)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("RegionId=0x%03x", RegionId)); +        r.msgs.emplace_back(1, strprintf("Len=%d Bytes", Length_FI_list));          i += 2;          const int FI_start_ix = i; +        r.msgs.emplace_back(1, "FIs:");          for (size_t FI_ix = 0; i < FI_start_ix + Length_FI_list; FI_ix++) {              if (i + 3 > fig0.figlen) {                  r.errors.push_back("FIG0/21 too small!"); @@ -74,8 +76,8 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)              const uint8_t RandM = f[i+2] >> 4;              const bool Continuity_flag = (f[i+2] >> 3) & 0x01;              const uint8_t Length_Freq_list = f[i+2] & 0x07; // in bytes -            r.msgs.emplace_back(1, -                    strprintf("Length Freq list=%d", Length_Freq_list)); +            r.msgs.emplace_back(2, "-"); +            r.msgs.emplace_back(3, strprintf("Length Freq list=%d", Length_Freq_list));              i += 3;              std::string idfield; @@ -93,7 +95,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                            r.errors.emplace_back("R&M invalid");                            break;              } -            r.msgs.emplace_back(1, +            r.msgs.emplace_back(3,                      strprintf("ID field=0x%X ", Id_field) + idfield);              std::string rm_str; @@ -110,7 +112,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                            r.errors.emplace_back("R&M is Rfu");                            break;              } -            r.msgs.emplace_back(1, +            r.msgs.emplace_back(3,                      strprintf("R&M=0x%1x ", RandM) + rm_str);              std::string continuity_str; @@ -120,22 +122,22 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                      switch (RandM) {                          case 0x0:                          case 0x1: -                            continuity_str = "=continuous output not expected"; +                            continuity_str = ", continuous output not expected";                              break;                          case 0x6: -                            continuity_str = "=no compensating time delay on DRM audio signal"; +                            continuity_str = ", no compensating time delay on DRM audio signal";                              break;                          case 0x8:                          case 0x9: -                            continuity_str = "=no compensating time delay on FM audio signal"; +                            continuity_str = ", no compensating time delay on FM audio signal";                              break;                          case 0xa:                          case 0xc:                          case 0xe: -                            continuity_str = "=no compensating time delay on AM audio signal"; +                            continuity_str = ", no compensating time delay on AM audio signal";                              break;                          default: -                            continuity_str = "=Rfu"; +                            continuity_str = ", Rfu";                              break;                      }                  } @@ -143,32 +145,32 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                      switch (RandM) {                          case 0x0:                          case 0x1: -                            continuity_str = "=continuous output possible"; +                            continuity_str = ", continuous output possible";                              break;                          case 0x6: -                            continuity_str = "=compensating time delay on DRM audio signal"; +                            continuity_str = ", compensating time delay on DRM audio signal";                              break;                          case 0x8:                          case 0x9: -                            continuity_str = "=compensating time delay on FM audio signal"; +                            continuity_str = ", compensating time delay on FM audio signal";                              break;                          case 0xa:                          case 0xc:                          case 0xe: -                            continuity_str = "=compensating time delay on AM audio signal"; +                            continuity_str = ", compensating time delay on AM audio signal";                              break;                          default: -                            continuity_str = "=Rfu"; +                            continuity_str = ", Rfu";                              break;                      }                  }              }              else {  // fig0.oe() == 1 -                continuity_str = "=reserved for future addition"; +                continuity_str = ", reserved for future addition";                  r.errors.emplace_back("Rfu");              } -            r.msgs.emplace_back(1, +            r.msgs.emplace_back(3,                      strprintf("Continuity flag=%d ", Continuity_flag) +                      continuity_str); @@ -176,14 +178,15 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                  ((uint64_t)fig0.oe() << 32) | ((uint64_t)fig0.pd() << 31) |                  ((uint64_t)RegionId << 20) | ((uint64_t)Id_field << 4) |                  (uint64_t)RandM; -            r.msgs.emplace_back(1, +            r.msgs.emplace_back(3,                      strprintf("database key=0x%09" PRId64, key));              // CEI Change Event Indication              if (Length_Freq_list == 0) { -                r.msgs.emplace_back(1, "CEI"); +                r.msgs.emplace_back(3, "CEI=true");              } +            r.msgs.emplace_back(3, "Frequency Information:");              // Iterate over the frequency infos              switch (RandM) {                  case 0x0: @@ -198,6 +201,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                          }                          for (int freq_ix = 0; freq_ix < num_freqs; freq_ix++) { +                            r.msgs.emplace_back(4, "-");                              if (i + bytes_per_entry > fig0.figlen) {                                  r.errors.push_back(strprintf(                                              "FIG 0/21 too small for" @@ -221,33 +225,33 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                              }                              const uint8_t Control_field_trans_mode = (Control_field >> 1) & 0x07;                              if ((Control_field & 0x10) == 0) { -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("%d KHz", freq));                                  if ((Control_field & 0x01) == 0) { -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              "geographically adjacent area");                                  }                                  else {  // (Control_field & 0x01) == 1 -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              "no geographically adjacent area");                                  }                                  if (Control_field_trans_mode == 0) { -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              "no transmission mode signalled");                                  }                                  else if (Control_field_trans_mode <= 4) { -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              strprintf("transmission mode %d",                                                  Control_field_trans_mode));                                  }                                  else {  // Control_field_trans_mode > 4 -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              strprintf("invalid transmission mode 0x%x",                                                  Control_field_trans_mode));                                  }                              }                              else {  // (Control_field & 0x10) == 0x10 -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("%d KHz,"                                              "invalid Control field b23 0x%x",                                              freq, Control_field)); @@ -264,6 +268,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                          const int num_freqs = Length_Freq_list / bytes_per_entry;                          for (int freq_ix = 0; freq_ix < num_freqs; freq_ix++) { +                            r.msgs.emplace_back(4, "-");                              if (i + bytes_per_entry > fig0.figlen) {                                  r.errors.push_back(strprintf(                                              "FIG 0/21 too small for" @@ -281,18 +286,18 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                              if (RandM == 0xA) {                                  if (freq < 16) { -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              strprintf("%d KHz",                                                  144 + ((uint32_t)freq * 9)));                                  }                                  else {  // f[k] >= 16 -                                    r.msgs.emplace_back(2, +                                    r.msgs.emplace_back(5,                                              strprintf("%d KHz",                                                  387 + ((uint32_t)freq * 9)));                                  }                              }                              else {  // RandM == 8 or 9 -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("%.1f MHz",                                              87.5 + ((float)freq * 0.1)));                              } @@ -308,7 +313,9 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                          if (Length_Freq_list % bytes_per_entry != 0) {                              r.errors.push_back("Length of freq list incorrect size");                          } +                          for (int freq_ix = 0; freq_ix < num_freqs; freq_ix++) { +                            r.msgs.emplace_back(4, "-");                              if (i + bytes_per_entry > fig0.figlen) {                                  r.errors.push_back(strprintf(                                              "FIG 0/21 too small for" @@ -322,7 +329,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                                   (uint32_t)f[i+1]);                              i += bytes_per_entry;                              if (freq != 0) { -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("%d KHz", freq));                              }                              else { @@ -355,6 +362,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                          i++;                          for (int freq_ix = 0; freq_ix < num_freqs; freq_ix++) { +                            r.msgs.emplace_back(4, "-");                              if (i + bytes_per_entry > fig0.figlen) {                                  r.errors.push_back(strprintf(                                              "FIG 0/21 too small for" @@ -368,7 +376,7 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                              i += bytes_per_entry;                              if (freq != 0) { -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("%d KHz", freq));                              }                              else { @@ -378,11 +386,11 @@ fig_result_t fig0_21(fig0_common_t& fig0, const display_settings_t &disp)                              const uint32_t srv_id = (Id_field2 << 16) | Id_field;                              if (RandM == 0x6) { -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("DRM Service Id 0x%X", srv_id));                              }                              else if (RandM == 0xE) { -                                r.msgs.emplace_back(2, +                                r.msgs.emplace_back(5,                                          strprintf("AMSS Service Id 0x%X", srv_id));                              }                          } diff --git a/src/fig0_22.cpp b/src/fig0_22.cpp index ca9bb06..a76de31 100644 --- a/src/fig0_22.cpp +++ b/src/fig0_22.cpp @@ -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 @@ -79,9 +79,10 @@ fig_result_t fig0_22(fig0_common_t& fig0, const display_settings_t &disp)          MainId = f[i] & 0x7F;          r.complete |= fig0_22_is_complete(MS, MainId);          key = (fig0.oe() << 8) | (fig0.pd() << 7) | MainId; -        r.msgs.push_back(strprintf("M/S=%d %sidentifier", +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("M/S=%d %sidentifier",                      MS, MS?"Sub-":"Main ")); -        r.msgs.push_back(strprintf("MainId=0x%X", MainId)); +        r.msgs.emplace_back(1, strprintf("MainId=0x%X", MainId));          // check MainId value          if ((Mode_Identity == 1) || (Mode_Identity == 2) || (Mode_Identity == 4)) {              if (MainId > 69) { @@ -96,7 +97,7 @@ fig_result_t fig0_22(fig0_common_t& fig0, const display_settings_t &disp)              }          }          // print database key -        r.msgs.push_back(strprintf("database key=0x%X", key)); +        r.msgs.emplace_back(1, strprintf("database key=0x%X", key));          i++;          if (MS == 0) {              // Main identifier @@ -109,7 +110,7 @@ fig_result_t fig0_22(fig0_common_t& fig0, const display_settings_t &disp)                  gps_pos.latitude = (double)((int32_t)((((int32_t)Latitude_coarse) << 4) | (uint32_t)Latitude_fine)) * 90 / 524288;                  gps_pos.longitude = (double)((int32_t)((((int32_t)Longitude_coarse) << 4) | (uint32_t)Longitude_fine)) * 180 / 524288;                  fig0_22_key_Lat_Lng[key] = gps_pos; -                r.msgs.push_back(strprintf("Lat Lng coarse=0x%X 0x%X, Lat Lng fine=0x%X 0x%X => Lat Lng=%f, %f", +                r.msgs.emplace_back(1, strprintf("Lat Lng coarse=0x%X 0x%X, Lat Lng fine=0x%X 0x%X => Lat Lng=%f, %f",                          Latitude_coarse, Longitude_coarse, Latitude_fine, Longitude_fine,                          gps_pos.latitude, gps_pos.longitude));                  i += 5; @@ -127,14 +128,16 @@ fig_result_t fig0_22(fig0_common_t& fig0, const display_settings_t &disp)                  if (Rfu != 0) {                      r.errors.push_back(strprintf("Rfu=%d invalid value", Rfu));                  } -                r.msgs.push_back(strprintf("Number of SubId fields=%d%s", +                r.msgs.emplace_back(1, strprintf("Number of SubId fields=%d%s",                          Nb_SubId_fields, (Nb_SubId_fields == 0)?", CEI":""));                  i++; +                r.msgs.emplace_back(1, "SubId Fields:");                  for(j = i; ((j < (i + (Nb_SubId_fields * 6))) && (j < (fig0.figlen - 5))); j += 6) {                      // iterate over SubId fields                      SubId = f[j] >> 3; -                    r.msgs.emplace_back(1, strprintf("SubId=0x%X", SubId)); +                    r.msgs.emplace_back(2, "-"); +                    r.msgs.emplace_back(3, strprintf("SubId=0x%X", SubId));                      // check SubId value                      if ((SubId == 0) || (SubId > 23)) {                          r.errors.push_back("invalid value"); @@ -143,20 +146,20 @@ fig_result_t fig0_22(fig0_common_t& fig0, const display_settings_t &disp)                      TD = ((f[j] & 0x03) << 8) | f[j+1];                      Latitude_offset = (f[j+2] << 8) | f[j+3];                      Longitude_offset = (f[j+4] << 8) | f[j+5]; -                    r.msgs.emplace_back(1, strprintf("TD=%d us", TD)); -                    r.msgs.emplace_back(1, strprintf("Lat Lng offset=0x%X 0x%X", Latitude_offset, Longitude_offset)); +                    r.msgs.emplace_back(3, strprintf("TD=%d us", TD)); +                    r.msgs.emplace_back(3, strprintf("Lat Lng offset=0x%X 0x%X", Latitude_offset, Longitude_offset));                      if (fig0_22_key_Lat_Lng.count(key) > 0) {                          // latitude longitude available in database for Main Identifier                          latitude_sub = (90 * (double)Latitude_offset / 524288) + fig0_22_key_Lat_Lng[key].latitude;                          longitude_sub = (180 * (double)Longitude_offset / 524288) + fig0_22_key_Lat_Lng[key].longitude; -                        r.msgs.emplace_back(2, strprintf(" => Lat Lng=%f, %f", latitude_sub, longitude_sub)); +                        r.msgs.emplace_back(3, strprintf("Lat Lng=%f, %f", latitude_sub, longitude_sub));                      }                      else {                          // latitude longitude not available in database for Main Identifier                          latitude_sub = 90 * (double)Latitude_offset / 524288;                          longitude_sub = 180 * (double)Longitude_offset / 524288; -                        r.msgs.emplace_back(2, strprintf(" => Lat Lng=%f, %f wrong value because" +                        r.msgs.emplace_back(3, strprintf("Lat Lng=%f, %f wrong value because"                                      " Main identifier latitude/longitude not available in database", latitude_sub, longitude_sub));                      }                  } diff --git a/src/fig0_24.cpp b/src/fig0_24.cpp index 24548e5..690979d 100644 --- a/src/fig0_24.cpp +++ b/src/fig0_24.cpp @@ -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 @@ -76,11 +76,12 @@ fig_result_t fig0_24(fig0_common_t& fig0, const display_settings_t &disp)          key = ((uint64_t)fig0.oe() << 33) | ((uint64_t)fig0.pd() << 32) | \                (uint64_t)SId; -        r.msgs.push_back(strprintf("PD=%d", fig0.pd())); -        r.msgs.push_back(strprintf("SId=0x%X", SId)); -        r.msgs.push_back(strprintf("CAId=%d", CAId)); -        r.msgs.push_back(strprintf("Number of EId=%d", Number_of_EIds)); -        r.msgs.push_back(strprintf("database key=%09" PRId64, key)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("PD=%d", fig0.pd())); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back(1, strprintf("CAId=%d", CAId)); +        r.msgs.emplace_back(1, strprintf("Number of EId=%d", Number_of_EIds)); +        r.msgs.emplace_back(1, strprintf("database key=%09" PRId64, key));          if (Rfa != 0) {              r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa)); @@ -88,15 +89,21 @@ fig_result_t fig0_24(fig0_common_t& fig0, const display_settings_t &disp)          // CEI Change Event Indication          if (Number_of_EIds == 0) { -            r.msgs.emplace_back("CEI"); +            r.msgs.emplace_back("CEI=true");          }          i++; +        std::stringstream eid_ss;          for (j = i; ((j < (i + (Number_of_EIds * 2))) && (j < fig0.figlen)); j += 2) {              // iterate over EIds              EId = ((uint16_t)f[j] <<8) | (uint16_t)f[j+1]; -            r.msgs.emplace_back(1, strprintf("EId 0x%04x", EId)); +            if (j > i) { +                eid_ss << ", "; +            } +            eid_ss << strprintf("0x%04x", EId);          } +        r.msgs.emplace_back(1, "EIds: [" + eid_ss.str() + "]"); +          i += (Number_of_EIds * 2);      } diff --git a/src/fig0_25.cpp b/src/fig0_25.cpp index 9aa64c0..bf02d13 100644 --- a/src/fig0_25.cpp +++ b/src/fig0_25.cpp @@ -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 @@ -65,7 +65,8 @@ fig_result_t fig0_25(fig0_common_t& fig0, const display_settings_t &disp)          Asu_flags = ((uint16_t)f[i+2] << 8) | (uint16_t)f[i+3];          Rfu = (f[i+4] >> 4);          Number_EIds = (f[i+4] & 0x0F); -        r.msgs.push_back(strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId));          r.msgs.emplace_back(1, strprintf("Asu flags=0x%X", Asu_flags));          r.msgs.emplace_back(1, strprintf("Number of EIds=%d", Number_EIds)); @@ -78,26 +79,31 @@ fig_result_t fig0_25(fig0_common_t& fig0, const display_settings_t &disp)          // CEI Change Event Indication          if (Number_EIds == 0) { -            r.msgs.emplace_back(1, "CEI"); +            r.msgs.emplace_back(1, "CEI=true");          }          i += 5; +        std::stringstream eid_ss;          for (j = 0; j < Number_EIds && i < fig0.figlen - 1; j++) {              // iterate over EIds              EId = ((uint16_t)f[i] << 8) | (uint16_t)f[i+1]; -            r.msgs.emplace_back(2, strprintf("EId=0x%X", EId)); +            if (j > 0) { +                eid_ss << ", "; +            } +            eid_ss << strprintf("0x%04x", EId);              i += 2;          } +        r.msgs.emplace_back(1, "EIds: [" + eid_ss.str() + "]");          if (j < Number_EIds) {              r.errors.push_back("missing EId, fig length too short !");          } -        // decode fig0.oe() announcement support types +        r.msgs.emplace_back(1, "OE Announcement support:"); +        // decode OE announcement support types          for (j = 0; j < 16; j++) {              if (Asu_flags & (1 << j)) { -                r.msgs.emplace_back(2, -                        strprintf("fig0.oe() Announcement support=%s", get_announcement_type(j))); +                r.msgs.emplace_back(2, strprintf("- %s", get_announcement_type(j)));              }          }      } diff --git a/src/fig0_26.cpp b/src/fig0_26.cpp index 332a900..0568b60 100644 --- a/src/fig0_26.cpp +++ b/src/fig0_26.cpp @@ -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 @@ -69,7 +69,8 @@ fig_result_t fig0_26(fig0_common_t& fig0, const display_settings_t &disp)          EId_Other_Ensemble = ((uint16_t)f[i+4] << 8) | (uint16_t)f[i+5];          Cluster_Id_Other_Ensemble = f[i+6]; -        r.msgs.push_back(strprintf("Cluster Id Current Ensemble=0x%X", Cluster_Id_Current_Ensemble)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("Cluster Id Current Ensemble=0x%X", Cluster_Id_Current_Ensemble));          r.msgs.emplace_back(1, strprintf("Asw flags=0x%X", Asw_flags));          r.msgs.emplace_back(1, strprintf("New flag=%d %s announcement", New_flag, New_flag?"newly introduced":"repeated"));          r.msgs.emplace_back(1, strprintf("Region flag=%d last byte %s", @@ -95,9 +96,10 @@ fig_result_t fig0_26(fig0_common_t& fig0, const display_settings_t &disp)              i++;          }          // decode announcement switching types +        r.msgs.emplace_back(1, "Announcement switching:");          for (j = 0; j < 16; j++) {              if (Asw_flags & (1 << j)) { -                r.msgs.emplace_back(2, strprintf("Announcement switching=%s", get_announcement_type(j))); +                r.msgs.emplace_back(2, strprintf("- %s", get_announcement_type(j)));              }          }      } diff --git a/src/fig0_27.cpp b/src/fig0_27.cpp index 2b37a85..fdcb5f5 100644 --- a/src/fig0_27.cpp +++ b/src/fig0_27.cpp @@ -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 @@ -63,7 +63,8 @@ fig_result_t fig0_27(fig0_common_t& fig0, const display_settings_t &disp)          Rfu = f[i+2] >> 4;          Number_PI_codes = f[i+2] & 0x0F;          key = (fig0.oe() << 5) | (fig0.pd() << 4) | Number_PI_codes; -        r.msgs.push_back(strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId));          if (Rfu != 0) {              r.errors.push_back(strprintf("Rfu=%d invalid value", Rfu));          } @@ -75,14 +76,15 @@ fig_result_t fig0_27(fig0_common_t& fig0, const display_settings_t &disp)          // CEI Change Event Indication          if (Number_PI_codes == 0) {              // The Change Event Indication (CEI) is signalled by the Number of PI codes field = 0 -            r.msgs.emplace_back(1, "CEI"); +            r.msgs.emplace_back(1, "CEI=true");          }          i += 3; +        r.msgs.emplace_back(1, "PI Codes:");          for (j = 0; j < Number_PI_codes && i < fig0.figlen - 1; j++) {              // iterate over PI              PI = ((uint16_t)f[i] << 8) | (uint16_t)f[i+1]; -            r.msgs.emplace_back(2, strprintf("PI=0x%X", PI)); +            r.msgs.emplace_back(2, strprintf("- 0x%X", PI));              i += 2;          }          if (j != Number_PI_codes) { diff --git a/src/fig0_28.cpp b/src/fig0_28.cpp index c729b03..3a95c5c 100644 --- a/src/fig0_28.cpp +++ b/src/fig0_28.cpp @@ -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 @@ -65,7 +65,8 @@ fig_result_t fig0_28(fig0_common_t& fig0, const display_settings_t &disp)          Rfa = (f[i+1] >> 6) & 0x01;          Region_Id_Current_Ensemble = f[i+1] & 0x3F;          PI = ((uint16_t)f[i+2] << 8) | (uint16_t)f[i+3]; -        r.msgs.push_back(strprintf("Cluster Id Current Ensemble=0x%X", Cluster_Id_Current_Ensemble)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("Cluster Id Current Ensemble=0x%X", Cluster_Id_Current_Ensemble));          if (Cluster_Id_Current_Ensemble == 0) {              r.errors.push_back("Cluster Id Current Ensemble invalid value 0"); diff --git a/src/fig0_3.cpp b/src/fig0_3.cpp index 14e395f..f07c1f6 100644 --- a/src/fig0_3.cpp +++ b/src/fig0_3.cpp @@ -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 @@ -68,13 +68,14 @@ fig_result_t fig0_3(fig0_common_t& fig0, const display_settings_t &disp)          DSCTy = f[i+2] & 0x3F;          SubChId = (f[i+3] >> 2);          Packet_address = ((uint16_t)(f[i+3] & 0x03) << 8) | ((uint16_t)f[i+4]); -        r.msgs.push_back(strprintf("SCId=0x%X", SCId)); -        r.msgs.push_back(strprintf("CAOrg flag=%d CAOrg field %s", CAOrg_flag, CAOrg_flag?"present":"absent")); -        r.msgs.push_back(strprintf("DG flag=%d", DG_flag)); -        r.msgs.push_back(strprintf("data groups are %sused to transport the service component", DG_flag ? "not ": "")); -        r.msgs.push_back(strprintf("DSCTy=%d %s", DSCTy, get_dscty_type(DSCTy))); -        r.msgs.push_back(strprintf("SubChId=0x%X", SubChId)); -        r.msgs.push_back(strprintf("Packet address=0x%X", Packet_address)); +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SCId=0x%X", SCId)); +        r.msgs.emplace_back(1, strprintf("CAOrg flag=%d CAOrg field %s", CAOrg_flag, CAOrg_flag?"present":"absent")); +        r.msgs.emplace_back(1, strprintf("DG flag=%d", DG_flag)); +        r.msgs.emplace_back(1, strprintf("data groups are %sused to transport the service component", DG_flag ? "not ": "")); +        r.msgs.emplace_back(1, strprintf("DSCTy=%d %s", DSCTy, get_dscty_type(DSCTy))); +        r.msgs.emplace_back(1, strprintf("SubChId=0x%X", SubChId)); +        r.msgs.emplace_back(1, strprintf("Packet address=0x%X", Packet_address));          if (Rfa != 0) {              r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa)); @@ -90,7 +91,7 @@ fig_result_t fig0_3(fig0_common_t& fig0, const display_settings_t &disp)                  CAOrg = ((uint16_t)f[i] << 8) | ((uint16_t)f[i+1]);                  CAMode = (f[i] >> 5);                  SharedFlag = f[i+1]; -        r.msgs.push_back(strprintf("CAOrg=0x%X CAMode=%d \"%s\" SharedFlag=0x%X%s", +                r.msgs.emplace_back(1, strprintf("CAOrg=0x%X CAMode=%d \"%s\" SharedFlag=0x%X%s",                          CAOrg, CAMode, get_ca_mode(CAMode), SharedFlag, (SharedFlag == 0) ? " invalid" : ""));              }              else { diff --git a/src/fig0_31.cpp b/src/fig0_31.cpp index 46e5809..c869bf4 100644 --- a/src/fig0_31.cpp +++ b/src/fig0_31.cpp @@ -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 @@ -75,18 +75,18 @@ fig_result_t fig0_31(fig0_common_t& fig0, const display_settings_t &disp)              if ((flag_field != 0) && ((j <= 5) || (j == 8) ||                          (j == 10) || (j == 13) || (j == 14) ||                          (j == 19) || (j == 26) || (j == 28))) { -                r.errors.push_back(strprintf("fig0.oe()=%d FIG 0/%d carried in AIC, invalid configuration, shall always be carried entirely in the FIC", +                r.errors.push_back(strprintf("OE %d FIG 0/%d=carried in AIC, invalid configuration, shall always be carried entirely in the FIC",                              fig0.oe(), j));              }              else if ((flag_field != 0) && ((j == 21) || (j == 24))) { -                r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 0/%d carried in AIC, same shall be carried in FIC", fig0.oe(), j)); +                r.msgs.emplace_back(1, strprintf("OE %d FIG 0/%d=carried in AIC, same shall be carried in FIC", fig0.oe(), j));              }              else if (flag_field != 0) {                  if (fig0.oe() == 0) { -                    r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 0/%d carried in AIC, same shall be carried in FIC", fig0.oe(), j)); +                    r.msgs.emplace_back(1, strprintf("OE %d FIG 0/%d=carried in AIC, same shall be carried in FIC", fig0.oe(), j));                  }                  else {  // fig0.oe() == 1 -                r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 0/%d carried in AIC, may be carried entirely in AIC", fig0.oe(), j)); +                r.msgs.emplace_back(1, strprintf("OE %d FIG 0/%d=carried in AIC, may be carried entirely in AIC", fig0.oe(), j));                  }              }          } @@ -96,10 +96,10 @@ fig_result_t fig0_31(fig0_common_t& fig0, const display_settings_t &disp)              flag_field = FIG_type1_flag_field & ((uint32_t)1 << j);              if (flag_field != 0) {                  if (fig0.oe() == 0) { -                    r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 1/%d carried in AIC, same shall be carried in FIC", fig0.oe(), j)); +                    r.msgs.emplace_back(1, strprintf("OE %d FIG 1/%d=carried in AIC, same shall be carried in FIC", fig0.oe(), j));                  }                  else {  // fig0.oe() == 1 -                    r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 1/%d carried in AIC, may be carried entirely in AIC", fig0.oe(), j)); +                    r.msgs.emplace_back(1, strprintf("OE %d FIG 1/%d=carried in AIC, may be carried entirely in AIC", fig0.oe(), j));                  }              }          } @@ -109,10 +109,10 @@ fig_result_t fig0_31(fig0_common_t& fig0, const display_settings_t &disp)              flag_field = FIG_type2_flag_field & ((uint32_t)1 << j);              if (flag_field != 0) {                  if (fig0.oe() == 0) { -                    r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 2/%d carried in AIC, same shall be carried in FIC", fig0.oe(), j)); +                    r.msgs.emplace_back(1, strprintf("OE %d FIG 2/%d=carried in AIC, same shall be carried in FIC", fig0.oe(), j));                  }                  else {  // fig0.oe() == 1 -                    r.msgs.emplace_back(1, strprintf("fig0.oe()=%d FIG 2/%d carried in AIC, may be carried entirely in AIC", fig0.oe(), j)); +                    r.msgs.emplace_back(1, strprintf("OE %d FIG 2/%d=carried in AIC, may be carried entirely in AIC", fig0.oe(), j));                  }              }          } diff --git a/src/fig0_5.cpp b/src/fig0_5.cpp index 485c479..2243539 100644 --- a/src/fig0_5.cpp +++ b/src/fig0_5.cpp @@ -60,24 +60,25 @@ fig_result_t fig0_5(fig0_common_t& fig0, const display_settings_t &disp)      while (i < fig0.figlen - 1) {          // iterate over service component language          LS_flag = f[i] >> 7; +        r.msgs.emplace_back("-");          if (LS_flag == 0) {              // Short form (L/S = 0)              MSC_FIC_flag = (f[i] >> 6) & 0x01;              Language = f[i+1]; -            r.msgs.emplace_back("Short form"); -            r.msgs.push_back(strprintf("MSC/FIC flag=%d MSC", MSC_FIC_flag)); +            r.msgs.emplace_back(1, "form=short"); +            r.msgs.emplace_back(1, strprintf("MSC/FIC flag=%d MSC", MSC_FIC_flag));              if (MSC_FIC_flag == 0) {                  // 0: MSC in Stream mode and SubChId identifies the sub-channel                  SubChId = f[i] & 0x3F; -                r.msgs.push_back(strprintf("SubChId=0x%X", SubChId)); +                r.msgs.emplace_back(1, strprintf("SubChId=0x%X", SubChId));              }              else {                  // 1: FIC and FIDCId identifies the component                  FIDCId = f[i] & 0x3F; -                r.msgs.push_back(strprintf("FIDCId=0x%X", FIDCId)); +                r.msgs.emplace_back(1, strprintf("FIDCId=0x%X", FIDCId));              } -            r.msgs.push_back(strprintf("Language=0x%X %s", +            r.msgs.emplace_back(1, strprintf("Language=0x%X %s",                          Language, get_language_name(Language)));              int key = (MSC_FIC_flag << 7) | (f[i] % 0x3F); @@ -87,7 +88,7 @@ fig_result_t fig0_5(fig0_common_t& fig0, const display_settings_t &disp)          else {              // Long form (L/S = 1)              if (i < (fig0.figlen - 2)) { -                r.msgs.emplace_back("Long form"); +                r.msgs.emplace_back(1, "form=long");                  Rfa = (f[i] >> 4) & 0x07;                  SCId = (((uint16_t)f[i] & 0x0F) << 8) | (uint16_t)f[i+1]; @@ -95,13 +96,16 @@ fig_result_t fig0_5(fig0_common_t& fig0, const display_settings_t &disp)                  r.complete |= fig0_5_is_complete(key);                  Language = f[i+2];                  if (Rfa != 0) { -                    r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa)); +                    r.errors.emplace_back(strprintf("Rfa=%d invalid value", Rfa));                  } -                r.msgs.push_back(strprintf("SCId=0x%X", SCId)); -                r.msgs.push_back(strprintf("Language=0x%X %s", +                r.msgs.emplace_back(1, strprintf("SCId=0x%X", SCId)); +                r.msgs.emplace_back(1, strprintf("Language=0x%X %s",                              Language, get_language_name(Language)));              } +            else { +                r.errors.emplace_back("Long form FIG is too short"); +            }              i += 3;          }      } diff --git a/src/fig0_6.cpp b/src/fig0_6.cpp index 1230be9..0ba4132 100644 --- a/src/fig0_6.cpp +++ b/src/fig0_6.cpp @@ -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 @@ -76,27 +76,28 @@ fig_result_t fig0_6(fig0_common_t& fig0, const display_settings_t &disp)          key = (fig0.oe() << 15) | (fig0.pd() << 14) | (SH << 13) | (ILS << 12) | LSN;          r.complete |= fig0_6_is_complete(key); -        r.msgs.push_back(strprintf("Id list flag=%d", Id_list_flag)); -        r.msgs.push_back(strprintf("LA=%d %s", LA, LA ? "active" : "inactive")); -        r.msgs.push_back(strprintf("S/H=%d %s", SH, SH ? "Hard" : "Soft")); -        r.msgs.push_back(strprintf("ILS=%d %s", ILS, ILS ? "international" : "national")); -        r.msgs.push_back(strprintf("LSN=%d", LSN)); -        r.msgs.push_back(strprintf("database key=0x%04x", key)); +        r.msgs.emplace_back(0, "-"); +        r.msgs.emplace_back(1, strprintf("Id list flag=%d", Id_list_flag)); +        r.msgs.emplace_back(1, strprintf("LA=%d %s", LA, LA ? "active" : "inactive")); +        r.msgs.emplace_back(1, strprintf("S/H=%d %s", SH, SH ? "Hard" : "Soft")); +        r.msgs.emplace_back(1, strprintf("ILS=%d %s", ILS, ILS ? "international" : "national")); +        r.msgs.emplace_back(1, strprintf("LSN=%d", LSN)); +        r.msgs.emplace_back(1, strprintf("database key=0x%04x", key));          // check activation / deactivation          if ((fig0_6_key_la.count(key) > 0) && (fig0_6_key_la[key] != LA)) {              if (LA == 0) { -                r.msgs.emplace_back("deactivated"); +                r.msgs.emplace_back(1, "status=deactivated");              }              else { -                r.msgs.emplace_back("activated"); +                r.msgs.emplace_back(1, "status=activated");              }          }          fig0_6_key_la[key] = LA;          i += 2;          if (Id_list_flag == 0) {              if (fig0.cn() == 0) {  // Id_list_flag=0 && fig0.cn()=0: CEI Change Event Indication -                r.msgs.emplace_back("CEI"); +                r.msgs.emplace_back(1, "CEI=true");              }          }          else {  // Id_list_flag == 1 @@ -105,29 +106,30 @@ fig_result_t fig0_6(fig0_common_t& fig0, const display_settings_t &disp)                  if (fig0.pd() == 0) {                      IdLQ = (f[i] >> 5) & 0x03;                      Shd   = (f[i] >> 4) & 0x01; -                    r.msgs.push_back(strprintf("IdLQ=%d", IdLQ)); -                    r.msgs.push_back(strprintf("Shd=%d %s", Shd, (Shd)?"b11-8 in 4-F are different services":"single service")); -                    r.msgs.push_back(strprintf("Number of Ids=%d", Number_of_Ids)); +                    r.msgs.emplace_back(1, strprintf("IdLQ=%d", IdLQ)); +                    r.msgs.emplace_back(1, strprintf("Shd=%d %s", Shd, (Shd)?"b11-8 in 4-F are different services":"single service"));                      if (ILS == 0) {                          // read Id list +                        r.msgs.emplace_back(1, "Id List:");                          for(j = 0; ((j < Number_of_Ids) && ((i+2+(j*2)) < fig0.figlen)); j++) { +                            r.msgs.emplace_back(2, "-");                              // ETSI EN 300 401 8.1.15. Some changes were introducted in spec V2                              if (((j == 0) && (fig0.oe() == 0) && (fig0.cn() == 0)) ||                                      (IdLQ == 0)) { -                                r.msgs.emplace_back(1, strprintf("DAB SId          0x%X", +                                r.msgs.emplace_back(3, strprintf("DAB SId=0x%X",                                              ((f[i+1+(j*2)] << 8) | f[i+2+(j*2)])));                              }                              else if (IdLQ == 1) { -                                r.msgs.emplace_back(1, strprintf("RDS PI           0x%X", +                                r.msgs.emplace_back(3, strprintf("RDS PI=0x%X",                                              ((f[i+1+(j*2)] << 8) | f[i+2+(j*2)])));                              }                              else if (IdLQ == 2) { -                                r.msgs.emplace_back(1, strprintf("(AM-FM legacy)   0x%X", +                                r.msgs.emplace_back(3, strprintf("(AM-FM legacy)=0x%X",                                              ((f[i+1+(j*2)] << 8) | f[i+2+(j*2)])));                              }                              else {  // IdLQ == 3 -                                r.msgs.emplace_back(1, strprintf("DRM-AMSS service 0x%X", +                                r.msgs.emplace_back(3, strprintf("DRM-AMSS service=0x%X",                                              ((f[i+1+(j*2)] << 8) | f[i+2+(j*2)])));                              }                          } @@ -139,23 +141,25 @@ fig_result_t fig0_6(fig0_common_t& fig0, const display_settings_t &disp)                          i += (Number_of_Ids * 2) + 1;                      }                      else {  // fig0.pd() == 0 && ILS == 1 +                        r.msgs.emplace_back(1, "Id List:");                          // read Id list                          for(j = 0; ((j < Number_of_Ids) && ((i+3+(j*3)) < fig0.figlen)); j++) { +                            r.msgs.emplace_back(2, "-");                              if (((j == 0) && (fig0.oe() == 0) && (fig0.cn() == 0)) ||                                      (IdLQ == 0)) { -                                r.msgs.emplace_back(1, strprintf("DAB SId          ecc 0x%02X Id 0x%04X", +                                r.msgs.emplace_back(3, strprintf("DAB SId=ecc 0x%02X Id 0x%04X",                                              f[i+1+(j*3)], ((f[i+2+(j*3)] << 8) | f[i+3+(j*3)])));                              }                              else if (IdLQ == 1) { -                                r.msgs.emplace_back(1, strprintf("RDS PI           ecc 0x%02X Id 0x%04X", +                                r.msgs.emplace_back(3, strprintf("RDS PI=ecc 0x%02X Id 0x%04X",                                              f[i+1+(j*3)], ((f[i+2+(j*3)] << 8) | f[i+3+(j*3)])));                              }                              else if (IdLQ == 2) { -                                r.msgs.emplace_back(1, strprintf("(AM-FM legacy)   ecc 0x%02X Id 0x%04X", +                                r.msgs.emplace_back(3, strprintf("(AM-FM legacy)=ecc 0x%02X Id 0x%04X",                                              f[i+1+(j*3)], ((f[i+2+(j*3)] << 8) | f[i+3+(j*3)])));                              }                              else {  // IdLQ == 3 -                                r.msgs.emplace_back(1, strprintf("DRM/AMSS service ecc 0x%02X Id 0x%04X", +                                r.msgs.emplace_back(3, strprintf("DRM/AMSS service=ecc 0x%02X Id 0x%04X",                                              f[i+1+(j*3)], ((f[i+2+(j*3)] << 8) | f[i+3+(j*3)])));                              }                          } @@ -167,11 +171,11 @@ fig_result_t fig0_6(fig0_common_t& fig0, const display_settings_t &disp)                      }                  }                  else {  // fig0.pd() == 1 -                    r.msgs.push_back(strprintf("Number of Ids=%d%s", Number_of_Ids)); +                    r.msgs.emplace_back(1, "Id List:");                      if (Number_of_Ids > 0) {                          // read Id list                          for(j = 0; ((j < Number_of_Ids) && ((i+4+(j*4)) < fig0.figlen)); j++) { -                            r.msgs.emplace_back(1, strprintf("SId 0x%X", +                            r.msgs.emplace_back(2, strprintf("- 0x%X",                                      ((f[i+1+(j*4)] << 24) | (f[i+2+(j*4)] << 16) | (f[i+3+(j*4)] << 8) | f[i+4+(j*4)])));                          }                      } diff --git a/src/fig0_8.cpp b/src/fig0_8.cpp index c283a52..5060202 100644 --- a/src/fig0_8.cpp +++ b/src/fig0_8.cpp @@ -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 @@ -83,18 +83,19 @@ fig_result_t fig0_8(fig0_common_t& fig0, const display_settings_t &disp)          Rfa = (f[i] >> 4) & 0x7;          SCIdS = f[i] & 0x0F;          r.complete |= fig0_8_is_complete(SId, SCIdS); -        r.msgs.push_back(strprintf("SId=0x%X", SId)); -        r.msgs.push_back(strprintf("Ext flag=%d 8-bit Rfa %s", +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("SId=0x%X", SId)); +        r.msgs.emplace_back(1, strprintf("Ext flag=%d 8-bit Rfa %s",                      Ext_flag, (Ext_flag)?"present":"absent"));          if (Rfa != 0) {              r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa));          } -        r.msgs.push_back(strprintf("SCIdS=0x%X", SCIdS)); +        r.msgs.emplace_back(1, strprintf("SCIdS=0x%X", SCIdS));          i++;          if (i < fig0.figlen) {              LS_flag = f[i] >> 7; -            r.msgs.push_back(strprintf("L/S flag=%d %s", LS_flag, (LS_flag)?"Long form":"Short form")); +            r.msgs.emplace_back(1, strprintf("L/S flag=%d %s", LS_flag, (LS_flag)?"Long form":"Short form"));              if (LS_flag == 0) {                  // Short form                  if (i < (fig0.figlen - Ext_flag)) { @@ -102,12 +103,12 @@ fig_result_t fig0_8(fig0_common_t& fig0, const display_settings_t &disp)                      if (MSC_FIC_flag == 0) {                          // MSC in stream mode and SubChId identifies the sub-channel                          SubChId = f[i] & 0x3F; -                        r.msgs.push_back(strprintf("MSC/FIC flag=%d MSC, SubChId=0x%X", MSC_FIC_flag, SubChId)); +                        r.msgs.emplace_back(1, strprintf("MSC/FIC flag=%d MSC, SubChId=0x%X", MSC_FIC_flag, SubChId));                      }                      else {                          // FIC and FIDCId identifies the component                          FIDCId = f[i] & 0x3F; -                        r.msgs.push_back(strprintf("MSC/FIC flag=%d FIC, FIDCId=0x%X", MSC_FIC_flag, FIDCId)); +                        r.msgs.emplace_back(1, strprintf("MSC/FIC flag=%d FIC, FIDCId=0x%X", MSC_FIC_flag, FIDCId));                      }                      if (Ext_flag == 1) {                          // Rfa field present @@ -127,7 +128,7 @@ fig_result_t fig0_8(fig0_common_t& fig0, const display_settings_t &disp)                      if (Rfa != 0) {                          r.errors.push_back(strprintf("Rfa=%d invalid value", Rfa));                      } -                    r.msgs.push_back(strprintf("SCId=0x%X", SCId)); +                    r.msgs.emplace_back(1, strprintf("SCId=0x%X", SCId));                  }                  i += 2;              } diff --git a/src/fig0_9.cpp b/src/fig0_9.cpp index 7c41bdf..b4f2078 100644 --- a/src/fig0_9.cpp +++ b/src/fig0_9.cpp @@ -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 @@ -53,12 +53,13 @@ fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp)              // negative Ensemble LTO              Ensemble_LTO |= 0xC0;          } -        r.msgs.push_back(strprintf("Ext flag=%d extended field %s", +        r.msgs.emplace_back("-"); +        r.msgs.emplace_back(1, strprintf("Ext flag=%d extended field %s",                      Ext_flag, Ext_flag?"present":"absent")); -        r.msgs.push_back(strprintf("LTO uniq=%d %s", +        r.msgs.emplace_back(1, strprintf("LTO uniq=%d %s",                      LTO_uniq,                      LTO_uniq?"several time zones":"one time zone (time specified by Ensemble LTO)")); -        r.msgs.push_back(strprintf("Ensemble LTO=0x%X %s%d:%02d", +        r.msgs.emplace_back(1, strprintf("Ensemble LTO=0x%X %s%d:%02d",                      (Ensemble_LTO & 0x3F), (Ensemble_LTO >= 0)?"":"-" , abs(Ensemble_LTO) >> 1, (Ensemble_LTO & 0x01) * 30));          if (abs(Ensemble_LTO) > 24) { @@ -68,13 +69,14 @@ fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp)          Ensemble_ECC = f[i+1];          uint8_t International_Table_Id = f[i+2];          set_international_table(International_Table_Id); -        r.msgs.push_back(strprintf("Ensemble ECC=0x%X", Ensemble_ECC)); -        r.msgs.push_back(strprintf("International Table Id=0x%X", International_Table_Id)); -        r.msgs.push_back(strprintf("database key=0x%x", key)); +        r.msgs.emplace_back(1, strprintf("Ensemble ECC=0x%X", Ensemble_ECC)); +        r.msgs.emplace_back(1, strprintf("International Table Id=0x%X", International_Table_Id)); +        r.msgs.emplace_back(1, strprintf("database key=0x%x", key));          i += 3;          if (Ext_flag == 1) {              // extended field present +            r.msgs.emplace_back(1, "Subfields:");              while (i < fig0.figlen) {                  // iterate over extended sub-field                  Number_of_services = f[i] >> 6; @@ -83,8 +85,9 @@ fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp)                      // negative LTO                      LTO |= 0xC0;                  } -                r.msgs.push_back(strprintf("Number of services=%d", Number_of_services)); -                r.msgs.push_back(strprintf("LTO=0x%X %s%d:%02d", +                r.msgs.emplace_back(2, "-"); +                r.msgs.emplace_back(3, strprintf("Number of services=%d", Number_of_services)); +                r.msgs.emplace_back(3, strprintf("LTO=0x%X %s%d:%02d",                          (LTO & 0x3F), (LTO >= 0)?"":"-" , abs(LTO) >> 1,  (LTO & 0x01) * 30));                  if (abs(LTO) > 24) {                      r.errors.push_back("LTO in extended field out of range -12 hours to +12 hours"); @@ -92,7 +95,7 @@ fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp)                  // CEI Change Event Indication                  if ((Number_of_services == 0) && (LTO == 0) /* && (Ext_flag == 1) */) { -                    r.msgs.emplace_back("CEI"); +                    r.msgs.emplace_back(3, "CEI=true");                  }                  i++; @@ -100,12 +103,12 @@ fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp)                      // Programme services, 16 bit SId                      if (i < fig0.figlen) {                          ECC = f[i]; -                        r.msgs.emplace_back(1, strprintf("ECC=0x%X", ECC)); +                        r.msgs.emplace_back(3, strprintf("ECC=0x%X", ECC));                          i++;                          for(j = i; ((j < (i + (Number_of_services * 2))) && (j < fig0.figlen)); j += 2) {                              // iterate over SId                              SId = ((uint32_t)f[j] << 8) | (uint32_t)f[j+1]; -                            r.msgs.emplace_back(2, strprintf("SId 0x%X", SId)); +                            r.msgs.emplace_back(3, strprintf("SId=0x%X", SId));                          }                          i += (Number_of_services * 2);                      } @@ -116,7 +119,7 @@ fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp)                          // iterate over SId                          SId = ((uint32_t)f[j] << 24) | ((uint32_t)f[j+1] << 16) |                              ((uint32_t)f[j+2] << 8) | (uint32_t)f[j+3]; -                        r.msgs.emplace_back(2, strprintf("SId 0x%X", SId)); +                        r.msgs.emplace_back(3, strprintf("SId=0x%X", SId));                      }                      i += (Number_of_services * 4);                  } diff --git a/src/fig1.cpp b/src/fig1.cpp index 5ae92c5..0a77d83 100644 --- a/src/fig1.cpp +++ b/src/fig1.cpp @@ -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 @@ -55,9 +55,9 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp)              {   // ETSI EN 300 401 8.1.13                  uint16_t eid;                  eid = f[1] * 256 + f[2]; -                r.msgs.push_back(strprintf("Ensemble ID: 0x%04X", eid)); -                r.msgs.push_back(strprintf("Label: \"%s\"", label)); -                r.msgs.push_back(strprintf("Short label mask: 0x%04X", flag)); +                r.msgs.push_back(strprintf("Ensemble ID=0x%04X", eid)); +                r.msgs.push_back(strprintf("Label=\"%s\"", label)); +                r.msgs.push_back(strprintf("Short label mask=0x%04X", flag));                  if (fig1.fibcrccorrect) {                      fig1.ensemble.EId = eid; @@ -71,9 +71,9 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp)              {   // ETSI EN 300 401 8.1.14.1                  uint16_t sid;                  sid = f[1] * 256 + f[2]; -                r.msgs.push_back(strprintf("Service ID: 0x%04X", sid)); -                r.msgs.push_back(strprintf("Label: \"%s\"", label)); -                r.msgs.push_back(strprintf("Short label mask: 0x%04X", flag)); +                r.msgs.push_back(strprintf("Service ID=0x%04X", sid)); +                r.msgs.push_back(strprintf("Label=\"%s\"", label)); +                r.msgs.push_back(strprintf("Short label mask=0x%04X", flag));                  if (fig1.fibcrccorrect) {                      try { @@ -104,10 +104,10 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp)                            f[4] * 256 + \                            f[5];                  } -                r.msgs.push_back(strprintf("Service ID: 0x%04X", sid)); -                r.msgs.push_back(strprintf("Service Component ID: 0x%04X", SCIdS)); -                r.msgs.push_back(strprintf("Label: \"%s\"", label)); -                r.msgs.push_back(strprintf("Short label mask: 0x%04X", flag)); +                r.msgs.push_back(strprintf("Service ID=0x%04X", sid)); +                r.msgs.push_back(strprintf("Service Component ID=0x%04X", SCIdS)); +                r.msgs.push_back(strprintf("Label=\"%s\"", label)); +                r.msgs.push_back(strprintf("Short label mask=0x%04X", flag));              }              break; @@ -119,9 +119,9 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp)                        f[3] * 256 + \                        f[4]; -                r.msgs.push_back(strprintf("Service ID: 0x%04X", sid)); -                r.msgs.push_back(strprintf("Label: \"%s\"", label)); -                r.msgs.push_back(strprintf("Short label mask: 0x%04X", flag)); +                r.msgs.push_back(strprintf("Service ID=0x%04X", sid)); +                r.msgs.push_back(strprintf("Label=\"%s\"", label)); +                r.msgs.push_back(strprintf("Short label mask=0x%04X", flag));              }              break; @@ -158,11 +158,11 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp)                  } -                r.msgs.push_back(strprintf("Service ID: 0x%04X", sid)); -                r.msgs.push_back(strprintf("Service Component ID: 0x%04X", SCIdS)); -                r.msgs.push_back(strprintf("X-PAD App %02X (", xpadapp) + xpadappdesc + ")"); -                r.msgs.push_back(strprintf("Label: \"%s\"", label)); -                r.msgs.push_back(strprintf("Short label mask: 0x%04X", flag)); +                r.msgs.push_back(strprintf("Service ID=0x%04X", sid)); +                r.msgs.push_back(strprintf("Service Component ID=0x%04X", SCIdS)); +                r.msgs.push_back(strprintf("X-PAD App=%02X (", xpadapp) + xpadappdesc + ")"); +                r.msgs.push_back(strprintf("Label=\"%s\"", label)); +                r.msgs.push_back(strprintf("Short label mask=0x%04X", flag));              }              break;      } diff --git a/src/utils.cpp b/src/utils.cpp index 90231ce..2d5af6a 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -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 @@ -76,77 +76,137 @@ std::string strprintf(const char* fmt, ...)      return str;  } -void printbuf(std::string header, -        int indent, -        uint8_t* buffer, -        size_t size, -        std::string desc) -{ -    display_settings_t disp(true, indent); -    printbuf(header, disp, buffer, size, desc); -} - -void printfig(string header, +static void printyaml(const string& header,          const display_settings_t &disp, -        uint8_t* buffer, -        size_t size, -        string desc) +        uint8_t* buffer = nullptr, +        size_t size = 0, +        const std::string& desc = "", +        const std::string& value = "")  {      if (disp.print) { +        stringstream ss;          for (int i = 0; i < disp.indent; i++) { -            printf("\t"); +            ss << " ";          } -        printf("%s", header.c_str()); +        ss << header; +        ss << ":"; -        if (verbosity > 1) { -            if (size != 0) { -                printf(": "); +        if (not value.empty() and desc.empty() and not buffer) { +            ss << " " << value; +        } +        else { +            if (not value.empty()) { +                ss << "\n"; +                for (int i = 0; i < disp.indent + 1; i++) { +                    ss << " "; +                } +                ss << strprintf("value: %s", value.c_str());              } -            for (size_t i = 0; i < size; i++) { -                printf("%02x ", buffer[i]); +            if (not desc.empty()) { +                ss << "\n"; +                for (int i = 0; i < disp.indent + 1; i++) { +                    ss << " "; +                } +                ss << strprintf("desc: %s", desc.c_str());              } -        } -        if (desc != "") { -            printf(" [%s] ", desc.c_str()); +            if (buffer and verbosity > 0) { +                if (size != 0) { +                    ss << "\n"; +                    for (int i = 0; i < disp.indent + 1; i++) { +                        ss << " "; +                    } +                    ss << "data: ["; + +                    size_t num_printed = 0; + +                    for (size_t i = 0; i < size; i++) { +                        if (i > 0) { +                            ss << ","; +                            num_printed++; +                        } + +                        if (num_printed + disp.indent + 1 + 7 > 60 ) { +                            ss << "\n"; +                            for (int i = 0; i < disp.indent + 8; i++) { +                                ss << " "; +                            } +                            num_printed = 2; +                        } +                        else if (i > 0) { +                            ss << " "; +                            num_printed++; +                        } + +                        ss << strprintf("0x%02x", buffer[i]); +                        num_printed += 3; +                    } +                    ss << "]"; +                } +            }          } -        printf("\n"); +        ss << "\n"; +        printf("%s", ss.str().c_str());      }  } +void printbuf(const std::string& header, +        int indent, +        uint8_t* buffer, +        size_t size, +        const std::string& desc, +        const std::string& value) +{ +    display_settings_t disp(true, indent); +    printyaml(header, disp, buffer, size, desc, value); +} -void printbuf(string header, +void printbuf(const string& header,          const display_settings_t &disp,          uint8_t* buffer,          size_t size, -        string desc) +        const std::string& desc, +        const std::string& value)  { -    if (verbosity > 0) { -        for (int i = 0; i < disp.indent; i++) { -            printf("\t"); -        } - -        printf("%s", header.c_str()); +    display_settings_t d = disp; +    d.print = (verbosity > 0); +    printyaml(header, d, buffer, size, desc, value); +} -        if (verbosity > 1) { -            if (size != 0) { -                printf(": "); -            } +void printbuf(const std::string& header, int indent) +{ +    display_settings_t disp(true, indent); +    return printyaml(header, disp); +} -            for (size_t i = 0; i < size; i++) { -                printf("%02x ", buffer[i]); -            } -        } +void printfig(const string& header, +        const display_settings_t &disp, +        uint8_t* buffer, +        size_t size, +        const std::string& desc, +        const std::string& value) +{ +    printyaml(header, disp, buffer, size, desc, value); +} -        if (desc != "") { -            printf(" [%s] ", desc.c_str()); -        } +void printvalue(const std::string& header, +        const display_settings_t &disp, +        const std::string& desc, +        const std::string& value) +{ +    return printyaml(header, disp, nullptr, 0, desc, value); +} -        printf("\n"); -    } +void printvalue(const std::string& header, +        int indent, +        const std::string& desc, +        const std::string& value) +{ +    display_settings_t disp(true, indent); +    return printyaml(header, disp, nullptr, 0, desc, value);  }  void printinfo(const string &header, @@ -155,19 +215,26 @@ void printinfo(const string &header,  {      if (verbosity >= min_verb) {          for (int i = 0; i < disp.indent; i++) { -            printf("\t"); +            printf(" ");          } -        printf("%s\n", header.c_str()); +        printf("info: %s\n", header.c_str());      }  } -void printinfo(const std::string &header, -        int min_verb) +void printinfo(const std::string &header, int min_verb)  {      const display_settings_t disp(true, 0);      printinfo(header, min_verb);  } +void printsequencestart(int indent) +{ +    for (int i = 0; i < indent; i++) { +        printf(" "); +    } +    printf("-\n"); +} +  int sprintfMJD(char *dst, int mjd) {      // EN 62106 Annex G      // These formulas are applicable between the inclusive dates: 1st March 1900 to 28th February 2100 diff --git a/src/utils.hpp b/src/utils.hpp index fdb673e..e473166 100644 --- a/src/utils.hpp +++ b/src/utils.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 @@ -48,23 +48,38 @@ struct display_settings_t {  std::string strprintf(const char* fmt, ...); -void printbuf(std::string header, +void printbuf(const std::string& header,          const display_settings_t &disp,          uint8_t* buffer,          size_t size, -        std::string desc=""); +        const std::string& desc="", +        const std::string& value=""); -void printfig(std::string header, +void printfig(const std::string& header,          const display_settings_t &disp,          uint8_t* buffer,          size_t size, -        std::string desc=""); +        const std::string& desc="", +        const std::string& value=""); -void printbuf(std::string header, +void printbuf(const std::string& header,          int indent,          uint8_t* buffer,          size_t size, -        std::string desc=""); +        const std::string& desc="", +        const std::string& value=""); + +void printbuf(const std::string& header, int indent = 0); + +void printvalue(const std::string& header, +        int indent = 0, +        const std::string& desc="", +        const std::string& value=""); + +void printvalue(const std::string& header, +        const display_settings_t &disp, +        const std::string& desc="", +        const std::string& value="");  void printinfo(const std::string &header,          const display_settings_t &disp, @@ -73,6 +88,8 @@ void printinfo(const std::string &header,  void printinfo(const std::string &header,          int min_verb); +void printsequencestart(int indent = 0); +  // sprintfMJD: convert MJD (Modified Julian Date) into date string  int sprintfMJD(char *dst, int mjd); diff --git a/src/watermarkdecoder.hpp b/src/watermarkdecoder.hpp index 57196e1..171d1ae 100644 --- a/src/watermarkdecoder.hpp +++ b/src/watermarkdecoder.hpp @@ -63,7 +63,8 @@ class WatermarkDecoder              } -            printf("Found SYNC at offset %zu out of %zu\n", bit_ix - alternance_count, m_confind_bits.size()); +            fprintf(stderr, "Found SYNC at offset %zu out of %zu\n", +                    bit_ix - alternance_count, m_confind_bits.size());              std::stringstream watermark_ss; diff --git a/yamlexample.py b/yamlexample.py new file mode 100755 index 0000000..7001b23 --- /dev/null +++ b/yamlexample.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# +# An example on how to read the YAML output from etisnoop +# Pipe etisnoop to this script +# +# License: public domain + +import sys +import yaml + +for frame in yaml.load_all(sys.stdin): +    print("FIGs in frame {}".format(frame['Frame'])) +    for fib in frame['LIDATA']['FIC']: +        if fib['FIGs']: +            for fig in fib['FIGs']: +                print(" FIG " + fig['FIG']) +  | 
