MBC Header and Blocks CRC;
This commit is contained in:
parent
a2b3da5b5a
commit
a5d23d9e12
|
|
@ -846,6 +846,7 @@ rs_12_9_checksum_t *rs_12_9_calc_checksum(rs_12_9_codeword_t *codeword);
|
|||
|
||||
//DMR CRC Functions
|
||||
uint16_t ComputeCrcCCITT(uint8_t * DMRData);
|
||||
uint16_t ComputeCrcCCITT16d(const uint8_t buf[], uint8_t len);
|
||||
uint32_t ComputeAndCorrectFullLinkControlCrc(uint8_t * FullLinkControlDataBytes, uint32_t * CRCComputed, uint32_t CRCMask);
|
||||
uint8_t ComputeCrc5Bit(uint8_t * DMRData);
|
||||
|
||||
|
|
|
|||
|
|
@ -276,9 +276,14 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||
uint32_t CRCCorrect = 0;
|
||||
uint32_t CRCComputed = 0;
|
||||
uint32_t CRCExtracted = 0;
|
||||
uint32_t IrrecoverableErrors = 0;
|
||||
uint32_t IrrecoverableErrors = 0;
|
||||
|
||||
uint8_t dmr_pdu_sf_bits[18*8*8]; //8 blocks at 18 bytes at 8 bits //just a large value to have plenty storage space
|
||||
|
||||
//MBC Header and Block CRC
|
||||
uint8_t mbc_crc_good[2]; //header and blocks crc pass/fail local storage
|
||||
memset (mbc_crc_good, 0, sizeof (mbc_crc_good)); //init on 0 - bad crc
|
||||
|
||||
if (type == 1) blocks = state->data_header_blocks[slot] - 1;
|
||||
if (type == 2) blocks = state->data_block_counter[slot];
|
||||
|
||||
|
|
@ -344,12 +349,46 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||
dmr_pdu_sf_bits[j + 7] = (state->dmr_pdu_sf[slot][i] >> 0) & 0x01;
|
||||
}
|
||||
|
||||
//TODO: CRC check on Header and full frames as appropriate
|
||||
//CRC check on Header and full frames as appropriate (header crc already stored)
|
||||
//The 16 bit CRC in the header shall include the data carried by the header.
|
||||
//The 16 bit CRC in the last block shall be performed on
|
||||
//all MBC blocks (conmbined) except the header block. <-- misleading statement, just like half the dmr manual
|
||||
|
||||
mbc_crc_good[0] = state->data_block_crc_valid[slot][0];
|
||||
|
||||
CRCExtracted = 0;
|
||||
//extract crc from last block, apply to completed 'superframe' minus header
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
CRCExtracted = CRCExtracted << 1;
|
||||
CRCExtracted = CRCExtracted | (uint32_t)(dmr_pdu_sf_bits[i + 96*(1+blocks) - 16] & 1);
|
||||
}
|
||||
|
||||
//shim these values for now
|
||||
CRCCorrect = 1;
|
||||
IrrecoverableErrors = 0;
|
||||
uint8_t mbc_block_bits[12*8*3];
|
||||
memset (mbc_block_bits, 0, sizeof(mbc_block_bits));
|
||||
//shift continuation blocks and last block into seperate array for crc check
|
||||
for (i = 0; i < 12*8*3; i++)
|
||||
{
|
||||
mbc_block_bits[i] = dmr_pdu_sf_bits[i+96]; //skip mbc header
|
||||
}
|
||||
|
||||
CRCComputed = ComputeCrcCCITT16d (mbc_block_bits, ((blocks+0)*96)-16 );
|
||||
|
||||
// fprintf (stderr, " \n CRC EXT %X CRC CMP %X", CRCExtracted, CRCComputed);
|
||||
|
||||
if (CRCComputed == CRCExtracted) mbc_crc_good[1] = 1;
|
||||
|
||||
CRCCorrect = 0;
|
||||
IrrecoverableErrors = 1;
|
||||
|
||||
//set good on good header and good blocks
|
||||
if (mbc_crc_good[0] == 1 && mbc_crc_good[1] == 1)
|
||||
{
|
||||
CRCCorrect = 1;
|
||||
IrrecoverableErrors = 0;
|
||||
}
|
||||
|
||||
//cspdu will only act on any fid/opcodes if good CRC to prevent falsing on control signalling
|
||||
dmr_cspdu (opts, state, dmr_pdu_sf_bits, state->dmr_pdu_sf[slot], CRCCorrect, IrrecoverableErrors);
|
||||
|
||||
}
|
||||
|
|
@ -358,7 +397,7 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||
//Full Super Frame Type 1 - Debug Output
|
||||
if (opts->payload == 1 && type == 1 && state->data_block_counter[slot] == state->data_header_blocks[slot])
|
||||
{
|
||||
fprintf (stderr, "%s",KGRN);
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf (stderr, "\n Multi Block PDU Superframe - Slot [%d]\n ", slot+1);
|
||||
for (i = 0; i < ((blocks+1)*block_len); i++)
|
||||
{
|
||||
|
|
@ -374,7 +413,7 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||
//Full Super Frame MBC - Debug Output
|
||||
if (opts->payload == 1 && type == 2 && lb == 1)
|
||||
{
|
||||
fprintf (stderr, "%s",KGRN);
|
||||
fprintf (stderr, "%s", KGRN);
|
||||
fprintf (stderr, "\n MBC Multi Block PDU Superframe - Slot [%d]\n ", slot+1);
|
||||
for (i = 0; i < ((blocks+1)*block_len); i++)
|
||||
{
|
||||
|
|
@ -384,6 +423,9 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||
fprintf (stderr, "\n ");
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "%s", KRED);
|
||||
if (mbc_crc_good[0] == 0) fprintf (stderr, "MBC Header CRC ERR ");
|
||||
if (mbc_crc_good[1] == 0) fprintf (stderr, "MBC Blocks CRC ERR ");
|
||||
fprintf (stderr, "%s ", KNRM);
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +447,7 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||
|
||||
}
|
||||
|
||||
//failsafe to clear old data header and block info in case of tact/emb/slottype failures and we
|
||||
//failsafe to clear old data header, block info, cach, in case of tact/emb/slottype failures and we
|
||||
//can no longer verify accurate data block reporting
|
||||
void dmr_reset_blocks (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
|
@ -416,4 +458,5 @@ void dmr_reset_blocks (dsd_opts * opts, dsd_state * state)
|
|||
memset (state->data_header_blocks, 0, sizeof(state->data_header_blocks));
|
||||
memset (state->data_block_crc_valid, 0, sizeof(state->data_block_crc_valid));
|
||||
memset (state->dmr_lrrp_source, 0, sizeof(state->dmr_lrrp_source));
|
||||
memset (state->dmr_cach_fragment, 0, sizeof (state->dmr_cach_fragment));
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
//TODO: CRC9 on confirmed data blocks; CRC32 on completed data sf;
|
||||
//TODO: MBC full message CRC16 (does this include the header or not though?)
|
||||
//TODO: Reverse Channel Signalling - RC single burst BPTC/7-bit CRC
|
||||
//TODO: Single Burst Embedded LC - Non-RC single burst LC - Look for Late Entry Alg/Key
|
||||
|
||||
|
|
@ -325,7 +324,8 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||
{
|
||||
CRCExtracted = 0;
|
||||
CRCComputed = 0;
|
||||
IrrecoverableErrors = 1; //can't be tested, but maybe can poll trellis decoder for a value in the future
|
||||
IrrecoverableErrors = 1;
|
||||
bool trellis_good = TRUE;
|
||||
|
||||
uint8_t tdibits[98];
|
||||
memset (tdibits, 0, sizeof(tdibits));
|
||||
|
|
@ -339,7 +339,9 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
|
|||
unsigned char TrellisReturn[18];
|
||||
memset (TrellisReturn, 0, sizeof(TrellisReturn));
|
||||
|
||||
CDMRTrellisDecode(tdibits, TrellisReturn);
|
||||
trellis_good = CDMRTrellisDecode(tdibits, TrellisReturn);
|
||||
if (trellis_good == TRUE) IrrecoverableErrors = 0;
|
||||
// else (fprintf (stderr, " Trellis Failure")); //debug print
|
||||
|
||||
for (i = 0; i < pdu_len; i++) //18
|
||||
{
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ uint8_t dmr_cach (dsd_opts * opts, dsd_state * state, uint8_t cach_bits[25])
|
|||
h1 = Hamming17123 (slco_bits + 0);
|
||||
|
||||
//run single - manual would suggest that though this exists, there is no support? or perhaps its manufacturer only thing?
|
||||
if (h1) dmr_slco (opts, state, slco_bits);
|
||||
if (h1) ; // dmr_slco (opts, state, slco_bits); //random false positibes for con+, so diabled for now
|
||||
else
|
||||
{
|
||||
err = 1;
|
||||
|
|
@ -593,7 +593,7 @@ void dmr_embedded_alias_blocks (dsd_opts * opts, dsd_state * state, uint8_t lc_b
|
|||
|
||||
}
|
||||
|
||||
//externalize embedded GPS
|
||||
//externalize embedded GPS - Needs samples to test/fix function
|
||||
void dmr_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[])
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
|
|
@ -603,14 +603,15 @@ void dmr_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[])
|
|||
uint8_t res_a = lc_bits[1];
|
||||
uint8_t res_b = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 4);
|
||||
uint8_t pos_err = (uint8_t)ConvertBitIntoBytes(&lc_bits[20], 3);
|
||||
uint32_t lon = (uint32_t)ConvertBitIntoBytes(&lc_bits[23], 25);
|
||||
uint32_t lat = (uint32_t)ConvertBitIntoBytes(&lc_bits[48], 24);
|
||||
|
||||
uint32_t lon_sign = lc_bits[23];
|
||||
uint32_t lon = (uint32_t)ConvertBitIntoBytes(&lc_bits[24], 24);
|
||||
uint32_t lat_sign = lc_bits[48];
|
||||
uint32_t lat = (uint32_t)ConvertBitIntoBytes(&lc_bits[49], 23);
|
||||
|
||||
double lat_unit = (double)180/ pow (2.0, 24); //180 divided by 2^24
|
||||
double lon_unit = (double)360/ pow (2.0, 25); //360 divided by 2^25
|
||||
|
||||
uint32_t lat_sign = lat >> 23;
|
||||
uint32_t lon_sign = lon >> 24;
|
||||
char latstr[3];
|
||||
char lonstr[3];
|
||||
sprintf (latstr, "%s", "N");
|
||||
|
|
@ -627,14 +628,14 @@ void dmr_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[])
|
|||
{
|
||||
if (lat_sign)
|
||||
{
|
||||
lat = 0x800001 - (lat & 0x7FFFFF);
|
||||
lat = 0x800001 - lat;
|
||||
sprintf (latstr, "%s", "S");
|
||||
}
|
||||
latitude = ((double)lat * lat_unit);
|
||||
|
||||
if (lon_sign)
|
||||
{
|
||||
lon = 0x1000001 - (lon & 0xFFFFFF);
|
||||
lon = 0x1000001 - lon;
|
||||
sprintf (lonstr, "%s", "W");
|
||||
}
|
||||
longitude = ((double)lon * lon_unit);
|
||||
|
|
@ -657,7 +658,6 @@ void dmr_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[])
|
|||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,36 @@
|
|||
|
||||
#include "dsd.h"
|
||||
|
||||
//modified to accept variable payload size and len
|
||||
uint16_t ComputeCrcCCITT16d(const uint8_t buf[], uint8_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint16_t CRC = 0x0000; /* Initialization value = 0x0000 */
|
||||
/* Polynomial x^16 + x^12 + x^5 + 1
|
||||
* Normal = 0x1021
|
||||
* Reciprocal = 0x0811
|
||||
* Reversed = 0x8408
|
||||
* Reversed reciprocal = 0x8810 */
|
||||
uint16_t Polynome = 0x1021;
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if(((CRC >> 15) & 1) ^ (buf[i] & 1))
|
||||
{
|
||||
CRC = (CRC << 1) ^ Polynome;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRC <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Invert the CRC */
|
||||
CRC ^= 0xFFFF;
|
||||
|
||||
/* Return the CRC */
|
||||
return CRC;
|
||||
} /* End ComputeCrcCCITTd() */
|
||||
|
||||
// A Hamming (17,12,3) Check for completed SLC message
|
||||
bool Hamming17123(uint8_t* d)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue