Finally process the Golay(24,12,8) parity bit.

This commit is contained in:
Jonathan Naylor 2021-03-27 20:00:53 +00:00
parent 4422444179
commit 6ac672e106
8 changed files with 63 additions and 67 deletions

View file

@ -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 * Copyright (C) 2016 Mathias Weyland, HB9FRV
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,6 +20,7 @@
#include "Golay24128.h" #include "Golay24128.h"
#include "Hamming.h" #include "Hamming.h"
#include "AMBEFEC.h" #include "AMBEFEC.h"
#include "Utils.h"
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
@ -792,10 +793,12 @@ unsigned int CAMBEFEC::regenerateIMBE(unsigned char* bytes) const
unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const
{ {
bool valid;
unsigned int orig_a = a; unsigned int orig_a = a;
unsigned int orig_b = b; unsigned int orig_b = b;
unsigned int data = CGolay24128::decode24128(a); unsigned int data = CGolay24128::decode24128(a, valid);
a = CGolay24128::encode24128(data); a = CGolay24128::encode24128(data);
@ -804,35 +807,29 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const
b ^= p; b ^= p;
unsigned int datb = CGolay24128::decode24128(b); unsigned int datb = CGolay24128::decode24128(b, valid);
b = CGolay24128::encode24128(datb); b = CGolay24128::encode24128(datb);
b ^= p; b ^= p;
unsigned int errsA = 0U, errsB = 0U;
unsigned int v = a ^ orig_a; unsigned int v = a ^ orig_a;
while (v != 0U) { unsigned int errsA = CUtils::countBits(v);
v &= v - 1U;
errsA++;
}
v = b ^ orig_b; v = b ^ orig_b;
while (v != 0U) { unsigned int errsB = CUtils::countBits(v);
v &= v - 1U;
errsB++;
}
return errsA + errsB; return errsA + errsB;
} }
unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned int& c) const unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned int& c) const
{ {
bool valid;
unsigned int orig_a = a; unsigned int orig_a = a;
unsigned int orig_b = b; unsigned int orig_b = b;
unsigned int data = CGolay24128::decode24128(a); unsigned int data = CGolay24128::decode24128(a, valid);
a = CGolay24128::encode24128(data); a = CGolay24128::encode24128(data);
@ -847,19 +844,11 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned
b ^= p; b ^= p;
unsigned int errsA = 0U, errsB = 0U;
unsigned int v = a ^ orig_a; unsigned int v = a ^ orig_a;
while (v != 0U) { unsigned int errsA = CUtils::countBits(v);
v &= v - 1U;
errsA++;
}
v = b ^ orig_b; v = b ^ orig_b;
while (v != 0U) { unsigned int errsB = CUtils::countBits(v);
v &= v - 1U;
errsB++;
}
if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) { if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) {
a = 0xF00292U; a = 0xF00292U;

View file

@ -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. * Copyright (C) 2002 by Robert H. Morelos-Zaragoza. All rights reserved.
*/ */
#include "Golay24128.h" #include "Golay24128.h"
#include "Utils.h"
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
@ -1089,20 +1090,23 @@ unsigned int CGolay24128::decode23127(unsigned int code)
return code >> 11; 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); assert(bytes != NULL);
unsigned int code = bytes[0U]; unsigned int code = (bytes[0U] << 16) | (bytes[1U] << 8) | (bytes[2U] << 0);
code <<= 8;
code |= bytes[1U];
code <<= 8;
code |= bytes[2U];
return decode23127(code >> 1); return decode24128(code, valid);
} }

View file

@ -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 * 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 * 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 encode24128(unsigned int data);
static unsigned int decode23127(unsigned int code); static unsigned int decode23127(unsigned int code);
static unsigned int decode24128(unsigned int code); static unsigned int decode24128(unsigned int code, bool& valid);
static unsigned int decode24128(unsigned char* bytes); static unsigned int decode24128(unsigned char* bytes, bool& valid);
}; };
#endif #endif

View file

@ -206,13 +206,14 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
} }
if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) { if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) {
unsigned int frag1, frag2, frag3, frag4; bool valid1, valid2, valid3, valid4;
CM17Utils::splitFragmentLICHFEC(data + 2U + M17_SYNC_LENGTH_BYTES, frag1, frag2, frag3, frag4); 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); if (!valid1 || !valid2 || !valid3 || !valid4)
unsigned int lich2 = CGolay24128::decode24128(frag2); return false;
unsigned int lich3 = CGolay24128::decode24128(frag3);
unsigned int lich4 = CGolay24128::decode24128(frag4);
unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES];
CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich); CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich);
@ -306,7 +307,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
unsigned int errors = 0U; unsigned int errors = 0U;
for (unsigned int i = 0U; i < (M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); i++) { 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; 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); 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; 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;
}

View file

@ -92,8 +92,6 @@ private:
bool checkCallsign(const std::string& source) const; bool checkCallsign(const std::string& source) const;
unsigned int countBits(unsigned char byte);
void writeEndRF(); void writeEndRF();
void writeEndNet(); void writeEndNet();

View file

@ -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 * 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 * 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[6U] ? 0x40U : 0x00U;
byte |= bits[7U] ? 0x80U : 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;
}

View file

@ -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 * 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 * 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 bitsToByteBE(const bool* bits, unsigned char& byte);
static void bitsToByteLE(const bool* bits, unsigned char& byte); static void bitsToByteLE(const bool* bits, unsigned char& byte);
static unsigned int countBits(unsigned int v);
private: private:
}; };

View file

@ -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 * 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 * 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]; unsigned char output[13U];
viterbi.chainback(output, 96U); viterbi.chainback(output, 96U);
unsigned int b0 = CGolay24128::decode24128(output + 0U); bool valid1, valid2, valid3, valid4;
unsigned int b1 = CGolay24128::decode24128(output + 3U); unsigned int b0 = CGolay24128::decode24128(output + 0U, valid1);
unsigned int b2 = CGolay24128::decode24128(output + 6U); unsigned int b1 = CGolay24128::decode24128(output + 3U, valid2);
unsigned int b3 = CGolay24128::decode24128(output + 9U); 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[0U] = (b0 >> 4) & 0xFFU;
m_fich[1U] = ((b0 << 4) & 0xF0U) | ((b1 >> 8) & 0x0FU); m_fich[1U] = ((b0 << 4) & 0xF0U) | ((b1 >> 8) & 0x0FU);