diff options
| -rw-r--r-- | src/DabMux.cpp | 126 | ||||
| -rw-r--r-- | src/Eti.cpp | 35 | ||||
| -rw-r--r-- | src/Eti.h | 39 | ||||
| -rw-r--r-- | src/TcpLog.cpp | 4 | 
4 files changed, 189 insertions, 15 deletions
diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 59278f9..3f5f87c 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -2,6 +2,9 @@     Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,     2011 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) + +   Includes modifications +   2012, Matthias P. Braendli, matthias.braendli@mpb.li     */  /*     This file is part of CRC-DabMux. @@ -920,6 +923,7 @@ void printUsage(char *name, FILE* out = stderr)      fprintf(out, "  -m                   : DAB mode (default: 2)\n");      fprintf(out, "  -n nbFrames          : number of frames to produce\n");      fprintf(out, "  -o                   : turn on TCP log on port 12222\n"); +    fprintf(out, "  -r                   : throttle the output rate to one ETI frame every 24ms\n");      fprintf(out, "  -V                   : print version information and "              "exit\n");      fprintf(out, "  -z                   : write SCCA field for Factum ETI" @@ -942,7 +946,7 @@ void printUsage(char *name, FILE* out = stderr)              "subchannel (default: audio 1st frame, data %i, packet %i)\n",              DEFAULT_DATA_BITRATE, DEFAULT_PACKET_BITRATE);      fprintf(out, "  -c                   : set the extendend country code ECC " -            "(default: %u (0x%2x)\n"); +            "(default: %u (0x%2x)\n", DEFAULT_ENSEMBLE_ECC, DEFAULT_ENSEMBLE_ECC);      fprintf(out, "  -d                   : turn on datagroups in packet "              "mode\n");      fprintf(out, "  -f figType           : user application type in FIG " @@ -958,7 +962,7 @@ void printUsage(char *name, FILE* out = stderr)      fprintf(out, "  -l sLabel<n>         : short label flag of service <n>"              " (default: 0xf040)\n");      fprintf(out, "  -p protection<n>     : protection level (default: 3)\n"); -    fprintf(out, "  -s                   : enable TIST, synchronized on 1PPS at level 2\n"); +    fprintf(out, "  -s                   : enable TIST, synchronized on 1PPS at level 2. This also transmits time using the MNSC.\n");      fprintf(out, "  -t type              : audio/data service component type"              " (default: 0)\n");      fprintf(out, "                         audio: foreground=0, " @@ -1368,8 +1372,22 @@ int main(int argc, char *argv[])      bool factumAnalyzer = false;      unsigned long limit = 0;      time_t date; -    unsigned timestamp = 0xffffff; +    bool enableTist = false; +    unsigned timestamp = 0; + +    unsigned long time_seconds = 0; + +    struct timeval mnsc_time; +    /* TODO:  +     * In a SFN, when reconfiguring the ensemble, the multiplexer +     * has to be restarted (crc-dabmux doesn't support reconfiguration). +     * Ideally, we must be able to restart transmission s.t. the receiver +     * synchronisation is preserved. +     */ +    gettimeofday(&mnsc_time, NULL); + +    bool MNSC_increment_time = false;      char* progName = strrchr(argv[0], '/');      if (progName == NULL) { @@ -1381,7 +1399,7 @@ int main(int argc, char *argv[])      while (1) {          int c = getopt(argc, argv, -                "A:B:CD:E:F:L:M:O:P:STVa:b:c:de:f:g:hi:kl:m:n:op:st:y:z"); +                "A:B:CD:E:F:L:M:O:P:STVa:b:c:de:f:g:hi:kl:m:n:op:rst:y:z");          if (c == -1) {              break;          } @@ -2078,6 +2096,7 @@ int main(int argc, char *argv[])              break;          case 's':              { +                /*                  struct timeval tv;                  gettimeofday(&tv, NULL);                  unsigned _8ms = (tv.tv_usec / 1000) / 8; @@ -2086,6 +2105,8 @@ int main(int argc, char *argv[])                  unsigned _488ns = 0;                  unsigned _61ns = 0;                  timestamp = (((((((_8ms << 3) | _1ms) << 8) | _4us) << 3) | _488ns) << 8) | _61ns; +                */ +                enableTist = true;              }              break;          case 'y': @@ -2101,6 +2122,23 @@ int main(int argc, char *argv[])          case 'z':              factumAnalyzer = true;              break; +        case 'r': +            etiLog.printHeader(TcpLog::INFO, +                    "Enabling throttled output using simul, one frame every 24ms\n"); +            outputs.push_back(new dabOutput); +            output = outputs.end() - 1; + +            memset(*output, 0, sizeof(dabOutput)); +            (*output)->outputProto = "simul"; +            (*output)->outputName = ""; +            (*output)->data = NULL; +            (*output)->operations = dabOutputDefaultOperations; + +            subchannel = ensemble->subchannels.end(); +            protection = NULL; +            component = ensemble->components.end(); +            service = ensemble->services.end(); +            break;          case '?':              returnCode = -1;          case 'h': @@ -2436,7 +2474,7 @@ int main(int argc, char *argv[])          //****** FP ******//          // Frame Phase, 3 bits, compteur sur 3 bits, permet au COFDM generator -        // de savoir quand inserer le TII utilise egalement par le MNST +        // de savoir quand inserer le TII utilise egalement par le MNSC          fc->FP = currentFrame & 0x7;          //****** MID ******// @@ -2491,8 +2529,50 @@ int main(int argc, char *argv[])          eti_EOH *eoh = (eti_EOH *) & etiFrame[index];          //MNSC Multiplex Network Signalling Channel, 2 octets +          eoh->MNSC = 0; +        struct tm *time_tm = gmtime(&mnsc_time.tv_sec); +        switch (fc->FP & 0x3) +        { +            case 0: +                if (MNSC_increment_time) +                { +                    MNSC_increment_time = false; +                    mnsc_time.tv_sec += 1; +                } +                { + +                    eti_MNSC_TIME_0 *mnsc = (eti_MNSC_TIME_0 *) &eoh->MNSC; +                    // Set fields according to ETS 300 799 -- 5.5.1 and A.2.2  +                    mnsc->type = 0; +                    mnsc->identifier = 0; +                    mnsc->rfa = 0; +                } +                break; +            case 1: +                { +                    eti_MNSC_TIME_1 *mnsc = (eti_MNSC_TIME_1 *) &eoh->MNSC; +                    mnsc->setFromTime(time_tm); +                    mnsc->accuracy = 1; +                    mnsc->sync_to_frame = 1; +                } +                break; +            case 2: +                { +                    eti_MNSC_TIME_2 *mnsc = (eti_MNSC_TIME_2 *) &eoh->MNSC; +                    mnsc->setFromTime(time_tm); +                } +                break; +            case 3: +                { +                    eti_MNSC_TIME_3 *mnsc = (eti_MNSC_TIME_3 *) &eoh->MNSC; +                    mnsc->setFromTime(time_tm); +                } +                break; +        } + +          //CRC Cyclic Redundancy Checksum du FC,  STC et MNSC, 2 octets          nbBytesCRC = 4 + ((fc->NST) * 4) + 2; @@ -3481,21 +3561,32 @@ int main(int argc, char *argv[])          index = (FLtmp + 2 + 1) * 4;          eti_TIST *tist = (eti_TIST *) & etiFrame[index]; -        tist->TIST = htonl(timestamp) | 0xff; -        if (timestamp != 0xffffff) { -            timestamp += 3 << 17; -            if (timestamp > 0xf9ffff) { -                timestamp -= 0xfa0000; -            } +        if (enableTist) { +            tist->TIST = htonl(timestamp) | 0xff; +        } +        else { +            tist->TIST = htonl(0xffffff) | 0xff;          } -        /********************************************************************** +        timestamp += 3 << 17; +        if (timestamp > 0xf9ffff) +        { +            timestamp -= 0xfa0000; + +            // Also update MNSC time for next frame +            MNSC_increment_time = true; +        } + + + +        /**********************************************************************            ***********   Section FRPD   *****************************************           **********************************************************************/          //Donne le nombre total d'octets utils dans la trame          index = (FLtmp + 1 + 1 + 1 + 1) * 4; +        // Give the data to the outputs          for (output = outputs.begin() ; output != outputs.end(); ++output) {              if ((*output)->operations.write((*output)->data, etiFrame, index)                      == -1) { @@ -3509,12 +3600,21 @@ int main(int argc, char *argv[])  #endif // DUMP_BRIDGE          if (currentFrame % 100 == 0) { -            etiLog.print(TcpLog::INFO, "ETI frame number %i \n", currentFrame); +            if (enableTist) { +                etiLog.print(TcpLog::INFO, "ETI frame number %i Timestamp: %d + %f\n", +                        currentFrame, mnsc_time.tv_sec,  +                        (timestamp & 0xFFFFFF) / 16384000.0); +            } +            else { +                etiLog.print(TcpLog::INFO, "ETI frame number %i Time: %d, no TIST\n", +                        currentFrame, mnsc_time.tv_sec); +            }          }      }  EXIT:      etiLog.print(TcpLog::DBG, "exiting...\n"); +    fflush(stderr);      //fermeture des fichiers      for (subchannel = ensemble->subchannels.begin();              subchannel != ensemble->subchannels.end(); diff --git a/src/Eti.cpp b/src/Eti.cpp index 3dd11e2..74366e0 100644 --- a/src/Eti.cpp +++ b/src/Eti.cpp @@ -1,6 +1,9 @@  /*     Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right     of Canada (Communications Research Center Canada) + +   Includes modifications +   2012, Matthias P. Braendli, matthias.braendli@mpb.li     */  /*     This file is part of CRC-DabMux. @@ -25,6 +28,7 @@  #   pragma warning ( default : 4103 )  #else  #   include "Eti.h" +#   include <time.h>  #endif @@ -68,3 +72,34 @@ uint16_t eti_STC::getStartAddress()  {      return (uint16_t)((startAddress_high << 8) + startAddress_low);  } + +/* Helper functions for eti_MNSC_TIME_x which fill the time-relevant + * fields for the MNSC + */ +void eti_MNSC_TIME_1::setFromTime(struct tm *time_tm) +{ +    second_unit = time_tm->tm_sec % 10; +    second_tens = time_tm->tm_sec / 10; +     +    minute_unit = time_tm->tm_min % 10; +    minute_tens = time_tm->tm_min / 10; +} + +void eti_MNSC_TIME_2::setFromTime(struct tm *time_tm) +{ +    hour_unit = time_tm->tm_hour % 10; +    hour_tens = time_tm->tm_hour / 10; +     +    day_unit = time_tm->tm_mday % 10; +    day_tens = time_tm->tm_mday / 10; +} + +void eti_MNSC_TIME_3::setFromTime(struct tm *time_tm) +{ +    month_unit = (time_tm->tm_mon + 1) % 10; +    month_tens = (time_tm->tm_mon + 1) / 10; +     +    // They didn't see the y2k bug coming, did they ? +    year_unit = (time_tm->tm_year - 100) % 10; +    year_tens = (time_tm->tm_year - 100) / 10; +} @@ -1,6 +1,9 @@  /*     Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right     of Canada (Communications Research Center Canada) + +   Includes modifications +   2012, Matthias P. Braendli, matthias.braendli@mpb.li     */  /*     This file is part of CRC-DabMux. @@ -35,6 +38,7 @@ typedef DWORD32 uint32_t;  #   pragma pack(push, 1)  #else  #   include <stdint.h> +#   include <time.h>  #   define PACKED __attribute__ ((packed))  #endif @@ -93,4 +97,39 @@ struct eti_TIST {  } PACKED; +struct eti_MNSC_TIME_0 { +    uint32_t type:4; +    uint32_t identifier:4; +    uint32_t rfa:8; +} PACKED; + +struct eti_MNSC_TIME_1 { +    uint32_t second_unit:4; +    uint32_t second_tens:3; +    uint32_t accuracy:1; +     +    uint32_t minute_unit:4; +    uint32_t minute_tens:3; +    uint32_t sync_to_frame:1; +    void setFromTime(struct tm *time_tm); +} PACKED; + +struct eti_MNSC_TIME_2 { +    uint32_t hour_unit:4; +    uint32_t hour_tens:4; +     +    uint32_t day_unit:4; +    uint32_t day_tens:4; +    void setFromTime(struct tm *time_tm); +} PACKED; + +struct eti_MNSC_TIME_3 { +    uint32_t month_unit:4; +    uint32_t month_tens:4; +     +    uint32_t year_unit:4; +    uint32_t year_tens:4; +    void setFromTime(struct tm *time_tm); +} PACKED; +  #endif // ETI_ diff --git a/src/TcpLog.cpp b/src/TcpLog.cpp index 7161c92..9fc73b7 100644 --- a/src/TcpLog.cpp +++ b/src/TcpLog.cpp @@ -157,7 +157,7 @@ void TcpLog::printHeader(const int priority, const char *format, ...)          message.insert(pos, beginning);      } -    fprintf(stderr, message.c_str()); +    fprintf(stderr, "%s", message.c_str());      if (client != -1) {          if (write(client, message.c_str(), message.size())                  != (int)message.size()) { @@ -216,7 +216,7 @@ void TcpLog::print(const int priority, const char *format, ...)          message.insert(pos, beginning);      } -    fprintf(stderr, message.c_str()); +    fprintf(stderr, "%s", message.c_str());      if (client != -1) {          if (send(client, message.c_str(), message.size(), MSG_NOSIGNAL)                  != (int)message.size()) {  | 
