diff options
-rw-r--r-- | src/DabMux.cpp | 86 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/dabOutput/edi/AFPacket.cpp | 8 | ||||
-rw-r--r-- | src/dabOutput/edi/AFPacket.h | 10 | ||||
-rw-r--r-- | src/dabOutput/edi/TagItems.h | 2 | ||||
-rw-r--r-- | src/dabOutput/edi/TagPacket.cpp | 58 | ||||
-rw-r--r-- | src/dabOutput/edi/TagPacket.h | 51 |
7 files changed, 204 insertions, 14 deletions
diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 8472cfb..31e5baf 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -27,6 +27,8 @@ # include "config.h" #endif +#define EDI_DEBUG 1 + #include <cstdio> #include <stdlib.h> #include <iostream> @@ -43,8 +45,11 @@ // for basename #include <libgen.h> +#include <iterator> #include <vector> +#include <list> #include <set> +#include <map> #include <functional> #include <algorithm> @@ -109,6 +114,8 @@ typedef DWORD32 uint32_t; #include "dabOutput/dabOutput.h" #include "dabOutput/edi/TagItems.h" +#include "dabOutput/edi/TagPacket.h" +#include "dabOutput/edi/AFPacket.h" #include "crc.h" #include "UdpSocket.h" #include "InetAddress.h" @@ -635,14 +642,30 @@ int main(int argc, char *argv[]) /* 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; } - // For EDI, save ETI(LI) Management data into a TAG Item DETI/*{{{*/ - TagDETI tagDETI; - 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<TagESTn> edi_subchannels; + map<dabSubchannel*, TagESTn*> edi_subchannelToTag; + + // The above Tag Items will be assembled into a TAG Packet + TagPacket edi_tagpacket; + + // The TagPacket will then be placed into an AFPacket + AFPacket edi_afPacket(EDI_AFPACKET_PROTOCOLTYPE_TAGITEMS); + + edi_tagDETI.atstf = 0; // TODO add ATST support + + date = getDabTime(); // Initialise the ETI frame @@ -655,7 +678,7 @@ int main(int argc, char *argv[]) // See ETS 300 799 Clause 6 eti_SYNC *etiSync = (eti_SYNC *) etiFrame; - etiSync->ERR = tagDETI.stat = 0xFF; // ETS 300 799, 5.2, no error + etiSync->ERR = edi_tagDETI.stat = 0xFF; // ETS 300 799, 5.2, no error //****** Field FSYNC *****// // See ETS 300 799, 6.2.1.2 @@ -674,11 +697,11 @@ int main(int argc, char *argv[]) //****** FCT ******// // Incremente for each frame, overflows at 249 - fc->FCT = tagDETI.fct = currentFrame % 250; + fc->FCT = edi_tagDETI.fct = currentFrame % 250; //****** FICF ******// // Fast Information Channel Flag, 1 bit, =1 if FIC present - fc->FICF = tagDETI.ficf = 1; + fc->FICF = edi_tagDETI.ficf = 1; //****** NST ******// /* Number of audio of data sub-channels, 7 bits, 0-64. @@ -691,11 +714,11 @@ int main(int argc, char *argv[]) /* Frame Phase, 3 bit counter, tells the COFDM generator * when to insert the TII. Is also used by the MNSC. */ - fc->FP = tagDETI.fp = currentFrame & 0x7; + fc->FP = edi_tagDETI.fp = currentFrame & 0x7; //****** MID ******// //Mode Identity, 2 bits, 01 ModeI, 10 modeII, 11 ModeIII, 00 ModeIV - fc->MID = tagDETI.mid = ensemble->mode; //mode 2 needs 3 FIB, 3*32octets = 96octets + fc->MID = edi_tagDETI.mid = ensemble->mode; //mode 2 needs 3 FIB, 3*32octets = 96octets //****** FL ******// /* Frame Length, 11 bits, nb of words(4 bytes) in STC, EOH and MST @@ -717,6 +740,7 @@ int main(int argc, char *argv[]) /******* 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) { @@ -738,6 +762,17 @@ int main(int argc, char *argv[]) //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; } @@ -789,7 +824,7 @@ int main(int argc, char *argv[]) break; } - tagDETI.mnsc = eoh->MNSC; + edi_tagDETI.mnsc = eoh->MNSC; //CRC Cyclic Redundancy Checksum du FC, STC et MNSC, 2 octets nbBytesCRC = 4 + ((fc->NST) * 4) + 2; @@ -803,6 +838,8 @@ int main(int argc, char *argv[]) // 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; @@ -1805,13 +1842,21 @@ int main(int argc, char *argv[]) for (subchannel = ensemble->subchannels.begin(); subchannel != ensemble->subchannels.end(); ++subchannel) { + + TagESTn* tag = edi_subchannelToTag[*subchannel]; + int sizeSubchannel = getSizeByte(*subchannel); result = (*subchannel)->input->readFrame( &etiFrame[index], sizeSubchannel); + if (result < 0) { etiLog.log(info, "Subchannel %d read failed at ETI frame number: %d\n", (*subchannel)->id, currentFrame); } + + // save pointer to Audio or Data Stream into correct TagESTn for EDI + tag->mst_data = &etiFrame[index]; + index += sizeSubchannel; } @@ -1883,7 +1928,30 @@ int main(int argc, char *argv[]) dumpBytes(dumpData, sizeSubChannel, stderr); #endif // DUMP_BRIDGE + /********************************************************************** + *********** Finalise EDI ***************************************** + **********************************************************************/ + + // put all tags into one TagPacket + edi_tagpacket.tag_items.push_back(&edi_tagStarPtr); + edi_tagpacket.tag_items.push_back(&edi_tagDETI); + + list<TagESTn>::iterator tag; + for (tag = edi_subchannels.begin(); tag != edi_subchannels.end(); ++tag) { + edi_tagpacket.tag_items.push_back(&(*tag)); + } + + vector<uint8_t> edi_afpacketData = edi_afPacket.Assemble(edi_tagpacket); + +#if EDI_DEBUG + std::ostream_iterator<uint8_t> 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", diff --git a/src/Makefile.am b/src/Makefile.am index 738168c..709abe4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,6 +70,9 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \ dabOutput/dabOutputTcp.cpp \ dabOutput/dabOutputUdp.cpp \ dabOutput/dabOutputZMQ.cpp \ + dabOutput/edi/AFPacket.cpp dabOutput/edi/AFPacket.h \ + dabOutput/edi/TagItems.cpp dabOutput/edi/TagItems.h \ + dabOutput/edi/TagPacket.cpp dabOutput/edi/TagPacket.h \ bridge.h bridge.c \ utils.cpp utils.h \ MuxElements.cpp MuxElements.h \ diff --git a/src/dabOutput/edi/AFPacket.cpp b/src/dabOutput/edi/AFPacket.cpp index cd845d7..1516561 100644 --- a/src/dabOutput/edi/AFPacket.cpp +++ b/src/dabOutput/edi/AFPacket.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "crc.h" #include "AFPacket.h" +#include "TagItems.h" +#include "TagPacket.h" #include <vector> #include <string> #include <stdint.h> @@ -37,8 +39,10 @@ // AF Packet Major (3 bits) and Minor (4 bits) version #define AFHEADER_VERSION 0x8 // MAJ=1, MIN=0 -std::vector<uint8_t> AFPacket::Assemble(char protocol_type, std::vector<uint8_t> payload) +std::vector<uint8_t> AFPacket::Assemble(TagPacket tag_packet) { + std::vector<uint8_t> payload = tag_packet.Assemble(); + header.ar_maj = 1; header.ar_min = 0; header.pt = protocol_type; @@ -60,7 +64,7 @@ std::vector<uint8_t> AFPacket::Assemble(char protocol_type, std::vector<uint8_t> packet.push_back((have_crc ? 0x80 : 0) | AFHEADER_VERSION); // ar_cf: CRC=1 packet.push_back(AFHEADER_PT_TAG); - // insert payload + // insert payload, must have a length multiple of 8 bytes packet.insert(packet.end(), payload.begin(), payload.end()); // calculate CRC over AF Header and payload diff --git a/src/dabOutput/edi/AFPacket.h b/src/dabOutput/edi/AFPacket.h index 1fd0d16..0d41878 100644 --- a/src/dabOutput/edi/AFPacket.h +++ b/src/dabOutput/edi/AFPacket.h @@ -30,8 +30,12 @@ #include "config.h" #include <vector> #include <stdint.h> +#include "TagItems.h" +#include "TagPacket.h" #define PACKED __attribute__ ((packed)) +#define EDI_AFPACKET_PROTOCOLTYPE_TAGITEMS ('T') + // ETSI TS 102 821, 6.1 AF packet structure struct AFHeader { @@ -47,15 +51,17 @@ struct AFHeader class AFPacket { public: - AFPacket(); + AFPacket(char protocolType) : protocol_type(protocolType) {}; - std::vector<uint8_t> Assemble(char protocol_type, std::vector<uint8_t> payload); + std::vector<uint8_t> Assemble(TagPacket tag_packet); private: static const bool have_crc = true; AFHeader header; uint16_t seq; //counter that overflows at 0xFFFF + + char protocol_type; }; #endif diff --git a/src/dabOutput/edi/TagItems.h b/src/dabOutput/edi/TagItems.h index 6ae3bc6..2cebaf8 100644 --- a/src/dabOutput/edi/TagItems.h +++ b/src/dabOutput/edi/TagItems.h @@ -82,7 +82,7 @@ class TagDETI : public TagItem // the FIC (optional) bool ficf; - const char* fic_data; + const unsigned char* fic_data; size_t fic_length; // rfu diff --git a/src/dabOutput/edi/TagPacket.cpp b/src/dabOutput/edi/TagPacket.cpp new file mode 100644 index 0000000..b4d0bce --- /dev/null +++ b/src/dabOutput/edi/TagPacket.cpp @@ -0,0 +1,58 @@ +/* + Copyright (C) 2013 Matthias P. Braendli + http://mpb.li + + EDI output. + This defines a TAG Packet. + */ +/* + This file is part of CRC-DabMux. + + CRC-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + CRC-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CRC-DabMux. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" +#include "Eti.h" +#include "TagPacket.h" +#include "TagItems.h" +#include <vector> +#include <string> +#include <list> +#include <stdint.h> + + +std::vector<uint8_t> TagPacket::Assemble() +{ + std::list<TagItem*>::iterator tag; + + std::vector<uint8_t> packet; + + size_t packet_length = 0; + for (tag = tag_items.begin(); tag != tag_items.end(); ++tag) { + std::vector<uint8_t> tag_data = (*tag)->Assemble(); + packet.insert(packet.end(), tag_data.begin(), tag_data.end()); + + packet_length += tag_data.size(); + } + + // Add padding + while (packet_length % 8 > 0) + { + packet.push_back(0); // TS 102 821, 5.1, "padding shall be undefined" + packet_length++; + } + + return packet; +} + diff --git a/src/dabOutput/edi/TagPacket.h b/src/dabOutput/edi/TagPacket.h new file mode 100644 index 0000000..1286d2c --- /dev/null +++ b/src/dabOutput/edi/TagPacket.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2013 Matthias P. Braendli + http://mpb.li + + EDI output. + This defines a TAG Packet. + */ +/* + This file is part of CRC-DabMux. + + CRC-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + CRC-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CRC-DabMux. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TAGPACKET_H_ +#define _TAGPACKET_H_ + +#include "config.h" +#include "Eti.h" +#include <vector> +#include <string> +#include <list> +#include <stdint.h> + + + +// A TagPacket is nothing else than a list of tag items, with an +// Assemble function that puts the bytestream together and adds +// padding such that the total length is a multiple of 8 Bytes. +// +// ETSI TS 102 821, 5.1 Tag Packet +class TagPacket +{ + public: + std::vector<uint8_t> Assemble(); + + std::list<TagItem*> tag_items; +}; + +#endif + |