From 6ac672e10619f4abe0e113ceaebcea00cbb62f11 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sat, 27 Mar 2021 20:00:53 +0000 Subject: [PATCH] Finally process the Golay(24,12,8) parity bit. --- AMBEFEC.cpp | 37 +++++++++++++------------------------ Golay24128.cpp | 24 ++++++++++++++---------- Golay24128.h | 6 +++--- M17Control.cpp | 29 ++++++++--------------------- M17Control.h | 2 -- Utils.cpp | 14 +++++++++++++- Utils.h | 4 +++- YSFFICH.cpp | 14 +++++++++----- 8 files changed, 63 insertions(+), 67 deletions(-) diff --git a/AMBEFEC.cpp b/AMBEFEC.cpp index 864c35d..4b28046 100644 --- a/AMBEFEC.cpp +++ b/AMBEFEC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2014,2016,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2010,2014,2016,2018,2021 by Jonathan Naylor G4KLX * Copyright (C) 2016 Mathias Weyland, HB9FRV * * This program is free software; you can redistribute it and/or modify @@ -20,6 +20,7 @@ #include "Golay24128.h" #include "Hamming.h" #include "AMBEFEC.h" +#include "Utils.h" #include #include @@ -792,10 +793,12 @@ unsigned int CAMBEFEC::regenerateIMBE(unsigned char* bytes) const unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const { + bool valid; + unsigned int orig_a = a; unsigned int orig_b = b; - unsigned int data = CGolay24128::decode24128(a); + unsigned int data = CGolay24128::decode24128(a, valid); a = CGolay24128::encode24128(data); @@ -804,35 +807,29 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const b ^= p; - unsigned int datb = CGolay24128::decode24128(b); + unsigned int datb = CGolay24128::decode24128(b, valid); b = CGolay24128::encode24128(datb); b ^= p; - unsigned int errsA = 0U, errsB = 0U; - unsigned int v = a ^ orig_a; - while (v != 0U) { - v &= v - 1U; - errsA++; - } + unsigned int errsA = CUtils::countBits(v); v = b ^ orig_b; - while (v != 0U) { - v &= v - 1U; - errsB++; - } + unsigned int errsB = CUtils::countBits(v); return errsA + errsB; } unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned int& c) const { + bool valid; + unsigned int orig_a = a; unsigned int orig_b = b; - unsigned int data = CGolay24128::decode24128(a); + unsigned int data = CGolay24128::decode24128(a, valid); a = CGolay24128::encode24128(data); @@ -847,19 +844,11 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned b ^= p; - unsigned int errsA = 0U, errsB = 0U; - unsigned int v = a ^ orig_a; - while (v != 0U) { - v &= v - 1U; - errsA++; - } + unsigned int errsA = CUtils::countBits(v); v = b ^ orig_b; - while (v != 0U) { - v &= v - 1U; - errsB++; - } + unsigned int errsB = CUtils::countBits(v); if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) { a = 0xF00292U; diff --git a/Golay24128.cpp b/Golay24128.cpp index 417da00..715c8dc 100644 --- a/Golay24128.cpp +++ b/Golay24128.cpp @@ -1,9 +1,10 @@ /* - * Copyright (C) 2010,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2010,2016,2021 by Jonathan Naylor G4KLX * Copyright (C) 2002 by Robert H. Morelos-Zaragoza. All rights reserved. */ #include "Golay24128.h" +#include "Utils.h" #include #include @@ -1089,20 +1090,23 @@ unsigned int CGolay24128::decode23127(unsigned int code) return code >> 11; } -unsigned int CGolay24128::decode24128(unsigned int code) +unsigned int CGolay24128::decode24128(unsigned int input, bool& valid) { - return decode23127(code >> 1); + unsigned int syndrome = ::get_syndrome_23127(input >> 1); + unsigned int error_pattern = DECODING_TABLE_23127[syndrome] << 1; + + unsigned int output = input ^ error_pattern; + + valid = (CUtils::countBits(syndrome) < 3U) || !(CUtils::countBits(output) & 1); + + return output >> 12; } -unsigned int CGolay24128::decode24128(unsigned char* bytes) +unsigned int CGolay24128::decode24128(unsigned char* bytes, bool& valid) { assert(bytes != NULL); - unsigned int code = bytes[0U]; - code <<= 8; - code |= bytes[1U]; - code <<= 8; - code |= bytes[2U]; + unsigned int code = (bytes[0U] << 16) | (bytes[1U] << 8) | (bytes[2U] << 0); - return decode23127(code >> 1); + return decode24128(code, valid); } diff --git a/Golay24128.h b/Golay24128.h index 1ac7852..721dcbc 100644 --- a/Golay24128.h +++ b/Golay24128.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2010,2016,2021 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,8 +25,8 @@ public: static unsigned int encode24128(unsigned int data); static unsigned int decode23127(unsigned int code); - static unsigned int decode24128(unsigned int code); - static unsigned int decode24128(unsigned char* bytes); + static unsigned int decode24128(unsigned int code, bool& valid); + static unsigned int decode24128(unsigned char* bytes, bool& valid); }; #endif diff --git a/M17Control.cpp b/M17Control.cpp index 14d1c83..4defcd7 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -206,13 +206,14 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) } if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) { - unsigned int frag1, frag2, frag3, frag4; - CM17Utils::splitFragmentLICHFEC(data + 2U + M17_SYNC_LENGTH_BYTES, frag1, frag2, frag3, frag4); + bool valid1, valid2, valid3, valid4; + unsigned int lich1 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 0U, valid1); + unsigned int lich2 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 3U, valid2); + unsigned int lich3 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 6U, valid3); + unsigned int lich4 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 9U, valid4); - unsigned int lich1 = CGolay24128::decode24128(frag1); - unsigned int lich2 = CGolay24128::decode24128(frag2); - unsigned int lich3 = CGolay24128::decode24128(frag3); - unsigned int lich4 = CGolay24128::decode24128(frag4); + if (!valid1 || !valid2 || !valid3 || !valid4) + return false; unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich); @@ -306,7 +307,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) unsigned int errors = 0U; for (unsigned int i = 0U; i < (M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); i++) { unsigned int offset = i + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES; - errors += countBits(rfData[offset] ^ data[offset]); + errors += CUtils::countBits(rfData[offset] ^ data[offset]); } LogDebug("M17, FN: %u, errs: %u/144 (%.1f%%)", m_rfFN & 0x7FU, errors, float(errors) / 1.44F); @@ -785,17 +786,3 @@ void CM17Control::enable(bool enabled) m_enabled = enabled; } - -unsigned int CM17Control::countBits(unsigned char byte) -{ - unsigned int count = 0U; - - const unsigned char* p = &byte; - - for (unsigned int i = 0U; i < 8U; i++) { - if (READ_BIT(p, i) != 0U) - count++; - } - - return count; -} diff --git a/M17Control.h b/M17Control.h index 9ed515c..d351099 100644 --- a/M17Control.h +++ b/M17Control.h @@ -92,8 +92,6 @@ private: bool checkCallsign(const std::string& source) const; - unsigned int countBits(unsigned char byte); - void writeEndRF(); void writeEndNet(); diff --git a/Utils.cpp b/Utils.cpp index 49ded13..3ecdf60 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2014,2015,2016 Jonathan Naylor, G4KLX + * Copyright (C) 2009,2014,2015,2016,2021 Jonathan Naylor, G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -144,3 +144,15 @@ void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte) byte |= bits[6U] ? 0x40U : 0x00U; byte |= bits[7U] ? 0x80U : 0x00U; } + +unsigned int CUtils::countBits(unsigned int v) +{ + unsigned int count = 0U; + + while (v != 0U) { + v &= v - 1U; + count++; + } + + return count; +} diff --git a/Utils.h b/Utils.h index ade28c0..1929aa0 100644 --- a/Utils.h +++ b/Utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2014,2015 by Jonathan Naylor, G4KLX + * Copyright (C) 2009,2014,2015,2021 by Jonathan Naylor, G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,8 @@ public: static void bitsToByteBE(const bool* bits, unsigned char& byte); static void bitsToByteLE(const bool* bits, unsigned char& byte); + static unsigned int countBits(unsigned int v); + private: }; diff --git a/YSFFICH.cpp b/YSFFICH.cpp index 7227014..ce37a7f 100644 --- a/YSFFICH.cpp +++ b/YSFFICH.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016,2017,2019,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2016,2017,2019,2020,2021 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -99,10 +99,14 @@ bool CYSFFICH::decode(const unsigned char* bytes) unsigned char output[13U]; viterbi.chainback(output, 96U); - unsigned int b0 = CGolay24128::decode24128(output + 0U); - unsigned int b1 = CGolay24128::decode24128(output + 3U); - unsigned int b2 = CGolay24128::decode24128(output + 6U); - unsigned int b3 = CGolay24128::decode24128(output + 9U); + bool valid1, valid2, valid3, valid4; + unsigned int b0 = CGolay24128::decode24128(output + 0U, valid1); + unsigned int b1 = CGolay24128::decode24128(output + 3U, valid2); + unsigned int b2 = CGolay24128::decode24128(output + 6U, valid3); + unsigned int b3 = CGolay24128::decode24128(output + 9U, valid4); + + if (!valid1 || !valid2 || !valid3 || !valid4) + return false; m_fich[0U] = (b0 >> 4) & 0xFFU; m_fich[1U] = ((b0 << 4) & 0xF0U) | ((b1 >> 8) & 0x0FU);