From e79b6fd2312032a2cb8102da41000b363c8eacbc Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Thu, 10 Aug 2023 03:47:08 -0400 Subject: [PATCH] Simplify DMR Trellis Decoder; --- include/dsd.h | 12 +- src/dmr_34.c | 109 ++++++++++ src/dmr_dburst.c | 24 +-- src/trellis.cpp | 538 ----------------------------------------------- 4 files changed, 122 insertions(+), 561 deletions(-) create mode 100644 src/dmr_34.c delete mode 100644 src/trellis.cpp diff --git a/include/dsd.h b/include/dsd.h index 472453c..3205a4b 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -1042,6 +1042,8 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8_t cs_pdu[], uint32_t CRCCorrect, uint32_t IrrecoverableErrors); void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]); uint8_t dmr_cach (dsd_opts * opts, dsd_state * state, uint8_t cach_bits[25]); +uint32_t dmr_34(uint8_t * input, uint8_t treturn[18]); //simplier trellis decoder +void beeper (dsd_opts * opts, dsd_state * state, int type); //the tone beeper function //Embedded Alias and GPS void dmr_embedded_alias_header (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]); @@ -1187,15 +1189,7 @@ void rtl_dev_tune(dsd_opts * opts, long int frequency); long int rtl_return_rms(); void rtl_clean_queue(); #endif -//DMR TRELLIS -void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload); -unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits); -bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned char* payload); -void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits); -void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points); -void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits); -void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribits); -bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload); + //Phase 2 Helper Functions int ez_rs28_ess (int payload[96], int parity[168]); //ezpwd bridge for FME diff --git a/src/dmr_34.c b/src/dmr_34.c new file mode 100644 index 0000000..b97117a --- /dev/null +++ b/src/dmr_34.c @@ -0,0 +1,109 @@ +/*------------------------------------------------------------------------------- + * dmr_34.c + * DMR 3/4 Rate Simple Trellis Decoder + * + * LWVMOBILE + * 2023-08 DSD-FME Florida Man Edition + *-----------------------------------------------------------------------------*/ + +#include "dsd.h" + +uint8_t interleave[98] = { + 0, 1, 8, 9, 16, 17, 24, 25, 32, 33, 40, 41, 48, 49, 56, 57, 64, 65, 72, 73, 80, 81, 88, 89, 96, 97, + 2, 3, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 50, 51, 58, 59, 66, 67, 74, 75, 82, 83, 90, 91, + 4, 5, 12, 13, 20, 21, 28, 29, 36, 37, 44, 45, 52, 53, 60, 61, 68, 69, 76, 77, 84, 85, 92, 93, + 6, 7, 14, 15, 22, 23, 30, 31, 38, 39, 46, 47, 54, 55, 62, 63, 70, 71, 78, 79, 86, 87, 94, 95}; + +//this is a convertion table for converting the dibit pairs into contellation points +uint8_t constellation_map[16] = { +11, 12, 0, 7, 14, 9, 5, 2, 10, 13, 1, 6, 15, 8, 4, 3 +}; + +//digitized dibit to OTA symbol conversion for reference +//0 = +1; 1 = +3; +//2 = -1; 3 = -3; + +//finite state machine values +uint8_t fsm[64] = { + 0, 8, 4, 12, 2, 10, 6, 14, + 4, 12, 2, 10, 6, 14, 0, 8, + 1, 9, 5, 13, 3, 11, 7, 15, + 5, 13, 3, 11, 7, 15, 1, 9, + 3, 11, 7, 15, 1, 9, 5, 13, + 7, 15, 1, 9, 5, 13, 3, 11, + 2, 10, 6, 14, 0, 8, 4, 12, + 6, 14, 0, 8, 4, 12, 2, 10}; + +uint32_t dmr_34(uint8_t * input, uint8_t treturn[18]) +{ + int i, j; + uint32_t irr_err = 0; + + uint8_t deinterleaved_dibits[98]; + memset (deinterleaved_dibits, 0, sizeof(deinterleaved_dibits)); + + //deinterleave our input dibits + for (i = 0; i < 98; i++) + deinterleaved_dibits[interleave[i]] = input[i]; + + //pack the input into nibbles (dibit pairs) + uint8_t nibs[49]; + memset (nibs, 0, sizeof(nibs)); + + for (i = 0; i < 49; i++) + nibs[i] = (deinterleaved_dibits[i*2+0] << 2) | (deinterleaved_dibits[i*2+1] << 0); + + //convert our dibit pairs into constellation point values + uint8_t point[49]; + memset (point, 0xFF, sizeof(point)); + + for (i = 0; i < 49; i++) + point[i] = constellation_map[nibs[i]]; + + //convert constellation points into tribit values using the FSM + uint8_t state = 0; + uint32_t tribits[49]; + memset (tribits, 0xF, sizeof(tribits)); + + for (i = 0; i < 49; i++) + { + + for (j = 0; j < 8; j++) + { + if ( fsm[(state*8)+j] == point[i] ) + { + //return our tribit value and state for the next point + tribits[i] = state = (uint8_t)j; + break; + } + } + + //if tribit value is greater than 7, then we have a decoding error + if (tribits[i] > 7) + { + irr_err++; //tally number of errors + state = 0; //just using this for now, ideally we want to try to correct errors + } + + //TODO: Implement some form/attempt to correct errors here + + } + + //if there are no errors, then convert tribits into a return payload + uint32_t temp = 0; + if (irr_err == 0) + { + //break into chunks of 24 bit values and shuffle into 8-bit (byte) treturn values + for (i = 0; i < 6; i++) + { + temp = (tribits[(i*8)+0] << 21) + (tribits[(i*8)+1] << 18) + (tribits[(i*8)+2] << 15) + (tribits[(i*8)+3] << 12) + (tribits[(i*8)+4] << 9) + (tribits[(i*8)+5] << 6) + (tribits[(i*8)+6] << 3) + (tribits[(i*8)+7] << 0); + + treturn[(i*3)+0] = (temp >> 16) & 0xFF; + treturn[(i*3)+1] = (temp >> 8) & 0xFF; + treturn[(i*3)+2] = (temp >> 0) & 0xFF; + } + } + + return (irr_err); +} + diff --git a/src/dmr_dburst.c b/src/dmr_dburst.c index 6248289..76116ce 100644 --- a/src/dmr_dburst.c +++ b/src/dmr_dburst.c @@ -418,34 +418,30 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 } - //the ugly one + //the sexy one if (is_trellis) { CRCExtracted = 0; CRCComputed = 0; IrrecoverableErrors = 1; - bool trellis_good = TRUE; uint8_t tdibits[98]; memset (tdibits, 0, sizeof(tdibits)); //reconstitute info bits into reverse ordered dibits for the trellis decoder for (i = 0; i < 98; i++) - { - tdibits[97-i] = (info[i*2] << 1) | info[i*2+1]; - } + tdibits[i] = (info[i*2] << 1) | info[i*2+1]; - unsigned char TrellisReturn[18]; + uint8_t TrellisReturn[18]; memset (TrellisReturn, 0, sizeof(TrellisReturn)); + IrrecoverableErrors = dmr_34(tdibits, TrellisReturn); - trellis_good = CDMRTrellisDecode(tdibits, TrellisReturn); - if (trellis_good == TRUE) IrrecoverableErrors = 0; - // else (fprintf (stderr, " Trellis Failure")); //debug print + //debug -- its a lot easier to hear the number of errors, than to eyeball it + // if (IrrecoverableErrors) beeper (opts, state, slot); for (i = 0; i < pdu_len; i++) //18 - { - DMR_PDU[i] = (uint8_t)TrellisReturn[i+pdu_start]; - } + DMR_PDU[i] = TrellisReturn[i+pdu_start]; + for(i = 0, j = 0; i < 18; i++, j+=8) { @@ -483,7 +479,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 } else { - // IrrecoverableErrors = 9; //set as a shim since the trellis decoder is a pain to fix + state->data_block_crc_valid[slot][blockcounter] = 0; } @@ -505,7 +501,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 } - if (is_full) //Rate 1 Data + if (is_full) //Rate 1 Data -- todo: fix padding bits, the four padding bits are on bit 96,97,98,99 { CRCExtracted = 0; CRCComputed = 0; diff --git a/src/trellis.cpp b/src/trellis.cpp deleted file mode 100644 index ec1e855..0000000 --- a/src/trellis.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (C) 2016 by Jonathan Naylor, G4KLX - * - * Heavy Modificatins of Original Code to work for DSD-FME - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include "dsd.h" - -#include -#include - -const unsigned int INTERLEAVE_TABLE[] = { - 0U, 1U, 8U, 9U, 16U, 17U, 24U, 25U, 32U, 33U, 40U, 41U, 48U, 49U, 56U, 57U, 64U, 65U, 72U, 73U, 80U, 81U, 88U, 89U, 96U, 97U, - 2U, 3U, 10U, 11U, 18U, 19U, 26U, 27U, 34U, 35U, 42U, 43U, 50U, 51U, 58U, 59U, 66U, 67U, 74U, 75U, 82U, 83U, 90U, 91U, - 4U, 5U, 12U, 13U, 20U, 21U, 28U, 29U, 36U, 37U, 44U, 45U, 52U, 53U, 60U, 61U, 68U, 69U, 76U, 77U, 84U, 85U, 92U, 93U, - 6U, 7U, 14U, 15U, 22U, 23U, 30U, 31U, 38U, 39U, 46U, 47U, 54U, 55U, 62U, 63U, 70U, 71U, 78U, 79U, 86U, 87U, 94U, 95U}; - -const unsigned char ENCODE_TABLE[] = { - 0U, 8U, 4U, 12U, 2U, 10U, 6U, 14U, - 4U, 12U, 2U, 10U, 6U, 14U, 0U, 8U, - 1U, 9U, 5U, 13U, 3U, 11U, 7U, 15U, - 5U, 13U, 3U, 11U, 7U, 15U, 1U, 9U, - 3U, 11U, 7U, 15U, 1U, 9U, 5U, 13U, - 7U, 15U, 1U, 9U, 5U, 13U, 3U, 11U, - 2U, 10U, 6U, 14U, 0U, 8U, 4U, 12U, - 6U, 14U, 0U, 8U, 4U, 12U, 2U, 10U}; - -const unsigned char DECODE_TABLE[] = { //flip the rows and columns, right? - 0,4,1,5,3,7,2,6, - 8,12,9,13,11,15,10,14, - 4,2,5,3,7,1,6,0, - 12,10,13,11,15,9,14,8, - 2,6,3,7,1,5,0,4, - 10,14,11,15,9,13,8,12, - 6,0,7,1,5,3,4,2, - 14,8,15,9,13,11,12,10 -}; - -const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; - -#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) -#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) - -unsigned char state = 0U; -//rework quickHamming to accept unsigned intergers instead and go bit by bit -int quickHamming(unsigned int butt, unsigned int farts) -{ - unsigned int i = 0, count = 0, shit = 0, shart = 0; - //fprintf (stderr, "Distance Compare %X - %X \n", butt, farts ); - for (i; i < 3; i++) //shift three places tops; - { - shit = (butt >> i) & 0b1; - shart = (farts >> i) & 0b1; - if (shit != shart) - { - count++; - } - } - - return count; -} - -bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned char* payload) -{ - //unsigned int bestPos = 0U; - //unsigned int bestVal = 0U; - - for (unsigned j = 0U; j < 20U; j++) { - unsigned int bestPos = 0U; - unsigned int bestVal = 0U; - //fprintf (stderr, " fail%d-", failPos); - - for (unsigned int i = 0U; i < 16U; i++) { - points[failPos] = i; - - //fprintf (stderr, "i%d", i); - - unsigned char tribits[49U]; - unsigned int pos = CDMRTrellisCheckCode(points, tribits); - if (pos == 999U) { - CDMRTrellisTribitsToBits(tribits, payload); - return true; - } - - if (pos > bestPos) { - bestPos = pos; - bestVal = i; - } - } - - points[failPos] = bestVal; - failPos = bestPos; - } - - return false; -} - -void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload) -{ - - - unsigned char bits[144]; - for (int i = 0; i < 48; i++) { - bits[(i * 3) + 0] = (tribits[i] >> 2) & 1; - bits[(i * 3) + 1] = (tribits[i] >> 1) & 1; - bits[(i * 3) + 2] = tribits[i] & 1; - } - - - // convert bits to bytes - //fprintf (stderr, "\n Tribit Binary Sequence\n "); - for (short i = 0; i < 144; i++) - { - //fprintf (stderr, "%b", bits[i]); - } - for(short int i = 0; i < 18; i++) - { - payload[i] = (bits[i * 8 + 0] << 7) | (bits[i * 8 + 1] << 6) | (bits[i * 8 + 2] << 5) | (bits[i * 8 + 3] << 4) | - (bits[i * 8 + 4] << 3) | (bits[i * 8 + 5] << 2) | (bits[i * 8 + 6] << 1) | (bits[i * 8 + 7] << 0); - } - - //for (int i = 0; i < 144; i++) - //payload[i/8] = (payload[i/8] << 1) | bits[i]; - //DmrDataBit[j + 0] = (TrellisReturn[17-i] >> 0) & 0x01; //example - -} - -unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits) -{ - - //unsigned char state = 0U; //move outside of function to preserve state for every iteration - //let's try reversing the points to pass through the decode table instead of flipping them here, - //it may mess up the fixcode and failpos POS - state = 0U; - for (unsigned int i = 0U; i < 49U;) //total number of points to process - { - tribits[i] = 9U; - for (unsigned int j = 0U; j < 8U; j++) - { - //if (points[i] == DECODE_TABLE[state * 8U + j]) - //if (points[48-i] == DECODE_TABLE[state * 8U + j]) - if (points[i] == ENCODE_TABLE[state * 8U + j]) - { - tribits[i] = j; - state = tribits[i]; //carry over if found right away - i++; //increment i by one value - break; - } - } - //try to find shortest distance for surviving paths and decide on one - //seems to be that two paths will have distance value 1, and two will have distance value 2 - //need to keep totaling up a few rounds before we can eliminate a path and resume? - if (tribits[i] == 9U) - { - int distance = 0; - int maxdistance = 99; //random metric for two position distance - int pathdistance = 0; - unsigned int match = 0; - unsigned int nextmatch = 0; - unsigned int q = 0; - //only 4 possible states for each point, but in 8 (0-7) FSM states - char path[99][99] = {0}; //[i][pathcount] = distance - int pathcount = 0; - for (unsigned int o = 0; o < 64; o++) //check entire state transition table for matches - { - if (points[i] == ENCODE_TABLE[o]) //ENCODE TABLE - { - match = o / (unsigned int)8; //get dividend no remainder/decimal I hope, get fsm state 0-7 - //fprintf (stderr, "\n Point #%d [%d] Match State %d Position %d Tribit Value %d \n", i, points[i], match, o, o % (unsigned int)8); - distance = quickHamming(match, state); - //fprintf (stderr, "Raw Distance Current %d\n", distance); - path[i][pathcount] = distance ; //save which table values (paths) match as possible values and distance - for (q; q < 64; q++) //check entire state transition table for next point match - { - if (points[i+1] == ENCODE_TABLE[q]) //ENCODE TABLE - { - nextmatch = q / (unsigned int)8; - path[i+1][pathcount] = quickHamming(nextmatch, q % (unsigned int)8); - //fprintf (stderr, "Raw Distance Next %d\n", path[i+1][pathcount]); - pathcount++; - //fprintf (stderr, "State 0 Match %d Distance %d \n", o, distance); - } - } - for (short int z = 0; z <= pathcount; z++) //add metrics on paths to find shortest distance - { - pathdistance = path[i][0] + path[i+1][z]; - //fprintf (stderr, "Total Path Distance %d\n", pathdistance); - if (pathdistance <= maxdistance) //equal too in case of tie? - { - maxdistance = pathdistance; - tribits[i] = o % (unsigned int)8; //remainder value will be tribit value on table - if (i < 49) //just in case we are on 49 already, don't want to crash or something. - { - tribits[i+1] = q % (unsigned int)8; //remainder value will be tribit value on table - } - - //fprintf (stderr, "Point #%d [%d] - Tribit Candidate %d\n", i, points[i], tribits[i] ); - //fprintf (stderr, "Point #%d [%d]- Tribit Candidate %d\n", i+1, points[i+1], tribits[i+1] ); - } - } - } - //fprintf (stderr, "Selected Point #%d [%d] - Tribit Selection %d\n", i, points[i], tribits[i] ); - //fprintf (stderr, "Selected Point #%d [%d]- Tribit Selection %d\n", i+1, points[i+1], tribits[i+1] ); - } - state = tribits[i+1]; //not quite sure if this will be needed or not, if so, set state to last found value - i += 2; //increment i by two since we already got the next tribit value as well; - //state = tribits[i]; //not quite sure if this will be needed or not, if so, set state to last found value - //i++; //increment i by two since we already got the next tribit value as well; - } - - } - return 999U; -} - -void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits) -{ - int n; - //can only assume this is giving the correct dibits out, and not inverse or something. - /* - for (int i = 0; i < 98; i++) { - n = i * 2; - if (n >= 98) n += 68; - bool b1 = data[n] != 0x0; - - n = i * 2 + 1; - if (n >= 98) n += 68; - bool b2 = data[n] != 0x0; - - if (!b1 && b2) - dibit = +3; // 1 - 01 - else if (!b1 && !b2) - dibit = +1; // 0 - 00 - else if (b1 && !b2) - dibit = -1; // 2 - 10 - else - dibit = -3; // 3 - 11 - - */ - //Keep it simple! - for (int i = 0; i < 98; i++) - { - n = INTERLEAVE_TABLE[97-i]; - //n = i; - if (data[i] == 0) - { - dibits[n] = 1; //1 - } - if (data[i] == 1) - { - dibits[n] = 3; //3 - } - if (data[i] == 2) - { - dibits[n] = -1; //-1 - } - if (data[i] == 3) - { - dibits[n] = -3; //-3 - } - } - - //n = INTERLEAVE_TABLE[i]; //should this go in reverse? - //n = INTERLEAVE_TABLE[97-i]; //should this go in reverse? - //dibits[n] = dibit; //should this go in reverse too? not sure on this one, but definitely the INTERLEAVE_TABLE - //n = INTERLEAVE_TABLE[97-i]; //should this go in reverse? - //dibits[97-n] = dibit; - //} -} - -void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points) -{ - for (unsigned int i = 0U; i < 49U; i++) { - if (dibits[i * 2U + 0U] == +1 && dibits[i * 2U + 1U] == -1) - points[i] = 0U; - else if (dibits[i * 2U + 0U] == -1 && dibits[i * 2U + 1U] == -1) - points[i] = 1U; - else if (dibits[i * 2U + 0U] == +3 && dibits[i * 2U + 1U] == -3) - points[i] = 2U; - else if (dibits[i * 2U + 0U] == -3 && dibits[i * 2U + 1U] == -3) - points[i] = 3U; - else if (dibits[i * 2U + 0U] == -3 && dibits[i * 2U + 1U] == -1) - points[i] = 4U; - else if (dibits[i * 2U + 0U] == +3 && dibits[i * 2U + 1U] == -1) - points[i] = 5U; - else if (dibits[i * 2U + 0U] == -1 && dibits[i * 2U + 1U] == -3) - points[i] = 6U; - else if (dibits[i * 2U + 0U] == +1 && dibits[i * 2U + 1U] == -3) - points[i] = 7U; - else if (dibits[i * 2U + 0U] == -3 && dibits[i * 2U + 1U] == +3) - points[i] = 8U; - else if (dibits[i * 2U + 0U] == +3 && dibits[i * 2U + 1U] == +3) - points[i] = 9U; - else if (dibits[i * 2U + 0U] == -1 && dibits[i * 2U + 1U] == +1) - points[i] = 10U; - else if (dibits[i * 2U + 0U] == +1 && dibits[i * 2U + 1U] == +1) - points[i] = 11U; - else if (dibits[i * 2U + 0U] == +1 && dibits[i * 2U + 1U] == +3) - points[i] = 12U; - else if (dibits[i * 2U + 0U] == -1 && dibits[i * 2U + 1U] == +3) - points[i] = 13U; - else if (dibits[i * 2U + 0U] == +3 && dibits[i * 2U + 1U] == +1) - points[i] = 14U; - else if (dibits[i * 2U + 0U] == -3 && dibits[i * 2U + 1U] == +1) - points[i] = 15U; - } -} - -void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits) -{ - for (unsigned int i = 0U; i < 49U; i++) { - switch (points[i]) { - case 0U: - dibits[i * 2U + 0U] = +1; - dibits[i * 2U + 1U] = -1; - break; - case 1U: - dibits[i * 2U + 0U] = -1; - dibits[i * 2U + 1U] = -1; - break; - case 2U: - dibits[i * 2U + 0U] = +3; - dibits[i * 2U + 1U] = -3; - break; - case 3U: - dibits[i * 2U + 0U] = -3; - dibits[i * 2U + 1U] = -3; - break; - case 4U: - dibits[i * 2U + 0U] = -3; - dibits[i * 2U + 1U] = -1; - break; - case 5U: - dibits[i * 2U + 0U] = +3; - dibits[i * 2U + 1U] = -1; - break; - case 6U: - dibits[i * 2U + 0U] = -1; - dibits[i * 2U + 1U] = -3; - break; - case 7U: - dibits[i * 2U + 0U] = +1; - dibits[i * 2U + 1U] = -3; - break; - case 8U: - dibits[i * 2U + 0U] = -3; - dibits[i * 2U + 1U] = +3; - break; - case 9U: - dibits[i * 2U + 0U] = +3; - dibits[i * 2U + 1U] = +3; - break; - case 10U: - dibits[i * 2U + 0U] = -1; - dibits[i * 2U + 1U] = +1; - break; - case 11U: - dibits[i * 2U + 0U] = +1; - dibits[i * 2U + 1U] = +1; - break; - case 12U: - dibits[i * 2U + 0U] = +1; - dibits[i * 2U + 1U] = +3; - break; - case 13U: - dibits[i * 2U + 0U] = -1; - dibits[i * 2U + 1U] = +3; - break; - case 14U: - dibits[i * 2U + 0U] = +3; - dibits[i * 2U + 1U] = +1; - break; - default: - dibits[i * 2U + 0U] = -3; - dibits[i * 2U + 1U] = +1; - break; - } - } -} - -void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribits) -{ - for (unsigned int i = 0U; i < 48U; i++) { - unsigned int n = 143U - i * 3U; - - bool b1 = READ_BIT(payload, n) != 0x00U; - n--; - bool b2 = READ_BIT(payload, n) != 0x00U; - n--; - bool b3 = READ_BIT(payload, n) != 0x00U; - - unsigned char tribit = 0U; - tribit |= b1 ? 4U : 0U; - tribit |= b2 ? 2U : 0U; - tribit |= b3 ? 1U : 0U; - - //tribits[i] = tribit; - } - - tribits[48U] = 0U; -} - -bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload) -{ - assert(data != NULL); - assert(payload != NULL); - unsigned char tribits[49U]; - for (short i = 0; i < 49; i++) - { - tribits[i] = 0; //initialize with 0 values so we know later on if these values are actually being assigned or not - } - - if (1 == 2) - { - fprintf (stderr, "\n Raw Trellis Dibits inside Decoder\n "); - for (short i = 0; i < 98; i++) - { - fprintf (stderr, "#%d [%0d] ", i, data[i]); - } - } - signed char dibits[98U]; - CDMRTrellisDeinterleave(data, dibits); - if (1 == 2) - { - fprintf (stderr, "\n Trellis Deinterleaved Dibits inside Decoder (converted to signed)\n "); - for (short i = 0; i < 98; i++) - { - fprintf (stderr, "#%d [%d] ", i, dibits[i]); //signed char, values should be -3, -1, 1, 3 only - } - } - unsigned char points[49U]; - // unsigned char reverse_points[49U]; - CDMRTrellisDibitsToPoints(dibits, points); - //maybe keep point 49 at 49, since its the flush? - //fprintf (stderr, "\n Trellis Reverse Points inside Decoder\n "); - // for (short i = 0; i < 49; i++) - // { - // reverse_points[i] = points[48-i]; - // //fprintf (stderr, "#%d [%02u] ", i, reverse_points[i]); - // } - //reverse_points[48] = points[48]; - //fprintf (stderr, "#%d [%02u] ", 48, reverse_points[48]); - - if (1 == 2) - { - fprintf (stderr, "\n Trellis Points inside Decoder\n "); - for (short i = 0; i < 49; i++) - { - fprintf (stderr, "#%d [%02u] ", i, points[i]); - } - } - // Check the original code - - unsigned int failPos = CDMRTrellisCheckCode(points, tribits); - //unsigned int failPos = CDMRTrellisCheckCode(reverse_points, tribits); //stack smashing detected terminated - - if (1 == 2) - { - fprintf (stderr, "\n Check Code Trellis Tribits inside Decoder\n "); - for (short i = 0; i < 49; i++) - { - fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7? - } - } - - if (failPos == 999U) - { - CDMRTrellisTribitsToBits(tribits, payload); - if (1 == 2) - { - fprintf (stderr, "\nTrellis Payload Tribits\n %s ", KCYN); - for (short i = 0; i < 49; i++) - { - fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7? - } - } - if (1 == 2) - { - fprintf (stderr, "\nTrellis Payload Tribits to Bytes inside Decoder\n %s ", KCYN); - for (short i = 0; i < 18; i++) - { - fprintf (stderr, "[%02X]", payload[i]); - } - fprintf (stderr,"%s", KNRM); //change back to normal - } - return true; - } - - unsigned char savePoints[49U]; - for (unsigned int i = 0U; i < 49U; i++) - savePoints[i] = points[i]; - //savePoints[i] = reverse_points[i]; - - bool ret = CDMRTrellisFixCode(points, failPos, payload); - //bool ret = CDMRTrellisFixCode(reverse_points, failPos, payload); - if (ret){ - - if (1 == 2) - { - fprintf (stderr, "\n if return Trellis Tribits inside Decoder\n "); - for (short i = 0; i < 49; i++) - { - fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7? - } - } - - if (1 == 2) - { - fprintf (stderr, "\nTrellis Payload Tribits to Bits fix return true\n "); //this one seems to be happening - for (short i = 0; i < 18; i++) - { - fprintf (stderr, "[%02X]", payload[i]); - } - } - return true; } - - if (failPos == 0U) - { - if (1 == 2) - { - fprintf (stderr, "\nTrellis Payload Tribits to Bytes failPos == 0U\n "); - for (short i = 0; i < 18; i++) - { - fprintf (stderr, "[%02X]", payload[i]); - } - } - return false; } - - // Backtrack one place for a last go - return CDMRTrellisFixCode(savePoints, failPos - 1U, payload); -}