From 37f3f44cc1c0f5cf3a9b3f0ffc32f638b281994e Mon Sep 17 00:00:00 2001 From: "Matthias (think)" Date: Wed, 11 Jul 2012 11:53:28 +0200 Subject: included timestamp modifications for dabmux --- src/DabMux.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++------ src/Eti.cpp | 35 ++++++++++++++++ src/Eti.h | 39 ++++++++++++++++++ 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 : short label flag of service " " (default: 0xf040)\n"); fprintf(out, " -p protection : 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 #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; +} diff --git a/src/Eti.h b/src/Eti.h index 5580aaf..d8e4b82 100644 --- a/src/Eti.h +++ b/src/Eti.h @@ -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 +# include # 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()) { -- cgit v1.2.3