diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-10-17 19:38:56 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-10-17 19:38:56 +0200 |
commit | 31e8a4fd8e4c057fffc84c071cc0b71a7989795c (patch) | |
tree | 3b44d5a3eb4e9379e4f5ffd481e5b082eec8ca31 | |
parent | a61ce56def02ae5fbfa41c4a2ec0c2ba4b93ba14 (diff) | |
download | dabmux-31e8a4fd8e4c057fffc84c071cc0b71a7989795c.tar.gz dabmux-31e8a4fd8e4c057fffc84c071cc0b71a7989795c.tar.bz2 dabmux-31e8a4fd8e4c057fffc84c071cc0b71a7989795c.zip |
Correct PFT RS encoding
-rw-r--r-- | src/ReedSolomon.cpp | 2 | ||||
-rw-r--r-- | src/dabOutput/edi/PFT.cpp | 28 |
2 files changed, 24 insertions, 6 deletions
diff --git a/src/ReedSolomon.cpp b/src/ReedSolomon.cpp index ced9e1d..c72fb14 100644 --- a/src/ReedSolomon.cpp +++ b/src/ReedSolomon.cpp @@ -29,7 +29,7 @@ extern "C" { #include <fec.h> } #include <assert.h> -#include <stdlib.h> +#include <stdlib.h> #define SYMSIZE 8 diff --git a/src/dabOutput/edi/PFT.cpp b/src/dabOutput/edi/PFT.cpp index 4578392..3352136 100644 --- a/src/dabOutput/edi/PFT.cpp +++ b/src/dabOutput/edi/PFT.cpp @@ -35,6 +35,8 @@ #include <cstring> #include <stdint.h> #include <arpa/inet.h> +#include <stdexcept> +#include <sstream> #include "PFT.h" #include "crc.h" #include "ReedSolomon.h" @@ -61,13 +63,24 @@ RSBlock PFT::Protect(AFPacket af_packet) // TS 102 821 7.2.2: k = ceil(l / c) // chunk_len does not include the 48 bytes of protection. const size_t chunk_len = CEIL_DIV(af_packet.size(), m_num_chunks); + if (chunk_len > 207) { + std::stringstream ss; + ss << "Chunk length " << chunk_len << " too large (>207)"; + throw std::runtime_error(ss.str()); + } // The last RS chunk is zero padded // TS 102 821 7.2.2: z = c*k - l const size_t zero_pad = m_num_chunks * chunk_len - af_packet.size(); // Create the RS(k+p,k) encoder - ReedSolomon rs_encoder(chunk_len + ParityBytes, chunk_len); + const int firstRoot = 1; // Discovered by analysing EDI dump + const int gfPoly = 0x11d; + const bool reverse = 0; + // The encoding has to be 255, 207 always, because the chunk has to + // be padded at the end, and not at the beginning as libfec would + // do + ReedSolomon rs_encoder(255, 207, reverse, gfPoly, firstRoot); // add zero padding to last chunk for (size_t i = 0; i < zero_pad; i++) { @@ -80,16 +93,21 @@ RSBlock PFT::Protect(AFPacket af_packet) // Calculate RS for each chunk and assemble RS block for (size_t i = 0; i < af_packet.size(); i+= chunk_len) { - vector<uint8_t> chunk(chunk_len + ParityBytes); + vector<uint8_t> chunk(207); + vector<uint8_t> protection(ParityBytes); // copy chunk_len bytes into new chunk memcpy(&chunk.front(), &af_packet[i], chunk_len); - // calculate RS for chunk - rs_encoder.encode(&chunk.front(), chunk.size()); + // calculate RS for chunk with padding + rs_encoder.encode(&chunk.front(), &protection.front(), 207); + + // Drop the padding + chunk.resize(chunk_len); - // append new chunk to the RS Packet + // append new chunk and protection to the RS Packet rs_block.insert(rs_block.end(), chunk.begin(), chunk.end()); + rs_block.insert(rs_block.end(), protection.begin(), protection.end()); } return rs_block; |