From ac2e922067be306a89cd10419263cade54b2f60f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 17 May 2014 18:01:26 +0200 Subject: fix segfault with EDI --- src/DabMux.cpp | 18 ++++++++++++++---- src/ReedSolomon.cpp | 4 ++-- src/dabOutput/edi/PFT.cpp | 21 +++++++++++++++------ src/dabOutput/edi/PFT.h | 13 +++++++++++-- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 6003c48..1b889f3 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -677,7 +677,7 @@ int main(int argc, char *argv[]) AFPacketiser edi_afPacketiser(EDI_AFPACKET_PROTOCOLTYPE_TAGITEMS); // The AF Packet will be protected with reed-solomon and split in fragments - PFT edi_pft(128, 3); + PFT edi_pft(208, 3); edi_tagDETI.atstf = 0; // TODO add ATST support @@ -1946,10 +1946,10 @@ int main(int argc, char *argv[]) #endif // DUMP_BRIDGE /********************************************************************** - *********** Finalise EDI ***************************************** + *********** Finalise and send EDI ******************************** **********************************************************************/ - // put all tags into one TagPacket + // put tags *ptr, DETI and all subchannels into one TagPacket edi_tagpacket.tag_items.push_back(&edi_tagStarPtr); edi_tagpacket.tag_items.push_back(&edi_tagDETI); @@ -1958,9 +1958,12 @@ int main(int argc, char *argv[]) edi_tagpacket.tag_items.push_back(&(*tag)); } + // Assemble into one AF Packet AFPacket edi_afpacket = edi_afPacketiser.Assemble(edi_tagpacket); - vector< vector > edi_fragments = edi_pft.ProtectAndFragment(edi_afpacket); + // Apply PFT layer to AF Packet (Reed Solomon FEC and Fragmentation) + vector< vector > edi_fragments = + edi_pft.ProtectAndFragment(edi_afpacket); #if EDI_DEBUG std::ostream_iterator debug_iterator(edi_debug_file); @@ -2004,6 +2007,13 @@ int main(int argc, char *argv[]) etiLog.level(error) << "Caught multiplex initialisation error: " << except.what(); } + catch (std::invalid_argument& except) { + etiLog.level(error) << "Caught invalid argument : %s", except.what(); + } + catch (std::runtime_error& except) { + etiLog.level(error) << "Caught runtime error : %s", except.what(); + } + etiLog.log(debug, "exiting...\n"); fflush(stderr); //fermeture des fichiers diff --git a/src/ReedSolomon.cpp b/src/ReedSolomon.cpp index 0989e17..5239a8f 100644 --- a/src/ReedSolomon.cpp +++ b/src/ReedSolomon.cpp @@ -20,6 +20,7 @@ */ #include "ReedSolomon.h" +#include #include // For galois.h ... #include // For memcpy @@ -46,8 +47,7 @@ ReedSolomon::ReedSolomon(int N, int K, bool reverse, int gfpoly, int firstRoot, rsData = init_rs_char(symsize, gfpoly, firstRoot, primElem, nroots, pad); if (rsData == NULL) { - fprintf(stderr, "ERROR: Invalid Reed Solomon parameters!\n"); - abort(); + throw std::invalid_argument("Invalid Reed-Solomon parameters!"); } } diff --git a/src/dabOutput/edi/PFT.cpp b/src/dabOutput/edi/PFT.cpp index e14a008..eba8ac0 100644 --- a/src/dabOutput/edi/PFT.cpp +++ b/src/dabOutput/edi/PFT.cpp @@ -31,6 +31,8 @@ #include "config.h" #include #include +#include +#include #include #include "PFT.h" #include "ReedSolomon.h" @@ -44,7 +46,14 @@ RSPacket PFT::Protect(AFPacket af_packet) { RSPacket rs_packet; - m_num_chunks = af_packet.size() / 207 + 1; + // number of chunks is ceil(afpacketsize / m_k) + if (af_packet.size() % m_k == 0) { + m_num_chunks = af_packet.size() / m_k; + } + else { + m_num_chunks = af_packet.size() / m_k + 1; + } + const size_t zero_pad = m_num_chunks * m_k - af_packet.size(); // add zero padding to last chunk @@ -53,16 +62,15 @@ RSPacket PFT::Protect(AFPacket af_packet) } for (size_t i = 1; i < af_packet.size(); i+= m_k) { - // add new chunk to the list Chunk c(m_k + ParityBytes); - for (size_t j = 0; j < m_k; j++) { - c[j] = af_packet[i+j]; - } + // copy m_k bytes into new chunk + memcpy(&c.front(), &af_packet[i], m_k); // calculate RS for chunk m_encoder.encode(&c.front(), c.size()); + // append new chunk to the RS Packet rs_packet.insert(rs_packet.end(), c.begin(), c.end()); } @@ -81,8 +89,9 @@ vector< vector > PFT::ProtectAndFragment(AFPacket af_packet) vector< vector > fragments(num_fragments); for (size_t i = 0; i < num_fragments; i++) { + fragments[i].resize(fragment_size); for (size_t j = 0; j < fragment_size; j++) { - fragments[i][j] = rs_packet[j*num_fragments + i]; //TODO that's wrong. fix it. + fragments[i][j] = rs_packet[j*num_fragments + i]; } } diff --git a/src/dabOutput/edi/PFT.h b/src/dabOutput/edi/PFT.h index 713170f..55ca569 100644 --- a/src/dabOutput/edi/PFT.h +++ b/src/dabOutput/edi/PFT.h @@ -34,6 +34,7 @@ #include "config.h" #include #include +#include #include #include "AFPacket.h" #include "Log.h" @@ -44,11 +45,19 @@ typedef std::vector RSPacket; class PFT { public: - static const int ParityBytes = 255 - 207; + static const int ParityBytes = 48; PFT(unsigned int RSDataWordLength, unsigned int NumRecoverableFragments) : - m_k(RSDataWordLength), m_m(NumRecoverableFragments), m_encoder(255, 207) + m_k(RSDataWordLength), + m_m(NumRecoverableFragments), + m_encoder(m_k + ParityBytes, m_k) { + if (m_k > 207) { + etiLog.level(warn) << + "EDI PFT: maximum chunk size is 207."; + throw std::out_of_range("EDI PFT Chunk size too large."); + } + if (m_m > 5) { etiLog.level(warn) << "EDI PFT: high number of recoverable fragments" -- cgit v1.2.3