From bdcf14ca3a83675cfc56f8656e7f7a5ea934ba3a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 17 Jul 2015 11:22:25 +0200 Subject: EDI: add options, fix AF sequence, revision --- doc/example.mux | 7 +++++++ src/DabMultiplexer.cpp | 31 +++++++++++++++---------------- src/DabMux.cpp | 3 +++ src/UdpSocket.cpp | 2 +- src/UdpSocket.h | 2 +- src/dabOutput/dabOutput.h | 2 ++ src/dabOutput/edi/AFPacket.cpp | 3 ++- src/dabOutput/edi/PFT.cpp | 2 +- src/dabOutput/edi/PFT.h | 8 +++----- 9 files changed, 35 insertions(+), 25 deletions(-) diff --git a/doc/example.mux b/doc/example.mux index abf01bc..1e6495b 100644 --- a/doc/example.mux +++ b/doc/example.mux @@ -296,6 +296,13 @@ outputs { ; Enable the PFT subsystem. If false, AFPackets are sent. enable_pft false + ; How many lost fragments can be recovered by Reed-Solomon + fec 3 + + ; Length of a RS chunk, can be overriden + ;default=207 + ;chunk_len 207 + ; Save the packets sent over ethernet to the file ./edi.debug dump false diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 4ca93aa..a894621 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -157,7 +157,7 @@ void DabMultiplexer::set_edi_config(const edi_configuration_t& new_edi_conf) edi_afPacketiser = afPacketiser; // The AF Packet will be protected with reed-solomon and split in fragments - PFT pft(207, 3, edi_conf); + PFT pft(edi_conf); edi_pft = pft; #endif } @@ -419,7 +419,9 @@ void DabMultiplexer::mux_frame(std::vector >& outpu // The above Tag Items will be assembled into a TAG Packet TagPacket edi_tagpacket; - edi_tagDETI.atstf = 0; // TODO add ATST support + edi_tagDETI.atstf = 1; + edi_tagDETI.utco = 0; + edi_tagDETI.seconds = 0; date = getDabTime(); @@ -1698,6 +1700,8 @@ void DabMultiplexer::mux_frame(std::vector >& outpu tist->TIST = htonl(0xffffff) | 0xff; } + edi_tagDETI.tsta = tist->TIST; + timestamp += 3 << 17; if (timestamp > 0xf9ffff) { @@ -1738,9 +1742,8 @@ void DabMultiplexer::mux_frame(std::vector >& outpu 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)); + for (auto& tag : edi_subchannels) { + edi_tagpacket.tag_items.push_back(&tag); } // Assemble into one AF Packet @@ -1752,24 +1755,20 @@ void DabMultiplexer::mux_frame(std::vector >& outpu edi_pft.Assemble(edi_afpacket); // Send over ethernet - vector< vector >::iterator edi_frag; - for (edi_frag = edi_fragments.begin(); - edi_frag != edi_fragments.end(); - ++edi_frag) { - + for (const auto& edi_frag : edi_fragments) { UdpPacket udppacket; InetAddress& addr = udppacket.getAddress(); addr.setAddress(edi_conf.dest_addr.c_str()); addr.setPort(edi_conf.dest_port); - udppacket.addData(&(edi_frag->front()), edi_frag->size()); + udppacket.addData(&(edi_frag.front()), edi_frag.size()); edi_output.send(udppacket); if (edi_conf.dump) { std::ostream_iterator debug_iterator(edi_debug_file); - std::copy(edi_frag->begin(), edi_frag->end(), debug_iterator); + std::copy(edi_frag.begin(), edi_frag.end(), debug_iterator); } } @@ -1790,11 +1789,11 @@ void DabMultiplexer::mux_frame(std::vector >& outpu udppacket.addData(&(edi_afpacket.front()), edi_afpacket.size()); edi_output.send(udppacket); - } - if (edi_conf.dump) { - std::ostream_iterator debug_iterator(edi_debug_file); - std::copy(edi_afpacket.begin(), edi_afpacket.end(), debug_iterator); + if (edi_conf.dump) { + std::ostream_iterator debug_iterator(edi_debug_file); + std::copy(edi_afpacket.begin(), edi_afpacket.end(), debug_iterator); + } } } #endif // HAVE_OUTPUT_EDI diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 20dc31d..854c311 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -331,6 +331,9 @@ int main(int argc, char *argv[]) edi_conf.enable_pft = pt_edi.get("enable_pft"); edi_conf.verbose = pt_edi.get("verbose"); + edi_conf.fec = pt_edi.get("fec"); + edi_conf.chunk_len = pt_edi.get("chunk_len", 207); + mux.set_edi_config(edi_conf); #else throw runtime_error("EDI output not compiled in"); diff --git a/src/UdpSocket.cpp b/src/UdpSocket.cpp index 6d2728b..74730e9 100644 --- a/src/UdpSocket.cpp +++ b/src/UdpSocket.cpp @@ -333,7 +333,7 @@ char *UdpPacket::getData() * @param data Pointer to the data to add * @param size Size in bytes of new data */ -void UdpPacket::addData(void *data, unsigned size) +void UdpPacket::addData(const void *data, unsigned size) { if (length + size > this->size) { setSize(this->size << 1); diff --git a/src/UdpSocket.h b/src/UdpSocket.h index f1487b3..109732f 100644 --- a/src/UdpSocket.h +++ b/src/UdpSocket.h @@ -106,7 +106,7 @@ class UdpPacket { ~UdpPacket(); char *getData(); - void addData(void *data, unsigned size); + void addData(const void *data, unsigned size); unsigned long getLength(); unsigned long getSize(); unsigned long getOffset(); diff --git a/src/dabOutput/dabOutput.h b/src/dabOutput/dabOutput.h index f6980fe..c8ce9f2 100644 --- a/src/dabOutput/dabOutput.h +++ b/src/dabOutput/dabOutput.h @@ -55,6 +55,8 @@ // Configuration for EDI output struct edi_configuration_t { + unsigned chunk_len; // RSk, data length of each chunk + unsigned fec; // number of fragments that can be recovered bool enabled; unsigned int source_port; bool dump; diff --git a/src/dabOutput/edi/AFPacket.cpp b/src/dabOutput/edi/AFPacket.cpp index 3b69f1c..a1d39b9 100644 --- a/src/dabOutput/edi/AFPacket.cpp +++ b/src/dabOutput/edi/AFPacket.cpp @@ -39,7 +39,7 @@ #define AFHEADER_PT_TAG 'T' // AF Packet Major (3 bits) and Minor (4 bits) version -#define AFHEADER_VERSION 0x8 // MAJ=1, MIN=0 +#define AFHEADER_VERSION 0x10 // MAJ=1, MIN=0 AFPacket AFPacketiser::Assemble(TagPacket tag_packet) { @@ -65,6 +65,7 @@ AFPacket AFPacketiser::Assemble(TagPacket tag_packet) // fill rest of header packet.push_back(seq >> 8); packet.push_back(seq & 0xFF); + seq++; packet.push_back((have_crc ? 0x80 : 0) | AFHEADER_VERSION); // ar_cf: CRC=1 packet.push_back(AFHEADER_PT_TAG); diff --git a/src/dabOutput/edi/PFT.cpp b/src/dabOutput/edi/PFT.cpp index e1c8249..7f463cc 100644 --- a/src/dabOutput/edi/PFT.cpp +++ b/src/dabOutput/edi/PFT.cpp @@ -52,7 +52,7 @@ RSBlock PFT::Protect(AFPacket af_packet) // number of chunks is ceil(afpacketsize / m_k) // TS 102 821 7.2.2: c = ceil(l / k_max) - m_num_chunks = CEIL_DIV(af_packet.size(), 207); + m_num_chunks = CEIL_DIV(af_packet.size(), m_k); if (m_verbose) { fprintf(stderr, "Protect %zu chunks of size %zu\n", diff --git a/src/dabOutput/edi/PFT.h b/src/dabOutput/edi/PFT.h index 9c6f7bd..e17d282 100644 --- a/src/dabOutput/edi/PFT.h +++ b/src/dabOutput/edi/PFT.h @@ -57,11 +57,9 @@ class PFT m_verbose(false) { } - PFT(unsigned int RSDataWordLength, - unsigned int NumRecoverableFragments, - const edi_configuration_t &conf) : - m_k(RSDataWordLength), - m_m(NumRecoverableFragments), + PFT(const edi_configuration_t &conf) : + m_k(conf.chunk_len), + m_m(conf.fec), m_dest_port(conf.dest_port), m_pseq(0), m_verbose(conf.verbose) -- cgit v1.2.3