From d60b36afc30460f070f25dd8ee8d52b556ea8790 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 21 May 2014 17:23:36 +0200 Subject: Add PFT Fragment header --- src/DabMux.cpp | 15 +++++++----- src/dabOutput/edi/PFT.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++ src/dabOutput/edi/PFT.h | 8 ++++++ 3 files changed, 79 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 41d7f72..704de4c 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -682,7 +682,7 @@ int main(int argc, char *argv[]) // The AF Packet will be protected with reed-solomon and split in fragments #if EDI_PFT - PFT edi_pft(208, 3); + PFT edi_pft(207, 3); #endif edi_tagDETI.atstf = 0; // TODO add ATST support @@ -1970,8 +1970,8 @@ int main(int argc, char *argv[]) # if EDI_PFT // Apply PFT layer to AF Packet (Reed Solomon FEC and Fragmentation) - vector< vector > edi_fragments = - edi_pft.ProtectAndFragment(edi_afpacket); + vector< PFTFragment > edi_fragments = + edi_pft.Assemble(edi_afpacket); // Send over ethernet vector< vector >::iterator edi_frag; @@ -1982,13 +1982,15 @@ int main(int argc, char *argv[]) UdpPacket udppacket; InetAddress& addr = udppacket.getAddress(); - addr.setAddress("192.168.2.2"); + addr.setAddress("127.0.0.1"); addr.setPort(12000); udppacket.addData(&(edi_frag->front()), edi_frag->size()); edi_output.send(udppacket); } + + fprintf(stderr, "EDI number of PFT fragments %zu\n", edi_fragments.size()); # else // Send over ethernet @@ -2005,7 +2007,6 @@ int main(int argc, char *argv[]) //std::ostream_iterator debug_iterator(edi_debug_file); //std::copy(edi_afpacket.begin(), edi_afpacket.end(), debug_iterator); - fprintf(stderr, "EDI number of fragments %zu\n", edi_fragments.size()); #endif #if _DEBUG @@ -2057,7 +2058,9 @@ int main(int argc, char *argv[]) for (subchannel = ensemble->subchannels.begin(); subchannel != ensemble->subchannels.end(); ++subchannel) { - (*subchannel)->input->close(); + if ((*subchannel)->input != NULL) { + (*subchannel)->input->close(); + } delete (*subchannel)->input; } for (output = outputs.begin() ; output != outputs.end(); ++output) { diff --git a/src/dabOutput/edi/PFT.cpp b/src/dabOutput/edi/PFT.cpp index eba8ac0..e04ffab 100644 --- a/src/dabOutput/edi/PFT.cpp +++ b/src/dabOutput/edi/PFT.cpp @@ -34,7 +34,9 @@ #include #include #include +#include #include "PFT.h" +#include "crc.h" #include "ReedSolomon.h" using namespace std; @@ -98,3 +100,63 @@ vector< vector > PFT::ProtectAndFragment(AFPacket af_packet) return fragments; } +std::vector< PFTFragment > PFT::Assemble(AFPacket af_packet) +{ + vector< vector > fragments = ProtectAndFragment(af_packet); + vector< vector > pft_fragments; + + unsigned int findex = 0; + + unsigned fcount = fragments.size(); + + const size_t zero_pad = m_num_chunks * m_k - af_packet.size(); + + for (size_t i = 0; i < fragments.size(); i++) { + const vector& fragment = fragments[i]; + + std::string psync("PF"); // SYNC + std::vector packet(psync.begin(), psync.end()); + + packet.push_back(m_pseq >> 8); + packet.push_back(m_pseq & 0xFF); + m_pseq++; + + packet.push_back(findex >> 16); + packet.push_back(findex >> 8); + packet.push_back(findex & 0xFF); + findex++; + + packet.push_back(fcount >> 16); + packet.push_back(fcount >> 8); + packet.push_back(fcount & 0xFF); + + unsigned int plen = fragment.size(); + plen |= 0x8000; // Set FEC bit + + packet.push_back(plen >> 16); + packet.push_back(plen >> 8); + packet.push_back(plen & 0xFF); + + packet.push_back(m_k); + packet.push_back(zero_pad); + + // calculate CRC over AF Header and payload + uint16_t crc = 0xffff; + crc = crc16(crc, &(packet.back()), packet.size()); + crc ^= 0xffff; + crc = htons(crc); + + packet.push_back((crc >> 24) & 0xFF); + packet.push_back((crc >> 16) & 0xFF); + packet.push_back((crc >> 8) & 0xFF); + packet.push_back(crc & 0xFF); + + // insert payload, must have a length multiple of 8 bytes + packet.insert(packet.end(), fragment.begin(), fragment.end()); + + pft_fragments.push_back(packet); + } + + return pft_fragments; +} + diff --git a/src/dabOutput/edi/PFT.h b/src/dabOutput/edi/PFT.h index 55ca569..49bb7b7 100644 --- a/src/dabOutput/edi/PFT.h +++ b/src/dabOutput/edi/PFT.h @@ -41,6 +41,7 @@ #include "ReedSolomon.h" typedef std::vector RSPacket; +typedef std::vector PFTFragment; class PFT { @@ -50,6 +51,7 @@ class PFT PFT(unsigned int RSDataWordLength, unsigned int NumRecoverableFragments) : m_k(RSDataWordLength), m_m(NumRecoverableFragments), + m_pseq(0), m_encoder(m_k + ParityBytes, m_k) { if (m_k > 207) { @@ -66,6 +68,10 @@ class PFT } } + // return a list of PFT fragments with the correct + // PFT headers + std::vector< PFTFragment > Assemble(AFPacket af_packet); + // Apply Reed-Solomon FEC to the AF Packet RSPacket Protect(AFPacket af_packet); @@ -76,6 +82,8 @@ class PFT unsigned int m_k; // length of RS data word unsigned int m_m; // number of fragments that can be recovered if lost + uint16_t m_pseq; + size_t m_num_chunks; ReedSolomon m_encoder; -- cgit v1.2.3