summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2014-05-21 17:23:36 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2014-05-21 17:23:36 +0200
commitd60b36afc30460f070f25dd8ee8d52b556ea8790 (patch)
tree7b1c9674579bc5de0535ff581e1f6ed99a60a669
parent91aa7a5ee75298f9ded7db18f4ba0156bbfc3bb3 (diff)
downloaddabmux-d60b36afc30460f070f25dd8ee8d52b556ea8790.tar.gz
dabmux-d60b36afc30460f070f25dd8ee8d52b556ea8790.tar.bz2
dabmux-d60b36afc30460f070f25dd8ee8d52b556ea8790.zip
Add PFT Fragment header
-rw-r--r--src/DabMux.cpp15
-rw-r--r--src/dabOutput/edi/PFT.cpp62
-rw-r--r--src/dabOutput/edi/PFT.h8
3 files changed, 79 insertions, 6 deletions
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<uint8_t> > edi_fragments =
- edi_pft.ProtectAndFragment(edi_afpacket);
+ vector< PFTFragment > edi_fragments =
+ edi_pft.Assemble(edi_afpacket);
// Send over ethernet
vector< vector<uint8_t> >::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<uint8_t> 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 <cstdio>
#include <cstring>
#include <stdint.h>
+#include <arpa/inet.h>
#include "PFT.h"
+#include "crc.h"
#include "ReedSolomon.h"
using namespace std;
@@ -98,3 +100,63 @@ vector< vector<uint8_t> > PFT::ProtectAndFragment(AFPacket af_packet)
return fragments;
}
+std::vector< PFTFragment > PFT::Assemble(AFPacket af_packet)
+{
+ vector< vector<uint8_t> > fragments = ProtectAndFragment(af_packet);
+ vector< vector<uint8_t> > 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<uint8_t>& fragment = fragments[i];
+
+ std::string psync("PF"); // SYNC
+ std::vector<uint8_t> 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<uint8_t> RSPacket;
+typedef std::vector<uint8_t> 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;