mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-15 02:07:24 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbe7fcab0e | ||
|
|
138a48ad31 | ||
|
|
cd6ce80124 | ||
|
|
edf97e26b8 |
185
src/bptc.c
185
src/bptc.c
@@ -213,8 +213,8 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== Pass 1: row Hamming(15,11) on rows 0..8 ========== */
|
/* ========== Pass 1: row Hamming(15,11) on rows 0..12 ========== */
|
||||||
for (i = 0; i < 9; i++)
|
for (i = 0; i < 13; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 15; j++)
|
for (j = 0; j < 15; j++)
|
||||||
{
|
{
|
||||||
@@ -232,8 +232,8 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
fprintf(stderr, "%u", LineBefore[j] & 1);
|
fprintf(stderr, "%u", LineBefore[j] & 1);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
/* Keep original data bits on failure */
|
/* Keep original bits on failure */
|
||||||
for (j = 0; j < 11; j++)
|
for (j = 0; j < 15; j++)
|
||||||
DataMatrix[i][j] = LineBefore[j];
|
DataMatrix[i][j] = LineBefore[j];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -253,8 +253,9 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; j < 11; j++)
|
/* Re-inject the full line (including corrected parity bits) in the matrix */
|
||||||
DataMatrix[i][j] = LineCorrected[j];
|
for (j = 0; j < 15; j++)
|
||||||
|
DataMatrix[i][j] = LineUncorrected[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if BPTC_196x96_DEBUG
|
#if BPTC_196x96_DEBUG
|
||||||
@@ -282,7 +283,7 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
fprintf(stderr, "%u", ColumnBefore[j] & 1);
|
fprintf(stderr, "%u", ColumnBefore[j] & 1);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
for (j = 0; j < 9; j++)
|
for (j = 0; j < 13; j++)
|
||||||
DataMatrix[j][i] = ColumnBefore[j];
|
DataMatrix[j][i] = ColumnBefore[j];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -301,8 +302,9 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; j < 9; j++)
|
/* Re-inject the full column (including corrected parity bits) in the matrix */
|
||||||
DataMatrix[j][i] = ColumnCorrected[j];
|
for (j = 0; j < 13; j++)
|
||||||
|
DataMatrix[j][i] = ColumnUncorrected[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if BPTC_196x96_DEBUG
|
#if BPTC_196x96_DEBUG
|
||||||
@@ -315,7 +317,7 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
HammingIrrecoverableErrorNb = 0;
|
HammingIrrecoverableErrorNb = 0;
|
||||||
|
|
||||||
/* ========== Pass 2: rows ========== */
|
/* ========== Pass 2: rows ========== */
|
||||||
for (i = 0; i < 9; i++)
|
for (i = 0; i < 13; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 15; j++)
|
for (j = 0; j < 15; j++)
|
||||||
{
|
{
|
||||||
@@ -333,7 +335,7 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
fprintf(stderr, "%u", LineBefore[j] & 1);
|
fprintf(stderr, "%u", LineBefore[j] & 1);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
for (j = 0; j < 11; j++)
|
for (j = 0; j < 15; j++)
|
||||||
DataMatrix[i][j] = LineBefore[j];
|
DataMatrix[i][j] = LineBefore[j];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -352,8 +354,9 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; j < 11; j++)
|
/* Re-inject the full line (including corrected parity bits) in the matrix */
|
||||||
DataMatrix[i][j] = LineCorrected[j];
|
for (j = 0; j < 15; j++)
|
||||||
|
DataMatrix[i][j] = LineUncorrected[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if BPTC_196x96_DEBUG
|
#if BPTC_196x96_DEBUG
|
||||||
@@ -381,7 +384,7 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
fprintf(stderr, "%u", ColumnBefore[j] & 1);
|
fprintf(stderr, "%u", ColumnBefore[j] & 1);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
for (j = 0; j < 9; j++)
|
for (j = 0; j < 13; j++)
|
||||||
DataMatrix[j][i] = ColumnBefore[j];
|
DataMatrix[j][i] = ColumnBefore[j];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -400,8 +403,58 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; j < 9; j++)
|
/* Re-inject the full column (including corrected parity bits) in the matrix */
|
||||||
DataMatrix[j][i] = ColumnCorrected[j];
|
for (j = 0; j < 13; j++)
|
||||||
|
DataMatrix[j][i] = ColumnUncorrected[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify that all rows (0..12) and columns (0..14) have converged to zero syndrome.
|
||||||
|
* Hamming_15_11_decode never returns false because all 15 non-zero 4-bit syndromes
|
||||||
|
* map to a bit flip, so without a post-pass consistency check a noisy burst can
|
||||||
|
* mis-correct data bits in Pass 2 Columns while still reporting 0 errors. */
|
||||||
|
for (i = 0; i < 13; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 15; j++)
|
||||||
|
{
|
||||||
|
LineUncorrected[j] = DataMatrix[i][j];
|
||||||
|
}
|
||||||
|
if (Hamming_15_11_decode(LineUncorrected, LineCorrected, 1) == false)
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (j = 0; j < 15; j++)
|
||||||
|
{
|
||||||
|
if (LineUncorrected[j] != DataMatrix[i][j])
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 13; j++)
|
||||||
|
{
|
||||||
|
ColumnUncorrected[j] = DataMatrix[j][i];
|
||||||
|
}
|
||||||
|
if (Hamming_13_9_decode(ColumnUncorrected, ColumnCorrected, 1) == false)
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (j = 0; j < 13; j++)
|
||||||
|
{
|
||||||
|
if (ColumnUncorrected[j] != DataMatrix[j][i])
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if BPTC_196x96_DEBUG
|
#if BPTC_196x96_DEBUG
|
||||||
@@ -430,12 +483,33 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196],
|
|||||||
DMRDataExtracted[k++] = DataMatrix[i][j];
|
DMRDataExtracted[k++] = DataMatrix[i][j];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t total_corr = row_corr_p1 + col_corr_p1 + row_corr_p2 + col_corr_p2;
|
||||||
|
uint32_t p2_corr = row_corr_p2 + col_corr_p2;
|
||||||
|
|
||||||
|
/* In DMR BPTC(196,96), R(0) and R(1) must be 0. Also reject R(2)==1 when the
|
||||||
|
* received R(2) bit was 0 or the matrix required heavy multi-pass corrections,
|
||||||
|
* because is_ras==1 bypasses downstream CRC checks when no RAS key is loaded. */
|
||||||
|
if (DataMatrix[0][2] != 0 || DataMatrix[0][1] != 0)
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
}
|
||||||
|
else if (DataMatrix[0][0] == 1 && ((InputDeInteleavedData[1] & 1) == 0 || total_corr > 8 || p2_corr > 2))
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
}
|
||||||
|
|
||||||
if (HammingIrrecoverableErrorNb == 0)
|
if (HammingIrrecoverableErrorNb == 0)
|
||||||
{
|
{
|
||||||
R[0] = DataMatrix[0][2]; /* R(0) */
|
R[0] = DataMatrix[0][2]; /* R(0) */
|
||||||
R[1] = DataMatrix[0][1]; /* R(1) */
|
R[1] = DataMatrix[0][1]; /* R(1) */
|
||||||
R[2] = DataMatrix[0][0]; /* R(2) */
|
R[2] = DataMatrix[0][0]; /* R(2) */
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R[0] = 0;
|
||||||
|
R[1] = 0;
|
||||||
|
R[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (R[0] == 0 && R[1] == 0 && R[2] == 1)
|
if (R[0] == 0 && R[1] == 0 && R[2] == 1)
|
||||||
*is_ras = 1;
|
*is_ras = 1;
|
||||||
@@ -466,7 +540,7 @@ uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDat
|
|||||||
uint32_t ParityCheckErrorNb = 0;
|
uint32_t ParityCheckErrorNb = 0;
|
||||||
uint32_t NbOfOne;
|
uint32_t NbOfOne;
|
||||||
|
|
||||||
uint8_t row_bad[7];
|
uint8_t row_bad[8];
|
||||||
uint8_t col_bad[16];
|
uint8_t col_bad[16];
|
||||||
|
|
||||||
#if BPTC_128x77_DEBUG
|
#if BPTC_128x77_DEBUG
|
||||||
@@ -479,9 +553,9 @@ uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDat
|
|||||||
DataMatrix[i][j] = (InputDataMatrix[i][j] & 1);
|
DataMatrix[i][j] = (InputDataMatrix[i][j] & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Pass 1: Hamming (16,11,4) on rows 0..6 ---------- */
|
/* ---------- Pass 1: Hamming (16,11,4) on rows 0..7 ---------- */
|
||||||
memset(row_bad, 0, sizeof(row_bad));
|
memset(row_bad, 0, sizeof(row_bad));
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
LineUncorrected[j] = DataMatrix[i][j];
|
LineUncorrected[j] = DataMatrix[i][j];
|
||||||
@@ -496,13 +570,11 @@ uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDat
|
|||||||
fprintf(stderr, "%u", LineUncorrected[j] & 1);
|
fprintf(stderr, "%u", LineUncorrected[j] & 1);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
for (j = 0; j < 11; j++)
|
|
||||||
DataMatrix[i][j] = LineUncorrected[j];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (j = 0; j < 11; j++)
|
for (j = 0; j < 16; j++)
|
||||||
DataMatrix[i][j] = LineCorrected[j];
|
DataMatrix[i][j] = LineUncorrected[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if BPTC_128x77_DEBUG
|
#if BPTC_128x77_DEBUG
|
||||||
@@ -537,12 +609,14 @@ uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDat
|
|||||||
(unsigned)ParityCheckErrorNb);
|
(unsigned)ParityCheckErrorNb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------- Parity-guided single-bit repair ---------- */
|
/* ---------- Parity-guided bit repair ---------- */
|
||||||
{
|
{
|
||||||
uint32_t n_bad_rows = 0, n_bad_cols = 0;
|
uint32_t n_bad_rows = 0, n_bad_cols = 0;
|
||||||
uint32_t br = 0, bc = 0;
|
uint32_t br = 0, bc = 0;
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
UNUSED(bc);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
if (row_bad[i]) { n_bad_rows++; br = i; }
|
if (row_bad[i]) { n_bad_rows++; br = i; }
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
if (col_bad[i]) { n_bad_cols++; bc = i; }
|
if (col_bad[i]) { n_bad_cols++; bc = i; }
|
||||||
@@ -558,29 +632,35 @@ uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDat
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (n_bad_rows == 1 && n_bad_cols == 1 && bc < 11)
|
if (n_bad_rows == 1 && (n_bad_cols == 1 || n_bad_cols == 2))
|
||||||
{
|
{
|
||||||
DataMatrix[br][bc] ^= 1;
|
for (i = 0; i < 16; i++)
|
||||||
row_bad[br] = 0;
|
{
|
||||||
|
if (col_bad[i])
|
||||||
|
{
|
||||||
|
DataMatrix[br][i] ^= 1;
|
||||||
#if BPTC_128x77_DEBUG
|
#if BPTC_128x77_DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" BPTC128 parity-guided FLIP at row=%u col=%u -> %u\n",
|
" BPTC128 parity-guided FLIP at row=%u col=%u -> %u\n",
|
||||||
(unsigned)br, (unsigned)bc, (unsigned)DataMatrix[br][bc]);
|
(unsigned)br, (unsigned)i, (unsigned)DataMatrix[br][i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
row_bad[br] = 0;
|
||||||
|
}
|
||||||
#if BPTC_128x77_DEBUG
|
#if BPTC_128x77_DEBUG
|
||||||
else if (n_bad_rows || n_bad_cols)
|
else if (n_bad_rows || n_bad_cols)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" BPTC128 no single-intersection flip "
|
" BPTC128 no repair flip "
|
||||||
"(need exactly 1 bad row and 1 data col)\n");
|
"(need 1 bad row and 1 or 2 bad cols)\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Pass 2: Hamming (16,11,4) again ---------- */
|
/* ---------- Pass 2: Hamming (16,11,4) again ---------- */
|
||||||
HammingIrrecoverableErrorNb = 0;
|
HammingIrrecoverableErrorNb = 0;
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
LineUncorrected[j] = DataMatrix[i][j];
|
LineUncorrected[j] = DataMatrix[i][j];
|
||||||
@@ -594,13 +674,11 @@ uint32_t BPTC_128x77_Extract_Data(uint8_t InputDataMatrix[8][16], uint8_t DMRDat
|
|||||||
fprintf(stderr, "%u", LineUncorrected[j] & 1);
|
fprintf(stderr, "%u", LineUncorrected[j] & 1);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
for (j = 0; j < 11; j++)
|
|
||||||
DataMatrix[i][j] = LineUncorrected[j];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (j = 0; j < 11; j++)
|
for (j = 0; j < 16; j++)
|
||||||
DataMatrix[i][j] = LineCorrected[j];
|
DataMatrix[i][j] = LineUncorrected[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if BPTC_128x77_DEBUG
|
#if BPTC_128x77_DEBUG
|
||||||
@@ -696,22 +774,45 @@ uint32_t BPTC_16x2_Extract_Data(uint8_t InputInterleavedData[32], uint8_t DMRDat
|
|||||||
DMRDataExtracted[i] = DataMatrix[i] & 1;
|
DMRDataExtracted[i] = DataMatrix[i] & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare the line to be corrected */
|
/* Prepare the first row (bits 0..15) to be corrected */
|
||||||
for(i = 0; i < 16; i++)
|
for(i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
LineUncorrected[i] = DataMatrix[i] & 1;
|
LineUncorrected[i] = DataMatrix[i] & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply Hamming (16,11,4) code correction */
|
/* Apply Hamming (16,11,4) code correction to row 0 */
|
||||||
if(Hamming_16_11_4_decode(LineUncorrected, LineCorrected, 1) == false)
|
if(Hamming_16_11_4_decode(LineUncorrected, LineCorrected, 1) == false)
|
||||||
{
|
{
|
||||||
HammingIrrecoverableErrorNb++;
|
HammingIrrecoverableErrorNb++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Copy the corrected content to the output buffer */
|
|
||||||
for(i = 0; i < 11; i++)
|
|
||||||
{
|
{
|
||||||
DMRDataExtracted[i] = LineCorrected[i] & 1;
|
/* Copy all 16 corrected bits (including parity bits 11..15) */
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
DMRDataExtracted[i] = LineUncorrected[i] & 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the second row (bits 16..31) to be corrected;
|
||||||
|
* 1^16 is a codeword of Hamming(16,11,4), so both even and odd parity rows are valid codewords */
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
LineUncorrected[i] = DataMatrix[i + 16] & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply Hamming (16,11,4) code correction to row 1 */
|
||||||
|
if(Hamming_16_11_4_decode(LineUncorrected, LineCorrected, 1) == false)
|
||||||
|
{
|
||||||
|
HammingIrrecoverableErrorNb++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Copy all 16 corrected bits (including parity bits 11..15) */
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
DMRDataExtracted[i + 16] = LineUncorrected[i] & 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Parity bits */
|
/* Check Parity bits */
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||||||
uint8_t bptc_res_bits[3];
|
uint8_t bptc_res_bits[3];
|
||||||
memset (bptc_res_bits, 0, sizeof(bptc_res_bits));
|
memset (bptc_res_bits, 0, sizeof(bptc_res_bits));
|
||||||
uint8_t crc_original_validity = 0;
|
uint8_t crc_original_validity = 0;
|
||||||
|
static uint8_t ras_confirm_count = 0;
|
||||||
|
static uint8_t prev_dmr_is_ras = 0;
|
||||||
|
if (prev_dmr_is_ras == 1 && state->dmr_is_ras == 0)
|
||||||
|
ras_confirm_count = 0;
|
||||||
|
|
||||||
uint32_t crcmask = 0;
|
uint32_t crcmask = 0;
|
||||||
uint8_t crclen = 0;
|
uint8_t crclen = 0;
|
||||||
@@ -304,6 +308,18 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||||||
if (is_lc)
|
if (is_lc)
|
||||||
{
|
{
|
||||||
if (is_ras)
|
if (is_ras)
|
||||||
|
{
|
||||||
|
uint8_t tmp_bytes[12];
|
||||||
|
uint32_t std_crc = 0;
|
||||||
|
memcpy (tmp_bytes, BPTCDmrDataByte, sizeof(tmp_bytes));
|
||||||
|
if (ComputeAndCorrectFullLinkControlCrc(tmp_bytes, &std_crc, crcmask) && std_crc == CRCExtracted)
|
||||||
|
{
|
||||||
|
memcpy (BPTCDmrDataByte, tmp_bytes, sizeof(tmp_bytes));
|
||||||
|
is_ras = 0;
|
||||||
|
CRCComputed = std_crc;
|
||||||
|
CRCCorrect = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
CRCComputed = ras_mac_calculator(state, BPTCDmrDataByte, 9, 1);
|
CRCComputed = ras_mac_calculator(state, BPTCDmrDataByte, 9, 1);
|
||||||
if (CRCComputed == CRCExtracted)
|
if (CRCComputed == CRCExtracted)
|
||||||
@@ -313,6 +329,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||||||
fprintf (stderr, " EXT: %06X; MAC: %06X;", CRCExtracted, CRCComputed);
|
fprintf (stderr, " EXT: %06X; MAC: %06X;", CRCExtracted, CRCComputed);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else CRCCorrect = ComputeAndCorrectFullLinkControlCrc(BPTCDmrDataByte, &CRCComputed, crcmask);
|
else CRCCorrect = ComputeAndCorrectFullLinkControlCrc(BPTCDmrDataByte, &CRCComputed, crcmask);
|
||||||
|
|
||||||
//Hytera OTA Encryption LC Context Creation for VLC Header
|
//Hytera OTA Encryption LC Context Creation for VLC Header
|
||||||
@@ -354,18 +371,28 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||||||
//run CCITT on other data forms
|
//run CCITT on other data forms
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (is_ras == 1)
|
uint32_t std_crc = ComputeCrcCCITT(BPTCDmrDataBit);
|
||||||
|
if (std_crc == CRCExtracted)
|
||||||
|
{
|
||||||
|
is_ras = 0;
|
||||||
|
CRCComputed = std_crc;
|
||||||
|
CRCCorrect = 1;
|
||||||
|
}
|
||||||
|
else if (is_ras == 1)
|
||||||
{
|
{
|
||||||
CRCComputed = ras_mac_calculator(state, BPTCDmrDataByte, 10, 0);
|
CRCComputed = ras_mac_calculator(state, BPTCDmrDataByte, 10, 0);
|
||||||
|
if (CRCComputed == CRCExtracted) CRCCorrect = 1;
|
||||||
|
else CRCCorrect = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_RAS
|
#ifdef DEBUG_RAS
|
||||||
fprintf (stderr, " EXT: %04X; MAC: %04X;", CRCExtracted, CRCComputed);
|
fprintf (stderr, " EXT: %04X; MAC: %04X;", CRCExtracted, CRCComputed);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else CRCComputed = ComputeCrcCCITT(BPTCDmrDataBit);
|
else
|
||||||
|
{
|
||||||
if (CRCComputed == CRCExtracted) CRCCorrect = 1;
|
CRCComputed = std_crc;
|
||||||
else CRCCorrect = 0;
|
CRCCorrect = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if this is a RAS system, set the CRC to okay if irrecoverable errors are okay
|
//if this is a RAS system, set the CRC to okay if irrecoverable errors are okay
|
||||||
@@ -473,9 +500,11 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||||||
/* Compute the 5 bit CRC */
|
/* Compute the 5 bit CRC */
|
||||||
CRCComputed = ComputeCrc5Bit(LC_DataBit);
|
CRCComputed = ComputeCrc5Bit(LC_DataBit);
|
||||||
|
|
||||||
//read ahead first two bytes, look for 1X10 or 2X10 pattern
|
//read ahead first two bytes, look for 1X10 or 2X10 pattern (with PF/R bits 0)
|
||||||
uint16_t ras_test = (uint16_t)(ConvertBitIntoBytes(&LC_DataBit[0], 16) & 0x30FF);
|
uint16_t ras_test = (uint16_t)(ConvertBitIntoBytes(&LC_DataBit[0], 16) & 0x30FF);
|
||||||
if ((IrrecoverableErrors == 0) && (ras_test == 0x2010 || ras_test == 0x1010))
|
if ((IrrecoverableErrors == 0) &&
|
||||||
|
(LC_DataBit[0] == 0) && (LC_DataBit[1] == 0) &&
|
||||||
|
(ras_test == 0x2010 || ras_test == 0x1010))
|
||||||
{
|
{
|
||||||
is_ras = 1;
|
is_ras = 1;
|
||||||
if (state->ras_effective_key != 0)
|
if (state->ras_effective_key != 0)
|
||||||
@@ -702,9 +731,28 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
//might flicker the terminal on partially enabled systems, may need to find a better placement
|
//require a key-verified RAS burst or 2 RAS bursts to latch [RAS]; clear on valid non-PI non-RAS BPTC burst
|
||||||
if (IrrecoverableErrors == 0 && (is_bptc || is_emb) && databurst != 0x05 && databurst != 0x07 && databurst != 0x09)
|
if (IrrecoverableErrors == 0 && is_ras == 1 && (is_bptc || is_emb) && databurst != 0x05 && databurst != 0x07 && databurst != 0x09)
|
||||||
state->dmr_is_ras = is_ras;
|
{
|
||||||
|
if (state->ras_effective_key != 0 && CRCCorrect == 1)
|
||||||
|
{
|
||||||
|
ras_confirm_count = 2;
|
||||||
|
state->dmr_is_ras = 1;
|
||||||
|
}
|
||||||
|
else if ((is_bptc || is_emb) && databurst != 0x00)
|
||||||
|
{
|
||||||
|
if (ras_confirm_count < 2)
|
||||||
|
ras_confirm_count++;
|
||||||
|
if (ras_confirm_count >= 2)
|
||||||
|
state->dmr_is_ras = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IrrecoverableErrors == 0 && is_ras == 0 && is_bptc && CRCCorrect == 1 && databurst != 0x00 && databurst != 0x05 && databurst != 0x07 && databurst != 0x09)
|
||||||
|
{
|
||||||
|
ras_confirm_count = 0;
|
||||||
|
state->dmr_is_ras = 0;
|
||||||
|
}
|
||||||
|
prev_dmr_is_ras = state->dmr_is_ras;
|
||||||
|
|
||||||
if (IrrecoverableErrors == 0 && CRCCorrect == 0 && is_ras == 0 && databurst != 0x09 && databurst != 0x05)
|
if (IrrecoverableErrors == 0 && CRCCorrect == 0 && is_ras == 0 && databurst != 0x09 && databurst != 0x05)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user