From 9e83d23c48bcdba9ca041989f5cc199c79a6f158 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 14 Jul 2016 18:58:03 +0100 Subject: [PATCH] Simple minded rate 3/4 FEC decoding. --- DMRSlot.cpp | 12 ++++----- DMRTrellis.cpp | 67 ++++++++++++++++++++++++++++++++++++++------------ DMRTrellis.h | 1 + 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 3dc8ecd..12dcbd8 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -365,11 +365,11 @@ void CDMRSlot::writeModem(unsigned char *data) bptc.decode(data + 2U, payload); bptc.encode(payload, data + 2U); } else if (dataType == DT_RATE_34_DATA) { - LogDebug("DMR Slot %u, received RF rate 3/4 data", m_slotNo); CDMRTrellis trellis; unsigned char payload[18U]; - trellis.decode(data + 2U, payload); - // trellis.encode(payload, data + 2U); + bool ret = trellis.decode(data + 2U, payload); + if (ret) + trellis.encode(payload, data + 2U); } // Regenerate the Slot Type @@ -1164,11 +1164,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) bptc.decode(data + 2U, payload); bptc.encode(payload, data + 2U); } else if (dataType == DT_RATE_34_DATA) { - LogDebug("DMR Slot %u, received network rate 3/4 data", m_slotNo); CDMRTrellis trellis; unsigned char payload[18U]; - trellis.decode(data + 2U, payload); - // trellis.encode(payload, data + 2U); + bool ret = trellis.decode(data + 2U, payload); + if (ret) + trellis.encode(payload, data + 2U); } // Regenerate the Slot Type diff --git a/DMRTrellis.cpp b/DMRTrellis.cpp index f2bc0c1..60eb33d 100644 --- a/DMRTrellis.cpp +++ b/DMRTrellis.cpp @@ -59,29 +59,38 @@ bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload) dibitsToPoints(dibits, points); unsigned char tribits[49U]; - unsigned char state = 0U; - for (unsigned int i = 0U; i < 49U; i++) { - tribits[i] = 9U; + // Check the original code + unsigned int failPos = checkCode(points, tribits); + if (failPos == 999U) { + tribitsToBits(tribits, payload); + return true; + } - for (unsigned int j = 0U; j < 8U; j++) { - if (points[i] == ENCODE_TABLE[state * 8U + j]) { - tribits[i] = j; - break; + for (unsigned j = 0U; j < 20U; j++) { + unsigned int bestPos = 0U; + unsigned int bestVal = 0U; + + for (unsigned int i = 0U; i < 16U; i++) { + points[failPos] = i; + + unsigned int pos = checkCode(points, tribits); + if (pos == 999U) { + tribitsToBits(tribits, payload); + return true; + } + + if (pos > bestPos) { + bestPos = pos; + bestVal = i; } } - if (tribits[i] == 9U) { - LogDebug("Decoding failure at position %u", i); - return false; - } - - state = tribits[i]; + points[failPos] = bestVal; + failPos = bestPos; } - tribitsToBits(tribits, payload); - - return true; + return false; } void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data) @@ -320,3 +329,29 @@ void CDMRTrellis::tribitsToBits(const unsigned char* tribits, unsigned char* pay WRITE_BIT(payload, n, b3); } } + +unsigned int CDMRTrellis::checkCode(const unsigned char* points, unsigned char* tribits) const +{ + unsigned char state = 0U; + + for (unsigned int i = 0U; i < 49U; i++) { + tribits[i] = 9U; + + for (unsigned int j = 0U; j < 8U; j++) { + if (points[i] == ENCODE_TABLE[state * 8U + j]) { + tribits[i] = j; + break; + } + } + + if (tribits[i] == 9U) + return i; + + state = tribits[i]; + } + + if (tribits[48U] != 0U) + return 48U; + + return 999U; +} diff --git a/DMRTrellis.h b/DMRTrellis.h index a902fd9..a63043b 100644 --- a/DMRTrellis.h +++ b/DMRTrellis.h @@ -29,6 +29,7 @@ private: void pointsToDibits(const unsigned char* points, signed char* dibits) const; void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const; void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const; + unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const; }; #endif