Skip to content

Commit

Permalink
Merge pull request #61 from srcejon/fix_golay20
Browse files Browse the repository at this point in the history
Fix Golay_20_8 parity correction
  • Loading branch information
f4exb committed Nov 29, 2023
2 parents 64e7590 + cdfa2af commit 75c5b94
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 13 deletions.
2 changes: 1 addition & 1 deletion dmr.cpp
Expand Up @@ -993,7 +993,7 @@ void DSDDMR::processSlotTypePDU()

unsigned int dataType = (slotTypeBits[4] << 3) + (slotTypeBits[5] << 2) + (slotTypeBits[6] << 1) + slotTypeBits[7];

if (dataType > DMR_TYPES_COUNT)
if (dataType >= DMR_TYPES_COUNT)
{
m_dataType = DSDDMRDataReserved;
memcpy(&m_slotText[4], "RES", 3);
Expand Down
20 changes: 10 additions & 10 deletions fec.cpp
Expand Up @@ -650,7 +650,7 @@ void Golay_20_8::init()
int syndromeIP = syndromeI ^ (1 << (11-ip));
m_corr[syndromeIP][0] = i1;
m_corr[syndromeIP][1] = i2;
m_corr[syndromeIP][2] = 12 + ip;
m_corr[syndromeIP][2] = 8 + ip;
}
}

Expand All @@ -669,14 +669,14 @@ void Golay_20_8::init()
{
int syndromeIP1 = syndromeI ^ (1 << (11-ip1));
m_corr[syndromeIP1][0] = i1;
m_corr[syndromeIP1][1] = 12 + ip1;
m_corr[syndromeIP1][1] = 8 + ip1;

for (int ip2 = ip1+1; ip2 < 12; ip2++) // 1 more bit flip in parity
{
int syndromeIP2 = syndromeIP1 ^ (1 << (11-ip2));
m_corr[syndromeIP2][0] = i1;
m_corr[syndromeIP2][1] = 12 + ip1;
m_corr[syndromeIP2][2] = 12 + ip2;
m_corr[syndromeIP2][1] = 8 + ip1;
m_corr[syndromeIP2][2] = 8 + ip2;
}
}
}
Expand All @@ -685,20 +685,20 @@ void Golay_20_8::init()
for (int ip1 = 0; ip1 < 12; ip1++) // 1 bit flip in parity
{
int syndromeIP1 = (1 << (11-ip1));
m_corr[syndromeIP1][0] = 12 + ip1;
m_corr[syndromeIP1][0] = 8 + ip1;

for (int ip2 = ip1+1; ip2 < 12; ip2++) // 1 more bit flip in parity
{
int syndromeIP2 = syndromeIP1 ^ (1 << (11-ip2));
m_corr[syndromeIP2][0] = 12 + ip1;
m_corr[syndromeIP2][1] = 12 + ip2;
m_corr[syndromeIP2][0] = 8 + ip1;
m_corr[syndromeIP2][1] = 8 + ip2;

for (int ip3 = ip2+1; ip3 < 12; ip3++) // 1 more bit flip in parity
{
int syndromeIP3 = syndromeIP2 ^ (1 << (11-ip3));
m_corr[syndromeIP3][0] = 12 + ip1;
m_corr[syndromeIP3][1] = 12 + ip2;
m_corr[syndromeIP3][2] = 12 + ip3;
m_corr[syndromeIP3][0] = 8 + ip1;
m_corr[syndromeIP3][1] = 8 + ip2;
m_corr[syndromeIP3][2] = 8 + ip3;
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions testfec/Makefile
Expand Up @@ -28,7 +28,7 @@ hamming16: fec.o hamming16.cpp
g++ -o hamming16 fec.o hamming16.cpp

golay20: fec.o golay20.cpp
g++ -o golay20 fec.o golay20.cpp
g++ $(CXXLFAGS) -o golay20 fec.o golay20.cpp

golay23: fec.o golay23.cpp
g++ -o golay23 fec.o golay23.cpp
Expand Down Expand Up @@ -65,4 +65,3 @@ descramble.o: ../descramble.h ../descramble.cpp

clean:
rm -f *.o qr golay20 golay23 golay24 hamming7 hamming12 hamming15 hamming16 viterbi viterbi35 crc

83 changes: 83 additions & 0 deletions testfec/golay20.cpp
Expand Up @@ -41,6 +41,87 @@ void decode(DSDcc::Golay_20_8& Golay_20_8, unsigned char *codeword)
}
}

void rand_test()
{
unsigned char msg[8];
unsigned char codeword[20], xcodeword[20];
int idx1, idx2, idx3;
int dataIn, dataOut;
int passCount = 0, failCount = 0, parityFailCount = 0;
DSDcc::Golay_20_8 golay_20_8;

// Run multiple times, to randomly corrupt different bits
// Takes about 10 seconds on a fast PC
for (int repeat = 0; repeat < 100000; repeat++)
{
// Exhaustively test all 8-bit inputs
for (int dataIn = 0; dataIn < 256; dataIn++)
{
// Convert to array of bits
for (int j = 0; j < 8; j++) {
msg[j] = (dataIn >> j) & 1;
}

// Encode
golay_20_8.encode(msg, codeword);

// Save copy of uncorrupted codeword
std::copy(codeword, codeword + 20, xcodeword);

// Randomly corrupt up to 3 bits
idx1 = rand() % 20;
idx2 = rand() % 20;
idx3 = rand() % 20;
codeword[idx1] ^= codeword[idx1];
codeword[idx2] ^= codeword[idx2];
codeword[idx3] ^= codeword[idx3];

bool fail = false;
// Decode and correct errors
dataOut = 0;
if (golay_20_8.decode(codeword))
{
// Check data is corrected
for (int j = 0; j < 8; j++) {
dataOut |= codeword[j] << j;
}
if (dataIn != dataOut) {
fail = true;
}

// Check also that parity has been corrected, as we previously had a bug with this
if (memcmp(codeword, xcodeword, 20)) {
parityFailCount++;
}
}
else
{
fail = true;
}
if (fail)
{
std::cout << "Decode failed:"
<< " dataIn=" << dataIn
<< " dataOut=" << dataOut
<< " idx1=" << idx1
<< " idx2=" << idx2
<< " idx3=" << idx3
<< "\n";
failCount++;
}
else
{
passCount++;
}
}
}

std::cout << "rand_test:"
<< " Passcount=" << passCount
<< " Failcount=" << failCount
<< " parityFailCount=" << parityFailCount << "\n";
}

int main(int argc, char *argv[])
{
unsigned char msg[8] = {1, 0, 0, 1, 0, 1, 0, 0};
Expand Down Expand Up @@ -106,6 +187,8 @@ int main(int argc, char *argv[])
xcodeword[19] ^= 1;
decode(golay_20_8, xcodeword);

rand_test();

return 0;
}

Expand Down

0 comments on commit 75c5b94

Please sign in to comment.