From 17f55e50e156c2d4c630cc7e18b1dedc88d78257 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 17 May 2014 17:40:41 +0200 Subject: Replace goto EXIT by new exception --- src/DabMux.cpp | 2785 +++++++++++++++++++++-------------------- src/dabOutput/edi/TagItems.h | 3 +- src/dabOutput/edi/TagPacket.h | 1 + 3 files changed, 1403 insertions(+), 1386 deletions(-) diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 31e5baf..b8c3fb6 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -135,6 +135,17 @@ using namespace std; /* Global stats server */ StatsServer* global_stats; +class MuxInitException : public exception +{ + public: + MuxInitException(const string m = "DABMUX initialisation error") throw() + : msg(m) {} + ~MuxInitException(void) throw() {} + const char* what() const throw() { return msg.c_str(); } + private: + string msg; +}; + static unsigned char Padding_FIB[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -330,696 +341,880 @@ int main(int argc, char *argv[]) bool MNSC_increment_time = false; - if (argc > 1 && strncmp(argv[1], "-e", 2) == 0) { // use external config file - try { + try { + if (argc > 1 && strncmp(argv[1], "-e", 2) == 0) { // use external config file + try { - if (argc != 3) { - printUsage(argv[0], stderr); - goto EXIT; - } + if (argc != 3) { + printUsage(argv[0], stderr); + throw MuxInitException(); + } - string conf_file = argv[2]; + string conf_file = argv[2]; - parse_configfile(conf_file, outputs, ensemble, &enableTist, &FICL, - &factumAnalyzer, &limit, &rc, &statsserverport); + parse_configfile(conf_file, outputs, ensemble, &enableTist, &FICL, + &factumAnalyzer, &limit, &rc, &statsserverport); + } + catch (runtime_error &e) { + etiLog.log(error, "Configuration file parsing error: %s\n", + e.what()); + throw MuxInitException(); + } } - catch (runtime_error &e) { - etiLog.log(error, "Configuration file parsing error: %s\n", - e.what()); - goto EXIT; - } - } - else { - if (!parse_cmdline(argv, argc, outputs, ensemble, &enableTist, &FICL, - &factumAnalyzer, &limit)) { - goto EXIT; + else { + if (!parse_cmdline(argv, argc, outputs, ensemble, &enableTist, &FICL, + &factumAnalyzer, &limit)) { + throw MuxInitException(); + } } - } - if (statsserverport != 0) { - global_stats = new StatsServer(statsserverport); - } - else { - global_stats = new StatsServer(); - } + if (statsserverport != 0) { + global_stats = new StatsServer(statsserverport); + } + else { + global_stats = new StatsServer(); + } - if (rc) { - ensemble->enrol_at(*rc); - } + if (rc) { + ensemble->enrol_at(*rc); + } - etiLog.level(info) << - PACKAGE_NAME << " " << + etiLog.level(info) << + PACKAGE_NAME << " " << #if defined(GITVERSION) - GITVERSION << + GITVERSION << #else - PACKAGE_VERSION << + PACKAGE_VERSION << #endif - " starting up"; - - if (outputs.size() == 0) { - etiLog.log(emerg, "no output defined"); - goto EXIT; - } + " starting up"; - // Check and adjust subchannels - { - set ids; - for (subchannel = ensemble->subchannels.begin(); - subchannel != ensemble->subchannels.end(); - ++subchannel) { - if (ids.find((*subchannel)->id) != ids.end()) { - etiLog.log(error, - "Subchannel %u is set more than once!\n", - (*subchannel)->id); - returnCode = -1; - goto EXIT; - } + if (outputs.size() == 0) { + etiLog.log(emerg, "no output defined"); + throw MuxInitException(); } - } - - // Check and adjust services and components - { - set ids; - for (service = ensemble->services.begin(); - service != ensemble->services.end(); - ++service) { - if (ids.find((*service)->id) != ids.end()) { - etiLog.log(error, - "Service id 0x%x (%u) is set more than once!\n", - (*service)->id, (*service)->id); - returnCode = -1; - goto EXIT; - } - // Get first component of this service - component = getComponent(ensemble->components, (*service)->id); - if (component == ensemble->components.end()) { - etiLog.log(error, - "Service id 0x%x (%u) includes no component!\n", - (*service)->id, (*service)->id); - returnCode = -1; - goto EXIT; + // Check and adjust subchannels + { + set ids; + for (subchannel = ensemble->subchannels.begin(); + subchannel != ensemble->subchannels.end(); + ++subchannel) { + if (ids.find((*subchannel)->id) != ids.end()) { + etiLog.log(error, + "Subchannel %u is set more than once!\n", + (*subchannel)->id); + returnCode = -1; + throw MuxInitException(); + } } + } - // Adjust service type from this first component - switch ((*service)->getType(ensemble)) { - case 0: // Audio - (*service)->program = true; - break; - case 1: - case 2: - case 3: - (*service)->program = false; - break; - default: - etiLog.log(error, - "Error, unknown service type: %u\n", (*service)->getType(ensemble)); - returnCode = -1; - goto EXIT; - } + // Check and adjust services and components + { + set ids; + for (service = ensemble->services.begin(); + service != ensemble->services.end(); + ++service) { + if (ids.find((*service)->id) != ids.end()) { + etiLog.log(error, + "Service id 0x%x (%u) is set more than once!\n", + (*service)->id, (*service)->id); + returnCode = -1; + throw MuxInitException(); + } - // Adjust components type for DAB+ - while (component != ensemble->components.end()) { - subchannel = - getSubchannel(ensemble->subchannels, (*component)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, "Error, service %u component " - "links to the invalid subchannel %u\n", - (*component)->serviceId, (*component)->subchId); + // Get first component of this service + component = getComponent(ensemble->components, (*service)->id); + if (component == ensemble->components.end()) { + etiLog.log(error, + "Service id 0x%x (%u) includes no component!\n", + (*service)->id, (*service)->id); returnCode = -1; - goto EXIT; + throw MuxInitException(); } - protection = &(*subchannel)->protection; - switch ((*subchannel)->type) { + // Adjust service type from this first component + switch ((*service)->getType(ensemble)) { case 0: // Audio - { - if (protection->form != 0) { - (*component)->type = 0x3f; // DAB+ - } - } + (*service)->program = true; break; case 1: case 2: case 3: + (*service)->program = false; break; default: etiLog.log(error, - "Error, unknown subchannel type\n"); + "Error, unknown service type: %u\n", (*service)->getType(ensemble)); returnCode = -1; - goto EXIT; + throw MuxInitException(); + } + + // Adjust components type for DAB+ + while (component != ensemble->components.end()) { + subchannel = + getSubchannel(ensemble->subchannels, (*component)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, "Error, service %u component " + "links to the invalid subchannel %u\n", + (*component)->serviceId, (*component)->subchId); + returnCode = -1; + throw MuxInitException(); + } + + protection = &(*subchannel)->protection; + switch ((*subchannel)->type) { + case 0: // Audio + { + if (protection->form != 0) { + (*component)->type = 0x3f; // DAB+ + } + } + break; + case 1: + case 2: + case 3: + break; + default: + etiLog.log(error, + "Error, unknown subchannel type\n"); + returnCode = -1; + throw MuxInitException(); + } + component = getComponent(ensemble->components, + (*service)->id, component); } - component = getComponent(ensemble->components, - (*service)->id, component); } } - } - for (output = outputs.begin(); output != outputs.end() ; ++output) { + for (output = outputs.begin(); output != outputs.end() ; ++output) { #if defined(HAVE_OUTPUT_FILE) - if ((*output)->outputProto == "file") { - (*output)->output = new DabOutputFile(); + if ((*output)->outputProto == "file") { + (*output)->output = new DabOutputFile(); #else // !defined(HAVE_OUTPUT_FILE) - if (0) { + if (0) { #endif // defined(HAVE_OUTPUT_FILE) #if defined(HAVE_OUTPUT_FIFO) - } else if ((*output)->outputProto == "fifo") { - (*output)->output = new DabOutputFifo(); + } else if ((*output)->outputProto == "fifo") { + (*output)->output = new DabOutputFifo(); #endif // !defined(HAVE_OUTPUT_FIFO) #if defined(HAVE_OUTPUT_RAW) - } else if ((*output)->outputProto == "raw") { - (*output)->output = new DabOutputRaw(); + } else if ((*output)->outputProto == "raw") { + (*output)->output = new DabOutputRaw(); #endif // defined(HAVE_OUTPUT_RAW) #if defined(HAVE_OUTPUT_UDP) - } else if ((*output)->outputProto == "udp") { - (*output)->output = new DabOutputUdp(); + } else if ((*output)->outputProto == "udp") { + (*output)->output = new DabOutputUdp(); #endif // defined(HAVE_OUTPUT_UDP) #if defined(HAVE_OUTPUT_TCP) - } else if ((*output)->outputProto == "tcp") { - (*output)->output = new DabOutputTcp(); + } else if ((*output)->outputProto == "tcp") { + (*output)->output = new DabOutputTcp(); #endif // defined(HAVE_OUTPUT_TCP) #if defined(HAVE_OUTPUT_SIMUL) - } else if ((*output)->outputProto == "simul") { - (*output)->output = new DabOutputSimul(); + } else if ((*output)->outputProto == "simul") { + (*output)->output = new DabOutputSimul(); #endif // defined(HAVE_OUTPUT_SIMUL) #if defined(HAVE_OUTPUT_ZEROMQ) - } else if ((*output)->outputProto == "zmq+tcp") { - (*output)->output = new DabOutputZMQ("tcp"); - } else if ((*output)->outputProto == "zmq+ipc") { - (*output)->output = new DabOutputZMQ("ipc"); - } else if ((*output)->outputProto == "zmq+pgm") { - (*output)->output = new DabOutputZMQ("pgm"); - } else if ((*output)->outputProto == "zmq+epgm") { - (*output)->output = new DabOutputZMQ("epgm"); + } else if ((*output)->outputProto == "zmq+tcp") { + (*output)->output = new DabOutputZMQ("tcp"); + } else if ((*output)->outputProto == "zmq+ipc") { + (*output)->output = new DabOutputZMQ("ipc"); + } else if ((*output)->outputProto == "zmq+pgm") { + (*output)->output = new DabOutputZMQ("pgm"); + } else if ((*output)->outputProto == "zmq+epgm") { + (*output)->output = new DabOutputZMQ("epgm"); #endif // defined(HAVE_OUTPUT_ZEROMQ) - } else { - etiLog.log(error, "Output protcol unknown: %s\n", - (*output)->outputProto.c_str()); - goto EXIT; - } + } else { + etiLog.log(error, "Output protcol unknown: %s\n", + (*output)->outputProto.c_str()); + throw MuxInitException(); + } - if ((*output)->output == NULL) { - etiLog.log(error, "Unable to init output %s://%s\n", - (*output)->outputProto.c_str(), (*output)->outputName.c_str()); - return -1; - } - if ((*output)->output->Open((*output)->outputName) - == -1) { - etiLog.log(error, "Unable to open output %s://%s\n", - (*output)->outputProto.c_str(), (*output)->outputName.c_str()); - return -1; + if ((*output)->output == NULL) { + etiLog.log(error, "Unable to init output %s://%s\n", + (*output)->outputProto.c_str(), (*output)->outputName.c_str()); + return -1; + } + if ((*output)->output->Open((*output)->outputName) + == -1) { + etiLog.log(error, "Unable to open output %s://%s\n", + (*output)->outputProto.c_str(), (*output)->outputName.c_str()); + return -1; + } } - } - // Prepare and check the data inputs - for (subchannel = ensemble->subchannels.begin(); - subchannel != ensemble->subchannels.end(); - ++subchannel) { - protection = &(*subchannel)->protection; - if (subchannel == ensemble->subchannels.begin()) { - (*subchannel)->startAddress = 0; - } else { - (*subchannel)->startAddress = (*(subchannel - 1))->startAddress + - getSizeCu(*(subchannel - 1)); + // Prepare and check the data inputs + for (subchannel = ensemble->subchannels.begin(); + subchannel != ensemble->subchannels.end(); + ++subchannel) { + protection = &(*subchannel)->protection; + if (subchannel == ensemble->subchannels.begin()) { + (*subchannel)->startAddress = 0; + } else { + (*subchannel)->startAddress = (*(subchannel - 1))->startAddress + + getSizeCu(*(subchannel - 1)); + } + if ((*subchannel)->input->open((*subchannel)->inputName) == -1) { + perror((*subchannel)->inputName); + returnCode = -1; + throw MuxInitException(); + } + + // TODO Check errors + result = (*subchannel)->input->setBitrate( (*subchannel)->bitrate); + if (result <= 0) { + etiLog.log(error, "can't set bitrate for source %s\n", + (*subchannel)->inputName); + returnCode = -1; + throw MuxInitException(); + } + (*subchannel)->bitrate = result; + + if (protection->form == 0) { + protection->form = 1; + for (int i = 0; i < 64; i++) { + if ((*subchannel)->bitrate == BitRateTable[i]) { + if (protection->level == ProtectionLevelTable[i]) { + protection->form = 0; + protection->shortForm.tableIndex = i; + } + } + } + } } - if ((*subchannel)->input->open((*subchannel)->inputName) == -1) { - perror((*subchannel)->inputName); + + if (ensemble->subchannels.size() == 0) { + etiLog.log(error, "can't multiplexed no subchannel!\n"); returnCode = -1; - goto EXIT; + throw MuxInitException(); } - // TODO Check errors - result = (*subchannel)->input->setBitrate( (*subchannel)->bitrate); - if (result <= 0) { - etiLog.log(error, "can't set bitrate for source %s\n", - (*subchannel)->inputName); + subchannel = ensemble->subchannels.end() - 1; + if ((*subchannel)->startAddress + getSizeCu((*subchannel)) > 864) { + etiLog.log(error, "Total size in CU exceeds 864\n"); + printSubchannels(ensemble->subchannels); returnCode = -1; - goto EXIT; + throw MuxInitException(); } - (*subchannel)->bitrate = result; - - if (protection->form == 0) { - protection->form = 1; - for (int i = 0; i < 64; i++) { - if ((*subchannel)->bitrate == BitRateTable[i]) { - if (protection->level == ProtectionLevelTable[i]) { - protection->form = 0; - protection->shortForm.tableIndex = i; - } - } + + // Init packet components SCId + cur = 0; + for (component = ensemble->components.begin(); + component != ensemble->components.end(); + ++component) { + subchannel = getSubchannel(ensemble->subchannels, + (*component)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, + "Subchannel %i does not exist for component " + "of service %i\n", + (*component)->subchId, (*component)->serviceId); + returnCode = -1; + throw MuxInitException(); } + if ((*subchannel)->type != 3) continue; + + (*component)->packet.id = cur++; } - } - if (ensemble->subchannels.size() == 0) { - etiLog.log(error, "can't multiplexed no subchannel!\n"); - returnCode = -1; - goto EXIT; - } + // Print settings before starting + etiLog.log(info, "--- Multiplex configuration ---"); + printEnsemble(ensemble); - subchannel = ensemble->subchannels.end() - 1; - if ((*subchannel)->startAddress + getSizeCu((*subchannel)) > 864) { - etiLog.log(error, "Total size in CU exceeds 864\n"); + etiLog.log(info, "--- Subchannels list ---"); printSubchannels(ensemble->subchannels); - returnCode = -1; - goto EXIT; - } - // Init packet components SCId - cur = 0; - for (component = ensemble->components.begin(); - component != ensemble->components.end(); - ++component) { - subchannel = getSubchannel(ensemble->subchannels, - (*component)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "Subchannel %i does not exist for component " - "of service %i\n", - (*component)->subchId, (*component)->serviceId); - returnCode = -1; - goto EXIT; - } - if ((*subchannel)->type != 3) continue; + etiLog.log(info, "--- Services list ---"); + printServices(ensemble->services); - (*component)->packet.id = cur++; - } + etiLog.log(info, "--- Components list ---"); + printComponents(ensemble->components); - // Print settings before starting - etiLog.log(info, "--- Multiplex configuration ---"); - printEnsemble(ensemble); + etiLog.log(info, "--- Output list ---"); + printOutputs(outputs); - etiLog.log(info, "--- Subchannels list ---"); - printSubchannels(ensemble->subchannels); - etiLog.log(info, "--- Services list ---"); - printServices(ensemble->services); + /* These iterators are used to fill the respective FIG. + * It is necessary to cycle through all the FIGs that have + * to be transmitted because they do not fit in a single + * FIB. + * + * ETSI EN 300 799 Clauses 5.2 and 8.1 + */ + serviceProgFIG0_2 = ensemble->services.end(); + serviceDataFIG0_2 = ensemble->services.end(); + componentProgFIG0_8 = ensemble->components.end(); + componentFIG0_13 = ensemble->components.end(); + componentDataFIG0_8 = ensemble->components.end(); + serviceFIG0_17 = ensemble->services.end(); + subchannelFIG0_1 = ensemble->subchannels.end(); - etiLog.log(info, "--- Components list ---"); - printComponents(ensemble->components); - etiLog.log(info, "--- Output list ---"); - printOutputs(outputs); + /* Each iteration of the main loop creates one ETI frame */ +#if EDI_DEBUG + std::ofstream edi_debug_file("./edi.debug"); +#endif + for (currentFrame = 0; running; currentFrame++) { + if ((limit > 0) && (currentFrame >= limit)) { + break; + } - /* These iterators are used to fill the respective FIG. - * It is necessary to cycle through all the FIGs that have - * to be transmitted because they do not fit in a single - * FIB. - * - * ETSI EN 300 799 Clauses 5.2 and 8.1 - */ - serviceProgFIG0_2 = ensemble->services.end(); - serviceDataFIG0_2 = ensemble->services.end(); - componentProgFIG0_8 = ensemble->components.end(); - componentFIG0_13 = ensemble->components.end(); - componentDataFIG0_8 = ensemble->components.end(); - serviceFIG0_17 = ensemble->services.end(); - subchannelFIG0_1 = ensemble->subchannels.end(); + // For EDI, save ETI(LI) Management data into a TAG Item DETI + TagDETI edi_tagDETI; + TagStarPTR edi_tagStarPtr; + list edi_subchannels; + map edi_subchannelToTag; + // The above Tag Items will be assembled into a TAG Packet + TagPacket edi_tagpacket; - /* Each iteration of the main loop creates one ETI frame */ -#if EDI_DEBUG - std::ofstream edi_debug_file("./edi.debug"); -#endif + // The TagPacket will then be placed into an AFPacket + AFPacket edi_afPacket(EDI_AFPACKET_PROTOCOLTYPE_TAGITEMS); - for (currentFrame = 0; running; currentFrame++) { - if ((limit > 0) && (currentFrame >= limit)) { - break; - } + edi_tagDETI.atstf = 0; // TODO add ATST support - // For EDI, save ETI(LI) Management data into a TAG Item DETI - TagDETI edi_tagDETI; - TagStarPTR edi_tagStarPtr; - list edi_subchannels; - map edi_subchannelToTag; - // The above Tag Items will be assembled into a TAG Packet - TagPacket edi_tagpacket; + date = getDabTime(); - // The TagPacket will then be placed into an AFPacket - AFPacket edi_afPacket(EDI_AFPACKET_PROTOCOLTYPE_TAGITEMS); + // Initialise the ETI frame + memset(etiFrame, 0, 6144); - edi_tagDETI.atstf = 0; // TODO add ATST support + /********************************************************************** + ********** Section SYNC of ETI(NI, G703) ************************* + **********************************************************************/ + // See ETS 300 799 Clause 6 + eti_SYNC *etiSync = (eti_SYNC *) etiFrame; - date = getDabTime(); + etiSync->ERR = edi_tagDETI.stat = 0xFF; // ETS 300 799, 5.2, no error - // Initialise the ETI frame - memset(etiFrame, 0, 6144); + //****** Field FSYNC *****// + // See ETS 300 799, 6.2.1.2 + sync ^= 0xffffff; + etiSync->FSYNC = sync; - /********************************************************************** - ********** Section SYNC of ETI(NI, G703) ************************* - **********************************************************************/ + /********************************************************************** + *********** Section LIDATA of ETI(NI, G703) ********************** + **********************************************************************/ - // See ETS 300 799 Clause 6 - eti_SYNC *etiSync = (eti_SYNC *) etiFrame; + // See ETS 300 799 Figure 5 for a better overview of these fields. - etiSync->ERR = edi_tagDETI.stat = 0xFF; // ETS 300 799, 5.2, no error + //****** Section FC ***************************************************/ + // 4 octets, starts at offset 4 + eti_FC *fc = (eti_FC *) &etiFrame[4]; - //****** Field FSYNC *****// - // See ETS 300 799, 6.2.1.2 - sync ^= 0xffffff; - etiSync->FSYNC = sync; + //****** FCT ******// + // Incremente for each frame, overflows at 249 + fc->FCT = currentFrame % 250; + edi_tagDETI.dflc = currentFrame % 5000; - /********************************************************************** - *********** Section LIDATA of ETI(NI, G703) ********************** - **********************************************************************/ + //****** FICF ******// + // Fast Information Channel Flag, 1 bit, =1 if FIC present + fc->FICF = edi_tagDETI.ficf = 1; - // See ETS 300 799 Figure 5 for a better overview of these fields. + //****** NST ******// + /* Number of audio of data sub-channels, 7 bits, 0-64. + * In the 15-frame period immediately preceding a multiplex + * re-configuration, NST can take the value 0 (see annex E). + */ + fc->NST = ensemble->subchannels.size(); - //****** Section FC ***************************************************/ - // 4 octets, starts at offset 4 - eti_FC *fc = (eti_FC *) &etiFrame[4]; + //****** FP ******// + /* Frame Phase, 3 bit counter, tells the COFDM generator + * when to insert the TII. Is also used by the MNSC. + */ + fc->FP = edi_tagDETI.fp = currentFrame & 0x7; - //****** FCT ******// - // Incremente for each frame, overflows at 249 - fc->FCT = edi_tagDETI.fct = currentFrame % 250; + //****** MID ******// + //Mode Identity, 2 bits, 01 ModeI, 10 modeII, 11 ModeIII, 00 ModeIV + fc->MID = edi_tagDETI.mid = ensemble->mode; //mode 2 needs 3 FIB, 3*32octets = 96octets - //****** FICF ******// - // Fast Information Channel Flag, 1 bit, =1 if FIC present - fc->FICF = edi_tagDETI.ficf = 1; + //****** FL ******// + /* Frame Length, 11 bits, nb of words(4 bytes) in STC, EOH and MST + * if NST=0, FL=1+FICL words, FICL=24 or 32 depending on the mode. + * The FL is given in words (4 octets), see ETS 300 799 5.3.6 for details + */ + FLtmp = 1 + FICL + (fc->NST); - //****** NST ******// - /* Number of audio of data sub-channels, 7 bits, 0-64. - * In the 15-frame period immediately preceding a multiplex - * re-configuration, NST can take the value 0 (see annex E). - */ - fc->NST = ensemble->subchannels.size(); + for (subchannel = ensemble->subchannels.begin(); + subchannel != ensemble->subchannels.end(); + ++subchannel) { + // Add STLsbch + FLtmp += getSizeWord(*subchannel); + } - //****** FP ******// - /* Frame Phase, 3 bit counter, tells the COFDM generator - * when to insert the TII. Is also used by the MNSC. - */ - fc->FP = edi_tagDETI.fp = currentFrame & 0x7; + fc->setFrameLength(FLtmp); + index = 8; - //****** MID ******// - //Mode Identity, 2 bits, 01 ModeI, 10 modeII, 11 ModeIII, 00 ModeIV - fc->MID = edi_tagDETI.mid = ensemble->mode; //mode 2 needs 3 FIB, 3*32octets = 96octets + /******* Section STC **************************************************/ + // Stream Characterization, + // number of channel * 4 octets = nb octets total + int edi_stream_id = 0; + for (subchannel = ensemble->subchannels.begin(); + subchannel != ensemble->subchannels.end(); + ++subchannel) { + protection = &(*subchannel)->protection; + eti_STC *sstc = (eti_STC *) & etiFrame[index]; - //****** FL ******// - /* Frame Length, 11 bits, nb of words(4 bytes) in STC, EOH and MST - * if NST=0, FL=1+FICL words, FICL=24 or 32 depending on the mode. - * The FL is given in words (4 octets), see ETS 300 799 5.3.6 for details - */ - FLtmp = 1 + FICL + (fc->NST); + sstc->SCID = (*subchannel)->id; + sstc->startAddress_high = (*subchannel)->startAddress / 256; + sstc->startAddress_low = (*subchannel)->startAddress % 256; + //devrait changer selon le mode de protection desire + if (protection->form == 0) { + sstc->TPL = 0x10 | + ProtectionLevelTable[protection->shortForm.tableIndex]; + } else { + sstc->TPL = 0x20 | + (protection->longForm.option << 2) | + (protection->level); + } + //Sub-channel Stream Length, multiple de 64 bits + sstc->STL_high = getSizeDWord(*subchannel) / 256; + sstc->STL_low = getSizeDWord(*subchannel) % 256; + + TagESTn tag_ESTn(edi_stream_id++); + tag_ESTn.scid = (*subchannel)->id; + tag_ESTn.sad = (*subchannel)->startAddress; + tag_ESTn.tpl = sstc->TPL; + tag_ESTn.rfa = 0; // two bits + tag_ESTn.mst_length = getSizeByte(*subchannel) / 8; + assert(getSizeByte(*subchannel) % 8 == 0); + + edi_subchannels.push_back(tag_ESTn); + edi_subchannelToTag[*subchannel] = &tag_ESTn; + index += 4; + } - for (subchannel = ensemble->subchannels.begin(); - subchannel != ensemble->subchannels.end(); - ++subchannel) { - // Add STLsbch - FLtmp += getSizeWord(*subchannel); - } + /******* Section EOH **************************************************/ + // End of Header 4 octets + eti_EOH *eoh = (eti_EOH *) & etiFrame[index]; - fc->setFrameLength(FLtmp); - index = 8; + //MNSC Multiplex Network Signalling Channel, 2 octets - /******* Section STC **************************************************/ - // Stream Characterization, - // number of channel * 4 octets = nb octets total - int edi_stream_id = 0; - for (subchannel = ensemble->subchannels.begin(); - subchannel != ensemble->subchannels.end(); - ++subchannel) { - protection = &(*subchannel)->protection; - eti_STC *sstc = (eti_STC *) & etiFrame[index]; + eoh->MNSC = 0; - sstc->SCID = (*subchannel)->id; - sstc->startAddress_high = (*subchannel)->startAddress / 256; - sstc->startAddress_low = (*subchannel)->startAddress % 256; - //devrait changer selon le mode de protection desire - if (protection->form == 0) { - sstc->TPL = 0x10 | - ProtectionLevelTable[protection->shortForm.tableIndex]; - } else { - sstc->TPL = 0x20 | - (protection->longForm.option << 2) | - (protection->level); + 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; } - //Sub-channel Stream Length, multiple de 64 bits - sstc->STL_high = getSizeDWord(*subchannel) / 256; - sstc->STL_low = getSizeDWord(*subchannel) % 256; - - TagESTn tag_ESTn(edi_stream_id++); - tag_ESTn.scid = (*subchannel)->id; - tag_ESTn.sad = (*subchannel)->startAddress; - tag_ESTn.tpl = sstc->TPL; - tag_ESTn.rfa = 0; // two bits - tag_ESTn.mst_length = getSizeByte(*subchannel) / 8; - assert(getSizeByte(*subchannel) % 8 == 0); - - edi_subchannels.push_back(tag_ESTn); - edi_subchannelToTag[*subchannel] = &tag_ESTn; - index += 4; - } - /******* Section EOH **************************************************/ - // End of Header 4 octets - eti_EOH *eoh = (eti_EOH *) & etiFrame[index]; + edi_tagDETI.mnsc = eoh->MNSC; + + //CRC Cyclic Redundancy Checksum du FC, STC et MNSC, 2 octets + nbBytesCRC = 4 + ((fc->NST) * 4) + 2; - //MNSC Multiplex Network Signalling Channel, 2 octets + CRCtmp = 0xffff; + CRCtmp = crc16(CRCtmp, &etiFrame[4], nbBytesCRC); + CRCtmp ^= 0xffff; + eoh->CRC = htons(CRCtmp); - eoh->MNSC = 0; + /******* Section MST **************************************************/ + // Main Stream Data, si FICF=1 alors les 96 ou 128 premiers octets + // transportent le FIC selon le mode + index = ((fc->NST) + 2 + 1) * 4; + edi_tagDETI.fic_data = &etiFrame[index]; + edi_tagDETI.fic_length = FICL; + + //Insertion du FIC + FIGtype0* fig0; + FIGtype0_0 *fig0_0; + FIGtype0_1 *figtype0_1; + + FIG_01_SubChannel_ShortF *fig0_1subchShort; + FIG_01_SubChannel_LongF *fig0_1subchLong1; + + FIGtype0_2 *fig0_2; + + FIGtype0_2_Service *fig0_2serviceAudio; + FIGtype0_2_Service_data *fig0_2serviceData; + FIGtype0_2_audio_component* audio_description; + FIGtype0_2_data_component* data_description; + FIGtype0_2_packet_component* packet_description; + + FIGtype0_3_header *fig0_3_header; + FIGtype0_3_data *fig0_3_data; + FIGtype0_9 *fig0_9; + FIGtype0_10 *fig0_10; + FIGtype0_17_programme *programme; + + FIGtype1_0 *fig1_0; + FIGtype1_1 *fig1_1; + FIGtype1_5 *fig1_5; + + tm* timeData; + + unsigned char figSize = 0; + + //Insertion du FIB 0 + switch (insertFIG) { - 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; - } - { + case 4: + // FIG type 0/0, Multiplex Configuration Info (MCI), + // Ensemble information + fig0_0 = (FIGtype0_0 *) & etiFrame[index]; + + fig0_0->FIGtypeNumber = 0; + fig0_0->Length = 5; + fig0_0->CN = 0; + fig0_0->OE = 0; + fig0_0->PD = 0; + fig0_0->Extension = 0; + + fig0_0->EId = htons(ensemble->id); + fig0_0->Change = 0; + fig0_0->Al = 0; + fig0_0->CIFcnt_hight = (currentFrame / 250) % 20; + fig0_0->CIFcnt_low = (currentFrame % 250); + index = index + 6; + figSize += 6; - 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); + // FIG type 0/1, MIC, Sub-Channel Organization, une instance de la + // sous-partie par sous-canal + figtype0_1 = (FIGtype0_1 *) & etiFrame[index]; + + figtype0_1->FIGtypeNumber = 0; + figtype0_1->Length = 1; + figtype0_1->CN = 0; + figtype0_1->OE = 0; + figtype0_1->PD = 0; + figtype0_1->Extension = 1; + index = index + 2; + figSize += 2; + + //Sous-partie du FIG type 0/1 + if (subchannelFIG0_1 == ensemble->subchannels.end()) { + subchannelFIG0_1 = ensemble->subchannels.begin(); } - break; - case 3: - { - eti_MNSC_TIME_3 *mnsc = (eti_MNSC_TIME_3 *) &eoh->MNSC; - mnsc->setFromTime(time_tm); + for (; subchannelFIG0_1 != ensemble->subchannels.end(); + ++subchannelFIG0_1) { + protection = &(*subchannelFIG0_1)->protection; + + if ((protection->form == 0 && figSize > 27) || + (protection->form != 0 && figSize > 26)) { + break; + } + + if (protection->form == 0) { + fig0_1subchShort = + (FIG_01_SubChannel_ShortF*) &etiFrame[index]; + fig0_1subchShort->SubChId = (*subchannelFIG0_1)->id; + fig0_1subchShort->StartAdress_high = + (*subchannelFIG0_1)->startAddress / 256; + fig0_1subchShort->StartAdress_low = + (*subchannelFIG0_1)->startAddress % 256; + fig0_1subchShort->Short_Long_form = 0; + fig0_1subchShort->TableSwitch = 0; + fig0_1subchShort->TableIndex = + protection->shortForm.tableIndex; + + index = index + 3; + figSize += 3; + figtype0_1->Length += 3; + } else { + fig0_1subchLong1 = + (FIG_01_SubChannel_LongF*) &etiFrame[index]; + fig0_1subchLong1->SubChId = (*subchannelFIG0_1)->id; + fig0_1subchLong1->StartAdress_high = + (*subchannelFIG0_1)->startAddress / 256; + fig0_1subchLong1->StartAdress_low = + (*subchannelFIG0_1)->startAddress % 256; + fig0_1subchLong1->Short_Long_form = 1; + fig0_1subchLong1->Option = protection->longForm.option; + fig0_1subchLong1->ProtectionLevel = + protection->level; + fig0_1subchLong1->Sub_ChannelSize_high = + getSizeCu(*subchannelFIG0_1) / 256; + fig0_1subchLong1->Sub_ChannelSize_low = + getSizeCu(*subchannelFIG0_1) % 256; + + index = index + 4; + figSize += 4; + figtype0_1->Length += 4; + } } break; - } - edi_tagDETI.mnsc = eoh->MNSC; - - //CRC Cyclic Redundancy Checksum du FC, STC et MNSC, 2 octets - nbBytesCRC = 4 + ((fc->NST) * 4) + 2; - - CRCtmp = 0xffff; - CRCtmp = crc16(CRCtmp, &etiFrame[4], nbBytesCRC); - CRCtmp ^= 0xffff; - eoh->CRC = htons(CRCtmp); - - /******* Section MST **************************************************/ - // Main Stream Data, si FICF=1 alors les 96 ou 128 premiers octets - // transportent le FIC selon le mode - index = ((fc->NST) + 2 + 1) * 4; - edi_tagDETI.fic_data = &etiFrame[index]; - edi_tagDETI.fic_length = FICL; - - //Insertion du FIC - FIGtype0* fig0; - FIGtype0_0 *fig0_0; - FIGtype0_1 *figtype0_1; - - FIG_01_SubChannel_ShortF *fig0_1subchShort; - FIG_01_SubChannel_LongF *fig0_1subchLong1; - - FIGtype0_2 *fig0_2; - - FIGtype0_2_Service *fig0_2serviceAudio; - FIGtype0_2_Service_data *fig0_2serviceData; - FIGtype0_2_audio_component* audio_description; - FIGtype0_2_data_component* data_description; - FIGtype0_2_packet_component* packet_description; - - FIGtype0_3_header *fig0_3_header; - FIGtype0_3_data *fig0_3_data; - FIGtype0_9 *fig0_9; - FIGtype0_10 *fig0_10; - FIGtype0_17_programme *programme; - - FIGtype1_0 *fig1_0; - FIGtype1_1 *fig1_1; - FIGtype1_5 *fig1_5; - - tm* timeData; - - unsigned char figSize = 0; - - //Insertion du FIB 0 - switch (insertFIG) { - - case 0: - case 4: - // FIG type 0/0, Multiplex Configuration Info (MCI), - // Ensemble information - fig0_0 = (FIGtype0_0 *) & etiFrame[index]; - - fig0_0->FIGtypeNumber = 0; - fig0_0->Length = 5; - fig0_0->CN = 0; - fig0_0->OE = 0; - fig0_0->PD = 0; - fig0_0->Extension = 0; - - fig0_0->EId = htons(ensemble->id); - fig0_0->Change = 0; - fig0_0->Al = 0; - fig0_0->CIFcnt_hight = (currentFrame / 250) % 20; - fig0_0->CIFcnt_low = (currentFrame % 250); - index = index + 6; - figSize += 6; - - break; - - case 1: - // FIG type 0/1, MIC, Sub-Channel Organization, une instance de la - // sous-partie par sous-canal - figtype0_1 = (FIGtype0_1 *) & etiFrame[index]; - - figtype0_1->FIGtypeNumber = 0; - figtype0_1->Length = 1; - figtype0_1->CN = 0; - figtype0_1->OE = 0; - figtype0_1->PD = 0; - figtype0_1->Extension = 1; - index = index + 2; - figSize += 2; - - //Sous-partie du FIG type 0/1 - if (subchannelFIG0_1 == ensemble->subchannels.end()) { - subchannelFIG0_1 = ensemble->subchannels.begin(); - } - for (; subchannelFIG0_1 != ensemble->subchannels.end(); - ++subchannelFIG0_1) { - protection = &(*subchannelFIG0_1)->protection; + case 2: + // FIG type 0/2, MCI, Service Organization, une instance de + // FIGtype0_2_Service par sous-canal + fig0_2 = NULL; + cur = 0; - if ((protection->form == 0 && figSize > 27) || - (protection->form != 0 && figSize > 26)) { - break; + if (serviceProgFIG0_2 == ensemble->services.end()) { + serviceProgFIG0_2 = ensemble->services.begin(); } + for (; serviceProgFIG0_2 != ensemble->services.end(); + ++serviceProgFIG0_2) { + if (!(*serviceProgFIG0_2)->nbComponent(ensemble->components)) { + continue; + } + if ((*serviceProgFIG0_2)->getType(ensemble) != 0) { + continue; + } - if (protection->form == 0) { - fig0_1subchShort = - (FIG_01_SubChannel_ShortF*) &etiFrame[index]; - fig0_1subchShort->SubChId = (*subchannelFIG0_1)->id; - fig0_1subchShort->StartAdress_high = - (*subchannelFIG0_1)->startAddress / 256; - fig0_1subchShort->StartAdress_low = - (*subchannelFIG0_1)->startAddress % 256; - fig0_1subchShort->Short_Long_form = 0; - fig0_1subchShort->TableSwitch = 0; - fig0_1subchShort->TableIndex = - protection->shortForm.tableIndex; - - index = index + 3; + ++cur; + + if (fig0_2 == NULL) { + fig0_2 = (FIGtype0_2 *) & etiFrame[index]; + + fig0_2->FIGtypeNumber = 0; + fig0_2->Length = 1; + fig0_2->CN = 0; + fig0_2->OE = 0; + fig0_2->PD = 0; + fig0_2->Extension = 2; + index = index + 2; + figSize += 2; + } + + if (figSize + 3 + + (*serviceProgFIG0_2)->nbComponent(ensemble->components) + * 2 > 30) { + break; + } + + fig0_2serviceAudio = (FIGtype0_2_Service*) &etiFrame[index]; + + fig0_2serviceAudio->SId = htons((*serviceProgFIG0_2)->id); + fig0_2serviceAudio->Local_flag = 0; + fig0_2serviceAudio->CAId = 0; + fig0_2serviceAudio->NbServiceComp = + (*serviceProgFIG0_2)->nbComponent(ensemble->components); + index += 3; + fig0_2->Length += 3; figSize += 3; - figtype0_1->Length += 3; - } else { - fig0_1subchLong1 = - (FIG_01_SubChannel_LongF*) &etiFrame[index]; - fig0_1subchLong1->SubChId = (*subchannelFIG0_1)->id; - fig0_1subchLong1->StartAdress_high = - (*subchannelFIG0_1)->startAddress / 256; - fig0_1subchLong1->StartAdress_low = - (*subchannelFIG0_1)->startAddress % 256; - fig0_1subchLong1->Short_Long_form = 1; - fig0_1subchLong1->Option = protection->longForm.option; - fig0_1subchLong1->ProtectionLevel = - protection->level; - fig0_1subchLong1->Sub_ChannelSize_high = - getSizeCu(*subchannelFIG0_1) / 256; - fig0_1subchLong1->Sub_ChannelSize_low = - getSizeCu(*subchannelFIG0_1) % 256; - - index = index + 4; - figSize += 4; - figtype0_1->Length += 4; - } - } - break; - case 2: - // FIG type 0/2, MCI, Service Organization, une instance de - // FIGtype0_2_Service par sous-canal - fig0_2 = NULL; - cur = 0; + int curCpnt = 0; + for (component = getComponent(ensemble->components, + (*serviceProgFIG0_2)->id); + component != ensemble->components.end(); + component = getComponent(ensemble->components, + (*serviceProgFIG0_2)->id, component)) { + subchannel = getSubchannel(ensemble->subchannels, + (*component)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, + "Subchannel %i does not exist for component " + "of service %i\n", + (*component)->subchId, (*component)->serviceId); + returnCode = -1; + throw MuxInitException(); + } - if (serviceProgFIG0_2 == ensemble->services.end()) { - serviceProgFIG0_2 = ensemble->services.begin(); - } - for (; serviceProgFIG0_2 != ensemble->services.end(); - ++serviceProgFIG0_2) { - if (!(*serviceProgFIG0_2)->nbComponent(ensemble->components)) { - continue; + switch ((*subchannel)->type) { + case 0: // Audio + audio_description = + (FIGtype0_2_audio_component*)&etiFrame[index]; + audio_description->TMid = 0; + audio_description->ASCTy = (*component)->type; + audio_description->SubChId = (*subchannel)->id; + audio_description->PS = ((curCpnt == 0) ? 1 : 0); + audio_description->CA_flag = 0; + break; + case 1: // Data + data_description = + (FIGtype0_2_data_component*)&etiFrame[index]; + data_description->TMid = 1; + data_description->DSCTy = (*component)->type; + data_description->SubChId = (*subchannel)->id; + data_description->PS = ((curCpnt == 0) ? 1 : 0); + data_description->CA_flag = 0; + break; + case 3: // Packet + packet_description = + (FIGtype0_2_packet_component*)&etiFrame[index]; + packet_description->TMid = 3; + packet_description->setSCId((*component)->packet.id); + packet_description->PS = ((curCpnt == 0) ? 1 : 0); + packet_description->CA_flag = 0; + break; + default: + etiLog.log(error, + "Component type not supported\n"); + returnCode = -1; + throw MuxInitException(); + } + index += 2; + fig0_2->Length += 2; + figSize += 2; + if (figSize > 30) { + etiLog.log(error, + "Sorry, no place left in FIG 0/2 to insert " + "component %i of program service %i.\n", + curCpnt, cur); + returnCode = -1; + throw MuxInitException(); + } + ++curCpnt; + } } - if ((*serviceProgFIG0_2)->getType(ensemble) != 0) { - continue; + break; + + case 3: + fig0_2 = NULL; + cur = 0; + + if (serviceDataFIG0_2 == ensemble->services.end()) { + serviceDataFIG0_2 = ensemble->services.begin(); } + for (; serviceDataFIG0_2 != ensemble->services.end(); + ++serviceDataFIG0_2) { + if (!(*serviceDataFIG0_2)->nbComponent(ensemble->components)) { + continue; + } + unsigned char type = (*serviceDataFIG0_2)->getType(ensemble); + if ((type == 0) || (type == 2)) { + continue; + } - ++cur; + ++cur; - if (fig0_2 == NULL) { - fig0_2 = (FIGtype0_2 *) & etiFrame[index]; + if (fig0_2 == NULL) { + fig0_2 = (FIGtype0_2 *) & etiFrame[index]; - fig0_2->FIGtypeNumber = 0; - fig0_2->Length = 1; - fig0_2->CN = 0; - fig0_2->OE = 0; - fig0_2->PD = 0; - fig0_2->Extension = 2; - index = index + 2; - figSize += 2; - } + fig0_2->FIGtypeNumber = 0; + fig0_2->Length = 1; + fig0_2->CN = 0; + fig0_2->OE = 0; + fig0_2->PD = 1; + fig0_2->Extension = 2; + index = index + 2; + figSize += 2; + } - if (figSize + 3 - + (*serviceProgFIG0_2)->nbComponent(ensemble->components) - * 2 > 30) { - break; - } + if (figSize + 5 + + (*serviceDataFIG0_2)->nbComponent(ensemble->components) + * 2 > 30) { + break; + } + + fig0_2serviceData = + (FIGtype0_2_Service_data*) &etiFrame[index]; + + fig0_2serviceData->SId = htonl((*serviceDataFIG0_2)->id); + fig0_2serviceData->Local_flag = 0; + fig0_2serviceData->CAId = 0; + fig0_2serviceData->NbServiceComp = + (*serviceDataFIG0_2)->nbComponent(ensemble->components); + fig0_2->Length += 5; + index += 5; + figSize += 5; + + int curCpnt = 0; + for (component = getComponent(ensemble->components, + (*serviceDataFIG0_2)->id); + component != ensemble->components.end(); + component = getComponent(ensemble->components, + (*serviceDataFIG0_2)->id, component)) { + subchannel = getSubchannel(ensemble->subchannels, + (*component)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, + "Subchannel %i does not exist for component " + "of service %i\n", + (*component)->subchId, (*component)->serviceId); + returnCode = -1; + throw MuxInitException(); + } - fig0_2serviceAudio = (FIGtype0_2_Service*) &etiFrame[index]; + switch ((*subchannel)->type) { + case 0: // Audio + audio_description = + (FIGtype0_2_audio_component*)&etiFrame[index]; + audio_description->TMid = 0; + audio_description->ASCTy = (*component)->type; + audio_description->SubChId = (*subchannel)->id; + audio_description->PS = ((curCpnt == 0) ? 1 : 0); + audio_description->CA_flag = 0; + break; + case 1: // Data + data_description = + (FIGtype0_2_data_component*)&etiFrame[index]; + data_description->TMid = 1; + data_description->DSCTy = (*component)->type; + data_description->SubChId = (*subchannel)->id; + data_description->PS = ((curCpnt == 0) ? 1 : 0); + data_description->CA_flag = 0; + break; + case 3: // Packet + packet_description = + (FIGtype0_2_packet_component*)&etiFrame[index]; + packet_description->TMid = 3; + packet_description->setSCId((*component)->packet.id); + packet_description->PS = ((curCpnt == 0) ? 1 : 0); + packet_description->CA_flag = 0; + break; + default: + etiLog.log(error, + "Component type not supported\n"); + returnCode = -1; + throw MuxInitException(); + } + index += 2; + fig0_2->Length += 2; + figSize += 2; + if (figSize > 30) { + etiLog.log(error, + "Sorry, no place left in FIG 0/2 to insert " + "component %i of data service %i.\n", + curCpnt, cur); + returnCode = -1; + throw MuxInitException(); + } + ++curCpnt; + } + } + break; - fig0_2serviceAudio->SId = htons((*serviceProgFIG0_2)->id); - fig0_2serviceAudio->Local_flag = 0; - fig0_2serviceAudio->CAId = 0; - fig0_2serviceAudio->NbServiceComp = - (*serviceProgFIG0_2)->nbComponent(ensemble->components); - index += 3; - fig0_2->Length += 3; - figSize += 3; + case 5: + fig0_3_header = NULL; - int curCpnt = 0; - for (component = getComponent(ensemble->components, - (*serviceProgFIG0_2)->id); + for (component = ensemble->components.begin(); component != ensemble->components.end(); - component = getComponent(ensemble->components, - (*serviceProgFIG0_2)->id, component)) { + ++component) { subchannel = getSubchannel(ensemble->subchannels, (*component)->subchId); if (subchannel == ensemble->subchannels.end()) { @@ -1028,531 +1223,161 @@ int main(int argc, char *argv[]) "of service %i\n", (*component)->subchId, (*component)->serviceId); returnCode = -1; - goto EXIT; + throw MuxInitException(); } - switch ((*subchannel)->type) { - case 0: // Audio - audio_description = - (FIGtype0_2_audio_component*)&etiFrame[index]; - audio_description->TMid = 0; - audio_description->ASCTy = (*component)->type; - audio_description->SubChId = (*subchannel)->id; - audio_description->PS = ((curCpnt == 0) ? 1 : 0); - audio_description->CA_flag = 0; - break; - case 1: // Data - data_description = - (FIGtype0_2_data_component*)&etiFrame[index]; - data_description->TMid = 1; - data_description->DSCTy = (*component)->type; - data_description->SubChId = (*subchannel)->id; - data_description->PS = ((curCpnt == 0) ? 1 : 0); - data_description->CA_flag = 0; - break; - case 3: // Packet - packet_description = - (FIGtype0_2_packet_component*)&etiFrame[index]; - packet_description->TMid = 3; - packet_description->setSCId((*component)->packet.id); - packet_description->PS = ((curCpnt == 0) ? 1 : 0); - packet_description->CA_flag = 0; - break; - default: - etiLog.log(error, - "Component type not supported\n"); - returnCode = -1; - goto EXIT; - } - index += 2; - fig0_2->Length += 2; - figSize += 2; - if (figSize > 30) { - etiLog.log(error, - "Sorry, no place left in FIG 0/2 to insert " - "component %i of program service %i.\n", - curCpnt, cur); - returnCode = -1; - goto EXIT; - } - ++curCpnt; - } - } - break; - - case 3: - fig0_2 = NULL; - cur = 0; - - if (serviceDataFIG0_2 == ensemble->services.end()) { - serviceDataFIG0_2 = ensemble->services.begin(); - } - for (; serviceDataFIG0_2 != ensemble->services.end(); - ++serviceDataFIG0_2) { - if (!(*serviceDataFIG0_2)->nbComponent(ensemble->components)) { - continue; - } - unsigned char type = (*serviceDataFIG0_2)->getType(ensemble); - if ((type == 0) || (type == 2)) { - continue; - } - - ++cur; - - if (fig0_2 == NULL) { - fig0_2 = (FIGtype0_2 *) & etiFrame[index]; - - fig0_2->FIGtypeNumber = 0; - fig0_2->Length = 1; - fig0_2->CN = 0; - fig0_2->OE = 0; - fig0_2->PD = 1; - fig0_2->Extension = 2; - index = index + 2; - figSize += 2; - } + if ((*subchannel)->type != 3) continue; - if (figSize + 5 - + (*serviceDataFIG0_2)->nbComponent(ensemble->components) - * 2 > 30) { - break; - } + if (fig0_3_header == NULL) { + fig0_3_header = (FIGtype0_3_header*)&etiFrame[index]; + fig0_3_header->FIGtypeNumber = 0; + fig0_3_header->Length = 1; + fig0_3_header->CN = 0; + fig0_3_header->OE = 0; + fig0_3_header->PD = 0; + fig0_3_header->Extension = 3; - fig0_2serviceData = - (FIGtype0_2_Service_data*) &etiFrame[index]; - - fig0_2serviceData->SId = htonl((*serviceDataFIG0_2)->id); - fig0_2serviceData->Local_flag = 0; - fig0_2serviceData->CAId = 0; - fig0_2serviceData->NbServiceComp = - (*serviceDataFIG0_2)->nbComponent(ensemble->components); - fig0_2->Length += 5; - index += 5; - figSize += 5; + index += 2; + figSize += 2; + } - int curCpnt = 0; - for (component = getComponent(ensemble->components, - (*serviceDataFIG0_2)->id); - component != ensemble->components.end(); - component = getComponent(ensemble->components, - (*serviceDataFIG0_2)->id, component)) { - subchannel = getSubchannel(ensemble->subchannels, - (*component)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "Subchannel %i does not exist for component " - "of service %i\n", - (*component)->subchId, (*component)->serviceId); - returnCode = -1; - goto EXIT; + /* Warning: When bit SCCA_flag is unset(0), the multiplexer + * R&S does not send the SCCA field. But, in the Factum ETI + * analyzer, if this field is not there, it is an error. + */ + fig0_3_data = (FIGtype0_3_data*)&etiFrame[index]; + fig0_3_data->setSCId((*component)->packet.id); + fig0_3_data->rfa = 0; + fig0_3_data->SCCA_flag = 0; + // if 0, datagroups are used + fig0_3_data->DG_flag = !(*component)->packet.datagroup; + fig0_3_data->rfu = 0; + fig0_3_data->DSCTy = (*component)->type; + fig0_3_data->SubChId = (*subchannel)->id; + fig0_3_data->setPacketAddress((*component)->packet.address); + if (factumAnalyzer) { + fig0_3_data->SCCA = 0; } - switch ((*subchannel)->type) { - case 0: // Audio - audio_description = - (FIGtype0_2_audio_component*)&etiFrame[index]; - audio_description->TMid = 0; - audio_description->ASCTy = (*component)->type; - audio_description->SubChId = (*subchannel)->id; - audio_description->PS = ((curCpnt == 0) ? 1 : 0); - audio_description->CA_flag = 0; - break; - case 1: // Data - data_description = - (FIGtype0_2_data_component*)&etiFrame[index]; - data_description->TMid = 1; - data_description->DSCTy = (*component)->type; - data_description->SubChId = (*subchannel)->id; - data_description->PS = ((curCpnt == 0) ? 1 : 0); - data_description->CA_flag = 0; - break; - case 3: // Packet - packet_description = - (FIGtype0_2_packet_component*)&etiFrame[index]; - packet_description->TMid = 3; - packet_description->setSCId((*component)->packet.id); - packet_description->PS = ((curCpnt == 0) ? 1 : 0); - packet_description->CA_flag = 0; - break; - default: - etiLog.log(error, - "Component type not supported\n"); - returnCode = -1; - goto EXIT; + fig0_3_header->Length += 5; + index += 5; + figSize += 5; + if (factumAnalyzer) { + fig0_3_header->Length += 2; + index += 2; + figSize += 2; } - index += 2; - fig0_2->Length += 2; - figSize += 2; + if (figSize > 30) { etiLog.log(error, - "Sorry, no place left in FIG 0/2 to insert " - "component %i of data service %i.\n", - curCpnt, cur); + "can't add to Fic Fig 0/3, " + "too much packet service\n"); returnCode = -1; - goto EXIT; + throw MuxInitException(); } - ++curCpnt; - } - } - break; - - case 5: - fig0_3_header = NULL; - - for (component = ensemble->components.begin(); - component != ensemble->components.end(); - ++component) { - subchannel = getSubchannel(ensemble->subchannels, - (*component)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "Subchannel %i does not exist for component " - "of service %i\n", - (*component)->subchId, (*component)->serviceId); - returnCode = -1; - goto EXIT; } + break; - if ((*subchannel)->type != 3) continue; - - if (fig0_3_header == NULL) { - fig0_3_header = (FIGtype0_3_header*)&etiFrame[index]; - fig0_3_header->FIGtypeNumber = 0; - fig0_3_header->Length = 1; - fig0_3_header->CN = 0; - fig0_3_header->OE = 0; - fig0_3_header->PD = 0; - fig0_3_header->Extension = 3; - - index += 2; - figSize += 2; - } - - /* Warning: When bit SCCA_flag is unset(0), the multiplexer - * R&S does not send the SCCA field. But, in the Factum ETI - * analyzer, if this field is not there, it is an error. - */ - fig0_3_data = (FIGtype0_3_data*)&etiFrame[index]; - fig0_3_data->setSCId((*component)->packet.id); - fig0_3_data->rfa = 0; - fig0_3_data->SCCA_flag = 0; - // if 0, datagroups are used - fig0_3_data->DG_flag = !(*component)->packet.datagroup; - fig0_3_data->rfu = 0; - fig0_3_data->DSCTy = (*component)->type; - fig0_3_data->SubChId = (*subchannel)->id; - fig0_3_data->setPacketAddress((*component)->packet.address); - if (factumAnalyzer) { - fig0_3_data->SCCA = 0; - } - - fig0_3_header->Length += 5; - index += 5; - figSize += 5; - if (factumAnalyzer) { - fig0_3_header->Length += 2; - index += 2; - figSize += 2; - } - - if (figSize > 30) { - etiLog.log(error, - "can't add to Fic Fig 0/3, " - "too much packet service\n"); - returnCode = -1; - goto EXIT; - } - } - break; - - case 7: - fig0 = NULL; - if (serviceFIG0_17 == ensemble->services.end()) { - serviceFIG0_17 = ensemble->services.begin(); - } - for (; serviceFIG0_17 != ensemble->services.end(); - ++serviceFIG0_17) { - if ((*serviceFIG0_17)->pty == 0 && (*serviceFIG0_17)->language == 0) { - continue; - } - if (fig0 == NULL) { - fig0 = (FIGtype0*)&etiFrame[index]; - fig0->FIGtypeNumber = 0; - fig0->Length = 1; - fig0->CN = 0; - fig0->OE = 0; - fig0->PD = 0; - fig0->Extension = 17; - index += 2; - figSize += 2; + case 7: + fig0 = NULL; + if (serviceFIG0_17 == ensemble->services.end()) { + serviceFIG0_17 = ensemble->services.begin(); } - - if ((*serviceFIG0_17)->language == 0) { - if (figSize + 4 > 30) { - break; + for (; serviceFIG0_17 != ensemble->services.end(); + ++serviceFIG0_17) { + if ((*serviceFIG0_17)->pty == 0 && (*serviceFIG0_17)->language == 0) { + continue; } - } else { - if (figSize + 5 > 30) { - break; + if (fig0 == NULL) { + fig0 = (FIGtype0*)&etiFrame[index]; + fig0->FIGtypeNumber = 0; + fig0->Length = 1; + fig0->CN = 0; + fig0->OE = 0; + fig0->PD = 0; + fig0->Extension = 17; + index += 2; + figSize += 2; } - } - programme = - (FIGtype0_17_programme*)&etiFrame[index]; - programme->SId = htons((*serviceFIG0_17)->id); - programme->SD = 1; - programme->PS = 0; - programme->L = (*serviceFIG0_17)->language != 0; - programme->CC = 0; - programme->Rfa = 0; - programme->NFC = 0; - if ((*serviceFIG0_17)->language == 0) { - etiFrame[index + 3] = (*serviceFIG0_17)->pty; - fig0->Length += 4; - index += 4; - figSize += 4; - } else { - etiFrame[index + 3] = (*serviceFIG0_17)->language; - etiFrame[index + 4] = (*serviceFIG0_17)->pty; - fig0->Length += 5; - index += 5; - figSize += 5; - } - } - break; - } - - if (figSize > 30) { - etiLog.log(error, - "FIG too big (%i > 30)\n", figSize); - returnCode = -1; - goto EXIT; - } - - memcpy(&etiFrame[index], Padding_FIB, 30 - figSize); - index += 30 - figSize; - - CRCtmp = 0xffff; - CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); - CRCtmp ^= 0xffff; - etiFrame[index++] = ((char *) &CRCtmp)[1]; - etiFrame[index++] = ((char *) &CRCtmp)[0]; - - figSize = 0; - // Insertion du FIB 1 - switch (alterneFIB) { - case 0: // FIG 0/8 program - fig0 = NULL; - - if (componentProgFIG0_8 == ensemble->components.end()) { - componentProgFIG0_8 = ensemble->components.begin(); - } - for (; componentProgFIG0_8 != ensemble->components.end(); - ++componentProgFIG0_8) { - service = getService(*componentProgFIG0_8, - ensemble->services); - subchannel = getSubchannel(ensemble->subchannels, - (*componentProgFIG0_8)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "Subchannel %i does not exist for component " - "of service %i\n", - (*componentProgFIG0_8)->subchId, - (*componentProgFIG0_8)->serviceId); - returnCode = -1; - goto EXIT; - } - - if (!(*service)->program) continue; - - if (fig0 == NULL) { - fig0 = (FIGtype0*)&etiFrame[index]; - fig0->FIGtypeNumber = 0; - fig0->Length = 1; - fig0->CN = 0; - fig0->OE = 0; - fig0->PD = 0; - fig0->Extension = 8; - index += 2; - figSize += 2; - } - - if ((*subchannel)->type == 3) { // Data packet - if (figSize > 30 - 5) { - break; + if ((*serviceFIG0_17)->language == 0) { + if (figSize + 4 > 30) { + break; + } + } else { + if (figSize + 5 > 30) { + break; + } } - etiFrame[index] = ((*componentProgFIG0_8)->serviceId >> 8) & 0xFF; - etiFrame[index+1] = ((*componentProgFIG0_8)->serviceId) & 0xFF; - fig0->Length += 2; - index += 2; - figSize += 2; - FIGtype0_8_long* definition = - (FIGtype0_8_long*)&etiFrame[index]; - memset(definition, 0, 3); - definition->ext = 0; // no rfa - definition->SCIdS = (*componentProgFIG0_8)->SCIdS; - definition->LS = 1; - definition->setSCId((*componentProgFIG0_8)->packet.id); - fig0->Length += 3; - index += 3; // 8 minus rfa - figSize += 3; - } else { // Audio, data stream or FIDC - if (figSize > 30 - 4) { - break; + programme = + (FIGtype0_17_programme*)&etiFrame[index]; + programme->SId = htons((*serviceFIG0_17)->id); + programme->SD = 1; + programme->PS = 0; + programme->L = (*serviceFIG0_17)->language != 0; + programme->CC = 0; + programme->Rfa = 0; + programme->NFC = 0; + if ((*serviceFIG0_17)->language == 0) { + etiFrame[index + 3] = (*serviceFIG0_17)->pty; + fig0->Length += 4; + index += 4; + figSize += 4; + } else { + etiFrame[index + 3] = (*serviceFIG0_17)->language; + etiFrame[index + 4] = (*serviceFIG0_17)->pty; + fig0->Length += 5; + index += 5; + figSize += 5; } - etiFrame[index] = ((*componentProgFIG0_8)->serviceId >> 8) & 0xFF; - etiFrame[index+1] = ((*componentProgFIG0_8)->serviceId) & 0xFF; - fig0->Length += 2; - index += 2; - figSize += 2; - - FIGtype0_8_short* definition = - (FIGtype0_8_short*)&etiFrame[index]; - memset(definition, 0, 2); - definition->ext = 0; // no rfa - definition->SCIdS = (*componentProgFIG0_8)->SCIdS; - definition->LS = 0; - definition->MscFic = 0; - definition->Id = (*componentProgFIG0_8)->subchId; - fig0->Length += 2; - index += 2; // 4 minus rfa - figSize += 2; } + break; } - break; - case 1: // FIG 0/8 data - fig0 = NULL; - - if (componentDataFIG0_8 == ensemble->components.end()) { - componentDataFIG0_8 = ensemble->components.begin(); + if (figSize > 30) { + etiLog.log(error, + "FIG too big (%i > 30)\n", figSize); + returnCode = -1; + throw MuxInitException(); } - for (; componentDataFIG0_8 != ensemble->components.end(); - ++componentDataFIG0_8) { - service = getService(*componentDataFIG0_8, - ensemble->services); - subchannel = getSubchannel(ensemble->subchannels, - (*componentDataFIG0_8)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "Subchannel %i does not exist for component " - "of service %i\n", - (*componentDataFIG0_8)->subchId, - (*componentDataFIG0_8)->serviceId); - returnCode = -1; - goto EXIT; - } - if ((*service)->program) continue; - - if (fig0 == NULL) { - fig0 = (FIGtype0*)&etiFrame[index]; - fig0->FIGtypeNumber = 0; - fig0->Length = 1; - fig0->CN = 0; - fig0->OE = 0; - fig0->PD = 1; - fig0->Extension = 8; - index += 2; - figSize += 2; - } + memcpy(&etiFrame[index], Padding_FIB, 30 - figSize); + index += 30 - figSize; - if ((*subchannel)->type == 3) { // Data packet - if (figSize > 30 - 7) { - break; - } - etiFrame[index] = ((*componentDataFIG0_8)->serviceId >> 8) & 0xFF; - etiFrame[index+1] = ((*componentDataFIG0_8)->serviceId) & 0xFF; - fig0->Length += 4; - index += 4; - figSize += 4; + CRCtmp = 0xffff; + CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); + CRCtmp ^= 0xffff; + etiFrame[index++] = ((char *) &CRCtmp)[1]; + etiFrame[index++] = ((char *) &CRCtmp)[0]; - FIGtype0_8_long* definition = - (FIGtype0_8_long*)&etiFrame[index]; - memset(definition, 0, 3); - definition->ext = 0; // no rfa - definition->SCIdS = (*componentDataFIG0_8)->SCIdS; - definition->LS = 1; - definition->setSCId((*componentDataFIG0_8)->packet.id); - fig0->Length += 3; - index += 3; // 8 minus rfa - figSize += 3; - } else { // Audio, data stream or FIDC - if (figSize > 30 - 6) { - break; - } - etiFrame[index] = ((*componentDataFIG0_8)->serviceId >> 8) & 0xFF; - etiFrame[index+1] = ((*componentDataFIG0_8)->serviceId) & 0xFF; - fig0->Length += 4; - index += 4; - figSize += 4; + figSize = 0; + // Insertion du FIB 1 + switch (alterneFIB) { + case 0: // FIG 0/8 program + fig0 = NULL; - FIGtype0_8_short* definition = - (FIGtype0_8_short*)&etiFrame[index]; - memset(definition, 0, 2); - definition->ext = 0; // no rfa - definition->SCIdS = (*componentDataFIG0_8)->SCIdS; - definition->LS = 0; - definition->MscFic = 0; - definition->Id = (*componentDataFIG0_8)->subchId; - fig0->Length += 2; - index += 2; // 4 minus rfa - figSize += 2; + if (componentProgFIG0_8 == ensemble->components.end()) { + componentProgFIG0_8 = ensemble->components.begin(); } - } - break; - - case 3: - // FIG type 1/0, Service Information (SI), Ensemble Label - fig1_0 = (FIGtype1_0 *) & etiFrame[index]; - - fig1_0->Length = 21; - fig1_0->FIGtypeNumber = 1; - fig1_0->Extension = 0; - fig1_0->OE = 0; - fig1_0->Charset = 0; - fig1_0->EId = htons(ensemble->id); - index = index + 4; - - memcpy(&etiFrame[index], ensemble->label.text(), 16); - index = index + 16; - - etiFrame[index++] = ensemble->label.flag() >> 8; - etiFrame[index++] = ensemble->label.flag() & 0xFF; - - figSize += 22; - break; - case 5: - // FIG 0 / 13 - fig0 = NULL; - - if (componentFIG0_13 == ensemble->components.end()) { - componentFIG0_13 = ensemble->components.begin(); - - transmitFIG0_13programme = !transmitFIG0_13programme; - // Alternate between data and and programme FIG0/13, - // do not mix fig0 with PD=0 with extension 13 stuff - // that actually needs PD=1, and vice versa - } - - for (; componentFIG0_13 != ensemble->components.end(); - ++componentFIG0_13) { + for (; componentProgFIG0_8 != ensemble->components.end(); + ++componentProgFIG0_8) { + service = getService(*componentProgFIG0_8, + ensemble->services); + subchannel = getSubchannel(ensemble->subchannels, + (*componentProgFIG0_8)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, + "Subchannel %i does not exist for component " + "of service %i\n", + (*componentProgFIG0_8)->subchId, + (*componentProgFIG0_8)->serviceId); + returnCode = -1; + throw MuxInitException(); + } - subchannel = getSubchannel(ensemble->subchannels, - (*componentFIG0_13)->subchId); - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "Subchannel %i does not exist for component " - "of service %i\n", - (*componentFIG0_13)->subchId, - (*componentFIG0_13)->serviceId); - returnCode = -1; - goto EXIT; - } + if (!(*service)->program) continue; - if (transmitFIG0_13programme && - (*subchannel)->type == 0) { // audio if (fig0 == NULL) { fig0 = (FIGtype0*)&etiFrame[index]; fig0->FIGtypeNumber = 0; @@ -1560,46 +1385,79 @@ int main(int argc, char *argv[]) fig0->CN = 0; fig0->OE = 0; fig0->PD = 0; - fig0->Extension = 13; + fig0->Extension = 8; index += 2; figSize += 2; } - if (figSize > 30 - (3+4+11)) { - break; + if ((*subchannel)->type == 3) { // Data packet + if (figSize > 30 - 5) { + break; + } + etiFrame[index] = ((*componentProgFIG0_8)->serviceId >> 8) & 0xFF; + etiFrame[index+1] = ((*componentProgFIG0_8)->serviceId) & 0xFF; + fig0->Length += 2; + index += 2; + figSize += 2; + + FIGtype0_8_long* definition = + (FIGtype0_8_long*)&etiFrame[index]; + memset(definition, 0, 3); + definition->ext = 0; // no rfa + definition->SCIdS = (*componentProgFIG0_8)->SCIdS; + definition->LS = 1; + definition->setSCId((*componentProgFIG0_8)->packet.id); + fig0->Length += 3; + index += 3; // 8 minus rfa + figSize += 3; + } else { // Audio, data stream or FIDC + if (figSize > 30 - 4) { + break; + } + etiFrame[index] = ((*componentProgFIG0_8)->serviceId >> 8) & 0xFF; + etiFrame[index+1] = ((*componentProgFIG0_8)->serviceId) & 0xFF; + fig0->Length += 2; + index += 2; + figSize += 2; + + FIGtype0_8_short* definition = + (FIGtype0_8_short*)&etiFrame[index]; + memset(definition, 0, 2); + definition->ext = 0; // no rfa + definition->SCIdS = (*componentProgFIG0_8)->SCIdS; + definition->LS = 0; + definition->MscFic = 0; + definition->Id = (*componentProgFIG0_8)->subchId; + fig0->Length += 2; + index += 2; // 4 minus rfa + figSize += 2; } + } + break; - FIG0_13_shortAppInfo* info = - (FIG0_13_shortAppInfo*)&etiFrame[index]; - info->SId = htonl((*componentFIG0_13)->serviceId) >> 16; - info->SCIdS = (*componentFIG0_13)->SCIdS; - info->No = 1; - index += 3; - figSize += 3; - fig0->Length += 3; - - FIG0_13_app* app = (FIG0_13_app*)&etiFrame[index]; - app->setType(FIG0_13_APPTYPE_SLIDESHOW); - app->length = 4; - app->xpad = htonl(0x0cbc0000); - /* xpad meaning - CA = 0 - CAOrg = 0 - Rfu = 0 - AppTy(5) = 12 (MOT, start of X-PAD data group) - DG = 0 (MSC data groups used) - Rfu = 0 - DSCTy(6) = 60 (MOT) - CAOrg(16) = 0 - */ - - index += 2 + app->length; - figSize += 2 + app->length; - fig0->Length += 2 + app->length; + case 1: // FIG 0/8 data + fig0 = NULL; + + if (componentDataFIG0_8 == ensemble->components.end()) { + componentDataFIG0_8 = ensemble->components.begin(); } - else if (!transmitFIG0_13programme && - (*subchannel)->type == 3 && // packet - (*componentFIG0_13)->packet.appType != 0xffff) { + for (; componentDataFIG0_8 != ensemble->components.end(); + ++componentDataFIG0_8) { + service = getService(*componentDataFIG0_8, + ensemble->services); + subchannel = getSubchannel(ensemble->subchannels, + (*componentDataFIG0_8)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, + "Subchannel %i does not exist for component " + "of service %i\n", + (*componentDataFIG0_8)->subchId, + (*componentDataFIG0_8)->serviceId); + returnCode = -1; + throw MuxInitException(); + } + + if ((*service)->program) continue; if (fig0 == NULL) { fig0 = (FIGtype0*)&etiFrame[index]; @@ -1608,378 +1466,537 @@ int main(int argc, char *argv[]) fig0->CN = 0; fig0->OE = 0; fig0->PD = 1; - fig0->Extension = 13; + fig0->Extension = 8; index += 2; figSize += 2; } - if (figSize > 30 - (5+2)) { - break; + if ((*subchannel)->type == 3) { // Data packet + if (figSize > 30 - 7) { + break; + } + etiFrame[index] = ((*componentDataFIG0_8)->serviceId >> 8) & 0xFF; + etiFrame[index+1] = ((*componentDataFIG0_8)->serviceId) & 0xFF; + fig0->Length += 4; + index += 4; + figSize += 4; + + FIGtype0_8_long* definition = + (FIGtype0_8_long*)&etiFrame[index]; + memset(definition, 0, 3); + definition->ext = 0; // no rfa + definition->SCIdS = (*componentDataFIG0_8)->SCIdS; + definition->LS = 1; + definition->setSCId((*componentDataFIG0_8)->packet.id); + fig0->Length += 3; + index += 3; // 8 minus rfa + figSize += 3; + } else { // Audio, data stream or FIDC + if (figSize > 30 - 6) { + break; + } + etiFrame[index] = ((*componentDataFIG0_8)->serviceId >> 8) & 0xFF; + etiFrame[index+1] = ((*componentDataFIG0_8)->serviceId) & 0xFF; + fig0->Length += 4; + index += 4; + figSize += 4; + + FIGtype0_8_short* definition = + (FIGtype0_8_short*)&etiFrame[index]; + memset(definition, 0, 2); + definition->ext = 0; // no rfa + definition->SCIdS = (*componentDataFIG0_8)->SCIdS; + definition->LS = 0; + definition->MscFic = 0; + definition->Id = (*componentDataFIG0_8)->subchId; + fig0->Length += 2; + index += 2; // 4 minus rfa + figSize += 2; } + } + break; - FIG0_13_longAppInfo* info = - (FIG0_13_longAppInfo*)&etiFrame[index]; - info->SId = htonl((*componentFIG0_13)->serviceId); - info->SCIdS = (*componentFIG0_13)->SCIdS; - info->No = 1; - index += 5; - figSize += 5; - fig0->Length += 5; + case 3: + // FIG type 1/0, Service Information (SI), Ensemble Label + fig1_0 = (FIGtype1_0 *) & etiFrame[index]; - FIG0_13_app* app = (FIG0_13_app*)&etiFrame[index]; - app->setType((*componentFIG0_13)->packet.appType); - app->length = 0; - index += 2; - figSize += 2; - fig0->Length += 2; - } - } - break; - case 7: - //Time and country identifier - fig0_10 = (FIGtype0_10 *) & etiFrame[index]; - - fig0_10->FIGtypeNumber = 0; - fig0_10->Length = 5; - fig0_10->CN = 0; - fig0_10->OE = 0; - fig0_10->PD = 0; - fig0_10->Extension = 10; - index = index + 2; - - timeData = gmtime(&date); - - fig0_10->RFU = 0; - fig0_10->setMJD(gregorian2mjd(timeData->tm_year + 1900, - timeData->tm_mon + 1, - timeData->tm_mday)); - fig0_10->LSI = 0; - fig0_10->ConfInd = (watermarkData[watermarkPos >> 3] >> - (7 - (watermarkPos & 0x07))) & 1; - if (++watermarkPos == watermarkSize) { - watermarkPos = 0; - } - fig0_10->UTC = 0; - fig0_10->setHours(timeData->tm_hour); - fig0_10->Minutes = timeData->tm_min; - index = index + 4; - figSize += 6; - - fig0_9 = (FIGtype0_9*)&etiFrame[index]; - fig0_9->FIGtypeNumber = 0; - fig0_9->Length = 4; - fig0_9->CN = 0; - fig0_9->OE = 0; - fig0_9->PD = 0; - fig0_9->Extension = 9; - - fig0_9->ext = 0; - fig0_9->lto = 0; // Unique LTO for ensemble - - if (ensemble->lto_auto) { - time_t now = time(NULL); - struct tm* ltime = localtime(&now); - time_t now2 = timegm(ltime); - ensemble->lto = (now2 - now) / 1800; - } + fig1_0->Length = 21; + fig1_0->FIGtypeNumber = 1; + fig1_0->Extension = 0; + fig1_0->OE = 0; + fig1_0->Charset = 0; + fig1_0->EId = htons(ensemble->id); + index = index + 4; - if (ensemble->lto >= 0) { - fig0_9->ensembleLto = ensemble->lto; - } - else { - /* Convert to 1-complement representation */ - fig0_9->ensembleLto = (-ensemble->lto) | (1<<5); - } + memcpy(&etiFrame[index], ensemble->label.text(), 16); + index = index + 16; - fig0_9->ensembleEcc = ensemble->ecc; - fig0_9->tableId = ensemble->international_table; - index += 5; - figSize += 5; + etiFrame[index++] = ensemble->label.flag() >> 8; + etiFrame[index++] = ensemble->label.flag() & 0xFF; - break; - } + figSize += 22; + break; + case 5: + // FIG 0 / 13 + fig0 = NULL; - assert(figSize <= 30); - memcpy(&etiFrame[index], Padding_FIB, 30 - figSize); - index += 30 - figSize; + if (componentFIG0_13 == ensemble->components.end()) { + componentFIG0_13 = ensemble->components.begin(); - CRCtmp = 0xffff; - CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); - CRCtmp ^= 0xffff; - etiFrame[index++] = ((char *) &CRCtmp)[1]; - etiFrame[index++] = ((char *) &CRCtmp)[0]; + transmitFIG0_13programme = !transmitFIG0_13programme; + // Alternate between data and and programme FIG0/13, + // do not mix fig0 with PD=0 with extension 13 stuff + // that actually needs PD=1, and vice versa + } + for (; componentFIG0_13 != ensemble->components.end(); + ++componentFIG0_13) { - figSize = 0; - // Insertion FIB 2 - if (alterneFIB < ensemble->services.size()) { - service = ensemble->services.begin() + alterneFIB; + subchannel = getSubchannel(ensemble->subchannels, + (*componentFIG0_13)->subchId); + if (subchannel == ensemble->subchannels.end()) { + etiLog.log(error, + "Subchannel %i does not exist for component " + "of service %i\n", + (*componentFIG0_13)->subchId, + (*componentFIG0_13)->serviceId); + returnCode = -1; + throw MuxInitException(); + } - // FIG type 1/1, SI, Service label, one instance per subchannel - if ((*service)->getType(ensemble) == 0) { - fig1_1 = (FIGtype1_1 *) & etiFrame[index]; + if (transmitFIG0_13programme && + (*subchannel)->type == 0) { // audio + if (fig0 == NULL) { + fig0 = (FIGtype0*)&etiFrame[index]; + fig0->FIGtypeNumber = 0; + fig0->Length = 1; + fig0->CN = 0; + fig0->OE = 0; + fig0->PD = 0; + fig0->Extension = 13; + index += 2; + figSize += 2; + } - fig1_1->FIGtypeNumber = 1; - fig1_1->Length = 21; - fig1_1->Charset = 0; - fig1_1->OE = 0; - fig1_1->Extension = 1; + if (figSize > 30 - (3+4+11)) { + break; + } - fig1_1->Sld = htons((*service)->id); - index += 4; - figSize += 4; - } else { - fig1_5 = (FIGtype1_5 *) & etiFrame[index]; - fig1_5->FIGtypeNumber = 1; - fig1_5->Length = 23; - fig1_5->Charset = 0; - fig1_5->OE = 0; - fig1_5->Extension = 5; - - fig1_5->SId = htonl((*service)->id); - index += 6; + FIG0_13_shortAppInfo* info = + (FIG0_13_shortAppInfo*)&etiFrame[index]; + info->SId = htonl((*componentFIG0_13)->serviceId) >> 16; + info->SCIdS = (*componentFIG0_13)->SCIdS; + info->No = 1; + index += 3; + figSize += 3; + fig0->Length += 3; + + FIG0_13_app* app = (FIG0_13_app*)&etiFrame[index]; + app->setType(FIG0_13_APPTYPE_SLIDESHOW); + app->length = 4; + app->xpad = htonl(0x0cbc0000); + /* xpad meaning + CA = 0 + CAOrg = 0 + Rfu = 0 + AppTy(5) = 12 (MOT, start of X-PAD data group) + DG = 0 (MSC data groups used) + Rfu = 0 + DSCTy(6) = 60 (MOT) + CAOrg(16) = 0 + */ + + index += 2 + app->length; + figSize += 2 + app->length; + fig0->Length += 2 + app->length; + } + else if (!transmitFIG0_13programme && + (*subchannel)->type == 3 && // packet + (*componentFIG0_13)->packet.appType != 0xffff) { + + if (fig0 == NULL) { + fig0 = (FIGtype0*)&etiFrame[index]; + fig0->FIGtypeNumber = 0; + fig0->Length = 1; + fig0->CN = 0; + fig0->OE = 0; + fig0->PD = 1; + fig0->Extension = 13; + index += 2; + figSize += 2; + } + + if (figSize > 30 - (5+2)) { + break; + } + + FIG0_13_longAppInfo* info = + (FIG0_13_longAppInfo*)&etiFrame[index]; + info->SId = htonl((*componentFIG0_13)->serviceId); + info->SCIdS = (*componentFIG0_13)->SCIdS; + info->No = 1; + index += 5; + figSize += 5; + fig0->Length += 5; + + FIG0_13_app* app = (FIG0_13_app*)&etiFrame[index]; + app->setType((*componentFIG0_13)->packet.appType); + app->length = 0; + index += 2; + figSize += 2; + fig0->Length += 2; + } + } + break; + case 7: + //Time and country identifier + fig0_10 = (FIGtype0_10 *) & etiFrame[index]; + + fig0_10->FIGtypeNumber = 0; + fig0_10->Length = 5; + fig0_10->CN = 0; + fig0_10->OE = 0; + fig0_10->PD = 0; + fig0_10->Extension = 10; + index = index + 2; + + timeData = gmtime(&date); + + fig0_10->RFU = 0; + fig0_10->setMJD(gregorian2mjd(timeData->tm_year + 1900, + timeData->tm_mon + 1, + timeData->tm_mday)); + fig0_10->LSI = 0; + fig0_10->ConfInd = (watermarkData[watermarkPos >> 3] >> + (7 - (watermarkPos & 0x07))) & 1; + if (++watermarkPos == watermarkSize) { + watermarkPos = 0; + } + fig0_10->UTC = 0; + fig0_10->setHours(timeData->tm_hour); + fig0_10->Minutes = timeData->tm_min; + index = index + 4; figSize += 6; + + fig0_9 = (FIGtype0_9*)&etiFrame[index]; + fig0_9->FIGtypeNumber = 0; + fig0_9->Length = 4; + fig0_9->CN = 0; + fig0_9->OE = 0; + fig0_9->PD = 0; + fig0_9->Extension = 9; + + fig0_9->ext = 0; + fig0_9->lto = 0; // Unique LTO for ensemble + + if (ensemble->lto_auto) { + time_t now = time(NULL); + struct tm* ltime = localtime(&now); + time_t now2 = timegm(ltime); + ensemble->lto = (now2 - now) / 1800; + } + + if (ensemble->lto >= 0) { + fig0_9->ensembleLto = ensemble->lto; + } + else { + /* Convert to 1-complement representation */ + fig0_9->ensembleLto = (-ensemble->lto) | (1<<5); + } + + fig0_9->ensembleEcc = ensemble->ecc; + fig0_9->tableId = ensemble->international_table; + index += 5; + figSize += 5; + + break; } - memcpy(&etiFrame[index], (*service)->label.text(), 16); - index += 16; - figSize += 16; - etiFrame[index++] = (*service)->label.flag() >> 8; - etiFrame[index++] = (*service)->label.flag() & 0xFF; - figSize += 2; - } else if (alterneFIB < - ensemble->services.size() + ensemble->components.size()) { - component = ensemble->components.begin() + - (alterneFIB - ensemble->services.size()); - service = getService(*component, ensemble->services); - subchannel = - getSubchannel(ensemble->subchannels, (*component)->subchId); - - if ((*component)->label.text()[0] != 0) { - if ((*service)->getType(ensemble) == 0) { // Programme - FIGtype1_4_programme *fig1_4; - fig1_4 = (FIGtype1_4_programme*)&etiFrame[index]; - - fig1_4->FIGtypeNumber = 1; - fig1_4->Length = 22; - fig1_4->Charset = 0; - fig1_4->OE = 0; - fig1_4->Extension = 4; - fig1_4->PD = 0; - fig1_4->rfa = 0; - fig1_4->SCIdS = (*component)->SCIdS; - - fig1_4->SId = htons((*service)->id); - index += 5; - figSize += 5; - } else { // Data - FIGtype1_4_data *fig1_4; - fig1_4 = (FIGtype1_4_data *) & etiFrame[index]; - fig1_4->FIGtypeNumber = 1; - fig1_4->Length = 24; - fig1_4->Charset = 0; - fig1_4->OE = 0; - fig1_4->Extension = 4; - fig1_4->PD = 1; - fig1_4->rfa = 0; - fig1_4->SCIdS = (*component)->SCIdS; - - fig1_4->SId = htonl((*service)->id); - index += 7; - figSize += 7; + + assert(figSize <= 30); + memcpy(&etiFrame[index], Padding_FIB, 30 - figSize); + index += 30 - figSize; + + CRCtmp = 0xffff; + CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); + CRCtmp ^= 0xffff; + etiFrame[index++] = ((char *) &CRCtmp)[1]; + etiFrame[index++] = ((char *) &CRCtmp)[0]; + + + figSize = 0; + // Insertion FIB 2 + if (alterneFIB < ensemble->services.size()) { + service = ensemble->services.begin() + alterneFIB; + + // FIG type 1/1, SI, Service label, one instance per subchannel + if ((*service)->getType(ensemble) == 0) { + fig1_1 = (FIGtype1_1 *) & etiFrame[index]; + + fig1_1->FIGtypeNumber = 1; + fig1_1->Length = 21; + fig1_1->Charset = 0; + fig1_1->OE = 0; + fig1_1->Extension = 1; + + fig1_1->Sld = htons((*service)->id); + index += 4; + figSize += 4; + } else { + fig1_5 = (FIGtype1_5 *) & etiFrame[index]; + fig1_5->FIGtypeNumber = 1; + fig1_5->Length = 23; + fig1_5->Charset = 0; + fig1_5->OE = 0; + fig1_5->Extension = 5; + + fig1_5->SId = htonl((*service)->id); + index += 6; + figSize += 6; } - memcpy(&etiFrame[index], (*component)->label.text(), 16); + memcpy(&etiFrame[index], (*service)->label.text(), 16); index += 16; figSize += 16; - - etiFrame[index++] = (*component)->label.flag() >> 8; - etiFrame[index++] = (*component)->label.flag() & 0xFF; + etiFrame[index++] = (*service)->label.flag() >> 8; + etiFrame[index++] = (*service)->label.flag() & 0xFF; figSize += 2; + } else if (alterneFIB < + ensemble->services.size() + ensemble->components.size()) { + component = ensemble->components.begin() + + (alterneFIB - ensemble->services.size()); + service = getService(*component, ensemble->services); + subchannel = + getSubchannel(ensemble->subchannels, (*component)->subchId); + + if ((*component)->label.text()[0] != 0) { + if ((*service)->getType(ensemble) == 0) { // Programme + FIGtype1_4_programme *fig1_4; + fig1_4 = (FIGtype1_4_programme*)&etiFrame[index]; + + fig1_4->FIGtypeNumber = 1; + fig1_4->Length = 22; + fig1_4->Charset = 0; + fig1_4->OE = 0; + fig1_4->Extension = 4; + fig1_4->PD = 0; + fig1_4->rfa = 0; + fig1_4->SCIdS = (*component)->SCIdS; + + fig1_4->SId = htons((*service)->id); + index += 5; + figSize += 5; + } else { // Data + FIGtype1_4_data *fig1_4; + fig1_4 = (FIGtype1_4_data *) & etiFrame[index]; + fig1_4->FIGtypeNumber = 1; + fig1_4->Length = 24; + fig1_4->Charset = 0; + fig1_4->OE = 0; + fig1_4->Extension = 4; + fig1_4->PD = 1; + fig1_4->rfa = 0; + fig1_4->SCIdS = (*component)->SCIdS; + + fig1_4->SId = htonl((*service)->id); + index += 7; + figSize += 7; + } + memcpy(&etiFrame[index], (*component)->label.text(), 16); + index += 16; + figSize += 16; + + etiFrame[index++] = (*component)->label.flag() >> 8; + etiFrame[index++] = (*component)->label.flag() & 0xFF; + figSize += 2; + } } - } - memcpy(&etiFrame[index], Padding_FIB, 30 - figSize); - index += 30 - figSize; - - CRCtmp = 0xffff; - CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); - CRCtmp ^= 0xffff; - etiFrame[index++] = ((char *) &CRCtmp)[1]; - etiFrame[index++] = ((char *) &CRCtmp)[0]; - - /* ETSI EN 300 799 Table 2: - * Only TM3 has a FIB count to CIF count that is - * not 3 to 1. - */ - if (ensemble->mode == 3) { - memcpy(&etiFrame[index], Padding_FIB, 30); - index += 30; + memcpy(&etiFrame[index], Padding_FIB, 30 - figSize); + index += 30 - figSize; CRCtmp = 0xffff; CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); CRCtmp ^= 0xffff; etiFrame[index++] = ((char *) &CRCtmp)[1]; etiFrame[index++] = ((char *) &CRCtmp)[0]; - } - if (ensemble->services.size() > 30) { - etiLog.log(error, - "Sorry, but this software currently can't write " - "Service Label of more than 30 services.\n"); - returnCode = -1; - goto EXIT; - } + /* ETSI EN 300 799 Table 2: + * Only TM3 has a FIB count to CIF count that is + * not 3 to 1. + */ + if (ensemble->mode == 3) { + memcpy(&etiFrame[index], Padding_FIB, 30); + index += 30; + + CRCtmp = 0xffff; + CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30); + CRCtmp ^= 0xffff; + etiFrame[index++] = ((char *) &CRCtmp)[1]; + etiFrame[index++] = ((char *) &CRCtmp)[0]; + } - // compteur pour FIG 0/0 - insertFIG = (insertFIG + 1) % 8; + if (ensemble->services.size() > 30) { + etiLog.log(error, + "Sorry, but this software currently can't write " + "Service Label of more than 30 services.\n"); + returnCode = -1; + throw MuxInitException(); + } - // compteur pour inserer FIB a toutes les 30 trames - alterneFIB = (alterneFIB + 1) % 30; + // compteur pour FIG 0/0 + insertFIG = (insertFIG + 1) % 8; - /********************************************************************** - ****** Section de lecture de donnees ******************************* - **********************************************************************/ + // compteur pour inserer FIB a toutes les 30 trames + alterneFIB = (alterneFIB + 1) % 30; - //Lecture des donnees dans les fichiers d'entree - for (subchannel = ensemble->subchannels.begin(); - subchannel != ensemble->subchannels.end(); - ++subchannel) { + /********************************************************************** + ****** Section de lecture de donnees ******************************* + **********************************************************************/ - TagESTn* tag = edi_subchannelToTag[*subchannel]; + //Lecture des donnees dans les fichiers d'entree + for (subchannel = ensemble->subchannels.begin(); + subchannel != ensemble->subchannels.end(); + ++subchannel) { - int sizeSubchannel = getSizeByte(*subchannel); - result = (*subchannel)->input->readFrame( - &etiFrame[index], sizeSubchannel); + TagESTn* tag = edi_subchannelToTag[*subchannel]; - if (result < 0) { - etiLog.log(info, "Subchannel %d read failed at ETI frame number: %d\n", - (*subchannel)->id, currentFrame); - } + int sizeSubchannel = getSizeByte(*subchannel); + result = (*subchannel)->input->readFrame( + &etiFrame[index], sizeSubchannel); - // save pointer to Audio or Data Stream into correct TagESTn for EDI - tag->mst_data = &etiFrame[index]; + if (result < 0) { + etiLog.log(info, "Subchannel %d read failed at ETI frame number: %d\n", + (*subchannel)->id, currentFrame); + } - index += sizeSubchannel; - } + // save pointer to Audio or Data Stream into correct TagESTn for EDI + tag->mst_data = &etiFrame[index]; + index += sizeSubchannel; + } - index = (3 + fc->NST + FICL) * 4; - for (subchannel = ensemble->subchannels.begin(); - subchannel != ensemble->subchannels.end(); - ++subchannel) { - index += getSizeByte(*subchannel); - } - /******* Section EOF **************************************************/ - // End of Frame, 4 octets - index = (FLtmp + 1 + 1) * 4; - eti_EOF *eof = (eti_EOF *) & etiFrame[index]; + index = (3 + fc->NST + FICL) * 4; + for (subchannel = ensemble->subchannels.begin(); + subchannel != ensemble->subchannels.end(); + ++subchannel) { + index += getSizeByte(*subchannel); + } - //CRC sur le Main Stream data (MST), sur 16 bits - index = ((fc->NST) + 2 + 1) * 4; //position du MST - MSTsize = ((FLtmp) - 1 - (fc->NST)) * 4; //nb d'octets de donnees + /******* Section EOF **************************************************/ + // End of Frame, 4 octets + index = (FLtmp + 1 + 1) * 4; + eti_EOF *eof = (eti_EOF *) & etiFrame[index]; - CRCtmp = 0xffff; - CRCtmp = crc16(CRCtmp, &etiFrame[index], MSTsize); - CRCtmp ^= 0xffff; - eof->CRC = htons(CRCtmp); + //CRC sur le Main Stream data (MST), sur 16 bits + index = ((fc->NST) + 2 + 1) * 4; //position du MST + MSTsize = ((FLtmp) - 1 - (fc->NST)) * 4; //nb d'octets de donnees - //RFU, Reserved for future use, 2 bytes, should be 0xFFFF - eof->RFU = htons(0xFFFF); + CRCtmp = 0xffff; + CRCtmp = crc16(CRCtmp, &etiFrame[index], MSTsize); + CRCtmp ^= 0xffff; + eof->CRC = htons(CRCtmp); - /******* Section TIST *************************************************/ - // TimeStamps, 24 bits + 1 octet - index = (FLtmp + 2 + 1) * 4; - eti_TIST *tist = (eti_TIST *) & etiFrame[index]; + //RFU, Reserved for future use, 2 bytes, should be 0xFFFF + eof->RFU = htons(0xFFFF); - if (enableTist) { - tist->TIST = htonl(timestamp) | 0xff; - } - else { - tist->TIST = htonl(0xffffff) | 0xff; - } + /******* Section TIST *************************************************/ + // TimeStamps, 24 bits + 1 octet + index = (FLtmp + 2 + 1) * 4; + eti_TIST *tist = (eti_TIST *) & etiFrame[index]; - timestamp += 3 << 17; - if (timestamp > 0xf9ffff) - { - timestamp -= 0xfa0000; + if (enableTist) { + tist->TIST = htonl(timestamp) | 0xff; + } + else { + tist->TIST = htonl(0xffffff) | 0xff; + } - // Also update MNSC time for next frame - MNSC_increment_time = true; - } + 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; + /********************************************************************** + *********** Section FRPD ***************************************** + **********************************************************************/ - // Give the data to the outputs - for (output = outputs.begin() ; output != outputs.end(); ++output) { - if ((*output)->output->Write(etiFrame, index) - == -1) { - etiLog.log(error, "Can't write to output %s://%s\n", - (*output)->outputProto.c_str(), (*output)->outputName.c_str()); + //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)->output->Write(etiFrame, index) + == -1) { + etiLog.log(error, "Can't write to output %s://%s\n", + (*output)->outputProto.c_str(), (*output)->outputName.c_str()); + } } - } #ifdef DUMP_BRIDGE - dumpBytes(dumpData, sizeSubChannel, stderr); + dumpBytes(dumpData, sizeSubChannel, stderr); #endif // DUMP_BRIDGE - /********************************************************************** - *********** Finalise EDI ***************************************** - **********************************************************************/ + /********************************************************************** + *********** Finalise EDI ***************************************** + **********************************************************************/ - // put all tags into one TagPacket - edi_tagpacket.tag_items.push_back(&edi_tagStarPtr); - edi_tagpacket.tag_items.push_back(&edi_tagDETI); + // put all tags into one TagPacket + edi_tagpacket.tag_items.push_back(&edi_tagStarPtr); + edi_tagpacket.tag_items.push_back(&edi_tagDETI); - list::iterator tag; - for (tag = edi_subchannels.begin(); tag != edi_subchannels.end(); ++tag) { - edi_tagpacket.tag_items.push_back(&(*tag)); - } + list::iterator tag; + for (tag = edi_subchannels.begin(); tag != edi_subchannels.end(); ++tag) { + edi_tagpacket.tag_items.push_back(&(*tag)); + } - vector edi_afpacketData = edi_afPacket.Assemble(edi_tagpacket); + vector edi_afpacketData = edi_afPacket.Assemble(edi_tagpacket); #if EDI_DEBUG - std::ostream_iterator debug_iterator(edi_debug_file); - std::copy(edi_afpacketData.begin(), edi_afpacketData.end(), debug_iterator); + std::ostream_iterator debug_iterator(edi_debug_file); + std::copy(edi_afpacketData.begin(), edi_afpacketData.end(), debug_iterator); #endif #if _DEBUG - /********************************************************************** - *********** Output a small message ********************************* - **********************************************************************/ - if (currentFrame % 100 == 0) { - if (enableTist) { - etiLog.log(info, "ETI frame number %i Timestamp: %d + %f\n", - currentFrame, mnsc_time.tv_sec, - (timestamp & 0xFFFFFF) / 16384000.0); - } - else { - etiLog.log(info, "ETI frame number %i Time: %d, no TIST\n", - currentFrame, mnsc_time.tv_sec); + /********************************************************************** + *********** Output a small message ********************************* + **********************************************************************/ + if (currentFrame % 100 == 0) { + if (enableTist) { + etiLog.log(info, "ETI frame number %i Timestamp: %d + %f\n", + currentFrame, mnsc_time.tv_sec, + (timestamp & 0xFFFFFF) / 16384000.0); + } + else { + etiLog.log(info, "ETI frame number %i Time: %d, no TIST\n", + currentFrame, mnsc_time.tv_sec); + } } - } #endif - /* Check every six seconds if the remote control is still working */ - if (rc && fc->FCT == 249 && rc->fault_detected()) { - etiLog.level(warn) << "Detected Remote Control fault, restarting it"; - rc->restart(); - } + /* Check every six seconds if the remote control is still working */ + if (rc && fc->FCT == 249 && rc->fault_detected()) { + etiLog.level(warn) << "Detected Remote Control fault, restarting it"; + rc->restart(); + } - /* Same for statistics server */ - if (global_stats && fc->FCT == 249 && global_stats->fault_detected()) { - etiLog.level(warn) << - "Detected Statistics Server fault, restarting it"; - global_stats->restart(); + /* Same for statistics server */ + if (global_stats && fc->FCT == 249 && global_stats->fault_detected()) { + etiLog.level(warn) << + "Detected Statistics Server fault, restarting it"; + global_stats->restart(); + } } - } -EXIT: + } + catch (MuxInitException& except) { + etiLog.level(error) << "Caught multiplex initialisation error: " << + except.what(); + } etiLog.log(debug, "exiting...\n"); fflush(stderr); //fermeture des fichiers diff --git a/src/dabOutput/edi/TagItems.h b/src/dabOutput/edi/TagItems.h index 2cebaf8..dc0037b 100644 --- a/src/dabOutput/edi/TagItems.h +++ b/src/dabOutput/edi/TagItems.h @@ -71,8 +71,7 @@ class TagDETI : public TagItem uint8_t rfa; uint8_t rfu; uint16_t mnsc; - uint8_t fcth; - uint8_t fct; + uint16_t dflc; // modulo 5000 frame counter // ATST (optional) bool atstf; // presence of atst data diff --git a/src/dabOutput/edi/TagPacket.h b/src/dabOutput/edi/TagPacket.h index 1286d2c..2227085 100644 --- a/src/dabOutput/edi/TagPacket.h +++ b/src/dabOutput/edi/TagPacket.h @@ -27,6 +27,7 @@ #include "config.h" #include "Eti.h" +#include "TagItems.h" #include #include #include -- cgit v1.2.3